Commit 9ff101a8a3ee99925f58ed96d34e62e7a7220303

Authored by Imanol-Mikel Barba Sabariego
1 parent 91ff09d1

Improved general code structure (no longer a fucking mess), disassembler now pro…

…duces correct code and debugger doesn't suck so much (still has input issues)
@@ -239,149 +239,211 @@ uint16_t fetch() @@ -239,149 +239,211 @@ uint16_t fetch()
239 return value; 239 return value;
240 } 240 }
241 241
  242 +
  243 +void decode_instruction(uint16_t opcode, uint16_t *arg1, uint16_t *arg2, uint16_t *arg3)
  244 +{
  245 + switch(opcode)
  246 + {
  247 + case HALT:
  248 + break;
  249 + case MOV:
  250 + *arg1 = fetch();
  251 + *arg2 = fetch();
  252 + break;
  253 + case PUSH:
  254 + *arg1 = fetch();
  255 + break;
  256 + case POP:
  257 + *arg1 = fetch();
  258 + break;
  259 + case TEQ:
  260 + *arg1 = fetch();
  261 + *arg2 = fetch();
  262 + *arg3 = fetch();
  263 + break;
  264 + case TGT:
  265 + *arg1 = fetch();
  266 + *arg2 = fetch();
  267 + *arg3 = fetch();
  268 + break;
  269 + case JMP:
  270 + *arg1 = fetch();
  271 + break;
  272 + case JNZ:
  273 + *arg1 = fetch();
  274 + *arg2 = fetch();
  275 + break;
  276 + case JZ:
  277 + *arg1 = fetch();
  278 + *arg2 = fetch();
  279 + break;
  280 + case ADD:
  281 + *arg1 = fetch();
  282 + *arg2 = fetch();
  283 + *arg3 = fetch();
  284 + break;
  285 + case MUL:
  286 + *arg1 = fetch();
  287 + *arg2 = fetch();
  288 + *arg3 = fetch();
  289 + break;
  290 + case MOD:
  291 + *arg1 = fetch();
  292 + *arg2 = fetch();
  293 + *arg3 = fetch();
  294 + break;
  295 + case AND:
  296 + *arg1 = fetch();
  297 + *arg2 = fetch();
  298 + *arg3 = fetch();
  299 + break;
  300 + case OR:
  301 + *arg1 = fetch();
  302 + *arg2 = fetch();
  303 + *arg3 = fetch();
  304 + break;
  305 + case NOT:
  306 + *arg1 = fetch();
  307 + *arg2 = fetch();
  308 + break;
  309 + case LOAD:
  310 + *arg1 = fetch();
  311 + *arg2 = fetch();
  312 + break;
  313 + case STOR:
  314 + *arg1 = fetch();
  315 + *arg2 = fetch();
  316 + break;
  317 + case CALL:
  318 + *arg1 = fetch();
  319 + break;
  320 + case RET:
  321 + break;
  322 + case OUT:
  323 + *arg1 = fetch();
  324 + break;
  325 + case IN:
  326 + *arg1 = fetch();
  327 + break;
  328 + case NOP:
  329 + break;
  330 + default:
  331 + break;
  332 + }
  333 +}
  334 +
  335 +uint8_t execute_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3)
  336 +{
  337 + switch(opcode)
  338 + {
  339 + case HALT:
  340 + return 1;
  341 + case MOV:
  342 + mov(arg1,arg2);
  343 + break;
  344 + case PUSH:
  345 + push(arg1);
  346 + break;
  347 + case POP:
  348 + pop(arg1);
  349 + break;
  350 + case TEQ:
  351 + teq(arg1,arg2,arg3);
  352 + break;
  353 + case TGT:
  354 + tgt(arg1,arg2,arg3);
  355 + break;
  356 + case JMP:
  357 + jmp(arg1);
  358 + break;
  359 + case JNZ:
  360 + jnz(arg1,arg2);
  361 + break;
  362 + case JZ:
  363 + jz(arg1,arg2);
  364 + break;
  365 + case ADD:
  366 + add(arg1,arg2,arg3);
  367 + break;
  368 + case MUL:
  369 + mul(arg1,arg2,arg3);
  370 + break;
  371 + case MOD:
  372 + mod(arg1,arg2,arg3);
  373 + break;
  374 + case AND:
  375 + and(arg1,arg2,arg3);
  376 + break;
  377 + case OR:
  378 + or(arg1,arg2,arg3);
  379 + break;
  380 + case NOT:
  381 + not(arg1,arg2);
  382 + break;
  383 + case LOAD:
  384 + load(arg1,arg2);
  385 + break;
  386 + case STOR:
  387 + stor(arg1,arg2);
  388 + break;
  389 + case CALL:
  390 + call(arg1);
  391 + break;
  392 + case RET:
  393 + if(ret())
  394 + {
  395 + return 1;
  396 + }
  397 + break;
  398 + case OUT:
  399 + out(arg1);
  400 + break;
  401 + case IN:
  402 + in(arg1);
  403 + break;
  404 + case NOP:
  405 + nop();
  406 + break;
  407 + default:
  408 + fprintf(stderr,"CRITICAL: UNKNOWN OPCODE %2x FOUND IN %2x\n",opcode,pc);
  409 + core_dump();
  410 + break;
  411 + }
  412 + return 0;
  413 +}
  414 +
242 void start_execution() 415 void start_execution()
243 { 416 {
244 uint16_t arg1; 417 uint16_t arg1;
245 uint16_t arg2; 418 uint16_t arg2;
246 uint16_t arg3; 419 uint16_t arg3;
  420 +
247 for(;;) 421 for(;;)
248 { 422 {
249 uint16_t opcode = fetch(); 423 uint16_t opcode = fetch();
250 - switch(opcode) 424 + decode_instruction(opcode, &arg1, &arg2, &arg3);
  425 + if(execute_instruction(opcode, arg1, arg2, arg3))
251 { 426 {
252 - case HALT:  
253 - return;  
254 - case MOV:  
255 - arg1 = fetch();  
256 - arg2 = fetch();  
257 - mov(arg1,arg2);  
258 - break;  
259 - case PUSH:  
260 - arg1 = fetch();  
261 - push(arg1);  
262 - break;  
263 - case POP:  
264 - arg1 = fetch();  
265 - pop(arg1);  
266 - break;  
267 - case TEQ:  
268 - arg1 = fetch();  
269 - arg2 = fetch();  
270 - arg3 = fetch();  
271 - teq(arg1,arg2,arg3);  
272 - break;  
273 - case TGT:  
274 - arg1 = fetch();  
275 - arg2 = fetch();  
276 - arg3 = fetch();  
277 - tgt(arg1,arg2,arg3);  
278 - break;  
279 - case JMP:  
280 - arg1 = fetch();  
281 - jmp(arg1);  
282 - break;  
283 - case JNZ:  
284 - arg1 = fetch();  
285 - arg2 = fetch();  
286 - jnz(arg1,arg2);  
287 - break;  
288 - case JZ:  
289 - arg1 = fetch();  
290 - arg2 = fetch();  
291 - jz(arg1,arg2);  
292 - break;  
293 - case ADD:  
294 - arg1 = fetch();  
295 - arg2 = fetch();  
296 - arg3 = fetch();  
297 - add(arg1,arg2,arg3);  
298 - break;  
299 - case MUL:  
300 - arg1 = fetch();  
301 - arg2 = fetch();  
302 - arg3 = fetch();  
303 - mul(arg1,arg2,arg3);  
304 - break;  
305 - case MOD:  
306 - arg1 = fetch();  
307 - arg2 = fetch();  
308 - arg3 = fetch();  
309 - mod(arg1,arg2,arg3);  
310 - break;  
311 - case AND:  
312 - arg1 = fetch();  
313 - arg2 = fetch();  
314 - arg3 = fetch();  
315 - and(arg1,arg2,arg3);  
316 - break;  
317 - case OR:  
318 - arg1 = fetch();  
319 - arg2 = fetch();  
320 - arg3 = fetch();  
321 - or(arg1,arg2,arg3);  
322 - break;  
323 - case NOT:  
324 - arg1 = fetch();  
325 - arg2 = fetch();  
326 - not(arg1,arg2);  
327 - break;  
328 - case LOAD:  
329 - arg1 = fetch();  
330 - arg2 = fetch();  
331 - load(arg1,arg2);  
332 - break;  
333 - case STOR:  
334 - arg1 = fetch();  
335 - arg2 = fetch();  
336 - stor(arg1,arg2);  
337 - break;  
338 - case CALL:  
339 - arg1 = fetch();  
340 - call(arg1);  
341 - break;  
342 - case RET:  
343 - if(ret())  
344 - {  
345 - return;  
346 - }  
347 - break;  
348 - case OUT:  
349 - arg1 = fetch();  
350 - out(arg1);  
351 - break;  
352 - case IN:  
353 - arg1 = fetch();  
354 - in(arg1);  
355 - break;  
356 - case NOP:  
357 - nop();  
358 - break;  
359 - default:  
360 - fprintf(stderr,"CRITICAL: UNKNOWN OPCODE %2x FOUND IN %2x\n",opcode,pc);  
361 - core_dump();  
362 - break; 427 + return;
363 } 428 }
364 } 429 }
365 } 430 }
366 431
367 -void print_regs()  
368 -{  
369 - fprintf(stderr,"r0: %2x\n",regs[0]);  
370 - fprintf(stderr,"r1: %2x\n",regs[1]);  
371 - fprintf(stderr,"r2: %2x\n",regs[2]);  
372 - fprintf(stderr,"r3: %2x\n",regs[3]);  
373 - fprintf(stderr,"r4: %2x\n",regs[4]);  
374 - fprintf(stderr,"r5: %2x\n",regs[5]);  
375 - fprintf(stderr,"r6: %2x\n",regs[6]);  
376 - fprintf(stderr,"r7: %2x\n",regs[7]);  
377 - fprintf(stderr,"pc: %2x\n",pc);  
378 -}  
379 -  
380 void core_dump() 432 void core_dump()
381 { 433 {
382 print_regs(); 434 print_regs();
383 - //dump memory to file  
384 - //dump stack to file 435 + uint16_t memdump[MEMSIZE];
  436 + uint16_t *stackdump;
  437 + dump_memory(memdump);
  438 + uint32_t stacksize = stack_dump(&stackdump);
  439 +
  440 + FILE *fpm = fopen("synacor.mem","w");
  441 + FILE *fps = fopen("synacor.stack","w");
  442 + fwrite(memdump,MEMSIZE,sizeof(uint16_t),fpm);
  443 + fwrite(stackdump,stacksize,sizeof(uint16_t),fps);
  444 + fclose(fpm);
  445 + fclose(fps);
  446 +
385 exit(1); 447 exit(1);
386 } 448 }
387 449
@@ -35,8 +35,11 @@ void out(uint16_t src); @@ -35,8 +35,11 @@ void out(uint16_t src);
35 void in(uint16_t dst); 35 void in(uint16_t dst);
36 void nop(); 36 void nop();
37 37
  38 +uint8_t execute_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3);
38 void start_execution(); 39 void start_execution();
39 void core_dump(); 40 void core_dump();
40 -void print_regs(); 41 +void print_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3);
  42 +void decode_instruction(uint16_t opcode, uint16_t *arg1, uint16_t *arg2, uint16_t *arg3);
  43 +
41 44
42 #endif //SYNACORVM_CPU_H 45 #endif //SYNACORVM_CPU_H
@@ -6,53 +6,74 @@ @@ -6,53 +6,74 @@
6 #include <string.h> 6 #include <string.h>
7 #include "debug.h" 7 #include "debug.h"
8 8
9 -uint64_t cycle_count = 0; 9 +//uint32_t cycle_count = 0;
10 uint8_t breakpoint = 1; 10 uint8_t breakpoint = 1;
11 uint16_t breakpoints[0xFF]; 11 uint16_t breakpoints[0xFF];
12 uint16_t nbpoints = 0; 12 uint16_t nbpoints = 0;
13 char lastchoice = 0; 13 char lastchoice = 0;
14 14
15 -uint8_t in_breakpoint(uint16_t pc) 15 +void load_state(char *filename)
16 { 16 {
17 - uint8_t i;  
18 - for(i = 0; i < nbpoints; i++)  
19 - {  
20 - if(breakpoints[i] == pc)  
21 - {  
22 - return 1;  
23 - }  
24 - }  
25 - return 0; 17 + FILE *state = fopen(filename,"r");
  18 + uint16_t regsdump[NUM_REGISTERS+1];
  19 + uint16_t memdump[MEMSIZE];
  20 + uint16_t *stackdump;
  21 + uint32_t stacksize, stackpos;
  22 +
  23 + fread(regsdump,sizeof(uint16_t),NUM_REGISTERS+1,state);
  24 + fread(memdump,sizeof(uint16_t),MEMSIZE,state);
  25 + stackpos = ftell(state);
  26 + fseek(state,0,SEEK_END);
  27 + stacksize = (ftell(state) - stackpos)/sizeof(uint16_t);
  28 + stackdump = calloc(stacksize,sizeof(uint16_t));
  29 + fseek(state,stackpos,SEEK_SET);
  30 + fread(stackdump,sizeof(uint16_t),stacksize,state);
  31 + fclose(state);
  32 +
  33 + load_regs(regsdump);
  34 + load_memory(memdump);
  35 + stack_load(stackdump,stacksize);
  36 +
  37 + free(stackdump);
26 } 38 }
27 39
28 -uint16_t fetch_debug() 40 +void save_state(char *filename)
29 { 41 {
30 - if(in_breakpoint(pc))  
31 - {  
32 - breakpoint = 1;  
33 - }  
34 - uint16_t value = mem[pc++];  
35 - /*if(breakpoint)  
36 - {  
37 - fprintf(stderr,"0x%2x (0x%2x): %d", pc, pc * sizeof(uint16_t),value);  
38 - fprintf(stderr," cycle: %d\n", cycle_count++);  
39 - }*/  
40 - return value; 42 + FILE *state = fopen(filename,"w");
  43 + uint16_t regsdump[NUM_REGISTERS+1];
  44 + uint16_t memdump[MEMSIZE];
  45 + uint16_t *stackdump;
  46 + uint32_t stacksize;
  47 +
  48 + dump_regs(regsdump);
  49 + dump_memory(memdump);
  50 + stacksize = stack_dump(&stackdump);
  51 +
  52 + fwrite(regsdump,sizeof(uint16_t),NUM_REGISTERS+1,state);
  53 + fwrite(memdump,sizeof(uint16_t),MEMSIZE,state);
  54 + fwrite(stackdump,sizeof(uint16_t),stacksize,state);
  55 + fclose(state);
  56 + free(stackdump);
41 } 57 }
42 58
43 void query() 59 void query()
44 { 60 {
  61 + //TODO discard stdin
45 uint8_t end = 0; 62 uint8_t end = 0;
46 uint16_t bpoint; 63 uint16_t bpoint;
47 uint16_t mempos; 64 uint16_t mempos;
  65 + char input[100] = {0};
  66 + char filename[32];
  67 + uint8_t reg;
  68 + uint8_t value;
48 while(!end) 69 while(!end)
49 { 70 {
50 printf("\n> "); 71 printf("\n> ");
51 - char command;  
52 - scanf("%c", &command); 72 + char command = 0;
  73 + fgets(input,100,stdin);
  74 + command = input[0];
53 if (command != '\n') 75 if (command != '\n')
54 { 76 {
55 - getchar();  
56 lastchoice = command; 77 lastchoice = command;
57 } 78 }
58 else 79 else
@@ -62,15 +83,15 @@ void query() @@ -62,15 +83,15 @@ void query()
62 switch (command) 83 switch (command)
63 { 84 {
64 case 'b': 85 case 'b':
65 - scanf("%d%*c",&bpoint); 86 + sscanf(input,"b %d\n",&bpoint);
66 fprintf(stderr,"Set breakpoint %d to %d",nbpoints,bpoint); 87 fprintf(stderr,"Set breakpoint %d to %d",nbpoints,bpoint);
67 breakpoints[nbpoints] = bpoint; 88 breakpoints[nbpoints] = bpoint;
68 nbpoints = nbpoints + 1 % 0xFF; 89 nbpoints = nbpoints + 1 % 0xFF;
69 break; 90 break;
70 case 'd': 91 case 'd':
71 - scanf("%d%*c",&bpoint); 92 + sscanf(input,"d %d\n",&bpoint);
72 fprintf(stderr,"Deleted breakpoint %d",bpoint); 93 fprintf(stderr,"Deleted breakpoint %d",bpoint);
73 - breakpoints[bpoint] = NULL; 94 + breakpoints[bpoint] = 0;
74 break; 95 break;
75 case 'c': 96 case 'c':
76 breakpoint = 0; 97 breakpoint = 0;
@@ -83,15 +104,131 @@ void query() @@ -83,15 +104,131 @@ void query()
83 print_regs(); 104 print_regs();
84 break; 105 break;
85 case 'm': 106 case 'm':
86 - scanf("%d%*c",&mempos); 107 + sscanf(input,"m %d\n",&mempos);
87 fprintf(stderr,"%d: %02x\n",mempos,mem[mempos]); 108 fprintf(stderr,"%d: %02x\n",mempos,mem[mempos]);
88 break; 109 break;
  110 + case 's':
  111 + sscanf(input,"s %s\n",filename);
  112 + save_state(filename);
  113 + fprintf(stderr,"Saved state as %s",filename);
  114 + break;
  115 + case 'l':
  116 + sscanf(input,"l %s\n",filename);
  117 + load_state(filename);
  118 + fprintf(stderr,"Loaded state as %s",filename);
  119 + break;
  120 + case 'w':
  121 + sscanf(input,"w %d %d\n",&reg,&value);
  122 + fprintf(stderr,"Setting register %d to %d",reg,value);
  123 + regs[reg] = value;
  124 + break;
89 default: 125 default:
90 break; 126 break;
91 } 127 }
92 } 128 }
93 } 129 }
94 130
  131 +uint8_t in_breakpoint(uint16_t pc)
  132 +{
  133 + uint8_t i;
  134 + for(i = 0; i < nbpoints; i++)
  135 + {
  136 + if(breakpoints[i] == pc)
  137 + {
  138 + return 1;
  139 + }
  140 + }
  141 + return 0;
  142 +}
  143 +
  144 +uint16_t fetch_debug()
  145 +{
  146 + uint16_t value = mem[pc++];
  147 + /*if(breakpoint)
  148 + {
  149 + fprintf(stderr,"0x%2x (0x%2x): %d", pc, pc * sizeof(uint16_t),value);
  150 + fprintf(stderr," cycle: %d\n", cycle_count++);
  151 + }*/
  152 + return value;
  153 +}
  154 +
  155 +void print_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3)
  156 +{
  157 + switch(opcode)
  158 + {
  159 + case HALT:
  160 + printf("HALT\n");
  161 + break;
  162 + case MOV:
  163 + printf("MOV %d %d\n",arg1,arg2);
  164 + break;
  165 + case PUSH:
  166 + printf("PUSH %d\n",arg1);
  167 + break;
  168 + case POP:
  169 + printf("POP %d\n",arg1);
  170 + break;
  171 + case TEQ:
  172 + printf("TEQ %d %d %d\n",arg1,arg2,arg3);
  173 + break;
  174 + case TGT:
  175 + printf("TGT %d %d %d\n",arg1,arg2,arg3);
  176 + break;
  177 + case JMP:
  178 + printf("JMP %d\n",arg1);
  179 + break;
  180 + case JNZ:
  181 + printf("JNZ %d %d\n",arg1,arg2);
  182 + break;
  183 + case JZ:
  184 + printf("JZ %d %d\n",arg1,arg2);
  185 + break;
  186 + case ADD:
  187 + printf("ADD %d %d %d\n",arg1,arg2,arg3);
  188 + break;
  189 + case MUL:
  190 + printf("MUL %d %d %d\n",arg1,arg2,arg3);
  191 + break;
  192 + case MOD:
  193 + printf("MOD %d %d %d\n",arg1,arg2,arg3);
  194 + break;
  195 + case AND:
  196 + printf("AND %d %d %d\n",arg1,arg2,arg3);
  197 + break;
  198 + case OR:
  199 + printf("OR %d %d %d\n",arg1,arg2,arg3);
  200 + break;
  201 + case NOT:
  202 + printf("NOT %d %d\n",arg1,arg2);
  203 + break;
  204 + case LOAD:
  205 + printf("LOAD %d %d\n",arg1,arg2);
  206 + break;
  207 + case STOR:
  208 + printf("STOR %d %d\n",arg1,arg2);
  209 + break;
  210 + case CALL:
  211 + printf("CALL %d\n",arg1);
  212 + break;
  213 + case RET:
  214 + printf("RET\n");
  215 + break;
  216 + case OUT:
  217 + printf("OUT %d\n",arg1);
  218 + break;
  219 + case IN:
  220 + printf("IN %d\n",arg1);
  221 + break;
  222 + case NOP:
  223 + printf("NOP\n");
  224 + break;
  225 + default:
  226 + printf("UNK %d\n", opcode);
  227 + break;
  228 + }
  229 +}
  230 +
  231 +
95 void debug_program() 232 void debug_program()
96 { 233 {
97 memset(breakpoints,0x00,0xFF); 234 memset(breakpoints,0x00,0xFF);
@@ -100,234 +237,18 @@ void debug_program() @@ -100,234 +237,18 @@ void debug_program()
100 uint16_t arg3; 237 uint16_t arg3;
101 for(;;) 238 for(;;)
102 { 239 {
103 - if(breakpoint) 240 + if(in_breakpoint(pc) || breakpoint)
104 { 241 {
105 - fprintf(stderr,"%d: ",pc); 242 + breakpoint = 1;
  243 + fprintf(stderr, "%d: ", pc);
  244 + print_instruction(mem[pc], mem[pc+1], mem[pc+2], mem[pc+3]);
  245 + query();
106 } 246 }
107 uint16_t opcode = fetch_debug(); 247 uint16_t opcode = fetch_debug();
108 - switch(opcode) 248 + decode_instruction(opcode, &arg1, &arg2, &arg3);
  249 + if (execute_instruction(opcode, arg1, arg2, arg3))
109 { 250 {
110 - case HALT:  
111 - if(breakpoint)  
112 - {  
113 - fprintf(stderr,"HALT\n");  
114 - query();  
115 - }  
116 - return;  
117 - case MOV:  
118 - arg1 = fetch_debug();  
119 - arg2 = fetch_debug();  
120 - if(breakpoint)  
121 - {  
122 - fprintf(stderr,"MOV %d %d\n",arg1,arg2);  
123 - query();  
124 - }  
125 - mov(arg1,arg2);  
126 - break;  
127 - case PUSH:  
128 - arg1 = fetch_debug();  
129 - if(breakpoint)  
130 - {  
131 - fprintf(stderr,"PUSH %d\n",arg1);  
132 - query();  
133 - }  
134 - push(arg1);  
135 - break;  
136 - case POP:  
137 - arg1 = fetch_debug();  
138 - if(breakpoint)  
139 - {  
140 - fprintf(stderr,"POP %d\n",arg1);  
141 - query();  
142 - }  
143 - pop(arg1);  
144 - break;  
145 - case TEQ:  
146 - arg1 = fetch_debug();  
147 - arg2 = fetch_debug();  
148 - arg3 = fetch_debug();  
149 - if(breakpoint)  
150 - {  
151 - fprintf(stderr,"TEQ %d %d %d\n",arg1,arg2,arg3);  
152 - query();  
153 - }  
154 - teq(arg1,arg2,arg3);  
155 - break;  
156 - case TGT:  
157 - arg1 = fetch_debug();  
158 - arg2 = fetch_debug();  
159 - arg3 = fetch_debug();  
160 - if(breakpoint)  
161 - {  
162 - fprintf(stderr,"TGT %d %d %d\n",arg1,arg2,arg3);  
163 - query();  
164 - }  
165 - tgt(arg1,arg2,arg3);  
166 - break;  
167 - case JMP:  
168 - arg1 = fetch_debug();  
169 - if(breakpoint)  
170 - {  
171 - fprintf(stderr,"JMP %d\n",arg1);  
172 - query();  
173 - }  
174 - jmp(arg1);  
175 - break;  
176 - case JNZ:  
177 - arg1 = fetch_debug();  
178 - arg2 = fetch_debug();  
179 - if(breakpoint)  
180 - {  
181 - fprintf(stderr,"JNZ %d %d\n",arg1,arg2);  
182 - query();  
183 - }  
184 - jnz(arg1,arg2);  
185 - break;  
186 - case JZ:  
187 - arg1 = fetch_debug();  
188 - arg2 = fetch_debug();  
189 - if(breakpoint)  
190 - {  
191 - fprintf(stderr,"JZ %d %d\n",arg1,arg2);  
192 - query();  
193 - }  
194 - jz(arg1,arg2);  
195 - break;  
196 - case ADD:  
197 - arg1 = fetch_debug();  
198 - arg2 = fetch_debug();  
199 - arg3 = fetch_debug();  
200 - if(breakpoint)  
201 - {  
202 - fprintf(stderr,"ADD %d %d %d\n",arg1,arg2,arg3);  
203 - query();  
204 - }  
205 - add(arg1,arg2,arg3);  
206 - break;  
207 - case MUL:  
208 - arg1 = fetch_debug();  
209 - arg2 = fetch_debug();  
210 - arg3 = fetch_debug();  
211 - if(breakpoint)  
212 - {  
213 - fprintf(stderr,"MUL %d %d %d\n",arg1,arg2,arg3);  
214 - query();  
215 - }  
216 - mul(arg1,arg2,arg3);  
217 - break;  
218 - case MOD:  
219 - arg1 = fetch_debug();  
220 - arg2 = fetch_debug();  
221 - arg3 = fetch_debug();  
222 - if(breakpoint)  
223 - {  
224 - fprintf(stderr,"MOD %d %d %d\n",arg1,arg2,arg3);  
225 - query();  
226 - }  
227 - mod(arg1,arg2,arg3);  
228 - break;  
229 - case AND:  
230 - arg1 = fetch_debug();  
231 - arg2 = fetch_debug();  
232 - arg3 = fetch_debug();  
233 - if(breakpoint)  
234 - {  
235 - fprintf(stderr,"AND %d %d %d\n",arg1,arg2,arg3);  
236 - query();  
237 - }  
238 - and(arg1,arg2,arg3);  
239 - break;  
240 - case OR:  
241 - arg1 = fetch_debug();  
242 - arg2 = fetch_debug();  
243 - arg3 = fetch_debug();  
244 - if(breakpoint)  
245 - {  
246 - fprintf(stderr,"OR %d %d %d\n",arg1,arg2,arg3);  
247 - query();  
248 - }  
249 - or(arg1,arg2,arg3);  
250 - break;  
251 - case NOT:  
252 - arg1 = fetch_debug();  
253 - arg2 = fetch_debug();  
254 - if(breakpoint)  
255 - {  
256 - fprintf(stderr,"NOT %d %d\n",arg1,arg2);  
257 - query();  
258 - }  
259 - not(arg1,arg2);  
260 - break;  
261 - case LOAD:  
262 - arg1 = fetch_debug();  
263 - arg2 = fetch_debug();  
264 - if(breakpoint)  
265 - {  
266 - fprintf(stderr,"LOAD %d %d\n",arg1,arg2);  
267 - query();  
268 - }  
269 - load(arg1,arg2);  
270 - break;  
271 - case STOR:  
272 - arg1 = fetch_debug();  
273 - arg2 = fetch_debug();  
274 - if(breakpoint)  
275 - {  
276 - fprintf(stderr,"STOR %d %d\n",arg1,arg2);  
277 - query();  
278 - }  
279 - stor(arg1,arg2);  
280 - break;  
281 - case CALL:  
282 - arg1 = fetch_debug();  
283 - if(breakpoint)  
284 - {  
285 - fprintf(stderr,"CALL %d\n",arg1);  
286 - query();  
287 - }  
288 - call(arg1);  
289 - break;  
290 - case RET:  
291 - if(breakpoint)  
292 - {  
293 - fprintf(stderr,"RET\n");  
294 - query();  
295 - }  
296 - if(ret())  
297 - {  
298 - return;  
299 - }  
300 - break;  
301 - case OUT:  
302 - arg1 = fetch_debug();  
303 - if(breakpoint)  
304 - {  
305 - fprintf(stderr,"OUT %d\n",arg1);  
306 - query();  
307 - }  
308 - out(arg1);  
309 - break;  
310 - case IN:  
311 - arg1 = fetch_debug();  
312 - if(breakpoint)  
313 - {  
314 - fprintf(stderr,"IN %d\n",arg1);  
315 - query();  
316 - }  
317 - in(arg1);  
318 - break;  
319 - case NOP:  
320 - if(breakpoint)  
321 - {  
322 - fprintf(stderr,"NOP\n");  
323 - query();  
324 - }  
325 - nop();  
326 - break;  
327 - default:  
328 - fprintf(stderr,"CRITICAL: UNKNOWN OPCODE %2x FOUND IN %2x\n",opcode,pc);  
329 - core_dump();  
330 - break; 251 + return;
331 } 252 }
332 } 253 }
333 } 254 }
334 \ No newline at end of file 255 \ No newline at end of file
disasm.c
1 #include "disasm.h" 1 #include "disasm.h"
2 2
3 -void disassemble_program(uint64_t length) 3 +void disassemble_program(uint32_t length)
4 { 4 {
5 uint16_t arg1; 5 uint16_t arg1;
6 uint16_t arg2; 6 uint16_t arg2;
@@ -11,118 +11,9 @@ void disassemble_program(uint64_t length) @@ -11,118 +11,9 @@ void disassemble_program(uint64_t length)
11 { 11 {
12 break; 12 break;
13 } 13 }
14 - uint16_t opcode = fetch();  
15 printf("%d: ",pc); 14 printf("%d: ",pc);
16 - switch(opcode)  
17 - {  
18 - case HALT:  
19 - printf("HALT\n");  
20 - break;  
21 - case MOV:  
22 - arg1 = fetch();  
23 - arg2 = fetch();  
24 - printf("MOV %d %d\n",arg1,arg2);  
25 - break;  
26 - case PUSH:  
27 - arg1 = fetch();  
28 - printf("PUSH %d\n",arg1);  
29 - break;  
30 - case POP:  
31 - arg1 = fetch();  
32 - printf("POP %d\n",arg1);  
33 - break;  
34 - case TEQ:  
35 - arg1 = fetch();  
36 - arg2 = fetch();  
37 - arg3 = fetch();  
38 - printf("TEQ %d %d %d\n",arg1,arg2,arg3);  
39 - break;  
40 - case TGT:  
41 - arg1 = fetch();  
42 - arg2 = fetch();  
43 - arg3 = fetch();  
44 - printf("TGT %d %d %d\n",arg1,arg2,arg3);  
45 - break;  
46 - case JMP:  
47 - arg1 = fetch();  
48 - printf("JMP %d\n",arg1);  
49 - break;  
50 - case JNZ:  
51 - arg1 = fetch();  
52 - arg2 = fetch();  
53 - printf("JNZ %d %d\n",arg1,arg2);  
54 - break;  
55 - case JZ:  
56 - arg1 = fetch();  
57 - arg2 = fetch();  
58 - printf("JZ %d %d\n",arg1,arg2);  
59 - break;  
60 - case ADD:  
61 - arg1 = fetch();  
62 - arg2 = fetch();  
63 - arg3 = fetch();  
64 - printf("ADD %d %d %d\n",arg1,arg2,arg3);  
65 - break;  
66 - case MUL:  
67 - arg1 = fetch();  
68 - arg2 = fetch();  
69 - arg3 = fetch();  
70 - printf("MUL %d %d %d\n",arg1,arg2,arg3);  
71 - break;  
72 - case MOD:  
73 - arg1 = fetch();  
74 - arg2 = fetch();  
75 - arg3 = fetch();  
76 - printf("MOD %d %d %d\n",arg1,arg2,arg3);  
77 - break;  
78 - case AND:  
79 - arg1 = fetch();  
80 - arg2 = fetch();  
81 - arg3 = fetch();  
82 - printf("AND %d %d %d\n",arg1,arg2,arg3);  
83 - break;  
84 - case OR:  
85 - arg1 = fetch();  
86 - arg2 = fetch();  
87 - arg3 = fetch();  
88 - printf("OR %d %d %d\n",arg1,arg2,arg3);  
89 - break;  
90 - case NOT:  
91 - arg1 = fetch();  
92 - arg2 = fetch();  
93 - printf("NOT %d %d\n",arg1,arg2);  
94 - break;  
95 - case LOAD:  
96 - arg1 = fetch();  
97 - arg2 = fetch();  
98 - printf("LOAD %d %d\n",arg1,arg2);  
99 - break;  
100 - case STOR:  
101 - arg1 = fetch();  
102 - arg2 = fetch();  
103 - printf("STOR %d %d\n",arg1,arg2);  
104 - break;  
105 - case CALL:  
106 - arg1 = fetch();  
107 - printf("CALL %d\n",arg1);  
108 - break;  
109 - case RET:  
110 - printf("RET\n");  
111 - break;  
112 - case OUT:  
113 - arg1 = fetch();  
114 - printf("OUT %d\n",arg1);  
115 - break;  
116 - case IN:  
117 - arg1 = fetch();  
118 - printf("IN %d\n",arg1);  
119 - break;  
120 - case NOP:  
121 - printf("NOP\n");  
122 - break;  
123 - default:  
124 - printf("UNK %d\n", opcode);  
125 - break;  
126 - } 15 + uint16_t opcode = fetch();
  16 + decode_instruction(opcode,&arg1,&arg2,&arg3);
  17 + print_instruction(opcode,arg1,arg2,arg3);
127 } 18 }
128 } 19 }
disasm.h
@@ -10,8 +10,9 @@ @@ -10,8 +10,9 @@
10 #include "registers.h" 10 #include "registers.h"
11 #include "mem.h" 11 #include "mem.h"
12 #include "instructions.h" 12 #include "instructions.h"
  13 +#include "debug.h"
13 14
14 extern uint16_t fetch(); 15 extern uint16_t fetch();
15 -void disassemble_program(uint64_t length); 16 +void disassemble_program(uint32_t length);
16 17
17 #endif //SYNACORVM_DISASM_H 18 #endif //SYNACORVM_DISASM_H
18 \ No newline at end of file 19 \ No newline at end of file
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 #include "disasm.h" 6 #include "disasm.h"
7 #include "debug.h" 7 #include "debug.h"
8 8
9 -uint64_t load_program(const char* path) 9 +uint32_t load_program(const char* path)
10 { 10 {
11 FILE *fp = fopen(path,"r"); 11 FILE *fp = fopen(path,"r");
12 fseek(fp, 0L, SEEK_END); 12 fseek(fp, 0L, SEEK_END);
@@ -20,8 +20,8 @@ uint64_t load_program(const char* path) @@ -20,8 +20,8 @@ uint64_t load_program(const char* path)
20 void startvm(char *program) 20 void startvm(char *program)
21 { 21 {
22 initialize_stack(); 22 initialize_stack();
23 - memset(regs,0x00,sizeof(short)*NUM_REGISTERS);  
24 - memset(mem,0x00,sizeof(short)*MEMSIZE); 23 + memset(regs,0x00,sizeof(uint16_t)*NUM_REGISTERS);
  24 + memset(mem,0x00,sizeof(uint16_t)*MEMSIZE);
25 load_program(program); 25 load_program(program);
26 start_execution(); 26 start_execution();
27 free_stack(); 27 free_stack();
@@ -35,8 +35,8 @@ void disasm(char *program) @@ -35,8 +35,8 @@ void disasm(char *program)
35 void debug(char *program) 35 void debug(char *program)
36 { 36 {
37 initialize_stack(); 37 initialize_stack();
38 - memset(regs,0x00,sizeof(short)*NUM_REGISTERS);  
39 - memset(mem,0x00,sizeof(short)*MEMSIZE); 38 + memset(regs,0x00,sizeof(uint16_t)*NUM_REGISTERS);
  39 + memset(mem,0x00,sizeof(uint16_t)*MEMSIZE);
40 load_program(program); 40 load_program(program);
41 debug_program(); 41 debug_program();
42 free_stack(); 42 free_stack();
@@ -2,6 +2,18 @@ @@ -2,6 +2,18 @@
2 // Created by imanol on 12/25/16. 2 // Created by imanol on 12/25/16.
3 // 3 //
4 4
  5 +#include <stdint.h>
  6 +#include <string.h>
5 #include "mem.h" 7 #include "mem.h"
6 8
7 -short mem[MEMSIZE];  
8 \ No newline at end of file 9 \ No newline at end of file
  10 +uint16_t mem[MEMSIZE];
  11 +
  12 +void dump_memory(uint16_t *dump)
  13 +{
  14 + memcpy(dump,mem,MEMSIZE*sizeof(uint16_t));
  15 +}
  16 +
  17 +void load_memory(uint16_t *dump)
  18 +{
  19 + memcpy(mem,dump,MEMSIZE*sizeof(uint16_t));
  20 +}
9 \ No newline at end of file 21 \ No newline at end of file
@@ -7,6 +7,11 @@ @@ -7,6 +7,11 @@
7 7
8 #define MEMSIZE 32768 8 #define MEMSIZE 32768
9 9
10 -extern short mem[MEMSIZE]; //64KiB RAM 10 +#include <stdint.h>
  11 +
  12 +extern uint16_t mem[MEMSIZE]; //64KiB RAM
  13 +
  14 +void dump_memory(uint16_t *dump);
  15 +void load_memory(uint16_t *dump);
11 16
12 #endif //SYNACORVM_MEM_H 17 #endif //SYNACORVM_MEM_H
registers.c
@@ -2,7 +2,34 @@ @@ -2,7 +2,34 @@
2 // Created by imanol on 12/25/16. 2 // Created by imanol on 12/25/16.
3 // 3 //
4 4
  5 +#include <stdio.h>
  6 +#include <string.h>
5 #include "registers.h" 7 #include "registers.h"
6 8
7 -short regs[NUM_REGISTERS];  
8 -short pc = 0;  
9 \ No newline at end of file 9 \ No newline at end of file
  10 +uint16_t regs[NUM_REGISTERS];
  11 +uint16_t pc = 0;
  12 +
  13 +void print_regs()
  14 +{
  15 + fprintf(stderr,"r0: %2x\n",regs[0]);
  16 + fprintf(stderr,"r1: %2x\n",regs[1]);
  17 + fprintf(stderr,"r2: %2x\n",regs[2]);
  18 + fprintf(stderr,"r3: %2x\n",regs[3]);
  19 + fprintf(stderr,"r4: %2x\n",regs[4]);
  20 + fprintf(stderr,"r5: %2x\n",regs[5]);
  21 + fprintf(stderr,"r6: %2x\n",regs[6]);
  22 + fprintf(stderr,"r7: %2x\n",regs[7]);
  23 + fprintf(stderr,"pc: %2x\n",pc);
  24 +}
  25 +
  26 +void dump_regs(uint16_t *dump)
  27 +{
  28 + dump[0] = pc;
  29 + memcpy(dump+1,regs,NUM_REGISTERS*sizeof(uint16_t));
  30 +}
  31 +
  32 +void load_regs(uint16_t *dump)
  33 +{
  34 + pc = dump[0];
  35 + memcpy(regs,dump+1,NUM_REGISTERS*sizeof(uint16_t));
  36 +}
10 \ No newline at end of file 37 \ No newline at end of file
registers.h
@@ -2,12 +2,18 @@ @@ -2,12 +2,18 @@
2 // Created by imanol on 12/25/16. 2 // Created by imanol on 12/25/16.
3 // 3 //
4 4
  5 +#include <stdint.h>
  6 +
5 #ifndef SYNACORVM_REGISTERS_H 7 #ifndef SYNACORVM_REGISTERS_H
6 #define SYNACORVM_REGISTERS_H 8 #define SYNACORVM_REGISTERS_H
7 9
8 #define NUM_REGISTERS 8 10 #define NUM_REGISTERS 8
9 11
10 -extern short regs[NUM_REGISTERS];  
11 -extern short pc; 12 +extern uint16_t regs[NUM_REGISTERS];
  13 +extern uint16_t pc;
  14 +
  15 +void print_regs();
  16 +void dump_regs(uint16_t *dump);
  17 +void load_regs(uint16_t *dump);
12 18
13 #endif //SYNACORVM_REGISTERS_H 19 #endif //SYNACORVM_REGISTERS_H
@@ -53,8 +53,7 @@ void shrink_stack() @@ -53,8 +53,7 @@ void shrink_stack()
53 void stack_push(uint16_t value) 53 void stack_push(uint16_t value)
54 { 54 {
55 stack[++stack_pos] = value; 55 stack[++stack_pos] = value;
56 - stack_elems++;  
57 - if(stack_pos == stack_size-1) 56 + if(++stack_elems == stack_size-1)
58 { 57 {
59 extend_stack(); 58 extend_stack();
60 } 59 }
@@ -68,11 +67,31 @@ uint16_t stack_pop() @@ -68,11 +67,31 @@ uint16_t stack_pop()
68 return -1; 67 return -1;
69 } 68 }
70 uint16_t value = stack[stack_pos--]; 69 uint16_t value = stack[stack_pos--];
71 - if(stack_size - stack_pos == 2*EXTEND_SIZE) 70 + if(stack_size - --stack_elems == 2*EXTEND_SIZE)
72 { 71 {
73 shrink_stack(); 72 shrink_stack();
74 } 73 }
75 return value; 74 return value;
76 } 75 }
77 76
  77 +uint32_t stack_dump(uint16_t **dump)
  78 +{
  79 + *dump = calloc(stack_elems,sizeof(uint16_t));
  80 + uint32_t i;
  81 + for(i = 0; i < stack_elems; i++)
  82 + {
  83 + (*dump)[i] = stack[i];
  84 + }
  85 + return stack_elems;
  86 +}
  87 +
  88 +void stack_load(uint16_t *dump,uint32_t size)
  89 +{
  90 + uint32_t i;
  91 + for(i = 0; i < size; i++)
  92 + {
  93 + stack_push(dump[i]);
  94 + }
  95 +}
  96 +
78 97
@@ -15,4 +15,7 @@ void free_stack(); @@ -15,4 +15,7 @@ void free_stack();
15 void stack_push(uint16_t value); 15 void stack_push(uint16_t value);
16 uint16_t stack_pop(); 16 uint16_t stack_pop();
17 17
  18 +uint32_t stack_dump(uint16_t **dump);
  19 +void stack_load(uint16_t *dump,uint32_t size);
  20 +
18 #endif //SYNACORVM_STACK_H 21 #endif //SYNACORVM_STACK_H