Tachibana

Dokumentation › Browser-Build

WebAssembly-(Browser-)Build

Phosphoric kompiliert über Emscripten zu WebAssembly: Der vollständige Emulator (6502-CPU, Speicher, VIA, PSG, ULA, Tastatur, Kassette, Diskette) läuft in einem Tab, gerendert auf einem <canvas>, Audio über Web Audio, Tastatur über das DOM — unter Wiederverwendung des bestehenden SDL2-Pfads (Emscriptens SDL-Port).

Voraussetzungen

Ein aktives Emscripten SDK (emcc im PATH):

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

Bauen und ausführen

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

make wasm erzeugt in web/: phosphoric.html (Seite + Canvas), phosphoric.js, phosphoric.wasm und phosphoric.data (die roms/-ROMs, vorgeladen ins virtuelle Dateisystem). Die Seite bootet den Atmos (-r /roms/basic11b.rom); klicke auf den Bildschirm für Tastaturfokus und Audio.

Bereitstellung: benötigte Assets + CSP

Die Seite lädt ihre Logik (die Module-Definition, UI, Tastatur, Drag-and-drop) aus web/shell.js — einer externen Datei, die neben phosphoric.html/.js/.wasm/.data bereitgestellt werden muss. shell.js steht unter Versionskontrolle (Quelle) und wird von phosphoric.html über <script src="shell.js"> referenziert.

Diese Auslagerung macht das Bundle mit einer strengen Content-Security-Policy kompatibel. Ein Host, der die Seite unter script-src 'self' 'wasm-unsafe-eval' ausliefert, würde ein Inline-<script> blockieren (script-src-elem) → Module nie definiert → Module.canvas undefined → fataler Fehler beim WebGL-createContext. Durch Auslagern des gesamten JS (und Ersetzen des Inline-oncontextmenu-Attributs des Canvas durch einen DOM-Listener) hat phosphoric.html kein einziges Inline-Skript/-Handler: Es läuft unter einer strengen CSP genauso wie unter einer permissiven (GitHub Pages).

Minimal erforderliche CSP

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

⚠️ 'wasm-unsafe-eval' nicht entfernen: Unter einem nackten script-src 'self' wird die WebAssembly-Kompilierung verweigert und der Emulator startet nicht. Nach dem Auslagerungs-Fix sind weder 'unsafe-inline' noch Hash/Nonce nötig — nur das WASM-Token.

Eine script-src-elem-Blockade mit Quelle sandbox eval code (nicht phosphoric.html) stammt von einer Browser-Erweiterung, nicht von Phosphoric: Die Seite injiziert kein Inline-Skript und kein eval. Keine Auswirkung auf den Emulator.

Oberfläche (Webseite)

Die Seite zeigt eine vertikale Icon-Leiste links (JOric-Stil) und die ORIC-Tastatur als Overlay:

CTRL+T und andere Chords: Der Browser reserviert manche Kürzel (CTRL+T = neuer Tab) auf OS-Ebene. Verwende die CTRL-Taste der virtuellen Tastatur: Sie schreibt die ORIC-Matrix über einen direkten C-Aufruf, sodass der Browser sie nicht abfängt.

Liefere Dateien über HTTP aus (nicht file://): Der Browser weigert sich, eine .wasm vom lokalen Dateisystem zu laden.

Technische Details

Treue — verifiziert

Die WASM-Ausgabe ist bei identischen Eingaben byte-identisch zum nativen Build: Ein Headless-Atmos-Boot, zu WASM kompiliert und unter Node.js ausgeführt, erzeugt exakt denselben PPM-Screenshot wie das native Binary (getestet bei 2 Mio. und 5 Mio. Takten). Der taktgenaue Determinismus des Kerns bleibt über die WebAssembly-Kompilierung erhalten.

Das Browser-Rendering wurde ebenfalls validiert: Die in Headless-Chromium geladene Seite zeigt den korrekten Atmos-Bootscreen, und die Tastatureingabe funktioniert (Eingabe von PRINT 6*7 + RETURN zeigt 42) — ROM-Boot → Tastaturinjektion → BASIC-Ausführung → Rendering, vollständig im Browser.

Reproduziert aus docs/wasm.md (maßgebliche, aktuelle Version auf GitHub).

← Dokumentation · Den Emulator öffnen →