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 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 415 void start_execution()
243 416 {
244 417 uint16_t arg1;
245 418 uint16_t arg2;
246 419 uint16_t arg3;
  420 +
247 421 for(;;)
248 422 {
249 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 432 void core_dump()
381 433 {
382 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 447 exit(1);
386 448 }
387 449  
... ...
... ... @@ -35,8 +35,11 @@ void out(uint16_t src);
35 35 void in(uint16_t dst);
36 36 void nop();
37 37  
  38 +uint8_t execute_instruction(uint16_t opcode, uint16_t arg1, uint16_t arg2, uint16_t arg3);
38 39 void start_execution();
39 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 45 #endif //SYNACORVM_CPU_H
... ...
... ... @@ -6,53 +6,74 @@
6 6 #include <string.h>
7 7 #include "debug.h"
8 8  
9   -uint64_t cycle_count = 0;
  9 +//uint32_t cycle_count = 0;
10 10 uint8_t breakpoint = 1;
11 11 uint16_t breakpoints[0xFF];
12 12 uint16_t nbpoints = 0;
13 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 59 void query()
44 60 {
  61 + //TODO discard stdin
45 62 uint8_t end = 0;
46 63 uint16_t bpoint;
47 64 uint16_t mempos;
  65 + char input[100] = {0};
  66 + char filename[32];
  67 + uint8_t reg;
  68 + uint8_t value;
48 69 while(!end)
49 70 {
50 71 printf("\n> ");
51   - char command;
52   - scanf("%c", &command);
  72 + char command = 0;
  73 + fgets(input,100,stdin);
  74 + command = input[0];
53 75 if (command != '\n')
54 76 {
55   - getchar();
56 77 lastchoice = command;
57 78 }
58 79 else
... ... @@ -62,15 +83,15 @@ void query()
62 83 switch (command)
63 84 {
64 85 case 'b':
65   - scanf("%d%*c",&bpoint);
  86 + sscanf(input,"b %d\n",&bpoint);
66 87 fprintf(stderr,"Set breakpoint %d to %d",nbpoints,bpoint);
67 88 breakpoints[nbpoints] = bpoint;
68 89 nbpoints = nbpoints + 1 % 0xFF;
69 90 break;
70 91 case 'd':
71   - scanf("%d%*c",&bpoint);
  92 + sscanf(input,"d %d\n",&bpoint);
72 93 fprintf(stderr,"Deleted breakpoint %d",bpoint);
73   - breakpoints[bpoint] = NULL;
  94 + breakpoints[bpoint] = 0;
74 95 break;
75 96 case 'c':
76 97 breakpoint = 0;
... ... @@ -83,15 +104,131 @@ void query()
83 104 print_regs();
84 105 break;
85 106 case 'm':
86   - scanf("%d%*c",&mempos);
  107 + sscanf(input,"m %d\n",&mempos);
87 108 fprintf(stderr,"%d: %02x\n",mempos,mem[mempos]);
88 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 125 default:
90 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 232 void debug_program()
96 233 {
97 234 memset(breakpoints,0x00,0xFF);
... ... @@ -100,234 +237,18 @@ void debug_program()
100 237 uint16_t arg3;
101 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 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 255 \ No newline at end of file
... ...
disasm.c
1 1 #include "disasm.h"
2 2  
3   -void disassemble_program(uint64_t length)
  3 +void disassemble_program(uint32_t length)
4 4 {
5 5 uint16_t arg1;
6 6 uint16_t arg2;
... ... @@ -11,118 +11,9 @@ void disassemble_program(uint64_t length)
11 11 {
12 12 break;
13 13 }
14   - uint16_t opcode = fetch();
15 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 10 #include "registers.h"
11 11 #include "mem.h"
12 12 #include "instructions.h"
  13 +#include "debug.h"
13 14  
14 15 extern uint16_t fetch();
15   -void disassemble_program(uint64_t length);
  16 +void disassemble_program(uint32_t length);
16 17  
17 18 #endif //SYNACORVM_DISASM_H
18 19 \ No newline at end of file
... ...
... ... @@ -6,7 +6,7 @@
6 6 #include "disasm.h"
7 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 11 FILE *fp = fopen(path,"r");
12 12 fseek(fp, 0L, SEEK_END);
... ... @@ -20,8 +20,8 @@ uint64_t load_program(const char* path)
20 20 void startvm(char *program)
21 21 {
22 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 25 load_program(program);
26 26 start_execution();
27 27 free_stack();
... ... @@ -35,8 +35,8 @@ void disasm(char *program)
35 35 void debug(char *program)
36 36 {
37 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 40 load_program(program);
41 41 debug_program();
42 42 free_stack();
... ...
... ... @@ -2,6 +2,18 @@
2 2 // Created by imanol on 12/25/16.
3 3 //
4 4  
  5 +#include <stdint.h>
  6 +#include <string.h>
5 7 #include "mem.h"
6 8  
7   -short mem[MEMSIZE];
8 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 21 \ No newline at end of file
... ...
... ... @@ -7,6 +7,11 @@
7 7  
8 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 17 #endif //SYNACORVM_MEM_H
... ...
registers.c
... ... @@ -2,7 +2,34 @@
2 2 // Created by imanol on 12/25/16.
3 3 //
4 4  
  5 +#include <stdio.h>
  6 +#include <string.h>
5 7 #include "registers.h"
6 8  
7   -short regs[NUM_REGISTERS];
8   -short pc = 0;
9 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 37 \ No newline at end of file
... ...
registers.h
... ... @@ -2,12 +2,18 @@
2 2 // Created by imanol on 12/25/16.
3 3 //
4 4  
  5 +#include <stdint.h>
  6 +
5 7 #ifndef SYNACORVM_REGISTERS_H
6 8 #define SYNACORVM_REGISTERS_H
7 9  
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 19 #endif //SYNACORVM_REGISTERS_H
... ...
... ... @@ -53,8 +53,7 @@ void shrink_stack()
53 53 void stack_push(uint16_t value)
54 54 {
55 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 58 extend_stack();
60 59 }
... ... @@ -68,11 +67,31 @@ uint16_t stack_pop()
68 67 return -1;
69 68 }
70 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 72 shrink_stack();
74 73 }
75 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 15 void stack_push(uint16_t value);
16 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 21 #endif //SYNACORVM_STACK_H
... ...