From 499b0539d313ae3a25e5ae07578ee021ee55533c Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Tue, 24 Jan 2017 19:47:19 +0100 Subject: [PATCH] Implemented all opcodes, including LOADI and STOREI --- .hgignore | 34 ++++++++++++++++++---------------- main.cpp | 5 +++-- stack.cpp | 7 +++---- stack.h | 2 +- vm.cpp | 53 ++++++++++++++++++++++++++++++----------------------- 5 files changed, 55 insertions(+), 46 deletions(-) diff --git a/.hgignore b/.hgignore index 1de44aa..8bef208 100644 --- a/.hgignore +++ b/.hgignore @@ -1,16 +1,18 @@ -syntax: glob - -aee -recursos/* -bin/* -obj/* -Debug/* -Release/* -data/* -*.suo -*.sdf -*.opensdf -*.user -*.dll -.DS_Store -trick.ini \ No newline at end of file +syntax: glob + +aee +recursos/* +bin/* +obj/* +Debug/* +Release/* +data/* +*.suo +*.sdf +*.opensdf +*.user +*.dll +.DS_Store +trick.ini +*.bin + diff --git a/main.cpp b/main.cpp index 5eeb685..e4392fe 100644 --- a/main.cpp +++ b/main.cpp @@ -3,8 +3,9 @@ int main(int argc, char** argv) { - int i = 10; - int x = i++ + (i++ + 1); + int i = 1; + char a[4] = { 1, 2, 3, 4 }; + int x = a[i++] + a[i++]; // aci, i == 12 ; x == 21 return 0; } \ No newline at end of file diff --git a/stack.cpp b/stack.cpp index 75104ea..91cf184 100644 --- a/stack.cpp +++ b/stack.cpp @@ -1,12 +1,11 @@ #include "stack.h" #include -t_stack stack_new(const int size) { - t_stack stack; +void stack_init(t_stack& stack, const int size) { + if (stack.data != nullptr) free(stack.data); + stack.data = (unsigned char*)malloc(size); stack.max = size; stack.top = -1; - stack.data = (unsigned char*)malloc(size); - return stack; } const bool stack_isempty(t_stack& stack) { diff --git a/stack.h b/stack.h index 65b5500..f2e2a87 100644 --- a/stack.h +++ b/stack.h @@ -6,7 +6,7 @@ struct t_stack { int max{ 0 }; }; -t_stack stack_new(const int size); +void stack_init(t_stack& stack, const int size); const bool stack_isempty(t_stack& stack); const bool stack_isfull(t_stack& stack); void stack_push(t_stack& stack, const char value); diff --git a/vm.cpp b/vm.cpp index 34cf394..c98122a 100644 --- a/vm.cpp +++ b/vm.cpp @@ -11,7 +11,9 @@ enum OPS { OP_DUP, OP_LOAD, + OP_LOADI, OP_STORE, + OP_STOREI, OP_JMP, OP_JNT, @@ -46,43 +48,48 @@ int vm_pc = 0; int vm_cycles = 0; t_stack vm_datastack; t_stack vm_callstack; +unsigned char mem[65536]; void vm_init(const unsigned char* program) { vm_program = program; vm_pc = 0; - vm_datastack = stack_new(MAX_DATA_STACK); - vm_callstack = stack_new(MAX_CALL_STACK); + stack_init(vm_datastack, MAX_DATA_STACK); + stack_init(vm_callstack, MAX_CALL_STACK); } +inline unsigned short WORD() { vm_pc += 2; return vm_program[vm_pc - 2] + (vm_program[vm_pc - 1] << 8); } void vm_step() { + char val; switch (vm_program[vm_pc++]) { 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_LOAD: vm_cycles++; break; - case OP_STORE: vm_cycles++; break; - case OP_JMP: vm_pc = vm_program[vm_pc] + (vm_program[vm_pc + 1] << 8); vm_cycles++; break; - case OP_JNT: vm_cycles++; break; - case OP_JTR: vm_cycles++; break; - case OP_JSR: vm_cycles++; break; - case OP_RET: 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_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_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_ADD: vm_cycles++; break; - case OP_SUB: vm_cycles++; break; - case OP_MUL: vm_cycles++; break; - case OP_DIV: vm_cycles++; break; - case OP_MOD: vm_cycles++; break; - case OP_AND: vm_cycles++; break; - case OP_OR: vm_cycles++; break; - case OP_NOT: vm_cycles++; break; - case OP_NEG: vm_cycles++; break; - case OP_INC: vm_cycles++; break; - case OP_EQ: vm_cycles++; break; - case OP_NEQ: vm_cycles++; break; - case OP_LT: vm_cycles++; break; - case OP_GT: 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_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; } }