diff --git a/src/opcodes.h b/src/opcodes.h index c76aec5..e42ab70 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -46,6 +46,7 @@ typedef enum { OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */ OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */ OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ + OP_STRLEN, /* strl : dest = length of str at src1 ptr */ OP_INT_TO_STRING, /* itos : dest = src1 as str */ OP_UINT_TO_STRING, /* utos : dest = src1 as str */ OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ @@ -91,8 +92,8 @@ typedef struct device_s { u32 flags; /* permissions, status, etc. */ } Device; -#define MEMORY_SIZE (640 * 480 + 65536) -#define CODE_SIZE 8192 +#define MEMORY_SIZE 1024 /*(640 * 480 + 65536)*/ +#define CODE_SIZE 128 /*8192*/ #define FRAMES_SIZE 128 #define STACK_SIZE 256 #define DEVICES_SIZE 8 diff --git a/src/test.c b/src/test.c index 1694e91..f82f503 100644 --- a/src/test.c +++ b/src/test.c @@ -2,6 +2,7 @@ #include "opcodes.h" #include "str.h" #include "vm.h" +#include u32 real_alloc(VM *vm, float v) { i32 fixed = TO_FIXED(v); @@ -58,23 +59,27 @@ bool test_simple_compile(VM *vm) { ptr = real_alloc(vm, 2.0f); write_u32(vm, code, vm->cp, ptr); vm->cp+=4; - vm->code[vm->cp++] = OP_ADD_UINT; + vm->code[vm->cp++] = OP_ADD_REAL; vm->code[vm->cp++] = 2; vm->code[vm->cp++] = 1; vm->code[vm->cp++] = 0; /* let sum = 1 + 2; */ vm->code[vm->cp++] = OP_REAL_TO_STRING; - vm->code[vm->cp++] = 4; + vm->code[vm->cp++] = 3; vm->code[vm->cp++] = 2; vm->code[vm->cp++] = OP_LOAD_IMM; - vm->code[vm->cp++] = 3; + vm->code[vm->cp++] = 2; write_u32(vm, code, vm->cp, terminal_path_addr); vm->cp+=4; + vm->code[vm->cp++] = OP_STRLEN; + vm->code[vm->cp++] = 4; + vm->code[vm->cp++] = 3; + vm->code[vm->cp++] = OP_SYSCALL; write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE)); vm->cp+=4; - write_u32(vm, code, vm->cp, AS_UINT(2)); vm->cp+=4; - vm->code[vm->cp++] = 3; + vm->code[vm->cp++] = 3; /* arg_count */ + vm->code[vm->cp++] = 2; /* first_reg */ /* syscall_id=WRITE, arg_count=2, start_reg=3 ; print(sum.toS()); */ vm->code[vm->cp++] = OP_HALT; /* explicit halt */ return true; diff --git a/src/vm.c b/src/vm.c index 92e73ce..395893c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -138,8 +138,8 @@ bool step_vm(VM *vm) { syscall_id = read_u32(vm, code, vm->pc); vm->pc += 4; - arg_count = read_u32(vm, code, vm->pc); - vm->pc += 4; + arg_count = read_u8(vm, code, vm->pc); + vm->pc++; first_reg = read_u8(vm, code, vm->pc); vm->pc++; @@ -147,13 +147,11 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_OPEN: { if (arg_count >= 2) { Device *dev; - u32 path_ptr, mode, str_src; + u32 path_ptr, mode; path_ptr = vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ mode = vm->frames[vm->fp].registers[first_reg + 1]; /* R1: mode */ - str_src = path_ptr + 1; - - dev = find_device_by_path(vm, (const char *)&vm->memory[str_src]); + dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev) { if (dev->ops->open) { @@ -173,17 +171,15 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_READ: { if (arg_count >= 3) { Device *dev; - u32 path_ptr, buffer_ptr, size, str_src; + u32 path_ptr, buffer_ptr, size; path_ptr = vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ buffer_ptr = vm->frames[vm->fp] .registers[first_reg + 1]; /* R1: buffer pointer */ size = vm->frames[vm->fp].registers[first_reg + 2]; /* R2: size */ - str_src = path_ptr + 1; - - dev = find_device_by_path(vm, (const char *)&vm->memory[str_src]); + dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev && dev->ops->read) { vm->acc = dev->ops->read(dev->data, (u8 *)&vm->memory[buffer_ptr], size); @@ -199,18 +195,17 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_WRITE: { if (arg_count >= 2) { Device *dev; - u32 path_ptr, buffer_ptr, size, str_src; + u32 path_ptr, buffer_ptr, size; path_ptr = vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ buffer_ptr = vm->frames[vm->fp] .registers[first_reg + 1]; /* R1: buffer pointer */ - size = read_u32(vm, memory, buffer_ptr); /* R2: size */ - str_src = path_ptr += 4; + size = vm->frames[vm->fp].registers[first_reg + 2]; /* R2: size */ - dev = find_device_by_path(vm, (const char *)&vm->memory[str_src]); + dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev && dev->ops->write) { - vm->acc = dev->ops->write(dev->data, - (const u8 *)&vm->memory[buffer_ptr], size); + vm->acc = dev->ops->write(dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], + size); } else { vm->acc = 0; } @@ -223,12 +218,11 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_CLOSE: { if (arg_count >= 1) { Device *dev; - u32 path_ptr, str_src; + u32 path_ptr; path_ptr = vm->frames[vm->fp].registers[first_reg]; /* R0: path pointer */ - str_src = path_ptr + 1; - dev = find_device_by_path(vm, (const char *)&vm->memory[str_src]); + dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev && dev->ops->close) { i32 result = dev->ops->close(dev->data); @@ -245,16 +239,15 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_IOCTL: { if (arg_count >= 3) { Device *dev; - u32 path_ptr, args_ptr, cmd, str_src; + u32 path_ptr, args_ptr, cmd; path_ptr = vm->frames[vm->fp].registers[first_reg]; /* R0: device path */ cmd = vm->frames[vm->fp].registers[first_reg + 1]; /* R1: ioctl command */ args_ptr = vm->frames[vm->fp].registers[first_reg + 2]; /* R2: args pointer */ - str_src = path_ptr + 1; - dev = find_device_by_path(vm, (const char *)&vm->memory[str_src]); + dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev && dev->ops && dev->ops->ioctl) { i32 result = dev->ops->ioctl(dev->data, cmd, &vm->memory[args_ptr]); @@ -468,6 +461,18 @@ bool step_vm(VM *vm) { vm->frames[vm->fp].registers[dest] = ptr; return true; } + case OP_STRLEN: { + u32 ptr, length; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + + ptr = vm->frames[vm->fp].registers[src1]; + length = read_u32(vm, memory, ptr); + vm->frames[vm->fp].registers[dest] = length; + return true; + } case OP_STRING_TO_INT: { /* not implemented yet */ return false;