Corrective tweaks
This commit is contained in:
parent
b2adf1f9dc
commit
5a02e7e52d
|
@ -11,6 +11,9 @@
|
||||||
// Object constructor
|
// Object constructor
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
|
// Configure instance fields
|
||||||
|
this.buffers = {};
|
||||||
|
|
||||||
// Configure message port
|
// Configure message port
|
||||||
onmessage = e=>this.onmessage(e.data);
|
onmessage = e=>this.onmessage(e.data);
|
||||||
}
|
}
|
||||||
|
@ -33,12 +36,11 @@
|
||||||
|
|
||||||
// Load and instantiate the WebAssembly module
|
// Load and instantiate the WebAssembly module
|
||||||
this.wasm = await WebAssembly.instantiate(msg.wasm,
|
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();
|
this.wasm.instance.exports.Init();
|
||||||
|
|
||||||
// Configure instance fields
|
// Configure instance fields
|
||||||
this.core = this.wasm.instance.exports;
|
this.core = this.wasm.instance.exports;
|
||||||
this.memory = this.core.memory.buffer;
|
|
||||||
|
|
||||||
postMessage({ command: "Init" });
|
postMessage({ command: "Init" });
|
||||||
}
|
}
|
||||||
|
@ -47,9 +49,9 @@
|
||||||
readBuffer(msg) {
|
readBuffer(msg) {
|
||||||
let buffer = this.malloc(Uint8Array, msg.size);
|
let buffer = this.malloc(Uint8Array, msg.size);
|
||||||
this.core.ReadBuffer(msg.sim, buffer.pointer, msg.address, 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);
|
buffer.pointer, buffer.pointer + msg.size);
|
||||||
this.core.Free(buffer.pointer);
|
this.free(buffer);
|
||||||
postMessage(msg, msg.buffer);
|
postMessage(msg, msg.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@
|
||||||
let rom = new Uint8Array(msg.rom);
|
let rom = new Uint8Array(msg.rom);
|
||||||
let buffer = this.malloc(Uint8Array, rom.length);
|
let buffer = this.malloc(Uint8Array, rom.length);
|
||||||
for (let x = 0; x < rom.length; x++)
|
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);
|
msg.success = !!this.core.SetROM(msg.sim, buffer.pointer, rom.length);
|
||||||
delete msg.rom;
|
delete msg.rom;
|
||||||
postMessage(msg);
|
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
|
// Allocate a typed array in WebAssembly core memory
|
||||||
malloc(type, size) {
|
malloc(type, size) {
|
||||||
let pointer = this.core.Malloc(size);
|
let pointer = this.core.Malloc(size);
|
||||||
let ret = new type(this.memory, pointer, size);
|
let data = new type(this.core.memory.buffer, pointer, size);
|
||||||
ret.pointer = pointer;
|
return this.buffers[pointer] = { data: data, pointer: pointer };
|
||||||
return ret;
|
}
|
||||||
|
|
||||||
|
// 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();
|
}).initializer();
|
||||||
|
|
|
@ -96,8 +96,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window {
|
||||||
|
|
||||||
// Determine the height in pixels of one row of output
|
// Determine the height in pixels of one row of output
|
||||||
lineHeight() {
|
lineHeight() {
|
||||||
let ret = this.rows[0].address.getBounds().height;
|
return Math.max(1, this.rows[0].address.getBounds().height);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the number of rows of output
|
// Determine the number of rows of output
|
||||||
|
@ -106,7 +105,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window {
|
||||||
lineHeight = lineHeight || this.lineHeight();
|
lineHeight = lineHeight || this.lineHeight();
|
||||||
let ret = clientHeight / lineHeight;
|
let ret = clientHeight / lineHeight;
|
||||||
ret = fullyVisible ? Math.floor(ret) : Math.ceil(ret);
|
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
|
// Key down event handler
|
||||||
|
@ -115,7 +114,7 @@ globalThis.MemoryWindow = class MemoryWindow extends Toolkit.Window {
|
||||||
// Control is pressed
|
// Control is pressed
|
||||||
if (e.ctrlKey) switch (e.key) {
|
if (e.ctrlKey) switch (e.key) {
|
||||||
case "g": case "G":
|
case "g": case "G":
|
||||||
let addr = prompt(this.application.translate("{app.romLoaded}"));
|
let addr = prompt(this.application.translate("{app.goto_}"));
|
||||||
if (addr === null)
|
if (addr === null)
|
||||||
break;
|
break;
|
||||||
this.seek(
|
this.seek(
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/**************************** Component Functions ****************************/
|
/**************************** 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) {
|
static int32_t busReadMemory(uint8_t *mem, int type) {
|
||||||
|
|
||||||
/* Generic implementation */
|
/* 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);
|
address &= ~((uint32_t) TYPE_SIZES[type] - 1);
|
||||||
|
|
||||||
/* Process by address range */
|
/* Process by address range */
|
||||||
switch (address >> 24 ^ 7) {
|
switch (address >> 24 & 7) {
|
||||||
case 0 : return 0; /* VIP */
|
case 0 : return 0; /* VIP */
|
||||||
case 1 : debug = debug; return 0; /* VSU */
|
case 1 : debug = debug; return 0; /* VSU */
|
||||||
case 2 : return 0; /* Miscellaneous hardware */
|
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(
|
static void busWrite(
|
||||||
VB *emu, uint32_t address, int type, uint32_t value, int debug) {
|
VB *emu, uint32_t address, int type, uint32_t value, int debug) {
|
||||||
|
|
||||||
|
|
23
core/vb.c
23
core/vb.c
|
@ -38,6 +38,20 @@ int32_t vbGetProgramRegister(VB *emu, int id) {
|
||||||
return id < 1 || id > 31 ? 0 : emu->cpu.program[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 */
|
/* Retrieve the value of a system register */
|
||||||
uint32_t vbGetSystemRegister(VB *emu, int id) {
|
uint32_t vbGetSystemRegister(VB *emu, int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
@ -76,8 +90,15 @@ uint32_t vbGetSystemRegister(VB *emu, int id) {
|
||||||
|
|
||||||
/* Prepare a simulation state instance for use */
|
/* Prepare a simulation state instance for use */
|
||||||
void vbInit(VB *emu) {
|
void vbInit(VB *emu) {
|
||||||
|
|
||||||
|
/* Cartridge */
|
||||||
emu->cart.rom = NULL;
|
emu->cart.rom = NULL;
|
||||||
|
emu->cart.romSize = 0;
|
||||||
emu->cart.sram = NULL;
|
emu->cart.sram = NULL;
|
||||||
|
emu->cart.sramSize = 0;
|
||||||
|
|
||||||
|
/* All others */
|
||||||
|
vbReset(emu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a data unit from the bus */
|
/* Read a data unit from the bus */
|
||||||
|
@ -96,6 +117,8 @@ void vbReset(VB *emu) {
|
||||||
vbSetSystemRegister(emu, VB_PSW, 0x00008000);
|
vbSetSystemRegister(emu, VB_PSW, 0x00008000);
|
||||||
|
|
||||||
/* Initialize extra CPU registers (the hardware does not do this) */
|
/* 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.adtre = 0;
|
||||||
emu->cpu.eipc = 0;
|
emu->cpu.eipc = 0;
|
||||||
emu->cpu.eipsw = 0;
|
emu->cpu.eipsw = 0;
|
||||||
|
|
|
@ -114,6 +114,8 @@ struct VB {
|
||||||
|
|
||||||
VBAPI uint32_t vbGetProgramCounter (VB *emu);
|
VBAPI uint32_t vbGetProgramCounter (VB *emu);
|
||||||
VBAPI int32_t vbGetProgramRegister (VB *emu, int id);
|
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 uint32_t vbGetSystemRegister (VB *emu, int id);
|
||||||
VBAPI void vbInit (VB *emu);
|
VBAPI void vbInit (VB *emu);
|
||||||
VBAPI int32_t vbRead (VB *emu, uint32_t address, int type, int debug);
|
VBAPI int32_t vbRead (VB *emu, uint32_t address, int type, int debug);
|
||||||
|
|
2
makefile
2
makefile
|
@ -1,7 +1,7 @@
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help:
|
help:
|
||||||
@echo
|
@echo
|
||||||
@echo "Virtual Boy Emulator - August 29, 2021"
|
@echo "Virtual Boy Emulator - August 30, 2021"
|
||||||
@echo
|
@echo
|
||||||
@echo "Target build environment is any Debian with the following packages:"
|
@echo "Target build environment is any Debian with the following packages:"
|
||||||
@echo " emscripten"
|
@echo " emscripten"
|
||||||
|
|
|
@ -78,11 +78,13 @@ EMSCRIPTEN_KEEPALIVE int32_t SetProgramRegister(int sim,int id,int32_t value) {
|
||||||
|
|
||||||
// Supply a ROM buffer
|
// Supply a ROM buffer
|
||||||
EMSCRIPTEN_KEEPALIVE int SetROM(int sim, void *rom, uint32_t size) {
|
EMSCRIPTEN_KEEPALIVE int SetROM(int sim, void *rom, uint32_t size) {
|
||||||
|
free(vbGetROM(&sims[sim], NULL));
|
||||||
return vbSetROM(&sims[sim], rom, size);
|
return vbSetROM(&sims[sim], rom, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supply an SRAM buffer
|
// Supply an SRAM buffer
|
||||||
EMSCRIPTEN_KEEPALIVE int SetSRAM(int sim, void *sram, uint32_t size) {
|
EMSCRIPTEN_KEEPALIVE int SetSRAM(int sim, void *sram, uint32_t size) {
|
||||||
|
free(vbGetSRAM(&sims[sim], NULL));
|
||||||
return vbSetSRAM(&sims[sim], sram, size);
|
return vbSetSRAM(&sims[sim], sram, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue