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 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <project version="4">
3 3 <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
  4 + <component name="CidrRootsConfiguration">
  5 + <sourceRoots />
  6 + <libraryRoots />
  7 + <excludeRoots />
  8 + </component>
4 9 <component name="ProjectLevelVcsManager" settingsEditedManually="false">
5 10 <OptionsSetting value="true" id="Add" />
6 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 7 \ No newline at end of file
... ...
... ... @@ -5,19 +5,21 @@
5 5 #include <stdlib.h>
6 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 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 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 24 if(src > MAX_INT)
23 25 {
... ... @@ -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 37 if(STACK_FAULT)
36 38 {
37 39 fprintf(stderr,"CRITICAL: STACK VIOLATION\n");
... ... @@ -40,7 +42,7 @@ void pop(short dst)
40 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 47 if(a > MAX_INT)
46 48 {
... ... @@ -53,7 +55,7 @@ void teq(short dst, short a, short b)
53 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 60 if(a > MAX_INT)
59 61 {
... ... @@ -66,7 +68,7 @@ void tgt(short dst, short a, short b)
66 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 73 if(dst > MAX_INT)
72 74 {
... ... @@ -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 85 if(cond > MAX_INT)
84 86 {
85   - cond = regs[dst % (MAX_INT+1)];
  87 + cond = regs[cond % (MAX_INT+1)];
86 88 }
87 89 if(cond)
88 90 {
... ... @@ -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 97 if(cond > MAX_INT)
96 98 {
97   - cond = regs[dst % (MAX_INT+1)];
  99 + cond = regs[cond % (MAX_INT+1)];
98 100 }
99 101 if(!cond)
100 102 {
... ... @@ -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 109 if(a > MAX_INT)
108 110 {
... ... @@ -115,7 +117,7 @@ void add(short dst, short a, short b)
115 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 122 if(a > MAX_INT)
121 123 {
... ... @@ -128,7 +130,7 @@ void mult(short dst, short a, short b)
128 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 135 if(a > MAX_INT)
134 136 {
... ... @@ -141,7 +143,7 @@ void mod(short dst, short a, short b)
141 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 148 if(a > MAX_INT)
147 149 {
... ... @@ -154,7 +156,7 @@ void and(short dst, short a, short b)
154 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 161 if(a > MAX_INT)
160 162 {
... ... @@ -167,7 +169,7 @@ void or(short dst, short a, short b)
167 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 174 if(src > MAX_INT)
173 175 {
... ... @@ -176,16 +178,16 @@ void not(short dst, short src)
176 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 183 if(src > MAX_INT)
182 184 {
183 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 192 if(src > MAX_INT)
191 193 {
... ... @@ -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 208 stack_push(pc);
207 209 jmp(dst);
... ... @@ -213,15 +215,19 @@ uint8_t ret()
213 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 229 int c = getchar();
224   - regs[dst] = (short)c;
  230 + regs[dst % (MAX_INT + 1)] = (uint16_t)c;
225 231 }
226 232  
227 233 void nop()
... ... @@ -229,24 +235,26 @@ void nop()
229 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 247 return value;
240 248 }
241 249  
242 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 255 for(;;)
248 256 {
249   - short opcode = fetch();
  257 + uint16_t opcode = fetch();
250 258 switch(opcode)
251 259 {
252 260 case HALT:
... ... @@ -346,7 +354,8 @@ void start_execution()
346 354 }
347 355 break;
348 356 case OUT:
349   - out((unsigned char)fetch());
  357 + arg1 = fetch();
  358 + out(arg1);
350 359 break;
351 360 case IN:
352 361 arg1 = fetch();
... ... @@ -377,4 +386,4 @@ void core_dump()
377 386 //dump memory to file
378 387 //dump stack to file
379 388 exit(1);
380   -}
381 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
... ...