Commit b5e96df63922e1408460c3f96f7f8a3a2865b091

Authored by Imanol-Mikel Barba Sabariego
1 parent 086defff

VM implemented, debugger and disasm WIP

Too many changes to show.

To preserve performance only 4 of 13 files are displayed.

.idea/misc.xml
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project version="4"> 2 <project version="4">
3 <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" /> 3 <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
  4 + <component name="CidrRootsConfiguration">
  5 + <sourceRoots />
  6 + <libraryRoots />
  7 + <excludeRoots />
  8 + </component>
4 <component name="ProjectLevelVcsManager" settingsEditedManually="false"> 9 <component name="ProjectLevelVcsManager" settingsEditedManually="false">
5 <OptionsSetting value="true" id="Add" /> 10 <OptionsSetting value="true" id="Add" />
6 <OptionsSetting value="true" id="Remove" /> 11 <OptionsSetting value="true" id="Remove" />
.idea/vcs.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="$PROJECT_DIR$" vcs="Git" />
  5 + </component>
  6 +</project>
0 \ No newline at end of file 7 \ No newline at end of file
@@ -5,19 +5,21 @@ @@ -5,19 +5,21 @@
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include "cpu.h" 6 #include "cpu.h"
7 7
8 -void mov(short dst, short src) 8 +uint64_t cycle_count = 0;
  9 +
  10 +void mov(uint16_t dst, uint16_t src)
9 { 11 {
10 if(src > MAX_INT) 12 if(src > MAX_INT)
11 { 13 {
12 - regs[dst] = regs[src % (MAX_INT+1)]; 14 + regs[dst % (MAX_INT+1)] = regs[src % (MAX_INT+1)];
13 } 15 }
14 else 16 else
15 { 17 {
16 - regs[dst] = src; 18 + regs[dst % (MAX_INT+1)] = src;
17 } 19 }
18 } 20 }
19 21
20 -void push(short src) 22 +void push(uint16_t src)
21 { 23 {
22 if(src > MAX_INT) 24 if(src > MAX_INT)
23 { 25 {
@@ -29,9 +31,9 @@ void push(short src) @@ -29,9 +31,9 @@ void push(short src)
29 } 31 }
30 } 32 }
31 33
32 -void pop(short dst) 34 +void pop(uint16_t dst)
33 { 35 {
34 - short value = stack_pop(); 36 + uint16_t value = stack_pop();
35 if(STACK_FAULT) 37 if(STACK_FAULT)
36 { 38 {
37 fprintf(stderr,"CRITICAL: STACK VIOLATION\n"); 39 fprintf(stderr,"CRITICAL: STACK VIOLATION\n");
@@ -40,7 +42,7 @@ void pop(short dst) @@ -40,7 +42,7 @@ void pop(short dst)
40 regs[dst % (MAX_INT+1)] = value; 42 regs[dst % (MAX_INT+1)] = value;
41 } 43 }
42 44
43 -void teq(short dst, short a, short b) 45 +void teq(uint16_t dst, uint16_t a, uint16_t b)
44 { 46 {
45 if(a > MAX_INT) 47 if(a > MAX_INT)
46 { 48 {
@@ -53,7 +55,7 @@ void teq(short dst, short a, short b) @@ -53,7 +55,7 @@ void teq(short dst, short a, short b)
53 regs[dst % (MAX_INT+1)] = (a == b); 55 regs[dst % (MAX_INT+1)] = (a == b);
54 } 56 }
55 57
56 -void tgt(short dst, short a, short b) 58 +void tgt(uint16_t dst, uint16_t a, uint16_t b)
57 { 59 {
58 if(a > MAX_INT) 60 if(a > MAX_INT)
59 { 61 {
@@ -66,7 +68,7 @@ void tgt(short dst, short a, short b) @@ -66,7 +68,7 @@ void tgt(short dst, short a, short b)
66 regs[dst % (MAX_INT+1)] = (a > b); 68 regs[dst % (MAX_INT+1)] = (a > b);
67 } 69 }
68 70
69 -void jmp(short dst) 71 +void jmp(uint16_t dst)
70 { 72 {
71 if(dst > MAX_INT) 73 if(dst > MAX_INT)
72 { 74 {
@@ -78,11 +80,11 @@ void jmp(short dst) @@ -78,11 +80,11 @@ void jmp(short dst)
78 } 80 }
79 } 81 }
80 82
81 -void jnz(short cond, short dst) 83 +void jnz(uint16_t cond, uint16_t dst)
82 { 84 {
83 if(cond > MAX_INT) 85 if(cond > MAX_INT)
84 { 86 {
85 - cond = regs[dst % (MAX_INT+1)]; 87 + cond = regs[cond % (MAX_INT+1)];
86 } 88 }
87 if(cond) 89 if(cond)
88 { 90 {
@@ -90,11 +92,11 @@ void jnz(short cond, short dst) @@ -90,11 +92,11 @@ void jnz(short cond, short dst)
90 } 92 }
91 } 93 }
92 94
93 -void jz(short cond, short dst) 95 +void jz(uint16_t cond, uint16_t dst)
94 { 96 {
95 if(cond > MAX_INT) 97 if(cond > MAX_INT)
96 { 98 {
97 - cond = regs[dst % (MAX_INT+1)]; 99 + cond = regs[cond % (MAX_INT+1)];
98 } 100 }
99 if(!cond) 101 if(!cond)
100 { 102 {
@@ -102,7 +104,7 @@ void jz(short cond, short dst) @@ -102,7 +104,7 @@ void jz(short cond, short dst)
102 } 104 }
103 } 105 }
104 106
105 -void add(short dst, short a, short b) 107 +void add(uint16_t dst, uint16_t a, uint16_t b)
106 { 108 {
107 if(a > MAX_INT) 109 if(a > MAX_INT)
108 { 110 {
@@ -115,7 +117,7 @@ void add(short dst, short a, short b) @@ -115,7 +117,7 @@ void add(short dst, short a, short b)
115 regs[dst % (MAX_INT+1)] = (a + b) % (MAX_INT+1); 117 regs[dst % (MAX_INT+1)] = (a + b) % (MAX_INT+1);
116 } 118 }
117 119
118 -void mult(short dst, short a, short b) 120 +void mult(uint16_t dst, uint16_t a, uint16_t b)
119 { 121 {
120 if(a > MAX_INT) 122 if(a > MAX_INT)
121 { 123 {
@@ -128,7 +130,7 @@ void mult(short dst, short a, short b) @@ -128,7 +130,7 @@ void mult(short dst, short a, short b)
128 regs[dst % (MAX_INT+1)] = (a * b) % (MAX_INT+1); 130 regs[dst % (MAX_INT+1)] = (a * b) % (MAX_INT+1);
129 } 131 }
130 132
131 -void mod(short dst, short a, short b) 133 +void mod(uint16_t dst, uint16_t a, uint16_t b)
132 { 134 {
133 if(a > MAX_INT) 135 if(a > MAX_INT)
134 { 136 {
@@ -141,7 +143,7 @@ void mod(short dst, short a, short b) @@ -141,7 +143,7 @@ void mod(short dst, short a, short b)
141 regs[dst % (MAX_INT+1)] = (a % b); 143 regs[dst % (MAX_INT+1)] = (a % b);
142 } 144 }
143 145
144 -void and(short dst, short a, short b) 146 +void and(uint16_t dst, uint16_t a, uint16_t b)
145 { 147 {
146 if(a > MAX_INT) 148 if(a > MAX_INT)
147 { 149 {
@@ -154,7 +156,7 @@ void and(short dst, short a, short b) @@ -154,7 +156,7 @@ void and(short dst, short a, short b)
154 regs[dst % (MAX_INT+1)] = (a & b); 156 regs[dst % (MAX_INT+1)] = (a & b);
155 } 157 }
156 158
157 -void or(short dst, short a, short b) 159 +void or(uint16_t dst, uint16_t a, uint16_t b)
158 { 160 {
159 if(a > MAX_INT) 161 if(a > MAX_INT)
160 { 162 {
@@ -167,7 +169,7 @@ void or(short dst, short a, short b) @@ -167,7 +169,7 @@ void or(short dst, short a, short b)
167 regs[dst % (MAX_INT+1)] = (a | b); 169 regs[dst % (MAX_INT+1)] = (a | b);
168 } 170 }
169 171
170 -void not(short dst, short src) 172 +void not(uint16_t dst, uint16_t src)
171 { 173 {
172 if(src > MAX_INT) 174 if(src > MAX_INT)
173 { 175 {
@@ -176,16 +178,16 @@ void not(short dst, short src) @@ -176,16 +178,16 @@ void not(short dst, short src)
176 regs[dst % (MAX_INT+1)] = ~src & 0x7FFF; 178 regs[dst % (MAX_INT+1)] = ~src & 0x7FFF;
177 } 179 }
178 180
179 -void load(short src, short dst) 181 +void load(uint16_t dst, uint16_t src)
180 { 182 {
181 if(src > MAX_INT) 183 if(src > MAX_INT)
182 { 184 {
183 src = regs[src % (MAX_INT+1)]; 185 src = regs[src % (MAX_INT+1)];
184 } 186 }
185 - regs[dst % (MAX_INT+1)] = src; 187 + regs[dst % (MAX_INT+1)] = mem[src];
186 } 188 }
187 189
188 -void stor(short dst, short src) 190 +void stor(uint16_t dst, uint16_t src)
189 { 191 {
190 if(src > MAX_INT) 192 if(src > MAX_INT)
191 { 193 {
@@ -201,7 +203,7 @@ void stor(short dst, short src) @@ -201,7 +203,7 @@ void stor(short dst, short src)
201 } 203 }
202 } 204 }
203 205
204 -void call(short dst) 206 +void call(uint16_t dst)
205 { 207 {
206 stack_push(pc); 208 stack_push(pc);
207 jmp(dst); 209 jmp(dst);
@@ -213,15 +215,19 @@ uint8_t ret() @@ -213,15 +215,19 @@ uint8_t ret()
213 return STACK_FAULT; 215 return STACK_FAULT;
214 } 216 }
215 217
216 -void out(unsigned char a) 218 +void out(uint16_t src)
217 { 219 {
218 - putchar(a); 220 + if(src > MAX_INT)
  221 + {
  222 + src = regs[src % (MAX_INT+1)];
  223 + }
  224 + putchar(src);
219 } 225 }
220 226
221 -void in(short dst) 227 +void in(uint16_t dst)
222 { 228 {
223 int c = getchar(); 229 int c = getchar();
224 - regs[dst] = (short)c; 230 + regs[dst % (MAX_INT + 1)] = (uint16_t)c;
225 } 231 }
226 232
227 void nop() 233 void nop()
@@ -229,24 +235,26 @@ void nop() @@ -229,24 +235,26 @@ void nop()
229 return; 235 return;
230 } 236 }
231 237
232 -short fetch() 238 +uint16_t fetch()
233 { 239 {
234 - short value = mem[pc++];  
235 - if(value < 0) 240 + /*if(pc == 0x5bf-1)
236 { 241 {
237 - value *= -1;  
238 - } 242 + //break
  243 + }*/
  244 + uint16_t value = mem[pc++];
  245 + //printf("0x%2x (0x%2x)",pc,pc*sizeof(uint16_t));
  246 + //printf(" cycle: %d\n",cycle_count++);
239 return value; 247 return value;
240 } 248 }
241 249
242 void start_execution() 250 void start_execution()
243 { 251 {
244 - short arg1;  
245 - short arg2;  
246 - short arg3; 252 + uint16_t arg1;
  253 + uint16_t arg2;
  254 + uint16_t arg3;
247 for(;;) 255 for(;;)
248 { 256 {
249 - short opcode = fetch(); 257 + uint16_t opcode = fetch();
250 switch(opcode) 258 switch(opcode)
251 { 259 {
252 case HALT: 260 case HALT:
@@ -346,7 +354,8 @@ void start_execution() @@ -346,7 +354,8 @@ void start_execution()
346 } 354 }
347 break; 355 break;
348 case OUT: 356 case OUT:
349 - out((unsigned char)fetch()); 357 + arg1 = fetch();
  358 + out(arg1);
350 break; 359 break;
351 case IN: 360 case IN:
352 arg1 = fetch(); 361 arg1 = fetch();
@@ -377,4 +386,4 @@ void core_dump() @@ -377,4 +386,4 @@ void core_dump()
377 //dump memory to file 386 //dump memory to file
378 //dump stack to file 387 //dump stack to file
379 exit(1); 388 exit(1);
380 -}  
381 \ No newline at end of file 389 \ No newline at end of file
  390 +}
data/arch-spec 0 → 100644
  1 +== Synacor Challenge ==
  2 +In this challenge, your job is to use this architecture spec to create a
  3 +virtual machine capable of running the included binary. Along the way,
  4 +you will find codes; submit these to the challenge website to track
  5 +your progress. Good luck!
  6 +
  7 +
  8 +== architecture ==
  9 +- three storage regions
  10 + - memory with 15-bit address space storing 16-bit values
  11 + - eight registers
  12 + - an unbounded stack which holds individual 16-bit values
  13 +- all numbers are unsigned integers 0..32767 (15-bit)
  14 +- all math is modulo 32768; 32758 + 15 => 5
  15 +
  16 +== binary format ==
  17 +- each number is stored as a 16-bit little-endian pair (low byte, high byte)
  18 +- numbers 0..32767 mean a literal value
  19 +- numbers 32768..32775 instead mean registers 0..7
  20 +- numbers 32776..65535 are invalid
  21 +- programs are loaded into memory starting at address 0
  22 +- address 0 is the first 16-bit value, address 1 is the second 16-bit value, etc
  23 +
  24 +== execution ==
  25 +- After an operation is executed, the next instruction to read is immediately after the last argument of the current operation. If a jump was performed, the next operation is instead the exact destination of the jump.
  26 +- Encountering a register as an operation argument should be taken as reading from the register or setting into the register as appropriate.
  27 +
  28 +== hints ==
  29 +- Start with operations 0, 19, and 21.
  30 +- Here's a code for the challenge website: WdXrmkgDVVgK
  31 +- The program "9,32768,32769,4,19,32768" occupies six memory addresses and should:
  32 + - Store into register 0 the sum of 4 and the value contained in register 1.
  33 + - Output to the terminal the character with the ascii code contained in register 0.
  34 +
  35 +== opcode listing ==
  36 +halt: 0
  37 + stop execution and terminate the program
  38 +set: 1 a b
  39 + set register <a> to the value of <b>
  40 +push: 2 a
  41 + push <a> onto the stack
  42 +pop: 3 a
  43 + remove the top element from the stack and write it into <a>; empty stack = error
  44 +eq: 4 a b c
  45 + set <a> to 1 if <b> is equal to <c>; set it to 0 otherwise
  46 +gt: 5 a b c
  47 + set <a> to 1 if <b> is greater than <c>; set it to 0 otherwise
  48 +jmp: 6 a
  49 + jump to <a>
  50 +jt: 7 a b
  51 + if <a> is nonzero, jump to <b>
  52 +jf: 8 a b
  53 + if <a> is zero, jump to <b>
  54 +add: 9 a b c
  55 + assign into <a> the sum of <b> and <c> (modulo 32768)
  56 +mult: 10 a b c
  57 + store into <a> the product of <b> and <c> (modulo 32768)
  58 +mod: 11 a b c
  59 + store into <a> the remainder of <b> divided by <c>
  60 +and: 12 a b c
  61 + stores into <a> the bitwise and of <b> and <c>
  62 +or: 13 a b c
  63 + stores into <a> the bitwise or of <b> and <c>
  64 +not: 14 a b
  65 + stores 15-bit bitwise inverse of <b> in <a>
  66 +rmem: 15 a b
  67 + read memory at address <b> and write it to <a>
  68 +wmem: 16 a b
  69 + write the value from <b> into memory at address <a>
  70 +call: 17 a
  71 + write the address of the next instruction to the stack and jump to <a>
  72 +ret: 18
  73 + remove the top element from the stack and jump to it; empty stack = halt
  74 +out: 19 a
  75 + write the character represented by ascii code <a> to the terminal
  76 +in: 20 a
  77 + read a character from the terminal and write its ascii code to <a>; it can be assumed that once input starts, it will continue until a newline is encountered; this means that you can safely read whole lines from the keyboard and trust that they will be fully read
  78 +noop: 21
  79 + no operation