diff --git a/Makefile b/Makefile index 4ad8f11..e54a567 100644 --- a/Makefile +++ b/Makefile @@ -99,11 +99,11 @@ DEPS := $(VM_OBJS:.o=.d) $(PLATFORM_OBJ:.o=.d) all: $(TARGET) # 'debug' target — just set BUILD_MODE and build -debug: BUILD_MODE = debug +debug: BUILD_MODE=debug debug: $(TARGET) # 'release' target — just set BUILD_MODE and build -release: BUILD_MODE = release +release: BUILD_MODE=release release: $(TARGET) # --- COMPILE VM CORE (freestanding) --- diff --git a/src/arch/linux/devices.c b/src/arch/linux/devices.c index 3f30787..ca935e4 100644 --- a/src/arch/linux/devices.c +++ b/src/arch/linux/devices.c @@ -1,54 +1,52 @@ #include "devices.h" -#include -#include +#include +#include i32 console_open(void *data, u32 mode) { - USED(mode); - USED(data); - /* Nothing to open — stdin/stdout are always available */ - return 0; /* Success */ + USED(mode); + USED(data); + /* Nothing to open — stdin/stdout are always available */ + return 0; /* Success */ } i32 console_read(void *data, u8 *buffer, u32 size) { - USED(data); - for (u32 i = 0; i < size; i++) { - u8 ch = getchar(); - if (ch == '\0') - break; - if (ch == '\n') - break; - buffer[i] = ch; - } - return 0; + USED(data); + for (u32 i = 0; i < size; i++) { + u8 ch = getchar(); + if (ch == '\0') + break; + if (ch == '\n') + break; + buffer[i] = ch; + } + return 0; } i32 console_write(void *data, const u8 *buffer, u32 size) { - USED(data); - for (u32 i = 0; i < size; i++) { - putchar(buffer[i]); - } - return 0; - + USED(data); + for (u32 i = 0; i < size; i++) { + putchar(buffer[i]); + } + return 0; } i32 console_close(void *data) { - USED(data); - /* Nothing to close — stdin/stdout are process-owned */ - return 0; + USED(data); + /* Nothing to close — stdin/stdout are process-owned */ + return 0; } i32 console_ioctl(void *data, u32 cmd, void *args) { - USED(data); - USED(cmd); - USED(args); - return -1; /* Unsupported */ + USED(data); + USED(cmd); + USED(args); + return -1; /* Unsupported */ } i32 screen_open(void *data, u32 mode) { USED(mode); ScreenDeviceData *screen = (ScreenDeviceData *)data; - screen->window = SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen->width, screen->height, @@ -62,9 +60,9 @@ i32 screen_open(void *data, u32 mode) { if (!screen->renderer) return -1; - screen->texture = SDL_CreateTexture( - screen->renderer, SDL_PIXELFORMAT_RGB332, SDL_TEXTUREACCESS_STREAMING, - screen->width, screen->height); + screen->texture = SDL_CreateTexture(screen->renderer, SDL_PIXELFORMAT_RGB332, + SDL_TEXTUREACCESS_STREAMING, + screen->width, screen->height); if (!screen->texture) return -1; @@ -72,21 +70,43 @@ i32 screen_open(void *data, u32 mode) { return 0; } -i32 screen_read(void *data, u8 *buffer, u32 size) { +i32 screen_read(void *data, u8 *buffer, u32 size) { USED(data); USED(buffer); USED(size); - return -1; + return -1; } i32 screen_write(void *data, const u8 *buffer, u32 size) { ScreenDeviceData *screen = (ScreenDeviceData *)data; + USED(buffer); if (size > screen->framebuffer_size * sizeof(u8)) { return -1; } - memcpy(&screen->vm->memory[screen->framebuffer_pos], buffer, size); + if (screen->texture && screen->renderer) { + SDL_UpdateTexture(screen->texture, nil, + &screen->vm->memory[screen->framebuffer_pos], + screen->width); + + SDL_RenderClear(screen->renderer); + + SDL_Rect output_rect; + SDL_RenderGetViewport(screen->renderer, &output_rect); + float scale_x = (float)output_rect.w / screen->width; + float scale_y = (float)output_rect.h / screen->height; + float scale = SDL_min(scale_x, scale_y); + + SDL_Rect dstrect = {(i32)((output_rect.w - screen->width * scale) / 2), + (i32)((output_rect.h - screen->height * scale) / 2), + (i32)(screen->width * scale), + (i32)(screen->height * scale)}; + + SDL_RenderCopy(screen->renderer, screen->texture, nil, &dstrect); + SDL_RenderPresent(screen->renderer); + } + return 0; } @@ -108,11 +128,29 @@ i32 screen_close(void *data) { return 0; } +i32 screen_ioctl(void *data, u32 cmd, void *args) { + ScreenDeviceData *screen = (ScreenDeviceData *)data; + + switch (cmd) { + case IOCTL_GET_INFO: { + u32 *info = (u32 *)args; + memcpy(&screen->vm->memory[*info], &screen->framebuffer_pos, sizeof(u32)); + memcpy(&screen->vm->memory[*info + 1], &screen->framebuffer_size, sizeof(u32)); + memcpy(&screen->vm->memory[*info + 2], &screen->width, sizeof(u32)); + memcpy(&screen->vm->memory[*info + 3], &screen->height, sizeof(u32)); + return 0; + } + + default: + return -1; // Error + } +} + /* MOUSE */ -i32 mouse_open(void *data, u32 mode) { +i32 mouse_open(void *data, u32 mode) { USED(data); USED(mode); - return 0; + return 0; } i32 mouse_read(void *data, u8 *buffer, u32 size) { @@ -129,22 +167,22 @@ i32 mouse_read(void *data, u8 *buffer, u32 size) { return 0; } -i32 mouse_write(void *data, const u8 *buffer, u32 size) { +i32 mouse_write(void *data, const u8 *buffer, u32 size) { USED(data); USED(buffer); USED(size); - return -1; + return -1; } -i32 mouse_close(void *data) { +i32 mouse_close(void *data) { USED(data); - return 0; + return 0; } i32 keyboard_open(void *data, u32 mode) { USED(data); USED(mode); - return 0; + return 0; } i32 keyboard_read(void *data, u8 *buffer, u32 size) { @@ -164,7 +202,7 @@ i32 keyboard_write(void *data, const u8 *buffer, u32 size) { return -1; /* not writable */ } -i32 keyboard_close(void *data) { +i32 keyboard_close(void *data) { USED(data); return 0; } diff --git a/src/arch/linux/devices.h b/src/arch/linux/devices.h index 376324a..3da4939 100644 --- a/src/arch/linux/devices.h +++ b/src/arch/linux/devices.h @@ -2,6 +2,8 @@ #include "../../vm/vm.h" #include +#define IOCTL_GET_INFO 0x01 + /* Screen device data */ typedef struct screen_device_data_s { u32 width; @@ -34,6 +36,7 @@ i32 screen_open(void *data, u32 mode); i32 screen_read(void *data, u8 *buffer, u32 size); i32 screen_write(void *data, const u8 *buffer, u32 size); i32 screen_close(void *data); +i32 screen_ioctl(void *data, u32 cmd, void *args); i32 mouse_open(void *data, u32 mode); i32 mouse_read(void *data, u8 *buffer, u32 size); diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index 3e3bfe4..1e31ef3 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -14,7 +14,7 @@ static DeviceOps screen_ops = {.open = screen_open, .read = screen_read, .write = screen_write, .close = screen_close, - .ioctl = nil}; + .ioctl = screen_ioctl}; static DeviceOps mouse_ops = {.open = mouse_open, .read = mouse_read, @@ -242,7 +242,10 @@ void register_sdl_devices(VM *vm) { screen_data.height = 480; screen_data.framebuffer_size = 640 * 480; screen_data.framebuffer_pos = vm->mp; - vm->mp += screen_data.framebuffer_size / 4; /* advance memory pointer */ + vm->mp += screen_data.framebuffer_size; /* advance memory pointer */ + vm->frames[vm->fp].end = vm->mp; + + printf("%d\n", screen_data.framebuffer_pos ); vm_register_device(vm, "/dev/screen/0", "screen", &screen_data, &screen_ops); @@ -292,9 +295,6 @@ i32 main(i32 argc, char *argv[]) { VM vm = {0}; - // Register terminal device first - vm_register_device(&vm, "/dev/term/0", "terminal", nil, &console_device_ops); - bool compilation_success = true; if (input_file) { if (is_rom) { @@ -330,6 +330,8 @@ i32 main(i32 argc, char *argv[]) { bool running = true; + vm_register_device(&vm, "/dev/term/0", "terminal", nil, &console_device_ops); + if (gui_mode) { register_sdl_devices(&vm); @@ -375,35 +377,6 @@ i32 main(i32 argc, char *argv[]) { } step_vm(&vm); - - for (u32 i = 0; i < vm.dc; i++) { - Device *dev = &vm.devices[i]; - if (strcmp(dev->type, "screen") == 0) { - ScreenDeviceData *screen = (ScreenDeviceData *)dev->data; - if (screen->texture && screen->renderer) { - SDL_UpdateTexture(screen->texture, nil, - &vm.memory[screen->framebuffer_pos], - screen->width * sizeof(u32)); - - SDL_RenderClear(screen->renderer); - - SDL_Rect output_rect; - SDL_RenderGetViewport(screen->renderer, &output_rect); - float scale_x = (float)output_rect.w / screen->width; - float scale_y = (float)output_rect.h / screen->height; - float scale = SDL_min(scale_x, scale_y); - - SDL_Rect dstrect = { - (i32)((output_rect.w - screen->width * scale) / 2), - (i32)((output_rect.h - screen->height * scale) / 2), - (i32)(screen->width * scale), (i32)(screen->height * scale)}; - - SDL_RenderCopy(screen->renderer, screen->texture, nil, &dstrect); - SDL_RenderPresent(screen->renderer); - } - break; - } - } } } else { while (running) { diff --git a/src/tools/assembler.c b/src/tools/assembler.c index d9baa04..79889ba 100644 --- a/src/tools/assembler.c +++ b/src/tools/assembler.c @@ -76,8 +76,8 @@ int get_instruction_byte_size(ExprNode *node) { } // Register-based opcodes (2 bytes: opcode + register) - if (strcmp(opname, "pop") == 0 || strcmp(opname, "push") == 0 || - strcmp(opname, "jump") == 0 || strcmp(opname, "jump-if-flag") == 0) { + if (strcmp(opname, "pop") == 0 || strcmp(opname, "jump-if-flag") == 0 || + strcmp(opname, "jump") == 0 || strcmp(opname, "push") == 0) { return 2; } @@ -89,19 +89,14 @@ int get_instruction_byte_size(ExprNode *node) { strcmp(opname, "real-to-int") == 0 || strcmp(opname, "real-to-nat") == 0 || strcmp(opname, "int-to-nat") == 0 || strcmp(opname, "nat-to-int") == 0 || - strcmp(opname, "string-length") == 0) { + strcmp(opname, "string-length") == 0 || strcmp(opname, "load") == 0 || + strcmp(opname, "store") == 0 || strcmp(opname, "load-u8") == 0 || + strcmp(opname, "load-i8") == 0 || strcmp(opname, "store-8") == 0 || + strcmp(opname, "load-u16") == 0 || strcmp(opname, "load-i16") == 0 || + strcmp(opname, "store-16") == 0 || strcmp(opname, "register-move") == 0) { return 3; } - // Load/store with register and address (5 bytes: 1 + 1 + 4) - if (strcmp(opname, "load") == 0 || strcmp(opname, "store") == 0 || - strcmp(opname, "load-u8") == 0 || strcmp(opname, "load-i8") == 0 || - strcmp(opname, "store-8") == 0 || strcmp(opname, "load-u16") == 0 || - strcmp(opname, "load-i16") == 0 || strcmp(opname, "store-16") == 0 || - strcmp(opname, "call") == 0) { - return 5; - } - // Register-register-register opcodes (4 bytes: 1 + 3) if (strcmp(opname, "add-int") == 0 || strcmp(opname, "sub-int") == 0 || strcmp(opname, "mul-int") == 0 || strcmp(opname, "div-int") == 0 || @@ -116,9 +111,13 @@ int get_instruction_byte_size(ExprNode *node) { return 4; } - // Load, Load-immediate (5 bytes: 1 + 1 + 4) - if (strcmp(opname, "load-immediate") == 0 || strcmp(opname, "load") == 0 || - strcmp(opname, "store") == 0) { + // (5 bytes: 1 + 4) + if (strcmp(opname, "call") == 0) { + return 5; + } + + // Load, Load-immediate (6 bytes: 1 + 1 + 4) + if (strcmp(opname, "load-immediate") == 0) { return 6; } @@ -163,12 +162,16 @@ void collect_symbols_in_node(SymbolTable *table, ExprNode *node, for (int i = 0; i < depth; i++) strcat(indent, " "); - // printf("%s%d %s ", indent, *current_addr, node->token); +#ifdef ASM_DEBUG + printf("%s%d %s ", indent, *current_addr, node->token); +#endif if (strcmp(node->token, "label") == 0) { if (node->child_count >= 1) { const char *name = node->children[0]->token; - // printf(" %s -> %d\n", name, *current_addr); +#ifdef ASM_DEBUG + printf(" %s -> %d\n", name, *current_addr); +#endif symbol_table_add(table, name, *current_addr, SYMBOL_CODE); } @@ -179,8 +182,9 @@ void collect_symbols_in_node(SymbolTable *table, ExprNode *node, } else { int size = get_instruction_byte_size(node); *current_addr += size; - // printf(" +%d bytes -> %d\n", size, *current_addr); - // printf("\n"); +#ifdef ASM_DEBUG + printf(" +%d bytes -> %d\n", size, *current_addr); +#endif } } @@ -242,15 +246,37 @@ int parse_register(const char *reg_str) { } u32 resolve_symbol(SymbolTable *table, const char *ref) { + // Handle symbol references (e.g., &label) if (ref[0] == '&') { return find_label_in_table(table, ref + 1); } - // Handle immediate values + // Handle fixed-point numbers (e.g., 0.5) if (strchr(ref, '.')) { return TO_FIXED(atof(ref)); } - return (u32)atoi(ref); + + // Handle hexadecimal literals (e.g., 0x7) + if (ref[0] == '0' && (ref[1] == 'x' || ref[1] == 'X')) { + char *endptr; + u32 value = (u32)strtoul(ref + 2, &endptr, 16); // Skip "0x" + + if (endptr == ref + 2 || *endptr != '\0') { + fprintf(stderr, "Invalid hex literal: %s\n", ref); + exit(1); + } + return value; + } + + // Handle decimal literals (e.g., 7) + char *endptr; + u32 value = (u32)strtoul(ref, &endptr, 10); + + if (endptr == ref || *endptr != '\0') { + fprintf(stderr, "Invalid decimal literal: %s\n", ref); + exit(1); + } + return value; } static char *unwrap_string(const char *quoted_str) { @@ -327,26 +353,59 @@ void process_data_block(VM *vm, SymbolTable *table, ExprNode *block) { ExprNode *val = item->children[1]; if (val->child_count == 0) { - if (strchr(val->token, '.')) { - float f = atof(val->token); - u32 addr = allocate_data(vm, table, name, 4); - write_u32(vm, memory, addr, TO_FIXED(f)); - } else { - // unwrap deals with control characters and "" literals - char *unwrapped = unwrap_string(val->token); - int len = strlen(unwrapped) + 1; // Include length + null terminator + const char *token = val->token; + + // Case 1: String literal (enclosed in quotes) + if (token[0] == '"' && token[strlen(token) - 1] == '"') { + char *unwrapped = unwrap_string(token); + int len = strlen(unwrapped) + 1; u32 addr = allocate_data(vm, table, name, len + 4); write_u32(vm, memory, addr, len); - // Copy string to memory for (int i = 0; i < len; i++) { write_u8(vm, memory, addr + 4 + i, unwrapped[i]); } - + vm->mp += 4 + len; free(unwrapped); } + // Case 2: Hexadecimal integer (0x...) + else if (token[0] == '0' && (token[1] == 'x' || token[1] == 'X')) { + char *endptr; + u32 value = (u32)strtoul(token + 2, &endptr, 16); + + if (endptr != token + strlen(token)) { + fprintf(stderr, "Invalid hex in data block: %s\n", token); + exit(1); + } + + u32 addr = allocate_data(vm, table, name, 4); + write_u32(vm, memory, addr, value); + vm->mp += 4; + } + // Case 3: Floating-point (has decimal point) + else if (strchr(token, '.')) { + float f = atof(token); + u32 addr = allocate_data(vm, table, name, 4); + write_u32(vm, memory, addr, TO_FIXED(f)); + vm->mp += 4; + } + // Case 4: Decimal integer + else { + char *endptr; + u32 value = (u32)strtoul(token, &endptr, 10); + + if (endptr != token + strlen(token)) { + fprintf(stderr, "Invalid decimal in data block: %s\n", token); + exit(1); + } + + u32 addr = allocate_data(vm, table, name, 4); + write_u32(vm, memory, addr, value); + vm->mp += 4; + } } else { fprintf(stderr, "Unsupported data item\n"); + exit(1); } } } @@ -374,24 +433,60 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_u32(vm, addr); } else if (strcmp(opname, "return") == 0) { emit_opcode(vm, OP_RETURN); - } else if (strcmp(opname, "load") == 0) { - emit_opcode(vm, OP_LOAD); - int reg = parse_register(node->children[0]->token); - u32 addr = resolve_symbol(table, node->children[1]->token); - emit_byte(vm, reg); - emit_u32(vm, addr); } else if (strcmp(opname, "load-immediate") == 0) { emit_opcode(vm, OP_LOAD_IMM); int reg = parse_register(node->children[0]->token); u32 addr = resolve_symbol(table, node->children[1]->token); emit_byte(vm, reg); emit_u32(vm, addr); + } else if (strcmp(opname, "load") == 0) { + emit_opcode(vm, OP_LOAD); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + } else if (strcmp(opname, "load-i8") == 0) { + emit_opcode(vm, OP_LOADI8); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + } else if (strcmp(opname, "load-u8") == 0) { + emit_opcode(vm, OP_LOADU8); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + } else if (strcmp(opname, "load-u16") == 0) { + emit_opcode(vm, OP_LOADU16); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + } else if (strcmp(opname, "load-i16") == 0) { + emit_opcode(vm, OP_LOADI16); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); } else if (strcmp(opname, "store") == 0) { emit_opcode(vm, OP_STORE); - int reg = parse_register(node->children[0]->token); - u32 addr = resolve_symbol(table, node->children[1]->token); - emit_byte(vm, reg); - emit_u32(vm, addr); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + } else if (strcmp(opname, "store-8") == 0) { + emit_opcode(vm, OP_STORE8); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + } else if (strcmp(opname, "store-16") == 0) { + emit_opcode(vm, OP_STORE16); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); } else if (strcmp(opname, "push") == 0) { emit_opcode(vm, OP_PUSH); int reg = parse_register(node->children[0]->token); @@ -432,6 +527,54 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { int reg = parse_register(node->children[i]->token); emit_byte(vm, reg); } + } else if (strcmp(opname, "bit-shift-left") == 0) { + emit_opcode(vm, OP_SLL); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + int src2 = parse_register(node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_byte(vm, src2); + } else if (strcmp(opname, "bit-shift-right") == 0) { + emit_opcode(vm, OP_SRL); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + int src2 = parse_register(node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_byte(vm, src2); + } else if (strcmp(opname, "bit-shift-right-extend") == 0) { + emit_opcode(vm, OP_SRE); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + int src2 = parse_register(node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_byte(vm, src2); + } else if (strcmp(opname, "bit-and") == 0) { + emit_opcode(vm, OP_BAND); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + int src2 = parse_register(node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_byte(vm, src2); + } else if (strcmp(opname, "bit-or") == 0) { + emit_opcode(vm, OP_BOR); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + int src2 = parse_register(node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_byte(vm, src2); + } else if (strcmp(opname, "bit-xor") == 0) { + emit_opcode(vm, OP_BXOR); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + int src2 = parse_register(node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_byte(vm, src2); } else if (strcmp(opname, "add-int") == 0) { emit_opcode(vm, OP_ADD_INT); int dest = parse_register(node->children[0]->token); @@ -780,14 +923,18 @@ void assemble(VM *vm, ExprNode *program) { for (size_t i = 0; i < program->child_count; ++i) { ExprNode *section = program->children[i]; if (strcmp(section->token, "code") == 0) { - for (size_t i = 0; i < section->child_count; ++i) { - process_code_expr(vm, &table, section->children[i]); + for (size_t j = 0; j < section->child_count; ++j) { + process_code_expr(vm, &table, section->children[j]); } } } // Cleanup symbol table for (int i = 0; i < table.count; i++) { +#ifdef ASM_DEBUG + Symbol s = table.symbols[i]; + printf("%s[%d]\n", s.name, s.address); +#endif free(table.symbols[i].name); } free(table.symbols); diff --git a/src/vm/vm.c b/src/vm/vm.c index d4b2636..73651a7 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -37,19 +37,17 @@ return true; \ } while (0) -#define BIT_OP(op) \ -do { \ - dest = read_u8(vm, code, vm->pc); \ - vm->pc++; \ - src1 = read_u8(vm, code, vm->pc); \ - vm->pc++; \ - src2 = read_u8(vm, code, vm->pc); \ - vm->pc++; \ - frame->registers[dest] = \ - frame->registers[src1] op frame->registers[src2]; \ - return true; \ -} while (0) - +#define BIT_OP(op) \ + do { \ + dest = read_u8(vm, code, vm->pc); \ + vm->pc++; \ + src1 = read_u8(vm, code, vm->pc); \ + vm->pc++; \ + src2 = read_u8(vm, code, vm->pc); \ + vm->pc++; \ + frame->registers[dest] = frame->registers[src1] op frame->registers[src2]; \ + return true; \ + } while (0) u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) { u32 str_addr = vm->mp; @@ -110,8 +108,10 @@ bool step_vm(VM *vm) { case OP_LOAD: { dest = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + v = frame->registers[src1]; + ptr = frame->registers[dest]; v = read_u32(vm, memory, ptr); frame->registers[dest] = v; return true; @@ -120,28 +120,33 @@ bool step_vm(VM *vm) { i8 v8; dest = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + v = frame->registers[src1]; + ptr = frame->registers[dest]; v8 = (i8)read_u8(vm, memory, ptr); - frame->registers[dest] = v8; + frame->registers[ptr] = v8; return true; } case OP_LOADU8: { u8 v8; dest = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + ptr = frame->registers[src1]; v8 = read_u8(vm, memory, ptr); - frame->registers[dest] = v8; + frame->registers[ptr] = v8; return true; } case OP_LOADI16: { i16 v16; dest = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + v = frame->registers[src1]; + ptr = frame->registers[dest]; v16 = (i16)read_u16(vm, memory, ptr); frame->registers[dest] = v16; return true; @@ -150,34 +155,41 @@ bool step_vm(VM *vm) { u16 v16; dest = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + v = frame->registers[src1]; + ptr = frame->registers[dest]; v16 = read_u16(vm, memory, ptr); - frame->registers[dest] = v16; + frame->registers[ptr] = v16; return true; } case OP_STORE: { + dest = read_u8(vm, code, vm->pc); + vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; v = frame->registers[src1]; + ptr = frame->registers[dest]; write_u32(vm, memory, ptr, v); return true; - }case OP_STORE8: { + } + case OP_STORE8: { + dest = read_u8(vm, code, vm->pc); + vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; v = frame->registers[src1]; + ptr = frame->registers[dest]; write_u8(vm, memory, ptr, v); return true; - }case OP_STORE16: { + } + case OP_STORE16: { + dest = read_u8(vm, code, vm->pc); + vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - ptr = read_u32(vm, code, vm->pc); - vm->pc += 4; v = frame->registers[src1]; + ptr = frame->registers[dest]; write_u16(vm, memory, ptr, v); return true; } @@ -261,16 +273,22 @@ bool step_vm(VM *vm) { vm->pc++; path_ptr = frame->registers[path_reg]; /* path pointer */ - size = frame->registers[size_reg]; /* size */ - buffer_ptr = (dest > 32) ? vm->mp : dest; /* dest ptr, if > 32 then use memory pointer*/ + size = frame->registers[size_reg]; /* size */ + buffer_ptr = (dest > 32) + ? vm->mp + : dest; /* dest ptr, if > 32 then use memory pointer*/ dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); if (dev && dev->ops->read) { vm->flag = dev->ops->read(dev->data, (u8 *)&vm->memory[buffer_ptr + 4], size); - if (dest > 32) { vm->mp += size + 4;} + if (dest > 32) { + vm->mp += size + 4; + } write_u32(vm, memory, buffer_ptr, size); - if (dest > 32) { frame->end = vm->mp; } + if (dest > 32) { + frame->end = vm->mp; + } frame->registers[buffer_reg] = buffer_ptr; } else { vm->flag = 0; diff --git a/test/box.asm.lisp b/test/box.asm.lisp new file mode 100644 index 0000000..f980fbf --- /dev/null +++ b/test/box.asm.lisp @@ -0,0 +1,20 @@ +((code + (label main + (load-immediate $0 &screen-namespace) + (load-immediate $1 0) + (syscall DEVICE-OPEN $0 $1) + + (load-immediate $3 0xE0) + (load-immediate $4 36) + + (load-immediate $1 1) + (load-immediate $5 50) + (label loop-x + (store-8 $4 $3) + (add-int $4 $4 $1) + (jump-lt-int &loop-x $4 $5)) + + (syscall DEVICE-WRITE $0 $0 $0) + (halt))) +(data + (label screen-namespace "/dev/screen/0"))) diff --git a/test/simple.asm.lisp b/test/simple.asm.lisp index acfcf04..49481b1 100644 --- a/test/simple.asm.lisp +++ b/test/simple.asm.lisp @@ -1,16 +1,21 @@ ((code (label main - (load $0 &x) - (load $1 &y) + (load-immediate $0 &x) + (load-immediate $1 &y) (add-real $2 $1 $0) (real-to-string $3 $2) - (string-length $4 $3) - (load-immediate $5 &terminal-namespace) - (syscall DEVICE-WRITE $5 $3 $4) - (load-immediate $6 &new-line) - (string-length $7 $6) - (syscall DEVICE-WRITE $5 $6 $7) - (halt))) + (push $3) + (call &println) + (halt)) + (label println + (load-immediate $0 &terminal-namespace) + (load-immediate $3 &new-line) + (pop $1) + (string-length $2 $1) + (syscall DEVICE-WRITE $0 $1 $2) + (string-length $4 $3) + (syscall DEVICE-WRITE $0 $3 $4) + (return))) (data (label terminal-namespace "/dev/term/0") (label new-line "\n") (label x 1.0) diff --git a/test/window.asm.lisp b/test/window.asm.lisp index 17650ae..06ab150 100644 --- a/test/window.asm.lisp +++ b/test/window.asm.lisp @@ -1,9 +1,14 @@ -((code - (label main - (load-immediate $0 &screen-namespace) - (load-immediate $1 0) ; mode 0 - (syscall DEVICE-OPEN $0 $2) - +((code + (label main + (load-immediate $0 &screen-namespace) + (load-immediate $1 0) + (syscall DEVICE-OPEN $0 $2) - (halt))) -(data (label screen-namespace "/dev/term/0"))) + (load-immediate $3 0x55) + (load-immediate $4 36) + (store-8 $4 $3) + (syscall DEVICE-WRITE $0 $0 $0) + + (halt))) +(data + (label screen-namespace "/dev/screen/0")))