Skip to content

Emulator jsbeeb

Retro Jack edited this page Jun 29, 2026 · 11 revisions

jsbeeb — BBC Micro

jsbeeb is Matt Godbolt's BBC Micro emulator. GenX-DOS ships it as two self-contained bundlessystems/bbcmicro/ (Model B) and systems/bbcmaster/ (Master 128, ?model=Master) — so each game's URL names the machine it runs on rather than hiding the model behind a shared systems/jsbeeb/ path. They're full copies of the same Vite build; the integration was mostly hands-off (jsbeeb is a polished web product in its own right), but each bundle is among the largest in the suite and has some scary-looking orphan situations that are actually load-bearing.

Where we started

jsbeeb is a Vite-built TypeScript bundle, GPL-3.0-or-later. Drop in the dist/ directory verbatim, point play.html at dist/index.html?disc=<url>, done. There wasn't really an integration step — jsbeeb already supports per-machine URL parameters and direct disc loading. We just hosted the build.

The bundle is 25 MB and most of it isn't orphan

A quick du -sh shows ~25 MB, which raises eyebrows on a static site. Two-thirds of that is intentional. Worth documenting because every audit pass re-discovers these:

  • dist/teletext/ is 21 MB. Four txt0..3.dat files, referenced by dist/assets/index-*.js via the URL pattern teletext/txt${n}. No GenX-DOS menu path triggers teletext mode. The data is there because upstream jsbeeb keeps Ceefax viewer alive (F12 menu inside jsbeeb). Removing it is safe iff no one ever hits the teletext button. Defensible for our use, but it counts as a feature regression, not a cleanup.

  • dist/roms/{atom,tube,compact,b1770,a01,us,b,bp}/ — system ROMs for BBC variants we don't expose (Acorn Atom, Tube co-processors, Master Compact, 1770 disc controller, BBC A01 / B early-OS / B+, US BBC). All referenced by assets/index-*.js's model picker, so they're technically not orphans even though we only ever launch Model B and Master 128. ~150 KB total.

The teletext blob is the only one that would meaningfully shrink the bundle if removed.

How the two bundles work

Each bundle is a full copy of the jsbeeb dist/. The BBC Micro menu launches systems/bbcmicro/dist/?disc1=<Title>.ssd&autoboot (jsbeeb defaults to Model B); the BBC Master menu launches systems/bbcmaster/dist/?model=Master&disc1=<Title>.dsd&autoboot. Same engine, two honest paths — the only functional difference is the ?model=Master param the Master menu adds.

Save / load state

jsbeeb exposes the running machine as window.processor, and its own rewind feature uses processor.snapshotState() / restoreState() — a complete machine snapshot. We ride that exact API: the adapter (injected into the Vite dist/index.html alongside the other genx links) registers getState/setState around those two calls, and _shared/genx-savestate-std.js draws the bottom-left save / load menus. Because it's a full snapshot it works mid-game in titles with no save of their own — Elite being the obvious one.

Bundle layout

systems/bbcmicro/   (and an identical systems/bbcmaster/)
├── dist/
│   ├── index.html              ← jsbeeb entry, used directly
│   ├── assets/                 ← Vite-built bundle (this is most of jsbeeb)
│   ├── discs/                  ← bundled disc images (full upstream set in each)
│   ├── images/, sounds/        ← jsbeeb chrome
│   ├── roms/                   ← BBC variant system ROMs (most unused)
│   ├── teletext/               ← 21 MB Ceefax data, kept for completeness
│   └── tapes/
├── controls.html               ← thin wrapper page (retitled per machine)
├── genx-gamedoc-link.js         ← rewrites the corner link to the per-game gamedoc
└── COPYING                     ← GPL-3.0

play.html for each is just dist/index.html. The controls.html next to it is GenX-specific, not from upstream.

Because jsbeeb launches with keyless disc URLs (?disc1=<Title>.ssd), the shared genx-controls-link.js can't resolve a per-game gamedoc. dist/index.html ships a hardcoded <a class="gx-controls-link" href="../controls.html"> plus a deferred genx-gamedoc-link.js that maps the disc filename → gamedoc key and upgrades the link's href on load. Each bundle's script targets its own gamedoc dir — bbcmicro/gamedocs/bbcmicro/ (e.g. Eliteelite), bbcmaster/gamedocs/bbcmaster/ (e.g. EliteMasterelite, the old master- prefix dropped now each machine has its own dir). Keyless BASIC / blank-Master launches keep the generic controls.html.

Related

Clone this wiki locally