-
Notifications
You must be signed in to change notification settings - Fork 0
Emulators
19 emulators ship with GenX-DOS, driving 28 sub-systems between them. Some of the integrations were one-liners; others took a week of trial and failure. Each one has its own story page — the table below is the index.
| Article | Sub-systems |
|---|---|
| Emulator-XRoar-CoCo | Tandy Color Computer |
| Emulator-atari800 | Atari 400, Atari 800XL |
| Emulator-VICE-family | PET, VIC-20, MAX, C64, C16, Plus/4, C128 |
| Emulator-gearcoleco-ColecoVision | ColecoVision |
| Emulator-jzIntv-Intellivision | Mattel Intellivision |
| Emulator-libretro-o2em-Odyssey2 | Magnavox Odyssey² |
| Emulator-apple2js | Apple ][+ |
| Emulator-tiny8bit-CPC | Amstrad CPC |
| Emulator-elkjs-Electron | Acorn Electron |
| Emulator-js99er-TI-99-4A | TI-99/4A |
| Emulator-jsvecx-Vectrex | GCE Vectrex |
| Emulator-apple1js | Apple I |
| Emulator-jsbeeb | BBC Micro, BBC Master 128 |
| Emulator-EmulatorJS-NES-FCEUmm | NES |
| Emulator-Javatari | Atari 2600 |
| Emulator-JS7800 | Atari 7800 |
| Emulator-WebMSX | MSX, MSX2 |
| Emulator-JSSpeccy | ZX Spectrum |
| Emulator-JtyOne | ZX81 |
Nine of these share one copy of the EmulatorJS framework at emulators/_shared-ejs/ — the seven VICE bundles, the Coleco bundle, and the NES bundle. All the EJS-specific gotchas live in Emulator-VICE-family; the Coleco and NES articles assume that context and only document what's different.
The same flow across every emulator:
- The user picks a number in a
GAMESmenu. -
N.batruns the named launcher (e.g.sonic1). -
sonic1.batis alink:entry pointing at the emulator's URL. - The terminal opens that URL in a new tab via
window.open(link, "_blank").
URL patterns vary per emulator. Each engine article documents its own.
Every emulator's GAMES menu has a "boot a clean machine" entry as item N+1. Labels match what the user actually sees on boot:
-
PROMPT for
>/Okstyle command-line systems -
BASIC for systems whose BASIC banner is the boot screen (
READY,Ready,READY.) - DESKTOP for OS-driven machines (none currently — reserved for future 16-bit additions)
All eight VICE-family + 800XL bundles route through a small empty.prg for the BASIC entry; Spectrum, ZX81, and CPC pass no query at all (their emulators already drop to ROM BASIC with no software inserted).
Every emulator directory has a controls.html documenting its keyboard / joystick mapping. Same dark-amber DOS-flavoured style across all pages; the page-level CSS lives in emulators/_shared/genx-controls.css.
Per-game instruction pages at gamedocs/<platform>/<key>.html replace controls.html when a game has researched gameplay instructions. The genx-controls-link.js script reads ?game=, ?tape=, or ?rom= from the URL and routes to the matching gamedocs page, falling back to controls.html when no game param is present (prompt/BASIC entries).
Every emulator's main entry HTML carries a small bottom-right controls link (fixed position, semi-transparent, Wikipedia-style external-link SVG icon). The link sits in the entry HTML itself — play.html for the wrapped emulators, the upstream index.html for the URL-driven ones (jsbeeb, webmsx, jsvecx). It's not in the virtual filesystem; the DOS prompt's dir output shows only .bat launchers and menu scripts, never raw .html files.
Same recipe each time:
-
Copy the deployed bundle into
emulators/<name>/. Mirror withwgetif it's hosted, or build from source if you must. Drop the upstreamnode_modules, the inner.git, any.gitignorethat excludes deploy artefacts, and any upstreamREADME.md/ dev tooling. -
Strip telemetry and external runtime fetches from the source's HTML and bundled JS/CSS before deploying. Each of these patterns has bitten us at least once:
- Inline analytics (
gtag(,umami, etc.) — jsbeeb and webmsx both shipped Google Analytics; removed both. - Framework-version checks like
fetch("https://cdn.<framework>.org/.../version.json")— EmulatorJS does this on every bootstrap. PatchedcheckForUpdates()to a no-opreturn;. - Hardcoded NetPlay / multiplayer relay servers — Javatari had
SERVER_ADDRESS: "webmsx.azurewebsites.net/"for keep-alive + WebSocket. Set the address to""so any guardedaddress && …short-circuits and the wss:// URL becomes invalid. - CSS web-font
@importrules pointing atfonts.googleapis.com— jsbeeb's Vite-built CSS had a Lato import. Strip it; fall through to the system-font fallback unless the visual difference matters.
- Inline analytics (
-
Add the standard
<noscript>overlay to every new HTML entry point — copy verbatim from any existing emulator page. -
Write
play.htmlif the emulator needs a key-based launcher. Skip if the emulator's own page already accepts URL params (BBC, WebMSX, JSVecX patterns). The wrapper reads?game=<key>, fetchesgames.json, looks up{title, rom}, and boots the emulator with that ROM. -
Bundle the ROMs under
emulators/<name>/<roms-dir>/. archive.org and most preservation sites don't set CORS for direct browser fetch, so wrappers can't pull at runtime — every byte must be on the same origin. -
Wire
fs.js: each game's.batgets alink:field pointing at the URL pattern above. Per-systemGAMESmenu follows the 45-char box format (see Customising the Filesystem) with 10 titles + a PROMPT/DESKTOP entry.
Some platforms host multiple machines under the same vendor — ATARI has 2600 / 7800 as siblings under CONSOLE and 400 / 800XL as siblings under HOMECOMP; MSX has MSX1 and MSX2; SINCLAIR has SPECTRUM and ZX81. The hierarchical pattern: a parent menu with 1.<MODEL1> / 2.<MODEL2> rows, each pointing into its own GAMES dir. See prompt/javascript/fs.js for the exact tree.
Single-platform manufacturers (NES, INTV, CVISION, ODYSSEY2, VECTREX, COCO) sit directly under their CONSOLE or HOMECOMP parent — no manufacturer middle level.
Note: Atari 400 + 800XL share one emulator build (emulators/atari800/). The menus differ only in which ?machine= URL param their launchers pass.
./serve.sh # or: python3 -m http.server 8765After editing fs.js or any emulator wrapper, hard-refresh the prompt page (Ctrl+Shift+R). Browsers aggressively cache fs.js between visits.
- Project Overview — what the site does
-
Virtual Filesystem — how
.batlaunchers reachplay.html - File Structure — where bundles sit in the repo
- Roadmap — what's shipped, what's next