Tachibana

ドキュメント › ブラウザビルド

WebAssembly(ブラウザ)ビルド

Phosphoric は Emscripten 経由で WebAssembly にコンパイルされます:完全なエミュレータ(6502 CPU、メモリ、VIA、PSG、ULA、キーボード、カセット、ディスク)がタブ内で動作し、<canvas> に描画、音声は Web Audio、キーボードは DOM 経由 — 既存の SDL2 パス(Emscripten の SDL ポート)を再利用します。

前提

有効な Emscripten SDKemccPATH に):

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

ビルドと実行

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

make wasmweb/ に生成します:phosphoric.html(ページ + canvas)、phosphoric.jsphosphoric.wasmphosphoric.dataroms/ の ROM を仮想ファイルシステムにプリロード)。ページは Atmos を起動します(-r /roms/basic11b.rom);キーボードフォーカスと音声のため画面をクリックしてください。

配置:必要なアセット + CSP

ページはロジック(Module の定義、UI、キーボード、ドラッグ&ドロップ)を web/shell.js から読み込みます — これは phosphoric.html/.js/.wasm/.data並べて配置する外部ファイルです。shell.js はバージョン管理下(ソース)にあり、phosphoric.html から <script src="shell.js"> で参照されます。

この外部化により、バンドルは厳格な Content-Security-Policy と互換になります。script-src 'self' 'wasm-unsafe-eval' でページを配信するホストは、インラインの <script> をブロックし(script-src-elem)→ Module が未定義 → Module.canvasundefined → WebGL の createContext で致命的エラー、となります。すべての JS を外部化し(canvas のインライン oncontextmenu 属性を DOM リスナに置換)、phosphoric.htmlインラインのスクリプト/ハンドラを一切持ちません:厳格な CSP でも寛容なポリシー(GitHub Pages)でも同様に動作します。

必要最小限の CSP

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

⚠️ 'wasm-unsafe-eval' を外さないでください:素の script-src 'self' では WebAssembly のコンパイルが拒否され、エミュレータは起動しません。外部化の修正後は 'unsafe-inline' もハッシュ/nonce も不要 — WASM トークンのみで十分です。

ソースが sandbox eval codephosphoric.html ではない)の script-src-elem ブロックは、Phosphoric ではなくブラウザ拡張由来です:ページはインラインスクリプトや eval を注入しません。エミュレータへの影響はありません。

インターフェース(Web ページ)

ページは左側に縦のアイコンレール(JOric 風)と、オーバーレイの ORIC キーボードを表示します:

CTRL+T などのコード入力:ブラウザは一部のショートカット(CTRL+T = 新規タブ)を OS レベルで予約します。仮想キーボードの CTRL キーを使ってください:直接の C 呼び出しで ORIC マトリクスに書き込むため、ブラウザは横取りしません。

ファイルは HTTP で配信してください(file:// は不可):ブラウザはローカルファイルシステムからの .wasm 読み込みを拒否します。

技術的な詳細

忠実性 — 検証済み

WASM 出力は同一入力に対してネイティブビルドとバイト単位で同一です:WASM にコンパイルし Node.js で実行した headless の Atmos 起動は、ネイティブバイナリとまったく同じ PPM スクリーンショットを生みます(200 万・500 万サイクルで検証)。コアのサイクル精度の決定論は WebAssembly コンパイルを通して保たれます。

ブラウザレンダリングも検証済み:headless Chromium で読み込んだページは正しい Atmos 起動画面を表示し、キーボード入力も動作します(PRINT 6*7 + RETURN の入力で 42 を表示)— ROM 起動 → キーボード注入 → BASIC 実行 → 描画まで、すべてブラウザ内で。

docs/wasm.md から再掲(正となる最新版は GitHub)。

← ドキュメント · エミュレータを開く →