From 5f87ae3918d3bdffd2663487141d2f1d992bc4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20H=C3=B6ppner?= Date: Wed, 12 Aug 2026 23:27:16 +0200 Subject: [PATCH] ppuClear call from zig to c# simulator; not yet implemented in simulator; also breakpoints are not working in vs-code --- core/src/nova64_api.c | 166 +++++++++++++++++++++++++++- simulator/Program.cs | 10 +- simulator/sd/slot0/init.wasm | Bin 169 -> 242 bytes software/init.zig | 4 +- software/nova64.zig | 202 ++++++++++++++++++++++++++++++++++- 5 files changed, 374 insertions(+), 8 deletions(-) diff --git a/core/src/nova64_api.c b/core/src/nova64_api.c index e3643a0..cb5c313 100644 --- a/core/src/nova64_api.c +++ b/core/src/nova64_api.c @@ -1,10 +1,14 @@ #include "FreeRTOS.h" +#include "nova64_framebuffer.h" #include "nova64_internal.h" #include "projdefs.h" #include "task.h" #include "wasm_export.h" #include +/* ========================================================================== */ +/* Core Native Callbacks */ +/* ========================================================================== */ static void native_yield(wasm_exec_env_t exec_env, uint32_t timeout_ms) { if (timeout_ms == 0) { @@ -28,10 +32,170 @@ static void native_log(wasm_exec_env_t exec_env, const char *message) { } } +/* ========================================================================== */ +/* PPU Native Callbacks */ +/* ========================================================================== */ + +static void native_ppu_fill_rect(wasm_exec_env_t exec_env, int32_t x, int32_t y, + int32_t w, int32_t h, uint32_t color) { + (void)exec_env; + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->fill_rect) { + ppu->fill_rect(nova64_framebuffer.back_buffer, NOVA64_DISPLAY_WIDTH, x, y, + w, h, (pixel_t)color); + } +} + +static void native_ppu_clear(wasm_exec_env_t exec_env, uint32_t color) { + (void)exec_env; + nova64_framebuffer_clear((pixel_t)color); +} + +static void native_ppu_blit(wasm_exec_env_t exec_env, uint32_t src_wasm_ptr, + uint32_t src_stride, int32_t src_x, int32_t src_y, + int32_t dst_x, int32_t dst_y, int32_t w, + int32_t h) { + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + const pixel_t *src_native = (const pixel_t *)wasm_runtime_addr_app_to_native( + module_inst, src_wasm_ptr); + + if (!src_native) + return; + + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->blit) { + ppu->blit(src_native, src_stride, nova64_framebuffer.back_buffer, + NOVA64_DISPLAY_WIDTH, src_x, src_y, dst_x, dst_y, w, h); + } +} + +static void native_ppu_blit_colorkey(wasm_exec_env_t exec_env, + uint32_t src_wasm_ptr, uint32_t src_stride, + int32_t src_x, int32_t src_y, + int32_t dst_x, int32_t dst_y, int32_t w, + int32_t h, uint32_t key_color) { + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + const pixel_t *src_native = (const pixel_t *)wasm_runtime_addr_app_to_native( + module_inst, src_wasm_ptr); + + if (!src_native) + return; + + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->blit_colorkey) { + ppu->blit_colorkey(src_native, src_stride, nova64_framebuffer.back_buffer, + NOVA64_DISPLAY_WIDTH, src_x, src_y, dst_x, dst_y, w, h, + (pixel_t)key_color); + } +} + +static void native_ppu_blend(wasm_exec_env_t exec_env, uint32_t src_wasm_ptr, + uint32_t src_stride, int32_t src_x, int32_t src_y, + int32_t dst_x, int32_t dst_y, int32_t w, int32_t h, + uint32_t global_alpha) { + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + const pixel_t *src_native = (const pixel_t *)wasm_runtime_addr_app_to_native( + module_inst, src_wasm_ptr); + + if (!src_native) + return; + + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->blend) { + ppu->blend(src_native, src_stride, nova64_framebuffer.back_buffer, + NOVA64_DISPLAY_WIDTH, src_x, src_y, dst_x, dst_y, w, h, + (uint8_t)global_alpha); + } +} + +static void native_ppu_blit_transform(wasm_exec_env_t exec_env, + uint32_t src_wasm_ptr, + uint32_t src_stride, int32_t src_x, + int32_t src_y, int32_t dst_x, + int32_t dst_y, int32_t w, int32_t h, + uint32_t transform) { + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + const pixel_t *src_native = (const pixel_t *)wasm_runtime_addr_app_to_native( + module_inst, src_wasm_ptr); + + if (!src_native) + return; + + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->blit_transform) { + ppu->blit_transform(src_native, src_stride, nova64_framebuffer.back_buffer, + NOVA64_DISPLAY_WIDTH, src_x, src_y, dst_x, dst_y, w, h, + (nova64_transform_t)transform); + } +} + +static void native_ppu_blit_scale(wasm_exec_env_t exec_env, + uint32_t src_wasm_ptr, uint32_t src_stride, + int32_t src_w, int32_t src_h, int32_t dst_x, + int32_t dst_y, int32_t dst_w, int32_t dst_h) { + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); + const pixel_t *src_native = (const pixel_t *)wasm_runtime_addr_app_to_native( + module_inst, src_wasm_ptr); + + if (!src_native) + return; + + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->blit_scale) { + ppu->blit_scale(src_native, src_stride, src_w, src_h, + nova64_framebuffer.back_buffer, NOVA64_DISPLAY_WIDTH, dst_x, + dst_y, dst_w, dst_h); + } +} + +static void native_ppu_wait_idle(wasm_exec_env_t exec_env) { + (void)exec_env; + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->wait_idle) { + ppu->wait_idle(); + } +} + +static uint32_t native_ppu_is_busy(wasm_exec_env_t exec_env) { + (void)exec_env; + const nova64_ppu_interface_t *ppu = nova64_get_ppu_interface(); + if (ppu && ppu->is_busy) { + return ppu->is_busy() ? 1 : 0; + } + return 0; +} + +static void native_framebuffer_swap(wasm_exec_env_t exec_env) { + (void)exec_env; + nova64_framebuffer_swap(); +} + +/* ========================================================================== */ +/* WAMR Native Symbols Table */ +/* ========================================================================== */ + static NativeSymbol native_symbols[] = { {"nova64_yield", (void *)native_yield, "(i)", NULL}, {"nova64_log", (void *)native_log, "($)", NULL}, - // { "flush_framebuffer", (void*)native_flush_framebuffer, "()", NULL } + + // Framebuffer Controls + {"nova64_ppu_clear", (void *)native_ppu_clear, "(i)", NULL}, + {"nova64_framebuffer_swap", (void *)native_framebuffer_swap, "()", NULL}, + + // PPU Drawing Primitives + {"nova64_ppu_fill_rect", (void *)native_ppu_fill_rect, "(iiiii)", NULL}, + {"nova64_ppu_blit", (void *)native_ppu_blit, "(iiiiiiiii)", NULL}, + {"nova64_ppu_blit_colorkey", (void *)native_ppu_blit_colorkey, + "(iiiiiiiiii)", NULL}, + {"nova64_ppu_blend", (void *)native_ppu_blend, "(iiiiiiiiii)", NULL}, + {"nova64_ppu_blit_transform", (void *)native_ppu_blit_transform, + "(iiiiiiiiii)", NULL}, + {"nova64_ppu_blit_scale", (void *)native_ppu_blit_scale, "(iiiiiiiii)", + NULL}, + + // Hardware Sync + {"nova64_ppu_wait_idle", (void *)native_ppu_wait_idle, "()", NULL}, + {"nova64_ppu_is_busy", (void *)native_ppu_is_busy, "()i", NULL}, }; void nova64_register_imports(void) { diff --git a/simulator/Program.cs b/simulator/Program.cs index 716af5d..c810880 100644 --- a/simulator/Program.cs +++ b/simulator/Program.cs @@ -13,7 +13,6 @@ internal static class Program return SdRoot / $"slot{slotIdx}" / normalizedPath; } - private static readonly Nova64.DisplayFlushDelegate DisplayFlush = (buffer, width, height) => { }; private static readonly Nova64.AudioOutputDelegate AudioOutput = (samples, count) => { }; private static readonly Nova64.SdReadFileDelegate SdReadFile = (slotIdx, filePath, destinationBuffer, destinationLength) => { @@ -47,6 +46,7 @@ internal static class Program return -1; } }; + private static readonly Nova64.SdGetFileSizeDelegate SdGetFileSize = (slotIdx, filePath) => { var path = GetSlotFilePath(slotIdx, filePath); @@ -69,6 +69,7 @@ internal static class Program return -1; } }; + private static readonly Nova64.CartridgeStatusDelegate CartridgeStatus = (slotIdx, isInserted) => { }; private static readonly Nova64.LogMessageDelegate LogMessage = (message) => { @@ -76,6 +77,11 @@ internal static class Program Console.Out.Flush(); }; + private static readonly Nova64.PpuFillRectDelegate FillRect = (dst, dstStride, x, y, w, h, color) => + { + + }; + private static GCHandle? _ioHandle; private static GCHandle? _ppuHandle; private static Thread? _coreThread; @@ -129,7 +135,7 @@ internal static class Program var ppuInterface = new Nova64.Nova64PpuInterface { - + fill_rect = Marshal.GetFunctionPointerForDelegate(FillRect), }; _ppuHandle = GCHandle.Alloc(ppuInterface, GCHandleType.Pinned); diff --git a/simulator/sd/slot0/init.wasm b/simulator/sd/slot0/init.wasm index f70185274749ffd0ce74997ce7be6e3a30fe0aa7..fca6774f7745c580e8300fccda4409ffa4ada9dd 100644 GIT binary patch delta 150 zcmZ3<_=z!vA+b1@k%57Mk%K9Lv7RA;fq^NFg)J|?EYZw_3qr-`0Vg&`I z@yR)