Implemented all opcodes, including LOADI and STOREI
This commit is contained in:
34
.hgignore
34
.hgignore
@@ -1,16 +1,18 @@
|
|||||||
syntax: glob
|
syntax: glob
|
||||||
|
|
||||||
aee
|
aee
|
||||||
recursos/*
|
recursos/*
|
||||||
bin/*
|
bin/*
|
||||||
obj/*
|
obj/*
|
||||||
Debug/*
|
Debug/*
|
||||||
Release/*
|
Release/*
|
||||||
data/*
|
data/*
|
||||||
*.suo
|
*.suo
|
||||||
*.sdf
|
*.sdf
|
||||||
*.opensdf
|
*.opensdf
|
||||||
*.user
|
*.user
|
||||||
*.dll
|
*.dll
|
||||||
.DS_Store
|
.DS_Store
|
||||||
trick.ini
|
trick.ini
|
||||||
|
*.bin
|
||||||
|
|
||||||
|
|||||||
5
main.cpp
5
main.cpp
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
int i = 10;
|
int i = 1;
|
||||||
int x = i++ + (i++ + 1);
|
char a[4] = { 1, 2, 3, 4 };
|
||||||
|
int x = a[i++] + a[i++];
|
||||||
// aci, i == 12 ; x == 21
|
// aci, i == 12 ; x == 21
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
t_stack stack_new(const int size) {
|
void stack_init(t_stack& stack, const int size) {
|
||||||
t_stack stack;
|
if (stack.data != nullptr) free(stack.data);
|
||||||
|
stack.data = (unsigned char*)malloc(size);
|
||||||
stack.max = size;
|
stack.max = size;
|
||||||
stack.top = -1;
|
stack.top = -1;
|
||||||
stack.data = (unsigned char*)malloc(size);
|
|
||||||
return stack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool stack_isempty(t_stack& stack) {
|
const bool stack_isempty(t_stack& stack) {
|
||||||
|
|||||||
2
stack.h
2
stack.h
@@ -6,7 +6,7 @@ struct t_stack {
|
|||||||
int max{ 0 };
|
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_isempty(t_stack& stack);
|
||||||
const bool stack_isfull(t_stack& stack);
|
const bool stack_isfull(t_stack& stack);
|
||||||
void stack_push(t_stack& stack, const char value);
|
void stack_push(t_stack& stack, const char value);
|
||||||
|
|||||||
53
vm.cpp
53
vm.cpp
@@ -11,7 +11,9 @@ enum OPS {
|
|||||||
OP_DUP,
|
OP_DUP,
|
||||||
|
|
||||||
OP_LOAD,
|
OP_LOAD,
|
||||||
|
OP_LOADI,
|
||||||
OP_STORE,
|
OP_STORE,
|
||||||
|
OP_STOREI,
|
||||||
|
|
||||||
OP_JMP,
|
OP_JMP,
|
||||||
OP_JNT,
|
OP_JNT,
|
||||||
@@ -46,43 +48,48 @@ int vm_pc = 0;
|
|||||||
int vm_cycles = 0;
|
int vm_cycles = 0;
|
||||||
t_stack vm_datastack;
|
t_stack vm_datastack;
|
||||||
t_stack vm_callstack;
|
t_stack vm_callstack;
|
||||||
|
unsigned char mem[65536];
|
||||||
|
|
||||||
void vm_init(const unsigned char* program) {
|
void vm_init(const unsigned char* program) {
|
||||||
vm_program = program;
|
vm_program = program;
|
||||||
vm_pc = 0;
|
vm_pc = 0;
|
||||||
vm_datastack = stack_new(MAX_DATA_STACK);
|
stack_init(vm_datastack, MAX_DATA_STACK);
|
||||||
vm_callstack = stack_new(MAX_CALL_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() {
|
void vm_step() {
|
||||||
|
char val;
|
||||||
switch (vm_program[vm_pc++]) {
|
switch (vm_program[vm_pc++]) {
|
||||||
case OP_NOP: vm_cycles++; break;
|
case OP_NOP: vm_cycles++; break;
|
||||||
case OP_PUSH: stack_push(vm_datastack, vm_program[vm_pc++]); 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_POP: stack_pop(vm_datastack); vm_cycles++; break;
|
||||||
case OP_DUP: stack_push(vm_datastack, stack_peek(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_LOAD: stack_push(vm_datastack, mem[WORD()]); vm_cycles++; break;
|
||||||
case OP_STORE: vm_cycles++; break;
|
case OP_LOADI: stack_push(vm_datastack, mem[WORD() + stack_pop(vm_datastack)]); vm_cycles++; break;
|
||||||
case OP_JMP: vm_pc = vm_program[vm_pc] + (vm_program[vm_pc + 1] << 8); vm_cycles++; break;
|
case OP_STORE: mem[WORD()] = stack_pop(vm_datastack); vm_cycles++; break;
|
||||||
case OP_JNT: vm_cycles++; break;
|
case OP_STOREI: val = stack_pop(vm_datastack); mem[WORD() + stack_pop(vm_datastack)] = val; vm_cycles++; break;
|
||||||
case OP_JTR: vm_cycles++; break;
|
case OP_JMP: vm_pc = WORD(); vm_cycles++; break;
|
||||||
case OP_JSR: vm_cycles++; break;
|
case OP_JNT: if (stack_pop(vm_datastack) == 0) { vm_pc = WORD(); } vm_cycles++; break;
|
||||||
case OP_RET: 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_CALL: external_calls[vm_program[vm_pc++]](vm_datastack); vm_cycles++; break;
|
||||||
case OP_ADD: vm_cycles++; break;
|
case OP_ADD: stack_push(vm_datastack, stack_pop(vm_datastack) + stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_SUB: vm_cycles++; break;
|
case OP_SUB: stack_push(vm_datastack, stack_pop(vm_datastack) - stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_MUL: vm_cycles++; break;
|
case OP_MUL: stack_push(vm_datastack, stack_pop(vm_datastack) * stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_DIV: vm_cycles++; break;
|
case OP_DIV: stack_push(vm_datastack, stack_pop(vm_datastack) / stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_MOD: vm_cycles++; break;
|
case OP_MOD: stack_push(vm_datastack, stack_pop(vm_datastack) % stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_AND: vm_cycles++; break;
|
case OP_AND: stack_push(vm_datastack, stack_pop(vm_datastack) & stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_OR: vm_cycles++; break;
|
case OP_OR: stack_push(vm_datastack, stack_pop(vm_datastack) | stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_NOT: vm_cycles++; break;
|
case OP_NOT: stack_push(vm_datastack, !stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_NEG: vm_cycles++; break;
|
case OP_NEG: stack_push(vm_datastack, -stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_INC: vm_cycles++; break;
|
case OP_INC: stack_push(vm_datastack, stack_pop(vm_datastack)+1); vm_cycles++; break;
|
||||||
case OP_EQ: vm_cycles++; break;
|
case OP_EQ: stack_push(vm_datastack, stack_pop(vm_datastack) == stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_NEQ: vm_cycles++; break;
|
case OP_NEQ: stack_push(vm_datastack, stack_pop(vm_datastack) != stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_LT: vm_cycles++; break;
|
case OP_LT: stack_push(vm_datastack, stack_pop(vm_datastack) < stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
case OP_GT: vm_cycles++; break;
|
case OP_GT: stack_push(vm_datastack, stack_pop(vm_datastack) > stack_pop(vm_datastack)); vm_cycles++; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user