Started implementing the debugger.
This commit is contained in:
152
vm.cpp
152
vm.cpp
@@ -87,24 +87,31 @@ typedef unsigned short word;
|
||||
OP_SLEEP,
|
||||
};*/
|
||||
|
||||
typedef void(*t_extcall)(t_stack&);
|
||||
/*typedef void(*t_extcall)(t_stack&);
|
||||
t_extcall external_calls[MAX_EXTERNAL_CALLS];
|
||||
int numcallbacks = 0;
|
||||
int numcallbacks = 0;*/
|
||||
|
||||
typedef void(*t_out_port)(const byte&);
|
||||
typedef byte(*t_in_port)();
|
||||
t_out_port out_ports[256];
|
||||
t_in_port in_ports[256];
|
||||
static t_out_port out_ports[256];
|
||||
static t_in_port in_ports[256];
|
||||
|
||||
static unsigned char mem[65536];
|
||||
|
||||
static const unsigned char* vm_program = mem;
|
||||
static unsigned char* ds = &mem[0x8800]; // data stack
|
||||
static unsigned char* cs = &mem[0x8900]; // call stack
|
||||
static unsigned short& rX = *(unsigned short*)&mem[0xFFFA];
|
||||
static unsigned char& rY = mem[0xFFFC];
|
||||
static unsigned char& rZ = mem[0xFFFD];
|
||||
static unsigned short& vm_pc = *(unsigned short*)&mem[0xFFFE];
|
||||
|
||||
static int vm_cycles = 0;
|
||||
|
||||
#define PUSH(x, y) x[++x[0]] = y
|
||||
#define POP(x) (x[x[0]--])
|
||||
#define PEEK(x) (x[x[0]])
|
||||
|
||||
unsigned char mem[65536];
|
||||
const unsigned char* vm_program = mem;
|
||||
int vm_pc = 2;
|
||||
int vm_cycles = 0;
|
||||
t_stack vm_datastack;
|
||||
t_stack vm_callstack;
|
||||
unsigned short rX = 0;
|
||||
unsigned char rY = 0;
|
||||
unsigned char rZ = 0;
|
||||
bool sleeping = false;
|
||||
|
||||
|
||||
@@ -146,12 +153,7 @@ static void load_program(const char* filename) {
|
||||
}
|
||||
|
||||
void vm_init(const char* filename) {
|
||||
vm_pc = 2; rX = rY = rZ = 0;
|
||||
vm_datastack.data = &mem[0x8800];
|
||||
vm_callstack.data = &mem[0x8900];
|
||||
vm_datastack.top = vm_callstack.top = 0;
|
||||
vm_datastack.max = MAX_DATA_STACK;
|
||||
vm_callstack.max = MAX_CALL_STACK;
|
||||
vm_pc = 2; rX = rY = rZ = 0; ds[0] = cs[0] = 0;
|
||||
load_rom();
|
||||
load_program(filename);
|
||||
}
|
||||
@@ -167,21 +169,21 @@ const int vm_step() {
|
||||
switch (opcode) {
|
||||
|
||||
case OP_NOP: vm_cycles++; break;
|
||||
case OP_PUSH: stack_push(vm_datastack, vm_program[vm_pc++]); vm_cycles++; break;
|
||||
case OP_POP: stack_pop(vm_datastack); vm_cycles++; break;
|
||||
case OP_DUP: stack_push(vm_datastack, stack_peek(vm_datastack)); vm_cycles++; break;
|
||||
case OP_SWAP: val = stack_pop(vm_datastack); val2 = stack_pop(vm_datastack); stack_push(vm_datastack, val); stack_push(vm_datastack, val2); vm_cycles++; break;
|
||||
case OP_LOAD: stack_push(vm_datastack, mem[WORD()]); vm_cycles++; break;
|
||||
case OP_LOADI: stack_push(vm_datastack, mem[WORD() + rY]); vm_cycles++; break;
|
||||
case OP_STORE: mem[WORD()] = stack_pop(vm_datastack); vm_cycles++; break;
|
||||
case OP_STOREI: val = stack_pop(vm_datastack); mem[WORD() + rY] = val; vm_cycles++; break;
|
||||
case OP_LOADXY: stack_push(vm_datastack, mem[rX + rY]); vm_cycles++; break;
|
||||
case OP_STOREXY: mem[rX + rY] = stack_pop(vm_datastack); vm_cycles++; break;
|
||||
case OP_PUSH: PUSH(ds, vm_program[vm_pc++]); vm_cycles++; break;
|
||||
case OP_POP: POP(ds); vm_cycles++; break;
|
||||
case OP_DUP: PUSH(ds, PEEK(ds)); vm_cycles++; break;
|
||||
case OP_SWAP: val = POP(ds); val2 = POP(ds); PUSH(ds, val); PUSH(ds, val2); vm_cycles++; break;
|
||||
case OP_LOAD: PUSH(ds, mem[WORD()]); vm_cycles++; break;
|
||||
case OP_LOADI: PUSH(ds, mem[WORD() + rY]); vm_cycles++; break;
|
||||
case OP_STORE: mem[WORD()] = POP(ds); vm_cycles++; break;
|
||||
case OP_STOREI: val = POP(ds); mem[WORD() + rY] = val; vm_cycles++; break;
|
||||
case OP_LOADXY: PUSH(ds, mem[rX + rY]); vm_cycles++; break;
|
||||
case OP_STOREXY: mem[rX + rY] = POP(ds); vm_cycles++; break;
|
||||
case OP_SETX: rX = WORD(); vm_cycles++; break;
|
||||
case OP_SETY: rY = stack_pop(vm_datastack); vm_cycles++; break;
|
||||
case OP_SETZ: rZ = stack_pop(vm_datastack); vm_cycles++; break;
|
||||
case OP_GETY: stack_push(vm_datastack, rY); vm_cycles++; break;
|
||||
case OP_GETZ: stack_push(vm_datastack, rZ); vm_cycles++; break;
|
||||
case OP_SETY: rY = POP(ds); vm_cycles++; break;
|
||||
case OP_SETZ: rZ = POP(ds); vm_cycles++; break;
|
||||
case OP_GETY: PUSH(ds, rY); vm_cycles++; break;
|
||||
case OP_GETZ: PUSH(ds, rZ); vm_cycles++; break;
|
||||
case OP_INCX: rX++; vm_cycles++; break;
|
||||
case OP_DECX: rX--; vm_cycles++; break;
|
||||
case OP_INCY: rY++; vm_cycles++; break;
|
||||
@@ -189,17 +191,17 @@ const int vm_step() {
|
||||
case OP_INCZ: rZ++; vm_cycles++; break;
|
||||
case OP_DECZ: rZ--; vm_cycles++; break;
|
||||
case OP_JMP: vm_pc = WORD(); vm_cycles++; break;
|
||||
case OP_JNT: if (stack_pop(vm_datastack) == 0) { vm_pc = WORD(); } else vm_pc+=2; vm_cycles++; break;
|
||||
case OP_JTR: if (stack_pop(vm_datastack) != 0) { vm_pc = WORD(); } else vm_pc+=2; vm_cycles++; break;
|
||||
case OP_JSR: stack_push(vm_callstack, vm_pc + 2); stack_push(vm_callstack, rX & 255); stack_push(vm_callstack, rX >> 8); stack_push(vm_callstack, rY); stack_push(vm_callstack, rZ); vm_pc = WORD(); vm_cycles++; break;
|
||||
case OP_RET: rZ = stack_pop(vm_callstack); rY = stack_pop(vm_callstack); rX = (stack_pop(vm_callstack) << 8) + stack_pop(vm_callstack); vm_pc = stack_pop(vm_callstack); vm_cycles++; break;
|
||||
case OP_CALL: external_calls[vm_program[vm_pc++]](vm_datastack); vm_cycles++; break;
|
||||
case OP_JNT: if (POP(ds) == 0) { vm_pc = WORD(); } else vm_pc+=2; vm_cycles++; break;
|
||||
case OP_JTR: if (POP(ds) != 0) { vm_pc = WORD(); } else vm_pc+=2; vm_cycles++; break;
|
||||
case OP_JSR: PUSH(cs, vm_pc + 2); PUSH(cs, rX & 255); PUSH(cs, rX >> 8); PUSH(cs, rY); PUSH(cs, rZ); vm_pc = WORD(); vm_cycles++; break;
|
||||
case OP_RET: rZ = POP(cs); rY = POP(cs); rX = (POP(cs) << 8) + POP(cs); vm_pc = POP(cs); vm_cycles++; break;
|
||||
case OP_CALL: /*external_calls[vm_program[vm_pc++]](vm_datastack); vm_cycles++;*/ break;
|
||||
case OP_RJ: vm_pc += vm_program[vm_pc]; vm_cycles++; break;
|
||||
case OP_RB: vm_pc -= vm_program[vm_pc]+1; vm_cycles++; break;
|
||||
case OP_RJZ: if (stack_pop(vm_datastack) == 0) vm_pc += vm_program[vm_pc]; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RJN: if (stack_pop(vm_datastack) != 0) vm_pc += vm_program[vm_pc]; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RBZ: if (stack_pop(vm_datastack) == 0) vm_pc -= vm_program[vm_pc] + 1; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RBN: if (stack_pop(vm_datastack) != 0) vm_pc -= vm_program[vm_pc] + 1; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RJZ: if (POP(ds) == 0) vm_pc += vm_program[vm_pc]; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RJN: if (POP(ds) != 0) vm_pc += vm_program[vm_pc]; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RBZ: if (POP(ds) == 0) vm_pc -= vm_program[vm_pc] + 1; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RBN: if (POP(ds) != 0) vm_pc -= vm_program[vm_pc] + 1; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RJYZ: if (rY == 0) vm_pc += vm_program[vm_pc]; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RJYN: if (rY != 0) vm_pc += vm_program[vm_pc]; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RBYZ: if (rY == 0) vm_pc -= vm_program[vm_pc] + 1; else vm_pc++; vm_cycles++; break;
|
||||
@@ -208,40 +210,40 @@ const int vm_step() {
|
||||
case OP_RJZN: if (rZ != 0) vm_pc += vm_program[vm_pc]; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RBZZ: if (rZ == 0) vm_pc -= vm_program[vm_pc] + 1; else vm_pc++; vm_cycles++; break;
|
||||
case OP_RBZN: if (rZ != 0) vm_pc -= vm_program[vm_pc] + 1; else vm_pc++; vm_cycles++; break;
|
||||
case OP_ADD: stack_push(vm_datastack, stack_pop(vm_datastack) + stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_SUB: stack_push(vm_datastack, stack_pop(vm_datastack) - stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_MUL: stack_push(vm_datastack, stack_pop(vm_datastack) * stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_DIV: stack_push(vm_datastack, stack_pop(vm_datastack) / stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_MOD: stack_push(vm_datastack, stack_pop(vm_datastack) % stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_AND: stack_push(vm_datastack, stack_pop(vm_datastack) & stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_OR: stack_push(vm_datastack, stack_pop(vm_datastack) | stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_NOT: stack_push(vm_datastack, !stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_NEG: stack_push(vm_datastack, -stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_INC: stack_push(vm_datastack, stack_pop(vm_datastack)+1); vm_cycles++; break;
|
||||
case OP_DEC: stack_push(vm_datastack, stack_pop(vm_datastack) - 1); vm_cycles++; break;
|
||||
case OP_ADD: PUSH(ds, POP(ds) + POP(ds)); vm_cycles++; break;
|
||||
case OP_SUB: PUSH(ds, POP(ds) - POP(ds)); vm_cycles++; break;
|
||||
case OP_MUL: PUSH(ds, POP(ds) * POP(ds)); vm_cycles++; break;
|
||||
case OP_DIV: PUSH(ds, POP(ds) / POP(ds)); vm_cycles++; break;
|
||||
case OP_MOD: PUSH(ds, POP(ds) % POP(ds)); vm_cycles++; break;
|
||||
case OP_AND: PUSH(ds, POP(ds) & POP(ds)); vm_cycles++; break;
|
||||
case OP_OR: PUSH(ds, POP(ds) | POP(ds)); vm_cycles++; break;
|
||||
case OP_NOT: PUSH(ds, !POP(ds)); vm_cycles++; break;
|
||||
case OP_NEG: PUSH(ds, -POP(ds)); vm_cycles++; break;
|
||||
case OP_INC: PUSH(ds, POP(ds) + 1); vm_cycles++; break;
|
||||
case OP_DEC: PUSH(ds, POP(ds) - 1); vm_cycles++; break;
|
||||
case OP_CONCAT:
|
||||
val = stack_pop(vm_datastack);
|
||||
for (int i = 0; i < val; i++) stack_push(vm_callstack, stack_pop(vm_datastack));
|
||||
val2 = stack_pop(vm_datastack);
|
||||
for (int i = 0; i < val; i++) stack_push(vm_datastack, stack_pop(vm_callstack));
|
||||
stack_push(vm_datastack, val + val2);
|
||||
val = POP(ds);
|
||||
for (int i = 0; i < val; i++) PUSH(cs, POP(ds));
|
||||
val2 = POP(ds);
|
||||
for (int i = 0; i < val; i++) PUSH(ds, POP(cs));
|
||||
PUSH(ds, val + val2);
|
||||
vm_cycles++; break;
|
||||
case OP_EQ: stack_push(vm_datastack, stack_pop(vm_datastack) == stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_NEQ: stack_push(vm_datastack, stack_pop(vm_datastack) != stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_LT: stack_push(vm_datastack, stack_pop(vm_datastack) < stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_GT: stack_push(vm_datastack, stack_pop(vm_datastack) > stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_LEQ: stack_push(vm_datastack, stack_pop(vm_datastack) <= stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_GEQ: stack_push(vm_datastack, stack_pop(vm_datastack) >= stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_IN: stack_push(vm_datastack, in_ports[vm_program[vm_pc++]]()); vm_cycles++; break;
|
||||
case OP_OUT: out_ports[vm_program[vm_pc++]](stack_pop(vm_datastack)); vm_cycles++; break;
|
||||
case OP_SLEEP: SDL_Delay(stack_pop(vm_datastack) * 1000); vm_cycles++; break;
|
||||
case OP_EQ: PUSH(ds, POP(ds) == POP(ds)); vm_cycles++; break;
|
||||
case OP_NEQ: PUSH(ds, POP(ds) != POP(ds)); vm_cycles++; break;
|
||||
case OP_LT: PUSH(ds, POP(ds) < POP(ds)); vm_cycles++; break;
|
||||
case OP_GT: PUSH(ds, POP(ds) > POP(ds)); vm_cycles++; break;
|
||||
case OP_LEQ: PUSH(ds, POP(ds) <= POP(ds)); vm_cycles++; break;
|
||||
case OP_GEQ: PUSH(ds, POP(ds) >= POP(ds)); vm_cycles++; break;
|
||||
case OP_IN: PUSH(ds, in_ports[vm_program[vm_pc++]]()); vm_cycles++; break;
|
||||
case OP_OUT: out_ports[vm_program[vm_pc++]](POP(ds)); vm_cycles++; break;
|
||||
case OP_SLEEP: SDL_Delay(POP(ds) * 1000); vm_cycles++; break;
|
||||
}
|
||||
return vm_cycles;
|
||||
}
|
||||
|
||||
void vm_register_call(void(*callback)(t_stack&)) {
|
||||
/*void vm_register_call(void(*callback)(t_stack&)) {
|
||||
external_calls[numcallbacks++] = callback;
|
||||
}
|
||||
}*/
|
||||
|
||||
void vm_register_in_port(const byte port, t_in_port callback) {
|
||||
in_ports[port] = callback;
|
||||
@@ -253,11 +255,13 @@ void vm_register_out_port(const byte port, t_out_port callback) {
|
||||
|
||||
void vm_call_interrupt(const char num) {
|
||||
sleeping = false;
|
||||
stack_push(vm_callstack, vm_pc);
|
||||
stack_push(vm_callstack, rX & 255);
|
||||
stack_push(vm_callstack, rX >> 8);
|
||||
stack_push(vm_callstack, rY);
|
||||
stack_push(vm_callstack, rZ);
|
||||
PUSH(cs, vm_pc);
|
||||
PUSH(cs, rX & 255);
|
||||
PUSH(cs, rX >> 8);
|
||||
PUSH(cs, rY);
|
||||
PUSH(cs, rZ);
|
||||
vm_pc = num == 0 ? 0xFFFA : 0xFFFD;
|
||||
vm_cycles++;
|
||||
}
|
||||
|
||||
unsigned char* vm_get_memory() { return mem; }
|
||||
|
||||
Reference in New Issue
Block a user