From 8d749ea633cff026e69b4ba227b534e7c0772ce1 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Wed, 25 Jan 2017 18:39:48 +0100 Subject: [PATCH] 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. --- vm.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/vm.cpp b/vm.cpp index c98122a..81c2d77 100644 --- a/vm.cpp +++ b/vm.cpp @@ -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; } }