diff --git a/cpu.c b/cpu.c index 64c4473..a04e1f6 100644 --- a/cpu.c +++ b/cpu.c @@ -239,149 +239,211 @@ uint16_t fetch() return value; } + +void decode_instruction(uint16_t opcode, uint16_t *arg1, uint16_t *arg2, uint16_t *arg3) +{ + switch(opcode) + { + case HALT: + break; + case MOV: + *arg1 = fetch(); + *arg2 = fetch(); + break; + case PUSH: + *arg1 = fetch(); + break; + case POP: + *arg1 = fetch(); + break; + case TEQ: + *arg1 = fetch(); + *arg2 = fetch(); + *arg3 = fetch(); + break; + case TGT: + *arg1 = fetch(); + *arg2 = fetch(); + *arg3 = fetch(); + break; + case JMP: + *arg1 = fetch(); + break; + case JNZ: + *arg1 = fetch(); + *arg2 = fetch(); + break; + case JZ: + *arg1 = fetch(); + *arg2 = fetch(); + break; + case ADD: + *arg1 = fetch(); + *arg2 = fetch(); + *arg3 = fetch(); + break; + case MUL: + *arg1 = fetch(); + *arg2 = fetch(); + *arg3 = fetch(); + break; + case MOD: + *arg1 = fetch(); + *arg2 = fetch(); + *arg3 = fetch(); + break; + case AND: + *arg1 = fetch(); + *arg2 = fetch(); + *arg3 = fetch(); + break; + case OR: + *arg1 = fetch(); + *arg2 = fetch(); + *arg3 = fetch(); + break; + case NOT: + *arg1 = fetch(); + *arg2 = fetch(); + break; + case LOAD: + *arg1 = fetch(); + *arg2 = fetch(); + break; + case STOR: + *arg1 = fetch(); + *arg2 = fetch(); + break; + case CALL: + *arg1 = fetch(); + break; + case RET: + break; + case OUT: + *arg1 = fetch(); + break; + case IN: + *arg1 = fetch(); + break; + case NOP: + break; + default: + break; + } +} + +uint8_t execute_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3) +{ + switch(opcode) + { + case HALT: + return 1; + case MOV: + mov(arg1,arg2); + break; + case PUSH: + push(arg1); + break; + case POP: + pop(arg1); + break; + case TEQ: + teq(arg1,arg2,arg3); + break; + case TGT: + tgt(arg1,arg2,arg3); + break; + case JMP: + jmp(arg1); + break; + case JNZ: + jnz(arg1,arg2); + break; + case JZ: + jz(arg1,arg2); + break; + case ADD: + add(arg1,arg2,arg3); + break; + case MUL: + mul(arg1,arg2,arg3); + break; + case MOD: + mod(arg1,arg2,arg3); + break; + case AND: + and(arg1,arg2,arg3); + break; + case OR: + or(arg1,arg2,arg3); + break; + case NOT: + not(arg1,arg2); + break; + case LOAD: + load(arg1,arg2); + break; + case STOR: + stor(arg1,arg2); + break; + case CALL: + call(arg1); + break; + case RET: + if(ret()) + { + return 1; + } + break; + case OUT: + out(arg1); + break; + case IN: + in(arg1); + break; + case NOP: + nop(); + break; + default: + fprintf(stderr,"CRITICAL: UNKNOWN OPCODE %2x FOUND IN %2x\n",opcode,pc); + core_dump(); + break; + } + return 0; +} + void start_execution() { uint16_t arg1; uint16_t arg2; uint16_t arg3; + for(;;) { uint16_t opcode = fetch(); - switch(opcode) + decode_instruction(opcode, &arg1, &arg2, &arg3); + if(execute_instruction(opcode, arg1, arg2, arg3)) { - case HALT: - return; - case MOV: - arg1 = fetch(); - arg2 = fetch(); - mov(arg1,arg2); - break; - case PUSH: - arg1 = fetch(); - push(arg1); - break; - case POP: - arg1 = fetch(); - pop(arg1); - break; - case TEQ: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - teq(arg1,arg2,arg3); - break; - case TGT: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - tgt(arg1,arg2,arg3); - break; - case JMP: - arg1 = fetch(); - jmp(arg1); - break; - case JNZ: - arg1 = fetch(); - arg2 = fetch(); - jnz(arg1,arg2); - break; - case JZ: - arg1 = fetch(); - arg2 = fetch(); - jz(arg1,arg2); - break; - case ADD: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - add(arg1,arg2,arg3); - break; - case MUL: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - mul(arg1,arg2,arg3); - break; - case MOD: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - mod(arg1,arg2,arg3); - break; - case AND: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - and(arg1,arg2,arg3); - break; - case OR: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - or(arg1,arg2,arg3); - break; - case NOT: - arg1 = fetch(); - arg2 = fetch(); - not(arg1,arg2); - break; - case LOAD: - arg1 = fetch(); - arg2 = fetch(); - load(arg1,arg2); - break; - case STOR: - arg1 = fetch(); - arg2 = fetch(); - stor(arg1,arg2); - break; - case CALL: - arg1 = fetch(); - call(arg1); - break; - case RET: - if(ret()) - { - return; - } - break; - case OUT: - arg1 = fetch(); - out(arg1); - break; - case IN: - arg1 = fetch(); - in(arg1); - break; - case NOP: - nop(); - break; - default: - fprintf(stderr,"CRITICAL: UNKNOWN OPCODE %2x FOUND IN %2x\n",opcode,pc); - core_dump(); - break; + return; } } } -void print_regs() -{ - fprintf(stderr,"r0: %2x\n",regs[0]); - fprintf(stderr,"r1: %2x\n",regs[1]); - fprintf(stderr,"r2: %2x\n",regs[2]); - fprintf(stderr,"r3: %2x\n",regs[3]); - fprintf(stderr,"r4: %2x\n",regs[4]); - fprintf(stderr,"r5: %2x\n",regs[5]); - fprintf(stderr,"r6: %2x\n",regs[6]); - fprintf(stderr,"r7: %2x\n",regs[7]); - fprintf(stderr,"pc: %2x\n",pc); -} - void core_dump() { print_regs(); - //dump memory to file - //dump stack to file + uint16_t memdump[MEMSIZE]; + uint16_t *stackdump; + dump_memory(memdump); + uint32_t stacksize = stack_dump(&stackdump); + + FILE *fpm = fopen("synacor.mem","w"); + FILE *fps = fopen("synacor.stack","w"); + fwrite(memdump,MEMSIZE,sizeof(uint16_t),fpm); + fwrite(stackdump,stacksize,sizeof(uint16_t),fps); + fclose(fpm); + fclose(fps); + exit(1); } diff --git a/cpu.h b/cpu.h index 18096fa..88e72f5 100644 --- a/cpu.h +++ b/cpu.h @@ -35,8 +35,11 @@ void out(uint16_t src); void in(uint16_t dst); void nop(); +uint8_t execute_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3); void start_execution(); void core_dump(); -void print_regs(); +void print_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3); +void decode_instruction(uint16_t opcode, uint16_t *arg1, uint16_t *arg2, uint16_t *arg3); + #endif //SYNACORVM_CPU_H diff --git a/debug.c b/debug.c index fe4064a..495e5ca 100644 --- a/debug.c +++ b/debug.c @@ -6,53 +6,74 @@ #include #include "debug.h" -uint64_t cycle_count = 0; +//uint32_t cycle_count = 0; uint8_t breakpoint = 1; uint16_t breakpoints[0xFF]; uint16_t nbpoints = 0; char lastchoice = 0; -uint8_t in_breakpoint(uint16_t pc) +void load_state(char *filename) { - uint8_t i; - for(i = 0; i < nbpoints; i++) - { - if(breakpoints[i] == pc) - { - return 1; - } - } - return 0; + FILE *state = fopen(filename,"r"); + uint16_t regsdump[NUM_REGISTERS+1]; + uint16_t memdump[MEMSIZE]; + uint16_t *stackdump; + uint32_t stacksize, stackpos; + + fread(regsdump,sizeof(uint16_t),NUM_REGISTERS+1,state); + fread(memdump,sizeof(uint16_t),MEMSIZE,state); + stackpos = ftell(state); + fseek(state,0,SEEK_END); + stacksize = (ftell(state) - stackpos)/sizeof(uint16_t); + stackdump = calloc(stacksize,sizeof(uint16_t)); + fseek(state,stackpos,SEEK_SET); + fread(stackdump,sizeof(uint16_t),stacksize,state); + fclose(state); + + load_regs(regsdump); + load_memory(memdump); + stack_load(stackdump,stacksize); + + free(stackdump); } -uint16_t fetch_debug() +void save_state(char *filename) { - if(in_breakpoint(pc)) - { - breakpoint = 1; - } - uint16_t value = mem[pc++]; - /*if(breakpoint) - { - fprintf(stderr,"0x%2x (0x%2x): %d", pc, pc * sizeof(uint16_t),value); - fprintf(stderr," cycle: %d\n", cycle_count++); - }*/ - return value; + FILE *state = fopen(filename,"w"); + uint16_t regsdump[NUM_REGISTERS+1]; + uint16_t memdump[MEMSIZE]; + uint16_t *stackdump; + uint32_t stacksize; + + dump_regs(regsdump); + dump_memory(memdump); + stacksize = stack_dump(&stackdump); + + fwrite(regsdump,sizeof(uint16_t),NUM_REGISTERS+1,state); + fwrite(memdump,sizeof(uint16_t),MEMSIZE,state); + fwrite(stackdump,sizeof(uint16_t),stacksize,state); + fclose(state); + free(stackdump); } void query() { + //TODO discard stdin uint8_t end = 0; uint16_t bpoint; uint16_t mempos; + char input[100] = {0}; + char filename[32]; + uint8_t reg; + uint8_t value; while(!end) { printf("\n> "); - char command; - scanf("%c", &command); + char command = 0; + fgets(input,100,stdin); + command = input[0]; if (command != '\n') { - getchar(); lastchoice = command; } else @@ -62,15 +83,15 @@ void query() switch (command) { case 'b': - scanf("%d%*c",&bpoint); + sscanf(input,"b %d\n",&bpoint); fprintf(stderr,"Set breakpoint %d to %d",nbpoints,bpoint); breakpoints[nbpoints] = bpoint; nbpoints = nbpoints + 1 % 0xFF; break; case 'd': - scanf("%d%*c",&bpoint); + sscanf(input,"d %d\n",&bpoint); fprintf(stderr,"Deleted breakpoint %d",bpoint); - breakpoints[bpoint] = NULL; + breakpoints[bpoint] = 0; break; case 'c': breakpoint = 0; @@ -83,15 +104,131 @@ void query() print_regs(); break; case 'm': - scanf("%d%*c",&mempos); + sscanf(input,"m %d\n",&mempos); fprintf(stderr,"%d: %02x\n",mempos,mem[mempos]); break; + case 's': + sscanf(input,"s %s\n",filename); + save_state(filename); + fprintf(stderr,"Saved state as %s",filename); + break; + case 'l': + sscanf(input,"l %s\n",filename); + load_state(filename); + fprintf(stderr,"Loaded state as %s",filename); + break; + case 'w': + sscanf(input,"w %d %d\n",®,&value); + fprintf(stderr,"Setting register %d to %d",reg,value); + regs[reg] = value; + break; default: break; } } } +uint8_t in_breakpoint(uint16_t pc) +{ + uint8_t i; + for(i = 0; i < nbpoints; i++) + { + if(breakpoints[i] == pc) + { + return 1; + } + } + return 0; +} + +uint16_t fetch_debug() +{ + uint16_t value = mem[pc++]; + /*if(breakpoint) + { + fprintf(stderr,"0x%2x (0x%2x): %d", pc, pc * sizeof(uint16_t),value); + fprintf(stderr," cycle: %d\n", cycle_count++); + }*/ + return value; +} + +void print_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3) +{ + switch(opcode) + { + case HALT: + printf("HALT\n"); + break; + case MOV: + printf("MOV %d %d\n",arg1,arg2); + break; + case PUSH: + printf("PUSH %d\n",arg1); + break; + case POP: + printf("POP %d\n",arg1); + break; + case TEQ: + printf("TEQ %d %d %d\n",arg1,arg2,arg3); + break; + case TGT: + printf("TGT %d %d %d\n",arg1,arg2,arg3); + break; + case JMP: + printf("JMP %d\n",arg1); + break; + case JNZ: + printf("JNZ %d %d\n",arg1,arg2); + break; + case JZ: + printf("JZ %d %d\n",arg1,arg2); + break; + case ADD: + printf("ADD %d %d %d\n",arg1,arg2,arg3); + break; + case MUL: + printf("MUL %d %d %d\n",arg1,arg2,arg3); + break; + case MOD: + printf("MOD %d %d %d\n",arg1,arg2,arg3); + break; + case AND: + printf("AND %d %d %d\n",arg1,arg2,arg3); + break; + case OR: + printf("OR %d %d %d\n",arg1,arg2,arg3); + break; + case NOT: + printf("NOT %d %d\n",arg1,arg2); + break; + case LOAD: + printf("LOAD %d %d\n",arg1,arg2); + break; + case STOR: + printf("STOR %d %d\n",arg1,arg2); + break; + case CALL: + printf("CALL %d\n",arg1); + break; + case RET: + printf("RET\n"); + break; + case OUT: + printf("OUT %d\n",arg1); + break; + case IN: + printf("IN %d\n",arg1); + break; + case NOP: + printf("NOP\n"); + break; + default: + printf("UNK %d\n", opcode); + break; + } +} + + void debug_program() { memset(breakpoints,0x00,0xFF); @@ -100,234 +237,18 @@ void debug_program() uint16_t arg3; for(;;) { - if(breakpoint) + if(in_breakpoint(pc) || breakpoint) { - fprintf(stderr,"%d: ",pc); + breakpoint = 1; + fprintf(stderr, "%d: ", pc); + print_instruction(mem[pc], mem[pc+1], mem[pc+2], mem[pc+3]); + query(); } uint16_t opcode = fetch_debug(); - switch(opcode) + decode_instruction(opcode, &arg1, &arg2, &arg3); + if (execute_instruction(opcode, arg1, arg2, arg3)) { - case HALT: - if(breakpoint) - { - fprintf(stderr,"HALT\n"); - query(); - } - return; - case MOV: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"MOV %d %d\n",arg1,arg2); - query(); - } - mov(arg1,arg2); - break; - case PUSH: - arg1 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"PUSH %d\n",arg1); - query(); - } - push(arg1); - break; - case POP: - arg1 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"POP %d\n",arg1); - query(); - } - pop(arg1); - break; - case TEQ: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - arg3 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"TEQ %d %d %d\n",arg1,arg2,arg3); - query(); - } - teq(arg1,arg2,arg3); - break; - case TGT: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - arg3 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"TGT %d %d %d\n",arg1,arg2,arg3); - query(); - } - tgt(arg1,arg2,arg3); - break; - case JMP: - arg1 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"JMP %d\n",arg1); - query(); - } - jmp(arg1); - break; - case JNZ: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"JNZ %d %d\n",arg1,arg2); - query(); - } - jnz(arg1,arg2); - break; - case JZ: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"JZ %d %d\n",arg1,arg2); - query(); - } - jz(arg1,arg2); - break; - case ADD: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - arg3 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"ADD %d %d %d\n",arg1,arg2,arg3); - query(); - } - add(arg1,arg2,arg3); - break; - case MUL: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - arg3 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"MUL %d %d %d\n",arg1,arg2,arg3); - query(); - } - mul(arg1,arg2,arg3); - break; - case MOD: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - arg3 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"MOD %d %d %d\n",arg1,arg2,arg3); - query(); - } - mod(arg1,arg2,arg3); - break; - case AND: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - arg3 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"AND %d %d %d\n",arg1,arg2,arg3); - query(); - } - and(arg1,arg2,arg3); - break; - case OR: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - arg3 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"OR %d %d %d\n",arg1,arg2,arg3); - query(); - } - or(arg1,arg2,arg3); - break; - case NOT: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"NOT %d %d\n",arg1,arg2); - query(); - } - not(arg1,arg2); - break; - case LOAD: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"LOAD %d %d\n",arg1,arg2); - query(); - } - load(arg1,arg2); - break; - case STOR: - arg1 = fetch_debug(); - arg2 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"STOR %d %d\n",arg1,arg2); - query(); - } - stor(arg1,arg2); - break; - case CALL: - arg1 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"CALL %d\n",arg1); - query(); - } - call(arg1); - break; - case RET: - if(breakpoint) - { - fprintf(stderr,"RET\n"); - query(); - } - if(ret()) - { - return; - } - break; - case OUT: - arg1 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"OUT %d\n",arg1); - query(); - } - out(arg1); - break; - case IN: - arg1 = fetch_debug(); - if(breakpoint) - { - fprintf(stderr,"IN %d\n",arg1); - query(); - } - in(arg1); - break; - case NOP: - if(breakpoint) - { - fprintf(stderr,"NOP\n"); - query(); - } - nop(); - break; - default: - fprintf(stderr,"CRITICAL: UNKNOWN OPCODE %2x FOUND IN %2x\n",opcode,pc); - core_dump(); - break; + return; } } } \ No newline at end of file diff --git a/disasm.c b/disasm.c index d268fcd..8a6b84f 100644 --- a/disasm.c +++ b/disasm.c @@ -1,6 +1,6 @@ #include "disasm.h" -void disassemble_program(uint64_t length) +void disassemble_program(uint32_t length) { uint16_t arg1; uint16_t arg2; @@ -11,118 +11,9 @@ void disassemble_program(uint64_t length) { break; } - uint16_t opcode = fetch(); printf("%d: ",pc); - switch(opcode) - { - case HALT: - printf("HALT\n"); - break; - case MOV: - arg1 = fetch(); - arg2 = fetch(); - printf("MOV %d %d\n",arg1,arg2); - break; - case PUSH: - arg1 = fetch(); - printf("PUSH %d\n",arg1); - break; - case POP: - arg1 = fetch(); - printf("POP %d\n",arg1); - break; - case TEQ: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - printf("TEQ %d %d %d\n",arg1,arg2,arg3); - break; - case TGT: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - printf("TGT %d %d %d\n",arg1,arg2,arg3); - break; - case JMP: - arg1 = fetch(); - printf("JMP %d\n",arg1); - break; - case JNZ: - arg1 = fetch(); - arg2 = fetch(); - printf("JNZ %d %d\n",arg1,arg2); - break; - case JZ: - arg1 = fetch(); - arg2 = fetch(); - printf("JZ %d %d\n",arg1,arg2); - break; - case ADD: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - printf("ADD %d %d %d\n",arg1,arg2,arg3); - break; - case MUL: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - printf("MUL %d %d %d\n",arg1,arg2,arg3); - break; - case MOD: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - printf("MOD %d %d %d\n",arg1,arg2,arg3); - break; - case AND: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - printf("AND %d %d %d\n",arg1,arg2,arg3); - break; - case OR: - arg1 = fetch(); - arg2 = fetch(); - arg3 = fetch(); - printf("OR %d %d %d\n",arg1,arg2,arg3); - break; - case NOT: - arg1 = fetch(); - arg2 = fetch(); - printf("NOT %d %d\n",arg1,arg2); - break; - case LOAD: - arg1 = fetch(); - arg2 = fetch(); - printf("LOAD %d %d\n",arg1,arg2); - break; - case STOR: - arg1 = fetch(); - arg2 = fetch(); - printf("STOR %d %d\n",arg1,arg2); - break; - case CALL: - arg1 = fetch(); - printf("CALL %d\n",arg1); - break; - case RET: - printf("RET\n"); - break; - case OUT: - arg1 = fetch(); - printf("OUT %d\n",arg1); - break; - case IN: - arg1 = fetch(); - printf("IN %d\n",arg1); - break; - case NOP: - printf("NOP\n"); - break; - default: - printf("UNK %d\n", opcode); - break; - } + uint16_t opcode = fetch(); + decode_instruction(opcode,&arg1,&arg2,&arg3); + print_instruction(opcode,arg1,arg2,arg3); } } diff --git a/disasm.h b/disasm.h index b0cb1ed..1265582 100644 --- a/disasm.h +++ b/disasm.h @@ -10,8 +10,9 @@ #include "registers.h" #include "mem.h" #include "instructions.h" +#include "debug.h" extern uint16_t fetch(); -void disassemble_program(uint64_t length); +void disassemble_program(uint32_t length); #endif //SYNACORVM_DISASM_H \ No newline at end of file diff --git a/main.c b/main.c index 9f62658..73cd479 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,7 @@ #include "disasm.h" #include "debug.h" -uint64_t load_program(const char* path) +uint32_t load_program(const char* path) { FILE *fp = fopen(path,"r"); fseek(fp, 0L, SEEK_END); @@ -20,8 +20,8 @@ uint64_t load_program(const char* path) void startvm(char *program) { initialize_stack(); - memset(regs,0x00,sizeof(short)*NUM_REGISTERS); - memset(mem,0x00,sizeof(short)*MEMSIZE); + memset(regs,0x00,sizeof(uint16_t)*NUM_REGISTERS); + memset(mem,0x00,sizeof(uint16_t)*MEMSIZE); load_program(program); start_execution(); free_stack(); @@ -35,8 +35,8 @@ void disasm(char *program) void debug(char *program) { initialize_stack(); - memset(regs,0x00,sizeof(short)*NUM_REGISTERS); - memset(mem,0x00,sizeof(short)*MEMSIZE); + memset(regs,0x00,sizeof(uint16_t)*NUM_REGISTERS); + memset(mem,0x00,sizeof(uint16_t)*MEMSIZE); load_program(program); debug_program(); free_stack(); diff --git a/mem.c b/mem.c index b4e7f8f..063bcb2 100644 --- a/mem.c +++ b/mem.c @@ -2,6 +2,18 @@ // Created by imanol on 12/25/16. // +#include +#include #include "mem.h" -short mem[MEMSIZE]; \ No newline at end of file +uint16_t mem[MEMSIZE]; + +void dump_memory(uint16_t *dump) +{ + memcpy(dump,mem,MEMSIZE*sizeof(uint16_t)); +} + +void load_memory(uint16_t *dump) +{ + memcpy(mem,dump,MEMSIZE*sizeof(uint16_t)); +} \ No newline at end of file diff --git a/mem.h b/mem.h index 2d1c9ab..b67c4fa 100644 --- a/mem.h +++ b/mem.h @@ -7,6 +7,11 @@ #define MEMSIZE 32768 -extern short mem[MEMSIZE]; //64KiB RAM +#include + +extern uint16_t mem[MEMSIZE]; //64KiB RAM + +void dump_memory(uint16_t *dump); +void load_memory(uint16_t *dump); #endif //SYNACORVM_MEM_H diff --git a/registers.c b/registers.c index 28f80a8..fc6a595 100644 --- a/registers.c +++ b/registers.c @@ -2,7 +2,34 @@ // Created by imanol on 12/25/16. // +#include +#include #include "registers.h" -short regs[NUM_REGISTERS]; -short pc = 0; \ No newline at end of file +uint16_t regs[NUM_REGISTERS]; +uint16_t pc = 0; + +void print_regs() +{ + fprintf(stderr,"r0: %2x\n",regs[0]); + fprintf(stderr,"r1: %2x\n",regs[1]); + fprintf(stderr,"r2: %2x\n",regs[2]); + fprintf(stderr,"r3: %2x\n",regs[3]); + fprintf(stderr,"r4: %2x\n",regs[4]); + fprintf(stderr,"r5: %2x\n",regs[5]); + fprintf(stderr,"r6: %2x\n",regs[6]); + fprintf(stderr,"r7: %2x\n",regs[7]); + fprintf(stderr,"pc: %2x\n",pc); +} + +void dump_regs(uint16_t *dump) +{ + dump[0] = pc; + memcpy(dump+1,regs,NUM_REGISTERS*sizeof(uint16_t)); +} + +void load_regs(uint16_t *dump) +{ + pc = dump[0]; + memcpy(regs,dump+1,NUM_REGISTERS*sizeof(uint16_t)); +} \ No newline at end of file diff --git a/registers.h b/registers.h index ec0f77f..fe17992 100644 --- a/registers.h +++ b/registers.h @@ -2,12 +2,18 @@ // Created by imanol on 12/25/16. // +#include + #ifndef SYNACORVM_REGISTERS_H #define SYNACORVM_REGISTERS_H #define NUM_REGISTERS 8 -extern short regs[NUM_REGISTERS]; -extern short pc; +extern uint16_t regs[NUM_REGISTERS]; +extern uint16_t pc; + +void print_regs(); +void dump_regs(uint16_t *dump); +void load_regs(uint16_t *dump); #endif //SYNACORVM_REGISTERS_H diff --git a/stack.c b/stack.c index 7b62000..1c62189 100644 --- a/stack.c +++ b/stack.c @@ -53,8 +53,7 @@ void shrink_stack() void stack_push(uint16_t value) { stack[++stack_pos] = value; - stack_elems++; - if(stack_pos == stack_size-1) + if(++stack_elems == stack_size-1) { extend_stack(); } @@ -68,11 +67,31 @@ uint16_t stack_pop() return -1; } uint16_t value = stack[stack_pos--]; - if(stack_size - stack_pos == 2*EXTEND_SIZE) + if(stack_size - --stack_elems == 2*EXTEND_SIZE) { shrink_stack(); } return value; } +uint32_t stack_dump(uint16_t **dump) +{ + *dump = calloc(stack_elems,sizeof(uint16_t)); + uint32_t i; + for(i = 0; i < stack_elems; i++) + { + (*dump)[i] = stack[i]; + } + return stack_elems; +} + +void stack_load(uint16_t *dump,uint32_t size) +{ + uint32_t i; + for(i = 0; i < size; i++) + { + stack_push(dump[i]); + } +} + diff --git a/stack.h b/stack.h index 7028c37..6f2ef5e 100644 --- a/stack.h +++ b/stack.h @@ -15,4 +15,7 @@ void free_stack(); void stack_push(uint16_t value); uint16_t stack_pop(); +uint32_t stack_dump(uint16_t **dump); +void stack_load(uint16_t *dump,uint32_t size); + #endif //SYNACORVM_STACK_H