Files
izapple2/doc/frontend_wasm.md
Iván Izaguirre 29c1762452 A page per frontend
The README listed only the SDL2 and the console frontends, and the build
instructions for all of them lived in the README. Now there is a Frontends
section with the eight of them, each linking to a page with how to build it,
how to use it and what it can not do.

The libretro pages take the frontend_ prefix as well. The feature list moves
to doc/features.md, leaving a summary in the README.

The default configuration was wrong in the two places it was written: it
listed a parallel card in slot 1 and a mouse in slot 4, which are empty and a
Mockingboard, and flags -disk35 and -hd that no longer exist. Both lists now
come from -showConfig.
2026-08-10 00:14:11 +02:00

3.4 KiB

The WebAssembly frontend

a2wasm is the emulator compiled to WebAssembly, running in the browser. The machine and the screen are the Go code of a2ebiten built for js/wasm, and around it there is a React interface with the controls and the disk drives.

There is nothing to install for whoever opens the page, and there is a fair amount to build: it is the only frontend that needs Node besides Go.

Building

You need Go and Node 18 or newer.

git clone github.com/ivanizag/izapple2
cd izapple2/frontend/a2wasm
npm install
npm run build

npm run build compiles the Go code to WebAssembly, type checks the React code and puts everything in dist, which is a static site that any web server can serve. To build only the WebAssembly part, run ./build-wasm.sh: it leaves izapple2.wasm, its gzipped copy and the wasm_exec.js of your Go installation in public/wasm.

The binary is around 26 MB, 7 MB gzipped, so serve it compressed.

Running it while working on it

casa@servidor:~$ npm run dev

Then open http://localhost:5173. Vite reloads the page when the React code changes; a change in the Go code needs ./build-wasm.sh and a refresh.

Serving it

dist is a static site, with two things to get right in the server:

  • .wasm files have to be served as application/wasm.
  • The page asks for Cross-Origin-Embedder-Policy: require-corp and Cross-Origin-Opener-Policy: same-origin, which Vite sets by itself while developing.

Using it

The machine boots by itself when the page loads. The toolbar on top has pause and resume, reset, a screenshot that downloads a PNG, and the screen mode: NTSC colour, plain or green. The bar at the bottom shows the speed in MHz.

The keyboard goes to the emulator once you click on the screen. There are no joysticks and no mouse.

To insert a diskette, use the file picker of a drive or drop the file on the disk panel: the first one goes to drive 1 and the second to drive 2. There is also a button to load DOS 3.3 from the resources embedded in the binary. The formats are the same as in the other frontends, compressed ones included.

Driving it from JavaScript

The Go code exports window.wasmAPI, which is what the React interface uses and is there for whatever else you want to do with it:

wasmAPI.reset()
wasmAPI.pause()
wasmAPI.resume()
wasmAPI.isPaused()
wasmAPI.getFrequency()
wasmAPI.setScreenMode("ntsc")   // "ntsc", "plain" or "green"
wasmAPI.screenshot()
wasmAPI.sendKey(13)
wasmAPI.sendText("10 PRINT \"HELLO\"\n")
wasmAPI.loadDisk(1, bytes, "game.dsk")
wasmAPI.loadDiskFromURL(1, "https://example.com/game.dsk")
wasmAPI.loadDiskFromURL(1, "<internal>/dos33.dsk")

An URL is fetched by the browser, so it has to allow it with CORS.

What is missing

  • Command line options. The machine is the default one and there is no way to choose a model or to configure the slots yet.
  • Joysticks and mouse.
  • Sound in some browsers until you click on the page: they do not start audio before the visitor asks for something.
  • State that survives a refresh. Reloading the page starts a new machine.
  • getDiskInfo, which is in the API and always answers null, so the drives do not show what is in them.

The notes on how it is put together, the file layout and the deployment recipes are in frontend/a2wasm/README.md.