Skip to content
Phosphoricwiki
Contents

In the browser

Compiled to WebAssembly, Phosphoric runs in a tab with nothing to install, and its output is identical, byte for byte, to that of the native binary.

On this page

The same machine

make wasm (with Emscripten) produces four files in web/: the phosphoric.html page, the phosphoric.js and phosphoric.wasm engine, and phosphoric.data, where the ROMs from the roms/ folder are preloaded. The processor, memory, VIA, PSG, ULA, keyboard, tape and floppy run in the tab; the picture goes to a <canvas>, the sound through Web Audio.

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

The files must be served over HTTP: a browser refuses to load a .wasm from the disk.

The page

On the left, an icon rail:

ButtonEffect
MODELOric-1 or Atmos (cold restart)
I/Othe peripherals menu, like F1 (the browser keeps F1 for itself)
LOAD, drag and dropa .tap tape or a .dsk floppy, and the machine restarts on it
EJECTremove the media
LOCIplug in the LOCI cartridge
MODEMthe picowifi Wi-Fi modem
RESET, FULLcold restart, full screen
CRTa scanline and vignette filter
SAVE, RESTdownload an .ost state, restore one while running
KEYSshow or hide the keyboard

Under the screen, two lights, TAPE and DISK, come on during a CLOAD or a disk access.

The Oric keyboard shows as a semi-transparent overlay, with its real layout and sticky CTRL, FUNCT and SHIFT keys. The key symbols come from the real matrix. On the Oric-1, the FUNCT key, which only the Atmos has, is absent.

The page’s address accepts parameters:

ParameterEffect
?rom=oric1 or atmoschoose the machine
?media=prog.tap or game.dskstart on a tape, or on a floppy (the Microdisc then turns on by itself)
?loci=1start on the LOCI cartridge’s menu
?modem=1plug in the Wi-Fi modem
?relay=ws://host:port/ or ?relay=nonechoose the modem’s relay, or do without

The targeted file must be served as binary: a server that returned a fallback HTML page makes the insertion fail.

The LOCI in the browser

With ?loci=1, the machine starts on the LOCI menu. Its internal flash is kept in the browser (IndexedDB): it survives reloads, and it is filled with the ROMs at first launch. In LOCI mode, LOAD and drag and drop copy the file into that flash instead of inserting it: you then choose it in the menu, as on the real cartridge.

Not available in the browser: co-simulation of the real firmware, host USB keys and SD images.

The modem without direct networking

A browser does not open TCP connections. The picowifi modem therefore goes:

  • through a WebSocket relay to run on your machine (tools/picowifi_ws_relay.py, on 127.0.0.1:8766 by default), which also handles TLS;
  • or without a relay (?relay=none): the modem’s HTTP requests are replayed by fetch(), for the sites that allow it, and the time comes from the browser. Telnet, BBSes and raw TCP need the relay.

What does not work on the web

Features that need native sockets or threads are disabled: TCP, PTY and COM serial transports, the GDB server, Chromecast streaming. Expansion cards are read-only, since the page cannot relaunch itself (decision 0004).

The security policy

The page has no inline script: it runs under a strict security policy. The minimum required is:

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

Without 'wasm-unsafe-eval', the browser refuses to compile the WebAssembly and the emulator does not start. It is a token specific to WebAssembly, much narrower than 'unsafe-eval'.

Sources in the repository : docs/wasm.md, README.md, docs/loci.md.