/*
|
/*
|
* main.c -- ECO32 simulator
|
* main.c -- ECO32 simulator
|
*/
|
*/
|
|
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
#include "common.h"
|
#include "common.h"
|
#include "console.h"
|
#include "console.h"
|
#include "error.h"
|
#include "error.h"
|
#include "command.h"
|
#include "command.h"
|
#include "instr.h"
|
#include "instr.h"
|
#include "cpu.h"
|
#include "cpu.h"
|
#include "mmu.h"
|
#include "mmu.h"
|
#include "memory.h"
|
#include "memory.h"
|
#include "timer.h"
|
#include "timer.h"
|
#include "dspkbd.h"
|
#include "dspkbd.h"
|
#include "term.h"
|
#include "term.h"
|
#include "disk.h"
|
#include "disk.h"
|
#include "output.h"
|
#include "output.h"
|
#include "graph.h"
|
#include "graph.h"
|
|
|
|
|
static void usage(char *myself) {
|
static void usage(char *myself) {
|
fprintf(stderr, "Usage: %s\n", myself);
|
fprintf(stderr, "Usage: %s\n", myself);
|
fprintf(stderr, " [-i] set interactive mode\n");
|
fprintf(stderr, " [-i] set interactive mode\n");
|
fprintf(stderr, " [-m <n>] install n MB of RAM (1-%d)\n",
|
fprintf(stderr, " [-m <n>] install n MB of RAM (1-%d)\n",
|
RAM_SIZE_MAX / M);
|
RAM_SIZE_MAX / M);
|
fprintf(stderr, " [-l <prog>] set program file name\n");
|
fprintf(stderr, " [-l <prog>] set program file name\n");
|
fprintf(stderr, " [-r <rom>] set ROM image file name\n");
|
fprintf(stderr, " [-r <rom>] set ROM image file name\n");
|
fprintf(stderr, " [-d <disk>] set disk image file name\n");
|
fprintf(stderr, " [-d <disk>] set disk image file name\n");
|
fprintf(stderr, " [-t <n>] connect n terminals (0-%d)\n",
|
fprintf(stderr, " [-t <n>] connect n terminals (0-%d)\n",
|
MAX_NTERMS);
|
MAX_NTERMS);
|
fprintf(stderr, " [-g] install graphics controller\n");
|
fprintf(stderr, " [-g] install graphics controller\n");
|
fprintf(stderr, " [-c] install console\n");
|
fprintf(stderr, " [-c] install console\n");
|
fprintf(stderr, " [-o <file>] bind output device to file\n");
|
fprintf(stderr, " [-o <file>] bind output device to file\n");
|
fprintf(stderr, "The options -l and -r are mutually exclusive.\n");
|
fprintf(stderr, "The options -l and -r are mutually exclusive.\n");
|
fprintf(stderr, "If both are omitted, interactive mode is assumed.\n");
|
fprintf(stderr, "If both are omitted, interactive mode is assumed.\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
|
|
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
int i;
|
int i;
|
char *argp;
|
char *argp;
|
char *endp;
|
char *endp;
|
Bool interactive;
|
Bool interactive;
|
int memSize;
|
int memSize;
|
char *progName;
|
char *progName;
|
char *romName;
|
char *romName;
|
char *diskName;
|
char *diskName;
|
int numTerms;
|
int numTerms;
|
Bool graphics;
|
Bool graphics;
|
Bool console;
|
Bool console;
|
char *outputName;
|
char *outputName;
|
Word initialPC;
|
Word initialPC;
|
char command[20];
|
char command[20];
|
char *line;
|
char *line;
|
|
|
interactive = false;
|
interactive = false;
|
memSize = RAM_SIZE_DFL / M;
|
memSize = RAM_SIZE_DFL / M;
|
progName = NULL;
|
progName = NULL;
|
romName = NULL;
|
romName = NULL;
|
diskName = NULL;
|
diskName = NULL;
|
numTerms = 0;
|
numTerms = 0;
|
graphics = false;
|
graphics = false;
|
console = false;
|
console = false;
|
outputName = NULL;
|
outputName = NULL;
|
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
argp = argv[i];
|
argp = argv[i];
|
if (*argp != '-') {
|
if (*argp != '-') {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
argp++;
|
argp++;
|
switch (*argp) {
|
switch (*argp) {
|
case 'i':
|
case 'i':
|
interactive = true;
|
interactive = true;
|
break;
|
break;
|
case 'm':
|
case 'm':
|
if (i == argc - 1) {
|
if (i == argc - 1) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
memSize = strtol(argv[++i], &endp, 10);
|
memSize = strtol(argv[++i], &endp, 10);
|
if (*endp != '\0' ||
|
if (*endp != '\0' ||
|
memSize <= 0 ||
|
memSize <= 0 ||
|
memSize > RAM_SIZE_MAX / M) {
|
memSize > RAM_SIZE_MAX / M) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
break;
|
break;
|
case 'l':
|
case 'l':
|
if (i == argc - 1 || progName != NULL || romName != NULL) {
|
if (i == argc - 1 || progName != NULL || romName != NULL) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
progName = argv[++i];
|
progName = argv[++i];
|
break;
|
break;
|
case 'r':
|
case 'r':
|
if (i == argc - 1 || romName != NULL || progName != NULL) {
|
if (i == argc - 1 || romName != NULL || progName != NULL) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
romName = argv[++i];
|
romName = argv[++i];
|
break;
|
break;
|
case 'd':
|
case 'd':
|
if (i == argc - 1 || diskName != NULL) {
|
if (i == argc - 1 || diskName != NULL) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
diskName = argv[++i];
|
diskName = argv[++i];
|
break;
|
break;
|
case 't':
|
case 't':
|
if (i == argc - 1) {
|
if (i == argc - 1) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
numTerms = strtol(argv[++i], &endp, 10);
|
numTerms = strtol(argv[++i], &endp, 10);
|
if (*endp != '\0' ||
|
if (*endp != '\0' ||
|
numTerms < 0 ||
|
numTerms < 0 ||
|
numTerms > MAX_NTERMS) {
|
numTerms > MAX_NTERMS) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
break;
|
break;
|
case 'g':
|
case 'g':
|
graphics = true;
|
graphics = true;
|
break;
|
break;
|
case 'c':
|
case 'c':
|
console = true;
|
console = true;
|
break;
|
break;
|
case 'o':
|
case 'o':
|
if (i == argc - 1 || outputName != NULL) {
|
if (i == argc - 1 || outputName != NULL) {
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
outputName = argv[++i];
|
outputName = argv[++i];
|
break;
|
break;
|
default:
|
default:
|
usage(argv[0]);
|
usage(argv[0]);
|
}
|
}
|
}
|
}
|
cInit();
|
cInit();
|
cPrintf("ECO32 Simulator started\n");
|
cPrintf("ECO32 Simulator started\n");
|
if (progName == NULL && romName == NULL && !interactive) {
|
if (progName == NULL && romName == NULL && !interactive) {
|
cPrintf("Neither a program to load nor a system ROM was\n");
|
cPrintf("Neither a program to load nor a system ROM was\n");
|
cPrintf("specified, so interactive mode is assumed.\n");
|
cPrintf("specified, so interactive mode is assumed.\n");
|
interactive = true;
|
interactive = true;
|
}
|
}
|
initInstrTable();
|
initInstrTable();
|
timerInit();
|
timerInit();
|
if (console) {
|
if (console) {
|
displayInit();
|
displayInit();
|
keyboardInit();
|
keyboardInit();
|
}
|
}
|
termInit(numTerms);
|
termInit(numTerms);
|
diskInit(diskName);
|
diskInit(diskName);
|
outputInit(outputName);
|
outputInit(outputName);
|
if (graphics) {
|
if (graphics) {
|
graphInit();
|
graphInit();
|
}
|
}
|
memoryInit(memSize * M, progName, romName);
|
memoryInit(memSize * M, progName, romName);
|
mmuInit();
|
mmuInit();
|
if (progName != NULL) {
|
if (progName != NULL) {
|
initialPC = 0xC0000000;
|
initialPC = 0xC0000000;
|
} else {
|
} else {
|
initialPC = 0xC0000000 | ROM_BASE;
|
initialPC = 0xC0000000 | ROM_BASE;
|
}
|
}
|
cpuInit(initialPC);
|
cpuInit(initialPC);
|
if (!interactive) {
|
if (!interactive) {
|
cPrintf("Start executing...\n");
|
cPrintf("Start executing...\n");
|
strcpy(command, "c\n");
|
strcpy(command, "c\n");
|
execCommand(command);
|
execCommand(command);
|
} else {
|
} else {
|
while (1) {
|
while (1) {
|
line = cGetLine("ECO32 > ");
|
line = cGetLine("ECO32 > ");
|
if (*line == '\0') {
|
if (*line == '\0') {
|
break;
|
break;
|
}
|
}
|
cAddHist(line);
|
cAddHist(line);
|
if (execCommand(line)) {
|
if (execCommand(line)) {
|
break;
|
break;
|
}
|
}
|
}
|
}
|
}
|
}
|
cpuExit();
|
cpuExit();
|
mmuExit();
|
mmuExit();
|
memoryExit();
|
memoryExit();
|
timerExit();
|
timerExit();
|
displayExit();
|
displayExit();
|
keyboardExit();
|
keyboardExit();
|
termExit();
|
termExit();
|
diskExit();
|
diskExit();
|
outputExit();
|
outputExit();
|
graphExit();
|
graphExit();
|
cPrintf("ECO32 Simulator finished\n");
|
cPrintf("ECO32 Simulator finished\n");
|
cExit();
|
cExit();
|
return 0;
|
return 0;
|
}
|
}
|
|
|