Corrected STOREI and LOADI to use rY. Implemented DEC, LEQ and GEQ opcodes. Implemented LOADXY, STOREXY, SETX, SETY, SETZ, INCX, DECX, INCY, DECY, INCZ and DECZ opcodes. Implemented RJYZ, RJYN, RBYZ, RBYN, RJZZ, RJZN, RBZZ and RBZN opcodes.

This commit is contained in:
2017-01-25 18:39:48 +01:00
parent 499b0539d3
commit 8d749ea633

58
vm.cpp
View File

@@ -15,6 +15,18 @@ enum OPS {
OP_STORE,
OP_STOREI,
OP_LOADXY,
OP_STOREXY,
OP_SETX,
OP_SETY,
OP_SETZ,
OP_INCX,
OP_DECX,
OP_INCY,
OP_DECY,
OP_INCZ,
OP_DECZ,
OP_JMP,
OP_JNT,
OP_JTR,
@@ -22,6 +34,15 @@ enum OPS {
OP_RET,
OP_CALL,
OP_RJYZ,
OP_RJYN,
OP_RBYZ,
OP_RBYN,
OP_RJZZ,
OP_RJZN,
OP_RBZZ,
OP_RBZN,
OP_ADD,
OP_SUB,
OP_MUL,
@@ -32,11 +53,14 @@ enum OPS {
OP_NOT,
OP_NEG,
OP_INC,
OP_DEC,
OP_EQ,
OP_NEQ,
OP_LT,
OP_GT
OP_GT,
OP_LEQ,
OP_GEQ,
};
typedef void(*t_extcall)(t_stack&);
@@ -49,10 +73,14 @@ int vm_cycles = 0;
t_stack vm_datastack;
t_stack vm_callstack;
unsigned char mem[65536];
unsigned short rX = 0;
unsigned char rY = 0;
unsigned char rZ = 0;
void vm_init(const unsigned char* program) {
vm_program = program;
vm_pc = 0;
vm_pc = rX = rY = rZ = 0;
stack_init(vm_datastack, MAX_DATA_STACK);
stack_init(vm_callstack, MAX_CALL_STACK);
}
@@ -67,15 +95,34 @@ void vm_step() {
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_LOAD: stack_push(vm_datastack, mem[WORD()]); vm_cycles++; break;
case OP_LOADI: stack_push(vm_datastack, mem[WORD() + stack_pop(vm_datastack)]); 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() + stack_pop(vm_datastack)] = val; 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_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_INCX: rX++; vm_cycles++; break;
case OP_DECX: rX--; vm_cycles++; break;
case OP_INCY: rY++; vm_cycles++; break;
case OP_DECY: rY--; vm_cycles++; break;
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(); } vm_cycles++; break;
case OP_JTR: if (stack_pop(vm_datastack) != 0) { vm_pc = WORD(); } vm_cycles++; break;
case OP_JSR: stack_push(vm_callstack, vm_pc+2); vm_pc = WORD(); vm_cycles++; break;
case OP_RET: 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_RJYZ: if (rY == 0) vm_pc += vm_program[vm_pc]; vm_cycles++; break;
case OP_RJYN: if (rY != 0) vm_pc += vm_program[vm_pc]; vm_cycles++; break;
case OP_RBYZ: if (rY == 0) vm_pc -= vm_program[vm_pc]; vm_cycles++; break;
case OP_RBYN: if (rY != 0) vm_pc -= vm_program[vm_pc]; vm_cycles++; break;
case OP_RJZZ: if (rZ == 0) vm_pc += vm_program[vm_pc]; vm_cycles++; break;
case OP_RJZN: if (rZ != 0) vm_pc += vm_program[vm_pc]; vm_cycles++; break;
case OP_RBZZ: if (rZ == 0) vm_pc -= vm_program[vm_pc]; vm_cycles++; break;
case OP_RBZN: if (rZ != 0) vm_pc -= vm_program[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;
@@ -86,10 +133,13 @@ void vm_step() {
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_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;
}
}