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