"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() { // Configure instance fields this.buffers = {}; // 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, { env: { emscripten_notify_memory_growth: ()=>this.onmemory() }}); this.wasm.instance.exports.Init(); // Configure instance fields this.core = this.wasm.instance.exports; 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); msg.buffer = this.core.memory.buffer.slice( buffer.pointer, buffer.pointer + msg.size); this.free(buffer); 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++) buffer.data[x] = rom[x]; msg.success = !!this.core.SetROM(msg.sim, buffer.pointer, rom.length); delete msg.rom; postMessage(msg); } ///////////////////////////// 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 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();