/*
|
/*
|
* command.c -- command interpreter
|
* command.c -- command interpreter
|
*/
|
*/
|
|
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
#include <setjmp.h>
|
#include <setjmp.h>
|
|
|
#include "common.h"
|
#include "common.h"
|
#include "console.h"
|
#include "console.h"
|
#include "error.h"
|
#include "error.h"
|
#include "except.h"
|
#include "except.h"
|
#include "command.h"
|
#include "command.h"
|
#include "asm.h"
|
#include "asm.h"
|
#include "disasm.h"
|
#include "disasm.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 "shutdown.h"
|
#include "shutdown.h"
|
#include "graph.h"
|
#include "graph.h"
|
|
|
|
|
#define MAX_TOKENS 10
|
#define MAX_TOKENS 10
|
|
|
|
|
static Bool quit;
|
static Bool quit;
|
|
|
|
|
typedef struct {
|
typedef struct {
|
char *name;
|
char *name;
|
void (*hlpProc)(void);
|
void (*hlpProc)(void);
|
void (*cmdProc)(char *tokens[], int n);
|
void (*cmdProc)(char *tokens[], int n);
|
} Command;
|
} Command;
|
|
|
extern Command commands[];
|
extern Command commands[];
|
extern int numCommands;
|
extern int numCommands;
|
|
|
|
|
static void help(void) {
|
static void help(void) {
|
cPrintf("valid commands are:\n");
|
cPrintf("valid commands are:\n");
|
cPrintf(" help get help\n");
|
cPrintf(" help get help\n");
|
cPrintf(" + add and subtract\n");
|
cPrintf(" + add and subtract\n");
|
cPrintf(" a assemble\n");
|
cPrintf(" a assemble\n");
|
cPrintf(" u unassemble\n");
|
cPrintf(" u unassemble\n");
|
cPrintf(" b set/reset breakpoint\n");
|
cPrintf(" b set/reset breakpoint\n");
|
cPrintf(" c continue from breakpoint\n");
|
cPrintf(" c continue from breakpoint\n");
|
cPrintf(" s single-step\n");
|
cPrintf(" s single-step\n");
|
cPrintf(" # show/set PC\n");
|
cPrintf(" # show/set PC\n");
|
cPrintf(" p show/set PSW\n");
|
cPrintf(" p show/set PSW\n");
|
cPrintf(" r show/set register\n");
|
cPrintf(" r show/set register\n");
|
cPrintf(" d dump memory\n");
|
cPrintf(" d dump memory\n");
|
cPrintf(" mw show/set memory word\n");
|
cPrintf(" mw show/set memory word\n");
|
cPrintf(" mh show/set memory halfword\n");
|
cPrintf(" mh show/set memory halfword\n");
|
cPrintf(" mb show/set memory byte\n");
|
cPrintf(" mb show/set memory byte\n");
|
cPrintf(" t show/set TLB contents\n");
|
cPrintf(" t show/set TLB contents\n");
|
cPrintf(" i initialize hardware\n");
|
cPrintf(" i initialize hardware\n");
|
cPrintf(" q quit simulator\n");
|
cPrintf(" q quit simulator\n");
|
cPrintf("type 'help <cmd>' to get help for <cmd>\n");
|
cPrintf("type 'help <cmd>' to get help for <cmd>\n");
|
}
|
}
|
|
|
|
|
static void help00(void) {
|
static void help00(void) {
|
cPrintf(" help show a list of commands\n");
|
cPrintf(" help show a list of commands\n");
|
cPrintf(" help <cmd> show help for <cmd>\n");
|
cPrintf(" help <cmd> show help for <cmd>\n");
|
}
|
}
|
|
|
|
|
static void help01(void) {
|
static void help01(void) {
|
cPrintf(" + <num1> <num2> add and subtract <num1> and <num2>\n");
|
cPrintf(" + <num1> <num2> add and subtract <num1> and <num2>\n");
|
}
|
}
|
|
|
|
|
static void help02(void) {
|
static void help02(void) {
|
cPrintf(" a assemble starting at PC\n");
|
cPrintf(" a assemble starting at PC\n");
|
cPrintf(" a <addr> assemble starting at <addr>\n");
|
cPrintf(" a <addr> assemble starting at <addr>\n");
|
}
|
}
|
|
|
|
|
static void help03(void) {
|
static void help03(void) {
|
cPrintf(" u unassemble 16 instrs starting at PC\n");
|
cPrintf(" u unassemble 16 instrs starting at PC\n");
|
cPrintf(" u <addr> unassemble 16 instrs starting at <addr>\n");
|
cPrintf(" u <addr> unassemble 16 instrs starting at <addr>\n");
|
cPrintf(" u <addr> <cnt> unassemble <cnt> instrs starting at <addr>\n");
|
cPrintf(" u <addr> <cnt> unassemble <cnt> instrs starting at <addr>\n");
|
}
|
}
|
|
|
|
|
static void help04(void) {
|
static void help04(void) {
|
cPrintf(" b reset break\n");
|
cPrintf(" b reset break\n");
|
cPrintf(" b <addr> set break at <addr>\n");
|
cPrintf(" b <addr> set break at <addr>\n");
|
}
|
}
|
|
|
|
|
static void help05(void) {
|
static void help05(void) {
|
cPrintf(" c continue execution\n");
|
cPrintf(" c continue execution\n");
|
cPrintf(" c <cnt> continue execution <cnt> times\n");
|
cPrintf(" c <cnt> continue execution <cnt> times\n");
|
}
|
}
|
|
|
|
|
static void help06(void) {
|
static void help06(void) {
|
cPrintf(" s single-step one instruction\n");
|
cPrintf(" s single-step one instruction\n");
|
cPrintf(" s <cnt> single-step <cnt> instructions\n");
|
cPrintf(" s <cnt> single-step <cnt> instructions\n");
|
}
|
}
|
|
|
|
|
static void help07(void) {
|
static void help07(void) {
|
cPrintf(" # show PC\n");
|
cPrintf(" # show PC\n");
|
cPrintf(" # <addr> set PC to <addr>\n");
|
cPrintf(" # <addr> set PC to <addr>\n");
|
}
|
}
|
|
|
|
|
static void help08(void) {
|
static void help08(void) {
|
cPrintf(" p show PSW\n");
|
cPrintf(" p show PSW\n");
|
cPrintf(" p <data> set PSW to <data>\n");
|
cPrintf(" p <data> set PSW to <data>\n");
|
}
|
}
|
|
|
|
|
static void help09(void) {
|
static void help09(void) {
|
cPrintf(" r show all registers\n");
|
cPrintf(" r show all registers\n");
|
cPrintf(" r <reg> show register <reg>\n");
|
cPrintf(" r <reg> show register <reg>\n");
|
cPrintf(" r <reg> <data> set register <reg> to <data>\n");
|
cPrintf(" r <reg> <data> set register <reg> to <data>\n");
|
}
|
}
|
|
|
|
|
static void help10(void) {
|
static void help10(void) {
|
cPrintf(" d dump 256 bytes starting at PC\n");
|
cPrintf(" d dump 256 bytes starting at PC\n");
|
cPrintf(" d <addr> dump 256 bytes starting at <addr>\n");
|
cPrintf(" d <addr> dump 256 bytes starting at <addr>\n");
|
cPrintf(" d <addr> <cnt> dump <cnt> bytes starting at <addr>\n");
|
cPrintf(" d <addr> <cnt> dump <cnt> bytes starting at <addr>\n");
|
}
|
}
|
|
|
|
|
static void help11(void) {
|
static void help11(void) {
|
cPrintf(" mw show memory word at PC\n");
|
cPrintf(" mw show memory word at PC\n");
|
cPrintf(" mw <addr> show memory word at <addr>\n");
|
cPrintf(" mw <addr> show memory word at <addr>\n");
|
cPrintf(" mw <addr> <data> set memory word at <addr> to <data>\n");
|
cPrintf(" mw <addr> <data> set memory word at <addr> to <data>\n");
|
}
|
}
|
|
|
|
|
static void help12(void) {
|
static void help12(void) {
|
cPrintf(" mh show memory halfword at PC\n");
|
cPrintf(" mh show memory halfword at PC\n");
|
cPrintf(" mh <addr> show memory halfword at <addr>\n");
|
cPrintf(" mh <addr> show memory halfword at <addr>\n");
|
cPrintf(" mh <addr> <data> set memory halfword at <addr> to <data>\n");
|
cPrintf(" mh <addr> <data> set memory halfword at <addr> to <data>\n");
|
}
|
}
|
|
|
|
|
static void help13(void) {
|
static void help13(void) {
|
cPrintf(" mb show memory byte at PC\n");
|
cPrintf(" mb show memory byte at PC\n");
|
cPrintf(" mb <addr> show memory byte at <addr>\n");
|
cPrintf(" mb <addr> show memory byte at <addr>\n");
|
cPrintf(" mb <addr> <data> set memory byte at <addr> to <data>\n");
|
cPrintf(" mb <addr> <data> set memory byte at <addr> to <data>\n");
|
}
|
}
|
|
|
|
|
static void help14(void) {
|
static void help14(void) {
|
cPrintf(" t show TLB contents\n");
|
cPrintf(" t show TLB contents\n");
|
cPrintf(" t <i> show TLB contents at <i>\n");
|
cPrintf(" t <i> show TLB contents at <i>\n");
|
cPrintf(" t <i> p <data> set TLB contents at <i> to page <data>\n");
|
cPrintf(" t <i> p <data> set TLB contents at <i> to page <data>\n");
|
cPrintf(" t <i> f <data> set TLB contents at <i> to frame <data>\n");
|
cPrintf(" t <i> f <data> set TLB contents at <i> to frame <data>\n");
|
}
|
}
|
|
|
|
|
static void help15(void) {
|
static void help15(void) {
|
cPrintf(" i initialize hardware\n");
|
cPrintf(" i initialize hardware\n");
|
}
|
}
|
|
|
|
|
static void help16(void) {
|
static void help16(void) {
|
cPrintf(" q quit simulator\n");
|
cPrintf(" q quit simulator\n");
|
}
|
}
|
|
|
|
|
static char *cause[32] = {
|
static char *cause[32] = {
|
/* 0 */ "serial line 0 xmt interrupt",
|
/* 0 */ "serial line 0 xmt interrupt",
|
/* 1 */ "serial line 0 rcv interrupt",
|
/* 1 */ "serial line 0 rcv interrupt",
|
/* 2 */ "serial line 1 xmt interrupt",
|
/* 2 */ "serial line 1 xmt interrupt",
|
/* 3 */ "serial line 1 rcv interrupt",
|
/* 3 */ "serial line 1 rcv interrupt",
|
/* 4 */ "keyboard interrupt",
|
/* 4 */ "keyboard interrupt",
|
/* 5 */ "unknown interrupt",
|
/* 5 */ "unknown interrupt",
|
/* 6 */ "unknown interrupt",
|
/* 6 */ "unknown interrupt",
|
/* 7 */ "unknown interrupt",
|
/* 7 */ "unknown interrupt",
|
/* 8 */ "disk interrupt",
|
/* 8 */ "disk interrupt",
|
/* 9 */ "unknown interrupt",
|
/* 9 */ "unknown interrupt",
|
/* 10 */ "unknown interrupt",
|
/* 10 */ "unknown interrupt",
|
/* 11 */ "unknown interrupt",
|
/* 11 */ "unknown interrupt",
|
/* 12 */ "unknown interrupt",
|
/* 12 */ "unknown interrupt",
|
/* 13 */ "unknown interrupt",
|
/* 13 */ "unknown interrupt",
|
/* 14 */ "timer 0 interrupt",
|
/* 14 */ "timer 0 interrupt",
|
/* 15 */ "timer 1 interrupt",
|
/* 15 */ "timer 1 interrupt",
|
/* 16 */ "bus timeout exception",
|
/* 16 */ "bus timeout exception",
|
/* 17 */ "illegal instruction exception",
|
/* 17 */ "illegal instruction exception",
|
/* 18 */ "privileged instruction exception",
|
/* 18 */ "privileged instruction exception",
|
/* 19 */ "divide instruction exception",
|
/* 19 */ "divide instruction exception",
|
/* 20 */ "trap instruction exception",
|
/* 20 */ "trap instruction exception",
|
/* 21 */ "TLB miss exception",
|
/* 21 */ "TLB miss exception",
|
/* 22 */ "TLB write exception",
|
/* 22 */ "TLB write exception",
|
/* 23 */ "TLB invalid exception",
|
/* 23 */ "TLB invalid exception",
|
/* 24 */ "illegal address exception",
|
/* 24 */ "illegal address exception",
|
/* 25 */ "privileged address exception",
|
/* 25 */ "privileged address exception",
|
/* 26 */ "unknown exception",
|
/* 26 */ "unknown exception",
|
/* 27 */ "unknown exception",
|
/* 27 */ "unknown exception",
|
/* 28 */ "unknown exception",
|
/* 28 */ "unknown exception",
|
/* 29 */ "unknown exception",
|
/* 29 */ "unknown exception",
|
/* 30 */ "unknown exception",
|
/* 30 */ "unknown exception",
|
/* 31 */ "unknown exception"
|
/* 31 */ "unknown exception"
|
};
|
};
|
|
|
|
|
static char *exceptionToString(int exception) {
|
static char *exceptionToString(int exception) {
|
if (exception < 0 ||
|
if (exception < 0 ||
|
exception >= sizeof(cause)/sizeof(cause[0])) {
|
exception >= sizeof(cause)/sizeof(cause[0])) {
|
error("exception number out of bounds");
|
error("exception number out of bounds");
|
}
|
}
|
return cause[exception];
|
return cause[exception];
|
}
|
}
|
|
|
|
|
static Bool getHexNumber(char *str, Word *valptr) {
|
static Bool getHexNumber(char *str, Word *valptr) {
|
char *end;
|
char *end;
|
|
|
*valptr = strtoul(str, &end, 16);
|
*valptr = strtoul(str, &end, 16);
|
return *end == '\0';
|
return *end == '\0';
|
}
|
}
|
|
|
|
|
static Bool getDecNumber(char *str, int *valptr) {
|
static Bool getDecNumber(char *str, int *valptr) {
|
char *end;
|
char *end;
|
|
|
*valptr = strtoul(str, &end, 10);
|
*valptr = strtoul(str, &end, 10);
|
return *end == '\0';
|
return *end == '\0';
|
}
|
}
|
|
|
|
|
static void showPC(void) {
|
static void showPC(void) {
|
Word pc, psw;
|
Word pc, psw;
|
Word instr;
|
Word instr;
|
|
|
pc = cpuGetPC();
|
pc = cpuGetPC();
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
instr = mmuReadWord(pc, psw & PSW_UM);
|
instr = mmuReadWord(pc, psw & PSW_UM);
|
cPrintf("PC %08X [PC] %08X %s\n",
|
cPrintf("PC %08X [PC] %08X %s\n",
|
pc, instr, disasm(instr, pc));
|
pc, instr, disasm(instr, pc));
|
}
|
}
|
|
|
|
|
static void showBreakAndTotal(void) {
|
static void showBreakAndTotal(void) {
|
Word brk;
|
Word brk;
|
Word tot;
|
Word tot;
|
|
|
brk = cpuGetBreak();
|
brk = cpuGetBreak();
|
tot = cpuGetTotal();
|
tot = cpuGetTotal();
|
cPrintf("Brk ");
|
cPrintf("Brk ");
|
if (cpuTestBreak()) {
|
if (cpuTestBreak()) {
|
cPrintf("%08X", brk);
|
cPrintf("%08X", brk);
|
} else {
|
} else {
|
cPrintf("--------");
|
cPrintf("--------");
|
}
|
}
|
cPrintf(" Total %08X instructions\n", tot);
|
cPrintf(" Total %08X instructions\n", tot);
|
}
|
}
|
|
|
|
|
static void showIRQ(void) {
|
static void showIRQ(void) {
|
Word irq;
|
Word irq;
|
int i;
|
int i;
|
|
|
irq = cpuGetIRQ();
|
irq = cpuGetIRQ();
|
cPrintf("IRQ ");
|
cPrintf("IRQ ");
|
for (i = 15; i >= 0; i--) {
|
for (i = 15; i >= 0; i--) {
|
cPrintf("%c", irq & (1 << i) ? '1' : '0');
|
cPrintf("%c", irq & (1 << i) ? '1' : '0');
|
}
|
}
|
cPrintf("\n");
|
cPrintf("\n");
|
}
|
}
|
|
|
|
|
static void showPSW(void) {
|
static void showPSW(void) {
|
Word psw;
|
Word psw;
|
int i;
|
int i;
|
|
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
cPrintf(" xxxx V UPO IPO IACK MASK\n");
|
cPrintf(" xxxx V UPO IPO IACK MASK\n");
|
cPrintf("PSW ");
|
cPrintf("PSW ");
|
for (i = 31; i >= 0; i--) {
|
for (i = 31; i >= 0; i--) {
|
if (i == 27 || i == 26 || i == 23 || i == 20 || i == 15) {
|
if (i == 27 || i == 26 || i == 23 || i == 20 || i == 15) {
|
cPrintf(" ");
|
cPrintf(" ");
|
}
|
}
|
cPrintf("%c", psw & (1 << i) ? '1' : '0');
|
cPrintf("%c", psw & (1 << i) ? '1' : '0');
|
}
|
}
|
cPrintf("\n");
|
cPrintf("\n");
|
}
|
}
|
|
|
|
|
static void doHelp(char *tokens[], int n) {
|
static void doHelp(char *tokens[], int n) {
|
int i;
|
int i;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
help();
|
help();
|
} else if (n == 2) {
|
} else if (n == 2) {
|
for (i = 0; i < numCommands; i++) {
|
for (i = 0; i < numCommands; i++) {
|
if (strcmp(commands[i].name, tokens[1]) == 0) {
|
if (strcmp(commands[i].name, tokens[1]) == 0) {
|
(*commands[i].hlpProc)();
|
(*commands[i].hlpProc)();
|
return;
|
return;
|
}
|
}
|
}
|
}
|
cPrintf("no help available for '%s', sorry\n", tokens[1]);
|
cPrintf("no help available for '%s', sorry\n", tokens[1]);
|
} else {
|
} else {
|
help00();
|
help00();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doArith(char *tokens[], int n) {
|
static void doArith(char *tokens[], int n) {
|
Word num1, num2, num3, num4;
|
Word num1, num2, num3, num4;
|
|
|
if (n == 3) {
|
if (n == 3) {
|
if (!getHexNumber(tokens[1], &num1)) {
|
if (!getHexNumber(tokens[1], &num1)) {
|
cPrintf("illegal first number\n");
|
cPrintf("illegal first number\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[2], &num2)) {
|
if (!getHexNumber(tokens[2], &num2)) {
|
cPrintf("illegal second number\n");
|
cPrintf("illegal second number\n");
|
return;
|
return;
|
}
|
}
|
num3 = num1 + num2;
|
num3 = num1 + num2;
|
num4 = num1 - num2;
|
num4 = num1 - num2;
|
cPrintf("add = %08X, sub = %08X\n", num3, num4);
|
cPrintf("add = %08X, sub = %08X\n", num3, num4);
|
} else {
|
} else {
|
help01();
|
help01();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doAssemble(char *tokens[], int n) {
|
static void doAssemble(char *tokens[], int n) {
|
Word addr;
|
Word addr;
|
Word psw;
|
Word psw;
|
char prompt[30];
|
char prompt[30];
|
char *line;
|
char *line;
|
char *msg;
|
char *msg;
|
Word instr;
|
Word instr;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
addr = cpuGetPC();
|
addr = cpuGetPC();
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
} else {
|
} else {
|
help02();
|
help02();
|
return;
|
return;
|
}
|
}
|
addr &= ~0x00000003;
|
addr &= ~0x00000003;
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
while (1) {
|
while (1) {
|
sprintf(prompt, "ASM # %08X: ", addr);
|
sprintf(prompt, "ASM # %08X: ", addr);
|
line = cGetLine(prompt);
|
line = cGetLine(prompt);
|
if (*line == '\0' || *line == '\n') {
|
if (*line == '\0' || *line == '\n') {
|
break;
|
break;
|
}
|
}
|
cAddHist(line);
|
cAddHist(line);
|
msg = asmInstr(line, addr, &instr);
|
msg = asmInstr(line, addr, &instr);
|
if (msg != NULL) {
|
if (msg != NULL) {
|
cPrintf("%s\n", msg);
|
cPrintf("%s\n", msg);
|
} else {
|
} else {
|
mmuWriteWord(addr, instr, psw & PSW_UM);
|
mmuWriteWord(addr, instr, psw & PSW_UM);
|
addr += 4;
|
addr += 4;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doUnassemble(char *tokens[], int n) {
|
static void doUnassemble(char *tokens[], int n) {
|
Word addr, count;
|
Word addr, count;
|
Word psw;
|
Word psw;
|
int i;
|
int i;
|
Word instr;
|
Word instr;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
addr = cpuGetPC();
|
addr = cpuGetPC();
|
count = 16;
|
count = 16;
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
count = 16;
|
count = 16;
|
} else if (n == 3) {
|
} else if (n == 3) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[2], &count)) {
|
if (!getHexNumber(tokens[2], &count)) {
|
cPrintf("illegal count\n");
|
cPrintf("illegal count\n");
|
return;
|
return;
|
}
|
}
|
if (count == 0) {
|
if (count == 0) {
|
return;
|
return;
|
}
|
}
|
} else {
|
} else {
|
help03();
|
help03();
|
return;
|
return;
|
}
|
}
|
addr &= ~0x00000003;
|
addr &= ~0x00000003;
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
instr = mmuReadWord(addr, psw & PSW_UM);
|
instr = mmuReadWord(addr, psw & PSW_UM);
|
cPrintf("%08X: %08X %s\n",
|
cPrintf("%08X: %08X %s\n",
|
addr, instr, disasm(instr, addr));
|
addr, instr, disasm(instr, addr));
|
if (addr + 4 < addr) {
|
if (addr + 4 < addr) {
|
/* wrap-around */
|
/* wrap-around */
|
break;
|
break;
|
}
|
}
|
addr += 4;
|
addr += 4;
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doBreak(char *tokens[], int n) {
|
static void doBreak(char *tokens[], int n) {
|
Word addr;
|
Word addr;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
cpuResetBreak();
|
cpuResetBreak();
|
showBreakAndTotal();
|
showBreakAndTotal();
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
addr &= ~0x00000003;
|
addr &= ~0x00000003;
|
cpuSetBreak(addr);
|
cpuSetBreak(addr);
|
showBreakAndTotal();
|
showBreakAndTotal();
|
} else {
|
} else {
|
help04();
|
help04();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doContinue(char *tokens[], int n) {
|
static void doContinue(char *tokens[], int n) {
|
Word count, i;
|
Word count, i;
|
Word addr;
|
Word addr;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
count = 1;
|
count = 1;
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &count) || count == 0) {
|
if (!getHexNumber(tokens[1], &count) || count == 0) {
|
cPrintf("illegal count\n");
|
cPrintf("illegal count\n");
|
return;
|
return;
|
}
|
}
|
} else {
|
} else {
|
help05();
|
help05();
|
return;
|
return;
|
}
|
}
|
cPrintf("CPU is running, press ^C to interrupt...\n");
|
cPrintf("CPU is running, press ^C to interrupt...\n");
|
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
cpuRun();
|
cpuRun();
|
}
|
}
|
addr = cpuGetPC();
|
addr = cpuGetPC();
|
cPrintf("Break at %08X\n", addr);
|
cPrintf("Break at %08X\n", addr);
|
showPC();
|
showPC();
|
}
|
}
|
|
|
|
|
static void doStep(char *tokens[], int n) {
|
static void doStep(char *tokens[], int n) {
|
Word count, i;
|
Word count, i;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
count = 1;
|
count = 1;
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &count) || count == 0) {
|
if (!getHexNumber(tokens[1], &count) || count == 0) {
|
cPrintf("illegal count\n");
|
cPrintf("illegal count\n");
|
return;
|
return;
|
}
|
}
|
} else {
|
} else {
|
help06();
|
help06();
|
return;
|
return;
|
}
|
}
|
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
cpuStep();
|
cpuStep();
|
}
|
}
|
showPC();
|
showPC();
|
}
|
}
|
|
|
|
|
static void doPC(char *tokens[], int n) {
|
static void doPC(char *tokens[], int n) {
|
Word addr;
|
Word addr;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
showPC();
|
showPC();
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
addr &= ~0x00000003;
|
addr &= ~0x00000003;
|
cpuSetPC(addr);
|
cpuSetPC(addr);
|
showPC();
|
showPC();
|
} else {
|
} else {
|
help07();
|
help07();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void explainPSW(Word data) {
|
static void explainPSW(Word data) {
|
int i;
|
int i;
|
|
|
cPrintf("interrupt vector : %s (%s)\n",
|
cPrintf("interrupt vector : %s (%s)\n",
|
data & PSW_V ? "on " : "off",
|
data & PSW_V ? "on " : "off",
|
data & PSW_V ? "RAM" : "ROM");
|
data & PSW_V ? "RAM" : "ROM");
|
cPrintf("current user mode : %s (%s)\n",
|
cPrintf("current user mode : %s (%s)\n",
|
data & PSW_UM ? "on " : "off",
|
data & PSW_UM ? "on " : "off",
|
data & PSW_UM ? "user" : "kernel");
|
data & PSW_UM ? "user" : "kernel");
|
cPrintf("previous user mode : %s (%s)\n",
|
cPrintf("previous user mode : %s (%s)\n",
|
data & PSW_PUM ? "on " : "off",
|
data & PSW_PUM ? "on " : "off",
|
data & PSW_PUM ? "user" : "kernel");
|
data & PSW_PUM ? "user" : "kernel");
|
cPrintf("old user mode : %s (%s)\n",
|
cPrintf("old user mode : %s (%s)\n",
|
data & PSW_OUM ? "on " : "off",
|
data & PSW_OUM ? "on " : "off",
|
data & PSW_OUM ? "user" : "kernel");
|
data & PSW_OUM ? "user" : "kernel");
|
cPrintf("current interrupt enable : %s (%s)\n",
|
cPrintf("current interrupt enable : %s (%s)\n",
|
data & PSW_IE ? "on " : "off",
|
data & PSW_IE ? "on " : "off",
|
data & PSW_IE ? "enabled" : "disabled");
|
data & PSW_IE ? "enabled" : "disabled");
|
cPrintf("previous interrupt enable : %s (%s)\n",
|
cPrintf("previous interrupt enable : %s (%s)\n",
|
data & PSW_PIE ? "on " : "off",
|
data & PSW_PIE ? "on " : "off",
|
data & PSW_PIE ? "enabled" : "disabled");
|
data & PSW_PIE ? "enabled" : "disabled");
|
cPrintf("old interrupt enable : %s (%s)\n",
|
cPrintf("old interrupt enable : %s (%s)\n",
|
data & PSW_OIE ? "on " : "off",
|
data & PSW_OIE ? "on " : "off",
|
data & PSW_OIE ? "enabled" : "disabled");
|
data & PSW_OIE ? "enabled" : "disabled");
|
cPrintf("last interrupt acknowledged : %02X (%s)\n",
|
cPrintf("last interrupt acknowledged : %02X (%s)\n",
|
(data & PSW_PRIO_MASK) >> 16,
|
(data & PSW_PRIO_MASK) >> 16,
|
exceptionToString((data & PSW_PRIO_MASK) >> 16));
|
exceptionToString((data & PSW_PRIO_MASK) >> 16));
|
for (i = 15; i >= 0; i--) {
|
for (i = 15; i >= 0; i--) {
|
cPrintf("%-35s: %s (%s)\n",
|
cPrintf("%-35s: %s (%s)\n",
|
exceptionToString(i),
|
exceptionToString(i),
|
data & (1 << i) ? "on " : "off",
|
data & (1 << i) ? "on " : "off",
|
data & (1 << i) ? "enabled" : "disabled");
|
data & (1 << i) ? "enabled" : "disabled");
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doPSW(char *tokens[], int n) {
|
static void doPSW(char *tokens[], int n) {
|
Word data;
|
Word data;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
data = cpuGetPSW();
|
data = cpuGetPSW();
|
showPSW();
|
showPSW();
|
showIRQ();
|
showIRQ();
|
explainPSW(data);
|
explainPSW(data);
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &data)) {
|
if (!getHexNumber(tokens[1], &data)) {
|
cPrintf("illegal data\n");
|
cPrintf("illegal data\n");
|
return;
|
return;
|
}
|
}
|
data &= 0x0FFFFFFF;
|
data &= 0x0FFFFFFF;
|
cpuSetPSW(data);
|
cpuSetPSW(data);
|
showPSW();
|
showPSW();
|
showIRQ();
|
showIRQ();
|
explainPSW(data);
|
explainPSW(data);
|
} else {
|
} else {
|
help08();
|
help08();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doRegister(char *tokens[], int n) {
|
static void doRegister(char *tokens[], int n) {
|
int i, j;
|
int i, j;
|
int reg;
|
int reg;
|
Word data;
|
Word data;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
for (j = 0; j < 4; j++) {
|
for (j = 0; j < 4; j++) {
|
reg = 8 * j + i;
|
reg = 8 * j + i;
|
data = cpuGetReg(reg);
|
data = cpuGetReg(reg);
|
cPrintf("$%-2d %08X ", reg, data);
|
cPrintf("$%-2d %08X ", reg, data);
|
}
|
}
|
cPrintf("\n");
|
cPrintf("\n");
|
}
|
}
|
showPSW();
|
showPSW();
|
showIRQ();
|
showIRQ();
|
showBreakAndTotal();
|
showBreakAndTotal();
|
showPC();
|
showPC();
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) {
|
if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) {
|
cPrintf("illegal register number\n");
|
cPrintf("illegal register number\n");
|
return;
|
return;
|
}
|
}
|
data = cpuGetReg(reg);
|
data = cpuGetReg(reg);
|
cPrintf("$%-2d %08X\n", reg, data);
|
cPrintf("$%-2d %08X\n", reg, data);
|
} else if (n == 3) {
|
} else if (n == 3) {
|
if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) {
|
if (!getDecNumber(tokens[1], ®) || reg < 0 || reg >= 32) {
|
cPrintf("illegal register number\n");
|
cPrintf("illegal register number\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[2], &data)) {
|
if (!getHexNumber(tokens[2], &data)) {
|
cPrintf("illegal data\n");
|
cPrintf("illegal data\n");
|
return;
|
return;
|
}
|
}
|
cpuSetReg(reg, data);
|
cpuSetReg(reg, data);
|
} else {
|
} else {
|
help09();
|
help09();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doDump(char *tokens[], int n) {
|
static void doDump(char *tokens[], int n) {
|
Word addr, count;
|
Word addr, count;
|
Word psw;
|
Word psw;
|
Word lo, hi, curr;
|
Word lo, hi, curr;
|
int lines, i, j;
|
int lines, i, j;
|
Word tmp;
|
Word tmp;
|
Byte c;
|
Byte c;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
addr = cpuGetPC();
|
addr = cpuGetPC();
|
count = 16 * 16;
|
count = 16 * 16;
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
count = 16 * 16;
|
count = 16 * 16;
|
} else if (n == 3) {
|
} else if (n == 3) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[2], &count)) {
|
if (!getHexNumber(tokens[2], &count)) {
|
cPrintf("illegal count\n");
|
cPrintf("illegal count\n");
|
return;
|
return;
|
}
|
}
|
if (count == 0) {
|
if (count == 0) {
|
return;
|
return;
|
}
|
}
|
} else {
|
} else {
|
help10();
|
help10();
|
return;
|
return;
|
}
|
}
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
lo = addr & ~0x0000000F;
|
lo = addr & ~0x0000000F;
|
hi = addr + count - 1;
|
hi = addr + count - 1;
|
if (hi < lo) {
|
if (hi < lo) {
|
/* wrap-around */
|
/* wrap-around */
|
hi = 0xFFFFFFFF;
|
hi = 0xFFFFFFFF;
|
}
|
}
|
lines = (hi - lo + 16) >> 4;
|
lines = (hi - lo + 16) >> 4;
|
curr = lo;
|
curr = lo;
|
for (i = 0; i < lines; i++) {
|
for (i = 0; i < lines; i++) {
|
cPrintf("%08X: ", curr);
|
cPrintf("%08X: ", curr);
|
for (j = 0; j < 16; j++) {
|
for (j = 0; j < 16; j++) {
|
tmp = curr + j;
|
tmp = curr + j;
|
if (tmp < addr || tmp > hi) {
|
if (tmp < addr || tmp > hi) {
|
cPrintf(" ");
|
cPrintf(" ");
|
} else {
|
} else {
|
c = mmuReadByte(tmp, psw & PSW_UM);
|
c = mmuReadByte(tmp, psw & PSW_UM);
|
cPrintf("%02X", c);
|
cPrintf("%02X", c);
|
}
|
}
|
cPrintf(" ");
|
cPrintf(" ");
|
}
|
}
|
cPrintf(" ");
|
cPrintf(" ");
|
for (j = 0; j < 16; j++) {
|
for (j = 0; j < 16; j++) {
|
tmp = curr + j;
|
tmp = curr + j;
|
if (tmp < addr || tmp > hi) {
|
if (tmp < addr || tmp > hi) {
|
cPrintf(" ");
|
cPrintf(" ");
|
} else {
|
} else {
|
c = mmuReadByte(tmp, psw & PSW_UM);
|
c = mmuReadByte(tmp, psw & PSW_UM);
|
if (c >= 32 && c <= 126) {
|
if (c >= 32 && c <= 126) {
|
cPrintf("%c", c);
|
cPrintf("%c", c);
|
} else {
|
} else {
|
cPrintf(".");
|
cPrintf(".");
|
}
|
}
|
}
|
}
|
}
|
}
|
cPrintf("\n");
|
cPrintf("\n");
|
curr += 16;
|
curr += 16;
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doMemoryWord(char *tokens[], int n) {
|
static void doMemoryWord(char *tokens[], int n) {
|
Word psw;
|
Word psw;
|
Word addr;
|
Word addr;
|
Word data;
|
Word data;
|
Word tmpData;
|
Word tmpData;
|
|
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
if (n == 1) {
|
if (n == 1) {
|
addr = cpuGetPC();
|
addr = cpuGetPC();
|
data = mmuReadWord(addr, psw & PSW_UM);
|
data = mmuReadWord(addr, psw & PSW_UM);
|
cPrintf("%08X: %08X\n", addr, data);
|
cPrintf("%08X: %08X\n", addr, data);
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
data = mmuReadWord(addr, psw & PSW_UM);
|
data = mmuReadWord(addr, psw & PSW_UM);
|
cPrintf("%08X: %08X\n", addr, data);
|
cPrintf("%08X: %08X\n", addr, data);
|
} else if (n == 3) {
|
} else if (n == 3) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[2], &tmpData)) {
|
if (!getHexNumber(tokens[2], &tmpData)) {
|
cPrintf("illegal data\n");
|
cPrintf("illegal data\n");
|
return;
|
return;
|
}
|
}
|
data = tmpData;
|
data = tmpData;
|
mmuWriteWord(addr, data, psw & PSW_UM);
|
mmuWriteWord(addr, data, psw & PSW_UM);
|
} else {
|
} else {
|
help11();
|
help11();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doMemoryHalf(char *tokens[], int n) {
|
static void doMemoryHalf(char *tokens[], int n) {
|
Word psw;
|
Word psw;
|
Word addr;
|
Word addr;
|
Half data;
|
Half data;
|
Word tmpData;
|
Word tmpData;
|
|
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
if (n == 1) {
|
if (n == 1) {
|
addr = cpuGetPC();
|
addr = cpuGetPC();
|
data = mmuReadHalf(addr, psw & PSW_UM);
|
data = mmuReadHalf(addr, psw & PSW_UM);
|
cPrintf("%08X: %04X\n", addr, data);
|
cPrintf("%08X: %04X\n", addr, data);
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
data = mmuReadHalf(addr, psw & PSW_UM);
|
data = mmuReadHalf(addr, psw & PSW_UM);
|
cPrintf("%08X: %04X\n", addr, data);
|
cPrintf("%08X: %04X\n", addr, data);
|
} else if (n == 3) {
|
} else if (n == 3) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[2], &tmpData)) {
|
if (!getHexNumber(tokens[2], &tmpData)) {
|
cPrintf("illegal data\n");
|
cPrintf("illegal data\n");
|
return;
|
return;
|
}
|
}
|
data = (Half) tmpData;
|
data = (Half) tmpData;
|
mmuWriteHalf(addr, data, psw & PSW_UM);
|
mmuWriteHalf(addr, data, psw & PSW_UM);
|
} else {
|
} else {
|
help12();
|
help12();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doMemoryByte(char *tokens[], int n) {
|
static void doMemoryByte(char *tokens[], int n) {
|
Word psw;
|
Word psw;
|
Word addr;
|
Word addr;
|
Byte data;
|
Byte data;
|
Word tmpData;
|
Word tmpData;
|
|
|
psw = cpuGetPSW();
|
psw = cpuGetPSW();
|
if (n == 1) {
|
if (n == 1) {
|
addr = cpuGetPC();
|
addr = cpuGetPC();
|
data = mmuReadByte(addr, psw & PSW_UM);
|
data = mmuReadByte(addr, psw & PSW_UM);
|
cPrintf("%08X: %02X\n", addr, data);
|
cPrintf("%08X: %02X\n", addr, data);
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
data = mmuReadByte(addr, psw & PSW_UM);
|
data = mmuReadByte(addr, psw & PSW_UM);
|
cPrintf("%08X: %02X\n", addr, data);
|
cPrintf("%08X: %02X\n", addr, data);
|
} else if (n == 3) {
|
} else if (n == 3) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
if (!getHexNumber(tokens[1], &addr)) {
|
cPrintf("illegal address\n");
|
cPrintf("illegal address\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[2], &tmpData)) {
|
if (!getHexNumber(tokens[2], &tmpData)) {
|
cPrintf("illegal data\n");
|
cPrintf("illegal data\n");
|
return;
|
return;
|
}
|
}
|
data = (Byte) tmpData;
|
data = (Byte) tmpData;
|
mmuWriteByte(addr, data, psw & PSW_UM);
|
mmuWriteByte(addr, data, psw & PSW_UM);
|
} else {
|
} else {
|
help13();
|
help13();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doTLB(char *tokens[], int n) {
|
static void doTLB(char *tokens[], int n) {
|
|
static char *mmuAccsWidth[4] = { "byte", "half", "word", "????" };
|
int index;
|
int index;
|
TLB_Entry tlbEntry;
|
TLB_Entry tlbEntry;
|
|
Word mmuAccs;
|
Word data;
|
Word data;
|
|
|
if (n == 1) {
|
if (n == 1) {
|
for (index = 0; index < TLB_SIZE; index++) {
|
for (index = 0; index < TLB_SIZE; index++) {
|
tlbEntry = mmuGetTLB(index);
|
tlbEntry = mmuGetTLB(index);
|
cPrintf("TLB[%02d] page %08X frame %08X %c %c\n",
|
cPrintf("TLB[%02d] page %08X frame %08X %c %c\n",
|
index, tlbEntry.page, tlbEntry.frame,
|
index, tlbEntry.page, tlbEntry.frame,
|
tlbEntry.write ? 'w' : '-',
|
tlbEntry.write ? 'w' : '-',
|
tlbEntry.valid ? 'v' : '-');
|
tlbEntry.valid ? 'v' : '-');
|
}
|
}
|
cPrintf("Index(1) %08X\n", mmuGetIndex());
|
cPrintf("Index (1) %08X\n", mmuGetIndex());
|
cPrintf("EntryHi(2) %08X\n", mmuGetEntryHi());
|
cPrintf("EntryHi (2) %08X\n", mmuGetEntryHi());
|
cPrintf("EntryLo(3) %08X\n", mmuGetEntryLo());
|
cPrintf("EntryLo (3) %08X\n", mmuGetEntryLo());
|
cPrintf("BadAddr(4) %08X\n", mmuGetBadAddr());
|
cPrintf("BadAddr(4) %08X\n", mmuGetBadAddr());
|
|
mmuAccs = mmuGetBadAccs();
|
|
cPrintf("BadAccs (5) %08X (%s %s)\n",
|
|
mmuAccs,
|
|
(mmuAccs & MMU_ACCS_WRITE) ? "write" : "read",
|
|
mmuAccsWidth[mmuAccs & 0x03]);
|
} else if (n == 2) {
|
} else if (n == 2) {
|
if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) {
|
if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) {
|
cPrintf("illegal TLB index\n");
|
cPrintf("illegal TLB index\n");
|
return;
|
return;
|
}
|
}
|
tlbEntry = mmuGetTLB(index);
|
tlbEntry = mmuGetTLB(index);
|
cPrintf("TLB[%02d] page %08X frame %08X %c %c\n",
|
cPrintf("TLB[%02d] page %08X frame %08X %c %c\n",
|
index, tlbEntry.page, tlbEntry.frame,
|
index, tlbEntry.page, tlbEntry.frame,
|
tlbEntry.write ? 'w' : '-',
|
tlbEntry.write ? 'w' : '-',
|
tlbEntry.valid ? 'v' : '-');
|
tlbEntry.valid ? 'v' : '-');
|
} else if (n == 3) {
|
} else if (n == 3) {
|
help14();
|
help14();
|
} else if (n == 4) {
|
} else if (n == 4) {
|
if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) {
|
if (!getDecNumber(tokens[1], &index) || index < 0 || index >= TLB_SIZE) {
|
cPrintf("illegal TLB index\n");
|
cPrintf("illegal TLB index\n");
|
return;
|
return;
|
}
|
}
|
if (!getHexNumber(tokens[3], &data)) {
|
if (!getHexNumber(tokens[3], &data)) {
|
cPrintf("illegal data\n");
|
cPrintf("illegal data\n");
|
return;
|
return;
|
}
|
}
|
tlbEntry = mmuGetTLB(index);
|
tlbEntry = mmuGetTLB(index);
|
if (strcmp(tokens[2], "p") == 0) {
|
if (strcmp(tokens[2], "p") == 0) {
|
tlbEntry.page = data & PAGE_MASK;
|
tlbEntry.page = data & PAGE_MASK;
|
} else
|
} else
|
if (strcmp(tokens[2], "f") == 0) {
|
if (strcmp(tokens[2], "f") == 0) {
|
tlbEntry.frame = data & PAGE_MASK;
|
tlbEntry.frame = data & PAGE_MASK;
|
tlbEntry.write = data & TLB_WRITE ? true : false;
|
tlbEntry.write = data & TLB_WRITE ? true : false;
|
tlbEntry.valid = data & TLB_VALID ? true : false;
|
tlbEntry.valid = data & TLB_VALID ? true : false;
|
} else {
|
} else {
|
cPrintf("TLB selector is not one of 'p' or 'f'\n");
|
cPrintf("TLB selector is not one of 'p' or 'f'\n");
|
return;
|
return;
|
}
|
}
|
mmuSetTLB(index, tlbEntry);
|
mmuSetTLB(index, tlbEntry);
|
cPrintf("TLB[%02d] page %08X frame %08X %c %c\n",
|
cPrintf("TLB[%02d] page %08X frame %08X %c %c\n",
|
index, tlbEntry.page, tlbEntry.frame,
|
index, tlbEntry.page, tlbEntry.frame,
|
tlbEntry.write ? 'w' : '-',
|
tlbEntry.write ? 'w' : '-',
|
tlbEntry.valid ? 'v' : '-');
|
tlbEntry.valid ? 'v' : '-');
|
} else {
|
} else {
|
help14();
|
help14();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doInit(char *tokens[], int n) {
|
static void doInit(char *tokens[], int n) {
|
if (n == 1) {
|
if (n == 1) {
|
timerReset();
|
timerReset();
|
displayReset();
|
displayReset();
|
keyboardReset();
|
keyboardReset();
|
termReset();
|
termReset();
|
diskReset();
|
diskReset();
|
outputReset();
|
outputReset();
|
shutdownReset();
|
shutdownReset();
|
graphReset();
|
graphReset();
|
memoryReset();
|
memoryReset();
|
mmuReset();
|
mmuReset();
|
cpuReset();
|
cpuReset();
|
} else {
|
} else {
|
help15();
|
help15();
|
}
|
}
|
}
|
}
|
|
|
|
|
static void doQuit(char *tokens[], int n) {
|
static void doQuit(char *tokens[], int n) {
|
if (n == 1) {
|
if (n == 1) {
|
quit = true;
|
quit = true;
|
} else {
|
} else {
|
help16();
|
help16();
|
}
|
}
|
}
|
}
|
|
|
|
|
Command commands[] = {
|
Command commands[] = {
|
{ "help", help00, doHelp },
|
{ "help", help00, doHelp },
|
{ "+", help01, doArith },
|
{ "+", help01, doArith },
|
{ "a", help02, doAssemble },
|
{ "a", help02, doAssemble },
|
{ "u", help03, doUnassemble },
|
{ "u", help03, doUnassemble },
|
{ "b", help04, doBreak },
|
{ "b", help04, doBreak },
|
{ "c", help05, doContinue },
|
{ "c", help05, doContinue },
|
{ "s", help06, doStep },
|
{ "s", help06, doStep },
|
{ "#", help07, doPC },
|
{ "#", help07, doPC },
|
{ "p", help08, doPSW },
|
{ "p", help08, doPSW },
|
{ "r", help09, doRegister },
|
{ "r", help09, doRegister },
|
{ "d", help10, doDump },
|
{ "d", help10, doDump },
|
{ "mw", help11, doMemoryWord },
|
{ "mw", help11, doMemoryWord },
|
{ "mh", help12, doMemoryHalf },
|
{ "mh", help12, doMemoryHalf },
|
{ "mb", help13, doMemoryByte },
|
{ "mb", help13, doMemoryByte },
|
{ "t", help14, doTLB },
|
{ "t", help14, doTLB },
|
{ "i", help15, doInit },
|
{ "i", help15, doInit },
|
{ "q", help16, doQuit },
|
{ "q", help16, doQuit },
|
};
|
};
|
|
|
int numCommands = sizeof(commands) / sizeof(commands[0]);
|
int numCommands = sizeof(commands) / sizeof(commands[0]);
|
|
|
|
|
static Bool doCommand(char *line) {
|
static Bool doCommand(char *line) {
|
char *tokens[MAX_TOKENS];
|
char *tokens[MAX_TOKENS];
|
int n;
|
int n;
|
char *p;
|
char *p;
|
int i;
|
int i;
|
|
|
n = 0;
|
n = 0;
|
p = strtok(line, " \t\n");
|
p = strtok(line, " \t\n");
|
while (p != NULL) {
|
while (p != NULL) {
|
if (n == MAX_TOKENS) {
|
if (n == MAX_TOKENS) {
|
cPrintf("too many tokens on line\n");
|
cPrintf("too many tokens on line\n");
|
return false;
|
return false;
|
}
|
}
|
tokens[n++] = p;
|
tokens[n++] = p;
|
p = strtok(NULL, " \t\n");
|
p = strtok(NULL, " \t\n");
|
}
|
}
|
if (n == 0) {
|
if (n == 0) {
|
return false;
|
return false;
|
}
|
}
|
quit = false;
|
quit = false;
|
for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
|
for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
|
if (strcmp(commands[i].name, tokens[0]) == 0) {
|
if (strcmp(commands[i].name, tokens[0]) == 0) {
|
(*commands[i].cmdProc)(tokens, n);
|
(*commands[i].cmdProc)(tokens, n);
|
return quit;
|
return quit;
|
}
|
}
|
}
|
}
|
help();
|
help();
|
return false;
|
return false;
|
}
|
}
|
|
|
|
|
static char *article(char firstLetterOfNoun) {
|
static char *article(char firstLetterOfNoun) {
|
switch (firstLetterOfNoun) {
|
switch (firstLetterOfNoun) {
|
case 'a':
|
case 'a':
|
case 'e':
|
case 'e':
|
case 'i':
|
case 'i':
|
case 'o':
|
case 'o':
|
case 'u':
|
case 'u':
|
return "An";
|
return "An";
|
default:
|
default:
|
return "A";
|
return "A";
|
}
|
}
|
}
|
}
|
|
|
|
|
static void interactiveException(int exception) {
|
static void interactiveException(int exception) {
|
char *what;
|
char *what;
|
|
|
what = exceptionToString(exception);
|
what = exceptionToString(exception);
|
cPrintf("\n");
|
cPrintf("\n");
|
cPrintf("NOTE: %s %s occurred while executing the command.\n",
|
cPrintf("NOTE: %s %s occurred while executing the command.\n",
|
article(*what), what);
|
article(*what), what);
|
cPrintf(" This event will not alter the state of the CPU.\n");
|
cPrintf(" This event will not alter the state of the CPU.\n");
|
}
|
}
|
|
|
|
|
Bool execCommand(char *line) {
|
Bool execCommand(char *line) {
|
jmp_buf myEnvironment;
|
jmp_buf myEnvironment;
|
int exception;
|
int exception;
|
Bool quit;
|
Bool quit;
|
|
|
exception = setjmp(myEnvironment);
|
exception = setjmp(myEnvironment);
|
if (exception == 0) {
|
if (exception == 0) {
|
/* initialization */
|
/* initialization */
|
pushEnvironment(&myEnvironment);
|
pushEnvironment(&myEnvironment);
|
quit = doCommand(line);
|
quit = doCommand(line);
|
} else {
|
} else {
|
/* an exception was thrown */
|
/* an exception was thrown */
|
interactiveException(exception);
|
interactiveException(exception);
|
quit = false;
|
quit = false;
|
}
|
}
|
popEnvironment();
|
popEnvironment();
|
return quit;
|
return quit;
|
}
|
}
|
|
|