123 lines
3.0 KiB
C
123 lines
3.0 KiB
C
#include "../../../vm/vm.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define CODE_SIZE 8192
|
|
#define MEMORY_SIZE 65536
|
|
u8 lmem[MEMORY_SIZE] = {0};
|
|
u32 lcode[CODE_SIZE] = {0};
|
|
|
|
bool init_vm() {
|
|
mem = lmem;
|
|
memset(mem, 0, MEMORY_SIZE*sizeof(u8));
|
|
code = lcode;
|
|
lc = 0;
|
|
mp = 0;
|
|
cp = 0;
|
|
pc = 0;
|
|
interrupt = 0;
|
|
status = 0;
|
|
return true;
|
|
}
|
|
|
|
u32 syscall(u32 id, u32 size, u32 mem_ptr) {
|
|
USED(size);
|
|
switch(id) {
|
|
case SYSCALL_CONSOLE_WRITE: {
|
|
u32 size_ptr = mem[mem_ptr];
|
|
u32 size = mem[size_ptr];
|
|
u8 *ptr = &mem[size_ptr + 4];
|
|
for (u32 i = 0; i < size; i++) {
|
|
putchar(*(ptr++));
|
|
}
|
|
putchar('\n');
|
|
return 0;
|
|
}
|
|
case SYSCALL_CONSOLE_READ: {
|
|
u8 *ptr = &mem[mp];
|
|
mcpy(ptr, &size, sizeof(u32));
|
|
ptr += 4;
|
|
for (u32 i = 0; i < size; i++) {
|
|
u8 ch = getchar();
|
|
if (ch == '\0')
|
|
break;
|
|
if (ch == '\n')
|
|
break;
|
|
*(ptr++) = ch;
|
|
}
|
|
ptr[size] = '\0';
|
|
mp += 4 + size + 1;
|
|
}
|
|
}
|
|
|
|
return 1; // generic error
|
|
}
|
|
|
|
void test_add_two_num() {
|
|
i32 main_local_count = 5;
|
|
mp += (4 * main_local_count);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 1);
|
|
code[cp++] = ENCODE_B(OP_PUSH, 0, 0);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 1);
|
|
code[cp++] = ENCODE_B(OP_PUSH, 1, 0);
|
|
i32 add = cp + 5;
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, add);
|
|
|
|
code[cp++] = ENCODE_A(OP_CALL, 2, 3, 0);
|
|
code[cp++] = ENCODE_A(OP_INT_TO_STR, 4, 3, 0);
|
|
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 4);
|
|
code[cp++] = ENCODE_A(OP_HALT, 0, 0, 0);
|
|
|
|
/* add */
|
|
code[cp++] = ENCODE_A(OP_ADD_INT, 2, 1, 0);
|
|
code[cp++] = ENCODE_B(OP_RETURN, 2, 0);
|
|
}
|
|
|
|
void test_fibonacci() {
|
|
i32 fib = 7;
|
|
i32 base_case = 21;
|
|
/* function main() */
|
|
i32 main_local_count = 4;
|
|
mp += (4 * main_local_count);
|
|
/* fib(35) */
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35);
|
|
code[cp++] = ENCODE_B(OP_PUSH, 0, 0);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, fib);
|
|
code[cp++] = ENCODE_A(OP_CALL, 1, 9, 2);
|
|
/* print */
|
|
code[cp++] = ENCODE_A(OP_INT_TO_STR, 3, 2, 0);
|
|
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 3);
|
|
code[cp++] = ENCODE_A(OP_HALT, 0, 0, 0);
|
|
/* function fib (int n) int */
|
|
//code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_DBG_PRINT, 1, 0);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 8, fib);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 2);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, base_case);
|
|
code[cp++] = ENCODE_A(OP_JLT_INT, 2, 0, 1);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 2);
|
|
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
|
code[cp++] = ENCODE_B(OP_PUSH, 4, 0);
|
|
code[cp++] = ENCODE_A(OP_CALL, 8, 9, 5);
|
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 1);
|
|
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
|
code[cp++] = ENCODE_B(OP_PUSH, 4, 0);
|
|
code[cp++] = ENCODE_A(OP_CALL, 8, 9, 6);
|
|
code[cp++] = ENCODE_A(OP_ADD_INT, 7, 6, 5);
|
|
code[cp++] = ENCODE_B(OP_RETURN, 7, 0);
|
|
code[cp++] = ENCODE_B(OP_RETURN, 0, 0);
|
|
}
|
|
|
|
i32 main() {
|
|
init_vm();
|
|
|
|
/* test_add_two_num(); */
|
|
test_fibonacci();
|
|
|
|
while(step_vm()) {
|
|
// do stuff
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|