Commit 5e06910cf73286209f0b134f2c969c22da434c03

Authored by Imanol-Mikel Barba Sabariego
1 parent 0f27ef74

Implemented. Testing and debugging...

.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
@@ -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
@@ -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
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
@@ -2,4 +2,6 @@ @@ -2,4 +2,6 @@
2 // Created by imanol on 12/25/16. 2 // Created by imanol on 12/25/16.
3 // 3 //
4 4
5 -#include "binary_decoder.h" 5 +#include "mem.h"
  6 +
  7 +short mem[MEMSIZE];
6 \ No newline at end of file 8 \ No newline at end of file
@@ -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
@@ -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 +
@@ -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