From 054012418badd193dfb6548f8e24825ce8a1bbc1 Mon Sep 17 00:00:00 2001 From: zongor Date: Tue, 14 Oct 2025 00:02:12 -0700 Subject: [PATCH] remove string lookup for devices use handles instead --- src/arch/linux/devices.c | 65 ++++++++++++++++++++------------- src/arch/linux/devices.h | 3 +- src/arch/linux/main.c | 37 +++++++++++++------ src/vm/device.c | 6 ++-- src/vm/opcodes.h | 3 +- src/vm/vm.c | 19 +++++----- test/add.asm.lisp | 36 +++++++++++-------- test/fib.asm.lisp | 77 ++++++++++++++++++++-------------------- test/hello.asm.lisp | 1 + test/loop.asm.lisp | 1 + test/malloc.asm.lisp | 1 + test/paint.asm.lisp | 20 ++++++----- test/simple.asm.lisp | 1 + test/window.asm.lisp | 8 +++-- 14 files changed, 164 insertions(+), 114 deletions(-) diff --git a/src/arch/linux/devices.c b/src/arch/linux/devices.c index f9f33e7..cf45dcb 100644 --- a/src/arch/linux/devices.c +++ b/src/arch/linux/devices.c @@ -53,8 +53,24 @@ i32 screen_open(void *data, u32 mode) { SDL_WINDOWPOS_CENTERED, screen->width, screen->height, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); - if (!screen->window) + if (!screen->window) { return -1; + } + + screen->renderer = + SDL_CreateRenderer(screen->window, -1, SDL_RENDERER_ACCELERATED); + if (!screen->renderer) { + return -1; + } + + screen->texture = SDL_CreateTexture(screen->renderer, SDL_PIXELFORMAT_RGB332, + SDL_TEXTUREACCESS_STREAMING, + screen->width, screen->height); + + if (!screen->texture) { + fprintf(stderr, "SDL_CreateTexture failed: %s\n", SDL_GetError()); + return -1; + } SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); return 0; @@ -73,30 +89,29 @@ i32 screen_write(void *data, const u8 *buffer, u32 size) { if (size > screen->size * sizeof(u8)) { return -1; } - - if (!screen->surface && screen->window) { - const u8 *pixel_buffer = buffer; - int pitch = screen->width; // bytes per row - - screen->surface = SDL_CreateRGBSurfaceFrom((void *)pixel_buffer, - screen->width, screen->height, - 8, // bits per pixel - pitch, - 0xE0, // R mask (RGB332) - 0x1C, // G mask - 0x03, // B mask - 0x00 // no alpha - ); - - if (!screen->surface) { - fprintf(stderr, "SDL_CreateRGBSurfaceFrom failed: %s\n", SDL_GetError()); - return -1; - } - } - - SDL_BlitScaled(screen->surface, NULL, SDL_GetWindowSurface(screen->window), - NULL); - SDL_UpdateWindowSurface(screen->window); + // Update texture with new frame data + SDL_UpdateTexture(screen->texture, NULL, buffer, screen->width); + + // Clear and render + SDL_RenderClear(screen->renderer); + + SDL_Rect output_rect; + SDL_RenderGetViewport(screen->renderer, &output_rect); + + // Calculate aspect ratio preserving scaling + 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, NULL, &dstrect); + SDL_RenderPresent(screen->renderer); return 0; } diff --git a/src/arch/linux/devices.h b/src/arch/linux/devices.h index 8cd9910..6c00fcb 100644 --- a/src/arch/linux/devices.h +++ b/src/arch/linux/devices.h @@ -11,7 +11,8 @@ typedef struct screen_device_data_s { u32 pos; u32 size; SDL_Window *window; - SDL_Surface *surface; + SDL_Renderer *renderer; + SDL_Texture *texture; } ScreenDeviceData; /* Mouse device data */ diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index de78fb5..357ea71 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -415,28 +415,45 @@ i32 main(i32 argc, char *argv[]) { return EXIT_SUCCESS; } - bool running = true; - vm_register_device(&vm, "/dev/term/0", "terminal", nil, &console_device_ops); if (gui_mode) { if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL initialization failed: %s\n", SDL_GetError()); return 1; } - register_sdl_devices(&vm); SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); + screen_data.width = 640; + screen_data.height = 480; + screen_data.size = screen_data.width * screen_data.height; + + vm_register_device(&vm, "/dev/screen/0", "screen", + &screen_data, &screen_ops); + + mouse_data.x = 0; + mouse_data.y = 0; + mouse_data.btn1 = 0; + mouse_data.btn2 = 0; + mouse_data.btn3 = 0; + mouse_data.btn4 = 0; + mouse_data.size = 12; + + 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); + + bool running = true; while (running) { -#ifdef ASM_DEBUG - printf("| %s %d\n", opcode_to_string(vm.code[vm.pc]), vm.pc); -#endif - running = step_vm(&vm); + if (!step_vm(&vm)) { + running = false; + break; + } } } else { + bool running = true; while (running) { -#ifdef ASM_DEBUG - printf("| %s %d\n", opcode_to_string(vm.code[vm.pc]), vm.pc); -#endif running = step_vm(&vm); } } diff --git a/src/vm/device.c b/src/vm/device.c index e6c3ebb..5d93c9f 100644 --- a/src/vm/device.c +++ b/src/vm/device.c @@ -8,8 +8,8 @@ i32 vm_register_device(VM *vm, const char *path, const char *type, void *data, if (vm->dc >= DEVICES_SIZE) return -1; - dev = &vm->devices[vm->dc++]; - + dev = &vm->devices[vm->dc]; + dev->handle = vm->dc++; strcopy(dev->path, path, DEVICE_PATH_MAX_LENGTH); dev->path[DEVICE_PATH_MAX_LENGTH - 1] = '\0'; @@ -19,7 +19,7 @@ i32 vm_register_device(VM *vm, const char *path, const char *type, void *data, dev->data = data; dev->ops = ops; dev->flags = 0; - return 0; + return dev->handle; } /* Find device by path */ diff --git a/src/vm/opcodes.h b/src/vm/opcodes.h index 04aa1bf..9ceebe4 100644 --- a/src/vm/opcodes.h +++ b/src/vm/opcodes.h @@ -105,7 +105,7 @@ typedef struct device_ops_s { const u8 *buffer); /* optional control */ } DeviceOps; -#define DEVICE_TYPE_MAX_LENGTH 24 /* 23 chars + null terminator */ +#define DEVICE_TYPE_MAX_LENGTH 16 /* 15 chars + null terminator */ #define DEVICE_PATH_MAX_LENGTH 64 /* 63 chars + null terminator */ typedef struct device_s { @@ -115,6 +115,7 @@ typedef struct device_s { void *data; /* device-specific data */ DeviceOps *ops; /* operations vtable */ u32 flags; /* permissions, status, etc. */ + u32 handle; /* id for fast access in VM */ } Device; #define MEMORY_SIZE (640 * 480 + 65536) diff --git a/src/vm/vm.c b/src/vm/vm.c index 8b244e7..65114ae 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -269,6 +269,7 @@ bool step_vm(VM *vm) { if (dev) { if (dev->ops->open) { vm->flag = dev->ops->open(dev->data, mode); + vm->stack[vm->sp++] = dev->handle; } else { vm->flag = 1; /* success, no open needed */ } @@ -282,11 +283,11 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_READ: { Device *dev; - u32 path_ptr = vm->stack[--vm->sp]; /* path pointer */ + u32 handle = vm->stack[--vm->sp]; /* path pointer */ u32 size = vm->stack[--vm->sp]; /* size */ u32 buffer_ptr = vm->stack[--vm->sp]; - dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); + dev = &vm->devices[handle]; if (dev && dev->ops->read) { vm->flag = dev->ops->read(dev->data, &vm->memory[buffer_ptr + 4], size); vm->stack[vm->sp++] = buffer_ptr; @@ -299,11 +300,11 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_WRITE: { Device *dev; - u32 path_ptr = vm->stack[--vm->sp]; /* path pointer */ + u32 handle = vm->stack[--vm->sp]; /* path pointer */ u32 size = vm->stack[--vm->sp]; /* size */ u32 buffer_ptr = vm->stack[--vm->sp]; /* buffer pointer */ - dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); + dev = &vm->devices[handle]; if (dev && dev->ops->write) { vm->flag = dev->ops->write( dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], size); @@ -316,10 +317,9 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_CLOSE: { Device *dev; - u32 path_ptr = vm->stack[--vm->sp]; /* path pointer */ - - dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); + u32 handle = vm->stack[--vm->sp]; /* path pointer */ + dev = &vm->devices[handle]; if (dev && dev->ops->close) { i32 result = dev->ops->close(dev->data); vm->flag = result; @@ -332,12 +332,11 @@ bool step_vm(VM *vm) { case SYSCALL_DEVICE_IOCTL: { Device *dev; - u32 path_ptr = vm->stack[--vm->sp]; /* device path */ + u32 handle = vm->stack[--vm->sp]; /* device path */ u32 cmd = vm->stack[--vm->sp]; /* ioctl command */ u32 args_ptr = vm->stack[--vm->sp]; /* args pointer */ - dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]); - + dev = &vm->devices[handle]; if (dev && dev->ops && dev->ops->ioctl) { i32 result = dev->ops->ioctl(dev->data, cmd, &vm->memory[args_ptr]); vm->flag = result; diff --git a/test/add.asm.lisp b/test/add.asm.lisp index ea016d7..9bd95bf 100644 --- a/test/add.asm.lisp +++ b/test/add.asm.lisp @@ -1,26 +1,32 @@ ((code (label main - (push 1) - (push 1) + (load-immediate $0 1) + (push $0) + (load-immediate $0 1) + (push $0) (call &add) - (int-to-string) - (call &pln) + (pop $0) + (int-to-string $1 $0) + (push $1) + (call &println) (halt)) (label add - (add-int) + (pop $0) + (pop $1) + (add-int $2 $1 $0) + (push $2) (return)) - (label pln - (dup) - (string-length) - (push &terminal-namespace) - (syscall WRITE) - (push &new-line) - (dup) - (string-length) - (push &terminal-namespace) - (syscall WRITE) + (label println + (load-immediate $0 &terminal-namespace) + (syscall OPEN $0 $0 $0) + (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 terminal-namespace "/dev/term/0") diff --git a/test/fib.asm.lisp b/test/fib.asm.lisp index bf8c516..71d501f 100644 --- a/test/fib.asm.lisp +++ b/test/fib.asm.lisp @@ -1,43 +1,42 @@ ((code - (label main - (push 35) - (call &fib) - (int-to-string) - (call &pln) - (halt)) - - (label fib - (dup) ; dup num - (push 2) ; Base case: n < 2 - (jump-lt-int &base-case) - - (dup) - (push 2) ; First call: fib(n-2) - (sub-int) ; n - 2 - (call &fib) - - (over) ; get n over the previous answer - (push 1) ; Second call: fib(n-1) - (sub-int) ; n-1 (using saved n) - (call &fib) ; Result in $2 - - ; Combine results - (add-int) ; fib(n-2) + fib(n-1) - (return) ; Return result - - (label base-case - (return))) ; Return n directly - - (label pln - (dup) - (string-length) - (push &terminal-namespace) - (syscall WRITE) - (push &new-line) - (dup) - (string-length) - (push &terminal-namespace) - (syscall WRITE) + (label main + (load-immediate $0 35) + (push $0) + (call &fib) + (pop $0) + (int-to-string $1 $0) + (push $1) + (call &pln) + (halt)) + (label fib + (pop $0) + (load-immediate $1 2) + (jump-lt-int &base-case $0 $1) + (load-immediate $3 2) + (sub-int $4 $0 $3) + (push $4) + (call &fib) + (load-immediate $3 1) + (sub-int $4 $0 $3) + (push $4) + (call &fib) + (pop $4) + (pop $5) + (add-int $6 $5 $4) + (push $6) + (return) + (label base-case + (push $0) + (return))) + (label pln + (load-immediate $0 &terminal-namespace) + (syscall OPEN $0 $0 $0) + (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 terminal-namespace "/dev/term/0") diff --git a/test/hello.asm.lisp b/test/hello.asm.lisp index 2e3e33a..ce12640 100644 --- a/test/hello.asm.lisp +++ b/test/hello.asm.lisp @@ -1,6 +1,7 @@ ((code (label main (load-immediate $0 &terminal-namespace) ; load terminal namespace + (syscall OPEN $0 $0 $0) (load-immediate $1 &hello-str) ; load hello string ptr (string-length $2 $1) ; get length to write to stdout (syscall WRITE $0 $1 $2) ; do the write syscall diff --git a/test/loop.asm.lisp b/test/loop.asm.lisp index 66f4e61..6f13625 100644 --- a/test/loop.asm.lisp +++ b/test/loop.asm.lisp @@ -29,6 +29,7 @@ (halt)) (label pln (load-immediate $0 &terminal-namespace) + (syscall OPEN $0 $0 $0) (load-immediate $3 &new-line) (pop $1) (string-length $2 $1) diff --git a/test/malloc.asm.lisp b/test/malloc.asm.lisp index ee827be..5ace03f 100644 --- a/test/malloc.asm.lisp +++ b/test/malloc.asm.lisp @@ -12,6 +12,7 @@ (halt)) (label pln (load-immediate $0 &terminal-namespace) + (syscall OPEN $0 $0 $0) (load-immediate $3 &new-line) (pop $1) (string-length $2 $1) diff --git a/test/paint.asm.lisp b/test/paint.asm.lisp index 8e4450b..b06dffe 100644 --- a/test/paint.asm.lisp +++ b/test/paint.asm.lisp @@ -4,7 +4,7 @@ ; use load immediate because it is a pointer to a string, not a value (load-immediate $0 &screen-namespace) (load-immediate $11 0) - (syscall OPEN $0 $11) + (syscall OPEN $0 $0 $11) (load-immediate $16 1) ; device info call (load-immediate $17 16) ; sizeof screen device info @@ -22,6 +22,7 @@ (load-immediate $16 &mouse-namespace) (load-immediate $3 12) ; malloc sizeof mouse data (malloc $4 $3) + (syscall OPEN $16 $16 $4) (label draw-loop ; load mouse click data @@ -240,14 +241,17 @@ (jump-eq-nat &draw-loop $9 $11) - (mul-nat $15 $8 $20) ; $15 = y * width - (add-nat $15 $15 $7) ; $15 += x - (add-nat $15 $21 $15) ; $15 = base + pixel_offset - (load-immediate $1 4) ; need to add offset for fat pointer size - (add-nat $15 $15 $1) - (load $22 &SELECTED-COLOR) ; color - (store-8 $15 $22) ; draw color at screen [x,y] + (load-immediate $1 5) ; size of brush + + (push $21) ;base + (push $20) ;width + (push $22) ; color + (push $7) ;x + (push $8) ;y + (push $1) + (push $1) + (call &draw-box) (jump-eq-nat &draw-loop $10 $11)) diff --git a/test/simple.asm.lisp b/test/simple.asm.lisp index 4f89b36..55a17b3 100644 --- a/test/simple.asm.lisp +++ b/test/simple.asm.lisp @@ -9,6 +9,7 @@ (halt)) (label pln (load-immediate $0 &terminal-namespace) + (syscall OPEN $0 $0 $0) (load-immediate $3 &new-line) (pop $1) (string-length $2 $1) diff --git a/test/window.asm.lisp b/test/window.asm.lisp index ee6947b..39e3a78 100644 --- a/test/window.asm.lisp +++ b/test/window.asm.lisp @@ -2,7 +2,9 @@ (label main (load-immediate $0 &screen-namespace) (load-immediate $11 0) - (syscall OPEN $0 $11) + (syscall OPEN $0 $0 $11) + (load-immediate $32 &terminal-namespace) + (syscall OPEN $32 $32 $11) (load-immediate $16 1) ; device info call (load-immediate $17 16) ; sizeof screen device info @@ -20,8 +22,10 @@ (load-immediate $16 &mouse-namespace) (load-immediate $3 12) ; malloc sizeof mouse data (malloc $4 $3) + (syscall OPEN $16 $16 $4) (nat-to-string $5 $4) + (push $32) (push $5) (call &pln) @@ -59,9 +63,9 @@ (jump-eq-nat &draw-loop $10 $11)) (halt)) (label pln - (load-immediate $0 &terminal-namespace) (load-immediate $3 &new-line) (pop $1) + (pop $0) (string-length $2 $1) (syscall WRITE $0 $1 $2) (string-length $4 $3)