Commit 5e06910cf73286209f0b134f2c969c22da434c03
1 parent
0f27ef74
Implemented. Testing and debugging...
Showing
11 changed files
with
433 additions
and
27 deletions
.idea/synacorvm.iml
@@ -4,13 +4,13 @@ | @@ -4,13 +4,13 @@ | ||
4 | <content url="file://$MODULE_DIR$"> | 4 | <content url="file://$MODULE_DIR$"> |
5 | <sourceFolder url="file://$MODULE_DIR$/cpu.h" isTestSource="false" /> | 5 | <sourceFolder url="file://$MODULE_DIR$/cpu.h" isTestSource="false" /> |
6 | <sourceFolder url="file://$MODULE_DIR$/CMakeLists.txt" isTestSource="false" /> | 6 | <sourceFolder url="file://$MODULE_DIR$/CMakeLists.txt" isTestSource="false" /> |
7 | - <sourceFolder url="file://$MODULE_DIR$/binary_decoder.c" isTestSource="false" /> | 7 | + <sourceFolder url="file://$MODULE_DIR$/main.c" isTestSource="false" /> |
8 | <sourceFolder url="file://$MODULE_DIR$/stack.c" isTestSource="false" /> | 8 | <sourceFolder url="file://$MODULE_DIR$/stack.c" isTestSource="false" /> |
9 | <sourceFolder url="file://$MODULE_DIR$/mem.h" isTestSource="false" /> | 9 | <sourceFolder url="file://$MODULE_DIR$/mem.h" isTestSource="false" /> |
10 | - <sourceFolder url="file://$MODULE_DIR$/main.c" isTestSource="false" /> | ||
11 | <sourceFolder url="file://$MODULE_DIR$/cpu.c" isTestSource="false" /> | 10 | <sourceFolder url="file://$MODULE_DIR$/cpu.c" isTestSource="false" /> |
11 | + <sourceFolder url="file://$MODULE_DIR$/mem.c" isTestSource="false" /> | ||
12 | <sourceFolder url="file://$MODULE_DIR$/registers.h" isTestSource="false" /> | 12 | <sourceFolder url="file://$MODULE_DIR$/registers.h" isTestSource="false" /> |
13 | - <sourceFolder url="file://$MODULE_DIR$/binary_decoder.h" isTestSource="false" /> | 13 | + <sourceFolder url="file://$MODULE_DIR$/registers.c" isTestSource="false" /> |
14 | <sourceFolder url="file://$MODULE_DIR$/stack.h" isTestSource="false" /> | 14 | <sourceFolder url="file://$MODULE_DIR$/stack.h" isTestSource="false" /> |
15 | </content> | 15 | </content> |
16 | <orderEntry type="sourceFolder" forTests="false" /> | 16 | <orderEntry type="sourceFolder" forTests="false" /> |
CMakeLists.txt
@@ -3,5 +3,5 @@ project(synacorvm) | @@ -3,5 +3,5 @@ project(synacorvm) | ||
3 | 3 | ||
4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") |
5 | 5 | ||
6 | -set(SOURCE_FILES main.c cpu.c cpu.h binary_decoder.c binary_decoder.h registers.h mem.h stack.c stack.h) | 6 | +set(SOURCE_FILES main.c cpu.c cpu.h registers.h mem.h stack.c stack.h registers.c mem.c) |
7 | add_executable(synacorvm ${SOURCE_FILES}) | 7 | add_executable(synacorvm ${SOURCE_FILES}) |
8 | \ No newline at end of file | 8 | \ No newline at end of file |
cpu.c
@@ -2,15 +2,333 @@ | @@ -2,15 +2,333 @@ | ||
2 | // Created by imanol on 12/25/16. | 2 | // Created by imanol on 12/25/16. |
3 | // | 3 | // |
4 | 4 | ||
5 | +#include <stdlib.h> | ||
5 | #include "cpu.h" | 6 | #include "cpu.h" |
6 | 7 | ||
8 | +void mov(short dst, short src) | ||
9 | +{ | ||
10 | + if(src > MAX_INT) | ||
11 | + { | ||
12 | + regs[dst] = regs[src % (MAX_INT+1)]; | ||
13 | + } | ||
14 | + else | ||
15 | + { | ||
16 | + regs[dst] = src; | ||
17 | + } | ||
18 | +} | ||
19 | + | ||
20 | +void push(short src) | ||
21 | +{ | ||
22 | + if(src > MAX_INT) | ||
23 | + { | ||
24 | + stack_push(regs[src % (MAX_INT+1)]); | ||
25 | + } | ||
26 | + else | ||
27 | + { | ||
28 | + stack_push(src); | ||
29 | + } | ||
30 | +} | ||
31 | + | ||
32 | +void pop(short dst) | ||
33 | +{ | ||
34 | + short value = stack_pop(); | ||
35 | + if(STACK_FAULT) | ||
36 | + { | ||
37 | + fprintf(stderr,"CRITICAL: STACK VIOLATION\n"); | ||
38 | + core_dump(); | ||
39 | + } | ||
40 | + regs[dst] = value; | ||
41 | +} | ||
42 | + | ||
43 | +void teq(short dst, short a, short b) | ||
44 | +{ | ||
45 | + if(a > MAX_INT) | ||
46 | + { | ||
47 | + a = regs[a % (MAX_INT+1)]; | ||
48 | + } | ||
49 | + if(b > MAX_INT) | ||
50 | + { | ||
51 | + b = regs[b % (MAX_INT+1)]; | ||
52 | + } | ||
53 | + regs[dst % (MAX_INT+1)] = (a == b); | ||
54 | +} | ||
55 | + | ||
56 | +void tgt(short dst, short a, short b) | ||
57 | +{ | ||
58 | + if(a > MAX_INT) | ||
59 | + { | ||
60 | + a = regs[a % (MAX_INT+1)]; | ||
61 | + } | ||
62 | + if(b > MAX_INT) | ||
63 | + { | ||
64 | + b = regs[b % (MAX_INT+1)]; | ||
65 | + } | ||
66 | + regs[dst % (MAX_INT+1)] = (a > b); | ||
67 | +} | ||
68 | + | ||
69 | +void jmp(short dst) | ||
70 | +{ | ||
71 | + if(dst > MAX_INT) | ||
72 | + { | ||
73 | + pc = regs[dst % (MAX_INT+1)]; | ||
74 | + } | ||
75 | + else | ||
76 | + { | ||
77 | + pc = dst; | ||
78 | + } | ||
79 | +} | ||
80 | + | ||
81 | +void jnz(short cond, short dst) | ||
82 | +{ | ||
83 | + if(cond) | ||
84 | + { | ||
85 | + jmp(dst); | ||
86 | + } | ||
87 | +} | ||
88 | + | ||
89 | +void jz(short cond, short dst) | ||
90 | +{ | ||
91 | + if(!cond) | ||
92 | + { | ||
93 | + jmp(dst); | ||
94 | + } | ||
95 | +} | ||
96 | + | ||
97 | +void add(short dst, short a, short b) | ||
98 | +{ | ||
99 | + if(a > MAX_INT) | ||
100 | + { | ||
101 | + a = regs[a % (MAX_INT+1)]; | ||
102 | + } | ||
103 | + if(b > MAX_INT) | ||
104 | + { | ||
105 | + b = regs[b % (MAX_INT+1)]; | ||
106 | + } | ||
107 | + regs[dst % (MAX_INT+1)] = (a + b) % (MAX_INT+1); | ||
108 | +} | ||
109 | + | ||
110 | +void mult(short dst, short a, short b) | ||
111 | +{ | ||
112 | + if(a > MAX_INT) | ||
113 | + { | ||
114 | + a = regs[a % (MAX_INT+1)]; | ||
115 | + } | ||
116 | + if(b > MAX_INT) | ||
117 | + { | ||
118 | + b = regs[b % (MAX_INT+1)]; | ||
119 | + } | ||
120 | + regs[dst % (MAX_INT+1)] = (a * b) % (MAX_INT+1); | ||
121 | +} | ||
122 | + | ||
123 | +void mod(short dst, short a, short b) | ||
124 | +{ | ||
125 | + if(a > MAX_INT) | ||
126 | + { | ||
127 | + a = regs[a % (MAX_INT+1)]; | ||
128 | + } | ||
129 | + if(b > MAX_INT) | ||
130 | + { | ||
131 | + b = regs[b % (MAX_INT+1)]; | ||
132 | + } | ||
133 | + regs[dst % (MAX_INT+1)] = (a % b); | ||
134 | +} | ||
135 | + | ||
136 | +void and(short dst, short a, short b) | ||
137 | +{ | ||
138 | + if(a > MAX_INT) | ||
139 | + { | ||
140 | + a = regs[a % (MAX_INT+1)]; | ||
141 | + } | ||
142 | + if(b > MAX_INT) | ||
143 | + { | ||
144 | + b = regs[b % (MAX_INT+1)]; | ||
145 | + } | ||
146 | + regs[dst % (MAX_INT+1)] = (a & b); | ||
147 | +} | ||
148 | + | ||
149 | +void or(short dst, short a, short b) | ||
150 | +{ | ||
151 | + if(a > MAX_INT) | ||
152 | + { | ||
153 | + a = regs[a % (MAX_INT+1)]; | ||
154 | + } | ||
155 | + if(b > MAX_INT) | ||
156 | + { | ||
157 | + b = regs[b % (MAX_INT+1)]; | ||
158 | + } | ||
159 | + regs[dst % (MAX_INT+1)] = (a | b); | ||
160 | +} | ||
161 | + | ||
162 | +void not(short dst, short src) | ||
163 | +{ | ||
164 | + if(src > MAX_INT) | ||
165 | + { | ||
166 | + src = regs[src % (MAX_INT+1)]; | ||
167 | + } | ||
168 | + regs[dst % (MAX_INT+1)] = ~src & 0x7FFF; | ||
169 | +} | ||
170 | + | ||
171 | +void load(short src, short dst) | ||
172 | +{ | ||
173 | + if(src > MAX_INT) | ||
174 | + { | ||
175 | + src = regs[src % (MAX_INT+1)]; | ||
176 | + } | ||
177 | + regs[dst % (MAX_INT+1)] = src; | ||
178 | +} | ||
179 | + | ||
180 | +void stor(short dst, short src) | ||
181 | +{ | ||
182 | + if(src > MAX_INT) | ||
183 | + { | ||
184 | + src = regs[src % (MAX_INT+1)]; | ||
185 | + } | ||
186 | + if(dst > MAX_INT) | ||
187 | + { | ||
188 | + mem[regs[dst % (MAX_INT+1)]] = src; | ||
189 | + } | ||
190 | + else | ||
191 | + { | ||
192 | + mem[dst] = src; | ||
193 | + } | ||
194 | +} | ||
195 | + | ||
196 | +void call(short dst) | ||
197 | +{ | ||
198 | + stack_push(pc); | ||
199 | + jmp(dst); | ||
200 | +} | ||
201 | + | ||
202 | +uint8_t ret() | ||
203 | +{ | ||
204 | + pc = stack_pop(); | ||
205 | + return STACK_FAULT; | ||
206 | +} | ||
207 | + | ||
208 | +void out(unsigned char a) | ||
209 | +{ | ||
210 | + putchar(a); | ||
211 | +} | ||
212 | + | ||
213 | +void in(short dst) | ||
214 | +{ | ||
215 | + int c = getchar(); | ||
216 | + regs[dst] = (short)c; | ||
217 | +} | ||
218 | + | ||
7 | void nop() | 219 | void nop() |
8 | { | 220 | { |
9 | return; | 221 | return; |
10 | } | 222 | } |
11 | 223 | ||
12 | -void out(unsigned char a) | 224 | +void start_execution() |
13 | { | 225 | { |
14 | - printf("%c",a); | 226 | + for(;;) |
227 | + { | ||
228 | + short opcode = mem[pc++]; | ||
229 | + switch(opcode) | ||
230 | + { | ||
231 | + case HALT: | ||
232 | + return; | ||
233 | + case MOV: | ||
234 | + mov(mem[pc],mem[pc+1]); | ||
235 | + pc += 2; | ||
236 | + break; | ||
237 | + case PUSH: | ||
238 | + push(mem[pc++]); | ||
239 | + break; | ||
240 | + case POP: | ||
241 | + pop(mem[pc++]); | ||
242 | + break; | ||
243 | + case TEQ: | ||
244 | + teq(mem[pc],mem[pc+1],mem[pc+2]); | ||
245 | + pc += 3; | ||
246 | + break; | ||
247 | + case TGT: | ||
248 | + tgt(mem[pc],mem[pc+1],mem[pc+2]); | ||
249 | + pc += 3; | ||
250 | + break; | ||
251 | + case JMP: | ||
252 | + jmp(mem[pc++]); | ||
253 | + break; | ||
254 | + case JNZ: | ||
255 | + jnz(mem[pc],mem[pc+1]); | ||
256 | + pc += 2; | ||
257 | + break; | ||
258 | + case JZ: | ||
259 | + jz(mem[pc],mem[pc+1]); | ||
260 | + pc += 2; | ||
261 | + break; | ||
262 | + case ADD: | ||
263 | + add(mem[pc],mem[pc+1],mem[pc+2]); | ||
264 | + pc += 3; | ||
265 | + break; | ||
266 | + case MULT: | ||
267 | + mult(mem[pc],mem[pc+1],mem[pc+2]); | ||
268 | + pc += 3; | ||
269 | + break; | ||
270 | + case MOD: | ||
271 | + mod(mem[pc],mem[pc+1],mem[pc+2]); | ||
272 | + pc += 3; | ||
273 | + break; | ||
274 | + case AND: | ||
275 | + and(mem[pc],mem[pc+1],mem[pc+2]); | ||
276 | + pc += 3; | ||
277 | + break; | ||
278 | + case OR: | ||
279 | + or(mem[pc],mem[pc+1],mem[pc+2]); | ||
280 | + pc += 3; | ||
281 | + break; | ||
282 | + case NOT: | ||
283 | + not(mem[pc],mem[pc+1]); | ||
284 | + pc += 2; | ||
285 | + break; | ||
286 | + case LOAD: | ||
287 | + load(mem[pc],mem[pc+1]); | ||
288 | + pc += 2; | ||
289 | + break; | ||
290 | + case STOR: | ||
291 | + stor(mem[pc],mem[pc+1]); | ||
292 | + pc += 2; | ||
293 | + break; | ||
294 | + case CALL: | ||
295 | + call(mem[pc++]); | ||
296 | + break; | ||
297 | + case RET: | ||
298 | + if(ret()) | ||
299 | + { | ||
300 | + return; | ||
301 | + } | ||
302 | + break; | ||
303 | + case OUT: | ||
304 | + out((unsigned char)mem[pc++]); | ||
305 | + break; | ||
306 | + case IN: | ||
307 | + in(mem[pc++]); | ||
308 | + break; | ||
309 | + case NOP: | ||
310 | + nop(); | ||
311 | + break; | ||
312 | + default: | ||
313 | + fprintf(stderr,"CRITICAL: UNKNOWN OPCODE %2x FOUND IN %2x\n",opcode,pc); | ||
314 | + core_dump(); | ||
315 | + break; | ||
316 | + } | ||
317 | + } | ||
15 | } | 318 | } |
16 | 319 | ||
320 | +void core_dump() | ||
321 | +{ | ||
322 | + fprintf(stderr,"r0: %2x\n",regs[0]); | ||
323 | + fprintf(stderr,"r1: %2x\n",regs[1]); | ||
324 | + fprintf(stderr,"r2: %2x\n",regs[2]); | ||
325 | + fprintf(stderr,"r3: %2x\n",regs[3]); | ||
326 | + fprintf(stderr,"r4: %2x\n",regs[4]); | ||
327 | + fprintf(stderr,"r5: %2x\n",regs[5]); | ||
328 | + fprintf(stderr,"r6: %2x\n",regs[6]); | ||
329 | + fprintf(stderr,"r7: %2x\n",regs[7]); | ||
330 | + fprintf(stderr,"pc: %2x\n",pc); | ||
331 | + //dump memory to file | ||
332 | + //dump stack to file | ||
333 | + exit(1); | ||
334 | +} | ||
17 | \ No newline at end of file | 335 | \ No newline at end of file |
cpu.h
@@ -6,5 +6,37 @@ | @@ -6,5 +6,37 @@ | ||
6 | #define SYNACORVM_CPU_H | 6 | #define SYNACORVM_CPU_H |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | +#include "mem.h" | ||
10 | +#include "stack.h" | ||
11 | +#include "registers.h" | ||
12 | + | ||
13 | +#define MAX_INT 32767 | ||
14 | + | ||
15 | +#define HALT 0x0000 | ||
16 | +#define MOV 0x0001 | ||
17 | +#define PUSH 0x0002 | ||
18 | +#define POP 0x0003 | ||
19 | +#define TEQ 0x0004 | ||
20 | +#define TGT 0x0005 | ||
21 | +#define JMP 0x0006 | ||
22 | +#define JNZ 0x0007 | ||
23 | +#define JZ 0x0008 | ||
24 | +#define ADD 0x0009 | ||
25 | +#define MULT 0x000A | ||
26 | +#define MOD 0x000B | ||
27 | +#define AND 0x000C | ||
28 | +#define OR 0x000D | ||
29 | +#define NOT 0x000E | ||
30 | +#define LOAD 0x000F | ||
31 | +#define STOR 0x0010 | ||
32 | +#define CALL 0x0011 | ||
33 | +#define RET 0x0012 | ||
34 | +#define OUT 0x0013 | ||
35 | +#define IN 0x0014 | ||
36 | +#define NOP 0x0015 | ||
37 | + | ||
38 | + | ||
39 | +void start_execution(); | ||
40 | +void core_dump(); | ||
9 | 41 | ||
10 | #endif //SYNACORVM_CPU_H | 42 | #endif //SYNACORVM_CPU_H |
main.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <string.h> | ||
3 | +#include "mem.h" | ||
4 | +#include "stack.h" | ||
5 | + | ||
6 | +void load_program(const char* path) | ||
7 | +{ | ||
8 | + FILE *fp = fopen(path,"r"); | ||
9 | + fseek(fp, 0L, SEEK_END); | ||
10 | + long file_size = ftell(fp); | ||
11 | + rewind(fp); | ||
12 | + fread(mem,1,(size_t)file_size,fp); | ||
13 | + fclose(fp); | ||
14 | +} | ||
2 | 15 | ||
3 | int main(int argc, char** argv) | 16 | int main(int argc, char** argv) |
4 | { | 17 | { |
18 | + if(argc != 2) | ||
19 | + { | ||
20 | + printf("Invalid argument\n\n"); | ||
21 | + printf(argv[0]); | ||
22 | + printf(" path_to_binary\n"); | ||
23 | + return 1; | ||
24 | + } | ||
25 | + initialize_stack(); | ||
26 | + memset(regs,0x00,sizeof(short)*NUM_REGISTERS); | ||
27 | + memset(mem,0x00,sizeof(short)*MEMSIZE); | ||
28 | + load_program(argv[1]); | ||
29 | + start_execution(); | ||
30 | + free_stack(); | ||
5 | return 0; | 31 | return 0; |
6 | } | 32 | } |
7 | \ No newline at end of file | 33 | \ No newline at end of file |
binary_decoder.c renamed to mem.c
mem.h
@@ -5,6 +5,8 @@ | @@ -5,6 +5,8 @@ | ||
5 | #ifndef SYNACORVM_MEM_H | 5 | #ifndef SYNACORVM_MEM_H |
6 | #define SYNACORVM_MEM_H | 6 | #define SYNACORVM_MEM_H |
7 | 7 | ||
8 | -short mem[32768]; //64KiB RAM | 8 | +#define MEMSIZE 32768 |
9 | + | ||
10 | +extern short mem[MEMSIZE]; //64KiB RAM | ||
9 | 11 | ||
10 | #endif //SYNACORVM_MEM_H | 12 | #endif //SYNACORVM_MEM_H |
binary_decoder.h renamed to registers.c
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | // Created by imanol on 12/25/16. | 2 | // Created by imanol on 12/25/16. |
3 | // | 3 | // |
4 | 4 | ||
5 | -#ifndef SYNACORVM_BINARY_DECODER_H | ||
6 | -#define SYNACORVM_BINARY_DECODER_H | 5 | +#include "registers.h" |
7 | 6 | ||
8 | -#endif //SYNACORVM_BINARY_DECODER_H | 7 | +short regs[NUM_REGISTERS]; |
8 | +short pc = 0; | ||
9 | \ No newline at end of file | 9 | \ No newline at end of file |
registers.h
@@ -5,15 +5,9 @@ | @@ -5,15 +5,9 @@ | ||
5 | #ifndef SYNACORVM_REGISTERS_H | 5 | #ifndef SYNACORVM_REGISTERS_H |
6 | #define SYNACORVM_REGISTERS_H | 6 | #define SYNACORVM_REGISTERS_H |
7 | 7 | ||
8 | -short r0 = 0; | ||
9 | -short r1 = 0; | ||
10 | -short r2 = 0; | ||
11 | -short r3 = 0; | ||
12 | -short r4 = 0; | ||
13 | -short r5 = 0; | ||
14 | -short r6 = 0; | ||
15 | -short r7 = 0; | 8 | +#define NUM_REGISTERS 8 |
16 | 9 | ||
17 | -short pc = 0; | 10 | +extern short regs[NUM_REGISTERS]; |
11 | +extern short pc; | ||
18 | 12 | ||
19 | #endif //SYNACORVM_REGISTERS_H | 13 | #endif //SYNACORVM_REGISTERS_H |
stack.c
@@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||
7 | 7 | ||
8 | #define EXTEND_SIZE 10 | 8 | #define EXTEND_SIZE 10 |
9 | 9 | ||
10 | +uint8_t STACK_FAULT = 0; | ||
10 | uint32_t stack_size = EXTEND_SIZE; | 11 | uint32_t stack_size = EXTEND_SIZE; |
11 | uint32_t stack_pos = 0; | 12 | uint32_t stack_pos = 0; |
12 | short *stack; | 13 | short *stack; |
@@ -16,19 +17,39 @@ void initialize_stack() | @@ -16,19 +17,39 @@ void initialize_stack() | ||
16 | stack = calloc(EXTEND_SIZE,sizeof(short)); | 17 | stack = calloc(EXTEND_SIZE,sizeof(short)); |
17 | } | 18 | } |
18 | 19 | ||
20 | +void free_stack() | ||
21 | +{ | ||
22 | + free(stack); | ||
23 | + stack_size = 0; | ||
24 | + stack_pos = 0; | ||
25 | + stack = NULL; | ||
26 | +} | ||
27 | + | ||
19 | void extend_stack() | 28 | void extend_stack() |
20 | { | 29 | { |
21 | stack_size += EXTEND_SIZE; | 30 | stack_size += EXTEND_SIZE; |
22 | - realloc(stack,stack_size*sizeof(short)); | 31 | + void *new_ptr = realloc(stack,stack_size*sizeof(short)); |
32 | + if(new_ptr == NULL) | ||
33 | + { | ||
34 | + fprintf(stderr,"CRITICAL: STACK ALLOCATION ERROR\n"); | ||
35 | + core_dump(); | ||
36 | + } | ||
37 | + stack = new_ptr; | ||
23 | } | 38 | } |
24 | 39 | ||
25 | void shrink_stack() | 40 | void shrink_stack() |
26 | { | 41 | { |
27 | stack_size -= EXTEND_SIZE; | 42 | stack_size -= EXTEND_SIZE; |
28 | - realloc(stack,stack_size*sizeof(short)); | 43 | + void *new_ptr = realloc(stack,stack_size*sizeof(short)); |
44 | + if(new_ptr == NULL) | ||
45 | + { | ||
46 | + fprintf(stderr,"CRITICAL: STACK ALLOCATION ERROR\n"); | ||
47 | + core_dump(); | ||
48 | + } | ||
49 | + stack = new_ptr; | ||
29 | } | 50 | } |
30 | 51 | ||
31 | -void push(short value) | 52 | +void stack_push(short value) |
32 | { | 53 | { |
33 | stack[stack_pos++] = value; | 54 | stack[stack_pos++] = value; |
34 | if(stack_pos == stack_size-1) | 55 | if(stack_pos == stack_size-1) |
@@ -36,12 +57,19 @@ void push(short value) | @@ -36,12 +57,19 @@ void push(short value) | ||
36 | extend_stack(); | 57 | extend_stack(); |
37 | } | 58 | } |
38 | } | 59 | } |
39 | -short pop() | 60 | + |
61 | +short stack_pop() | ||
40 | { | 62 | { |
63 | + if(!stack_pos) | ||
64 | + { | ||
65 | + STACK_FAULT = 1; | ||
66 | + return -1; | ||
67 | + } | ||
41 | short value = stack[stack_pos--]; | 68 | short value = stack[stack_pos--]; |
42 | if(stack_size - stack_pos == 2*EXTEND_SIZE) | 69 | if(stack_size - stack_pos == 2*EXTEND_SIZE) |
43 | { | 70 | { |
44 | shrink_stack(); | 71 | shrink_stack(); |
45 | } | 72 | } |
46 | return value; | 73 | return value; |
47 | -} | ||
48 | \ No newline at end of file | 74 | \ No newline at end of file |
75 | +} | ||
76 | + |
stack.h
@@ -6,9 +6,13 @@ | @@ -6,9 +6,13 @@ | ||
6 | #define SYNACORVM_STACK_H | 6 | #define SYNACORVM_STACK_H |
7 | 7 | ||
8 | #include <stdint.h> | 8 | #include <stdint.h> |
9 | +#include "cpu.h" | ||
10 | + | ||
11 | +extern uint8_t STACK_FAULT; | ||
9 | 12 | ||
10 | void initialize_stack(); | 13 | void initialize_stack(); |
11 | -void push(short value); | ||
12 | -short pop(); | 14 | +void free_stack(); |
15 | +void stack_push(short value); | ||
16 | +short stack_pop(); | ||
13 | 17 | ||
14 | #endif //SYNACORVM_STACK_H | 18 | #endif //SYNACORVM_STACK_H |