Tachibana

Documentatie › Browserbuild

WebAssembly-build (browser)

Phosphoric compileert naar WebAssembly via Emscripten: de volledige emulator (6502-CPU, geheugen, VIA, PSG, ULA, toetsenbord, cassette, schijf) draait in een tabblad, gerenderd op een <canvas>, audio via Web Audio, toetsenbord via de DOM — met hergebruik van het bestaande SDL2-pad (Emscriptens SDL-port).

Vereisten

Een actieve Emscripten SDK (emcc in het PATH):

git clone https://github.com/emscripten-core/emsdk
cd emsdk && ./emsdk install latest && ./emsdk activate latest
source ./emsdk_env.sh

Bouwen en uitvoeren

make wasm
(cd web && python3 -m http.server 8000)
# open http://localhost:8000/phosphoric.html

make wasm produceert in web/: phosphoric.html (pagina + canvas), phosphoric.js, phosphoric.wasm en phosphoric.data (de roms/-ROM's voorgeladen in het virtuele bestandssysteem). De pagina start de Atmos (-r /roms/basic11b.rom); klik op het scherm voor toetsenbordfocus en audio.

Implementatie: vereiste assets + CSP

De pagina laadt haar logica (de Module-definitie, UI, toetsenbord, drag-and-drop) uit web/shell.js — een extern bestand dat naast phosphoric.html/.js/.wasm/.data moet worden geïmplementeerd. shell.js staat onder versiebeheer (bron) en wordt door phosphoric.html gerefereerd via <script src="shell.js">.

Deze externalisatie maakt de bundel compatibel met een strikte Content-Security-Policy. Een host die de pagina serveert onder script-src 'self' 'wasm-unsafe-eval' zou een inline <script> blokkeren (script-src-elem) → Module nooit gedefinieerd → Module.canvas undefined → fatale fout bij de WebGL-createContext. Door alle JS te externaliseren (en het inline oncontextmenu-attribuut van het canvas te vervangen door een DOM-listener), heeft phosphoric.html geen enkel inline-script/handler: het draait onder een strikte CSP net als onder een permissieve (GitHub Pages).

Minimaal vereiste CSP

Content-Security-Policy: script-src 'self' 'wasm-unsafe-eval'

⚠️ Verwijder 'wasm-unsafe-eval' niet: onder een kaal script-src 'self' wordt WebAssembly-compilatie geweigerd en start de emulator niet. Na de externalisatiefix zijn noch 'unsafe-inline' noch hash/nonce nodig — alleen het WASM-token.

Een script-src-elem-blokkade met bron sandbox eval code (niet phosphoric.html) komt van een browserextensie, niet van Phosphoric: de pagina injecteert geen inline-script of eval. Geen effect op de emulator.

Interface (webpagina)

De pagina toont een verticale iconenrail links (JOric-stijl) en het ORIC-toetsenbord als overlay:

CTRL+T en andere chords: de browser reserveert sommige sneltoetsen (CTRL+T = nieuw tabblad) op OS-niveau. Gebruik de CTRL-toets van het virtuele toetsenbord: die schrijft de ORIC-matrix via een directe C-aanroep, zodat de browser hem niet onderschept.

Serveer bestanden via HTTP (niet file://): de browser weigert een .wasm vanaf het lokale bestandssysteem te laden.

Technische details

Getrouwheid — geverifieerd

De WASM-uitvoer is byte-identiek aan de native build voor identieke invoer: een headless Atmos-boot gecompileerd naar WASM en uitgevoerd onder Node.js produceert exact dezelfde PPM-schermafbeelding als het native binary (getest bij 2M en 5M cycli). Het cyclusnauwkeurige determinisme van de kern blijft behouden door de WebAssembly-compilatie.

Browserrendering is ook gevalideerd: de pagina geladen in headless Chromium toont het juiste Atmos-bootscherm, en toetsenbordinvoer werkt (typen van PRINT 6*7 + RETURN toont 42) — ROM-boot → toetsenbordinjectie → BASIC-uitvoering → rendering, geheel in de browser.

Gereproduceerd uit docs/wasm.md (gezaghebbende, actuele versie op GitHub).

← Documentatie · De emulator openen →