pvbemu/app/Emulator.js

95 lines
2.7 KiB
JavaScript
Raw Normal View History

2021-08-30 02:14:06 +00:00
"use strict";
// Worker that manages a WebAssembly instance of the C core library
(globalThis.Emulator = class Emulator {
// Static initializer
static initializer() {
new Emulator();
}
// Object constructor
constructor() {
2021-08-30 13:58:40 +00:00
// Configure instance fields
this.buffers = {};
2021-08-30 02:14:06 +00:00
// Configure message port
onmessage = e=>this.onmessage(e.data);
}
///////////////////////////// Message Methods /////////////////////////////
// Message received
onmessage(msg) {
switch (msg.command) {
case "Init" : this.init (msg); break;
case "ReadBuffer": this.readBuffer(msg); break;
case "SetROM" : this.setROM (msg); break;
}
}
// Initialize the WebAssembly core module
async init(msg) {
// Load and instantiate the WebAssembly module
this.wasm = await WebAssembly.instantiate(msg.wasm,
2021-08-30 13:58:40 +00:00
{ env: { emscripten_notify_memory_growth: ()=>this.onmemory() }});
2021-08-30 02:14:06 +00:00
this.wasm.instance.exports.Init();
// Configure instance fields
2021-08-30 13:58:40 +00:00
this.core = this.wasm.instance.exports;
2021-08-30 02:14:06 +00:00
postMessage({ command: "Init" });
}
// Read multiple data units from the bus
readBuffer(msg) {
let buffer = this.malloc(Uint8Array, msg.size);
this.core.ReadBuffer(msg.sim, buffer.pointer, msg.address, msg.size);
2021-08-30 13:58:40 +00:00
msg.buffer = this.core.memory.buffer.slice(
2021-08-30 02:14:06 +00:00
buffer.pointer, buffer.pointer + msg.size);
2021-08-30 13:58:40 +00:00
this.free(buffer);
2021-08-30 02:14:06 +00:00
postMessage(msg, msg.buffer);
}
// Supply a ROM buffer
setROM(msg) {
let rom = new Uint8Array(msg.rom);
let buffer = this.malloc(Uint8Array, rom.length);
for (let x = 0; x < rom.length; x++)
2021-08-30 13:58:40 +00:00
buffer.data[x] = rom[x];
2021-08-30 02:14:06 +00:00
msg.success = !!this.core.SetROM(msg.sim, buffer.pointer, rom.length);
delete msg.rom;
postMessage(msg);
}
2021-08-30 13:58:40 +00:00
///////////////////////////// Private Methods /////////////////////////////
// Delete a previously-allocated memory buffer
free(buffer) {
this.core.Free(buffer.pointer);
delete this.buffers[buffer.pointer];
}
2021-08-30 02:14:06 +00:00
// Allocate a typed array in WebAssembly core memory
malloc(type, size) {
let pointer = this.core.Malloc(size);
2021-08-30 13:58:40 +00:00
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);
}
2021-08-30 02:14:06 +00:00
}
}).initializer();