Commit 9ff101a8a3ee99925f58ed96d34e62e7a7220303
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)
Showing
12 changed files
with
460 additions
and
510 deletions
cpu.c
@@ -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 |
cpu.h
@@ -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 |
debug.c
@@ -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",®,&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 |
main.c
@@ -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(); |
mem.c
@@ -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 |
mem.h
@@ -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 |
stack.c
@@ -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 |
stack.h
@@ -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 |