From 77033e121bb2118acbfa695aa5ebf219b5127a51 Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 4 Oct 2025 17:24:24 -0700 Subject: [PATCH] Add malloc, load-r, load-r8. fix endianess, refactor devices, init box, init window drawing --- README.org | 2 +- docs/draw.ul | 46 +++++ src/arch/linux/devices.c | 73 ++++++-- src/arch/linux/devices.h | 13 +- src/arch/linux/main.c | 146 ++++++++++----- src/tools/assembler.c | 50 +++-- src/tools/parser.c | 394 ++++++++++++++++++++------------------- src/tools/parser.h | 8 +- src/vm/opcodes.h | 39 ++-- src/vm/str.c | 5 - src/vm/vm.c | 73 +++++--- test/add.asm.lisp | 4 +- test/add.rom | Bin 380960 -> 0 bytes test/box.asm.lisp | 173 +++++++++++++++-- test/fib.asm.lisp | 4 +- test/fib.rom | Bin 380960 -> 0 bytes test/hello.asm.lisp | 2 +- test/hello.rom | Bin 380960 -> 0 bytes test/loop.asm.lisp | 14 +- test/loop.rom | Bin 380960 -> 0 bytes test/malloc.asm.lisp | 25 +++ test/simple.asm.lisp | 4 +- test/simple.rom | Bin 380960 -> 0 bytes test/window.asm.lisp | 87 ++++++++- 24 files changed, 783 insertions(+), 379 deletions(-) create mode 100644 docs/draw.ul delete mode 100644 test/add.rom delete mode 100644 test/fib.rom delete mode 100644 test/hello.rom delete mode 100644 test/loop.rom create mode 100644 test/malloc.asm.lisp delete mode 100644 test/simple.rom diff --git a/README.org b/README.org index a2725f5..3f0f265 100644 --- a/README.org +++ b/README.org @@ -207,7 +207,7 @@ cd undar-lang && make (syscall DEVICE_WRITE $0 $1 $2) (load $3 &new-line) (string-length $4 $3) - (syscall DEVICE-WRITE, $0, $3, $4) + (syscall WRITE, $0, $3, $4) (halt))) (data (label terminal-str "/dev/term/0") diff --git a/docs/draw.ul b/docs/draw.ul new file mode 100644 index 0000000..4c05356 --- /dev/null +++ b/docs/draw.ul @@ -0,0 +1,46 @@ +Device screen("/dev/screen/0"); +u8[] colors = [0,255,36,73,146,182,128,224,144, +252,9,18,12,16,28,159,2,3,10,19,131,147,130,227,129,226, +72,141,136,241,208,244]; + +fn main() { + screen.open(0); + screen.draw(); + + int x = 10; + int y = 20; + for (int i = 0; i < colors.length; i+=2) { + draw_outline_swatch(colors[i], x, y); + draw_outline_swatch(colors[i + 1], x + 20, y); + x += 20; + y += 20; + } + screen.draw(); + exit(0); +} + +fn draw_outline_swatch(u8 color, int x, int y) { + u8 gray = colors[5]; + int outline_size = 20; + int fill_size = 17; + int offset = 2; + + draw_box(gray, x, y, outline_size, outline_size); + int swatch_pos = x + 2; + int offset_pos = y + 2; + draw_box(color, swatch_pos, offset_pos, fill_size, fill_size); + return; +} + +fn draw_box(u8 color, int x, int y, int width, int height) { + int screen_width = screen.width; + int pos = y * 640 + x; + + do (int i = height; i > 0; i--) { + int row = pos + width; + int pixel = offset; + do (int j = ; pos;j++) { + screen.buffer[j] = color; + } + } +} \ No newline at end of file diff --git a/src/arch/linux/devices.c b/src/arch/linux/devices.c index ca935e4..9ff81b9 100644 --- a/src/arch/linux/devices.c +++ b/src/arch/linux/devices.c @@ -36,10 +36,10 @@ i32 console_close(void *data) { return 0; } -i32 console_ioctl(void *data, u32 cmd, void *args) { +i32 console_ioctl(void *data, u32 cmd, const u8 *buffer) { USED(data); USED(cmd); - USED(args); + USED(buffer); return -1; /* Unsupported */ } @@ -81,13 +81,12 @@ i32 screen_write(void *data, const u8 *buffer, u32 size) { ScreenDeviceData *screen = (ScreenDeviceData *)data; USED(buffer); - if (size > screen->framebuffer_size * sizeof(u8)) { + if (size > screen->size * sizeof(u8)) { return -1; } if (screen->texture && screen->renderer) { - SDL_UpdateTexture(screen->texture, nil, - &screen->vm->memory[screen->framebuffer_pos], + SDL_UpdateTexture(screen->texture, nil, &buffer[screen->pos], screen->width); SDL_RenderClear(screen->renderer); @@ -128,16 +127,23 @@ i32 screen_close(void *data) { return 0; } -i32 screen_ioctl(void *data, u32 cmd, void *args) { +i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer) { 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)); + u8 *info = (u8 *)buffer; + u32 size; + memcpy(&size, &info[0], sizeof(u32)); + + if (size < 16) { + return -1; + } + + memcpy(&info[4], &screen->pos, sizeof(u32)); + memcpy(&info[8], &screen->size, sizeof(u32)); + memcpy(&info[12], &screen->width, sizeof(u32)); + memcpy(&info[16], &screen->height, sizeof(u32)); return 0; } @@ -156,14 +162,47 @@ i32 mouse_open(void *data, u32 mode) { i32 mouse_read(void *data, u8 *buffer, u32 size) { MouseDeviceData *mouse = (MouseDeviceData *)data; - if (size < 3 * sizeof(u32)) + if (size < 12) return -1; - u32 *out = (u32 *)buffer; - out[0] = mouse->x; - out[1] = mouse->y; - out[2] = (mouse->btn1 | (mouse->btn2 << 1) | (mouse->btn3 << 2) | - (mouse->btn4 << 3)); + SDL_PumpEvents(); + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_MOUSEMOTION: + mouse->x = event.motion.x; + mouse->y = event.motion.y; + break; + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + mouse->btn1 = 1; + if (event.button.button == SDL_BUTTON_RIGHT) + mouse->btn2 = 1; + if (event.button.button == SDL_BUTTON_MIDDLE) + mouse->btn3 = 1; + if (event.button.button == SDL_BUTTON_X1) + mouse->btn4 = 1; + break; + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + mouse->btn1 = 0; + if (event.button.button == SDL_BUTTON_RIGHT) + mouse->btn2 = 0; + if (event.button.button == SDL_BUTTON_MIDDLE) + mouse->btn3 = 0; + if (event.button.button == SDL_BUTTON_X1) + mouse->btn4 = 0; + break; + } + } + + u8 *info = (u8 *)buffer; + memcpy(&info[0], &mouse->x, sizeof(u32)); + memcpy(&info[4], &mouse->y, sizeof(u32)); + memcpy(&info[8], &mouse->btn1, sizeof(u8)); + memcpy(&info[9], &mouse->btn2, sizeof(u8)); + memcpy(&info[10], &mouse->btn3, sizeof(u8)); + memcpy(&info[11], &mouse->btn4, sizeof(u8)); return 0; } diff --git a/src/arch/linux/devices.h b/src/arch/linux/devices.h index 3da4939..6c00fcb 100644 --- a/src/arch/linux/devices.h +++ b/src/arch/linux/devices.h @@ -8,9 +8,8 @@ typedef struct screen_device_data_s { u32 width; u32 height; - u32 framebuffer_pos; - u32 framebuffer_size; - VM* vm; + u32 pos; + u32 size; SDL_Window *window; SDL_Renderer *renderer; SDL_Texture *texture; @@ -24,19 +23,23 @@ typedef struct mouse_device_data_s { u8 btn2; u8 btn3; u8 btn4; + u32 pos; + u32 size; } MouseDeviceData; /* Keyboard device data */ typedef struct keyboard_device_data_s { const u8 *keys; i32 key_count; + u32 pos; + u32 size; } KeyboardDeviceData; 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 screen_ioctl(void *data, u32 cmd, const u8 *buffer); i32 mouse_open(void *data, u32 mode); i32 mouse_read(void *data, u8 *buffer, u32 size); @@ -52,4 +55,4 @@ i32 console_open(void *data, u32 mode); i32 console_read(void *data, u8 *buffer, u32 size); i32 console_write(void *data, const u8 *buffer, u32 size); i32 console_close(void *data); -i32 console_ioctl(void *data, u32 cmd, void *args); \ No newline at end of file +i32 console_ioctl(void *data, u32 cmd, const u8 *buffer); diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index 1e31ef3..42231d8 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -146,6 +146,7 @@ bool compileAndSave(const char *source_file, const char *output_file, VM *vm) { printf("Parse failed.\n"); return false; } else { + expr_print(ast, 0); assemble(vm, ast); expr_free(ast); @@ -237,15 +238,12 @@ void repl(VM *vm) { * This needs to be done dynamically eventually */ void register_sdl_devices(VM *vm) { - screen_data.vm = vm; screen_data.width = 640; screen_data.height = 480; - screen_data.framebuffer_size = 640 * 480; - screen_data.framebuffer_pos = vm->mp; - vm->mp += screen_data.framebuffer_size; /* advance memory pointer */ + screen_data.size = 640 * 480; + screen_data.pos = vm->mp; + vm->mp += screen_data.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); @@ -255,15 +253,98 @@ void register_sdl_devices(VM *vm) { mouse_data.btn2 = 0; mouse_data.btn3 = 0; mouse_data.btn4 = 0; + mouse_data.size = 12; + mouse_data.pos = vm->mp; + vm->mp += mouse_data.size; /* advance memory pointer */ + vm->frames[vm->fp].end = vm->mp; vm_register_device(vm, "/dev/mouse/0", "mouse", &mouse_data, &mouse_ops); keyboard_data.keys = SDL_GetKeyboardState(&keyboard_data.key_count); - vm_register_device(vm, "/dev/keyboard/0", "keyboard", &keyboard_data, &keyboard_ops); } +const char *opcode_to_string(Opcode op) { + static const char *names[] = {[OP_HALT] = "halt", + [OP_JMP] = "jump", + [OP_JMPF] = "jump-if-flag", + [OP_CALL] = "call", + [OP_RETURN] = "return", + [OP_LOAD] = "load", + [OP_LOAD_REG] = "load-r", + [OP_LOAD_REG8] = "load-r8", + [OP_LOADI8] = "load-i8", + [OP_LOADU8] = "load-u8", + [OP_LOADI16] = "load-i16", + [OP_LOADU16] = "load-u16", + [OP_LOAD_IMM] = "load-immediate", + [OP_MALLOC] = "malloc", + [OP_STORE] = "store", + [OP_STORE8] = "store-8", + [OP_STORE16] = "store-16", + [OP_PUSH] = "push", + [OP_POP] = "pop", + [OP_REG_MOV] = "register-move", + [OP_SYSCALL] = "syscall", + [OP_SLL] = "bit-shift-left", + [OP_SRL] = "bit-shift-right", + [OP_SRE] = "bit-shift-right-extend", + [OP_BAND] = "bit-and", + [OP_BOR] = "bit-or", + [OP_BXOR] = "bit-xor", + [OP_ADD_INT] = "add-int", + [OP_SUB_INT] = "sub-int", + [OP_MUL_INT] = "mul-int", + [OP_DIV_INT] = "div-int", + [OP_ADD_UINT] = "add-nat", + [OP_SUB_UINT] = "sub-nat", + [OP_MUL_UINT] = "mul-nat", + [OP_DIV_UINT] = "div-nat", + [OP_ADD_REAL] = "add-real", + [OP_SUB_REAL] = "sub-real", + [OP_MUL_REAL] = "mul-real", + [OP_DIV_REAL] = "div-real", + [OP_INT_TO_REAL] = "int-to-real", + [OP_UINT_TO_REAL] = "nat-to-real", + [OP_REAL_TO_INT] = "real-to-int", + [OP_REAL_TO_UINT] = "real-to-nat", + [OP_JEQ_INT] = "jump-eq-int", + [OP_JGT_INT] = "jump-gt-int", + [OP_JLT_INT] = "jump-lt-int", + [OP_JLE_INT] = "jump-le-int", + [OP_JGE_INT] = "jump-ge-int", + [OP_JEQ_UINT] = "jump-eq-nat", + [OP_JGT_UINT] = "jump-gt-nat", + [OP_JLT_UINT] = "jump-lt-nat", + [OP_JLE_UINT] = "jump-le-nat", + [OP_JGE_UINT] = "jump-ge-nat", + [OP_JEQ_REAL] = "jump-eq-real", + [OP_JGE_REAL] = "jump-ge-real", + [OP_JGT_REAL] = "jump-gt-real", + [OP_JLT_REAL] = "jump-lt-real", + [OP_JLE_REAL] = "jump-le-real", + [OP_STRLEN] = "string-length", + [OP_STREQ] = "string-eq", + [OP_STRCAT] = "string-concat", + [OP_STR_GET_CHAR] = "string-get-char", + [OP_STR_FIND_CHAR] = "string-find-char", + [OP_STR_SLICE] = "string-slice", + [OP_INT_TO_STRING] = "int-to-string", + [OP_UINT_TO_STRING] = "nat-to-string", + [OP_REAL_TO_STRING] = "real-to-string", + [OP_STRING_TO_INT] = "string-to-int", + [OP_STRING_TO_UINT] = "string-to-nat", + [OP_STRING_TO_REAL] = "string-to-real"}; + + if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) { + return ""; + } + + const char *name = names[op]; + return name ? name : ""; +} + i32 main(i32 argc, char *argv[]) { bool gui_mode = false; bool dump_rom = false; @@ -331,55 +412,22 @@ 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); while (running) { - for (u32 i = 0; i < vm.dc; i++) { - Device *dev = &vm.devices[i]; - if (strcmp(dev->type, "mouse") == 0) { - MouseDeviceData *mouse = (MouseDeviceData *)dev->data; - SDL_PumpEvents(); - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - running = false; - break; - case SDL_MOUSEMOTION: - mouse->x = event.motion.x; - mouse->y = event.motion.y; - break; - case SDL_MOUSEBUTTONDOWN: - if (event.button.button == SDL_BUTTON_LEFT) - mouse->btn1 = 1; - if (event.button.button == SDL_BUTTON_RIGHT) - mouse->btn2 = 1; - if (event.button.button == SDL_BUTTON_MIDDLE) - mouse->btn3 = 1; - if (event.button.button == SDL_BUTTON_X1) - mouse->btn4 = 1; - break; - case SDL_MOUSEBUTTONUP: - if (event.button.button == SDL_BUTTON_LEFT) - mouse->btn1 = 0; - if (event.button.button == SDL_BUTTON_RIGHT) - mouse->btn2 = 0; - if (event.button.button == SDL_BUTTON_MIDDLE) - mouse->btn3 = 0; - if (event.button.button == SDL_BUTTON_X1) - mouse->btn4 = 0; - break; - } - } - } - } - - step_vm(&vm); +#ifdef ASM_DEBUG + printf("| %d %s %d\n", vm.code[vm.pc], opcode_to_string(vm.code[vm.pc]), + vm.pc); +#endif + running = step_vm(&vm); } } else { while (running) { +#ifdef ASM_DEBUG + printf("| %d %s %d\n", vm.code[vm.pc], opcode_to_string(vm.code[vm.pc]), + vm.pc); +#endif running = step_vm(&vm); } } diff --git a/src/tools/assembler.c b/src/tools/assembler.c index 79889ba..cc45592 100644 --- a/src/tools/assembler.c +++ b/src/tools/assembler.c @@ -1,5 +1,4 @@ #include "assembler.h" - typedef enum { SYMBOL_CODE, SYMBOL_DATA, SYMBOL_PLEX } SymbolType; typedef struct { @@ -86,14 +85,12 @@ int get_instruction_byte_size(ExprNode *node) { strcmp(opname, "real-to-string") == 0 || strcmp(opname, "int-to-real") == 0 || strcmp(opname, "nat-to-real") == 0 || - strcmp(opname, "real-to-int") == 0 || + strcmp(opname, "real-to-int") == 0 || strcmp(opname, "load-r") == 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, "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) { + strcmp(opname, "nat-to-int") == 0 || strcmp(opname, "load-r8") == 0 || + strcmp(opname, "string-length") == 0 || strcmp(opname, "store") == 0 || + strcmp(opname, "store-8") == 0 || strcmp(opname, "store-16") == 0 || + strcmp(opname, "register-move") == 0 || strcmp(opname, "malloc") == 0) { return 3; } @@ -117,7 +114,9 @@ int get_instruction_byte_size(ExprNode *node) { } // Load, Load-immediate (6 bytes: 1 + 1 + 4) - if (strcmp(opname, "load-immediate") == 0) { + if (strcmp(opname, "load") == 0 || strcmp(opname, "load-immediate") == 0 || + strcmp(opname, "load-u16") == 0 || strcmp(opname, "load-i16") == 0 || + strcmp(opname, "load-i8") == 0) { return 6; } @@ -365,7 +364,6 @@ void process_data_block(VM *vm, SymbolTable *table, ExprNode *block) { 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...) @@ -380,14 +378,12 @@ void process_data_block(VM *vm, SymbolTable *table, ExprNode *block) { 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 { @@ -442,6 +438,24 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { } else if (strcmp(opname, "load") == 0) { emit_opcode(vm, OP_LOAD); int dest = parse_register(node->children[0]->token); + u32 addr = resolve_symbol(table, node->children[1]->token); + emit_byte(vm, dest); + emit_u32(vm, addr); + } else if (strcmp(opname, "load-r") == 0) { + emit_opcode(vm, OP_LOAD_REG); + 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-r8") == 0) { + emit_opcode(vm, OP_LOAD_REG8); + 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, "malloc") == 0) { + emit_opcode(vm, OP_MALLOC); + int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); @@ -507,17 +521,17 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { // Parse syscall ID u32 syscall_id = 0; const char *syscall_name = node->children[0]->token; - if (strcmp(syscall_name, "DEVICE-EXIT") == 0) + if (strcmp(syscall_name, "EXIT") == 0) syscall_id = SYSCALL_EXIT; - else if (strcmp(syscall_name, "DEVICE-OPEN") == 0) + else if (strcmp(syscall_name, "OPEN") == 0) syscall_id = SYSCALL_DEVICE_OPEN; - else if (strcmp(syscall_name, "DEVICE-READ") == 0) + else if (strcmp(syscall_name, "READ") == 0) syscall_id = SYSCALL_DEVICE_READ; - else if (strcmp(syscall_name, "DEVICE-WRITE") == 0) + else if (strcmp(syscall_name, "WRITE") == 0) syscall_id = SYSCALL_DEVICE_WRITE; - else if (strcmp(syscall_name, "DEVICE-CLOSE") == 0) + else if (strcmp(syscall_name, "CLOSE") == 0) syscall_id = SYSCALL_DEVICE_CLOSE; - else if (strcmp(syscall_name, "DEVICE-IOCTL") == 0) + else if (strcmp(syscall_name, "IOCTL") == 0) syscall_id = SYSCALL_DEVICE_IOCTL; emit_u32(vm, syscall_id); diff --git a/src/tools/parser.c b/src/tools/parser.c index a60c9c4..72eac4c 100644 --- a/src/tools/parser.c +++ b/src/tools/parser.c @@ -1,27 +1,29 @@ #include "parser.h" +#include +#include #include #include #include -#include +#include // Helper function to allocate memory and handle errors void *safe_malloc(size_t size) { - void *ptr = malloc(size); - if (!ptr) { - fprintf(stderr, "Memory allocation failed\n"); - exit(1); - } - return ptr; + void *ptr = malloc(size); + if (!ptr) { + fprintf(stderr, "Memory allocation failed\n"); + exit(1); + } + return ptr; } // Helper function to create a new node static ExprNode *expr_node_create(const char *token, int line) { - ExprNode *node = (ExprNode *)safe_malloc(sizeof(ExprNode)); - node->token = strdup(token ? token : ""); - node->children = NULL; - node->child_count = 0; - node->line = line; - return node; + ExprNode *node = (ExprNode *)safe_malloc(sizeof(ExprNode)); + node->token = strdup(token ? token : ""); + node->children = NULL; + node->child_count = 0; + node->line = line; + return node; } // Forward declaration @@ -29,216 +31,224 @@ static ExprNode *parse_expression(const char **ptr, int line); // Skip whitespace characters and comments static const char *skip_whitespace(const char *ptr) { - while (*ptr) { - // Skip regular whitespace - if (isspace(*ptr)) { - ptr++; - continue; - } - - // Check for comment start - if (*ptr == ';') { - // Skip everything until end of line - while (*ptr && *ptr != '\n') { - ptr++; - } - continue; - } - break; + while (*ptr) { + // Skip regular whitespace + if (isspace(*ptr)) { + ptr++; + continue; } - return ptr; + + // Check for comment start + if (*ptr == ';') { + // Skip everything until end of line + while (*ptr && *ptr != '\n') { + ptr++; + } + continue; + } + break; + } + return ptr; } // Parse a token (atom) static char *parse_token(const char **ptr, int line) { - const char *start = *ptr; - - // Skip leading whitespace and comments - start = skip_whitespace(start); - if (!*start) { - printf("Error at line:%d\n", line); - return NULL; - } - - const char *end = start; - - // Handle quoted strings - if (*start == '"') { - end++; // Skip opening quote - // Read until closing quote or end of string - while (*end && *end != '"') { - if (*end == '\\' && *(end + 1)) { - end += 2; // Skip escaped character - } else { - end++; - } - } - if (*end == '"') { - end++; // Include closing quote - } - } - // Handle parentheses as separate tokens - else if (*end == '(' || *end == ')') { + const char *start = *ptr; + + // Skip leading whitespace and comments + start = skip_whitespace(start); + if (!*start) { + printf("Error at line:%d\n", line); + return NULL; + } + + const char *end = start; + + // Handle quoted strings + if (*start == '"') { + end++; // Skip opening quote + // Read until closing quote or end of string + while (*end && *end != '"') { + if (*end == '\\' && *(end + 1)) { + end += 2; // Skip escaped character + } else { end++; - } else { - // Read until whitespace, parentheses, or comment - while (*end && !isspace(*end) && *end != '(' && *end != ')' && *end != ';') { - end++; - } + } } - - if (end == start) { - printf("Error at line:%d\n", line); - return NULL; + if (*end == '"') { + end++; // Include closing quote } - - size_t len = end - start; - char *token = (char *)safe_malloc(len + 1); - memcpy(token, start, len); - token[len] = '\0'; - - *ptr = end; - return token; + } + // Handle parentheses as separate tokens + else if (*end == '(' || *end == ')') { + end++; + } else { + // Read until whitespace, parentheses, or comment + while (*end && !isspace(*end) && *end != '(' && *end != ')' && + *end != ';') { + end++; + } + } + + if (end == start) { + printf("Error at line:%d\n", line); + return NULL; + } + + size_t len = end - start; + char *token = (char *)safe_malloc(len + 1); + memcpy(token, start, len); + token[len] = '\0'; + + *ptr = end; + return token; } // Parse a list (expression starting with '(') static ExprNode *parse_list(const char **ptr, int line) { - // Skip the opening parenthesis + // Skip the opening parenthesis + (*ptr)++; + + *ptr = skip_whitespace(*ptr); + if (**ptr == ')') { + // Empty list (*ptr)++; - + return expr_node_create("nil", line); + } + + // Parse all children first + ExprNode **temp_children = NULL; + size_t temp_count = 0; + + while (**ptr && **ptr != ')') { + ExprNode *child = parse_expression(ptr, line); + if (child) { + // Resize temp children array + ExprNode **new_temp = + (ExprNode **)safe_malloc(sizeof(ExprNode *) * (temp_count + 1)); + + // Copy existing children + for (size_t i = 0; i < temp_count; i++) { + new_temp[i] = temp_children[i]; + } + + // Add new child + new_temp[temp_count] = child; + temp_count++; + + // Free old array and update + free(temp_children); + temp_children = new_temp; + } + *ptr = skip_whitespace(*ptr); - if (**ptr == ')') { - // Empty list - (*ptr)++; - return expr_node_create("nil", line); + } + + if (**ptr == ')') { + (*ptr)++; // Skip closing parenthesis + } else { + fprintf(stderr, "Error: Missing closing parenthesis at line %d\n", line); + } + + // Create the actual node + ExprNode *node; + if (temp_count > 0 && temp_children[0]->child_count == 0) { + // First child is an atom, use it as the operator + node = expr_node_create(temp_children[0]->token, line); + // Move remaining children + node->child_count = temp_count - 1; + if (node->child_count > 0) { + node->children = + (ExprNode **)safe_malloc(sizeof(ExprNode *) * node->child_count); + for (size_t i = 0; i < node->child_count; i++) { + node->children[i] = temp_children[i + 1]; + } } - - // Parse all children first - ExprNode **temp_children = NULL; - size_t temp_count = 0; - - while (**ptr && **ptr != ')') { - ExprNode *child = parse_expression(ptr, line); - if (child) { - // Resize temp children array - ExprNode **new_temp = (ExprNode **)safe_malloc(sizeof(ExprNode *) * (temp_count + 1)); - - // Copy existing children - for (size_t i = 0; i < temp_count; i++) { - new_temp[i] = temp_children[i]; - } - - // Add new child - new_temp[temp_count] = child; - temp_count++; - - // Free old array and update - free(temp_children); - temp_children = new_temp; - } - - *ptr = skip_whitespace(*ptr); - } - - if (**ptr == ')') { - (*ptr)++; // Skip closing parenthesis - } else { - fprintf(stderr, "Error: Missing closing parenthesis at line %d\n", line); - } - - // Create the actual node - ExprNode *node; - if (temp_count > 0 && temp_children[0]->child_count == 0) { - // First child is an atom, use it as the operator - node = expr_node_create(temp_children[0]->token, line); - // Move remaining children - node->child_count = temp_count - 1; - if (node->child_count > 0) { - node->children = (ExprNode **)safe_malloc(sizeof(ExprNode *) * node->child_count); - for (size_t i = 0; i < node->child_count; i++) { - node->children[i] = temp_children[i + 1]; - } - } - // Free the first child since we used its token - expr_free(temp_children[0]); - } else { - // No operator or first child is a list - node = expr_node_create("list", line); - node->children = temp_children; - node->child_count = temp_count; - } - - if (temp_count == 0) { - free(temp_children); - } - - return node; + // Free the first child since we used its token + expr_free(temp_children[0]); + } else { + // No operator or first child is a list + node = expr_node_create("list", line); + node->children = temp_children; + node->child_count = temp_count; + } + + if (temp_count == 0) { + free(temp_children); + } + + return node; } // Parse an expression (either atom or list) static ExprNode *parse_expression(const char **ptr, int line) { - *ptr = skip_whitespace(*ptr); - - if (!**ptr) return NULL; - - if (**ptr == '(') { - return parse_list(ptr, line); - } else { - // Parse atom - char *token = parse_token(ptr, line); - if (token) { - ExprNode *node = expr_node_create(token, line); - free(token); - return node; - } - return NULL; + *ptr = skip_whitespace(*ptr); + + if (!**ptr) + return NULL; + + if (**ptr == '(') { + return parse_list(ptr, line); + } else { + // Parse atom + char *token = parse_token(ptr, line); + if (token) { + ExprNode *node = expr_node_create(token, line); + free(token); + return node; } + return NULL; + } } // Main parsing function ExprNode *expr_parse(const char *source, size_t source_len) { - if (!source || source_len == 0) return NULL; - - const char *ptr = source; - int line = 1; - - ptr = skip_whitespace(ptr); - if (!*ptr) return NULL; - - return parse_expression(&ptr, line); + if (!source || source_len == 0) + return NULL; + + const char *ptr = source; + int line = 1; + + ptr = skip_whitespace(ptr); + if (!*ptr) + return NULL; + + return parse_expression(&ptr, line); } // Free an Expr AST (and all children) void expr_free(ExprNode *node) { - if (!node) return; - - free(node->token); - - for (size_t i = 0; i < node->child_count; i++) { - expr_free(node->children[i]); - } - free(node->children); - free(node); + if (!node) + return; + + free(node->token); + + for (size_t i = 0; i < node->child_count; i++) { + expr_free(node->children[i]); + } + free(node->children); + free(node); } // Debug: print AST (for dev) void expr_print(ExprNode *node, int indent) { - if (!node) return; - - for (int i = 0; i < indent; i++) { - printf(" "); - } - - if (node->child_count == 0) { - // Atom - printf("Atom: '%s' (line %d)\n", node->token, node->line); - } else { - // List - printf("List: '%s' (line %d) [%zu children]\n", - node->token, node->line, node->child_count); - - for (size_t i = 0; i < node->child_count; i++) { - expr_print(node->children[i], indent + 1); - } + if (!node) + return; + + for (int i = 0; i < indent; i++) { + printf(" "); + } + + if (node->child_count == 0) { + // Atom + printf("Atom: '%s' (line %d)\n", node->token, node->line); + } else { + // List + printf("List: '%s' (line %d) [%zu children]\n", node->token, node->line, + node->child_count); + + for (size_t i = 0; i < node->child_count; i++) { + expr_print(node->children[i], indent + 1); } + } } \ No newline at end of file diff --git a/src/tools/parser.h b/src/tools/parser.h index 149628d..594eca7 100644 --- a/src/tools/parser.h +++ b/src/tools/parser.h @@ -15,15 +15,11 @@ struct ExprNode { int line; // Source line number (for errors) }; -// Parse a string into an Expr AST ExprNode *expr_parse(const char *source, size_t source_len); - -// Free an Expr AST (and all children) +ExprNode* expand_macros(ExprNode* node); +ExprNode* expand_lambda(ExprNode* lambda_node); void expr_free(ExprNode *node); - -// Debug: print AST (for dev) void expr_print(ExprNode *node, int indent); - void *safe_malloc(size_t size); #endif \ No newline at end of file diff --git a/src/vm/opcodes.h b/src/vm/opcodes.h index ed3e132..8b88714 100644 --- a/src/vm/opcodes.h +++ b/src/vm/opcodes.h @@ -6,15 +6,18 @@ typedef enum { OP_HALT, /* halt : terminate execution with code [src1] */ OP_JMP, /* jump : jump to address dest unconditionally */ - OP_JMPF, /* jump-if-flag : jump to address dest if flag is ne 0 */ + OP_JMPF, /* jump-if-flag : jump to address dest if flag is ne 0 */ OP_CALL, /* call : creates a new frame */ OP_RETURN, /* return : returns from a frame to the parent frame */ - OP_LOAD, /* load : dest = memory[src1] */ - OP_LOADI8, /* load-i8 : dest = memory[src1] */ - OP_LOADU8, /* load-u8 : dest = memory[src1] */ - OP_LOADI16, /* load-i16 : dest = memory[src1] */ - OP_LOADU16, /* load-u16 : dest = memory[src1] */ + OP_LOAD, /* load : dest = memory[src1 as u32] */ + OP_LOAD_REG, /* load-r : dest = memory[registers[src1]] as u32 */ + OP_LOAD_REG8, /* load-r8 : dest = memory[registers[src1]] as u8 */ + OP_LOADI8, /* load-i8 : dest = memory[src1 as u32] */ + OP_LOADU8, /* load-u8 : dest = memory[src1 as u32] */ + OP_LOADI16, /* load-i16 : dest = memory[src1 as u32] */ + OP_LOADU16, /* load-u16 : dest = memory[src1 as u32] */ OP_LOAD_IMM, /* load-immediate : dest = constant */ + OP_MALLOC, /* malloc : dest = fat ptr to memory of ((src1 as size) + 4) */ OP_STORE, /* store : memory[dest] = src1 */ OP_STORE8, /* store-8 : memory[dest] = src1 << 8 */ OP_STORE16, /* store-16 : memory[dest] = src1 << 16 */ @@ -95,7 +98,7 @@ typedef struct device_ops_s { i32 (*read)(void *device_data, u8 *buffer, u32 size); i32 (*write)(void *device_data, const u8 *buffer, u32 size); i32 (*close)(void *device_data); - i32 (*ioctl)(void *device_data, u32 cmd, void *args); /* optional control */ + i32 (*ioctl)(void *device_data, u32 cmd, const u8 *buffer); /* optional control */ } DeviceOps; #define DEVICE_TYPE_MAX_LENGTH 24 /* 23 chars + null terminator */ @@ -133,12 +136,14 @@ typedef struct vm_s { } VM; #define read_u8(vm, location, addr) ((vm)->location[addr]) + #define read_u16(vm, location, addr) \ - (((u16)(vm)->location[(addr)] << 8) | ((u16)(vm)->location[(addr) + 1])) + (((u16)(vm)->location[(addr) + 1] << 8) | ((u16)(vm)->location[(addr)])) + #define read_u32(vm, location, addr) \ - (((u32)(vm)->location[(addr)] << 24) | \ - ((u32)(vm)->location[(addr) + 1] << 16) | \ - ((u32)(vm)->location[(addr) + 2] << 8) | ((u32)(vm)->location[(addr) + 3])) + (((u32)(vm)->location[(addr) + 3] << 24) | \ + ((u32)(vm)->location[(addr) + 2] << 16) | \ + ((u32)(vm)->location[(addr) + 1] << 8) | ((u32)(vm)->location[(addr)])) #define write_u8(vm, location, addr, value) \ do { \ @@ -150,18 +155,18 @@ typedef struct vm_s { #define write_u16(vm, location, addr, value) \ do { \ if ((addr) + 1 < sizeof((vm)->location)) { \ - (vm)->location[(addr)] = ((value) >> 8) & 0xFF; \ - (vm)->location[(addr) + 1] = (value) & 0xFF; \ + (vm)->location[(addr)] = (value) & 0xFF; \ + (vm)->location[(addr) + 1] = ((value) >> 8) & 0xFF; \ } \ } while (0) #define write_u32(vm, location, addr, value) \ do { \ if ((addr) + 3 < sizeof((vm)->location)) { \ - (vm)->location[(addr)] = ((value) >> 24) & 0xFF; \ - (vm)->location[(addr) + 1] = ((value) >> 16) & 0xFF; \ - (vm)->location[(addr) + 2] = ((value) >> 8) & 0xFF; \ - (vm)->location[(addr) + 3] = (value) & 0xFF; \ + (vm)->location[(addr)] = (value) & 0xFF; \ + (vm)->location[(addr) + 1] = ((value) >> 8) & 0xFF; \ + (vm)->location[(addr) + 2] = ((value) >> 16) & 0xFF; \ + (vm)->location[(addr) + 3] = ((value) >> 24) & 0xFF; \ } \ } while (0) diff --git a/src/vm/str.c b/src/vm/str.c index c0b805f..8dc736e 100644 --- a/src/vm/str.c +++ b/src/vm/str.c @@ -124,11 +124,6 @@ void fixed_to_string(i32 value, char *buffer) { /* Convert fractional part to 5 decimal digits */ frac_digits = (frac_part * 100000U) / 65536U; - /* Trim trailing zeros */ - while (frac_digits > 0 && frac_digits % 10 == 0) { - frac_digits /= 10; - } - if (frac_digits > 0) { end = write_digits_backwards(frac_digits, end, temp); *--end = '.'; diff --git a/src/vm/vm.c b/src/vm/vm.c index 73651a7..e73f7c9 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -97,6 +97,18 @@ bool step_vm(VM *vm) { of old slice, pop the frame */ return true; } + case OP_MALLOC: { + u32 size; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + frame->registers[dest] = vm->mp; + size = frame->registers[src1]; + write_u32(vm, memory, vm->mp, size); + vm->mp += (size + 4); + return true; + } case OP_LOAD_IMM: { dest = read_u8(vm, code, vm->pc); vm->pc++; @@ -106,24 +118,41 @@ bool step_vm(VM *vm) { return true; } case OP_LOAD: { + dest = read_u8(vm, code, vm->pc); + vm->pc++; + ptr = read_u32(vm, code, vm->pc); + vm->pc += 4; + v = read_u32(vm, memory, ptr); + frame->registers[dest] = v; + return true; + } + case OP_LOAD_REG: { dest = read_u8(vm, code, vm->pc); vm->pc++; 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; + ptr = read_u32(vm, memory, v); + frame->registers[dest] = ptr; + return true; + } + case OP_LOAD_REG8: { + u8 v8; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + v = frame->registers[src1]; + v8 = read_u8(vm, memory, v); + frame->registers[dest] = v8; return true; } case OP_LOADI8: { i8 v8; dest = read_u8(vm, code, vm->pc); vm->pc++; - src1 = read_u8(vm, code, vm->pc); - vm->pc++; - v = frame->registers[src1]; - ptr = frame->registers[dest]; + ptr = read_u32(vm, code, vm->pc); + vm->pc += 4; v8 = (i8)read_u8(vm, memory, ptr); frame->registers[ptr] = v8; return true; @@ -132,9 +161,8 @@ bool step_vm(VM *vm) { u8 v8; dest = read_u8(vm, code, vm->pc); vm->pc++; - src1 = read_u8(vm, code, vm->pc); - vm->pc++; - ptr = frame->registers[src1]; + ptr = read_u32(vm, code, vm->pc); + vm->pc += 4; v8 = read_u8(vm, memory, ptr); frame->registers[ptr] = v8; return true; @@ -143,10 +171,8 @@ bool step_vm(VM *vm) { i16 v16; dest = read_u8(vm, code, vm->pc); vm->pc++; - src1 = read_u8(vm, code, vm->pc); - vm->pc++; - v = frame->registers[src1]; - ptr = frame->registers[dest]; + ptr = read_u32(vm, code, vm->pc); + vm->pc += 4; v16 = (i16)read_u16(vm, memory, ptr); frame->registers[dest] = v16; return true; @@ -155,10 +181,8 @@ bool step_vm(VM *vm) { u16 v16; dest = read_u8(vm, code, vm->pc); vm->pc++; - src1 = read_u8(vm, code, vm->pc); - vm->pc++; - v = frame->registers[src1]; - ptr = frame->registers[dest]; + ptr = read_u32(vm, code, vm->pc); + vm->pc += 4; v16 = read_u16(vm, memory, ptr); frame->registers[ptr] = v16; return true; @@ -274,21 +298,12 @@ bool step_vm(VM *vm) { 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*/ + buffer_ptr = frame->registers[dest]; 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; - } - write_u32(vm, memory, buffer_ptr, size); - if (dest > 32) { - frame->end = vm->mp; - } + dev->ops->read(dev->data, &vm->memory[buffer_ptr + 4], size); frame->registers[buffer_reg] = buffer_ptr; } else { vm->flag = 0; diff --git a/test/add.asm.lisp b/test/add.asm.lisp index 3f98433..ef339dc 100644 --- a/test/add.asm.lisp +++ b/test/add.asm.lisp @@ -23,9 +23,9 @@ (load-immediate $3 &new-line) (pop $1) (string-length $2 $1) - (syscall DEVICE-WRITE $0 $1 $2) + (syscall WRITE $0 $1 $2) (string-length $4 $3) - (syscall DEVICE-WRITE $0 $3 $4) + (syscall WRITE $0 $3 $4) (return))) (data (label terminal-namespace "/dev/term/0") diff --git a/test/add.rom b/test/add.rom deleted file mode 100644 index 9db41ef49c39767687ac57e87413e25710b06932..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380960 zcmeI%y9&ZE6adhhv{R8r7jbr%x^?m={02L^i1_`cKETzb)434tgTM`EO+>`Gp5NHk zCVd9ooKqj)+|+ho;*_FKbA5;sCGB$UbNjj!-8^5HH0HFaRTC+XZSyXhwyh&UfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72rMnI8ZOggxKFq1aGZDN_c#C2&#;dG z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N R0t5&UAV7cs0RsOCJOS@m2220| diff --git a/test/box.asm.lisp b/test/box.asm.lisp index db38df8..1e68567 100644 --- a/test/box.asm.lisp +++ b/test/box.asm.lisp @@ -1,51 +1,159 @@ ((code (label main ; Open screen + ; use load immediate because it is a pointer to a string, not a value (load-immediate $0 &screen-namespace) (load-immediate $1 0) - (syscall DEVICE-OPEN $0 $1) + (syscall OPEN $0 $1) + ; draw to the device because otherwise the screen wont open + (syscall WRITE $0 $0 $0) - ; Draw red box at (10, 20) - (load-immediate $1 0xE0) ; color + ; first row + (load $1 &BLACK) (push $1) - (load-immediate $1 10) ; x + (load-immediate $1 1) (push $1) - (load-immediate $1 20) ; y + (load-immediate $1 1) (push $1) - (call &draw-box) + (call &draw-outlined-swatch) - ; Draw green box at (10, 40) - (load-immediate $1 0x1C) ; RGB332 green (00011100) + (load $1 &WHITE) + (push $1) + (load-immediate $1 21) + (push $1) + (load-immediate $1 1) + (push $1) + (call &draw-outlined-swatch) + + ; row 2 + (load $1 &CHARCOAL) + (push $1) + (load-immediate $1 30) + (push $1) + (load-immediate $1 40) + (push $1) + (call &draw-outlined-swatch) + + (load $1 &DARK-GRAY) (push $1) (load-immediate $1 10) (push $1) (load-immediate $1 40) (push $1) - (call &draw-box) + (call &draw-outlined-swatch) + + ; row 3 + (load $1 &RED) + (push $1) + (load-immediate $1 30) + (push $1) + (load-immediate $1 60) + (push $1) + (call &draw-outlined-swatch) + + (load $1 &ORANGE) + (push $1) + (load-immediate $1 10) + (push $1) + (load-immediate $1 60) + (push $1) + (call &draw-outlined-swatch) + + ; row 3 + (load $1 &YELLOW) + (push $1) + (load-immediate $1 30) + (push $1) + (load-immediate $1 80) + (push $1) + (call &draw-outlined-swatch) + + (load $1 &GREEN) + (push $1) + (load-immediate $1 10) + (push $1) + (load-immediate $1 80) + (push $1) + (call &draw-outlined-swatch) + + ; row 4 + (load $1 &BLUE) + (push $1) + (load-immediate $1 30) + (push $1) + (load-immediate $1 100) + (push $1) + (call &draw-outlined-swatch) + + (load $1 &PURPLE) + (push $1) + (load-immediate $1 10) + (push $1) + (load-immediate $1 100) + (push $1) + (call &draw-outlined-swatch) ; Flush and halt - (syscall DEVICE-WRITE $0 $0 $0) + (syscall WRITE $0 $0 $0) (halt)) + (label draw-outlined-swatch + (pop $3) ; y + (pop $2) ; x + (pop $1) ; color + + ; Constants + (load $4 &GRAY) + (load-immediate $5 20) ; outline size + (load-immediate $6 17) ; fill size + (load-immediate $7 2) ; offset + + (push $4) ; color (gray) + (push $2) ; x + (push $3) ; y + (push $5) ; width (20) + (push $5) ; height (20) + (call &draw-box) + + (add-int $8 $2 $7) ; x + 2 + (add-int $9 $3 $7) ; y + 2 + + (push $1) ; color (original) + (push $8) ; x + 2 + (push $9) ; y + 2 + (push $6) ; width (17) + (push $6) ; height (17) + (call &draw-box) + + (return)) + ; draw-box(color, x, y) ; Pops: y, x, color (label draw-box ; Pop arguments (reverse order) + (pop $14) ; height + (pop $12) ; width (pop $13) ; y_start (pop $11) ; x_start (pop $3) ; color + ;; get the screen width dynamically from the device + (load-immediate $0 &screen-namespace) + (load-immediate $16 1) ; device info call + (load-immediate $17 16) ; sizeof screen device info + (malloc $18 $17) + (syscall IOCTL $0 $16 $18) + (load-immediate $1 12) ; offset for width + (add-nat $19 $18 $1) + (load-r $2 $19) ; load width + ; Constants (load-immediate $1 1) ; increment - (load-immediate $2 640) ; row stride - (load-immediate $10 36) ; framebuffer base - (load-immediate $12 20) ; width - (load-immediate $14 20) ; height ; Compute start address: base + y*640 + x (mul-int $15 $13 $2) ; $15 = y * 640 (add-int $15 $15 $11) ; $15 += x - (add-int $4 $10 $15) ; $4 = base + offset + (register-move $4 $15) ; Outer loop: height times (register-move $5 $14) ; $5 = row counter @@ -64,4 +172,37 @@ (jump-gt-int &draw-box-outer $5 0)) (return))) (data - (label screen-namespace "/dev/screen/0"))) + (label screen-namespace "/dev/screen/0") + (label mouse-namespace "/dev/mouse/0") + (label BLACK 0) + (label WHITE 255) + (label CHARCOAL 36) + (label DARK-GRAY 73) + (label GRAY 146) + (label LIGHT-GRAY 182) + (label DARK-RED 128) + (label RED 224) + (label DARK-YELLOW 144) + (label YELLOW 252) + (label DARK-TEAL 9) + (label TEAL 18) + (label DARK-GREEN 12) + (label GREEN 16) + (label LIME 28) + (label LIGHT-CYAN 159) + (label NAVY 2) + (label BLUE 3) + (label DEEP-SKY-BLUE 10) + (label LIGHT-BLUE 19) + (label PURPLE 131) + (label LIGHT-PURPLE 147) + (label DARK-MAGENTA 130) + (label MAGENTA 227) + (label PLUM 129) + (label PINK 226) + (label SADDLE-BROWN 72) + (label PERU 141) + (label SIENNA 136) + (label ORANGE 241) + (label DARK-ORANGE 208) + (label GOLD 244))) diff --git a/test/fib.asm.lisp b/test/fib.asm.lisp index 09cc676..81a41e8 100644 --- a/test/fib.asm.lisp +++ b/test/fib.asm.lisp @@ -33,9 +33,9 @@ (load-immediate $3 &new-line) (pop $1) (string-length $2 $1) - (syscall DEVICE-WRITE $0 $1 $2) + (syscall WRITE $0 $1 $2) (string-length $4 $3) - (syscall DEVICE-WRITE $0 $3 $4) + (syscall WRITE $0 $3 $4) (return))) (data (label terminal-namespace "/dev/term/0") diff --git a/test/fib.rom b/test/fib.rom deleted file mode 100644 index 6206833d6581dc3e32e7989de813fc28500ad704..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380960 zcmeI%t4>5Q6a~=J$BeikEf@k=9OmLi@f##~Mq&s-^6j*D5c2_pTTS}fIXz<8MnwFK zc|LB(CH)1<+#g$%u|4#7Nzu|gzeSH_7Uie0yhd7Pn(u3rR=46UNM}K>eRsFt)wZuK z>ee{6qU)XxIo*u+B~m`rayph;M`REnK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pkmk_vG-;dwx*YWdXeV+aD>FfRyt@R*4fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ tfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfWZF=`~n7t2qypl diff --git a/test/hello.asm.lisp b/test/hello.asm.lisp index fb705d3..2e3e33a 100644 --- a/test/hello.asm.lisp +++ b/test/hello.asm.lisp @@ -3,7 +3,7 @@ (load-immediate $0 &terminal-namespace) ; load terminal namespace (load-immediate $1 &hello-str) ; load hello string ptr (string-length $2 $1) ; get length to write to stdout - (syscall DEVICE-WRITE $0 $1 $2) ; do the write syscall + (syscall WRITE $0 $1 $2) ; do the write syscall (halt))) ; done (data (label terminal-namespace "/dev/term/0") diff --git a/test/hello.rom b/test/hello.rom deleted file mode 100644 index 8cebff6490a18d1d1928a208b3252f7318ec471f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380960 zcmeI&p$@_@5C-7ua0?{hkf0`uo5b=URI&uZcz!yV;1w3WCYL|gGuKZyB4S_b_Z(}J z=8N`|?bL4jChcmjA~o|=5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjsV zSm$eb 32 will work - (syscall DEVICE-READ $10 $2 $8 $255) + + (malloc $11 $8) + (syscall READ $10 $2 $8 $11) (push $2) (call &println) (nat-to-string $4 $1) @@ -34,9 +32,9 @@ (load-immediate $3 &new-line) (pop $1) (string-length $2 $1) - (syscall DEVICE-WRITE $0 $1 $2) + (syscall WRITE $0 $1 $2) (string-length $4 $3) - (syscall DEVICE-WRITE $0 $3 $4) + (syscall WRITE $0 $3 $4) (return))) (data (label terminal-namespace "/dev/term/0") diff --git a/test/loop.rom b/test/loop.rom deleted file mode 100644 index 4d4576bcbc06b37e034698b17466dc851d652df2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380960 zcmeI%yGjE=6b9hAtYjS|8f>g&8?jJ`UBE&sA4D*Sg(+eXAHkRKS>xHn!qU>>JFq)v z{<$oC?WUB{S3JM#Dkk|SXek|})M9%2*~%EUx{YcFV?M;{S`v)2r#6Z4 zWYJG%G1fNeTOZBP4&%KYv(iexot7Hy$6c4F-LAW@Xw#Cb{6-m6}YZU`Y<>iL~x z4b8X6^S#e=Je*<^t|^XfDxZ2+%al`Fy876TeYX@{U!x&FfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C7Rwb|*ZqsXcPLKO=o)?Q{`5q8gwWVbU5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5Fqd; F@CGVJ1-<|P diff --git a/test/window.asm.lisp b/test/window.asm.lisp index 06ab150..5bc1b06 100644 --- a/test/window.asm.lisp +++ b/test/window.asm.lisp @@ -1,14 +1,83 @@ ((code (label main (load-immediate $0 &screen-namespace) - (load-immediate $1 0) - (syscall DEVICE-OPEN $0 $2) + (load-immediate $11 0) + (syscall OPEN $0 $11) + (syscall WRITE $0 $0 $0) - (load-immediate $3 0x55) - (load-immediate $4 36) - (store-8 $4 $3) - (syscall DEVICE-WRITE $0 $0 $0) - - (halt))) + (load-immediate $16 1) ; device info call + (load-immediate $17 16) ; sizeof screen device info + (malloc $18 $17) + (syscall IOCTL $0 $16 $18) + (load-immediate $1 12) ; offset for width + (add-nat $19 $18 $1) + (load-r $20 $19) ; load width + + (load-immediate $16 &mouse-namespace) + (load-immediate $3 12) ; malloc sizeof mouse data + (malloc $4 $3) + + (label draw-loop + ; load mouse click data + (syscall READ $16 $2 $3 $4) + (load-immediate $5 4) ; offset for x + (add-nat $6 $5 $2) + (load-r $7 $6) ; load x + (load-immediate $5 8) ; offset for y + (add-nat $6 $5 $2) + (load-r $8 $6) ; load y + (load-immediate $5 12) ; offset for btn1 + (add-nat $6 $5 $2) + (load-r8 $9 $6) ; load btn1 pressed + (load-immediate $5 13) ; offset for btn2 + (add-nat $6 $5 $2) + (load-r8 $10 $6) ; load btn2 pressed + (load-r $12 $5) ; load x + + (jump-eq-nat &draw-loop $9 $11) + + ;;(nat-to-string $1 $7) + ;;(push $1) + ;;(call &println) + ;; + ;;(nat-to-string $1 $8) + ;;(push $1) + ;;(call &println) + ;; + ;;(nat-to-string $1 $9) + ;;(push $1) + ;;(call &println) +;; + ;;(nat-to-string $1 $10) + ;;(push $1) + ;;(call &println) + ;; + ;;(nat-to-string $1 $12) + ;;(push $1) + ;;(call &println) + + ; Compute start address: y*width + x + (mul-nat $15 $8 $20) ; $15 = y * width + (add-nat $15 $15 $7) ; $15 += x + + (load $3 &WHITE) ; color + (store-8 $15 $3) ; draw color at screen [x,y] + (syscall WRITE $0 $0 $0) ; redraw + + (jump-eq-nat &draw-loop $10 $11)) + (halt)) + (label println + (load-immediate $0 &terminal-namespace) + (load-immediate $3 &new-line) + (pop $1) + (string-length $2 $1) + (syscall WRITE $0 $1 $2) + (string-length $4 $3) + (syscall WRITE $0 $3 $4) + (return))) (data - (label screen-namespace "/dev/screen/0"))) + (label screen-namespace "/dev/screen/0") + (label mouse-namespace "/dev/mouse/0") + (label terminal-namespace "/dev/term/0") + (label new-line "\n") + (label WHITE 255)))