diff --git a/app/Emulator.js b/app/Emulator.js index b087062..4c2ebae 100644 --- a/app/Emulator.js +++ b/app/Emulator.js @@ -11,6 +11,9 @@ // Object constructor constructor() { + // Configure instance fields + this.buffers = {}; + // Configure message port onmessage = e=>this.onmessage(e.data); } @@ -33,12 +36,11 @@ // Load and instantiate the WebAssembly module this.wasm = await WebAssembly.instantiate(msg.wasm, - { env: { emscripten_notify_memory_growth: function(){} }}); + { env: { emscripten_notify_memory_growth: ()=>this.onmemory() }}); this.wasm.instance.exports.Init(); // Configure instance fields - this.core = this.wasm.instance.exports; - this.memory = this.core.memory.buffer; + this.core = this.wasm.instance.exports; postMessage({ command: "Init" }); } @@ -47,9 +49,9 @@ readBuffer(msg) { let buffer = this.malloc(Uint8Array, msg.size); this.core.ReadBuffer(msg.sim, buffer.pointer, msg.address, msg.size); - msg.buffer = buffer.buffer.slice( + msg.buffer = this.core.memory.buffer.slice( buffer.pointer, buffer.pointer + msg.size); - this.core.Free(buffer.pointer); + this.free(buffer); postMessage(msg, msg.buffer); } @@ -58,7 +60,7 @@ let rom = new Uint8Array(msg.rom); let buffer = this.malloc(Uint8Array, rom.length); for (let x = 0; x < rom.length; x++) - buffer[x] = rom[x]; + buffer.data[x] = rom[x]; msg.success = !!this.core.SetROM(msg.sim, buffer.pointer, rom.length); delete msg.rom; postMessage(msg); @@ -66,14 +68,27 @@ - ///////////////////////////// Utility Methods ///////////////////////////// + ///////////////////////////// Private Methods ///////////////////////////// + + // Delete a previously-allocated memory buffer + free(buffer) { + this.core.Free(buffer.pointer); + delete this.buffers[buffer.pointer]; + } // Allocate a typed array in WebAssembly core memory malloc(type, size) { let pointer = this.core.Malloc(size); - let ret = new type(this.memory, pointer, size); - ret.pointer = pointer; - return ret; + let data = new type(this.core.memory.buffer, pointer, size); + return this.buffers[pointer] = { data: data, pointer: pointer }; + } + + // WebAssembly memory has grown + onmemory() { + for (let buffer of Object.values(this.buffers)) { + buffer.data = new buffer.data.constructor( + this.core.memory.buffer, buffer.pointer); + } } }).initializer(); diff --git a/app/windows/MemoryWindow.js b/app/windows/MemoryWindow.js index b8fdf89..0bfe4a1 100644 --- a/app/windows/MemoryWindow.js +++ b/app/windows/MemoryWindow.js @@ -96,8 +96,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window { // Determine the height in pixels of one row of output lineHeight() { - let ret = this.rows[0].address.getBounds().height; - return ret; + return Math.max(1, this.rows[0].address.getBounds().height); } // Determine the number of rows of output @@ -106,7 +105,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window { lineHeight = lineHeight || this.lineHeight(); let ret = clientHeight / lineHeight; ret = fullyVisible ? Math.floor(ret) : Math.ceil(ret); - return Math.max(1, Math.min(ret, Math.floor(clientHeight / 8))); + return Math.max(1, ret); } // Key down event handler @@ -115,7 +114,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window { // Control is pressed if (e.ctrlKey) switch (e.key) { case "g": case "G": - let addr = prompt(this.application.translate("{app.romLoaded}")); + let addr = prompt(this.application.translate("{app.goto_}")); if (addr === null) break; this.seek( diff --git a/core/bus.c b/core/bus.c index 7188dc9..ce253e5 100644 --- a/core/bus.c +++ b/core/bus.c @@ -5,7 +5,7 @@ /**************************** Component Functions ****************************/ -/* Read a value from a memory buffer */ +/* Read a data unit from a memory buffer */ static int32_t busReadMemory(uint8_t *mem, int type) { /* Generic implementation */ @@ -39,7 +39,7 @@ static int32_t busRead(VB *emu, uint32_t address, int type, int debug) { address &= ~((uint32_t) TYPE_SIZES[type] - 1); /* Process by address range */ - switch (address >> 24 ^ 7) { + switch (address >> 24 & 7) { case 0 : return 0; /* VIP */ case 1 : debug = debug; return 0; /* VSU */ case 2 : return 0; /* Miscellaneous hardware */ @@ -84,7 +84,7 @@ static void busWriteMemory(uint8_t *mem, int type, int32_t value) { } -/* Read a value from the bus */ +/* Write a data unit to the bus */ static void busWrite( VB *emu, uint32_t address, int type, uint32_t value, int debug) { diff --git a/core/vb.c b/core/vb.c index fd6bb82..a72a835 100644 --- a/core/vb.c +++ b/core/vb.c @@ -38,6 +38,20 @@ int32_t vbGetProgramRegister(VB *emu, int id) { return id < 1 || id > 31 ? 0 : emu->cpu.program[id]; } +/* Retrieve the ROM buffer */ +void* vbGetROM(VB *emu, uint32_t *size) { + if (size != NULL) + *size = emu->cart.romSize; + return emu->cart.rom; +} + +/* Retrieve the SRAM buffer */ +void* vbGetSRAM(VB *emu, uint32_t *size) { + if (size != NULL) + *size = emu->cart.sramSize; + return emu->cart.sram; +} + /* Retrieve the value of a system register */ uint32_t vbGetSystemRegister(VB *emu, int id) { switch (id) { @@ -76,8 +90,15 @@ uint32_t vbGetSystemRegister(VB *emu, int id) { /* Prepare a simulation state instance for use */ void vbInit(VB *emu) { - emu->cart.rom = NULL; - emu->cart.sram = NULL; + + /* Cartridge */ + emu->cart.rom = NULL; + emu->cart.romSize = 0; + emu->cart.sram = NULL; + emu->cart.sramSize = 0; + + /* All others */ + vbReset(emu); } /* Read a data unit from the bus */ @@ -96,6 +117,8 @@ void vbReset(VB *emu) { vbSetSystemRegister(emu, VB_PSW, 0x00008000); /* Initialize extra CPU registers (the hardware does not do this) */ + for (x = 0; x < 32; x++) + emu->cpu.program[x] = 0; emu->cpu.adtre = 0; emu->cpu.eipc = 0; emu->cpu.eipsw = 0; diff --git a/core/vb.h b/core/vb.h index 7858ecf..e6c9921 100644 --- a/core/vb.h +++ b/core/vb.h @@ -114,6 +114,8 @@ struct VB { VBAPI uint32_t vbGetProgramCounter (VB *emu); VBAPI int32_t vbGetProgramRegister (VB *emu, int id); +VBAPI void* vbGetROM (VB *emu, uint32_t *size); +VBAPI void* vbGetSRAM (VB *emu, uint32_t *size); VBAPI uint32_t vbGetSystemRegister (VB *emu, int id); VBAPI void vbInit (VB *emu); VBAPI int32_t vbRead (VB *emu, uint32_t address, int type, int debug); diff --git a/makefile b/makefile index 9dd47a8..cc95c2a 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ .PHONY: help help: @echo - @echo "Virtual Boy Emulator - August 29, 2021" + @echo "Virtual Boy Emulator - August 30, 2021" @echo @echo "Target build environment is any Debian with the following packages:" @echo " emscripten" diff --git a/wasm/wasm.c b/wasm/wasm.c index a92e833..d57ed8d 100644 --- a/wasm/wasm.c +++ b/wasm/wasm.c @@ -78,11 +78,13 @@ EMSCRIPTEN_KEEPALIVE int32_t SetProgramRegister(int sim,int id,int32_t value) { // Supply a ROM buffer EMSCRIPTEN_KEEPALIVE int SetROM(int sim, void *rom, uint32_t size) { + free(vbGetROM(&sims[sim], NULL)); return vbSetROM(&sims[sim], rom, size); } // Supply an SRAM buffer EMSCRIPTEN_KEEPALIVE int SetSRAM(int sim, void *sram, uint32_t size) { + free(vbGetSRAM(&sims[sim], NULL)); return vbSetSRAM(&sims[sim], sram, size); }