Changelog
[Unreleased]
Added
- BBC Micro Thrust: USB gamepad flight. The launch line gains a
GP.*remap so the pad flies it — d-pad rotates (Caps Lock/Ctrl) and up thrusts (Shift), A fires (Return, already the pad default) and B works the shield / tractor beam (Space). Rotation stays held-to-turn, as on the keys. Controls re-verified against the game's documented layout; gamedoc gained a matching pad note. - BBC Micro Repton: USB gamepad note. Verified against the game's own title/status screen — Repton has no define-keys screen (unlike Citadel), just fixed Z / X /
*/?movement and Space to start — so the default jsbeeb pad plays it with noGP.*remap: d-pad moves Repton, Start begins the game. Gamedoc gained a matching pad note. - Sega Master System: the pad's Start button now starts the game. The Master System has no Start button (its Pause lives on the console), so a USB pad's Start previously did nothing at a title screen. Now the physical Start button fires Button 1 — the "1 / START" button every SMS game begins on — via a one-button gamepad shim over EJS's native pad. The face buttons are set so A = Button 1, B = Button 2 (bottom face is the primary action), and the console Pause moves from the pad's Start to its Back button (
segaMSindex 3value2→SELECT). Controls page and the Alex Kidd gamedoc updated to match. - BBC Micro Elite: USB gamepad flight (digital). The launch line gains a
GP.*remap — d-pad rolls (,/.) and pitches (up=diveS, down=climbX, inverted), A fires the laser, RB accelerates (Space), LB decelerates (?); trading/chart keys stay on the keyboard. jsbeeb's analogue stick doesn't reach Elite (it boots keyboard-controlled), so this is a digital pad — fly-tested and signed off. Gamedoc gained a matching pad note. - Consistent "audio suspended" banner on every system. A shared
genx-audio-banner.jsgives all the other bundles the same fixed top banner jsbeeb ships — "Your browser has suspended audio — mouse click or key press for sound." It wraps theAudioContextconstructor to track the engine's context, shows the banner whenever audio is suspended, and clears it (resuming the context) on the first click/keypress. Wired into all 31 non-jsbeeb entry pages (eachplay.htmlplus WebMSX'sindex.html); jsbeeb keeps its own native banner. Verified the show/hide cycle on EmulatorJS, and the AudioContext hook catching contexts on emscripten-SDL (atari800) and sokol (CPC).
Changed
- BBC Micro: Uridium → Firetrack (Electric Dreams, 1987). The Uridium disc only started intermittently, and its opening "Select: 1. Joystick / 2. Keyboard" then "Redefine keys?" prompts put two answers between the player and the game. Firetrack — Nick Pelling's vertically-scrolling shooter, one of the Beeb's great technical showpieces — loads straight in and keeps the same arcade-shooter slot. Its documented main layout (
Zleft,Xright,:up,/down,Returnfast fire) is exactly the default gamepad mapping, so the pad flies it with noGP.*remap at all; a second keyboard layout (Caps Lock/Ctrl/[/:/cursor-up) is live alongside it. New gamedoc, controls taken from the game's inlay; Uridium's BBC disc, gamedoc and disc→doc mapping removed (Uridium stays on the C64). Menu keeps slot 9, still 1987. - BBC Micro: Revs → Castle Quest (Micro Power, 1985). Revs is admired more than played — a demanding analogue F3 sim that reads as a technical landmark rather than a pick-up-and-play game, and making it pad-friendly would have meant reintroducing the very control-mode friction we'd just designed out. Castle Quest — a BBC-original flip-screen puzzle-platform-adventure, "probably the most challenging game ever devised for the BBC micro" — restores the Citadel-style exploration feel and plays straight from the keyboard. Keyboard-only by design (its pick-up / drop / store / retrieve / directional-throw verbs are more than a pad maps cleanly, so no
GP.*). New gamedoc; Revs's disc, gamedoc and disc→doc mapping removed. Menu keeps slot 6, still 1985. - BBC Micro: Citadel → Frak! (Aardvark, 1984). Citadel's boot-time key-layout picker made pad play clunky — jsbeeb's gamepad only fakes keypresses, so it can't reach the BBC joystick that Citadel's "Press Fire to select Joystick" option needs. Frak!'s single fixed scheme (Z / X /
*/?+ Return) maps straight onto the default pad: d-pad moves (up jumps), A throws the yo-yo and starts the game, noGP.*remap. New Frak! gamedoc; Citadel's BBC disc, gamedoc and disc→doc mapping removed (Citadel stays on Electron and Plus/4). Menu keeps it at slot 4, now dated 1984 (after Elite). - SECURITY.md now documents the zero-external-calls posture. New "No external calls at runtime" section describing the self-hosting and the strict Content-Security-Policy that enforces it (browser-blocked off-site requests; zero external requests in DevTools).
- Per-game content moved off the system-level controls pages. Those pages describe the machine and emulator, not individual titles — the per-game details belong on each game's own page (as
m100/controls.htmlalready states). Fixed: Apple ][+ — dropped the per-game "starting hints" table (Lemonade Stand, Castle Wolfenstein, Choplifter, Aztec, Lode Runner, Sammy Lightfoot, Hard Hat Mack, Karateka, Oregon Trail); every entry was already covered in full on the game's own page, so it now points there (the Applesoft-BASIC prompt note, the one non-game row, moved into the BASIC section). TRS-80 — the "playing the games" note no longer names specific titles/keys (Super Nova, Armored Patrol, Defense Command, Sea Dragon, Eliminator — all verified present in their gamedocs); it keeps the general guidance. PET — the annotated ten-game lineup (already duplicated in each gamedoc) reduced to a pointer, and the "Why no PETSCII Robots?" note removed (an unshipped title with no game page).
Fixed
- Snapper gamedocs corrected against each machine's own instructions — and they differ. The BBC and Electron ports document different keys, so the two pages were verified separately. BBC: the game opens with a "Do you want instructions?" prompt that wasn't mentioned at all, then starts on any key; and ending the game is Shift + BREAK (
Shift+F12here), notEscas the page claimed. Electron: its key screen also listsS/Qsound, COPY pause and DELETE restart — all three missing — while theEscrow it claimed appears nowhere and has been dropped. - Electron gamedocs: stop labelling Electron keys as BBC ones. Boxer and Starship Command described their freeze/continue keys as "BBC COPY"/"BBC DELETE"; the Electron has its own COPY and DELETE keys, and this bundle maps them to
Home/Backspace(jsbeeb'sEndfor COPY is a BBC-only detail). Checked the whole Electron set for the same class of error — no gamedoc references function keys, which the Electron doesn't have (it uses FUNC + number,Alt+ number here). - Acorn Electron Cybertron Mission: a gamepad could not start the game. Its title reads "PRESS SPACE TO START OR FIRE BUTTON", but the game's fire is the
Mkey and the title itself only answers toSpace(or a real joystick's fire line, which this emulator doesn't drive) — so with all four face buttons mapped toM, a pad player was stranded on the title screen. Start now sendsSpace. Controls re-verified against the game's own KEYS screen —A/Z,</>,M, plusS/Qsound andP/Rpause, all as documented; gamedoc gained the pad note and the eight-direction/diagonal detail.
Added
check-doc-counts.sh— a guard against documentation drift. Several counts are repeated across README, the wiki, the feature article and the social card, and platform changes update some while missing others (the article's engine count sat stale from the Vectrex retirement until an audit caught it months later). The script measures the real numbers from the tree — gamedocs, sub-systems,controls.html, size on disk — and checks every place they're quoted, exiting non-zero on any mismatch. The engine count can't be derived (EmulatorJS is one engine hosting many libretro cores), so instead every document stating it must agree with the others. It also prints the line the social card should read, since a PNG can't be checked automatically. Excluded from the portable build.
Fixed
- BBC bundles now assume a US keyboard, so the
:*key is where the docs say it is. jsbeeb guesses the layout fromnavigator.language—en-us→ US,en-gb→ UK, and everything else falls back to UK. That fallback silently mis-maps the BBC : key for anyone on a US keyboard whose locale is neither (en-NZ,en-AU,en-CA,de-DE…): it moves to the backtick key, so following a gamedoc's "press'" typed→instead. Both bundles now setlocalStorage.keyboardLayout = 'US'before the engine loads — unless the browser really reportsen-GB(keeps UK), or the visitor already chose a layout (left alone). US is the most common layout worldwide, and a UK board has that key on the apostrophe too, so "press'" is now correct either way. Bothcontrols.htmlpages also spell out that a literal — for*CAT,*RUNand friends — is Shift+'. - The BBC BASIC prompt was throwing an error instead of booting. Both BBC bundles' BASIC system prompt entries launched jsbeeb with no disc parameter, and jsbeeb then falls back to its built-in default of
discs/elite.ssd— a file dropped long ago along with the other upstream test discs, so the page opened on "An error occurred — sorry! … Unable to load discs/elite.ssd, http code 404". Both entries now load the bundledblank.ssd, which boots to a cleanBBC Computer 32K / Acorn DFS / BASIC >and leaves a writable disc in drive 0, so*CATandSAVEwork from the prompt. (That disc turned out to be exactly whatblank.ssdwas for — it had simply never been wired up, and a passing orphan sweep had removed it as unreferenced.) - Feature article stats brought up to date. "Emulator engines" still read 19 — it was missed when the Vectrex/jsvecx bundle was retired in favour of the Sega Master System (EmulatorJS counts as one engine, so the retirement took the total to 18, as README and the wiki already said). Size on disk 138 → 139 MB. Systems (33) and games (327) were already correct, as is the social card.
- Wiki jsbeeb page: three stale claims. The fork version still read 1.13.1 in two places (it was rebased onto 1.14.0 for the Chrome-150 fix, as ATTRIBUTION already recorded); the positional-keyboard example cited Citadel, which no longer ships on the BBC Micro (now Repton/Firetrack); and Elite was described as running on the analogue stick, when its pad is a digital
GP.*mapping. The gamepad section also now records the games wired since (Elite, Thrust) and the ones needing no remap at all (Frak!, Jet Set Willy, Firetrack). - Wiki: jsbeeb's native BBC joystick documented for the first time. Separately from the
GP.*key-faking, jsbeeb feeds pad axes to the emulated ADC and reads the joystick fire buttons off the system VIA — but from Gamepad-API buttons 10 and 11, which are the stick-click buttons (L3/R3), not the face buttons. A game's own joystick option therefore answers to left stick to steer, click the stick to fire; pressing A does nothing, which makes the feature look broken when it isn't. - BBC Micro Exile gamedoc: add the missing pick-up and throw keys. The controls table listed take-out/store/drop but never said how to pick something up — M+1 to pick up and hold, M+2 to throw (M alone drops), which is unusable-without in a game built on carrying things. Verified against the documented BBC key list, along with the rest of the table (
Q/W,P/L,O/K/I,Space,Ctrl,G/S). Noted as a keyboard game: the jet-pack, separate aiming and full verb set need more inputs than a pad has, so noGP.*. - BBC Micro Jet Set Willy gamedoc: correct the jump key. The gamedoc had jump on the BBC
:/*key (PC apostrophe); the Tynesoft BBC port actually jumps on Return (Z/X walk, Q/S toggle music) — verified against the jswmm.co.uk community. Added the music keys and a pad note: the game plays on a USB gamepad as-is (d-pad walks, A jumps, since A is Return by default — noGP.*). - Wiki generator now emits the strict CSP.
docs/wiki-src/build.py's page template was missing the Content-Security-Policy<meta>added to every served page in v1.5.0, so rebuilding the wiki silently stripped the CSP from all 41 generated pages. The template now includes it (and the wiki was rebuilt — also catching the CHANGELOG and ATTRIBUTION wiki pages up to their current sources). - Elite gamedoc: document star-chart navigation and correct the arrow-key note. The quick-start now says how to actually pick a hyperspace target — on the F4/F5 charts, move the crosshair onto the star's dot with the cursor keys (F6 confirms the system), then H. The "BBC keyboard quirks" note previously claimed Elite doesn't use the arrow keys at all; corrected — that's true in flight (roll/pitch is
</>andS/X), but the cursor keys do move the chart crosshair. Verified in-game (selecting Diso from Lave). - BBC Micro Chuckie Egg gamedoc: add the missing Hold and Abort keys. The game's own KEYS screen lists Hold
H(pause) and AbortEsc+Halongside the movement/jump keys; both were absent from the gamedoc. Directional/jump keys and the pad remap re-verified correct against that screen.
[1.5.0] - 2026-08-02
Security
- Zero external calls at runtime — audited across every bundle, vendored code included, and now enforced. The site's premise is zero telemetry and fully self-hosted; this makes it verifiable. Every served bundle was checked for third-party network calls, which were removed. Attribution links and legally-required licence links are kept throughout — the goal is no runtime calls, not stripping credit:
- EmulatorJS (every EJS bundle): dropped the startup version-check fetch to the EmulatorJS CDN, blanked the netplay default endpoint, and pointed the core-download CDN failsafe back at the local
data/folder. Applied to both the productionemulator.min.jsand the debugsrc/runtime (jsnes, js7800). The About panel's EmulatorJS / RetroArch / core-repo credit links are kept — they are attribution, not runtime calls. - jsbeeb (BBC Micro / Master): the
Retro-Jack/jsbeebfork now strips Google Analytics (gtag), the Google Drive startup + OAuth loads, and the Stairway to Hell disc-archive fetches (fork Change 3 in itsGENX-CHANGES.md); both BBC bundles re-vendored off the telemetry-free build. - A strict Content-Security-Policy on all 438 served pages (
default-src 'self',connect-src 'self', tuned for WASM/workers/blob:/data:) makes any off-site request physically impossible — DevTools shows zero external requests. Re-tested across the engine families — EmulatorJS (SMB, WASM + workers), jsbeeb (Chuckie Egg, AudioWorklet), atari800 (Star Raiders, emscripten WASM) and apple1 (vanilla JS) — every emulator still boots and runs under the policy. - Deliberately kept, because they are not network calls: the SVG/XML namespace identifiers (
w3.org/2000/svg) that the icon markup needs, and the GPL/MIT/FontAwesome licence notices embedded in the vendored engines (removing those would breach the licences).
[1.4.1] - 2026-07-31
Fixed
- BBC Micro & Master no longer freeze on Chrome. Both bundles are rebuilt on jsbeeb 1.14.0, which carries the upstream workaround (#704) for a Chrome 150 V8 bug that wedged the emulator a few seconds into a game — Chrome-only (Firefox was fine), no gamepad needed, all BBC games affected (Elite was the reproducer). Diagnosed the hard way — gamepad, audio-context and CSP all turned out to be red herrings; the tell was that upstream's live jsbeeb ran Elite fine. Our
Retro-Jack/jsbeebfork was rebased onto 1.14.0 (keeping the d-pad remap and monitor inset); 1.14.0's new#restart-pendingconfig element is now in both bundles so the newer engine doesn't null-deref on it. With thanks to Matt Godbolt for shipping the upstream fix within a day.
[1.4.0] - 2026-07-31
Added
- BBC Micro/Master now run a jsbeeb fork, and Chuckie Egg gets USB gamepad support. The two BBC bundles are rebuilt from the new
Retro-Jack/jsbeebfork (jsbeeb 1.13.1) instead of carrying an ad-hoc edit to the shipped build. The fork adds a d-pad gamepad remap — fourGP.D12–GP.D15cases so a game's launch URL can map the d-pad buttons to any BBC key; jsbeeb hardwires them to Z/X/:/? with no remap hook, so a digital game with different keys couldn't drive the d-pad before. First game wired: Chuckie Egg (d-pad runs and climbs, any button jumps —GP.FIRE=SPACE&GP.D12=A&GP.D13=Z&GP.D14=COMMA&GP.D15=PERIOD). The d-pad remap is a general improvement and is offered upstream (the fork's cleangamepad-dpad-remapbranch); the only GenX-local fork change is the CUB-monitor inset (68→120, for the wallpaper breathing room), which stays on the fork's build branch. Snapper (native scheme) and Elite (analogue stick) verified unchanged by the rebuild. See the fork'sGENX-CHANGES.mdand ATTRIBUTION.md. - ATTRIBUTION: a "Research and reference sources" section crediting Paul Farrow. His fully-commented ZX81 disassembly of 3D Monster Maze (fruitcake.plus.com) is the authority behind that gamedoc's verified keys — proper credit for freely-shared preservation work.
- ATTRIBUTION: credit Mark Moxon's bbcelite.com. His fully-commented, line-by-line disassembly of Elite (bbcelite.com) is the authority behind our five Elite gamedocs' accuracy passes — publisher/year, real flight and chart keys, and each 8-bit port's true feature set. Already named in the BBC Master gamedoc and cited across the CHANGELOG's Elite corrections; now properly credited alongside Paul Farrow.
- Shared gamepad shim: multi-key stick directions. A stick direction's map value can now be an array of keys, pressed and released together on one edge — for games whose straight up/down/left/right is really two keyboard keys at once (e.g. 3D Defender's four-zone joystick emulation). Existing single-key maps are unaffected.
- GenX-DOS favicon on every page. The prompt's animated favicon (and its .ico fallback) now lives in
systems/_shared/and is linked from all 378 pages that lacked it — every play/controls/wrapper page and every gamedoc — so emulator tabs stop showing the browser default. - Sega Master System (replaces the Vectrex). New
systems/sms/bundle on the already-shipped genesis_plus_gx core (EmulatorJS bundle #14 — and with jsvecx retired the engine count actually drops to 18): ten games from Alex Kidd in Miracle World (1986) to the 8-bit Sonic the Hedgehog (1991), CONSOLE menu slot #6, CRT bezel, native USB gamepad support, five save-state slots, and persistent battery saves (Phantasy Star). All ten gamedocs researched — five from the official Sega manuals (Alex Kidd, Wonder Boy, Out Run, R-Type, Castle of Illusion), the rest from verified secondary sources. The Vectrex bundle (~22 MB), its eleven gamedocs and its bezel are removed: jsvecx's AY sound emulation overruns tones and can't voice Spike's speech (confirmed against upstream and the libretro vecx core — it's the emulation lineage, with no practical browser alternative), which no longer meets the site's accuracy bar. - Shared gamepad shim (
systems/_shared/genx-gamepad-keys.js). The CPC's Gamepad→keyboard shim generalised into a shared helper driven by a per-bundlewindow.GenXGamepadMap(axes + button-index → key), ready for any other standalone engine that needs it. CPC refactored onto it with identical behaviour (regression-tested on 3D Starstrike). - USB gamepad support on the ZX Spectrum bundle. Per-game maps for all ten games on the shared shim; the three fixes that made it work: the shim's dispatch target is now lazily resolvable (JSSpeccy rebinds its key listeners onto the app-container div it injects at boot, so events aimed at
documentnever arrived), the page gained the audio-unlock pattern (JSSpeccy's AudioContext is captured at construction and resumed on load/gesture — direct-URL opens used to stay silent), and the stick axes gained press/release hysteresis (0.5 on, 0.3 off) so a hovering stick can't machine-gun key events. All ten pad-verified in play; three gamedoc key tables corrected along the way (Chuckie Egg's ,/./A/Z were another platform's keys — the real defaults are 9/0/2/W with Z or M to jump, established in-game key by key; Pssst and Sabre Wulf had up/down swapped). Underwurlde's snapshot was also replaced — the old copy booted into an infinite-lives offer, off the accuracy bar — and its doc gained the full key set from the game's own instructions (pick up/drop, drop-from-rope, pause, and a "you begin unarmed" note), with the pad remapped to match: A/Y fire, B pick up/drop, X rope-drop, Start pause. - 3D Monster Maze: menus verified from a full disassembly, tape gentled, first ZX81 pad pass. The intro's keyword labels assumed a ZX81 keycap in front of you — the tape image now shows the real keys ("A"/"K"/"C" replace the inverse STOP/LIST/CONT, byte-for-byte), and its two NEW tokens are patched to RUN so no path dumps the player at a dead BASIC prompt. A is the quit key: the page closes the game tab (prompt-launched windows allow it), with the RUN restart as the fallback for hand-typed URLs. The ZX81 bundle also gained per-game key allowlists — on a ZX81 every stray key is live BASIC (Space is BREAK), so keys with no in-game function are swallowed before the emulator sees them (the three typed-command games keep the full keyboard). Gamedoc rewritten around the verified menus (press Y for the ringmaster, K instructions, C proceed, the 50/50 appeal) and the pad map extended (B/Start proceed, X instructions). The shared shim's
?paddebugoverlay now also reports a liveness heartbeat and whether the browser is exposing a pad. - USB gamepad support on the ZX81 bundle. Seven action games mapped (mostly the 5/6/7/8 cursor cluster + 0); Black Crystal, City of Zion and Chess get no map — their notes now say the game is typed-command by design instead of blaming the emulator. The pad-map block runs ahead of the loader's
?game=→?tzx=URL rewrite. - Acorn Electron: Elite axis flip +
?paddebug. Elite's vertical axis inverted — stick up now climbs. A?paddebugflag on the shim shows an on-screen log of every synthetic key event. - Jet Set Willy: working snapshot. The previous copy stopped at its code-entry screen and reset the machine; replaced with a copy that boots straight to the title.
- CPC: pad dormant at the BASIC prompt. The gamepad map now loads only with a
?game=, so a pad can't type into Locomotive BASIC (the three newer shim bundles were already gated). Lynx: California Games' controls line now names the pad buttons like its nine siblings. - USB gamepad support on the Acorn Electron bundle. Per-game
GenXGamepadMaps inplay.htmlon the shared shim — each of the six games gets its verified keys on the pad (d-pad/stick movement plus face buttons; Elite gets the full six-button flight set with LB ECM / RB fire missile). All six gamedocs' "keyboard-only" notes replaced with the actual pad mapping. - USB gamepad support on the Amstrad CPC bundle. The engine has no Gamepad API support, so
play.htmlnow polls pad 0 and synthesizes the arrow/Space key events it already understands, while a per-gamejoystickflag ingames.jsonlaunches tiny8bit's emulated 9-pin joystick mode. D-pad or left stick steers, any face button fires; idle pads send nothing so keyboard games are unaffected. First game wired: 3D Starstrike. - Community-profile files.
CONTRIBUTING.md(local setup, PR ground rules, scope rule, licensing),CODE_OF_CONDUCT.md(Contributor Covenant 2.1), issue templates (bug report + rights-holder takedown request, with a config pointing security reports at private advisories) and a PR checklist template. Completes the GitHub community-profile checklist.
Fixed
-
Menu codes now obey DOS 8.3 naming — 13 overflowing codes shortened. Nine-character codes (GALAFORCE, ASTEROIDS, CENTIPEDE, ADVENTURE, RIVERRAID, FOODFIGHT, CHOPLIFTR, KIDICARUS, LASTNINJA, LOCKCHASE, ALIENPLUS) filled the menu's code column flush against the border with no gap. All shortened to ≤8 characters with DOS-style truncation (ADVENTUR, CENTIPED, FOODFGHT…), with the numbered pointers and launcher
.batfiles renamed in lockstep. Also caught two launchers whose names never matched their advertised codes — typingCASTLEVorFINALFNTat the prompt didn't work because the files werecastlvnia.bat/finalfnts.bat; both renamed to match. The whole virtual filesystem now passes an 8.3 scan, and staying within 8.3 is policy from here on. CodeQL flagged the?game=key flowing intoinnerHTMLwhen a wrapper renders its "Unknown game key" / "no game" error. Real but low-impact (static site, no cookies/sessions to steal) — still, all error rendering now builds the message withtextContentinstead ofinnerHTML: the sharedgenx-game-loader.jsandgenx-ejs-boot.jshelpers plus the inlinefail()/error blocks in tenplay.htmlwrappers (Atari 400/800XL, 7800, NES, Spectrum, ZX81, PET, TRS-80, CoCo, CPC). Thegames.jsonfetch-error messages got the same treatment for uniformity. Also removed a dead no-opreplace(' \& ')incommands-core.js(CodeQL js/identity-replacement; real&&chaining is handled separately). -
Apple emulator CSS tidied. Dropped the Apple ][ disk-activity LEDs — their
red-off-16.png/red-on-16.pngimages were missing, so the indicators never rendered — and removed deadOPEN_APPLE/CLOSED_APPLEkeyboard rules (with their broken image references) from the Apple I stylesheet, for keys that machine never had.
Changed
- Controls and per-game instruction pages restyled to the site design language. The 33 controls pages and all 327 per-game instruction pages moved from the old DOS-flavoured look to the landing's dark-CRT design language (Michroma headings, amber/green/cyan on near-black, thin borders, keycaps as panels, self-hosted IBM Plex/Michroma). Only the interactive surfaces — the DOS prompt/menu and the emulator
play.htmlpages — keep the terminal look. Each controls/gamedoc page also gained a home link back to the site root. - Feature article now matches the landing page, and moves to
docs/article/. The article was recoloured and then reshaped to the landing's dark-CRT design language — thin amber hairlines, rounded dark panels, amber Michroma headings with trailing rules, green accents, cyan links, and soft glows in place of the old magazine's solid colour fields and hard offset shadows (the serif body stays, for long-form readability). It also moves fromdocs/tech_article.htmltodocs/article/(served asindex.html); the credit pill'sreadmelink, the landing's feature link, the README and ATTRIBUTION all follow. Shared fonts and both screenshots stay indocs/— the landing uses the same two screenshots. - Doc sync + orphan audit (July 29th pass — all repos). Orphans clean (33/33 gamedoc dirs, nothing untracked); the landing page's assets all resolve and the VGA font is referenced and attributed; counts unchanged and correct everywhere including the landing's own spec sheet (33/327/19), the social card and the article. Stale-text found and fixed: README and three wiki spots (File-Structure tree + table, Project-Overview boot step) still called the root
index.htmla<meta refresh>redirect toprompt/— it's been the landing page since a42d222. Sister repos audited 23/07 and unchanged since; Movie-Cleanup was deleted that session. - Landing page is desktop-only, with a graphic for touch visitors. All the responsive/mobile layout CSS is gone; the site is driven entirely from a physical keyboard, so a phone or tablet now gets a full-screen graphic instead of the landing — a CP437 keyboard drawn in the VGA font, the wordmark, and "This one needs a keyboard" with a plain note to open it on a desktop. Detection uses the comma (OR)
(pointer: coarse), (hover: none)form, since iPadOS reports hover; same query the prompt itself uses. - Landing page: section order and spacing. "What you're looking at" now comes before the spec sheet — plain words first, numbers as confirmation. Fixed a specificity bug while there: the sections carry
class="wrap", and.wrap's padding was silently cancelling thesectionrule's vertical padding, so the sections had been glued together since the page shipped.section.wrapnow carries the vertical rhythm (2rem, 1.6rem on mobile). - Landing page: real CP437 text on the spec sheet and the button. The spec sheet and the Enter the museum button now render in a genuine IBM VGA text-mode font (VileR's Web437, CC BY-SA 4.0, self-hosted) instead of the general monospace — the two "machine talking to you" moments, while the Michroma wordmark and body stay as they were. The button label changed from "Boot the prompt" to "Enter the museum". Fonts newly credited in ATTRIBUTION: the VGA font, plus the Michroma and IBM Plex faces the feature article had shipped uncredited.
- The site has a front door now. The root
index.htmlwas a zero-second redirect that dumped first-timers straight atC:\>with no context. It's now a designed landing page: an amber CRT-lit hero with the wordmark and a Boot the prompt button, a CP437 spec sheet (33 systems · 327 games · nothing to install · 0 tracking), plain-language cards on what the site is, the two real bezel screenshots, and links out to the feature article, the wiki and the source. Zero JavaScript, zero external requests (fonts self-hosted, like the article), and — unlike the old redirect — it's mobile-friendly: the page reads and links fine on a phone, and the prompt keeps its own desktop-only guard. The green Boot the prompt button is the one loud thing; everything else stays quiet around it. - Doc sync + orphan audit (July 23rd pass — all repos). GenX-DOS clean: 33 bundles map 1:1 to 33 gamedoc dirs, nothing untracked, no strays. Tonight's churn verified fully landed — the retired
docs/tech_article.mdis gone and all sevendocs/fonts/*.woff2are referenced by the new HTML article; the CMOS<DEL>password gag leaves no trace in code or docs (biosSetupLock/armSetupWindowgone, wiki Project-Overview updated); the credit pill'sreadmelink is consistent everywhere. Counts unchanged and correct across README, four wiki spots, the social card (327 games / 33 systems), and the rewritten article — whose non-technical rewrite actually removed two recurring stale spots (the spelled-out engine and EJS-share counts are no longer in the prose). Sister repos audited too: Jackify README was stale on the v1.9.0 per-profile output folder (fixed in that repo); Wget-Downloader-Script clean, CI green, branch protection intact. Forks (atari800, jsbeeb) and dormant repos out of scope. - Article: the LGR provenance corrected. The rewrite had demoted the terminal's origin to "a fan tribute" — it was a feature built for the Lazy Game Reviews channel's own website.
- Feature article rewritten for the reader it's for. The prose now assumes exactly one skill: having launched a program on a DOS machine. The developer vocabulary is gone — no JavaScript, asyncify, cores, builds or CDNs — replaced with the user's-eye truth of each fact: the prompt is "a very careful drawing" of a DOS machine, emulators are "working replicas faithful enough that the games can't tell the difference", the repo weighs "about a hundred floppy disks' worth", and pads "drive the machine's own joystick port, just as it would have in 1985". The Monster Maze tape surgery stays (it's a story anyone can love); the asyncify war story and the release-process section retire to the wiki, which the article links for the curious. Structure, design, figures and the verdict box are unchanged.
- Feature article: the wiki gets a prose link. The "week-long fights" section now points readers at the per-engine war stories on the project wiki — restoring an on-site route to it after the credit pill's slot went to the article.
- The credit pill's
wikilink is nowreadme, pointing at the feature article. The bottom-centreGenX-DOS · licence · source · readmepill on every emulator page and the prompt now sends readers to the on-site article rather than the GitHub wiki. Because the article lives on the site itself, the link is resolved from the script's own URL instead of being hard-coded — so it lands correctly on localhost, on Pages, and in any clone. - The CMOS SETUP password gate is removed. Pressing Del during the POST pause no longer opens the password box (nor its three-strikes
System Halted!) — the boot now simply pauses five seconds and carries on. TheHit <DEL> if you want to run SETUPline stays on the POST as period set dressing. - Feature article: the opening now matches the real boot flow. The first paragraph still had the machine clearing to a bare
C:\>and waiting for input — behaviour the site doesn't have. It now ends where the boot actually ends: the menu draws itself and a greyC:\SYSTEMS>blinks beneath it, which is where the waiting-for-you line truly belongs. The second paragraph's now-redundant menu description folds away, leaving it to get straight to booting a C64. - The feature article is now a designed page, not a markdown file.
docs/tech_article.mdis retired in favour ofdocs/tech_article.html— the article set as a 1980s computer-magazine feature spread: Michroma headline, newsprint ground, process-ink crossheads and pull quotes, the two repo screenshots as captioned figures, a THE NUMBERS boxout, and a period review box scoring the site (GX VERDICT 94%). Served straight off Pages like everything else. The three typefaces (Michroma, IBM Plex Serif, IBM Plex Mono — 7 woff2 files, ~126 KB) are self-hosted indocs/fonts/, because the article about the site with no runtime network calls was not going to be the page that makes one. The README's narrative-read link now points at the live page rather than the repo blob. - Feature article: full accuracy pass. Every checkable claim verified against the repo. Three more corrections on top of the autorun/VGA pair: the "no
package.json" boast has been false since the npm packaging landed in v1.0.7 (reworded — it exists to ship the site, never to build it); the C64 boots over the burnt-orange 70s wallpaper, not wood-grain (the wood block is the Model 100's desk); and the ZX81 key filter is now a fallback six games opt into, so "its game pages" became "the game pages that need it". Confirmed accurate along the way: the AMIBIOS table text and the 64 KB memory-count steps, 138 MB/~450 MB, the two BBC bundles at ~25 MB as the largest, 14 bundles sharing EmulatorJS, and the "five rebuilt from source" claim — six engines are self-compiled, but jsbeeb was forked to be modified, which sits outside the article's "no suitable browser build existed" scope. - Feature article: two accuracy fixes in the opening. The menu has been autorun since the AUTOEXEC boot sequence landed, so "Type
menu" misdescribed the site — the launcher boots itself. And the prompt's sprite font is a VGA text mode, not CGA (the article already said VGA two paragraphs later, so it was contradicting itself). - Doc sync + orphan audit (July 22nd pass). Orphans clean: 33 bundles map 1:1 to 33 gamedoc dirs, no strays, no untracked files, and a two-way gamedoc↔manifest reconciliation across all 33 systems comes back with zero mismatches. Counts are unchanged because the three CPC swaps were 1:1 — 19 engines / 14 EJS / 33 sub-systems / 327 gamedocs / 360 shared-CSS pages / 16 bezels — and they verify correct in every place they appear: README, the four wiki count spots, the feature article's spelled-out "nineteen"/"thirty-three", and the social card's baked-in "327 games · 33 systems" (no re-render needed). Repo size still matches the article at ~138 MB checked out. ATTRIBUTION is engine-level so the game swaps don't touch it. One stale spot found, on the wiki's CPC page: its game-sourcing note still said we'd swapped Sorcery for Elite — Elite has since left the bundle, and the line credited it with Roland's loader (
run"ontherun) into the bargain. Rewritten around the French-release trap that actually recurred (Get Dexter), plus the four screens a candidate disc now goes through. - Amstrad CPC: Elite → Prince of Persia (audit). Elite's keyboard response was poor even on its static trading and chart screens, which rules out frame rate — and it isn't the dump either (the alternative on offer is the same release, in the fragile extended-DSK format and still carrying the cheat file). Typed input in Tau Ceti is crisp, so the fault is Elite's own, not the emulator's. Replaced with Prince of Persia (1990, Broderbund — Jordan Mechner), the English release, verified single-disc and clean. It is joystick-native, so it takes gamepad support through the emulated 9-pin port rather than synthesised keystrokes. Menu re-sorts by year: Prince of Persia lands at #9 between Rick Dangerous and 3D Construction Kit. Gamedoc written from the Broderbund manual's Amstrad pages — joystick first, with the CPC cursor cluster and Shift as its documented keyboard stand-in, plus the special keys read off the scanned pages (the OCR text had them badly scrambled).
- Amstrad CPC: Get Dexter → The Eidolon, and Elite's cheat file erased (audit). Get Dexter had been shipping unplayable — its launcher pointed at
run"disc, a file absent from the disc, and the disc itself was a truncated 85 KBEXTENDED CPC DSKthat hung the emulator regardless; four earlier passes missed it because the game sat behind Bomb Jack and was never launched. The only working dump proved to be the French Crafton & Xunk (whose keys differ from the English release), and the English edition exists only on tape, which this build can't boot — so the game is replaced rather than shipped in the wrong language. In its place: The Eidolon (1986, Activision / Lucasfilm Games, CPC conversion by P.A.W. Software) — a fractal-cavern descent in a Victorian inventor's machine, joystick-native so it gets USB gamepad support, with 1–4 selecting fireball colours. Same year, so the menu only re-sorts within 1986 (Tau Ceti to #5, The Eidolon #6). Its gamedoc is written from Lucasfilm's manual. Separately, Elite's disc carried a dormantCHEAT.BAS(infinite shields, fuel and missiles) alongside the game: the file is now erased from the image AMSDOS-style — directory entry deleted, its data block wiped, and the cheat text that survived in slack space beyondELITE.BAS's 384-byte end cleared too, leaving the game itself byte-identical and still playing. - Amstrad CPC: Bomb Jack → Tau Ceti (audit). Bomb Jack's disc turned out to be a cracked trainer — it boots to "Trainer From T.H.C. · Cracked 1987 · Unlimited Lives (Y/N)?", and the disc holds no clean copy — so it fails the accuracy bar the same way the Underwurlde snapshot did. In its place: Tau Ceti (1986, CRL, Pete Cooke), the ground-skimmer mission to shut down a runaway fusion reactor on a dead colony world (the standard release, not the enhanced Special Edition — the only standard copy to hand was itself a crack with a cheat mode, so a clean one was sourced). Same year, so the menu only re-sorts within 1986 (Get Dexter to #5, Tau Ceti #6). Its gamedoc is written from the CRL manual — both control modes (typed ground-mode commands, sixteen single-key flight controls), the day/night cycle that forces infra-red after dark, and the cooling-rod objective; the author credit and 1986 copyright are read from the game's own data, which settles a conflict with sources dating this release 1987. Its predecessor's gamedoc invented nearly everything: wrong keys entirely (arrows/Space, when the game uses Q/A/N/M/X), a "glide" that doesn't exist, an "S" pickup that isn't in the game, and a 5x combo bonus in place of the real 20-23 bomb chain scores.
- Gamepad Start button dropped sitewide. Removed the pad Start-button (button 9) mappings from every hand-built-engine bundle (Electron, ZX Spectrum, ZX81), and new games get none — the pad is gameplay-only now, with the keyboard for a game's title/start. Docs swept to match: the three controls pages, the tech article, the README's USB-gamepad section, and all 22 affected per-game gamedocs (Start clauses reworded where they carried info — Atic Atac's character choice, Elite's commander prompt, the games where button 0 doubles as start). Reverses the earlier "Start presses the title key" approach.
- BBC Micro: USB gamepad documented (audit — Snapper). jsbeeb natively maps a pad's d-pad to the standard Z/X/'// steering keys, so Snapper and other standard-scheme games are pad-playable with no shim. The BBC controls page gains a USB-gamepad note and Snapper's gamedoc notes the pad steers.
- ZX81: Mazogs replaced by 3D Defender. Swapped Mazogs for 3D Defender (New Generation, 1981 — M. E. Evans, the 3D Monster Maze author): a fast machine-code 3D cockpit shooter, defend the planet from marauding alien craft. Its unusual four-zone keyboard "joystick" (a straight up/down/left/right needs two key-zones at once) is driven on the pad by the shim's new multi-key directions — push the stick and it presses the right pair of keys; any face button fires a torpedo salvo. Controls, instruments and scoring documented from the game's own inlay. Menu slot 2.
- ZX81 key allowlist is now a fallback, not the default. The per-game filter that swallows stray keys (to stop an accidental keypress dropping the machine to BASIC) is reached for only where a game actually needs it — it can fight the pad, as it did on Mazogs. The six games that use it keep it; new games (3D Defender) get none.
- ZX81: Chess (Psion) replaced by the iconic 1K Chess, behind an opening submenu. Swapped the 16K Psion program for David Horne's legendary 1K Chess (1982) — a working chess opponent in 672 bytes, the most famous 1K program ever written. Both cassette versions ship (the computer opens with its king's pawn, 1.e4, or its queen's pawn, 1.d4), reached through a new 1K Chess submenu off the ZX81 games list — the first per-game submenu in the DOS menu tree. Gamedocs written from the game itself: you play Black, moves are entered in backward algebraic notation (rank before file, e.g. 7e5e), there's no castling/en passant/promotion, and — memory being what it is — you can watch the engine sift its candidate moves right on the board. ZX81 games list re-sorted by year to suit (1K Chess is 1982). The gamedocs also flag it as a single-session game — the ZX81 engine has no reachable save-state, so a position is lost when the tab closes.
- Social card refreshed and renamed (
docs/images/genx-social.png, wassocial-preview.png). Rendered from the site's own CP437 sprite sheets; its stats line reads327 games · 33 systems · 100% self-hostedand the menu shows Sega Game Gear, not the retired Vectrex. Re-upload via repo Settings → Social preview to update the card GitHub shows. - Doc sync + orphan audit (July 6th pass).
.gitignorecaught up with theemulators/→systems/rename (15/06) and the Mac removal (25/05) — the twoemulators/macplus/build-artifact ignores were dead, and thenode_modulesignore now points atsystems/. Orphan scan otherwise clean (the only untracked file is a local_paddiag.htmlpad-probe dev tool, never referenced, never shipped). Wiki gamedoc/page counts refreshed to 317/349 and the JtyOne typed-command tally to four, after the ZX81 1K Chess opening split added a game key. - Doc sync + orphan audit (July 5th pass). Orphan scan clean — every zero-reference flag is the known dynamic/vendored taxonomy, and a new two-way reconciliation across all 32 systems confirms every gamedoc matches a launchable game key and vice versa (only the VICE-family/PET
basickeys have no docs, by design). Two reachability fixes it surfaced: the ZX81 page now keeps?game=alongside the?tzx=rewrite, and the CPC page builds its controls link inline (both rewrites raced the deferred shared link script, which could send players to the generic controls page instead of the gamedoc). Controls pages for the Electron, Spectrum and ZX81 gained USB-gamepad sections; the Spectrum page's Kempston section is replaced with the truth (the engine emulates no joystick hardware — arrows press the CAPS SHIFT+5-8 cursor keys) and its Ultimate-layout note now says Sabre Wulf, not Pssst, swaps E/R; the ZX81 page drops a stale external pointer. README gains a USB-gamepads section; the tech article's engine count catches up (eighteen), the gamepad fight joins the war stories and Chuckie Egg joins the audit examples. - Save-state slot label: "empty" → "vacant" in both slot-menu variants.
- Doc sync + orphan audit (July 4th pass). Orphan scan clean (the only flags are the VICE-family
basicmanifest keys, which have no gamedocs by design). Tech article updated post-Vectrex: repo size re-measured (~135 MB checked out / ~445 MB cloned), fourteen bundles now share EmulatorJS, and the Vectrex examples (Mine Storm's eleventh slot, the fire-button anecdote) replaced with current ones. CPC docs updated for the new gamepad reality:controls.htmlno longer claims the 9-pin port is unemulated (per-game joystick mode + USB pads exist now), and the nine keyboard-driven games' notes say the game is keyboard-driven rather than blaming the emulator. - CPC: Knight Lore → 3D Starstrike. The bundled Knight Lore build boots straight into a lives-cheat offer — not the shipped experience, so it fails the audit's accuracy bar. In its place: Realtime's 3D Starstrike (1985), the Star Wars-arcade-style wireframe shooter, on its own single-game disc (the disc's catalogue carries only the game's three files; it boots directly via
run"3d). "3D Starstrike" sorts ahead of Elite within 1985, so menu slots #3/#4 swap. Gamedoc written around the verified joystick controls; the game never displays its keyboard key list, and the doc says so rather than inventing one. - Amstrad CPC: bezel scaled to full viewport height. Dropped the 120px wallpaper margin from the height cap — the CRT stack now fills 100dvh, making the canvas noticeably more legible.
- BBC Master: Firetrack → Bonecruncher. Firetrack's documented controls couldn't be reconciled with observed behaviour (the inlay's Return "fast fire" made no difference in play, and firing turned out to be automatic) — with the primary source and the running game disagreeing, the doc couldn't meet the site's accuracy bar, so the title was swapped out. In its place: Superior's Bonecruncher (1987, Andreas Kemnitz & Martyn Howard), the Boulder Dash-style skeleton-soap puzzler — same year, so the menu sort is untouched. Disc, menu, launcher, gamedoc-link map and gamedoc all updated; the gamedoc is written from the inlay and verified against the game's own controls screen (including the D/W music keys the inlay omits), with the 22-chamber password system left for players to earn. The old page described a side-scrolling lane-dodger with wheelies, credited to the wrong author — the real game is Kevin Edwards' behind-the-bike 3D championship racer on real-world circuits (the Master version adds circuits, graphics and Martin Galway music). Now documents the true keys (Z/X steer, BBC */? accelerate/decelerate in the PC-vs-BBC three-column layout, P pause, S sound, K keyboard/joystick), the green-light start (jump it and the bike stalls), top-six qualification across the sixty-rider field, and the 200-point knock-off bonus with the side-swipe vs rear-end collision rules.
- Doc sync + orphan audit (July pass). Orphan scan found no authored orphans — every flagged candidate is a dynamic-path mechanism (js99er builds
carts/<key>.rpk, JtyOne's loader appends.hextotapes/<name>.p, jsvecx'sroms/library is upstream-vendored). Synced the repo trees in the README and the wiki File-Structure page with the root files that post-date them (LICENSE.TXT, SECURITY.md,docs/, the npm/container packaging trio,.github/), fixed the wiki's per-emulator table still listing the PET under VICE (it runs Skibo's pet2001), and added the shared save-state / soft-button helpers to the wiki's_shared/listing.
Removed
- GitHub Packages (container + npm) retired for a plain download. The ghcr container image and the
@retro-jack/genx-dosnpm package are gone — needless machinery for a static site that now runs from a one-command launcher or any static host. Each release ships a zip of the whole site instead; unzip and runGenX-DOS.sh(Linux/macOS) orGenX-DOS.bat(Windows).Dockerfile,index.js,package.json, the publish workflow and the placeholder Dependabot config are removed;build-portable.shnow builds the shipped site (identical to the portable export).
[1.3.2] - 2026-07-16
Fixed
- BBC controls pages named a URL parameter that doesn't exist. The auto-boot hyphenation pass reached inside a
<code>span and rewrote the literal?autobootlaunch param to?auto-booton both BBC pages — so anyone following the instruction got a disc that didn't boot. The prose verb hyphenates; the parameter must not. Caught by an audit cross-checking the docs againstfs.js, which is the runtime truth. The same pass also missed oneAutoboots.(capitalised at a sentence start, in the Apple ][+ page's Castle Wolfenstein row); it's dropped rather than hyphenated, per the auto-boot preamble rule.
Changed
- Gamedocs: dropped the auto-boot preamble. A game's "Getting started" list no longer opens by announcing that the cart or disk auto-boots — it is obvious from clicking the game, and on a page like Star Raiders' it read "Cart auto-boots to Star Raiders". All 109 affected gamedocs swept via an explicit per-variant map (40 distinct wordings, no regex guessing): 96 bullets keep whatever actually mattered (the focus note, "press 2 at the TI title", "press F4 Start to choose a mission"), 13 that said nothing else are gone. Detail wrapped inside those clauses was rescued rather than binned — the C128 pages' VDC 80-column mode, the PET's Color PETSCII start, a disk that multi-loads, and the BBC racers' instruction screens. The CPC's
run"…launch commands went with them: every CPC game auto-runs and the bundle's BASIC entry boots with nothing in the drive, so the command was unreachable trivia. - The auto-boot preamble goes from the controls pages too. Follows the gamedoc sweep: a per-system page no longer announces that its games auto-boot either (the Apple ][+'s "Boots straight in", the C64's "the bundled disk image auto-boots", the MSX pages saying it twice, the VIC-20 intro, and the CPC's paragraph on the boot-command mechanism — which also re-stated the
run"…commands just removed from the gamedocs). Eight pages. What a reader can't infer is kept and reworded off the verb: the BBC pages still say to drop?autobootfor a clean BASIC prompt, and the CPC's BASIC entry still explains that it loads no game. - Elite (CPC) gamedoc: audit pass. Corrected the saving story — the earlier text implied no persistence, but the CPC bundle has full save-state support (the 18/06 WASM rebuild), so the doc now points at the five-slot save/load buttons with a dock-first tip. Tables restructured to the BBC docs' pattern: a combined flight table, the dual-purpose 1–4 number keys as an in-flight/when-docked three-column table, information screens, and game controls — removing duplicated rows and the "(or joystick)" asides (this bundle is keyboard-only).
- Roland on the Run (CPC) gamedoc rewritten from the game's own operating instructions. The old page invented a different game entirely (sewer platformer, "the Cat", cheese collecting, five levels, cursor keys). The real game: control the train's speed with </> and leap lane-by-lane with Z/X/C from train to two traffic lines to the road hideouts; Esc holds, any key restarts; setup prompts ask for 1–255 lives and a starting level 1–9. Credited to Said A. Abouelhassan (Epicsoft/Egypt 1984, via Amsoft); the unverified "Roland the Rat" mascot claim dropped.
- Bruce Lee (CPC) gamedoc: real keys from the disc + title screen. The old table claimed cursor keys — the game actually uses A/Z up-down, </> (comma/period) left-right, Space punch/kick, P pause with Enter to continue, Esc to quit. Title-screen options documented (A toggles 1/2 players, B gives the Green Yamo to the computer or a second player) and unverifiable strategy claims dropped.
- Ballistix: year corrected to 1989 and gamedoc rewritten from the inlay. The Master menu had it as 1990 — the BBC release is ©1989 (confirmed on the game's own title screen), so it re-sorts to #8 ahead of Holed Out, with Nevryon back at #10. The old gamedoc invented the mechanic ("nudge balls with directional taps", goals to 10, "100+ playfields", a deflector/anti-grav/damper tile table): the real game fires ball streams from a movable firing arrow at the puck, three goals win a level, 29 levels one-player / 30 two-player, one lost level terminates to level 1 (four-letter passwords resume — earned in-game, not listed). Real keys documented from the key screen + inlay (Z/X/Q/A + Tab; Shift+COPY pause, Shift+DELETE restart, S/Q sound when paused, Shift+ESCAPE quit; C redefines) and both tile tables rebuilt from the inlay (ground features + shootable tiles).
- Holed Out gamedoc rewritten from the inlay. The old page invented the author ("Mark Reid" — it's Gordon J. Key), "four courses" (there are two: Cone Links and Pine Isles; the others were the Extra Courses packs), a three-press swing meter,
'//club keys and F1/F2 view keys. The real scheme is Z/X/Return through three stages — club, aim, then a power bar sweeping 19%→max→back where Return strikes and striking with Z hooks / X slices — plus the four skill levels as a wind-and-lie dial, Ctrl+Q on the scoreboard to abandon, and F12 (BBC BREAK) soft-resetting to the option screens from anywhere (verified in-game). - By Fair Means or Foul gamedoc rewritten from the Play It Again Sam 12 inlay. The old page invented its controls (Return "head clinch", Shift "kidney punch", biting, a three-warning disqualification and a ref "gaze icon"). The real scheme is the inlay's KY1 nine-key square (Q/W/E, A/D, Z/X/C) with Escape as Fire switching guards/footwork to punches and the four real fouls (head butt, knee, kick, groin punch), plus the full function-key set (F1/F2 start, F3/F4 control selection, F5 pause, F6 crowd, F7 sound FX, F8/F9 Master-only music volume, f0 quit). Mechanics corrected to match: 15 rounds or 5 chances, knock-outs only end the round, the corner silhouettes are the chance count and the green/amber/red foul-safety meter, and the auto-hold costs a chance if repeated. Authors credited (Michael & Terry Simpson). Controls verified against the game's own controls screen (all correct); table converted to the PC/BBC three-column layout, author credit added (Martyn R. Howard) and the title-screen Space/Return convention documented.
- Gamedocs: dropped the "keys from the game's own instructions screen" preamble from the BBC key-mapping notes (Revs, Commando) — the note now opens directly with the key facts.
[1.3.1] - 2026-07-14
Added
- Boot: the POST screen's
<DEL>prompt is no longer just for show. Press Delete during the post-POST pause and you'll meet the CMOS password prompt (white-on-blue, six characters, asterisk echo) — drawn in the boot sequence's own CP437 sprite font. No password unlocks it; the third wrong attempt turns the box red withSystem Halted!and only a reload reboots the machine. Exactly as AMI intended. Esc backs out to the POST with the boot pause re-armed — but there's no backing out of a halt. - "Your Data" wiki page + README link. A new wiki page documents exactly what GenX-DOS persists to a user's browser (save-state slots in IndexedDB, the Model 100's battery RAM and EmulatorJS cartridge saves / settings in localStorage), when each is written, and that nothing leaves the machine — no cookies, accounts or telemetry. Linked from the README's Documentation list, the wiki sidebar, the Project Overview's save/load section, every bundle's
controls.htmlfooter (33 pages), andSECURITY.md.
Changed
- Auto-boot hyphenation unified. The media-boot verb in the "Getting started" steps was split (
autoboots/auto-boots,autostart/auto-start); all now hyphenated to match the already-consistentauto-loads/auto-runs(83 files). The Cart/Disk/Tape media distinction and the boots-vs-loads verb stay — those are meaningful. (The save-slot and keyboard-only notes were reviewed and deliberately left: their two wordings each fit their context — per-systemcontrols.htmldetail vs per-game brevity for save slots; game-design "keyboard-driven" vs engine-limit "keyboard-only" — so they aren't drift.) - Getting-started "focus" note standardised sitewide. The "click to give it keyboard focus" instruction had drifted into ~15 wordings across platforms (
click the canvas first,…so the emulator receives keyboard input,Click the screen once so the keyboard has focus,click the screen for focus, …). All 170 gamedocs + controls pages now use one line — "click the game area to enable sound and controls" — which is element-agnostic (canvas or screen) and more accurate (the click unlocks both audio autoplay and keyboard input). Game-specific text fused into those steps (media auto-boot clauses,press Enter (Start), per-game start flow) was preserved. - User-facing text: sitewide terminology + punctuation consistency pass. Normalised across the 327 gamedocs + 33 controls pages:
D-padcasing unified (was a mix ofD-Pad/d-pad/D-pad→ allD-pad, 139), 11 stray curly apostrophes → straight, key references<kbd>Escape</kbd>→<kbd>Esc</kbd>(8), and the lonejoypad→gamepad. 124 files touched. (controllerdeliberately left alone — those 20 describe the original console hardware, e.g. "the ColecoVision controller had a 12-key keypad", not the USB gamepad.) .gitattributes: stop Linguist mis-labelling the Model 100 docs as Stata. The bundle'sADRS.DO/NOTE.DO(the Model 100 TEXT app's own document format) were being counted as the Stata language on the repo's Languages bar; markedlinguist-detectable=false. (WebAssembly still can't appear — the.wasmcores are compiled binary, which Linguist excludes; only.wat/.wasttext would count.)- SECURITY.md points at the exact reporting button. The vulnerability-reporting link now names the Security → Advisories page and gives its direct URL — the Report a vulnerability button lives there, not on the Security tab's landing page, so reporters don't hunt for it. (Private vulnerability reporting is enabled on the repo.)
[1.3.0] - 2026-07-07
Added
- Tandy TRS-80 Model 100 — a new platform and a new engine. New
systems/m100/bundle for the 1983 portable, built from Stephen Hurd & Ken Pettit's VirtualT by extracting its FLTK-free 8085 / HD44102-LCD / keyboard core to WASM behind a small headless SDL2 frontend (engine #19, 33 sub-systems now — an acknowledgement, not a fork, since the GUI/IDE/debugger are stripped away). Reached from the Tandy computers menu as slot #3 ("Model 100 (Portable)"), framed by a Model-100-on-a-desk bezel. Ten BASIC games: eight hand-transcribed from David Busch's 25 Games for your TRS-80 Model 100 (Codebreaker, Invisible Maze, Road Rally, Paper Rock Scissors, Slot Machine, Skydiver, Worm Hole, Bowling) plus Four Seasons Solitaire and ELIZA from club100 — each auto-boots via?game=and returns to its menu on close. An eleventh entry, Startup Menu, boots the bare machine, and it comes alive: a live RTC clock (real date and time, Y2K-correct — the ROM shows 2026 fine) and battery-backed RAM — files, address-book and scheduler entries, and typed-in BASIC programs persist to browser storage between visits, exactly like the real machine's battery-backed memory (games stay ephemeral). Full keyboard including the Caps Lock toggle and the PASTE / LABEL / BREAK command keys; ADDRSS and SCHEDL are seeded with emptyADRS.DO/NOTE.DOso they open instead of erroring. All ten gamedocs, plus a controls page sourced entirely from the Model 100 owner's manual (the three apps, file management, record formats). The platform was proposed by dplassgit in discussion #2; VirtualT, Busch's book, dplassgit's suggestion and the owner's manual are all credited in ATTRIBUTION.md.
[1.2.0] - 2026-07-03
Added
SECURITY.md. Short security policy — scope (static client-side site, no backend/user data), supported versions (latest release + live site), and private vulnerability reporting via the GitHub Security tab or email.- Social preview image (
docs/social-preview.png). The repo's GitHub social-preview card — a 1280×640 image rendered from the site's own CP437 sprite sheets (prompt/img/f12.*.png), with the glyphs vertically stretched to match the live terminal. Committed for safekeeping; also set as the repo's Social preview via Settings. - Wiki link in the bottom-centre credit. The "GenX-DOS · licence · source" pill on every emulator page now also links the wiki (
systems/_shared/genx-repo-link.js). - BBC COPY soft button (jsbeeb). The BBC's COPY key has no obvious PC equivalent (jsbeeb maps it to End), so the BBC Micro and Master bundles now show a clickable COPY button (top-left, in the GenX button style) that sends it — handy for games where COPY is "continue", e.g. Manic Miner. New shared
systems/_shared/genx-bbc-copykey.js.
Changed
- LICENSE.TXT: fixed a header typo ("EXPRESSCE" → "EXPRESS" disclaimer of warranty). No change to terms.
- ATTRIBUTION: corrected two BIOS paths. The Intellivision EXEC/GROM and Odyssey²
o2rom.binlive at their bundle roots (systems/intv/,systems/odyssey2/), not theroms/subdirs the table listed. - Tech article: corrected the repository-size paragraph. The
jsbeebbundle was split intobbcmicro/bbcmaster, so the "441 MB, with jsbeeb alone weighing 25 MB" line had gone stale. Updated to the current footprint (~150 MB checked out, ~460 MB cloned with history) with the two BBC builds and jsvecx as the heaviest bundles. - Revs gamedoc: added the Shift+f-key race options. Audited against the game's keyboard overlay — the driving keys were already right, but the doc was missing the shifted function-key controls: keyboard/joystick select, volume, retire, return to pits and freeze/resume.
- BBC/Electron gamedocs: authentic keycap notation. Acorn keys now render true to the real keyboard in the existing dark theme — the :/* key as a single dual-legend cap (it was wrongly shown as two separate keys), and the red function keys in
f₀italic-plus-subscript form. Scoped viabody.acorningenx-controls.cssand applied across every BBC Micro, BBC Master and Electron gamedoc and controls page. - BBC Master: Last Ninja 2 → Nevryon. Sequel sweep finished for the Master. Last Ninja 2 (a sequel) out; The Fourth Dimension's Nevryon (1990) in — an R-Type-style horizontal shooter. Both 1990, so it stays at #9; disc, menu, launcher, link, gamedoc-link map and gamedoc updated. Controls and mechanics taken from the game's own instruction pages (hold Return for constant fire, Space recalls the gun droid, bonus-pod weapon order); level-skip passwords left for players to earn.
- BBC Master: Repton Infinity → Palace of Magic. Sequel sweep continued. Repton Infinity (a sequel) out; Superior Software's Palace of Magic (1987) in — a Citadel-style flick-screen platform-adventure. As a 1987 title it stays at #6 (year order still ascending); disc, menu, launcher, link, gamedoc-link map and gamedoc updated. Controls researched from the game's instructions (Z/X, ' / / for up/down, Return jumps, Space picks up/drops).
- Gamepad-support notes across keyboard-only emulators. Audited every engine's gamepad handling and added a "keyboard-only — USB gamepads aren't supported" note to all gamedocs on the seven engines that don't read a gamepad (Apple I, Amstrad CPC, Acorn Electron, ZX Spectrum, Oric, Commodore PET, Vectrex). The Vectrex docs additionally had a bogus "Gamepad" control column removed — that engine never had one. The note uses a new
.note-plainclass (no divider rule above it). - BBC Master: Repton 3 → Galaforce. Sequel sweep continued. Repton 3 (a sequel) out; Superior Software's Galaforce (1986) in — Kevin Edwards' Galaga-inspired fixed shooter. Both 1986, so it's a straight swap at #2; disc, menu, launcher, link, gamedoc-link map and gamedoc updated. Controls researched from the game's instructions (Z/X sideways, ' / / for up/down, Return fires).
- MSX2: King Kong 2 → Bubble Bobble. Sequel sweep continued. King Kong 2 (a sequel) out; Taito's Bubble Bobble (1987) in — the language-agnostic co-op bubble-'em-up. (Metal Gear, the obvious pick, was already in the MSX2 menu; Golvellius turned out to be Japanese/disk-only on MSX, so Bubble Bobble is the clean cartridge fit.) It sorts to #3 (Vampire Killer moves up to #2); ROM, menu, launchers, link and gamedoc updated. Controls researched from a gameplay guide — the MSX quirk is that jump is a button (L Alt), not up.
- NES gamedoc control-accuracy pass. Re-checked the Kid Icarus / Mega Man / The Legend of Zelda control tables against their manuals (they'd originally been written from memory). Kid Icarus was already right; Mega Man gained a SELECT = plain pause row (the classic Yellow Devil damage trick, unique to MM1) and a clearer START = weapon-select note; Zelda's SELECT row was corrected to note it also pauses.
- Game Boy: Wario Land 3 → Final Fantasy Adventure. Sequel sweep continued. Wario Land 3 out; Square's Final Fantasy Adventure (1991) in — the first Mana-series action-RPG. It sorts to #5 (Kirby / Link's Awakening / Donkey Kong / Pokémon each shift down one);
games.json, launchers, link, ROM and gamedoc updated. The Game Boy now has no numbered sequels. - Game Boy: Metroid II → Gargoyle's Quest. Sequel sweep continued. Metroid II: Return of Samus out; Capcom's Gargoyle's Quest (1990) in — the Ghosts 'n Goblins spin-off starring Firebrand. It slots at #4 (between the 1989 block and Kirby);
games.json, launcher, link, ROM and gamedoc updated. - Atari Lynx: Gauntlet III → Zarlor Mercenary. Sequel sweep continued. Gauntlet: The Third Encounter out; Epyx's Zarlor Mercenary (1990) in — the buy-and-blast vertical shooter. Both 1990, so it's a straight swap at #6;
games.json, launcher, link, ROM and gamedoc updated. - Orphan + stale-doc audit. Cross-checked gamedocs, ROMs, discs and UEFs against runtime references and removed the one real orphan — a leftover
ManicMiner.ssdin the BBC Master dist disc library. (Everything else the scan flagged was legitimately referenced by mechanisms it didn't model: xroar'sautorunkey, system ROMs, the Apple I?tape=param, and BASIC-prompt launchers.) Synced docs to current state: dropped the stale "Manic Miner" COPY-button example (README + jsbeeb wiki page — it left the BBC), and corrected the Electron snapshot count to 6 across README, tech article and the wiki (File-Structure / elkjs-Electron / Virtual-Filesystem). - NES: Super Mario Bros. 3 → The Legend of Zelda. Sequel sweep — the third Mario on the NES (missed by the first pass because its code,
MARIO 3, had a space) swapped for Nintendo's 1987 open-world original. Zelda (1987) sorts to #7, closing the 1987 block (Contra, Tetris and Final Fantasy each shift down one);games.json, launcher, link, ROM and gamedoc updated. The NES now has Super Mario Bros. and no numbered sequels. - Acorn Electron: Repton 2 removed (now six games). Continuing the sequel sweep — but dropped rather than replaced: ElkJS only bundles memory-snapshot UEFs, and a swap-in would need a snapshot that doesn't exist, so for once consistency beat adding a game. Menu, number launcher, link,
repton2_snap.uef, gamedoc and the play.html game map all removed; README and tech-article snapshot counts updated (7 → 6). - NES: Mega Man 2 → Mega Man. Sequel sweep continued — swapped the sequel for Capcom's 1987 original. Mega Man (1987) sorts to #4 in the 1987 block (Metroid, Mike Tyson's Punch-Out!! and Contra each shift down one);
games.json, launcher, link, ROM and gamedoc updated. - NES: Super Mario Bros. 2 → Kid Icarus. Sequel sweep continued. Out goes Super Mario Bros. 2; in comes Kid Icarus (1987), Nintendo's Metroid-engine angel platformer. It sorts to #3 in the 1987 block (Metroid, Mike Tyson's Punch-Out!! and Contra each shift down one);
games.json, launcher, link, ROM and gamedoc updated. - Atari 7800: Pole Position II → Desert Falcon. Start of a sitewide sequel sweep — swapping numbered sequels for non-sequel games. Out goes Pole Position II; in comes Atari's Desert Falcon (1987), the isometric falcon shoot-'em-up. It sorts to #6 in the 1987 block (Xevious moves up to #5);
games.json, number launcher, link and gamedoc updated, and the Pole Position II ROM removed. - BBC Master: Stryker's Run → Commando. Dropped Stryker's Run because its controls can't be fully documented — the Master build uses user-definable keys with no on-screen key list, and the binary reads them in a relocated, IRQ-based scanner (verified by disassembly), so the aircraft enter/exit bindings are undocumented anywhere. Replaced it with Elite Systems' Commando (1985, BBC conversion by Trevor Harwood, from Capcom's arcade original) — a run-and-gun in the same spirit but with a tiny, fully-visible control set (the game's own instructions file lists Z/X/
*/?/Return/Shift). Commando (1985) sorts to #1, the same slot Stryker's held, so the rest of the menu is unchanged. Disc, number launcher, link, gamedoc-link map and gamedoc updated; the orphanedStrykersRun.ssdwas removed from both dist disc libraries. Also corrected the BBC Master controls.html intro (it wrongly described a 1981 Model B, not the 1986 Master), and dropped redundant glyph-name annotations ("(apostrophe)", "(slash)", "(comma)", "(period)", "(backquote)") from gamedoc control tables across all platforms (BBC Micro/Master, Electron, C64, Spectrum). Semantic annotations that say what a key does — "(Fire)", "(Start)", "(Select)"/"(Reset)", direction words, gamepad/joystick alternatives — were kept. - BBC Micro: Manic Miner → Revs. Replaced Manic Miner (1984) with Geoff Crammond's Revs (Acornsoft, 1985) — his landmark Formula Three simulation and the ancestor of the Formula One Grand Prix series. Manic Miner already appears on the Spectrum bundle and is ubiquitous across 8-bit platforms; Revs is far more distinctive to the Beeb. Year-ascending re-sort: Citadel and Repton shift up to #4/#5 and Revs lands at #6; the menu echo block, number launchers, the
?disc1=Acornsoft/Revs.ssdlink, the gamedoc-link map and the COPY-button example were updated, with a new gamedoc. The Spectrum Manic Miner is untouched. - C64: Hunchback → Attack of the PETSCII Robots (shareware). Replaced Hunchback (1983) with David Murray's Attack of the PETSCII Robots (2021) — the official free C64 shareware build (2 of the full game's 13 levels, single 1541 disk; manual/notes stripped). With the year-ascending order, Boulder Dash through Wizball shift up one and PETSCII Robots lands at #10; the menu echo block, number→code launchers,
games.json, the gamedoc and ATTRIBUTION were updated to match. - "This emulator" across player-facing docs. Adopted a doc-voice rule: gamedocs and the per-system controls.html pages no longer name the specific engine (jsbeeb, ElkJS, apple2js, JSVecX, gambatte, XRoar, EmulatorJS, VICE, atari800, tiny8bit, etc.) in descriptive or instructional text — they say "this emulator", since players don't need the implementation detail. The upstream credit lines at the foot of each controls.html are kept (and js99er / Electron, whose only credit was in the intro, gained a proper credit note). Engine names otherwise stay only in CHANGELOG / README / ATTRIBUTION / wiki. Console names (e.g. "Atari 7800 ProSystem") are unaffected. A follow-up made the sweep exhaustive across every engine name: VICE in the C64-family gamedocs, the apple1/apple2 intros (which spelled the engine "Apple ][js" and named the author), and the remaining libretro, core and AltirraOS references in controls.html body text. Credit lines keep their engine names; no engine name remains anywhere else in player-facing prose (the Scroll-Lock notes no longer cite the internal
genx-vice-softkeys.jspath). - Electron menu: Cybertron Mission re-dated 1983 and re-sorted. Corrected from 1984 (Wikipedia); it's now #1 (alphabetically first among the 1983 titles), pushing Snapper / Starship Command / Boxer down one. Number→game launchers remapped to match.
- Doc sync + orphan audit. Orphan-file pass found no authored orphans — every shared script/style, bezel, texture, gamedoc and font sprite is referenced (the f12 sprites and jsvecx thumbnails are built via dynamic paths); the only unreferenced files are vendored (apple2js PWA icons, one jsvecx ROM cover) and left in place. Fixed stale README text — dropped the removed VICE RUN/STOP clickable button (now keyboard-only) and documented the BBC COPY and TRS-80 CLEAR buttons. Added a "positional keyboard gotcha" section to the jsbeeb and Electron wiki pages (BBC/Electron
:/*→ PC apostrophe,@→[, COPY → End/Home, f0 → F10). A follow-up pass after the Electron trim confirmed no dangling references to the dropped games and no new orphans, recorded ElkJS's local patches (display row-doubling, the audio resume + 25% mix) in ATTRIBUTION, and corrected the Electron wiki bundle layout (nogames.json/games/subdir — 7 memory-snapshot UEFs at top level). - Acorn Electron canvas shrunk 5%. The ElkJS canvas now sits at 78.69%×76.69% of the bezel (down from 82.83%×80.73%), re-centred (left/top nudged to 10.96%/10.97%) so it shrinks toward the same point inside the Acorn monitor cutout.
- BBC Micro menu: Jet Set Willy re-dated to 1986 and re-sorted. The menu listed Jet Set Willy as 1985; the Tynesoft BBC release is 1986, matching the corrected gamedoc. With the year-ascending order, Repton (1985) moves up to #6 and Jet Set Willy (1986) drops to #7; the number→game launchers were swapped to match. Uridium re-dated 1986 → 1987 to match its title screen (A.I.M.'s BBC conversion; the Graftgold original is 1986) — it stays at #9 between Thrust (1986) and Exile (1988), so no reorder.
Removed
- Orphan disc cleanup — BBC bundles. The BBC Micro and BBC Master jsbeeb bundles are separate
dist/trees that had each accumulated the full 20-disc library, while each menu only loads its own 10. Removed the 18 cross-bundle discs (9 per bundle) that no menu references — no functional change; each bundle now carries exactly the discs its menu links. - Acorn Electron trimmed to the 7 games ElkJS ships. Dropped Hopper, Chuckie Egg and Frak — they were extras added beyond upstream ElkJS's bundled set, and the only versions available for them were cassette tapes (no snapshots exist, upstream or anywhere). Rather than mix instant-snapshot and real-time-tape loading, the Electron now carries exactly the 7 upstream snapshot games: Snapper, Starship Command, Boxer, Cybertron Mission, Citadel, Elite, Repton 2. Removed their tape UEFs, gamedocs, menu entries and number→game launchers, renumbered the menu (BASIC prompt now #8), and corrected the counts in the README, tech article and wiki (Electron is the one system with 7, not 10).
- VICE RUN/STOP / RESTORE on-screen buttons. Dropped the C64-family soft buttons — RUN/STOP and RESTORE aren't in-game keys (their real uses are breaking a program at the BASIC prompt and the RUN/STOP+RESTORE reset), so they were UI clutter. The keyboard routes stay: Scroll Lock / Pause → RUN/STOP, and Page Up → RESTORE (libretro default).
Fixed
- DOS prompt Backspace. The command line couldn't delete typed characters. The old handler sniffed the browser — simulating a
keypresson non-Firefox and relying on Firefox to firekeypressfor Backspace — but modern browsers no longer firekeypressfor non-printable keys, so on Firefox nothing happened. Backspace now deletes directly inkeydown(which fires everywhere), still guarding the'p'-classed prompt prefix / printed output so only typed input is erased. - Acorn Electron sound. ElkJS's
soundToggle()resumes the AudioContext only on its first call, so games could end up silent (the context never resumed without a real user gesture). Added an idempotentelkjs.resumeAudio()and hadplay.htmlretry it on every user gesture (keydown / pointer / touch) alongside the window.open activation, so sound reliably starts. Output is mixed down to 25% insound.js(the raw ±1 square wave was painfully loud). - BBC Micro / Master audio auto-unlock and visible prompt (jsbeeb). Replaced the fixed audio-unlock burst with a poll-loop that re-fires until audio actually resumes, covering a cold load that lands past the old 2 s cutoff, so Chromium/Brave start sound on launch again. Firefox won't resume an opened tab's audio from a synthetic event, so its "suspended audio — click for sound" prompt is now pinned as a fixed banner across the top of the window (it was buried behind the bezel) to make the required click obvious.
- Elite gamedoc corrections (BBC Micro + Master). Documented the dual-purpose function keys from the original control card (F10/F1–F3 are cockpit views in flight but Launch / Buy / Sell / Equip when docked); fixed the swapped F4/F5 (F4 = long-range galactic chart, F5 = short-range), the wrong "F1 sets a target" (F1 is rear view), and the startup flow (the real prompt is Load New Commander (Y/N)? — N for the default Commander Jameson). Replaced the false "disc save survives between sessions" claim with a note that the disc is read-only in the browser, so use the save / load buttons to persist progress.
- Implied-save-persistence sweep across gamedocs. Audited every save/load reference: EmulatorJS bundles genuinely persist (SRAM via IDBFS), but standalone engines don't. Corrected the docs that implied otherwise —
bbcmaster/holedout,bbcmaster/reptoninf,bbcmicro/exileandcpc/3dkitnow point at the load/save buttons (those engines have them), whilejtyone/blkcryst,jtyone/chessandpet/advlandnote plainly that the save is lost on closing the tab (no save-state on those engines). Where a save-state-capable engine is the answer, the docs point players at the save/load menus. - Thousands separators in gamedocs. Switched the space-style thousands separator to commas (e.g. "6 400 kills" → "6,400 kills", "2 048 planets" → "2,048") across the Elite, Chuckie Egg and Lunar Lander docs. Left the Punch-Out! "007 373 5963" Tyson code untouched (it's a code, not a quantity).
- BBC Master Elite gamedoc accuracy pass. Corrected against bbcelite.com: publisher is Acornsoft 1986 (dropped the erroneous "Imagineer"); the flicker-free ships come from the Apple II version's ship-drawing algorithm, not 65C12 "double-buffering" (and the 65C12 is no faster than the BBC B's 6502); removed the unfounded "extra cockpit colours / palette switching via 128K RAM" claim; and fixed the mission list — there is no "Cougar" mission and the Trumble mission is actually absent (Constrictor + Thargoid remain). Added the genuine Master differences (fractional kill scoring, coloured laser sights, energy-bomb lightning storm, updated sound + volume control). Standardised the decelerate key on ? to match the BBC Micro doc.
- Electron Elite gamedoc accuracy pass. Corrected against bbcelite.com: year is 1984 (was 1985); dropped the unverifiable "Electron port by Andy Onions" and the irrelevant "no Mode 7" (the real constraint is no 6845 CRTC); fixed the startup prompt (Load New Commander (Y/N)?); added the dual-purpose function keys and fixed the swapped/mislabelled Alt+4/Alt+5 charts. Removed two tips describing features the Electron lacks — there are no Thargoids and no suns (so fuel scooping is cargo-only) — and replaced the "one fewer colour / save files interchangeable" section with the actual cuts (no split-screen, suns, Thargoids; fewer ships; slower) plus a no-persistence note (ElkJS has no save-state button). Decelerate standardised on ?.
- No-save games now point at the save/load menus where the engine supports it. Games with no in-game save on a save-state-capable engine now tell players to use the menus —
cpc/chasehq(was "no save state"),xroar/canyon("three lives, no checkpoints"), plus the Manic Miner / Exile tips. Games with their own way to preserve progress are left alone —jsnes/metroid(password save),jsnes/smb(continue code),apple2/karateka(apple2js has no save-state button). - Manic Miner (BBC Micro) gamedoc. Corrected the converter credit — the BBC port is by D.J. Coathupe, not "Andy Williams" (per the TobyLobster disassembly) — and the controls: the BBC version moves with Z/X and jumps with Enter (verified in-emulator), not the Spectrum's Q/W/E/R… multi-key layout the doc had cloned. Added the title-screen keys too — Q/S sound off/on, Backspace (BBC Delete) freeze, End or the COPY button (BBC Copy) continue. Cavern list verified correct.
- BBC Micro / Master controls.html: COPY key mapping. Corrected COPY from Insert to End — jsbeeb maps End→COPY (Insert isn't in its keymap) — and noted the new COPY button.
- Citadel (BBC Micro) gamedoc. Fixed the objective — it's five hidden crystals to find and return (not "Cube — one of 16"; confirmed Wikipedia/Superior 1985) — and rewrote the controls to match the in-game "select which key layout" screen: four selectable layouts plus joystick, with layout 1 being Z/X (left/right), /? (up/down), Return (action/jump) and Space/Shift (cast spell / use), dropping the fabricated jump/use/sound/pause rows. Also noted that the BBC and ? keys map to the PC apostrophe ' and / in jsbeeb (the : * key sits on the apostrophe), so the table lists both the PC key and the BBC key.
- BBC
*/:key now listed as the PC apostrophe across all jsbeeb gamedocs. The BBC : * key isn't reachable by pressing PC:(Shift+;) in jsbeeb — that produces BBC+— so docs that listed:/*as a control were unusable as written. Every BBC Micro / Master gamedoc that uses it now lists it as the apostrophe ' (jsbeeb's mapping) with an explanatory note:holedout,snapper,uridium,reptoninf,firetrak,crazee,bfmof,ninja2,ballistx,stryker,repton3(pluscitadel,jetwilly,reptonalready done). The BBC Micro / Mastercontrols.htmlkeyboard-fallback note now states the mapping too. - Repton (BBC Micro) gamedoc. Corrected the movement keys — Repton uses Z/X and the BBC /? keys (up/down), which jsbeeb maps to the PC apostrophe ' and / (the doc had the unshifted
://with no PC-key guidance). Added the title-screen keys read from the game itself — Space play, P password, M map, S/Q sound, D/W music, Return back to title, Esc kill yourself. Replaced the false "pick any screen A–L at the start" step and the save-state tip with Repton's real progress mechanic: a per-screen password* system (so no save/load-button pointer — password saves are exempt). - Snapper (Acorn Electron) gamedoc. Corrected the author — Snapper was written by Jonathan Griffiths (an Acornsoft launch title), not "Christopher Beale". Replaced the unverified "Sour Faces" enemy name with the generic "ghosts" (no source confirms that name). Electron year (1983) confirmed.
- Elite (Acorn Electron) gamedoc. Fixed the function-key numbering — it had been cloned from the BBC's f0-based keys and listed as Alt+0…Alt+9, but the Electron's FUNC keys are 1-based, so each shifts up one: Front view/Launch = Alt+1 … Status = Alt+9, Inventory wrapping to Alt+0 (charts now Alt+5/Alt+6, market Alt+8; getting-started updated to match). Also rewrote the clunky, repetitive save note into one clear paragraph: Elite saves to tape on real hardware, but the read-only snapshot can't persist, so every visit starts as Commander Jameson.
- Repton 2 (Acorn Electron) gamedoc. Corrected a fabricated premise (verified against Wikipedia): Repton 2 has no "time capsules" / time-travel — those were invented. It's one continuous interconnected world linked by transporters with no save, so it must be done in a single sitting (the hardest Repton); you win by collecting all jigsaw pieces ("Repton 2 is ended"). Added the real mechanics — spirits (guide into cages → diamonds), skulls, meteors, keys/safes — fixed the getting-started "cursor keys" (it's Z/X + apostrophe/slash), and dropped the unverified Return/S/Esc secondary-key rows pending an in-game keys screen. Author (Tim Tyler) / year (1985) confirmed.
- Citadel (Acorn Electron) gamedoc. Same corrections as the BBC version: replaced the fabricated "Cube — one of 16" with the five crystals to find and return, and fixed the controls — Z/X left/right, '// (the Electron */? keys) up/down, Return action/jump, Space/Shift cast spell (was a bare Z/X/Return/Space scheme). The snapshot boots into the game's room slideshow (an attract demo) rather than a title/key-layout screen, so the doc now says press Return to start playing (not the old "press Space at the title"). No save-state tip (the Electron bundle has no save buttons).
- Cybertron Mission (Acorn Electron) gamedoc. Rewrote it almost entirely against the game's keys screen plus Wikipedia. Controls: A up, Z down, ,/. (the game's </>) left/right, M fire, S/Q sound, P/R pause/resume — the doc had a fabricated Z/X/
'///Return scheme and a non-existent "M = map". Fixed the premise too: 16 rooms (4×4) per level across four repeating maze levels, collecting treasures then reaching a safe (not a "64-room grid / keycards / reactor core"), with Spinners/Clones/Cyberdroids and the wall-phasing Spook. Added the author Matthew Bates and corrected the year to 1983 (was 1984). The on-screen title abbreviates to "Cybertron"; the published title is "Cybertron Mission" (kept). - Boxer (Acorn Electron) gamedoc. Fixed from the game's keys screen — getting up after a knock-down is Z/X (left/right), not Return as the doc claimed (Return is punch only) — and added the missing keys: S/Q sound on/off, Home/Backspace (COPY/DELETE) freeze/continue, Esc restart. ' (the BBC : * key) for Up and the Acornsoft 1984 credit confirmed correct.
- Starship Command (Acorn Electron) gamedoc. Rewrote the controls from the game's own controls screen — the doc had a fabricated scheme (
'///Return/S, plus a non-existent "hyperjump"). The real keys: Z/X rotate, N fire torpedoes, M thrust, , brake, F/G launch port/starboard escape capsules, and one-at-a-time system toggles (B shields / V scanners / C auto-changeover, 2/Q rotation dampers, 3/W velocity dampers) plus Home/Backspace (COPY/DELETE) freeze. Fixed the prose throughout (torpedoes not lasers, shields share the circuit with scanners, escape capsules not a hyperjump) and dropped the now-irrelevant apostrophe note (no:/*key is used). Author (Peter Irvin) and year (1983) confirmed correct. - Hopper (Acorn Electron) gamedoc. Completed the controls from the game's own keys screen — added the sound keys (Q off / S effects only / T tune & effects), Home pause (BBC COPY, which ElkJS maps to PC Home, not End), and Backspace continue (BBC DELETE); fixed the wrong "Space = start/pause" (Space only starts). Reworded the movement as forwards/backwards to match the screen, and dropped the unverified "Andrew Bray" credit — the title screen only shows "Acornsoft Ltd 1983".
- BBC
:/*key now listed as the PC apostrophe across the Electron gamedocs too. ElkJS maps the Electron : * key to keyCode 222 (PC apostrophe) — the same gotcha as jsbeeb — so a bare : is unpressable as written. The Electron docs that use it now list it as the apostrophe ' with an explanatory note:hopper,starship,snapper,frak,repton2,cybertron,boxer. - Exile (BBC Micro) gamedoc. Verified the controls against the Exile quick-docs (Q/W move, P/L jet-pack, O/K/I aim, Space fire, Ctrl lie down, G/S take out/store, M drop are all correct) and added the two missing ones — F1–F9 switch weapon and the arrow keys scroll the view. Removed a getting-started step claiming a "teleporter map" (Exile has no in-game map — it contradicted the strategy section). Documented the boot loader menu from its screen (Run Game = BBC f0 = PC F10, then Status / See position / Catalogue / Load position / Save position / Score Breakdown / Default position on F1–F7) and fixed the start step — the old "press Space" was wrong. Clarified the save note: the loader's Save position (F5) writes to the read-only browser disc and won't persist, so players are pointed at the save/load buttons (five slots).
- Uridium (BBC Micro) gamedoc. Rewrote the controls from the game's own title screen — the defaults are up A, down Z, left : (PC apostrophe '), right J, fire Return, and the keys are redefinable at the title (the doc had a wrong Z/X/
'//scheme plus fabricated Tab-flip/S/Esc rows). Corrected the BBC conversion credit and year from the title screen — the BBC port is A.I.M. 1987 (the Graftgold original is 1986), not "1986, Dominic Robinson" (he did the Spectrum port). Reworded the flip as reversing your direction of travel, and added a save-state tip (no in-game save → load/save buttons, five slots). - Thrust (BBC Micro) gamedoc. Added the control keys printed on the game's own title screen that were missing — End/COPY freeze, Backspace/DELETE unfreeze, Q/S sound off/on, Esc quit — and noted rotation (Caps Lock/Ctrl) is held; jsbeeb's default physical layout maps all of these straight to the PC keys. Corrected the credit to Jeremy C. Smith and the publisher line — the BBC version was Superior Software's own 1986 release (dropped the misleading "originally Firebird"; Firebird published the later ports, though its budget C64 version reached shops first). Added a save-state tip (no in-game save → load/save buttons, five slots).
- Jet Set Willy (BBC Micro) gamedoc. Corrected the year to 1986 (Tynesoft; was 1985) and noted the BBC conversion's "Chris Robson" credit is a pseudonym for Dave Mann. Fixed the bug-room note — the BBC version's game-breaker is the Watch Tower crash, not the Attic (that was the Spectrum's). Clarified the jump key: it's the BBC : * key, which jsbeeb maps to the PC apostrophe ', so the table now lists both the PC and BBC keys. Added the missing save-state tip (no in-game save → use the load/save buttons, five slots). Added a save-state tip (no in-game save → use the load/save buttons, five slots).
[1.1.0] - 2026-06-29
Added
- Five save slots per game. The bottom-left Save/Load controls each open a drop-up menu of five slots, each labelled empty/used (status by label only; no slot is dimmed or disabled). Persistence moved from
localStorageto IndexedDB (object storegx-savestate, keyedplatform:game:slot) — no quota worries, stores the state binary directly, and different games keep independent saves. Both the EmulatorJS (genx-savestate.js) and standalone (genx-savestate-std.js) handlers; gamedocs reworded to "Five save slots per game".
[1.0.8] - 2026-06-25
Changed
- Doc sync after the bundle splits. Updated README and the GitHub wiki (File Structure, Project Overview, Emulators, atari800, jsbeeb, WebMSX pages) to name the per-machine bundles —
atari400/+atari800/,msx1/+msx2/,bbcmicro/+bbcmaster/— and dropped the now-false "share one build" /?machine=claims. Orphan-file audit found none to remove (gamedocs, ROMs all referenced); the BBC bundles each carry the full upstream jsbeeb disc set by design (full-copy split).
[1.0.7] - 2026-06-25
Added
- Published as GitHub Packages. A
Dockerfile(the whole site served by nginx →ghcr.io/retro-jack/genx-dos) and an npm package (@retro-jack/genx-dos, the static site as files), each built and pushed by a.github/workflows/publish-package.ymlworkflow on every GitHub Release. README documentsdocker runandnpm installusage. Each package's listing description states its version and format (container via a manifest annotation, npm via the package description).
[1.0.6] - 2026-06-25
Added
- Separate
systems/atari400/bundle. The 400 menu now launches from its own bundle (honest…/systems/atari400/…URL path) instead of sharingsystems/atari800/. Same atari800 emulator core, but the 400 bundle defaults to OS-B and the 800XL bundle to OS-XL. The 10 OS-B games + their ROMs + gamedocs moved toatari400//gamedocs/atari400/;atari800/now holds the 800XL set only. - Split the shared WebMSX bundle into
systems/msx1/+systems/msx2/so the URL path names the actual machine instead of the ambiguoussystems/webmsx/. Each bundle ships the WebMSX engine and its owngames/+ gamedocs (gamedocs/msx1/,gamedocs/msx2/); the MSX2 menu links now pass an explicitM=MSX2rather than relying on the engine default. - Split the shared jsbeeb bundle into
systems/bbcmicro/+systems/bbcmaster/so the URL path names the machine instead of the ambiguoussystems/jsbeeb/. Each is a full self-contained jsbeeb copy (the Micro bundle boots Model B, the Master bundlemodel=Master); gamedocs split togamedocs/bbcmicro/andgamedocs/bbcmaster/(themaster-filename prefix dropped, now that each machine has its own dir), and each bundle's corner-link script points at its own gamedoc dir.
Fixed
- Atari 400 games were silently booting as an 800XL. The 400 menu launched every game with
?machine=atari, butplay.html's machine-flag table had noatarikey, so no machine flag was applied and atari800 fell back to its default machine — the 800XL. Fixed the flag table (added anatarialias) and split the bundles (above) so a 400 game boots OS-B fromsystems/atari400/. The tab title and the per-game gamedoc titles/subheads now name the actual machine (Atari 400 for the OS-B set, Atari 800XL for the XL set) instead of a blanket "Atari 800".
[1.0.5.1] - 2026-06-25
Added
- Prominent "accuracy not guaranteed" caveat on the three obscure gamedocs that couldn't be manual-verified in the re-audit (C128 Invaders, C128 Phazer, MAX Speed/Bingo Math). New reusable
.caveatcallout class ingenx-controls.css(amber left-bar warning box), placed directly under the header description.
[1.0.5] - 2026-06-25
Fixed
- Gamedoc accuracy re-audit of the EmulatorJS console/handheld bundles (post-quota pass). The original 12a audit verified the standalone emulators against manuals but only gave the EJS bundles a gamedoc↔controls.html consistency check (the WebSearch quota had run out). Re-verifying each game's specific keys against manuals:
- NES (4/10 fixed): Mega Man 2 — weapon menu opens with START, not Select (Select just moves the menu cursor). Final Fantasy — main menu opens with START; Select changes marching order (was attributed to Select / "Start unused"). Super Mario Bros. 3 — the world-map item box opens with B (A uses the chosen item); Select is unused (was "Select uses inventory"). Castlevania — stairs climb with Up / Down at a staircase, not a held diagonal (a CV3 mechanic).
- Atari 2600 (clean): all 10 verified against manuals (incl. Asteroids thrust=Up/hyperspace=Down and Pitfall ladder Up/Down) — no changes.
- Atari 7800 (1/10 fixed): Pole Position II — the ProLine maps gas to the left button (Z) and brake to the right button (X), with high/low gear on Up/Down; the gamedoc had accelerate/brake on the D-pad and the gears on the buttons (fully inverted). Xevious verified correct (Z = air Zapper, X = ground Blaster in two-button mode).
- ColecoVision (1/10 fixed): Mouse Trap — the three coloured doors are operated by keypad 1 / 2 / 3 and the dog transform by keypad 5 (not the fire buttons, and not by walking up to a wall switch). The other nine verified correct.
- Magnavox Odyssey² (1/10 fixed): Atlantis — there are two indestructible sentry posts (not three guns); the joystick selects the left/right post and you fire with the action button (the gamedoc had each direction firing a separate gun with no button), and pushing the stick forward launches the once-per-wave Blitz Bomb. Rewrote against the Odyssey² manual.
- Game Boy / Color (1/10 fixed): Donkey Kong '94 — corrected the handstand (↓ + A together) and backflip (opposite direction + A while running) move inputs (was "jump then ↓" / "jump backward"); the button table itself was right. The other nine verified correct (Kirby B = inhale, Castlevania B = whip, Metroid II Select = missiles, Zelda A/B = assigned items, etc.).
- Game Gear (1/10 fixed): Mortal Kombat — block is the START button (the two-button pad puts Punch on 1 and Kick on 2, so block moved to Start), not "hold back" as the table and a strategy note claimed. Also clarified that The GG Shinobi's Start switches between rescued ninja and uses magic. Streets of Rage confirmed as SoR1 (the one-off police-backup special is correct); the rest verified.
- Atari Lynx (3/10 fixed): Klax — the button drops a tile and Down speeds up the incoming tiles (the gamedoc had Down also dropping). Blue Lightning — the stick is inverted (Up dives, Down climbs), B fires guided missiles (not "bombs"), and speed is the Option 1 afterburner, not an Up/Down throttle. S.T.U.N. Runner — A = lasers, B = Shockwave; speed is automatic (boost pads) with no manual boost or jump button (the gamedoc had a boost button and a jump). Warbirds left as-is (A = guns, B = throttle plausible; no readable manual to confirm).
- Commodore VICE family (3 fixed): the joystick games (the bulk of VIC-20/C64/C16/MAX/Plus4/C128) are correct by construction (arrows/Numpad → joystick, L Ctrl/Numpad 0 → fire); only the keyboard-driven games were error-prone. C64 — The Last Ninja: there is no "walk/combat mode" toggle; F3 / F5 cycle carried objects ("Holding") and Space cycles/selects the weapon ("Using") — the gamedoc had Space toggling a (non-existent) mode and an "I = inventory" key. C64 — Impossible Mission: the puzzle-screen function keys only flip pieces (F1/F3) and recolour them (F5) — they do not "save snooze/reset codes" (those are used at in-room terminals via the joystick); also a completed puzzle is four pieces forming a colour-matched punch-card and the nine puzzles spell a password word, not "musical note-lines". Plus/4 — Mercenary: movement/aim/fire are on the joystick; the keyboard verbs are T/D take/drop, B/L board/leave, E elevator, +/− engine power — the gamedoc had "Space = pick up" and a fabricated "A = toggle aircraft pitch mode". C64 Elite re-verified against the manual and left unchanged (S = dive, X = climb, view/combat/nav keys all correct).
Changed
- Swapped the credit pill order to
GenX-DOS · licence · source(wassource · licence) sitewide — one edit ingenx-repo-link.js, so every emulator page and the DOS prompt page update together.
[1.0.4] - 2026-06-24
Changed
- README License section now links
LICENSE.TXTprominently, alongside the existingATTRIBUTION.mdlink (the full licence text was previously only reachable via the CC badge). - ZX Spectrum (jsspeccy) bezel no longer fisheye-distorted and sits flatter in the glass. Removed the
#crtbulgebarrel-distortion filter (and its now-unused SVG/displacement-map) and dropped the fixedtranslate()nudge it needed. The screen now overscans the bezel cutout atscale(1.09).
Fixed
- Atari 2600 (stella) canvas no longer drifts between games. (community-reported) Replaced the fixed
translateX(-18px)nudge with proper centre anchoring (top/left:50%+translate(-50%,-50%)), so the canvas centre pins to the bezel-hole centre regardless of the width the core emits per game. - ZX Spectrum (jsspeccy) screen now tracks the window size. (community-reported) JSSpeccy (
uiEnabled:false) injects its ownappContainerdiv with a fixed inline pixel width (320 × zoom), which pinned the whole stack to that size so the canvas ignored the percentage-sized bezel cutout. Forcing the injected div to fill the hole (inset:0; width/height:100%) lets the canvas scale with the bezel like the ZX81 (jtyone) canvas does — fixing both the broken resize and the resulting black band at the top of the screen.
Added
docs/tech_article.md— a magazine-style feature article on the project (the concept, the static/no-build constraint, the WASM-rebuild and save-state war stories, the curation philosophy, and the honest seams). Linked from the README's Documentation section and the new wiki_Sidebar.md.
[1.0.3] - 2026-06-24
Added
source · licencecredit on the DOS prompt page too. The same self-containedgenx-repo-link.jspill that sits on every emulator page is now included onprompt/index.html, so the menu/prompt surface carries the bottom-centreGenX-DOS · source · licencecredit as well.echo oncommand. The prompt now understandsecho on(mirroringecho off): it re-enables echo and drops to a freshC:\>prompt. A batch can end withecho onto return the user to a live prompt without the trailing blank line thatecho.leaves.
Fixed
- "0. Exit" now drops to a
C:\>prompt again. Trimming theecho.lines fromSYSTEMS\0.bat(above) removed the side effect that re-enabled echo and redrew the prompt — so the sign-off screen sat there with no cursor. The batch now ends with the newecho on, restoring the live prompt with no extra blank line.
Changed
- Simplified the "0. Exit" sign-off. Dropped the two
echo.blank lines and shortened the header toGenX-DOS (2026)with a short rule line — the exit screen now prints the title, rule, "Type help or menu to continue", then a freshC:\>prompt.
[1.0.2] - 2026-06-24
Changed
- Orphan + doc-sync audit (24/06/2026). Full sweep after the v1.0.1 release. No orphan files — every shared helper (JS/CSS), bezel, texture, font sheet, and prompt script resolves to a runtime reference; no stray/temp files; no leftover
packaging/dir. README and ATTRIBUTION verified current (19 engines / 32 sub-systems / 13 EmulatorJS bundles; every bundle and core attributed). Wiki fixes:Virtual-Filesystemwas stale — it still described only CONSOLE + HOMECOMP (no Handheld Consoles category) and counted "28 sub-systems"; rebuilt the menu tree to the current EMULATOR LAUNCHER layout (HOMECOMP / CONSOLE / HANDHELD / WIKI / Exit), added the TANDY parent (TRS-80 + CoCo) and the three handhelds (Game Boy/Color, Lynx, Game Gear), and corrected the count to 32.File-Structurewas missing thegbc/lynx/gamegear/dirs from both the tree and the per-emulator table, and omitted theprosystemcore from the_shared-ejsline — all added.
[1.0.1] - 2026-06-23
Added
- Subtle "source · licence" credit on every emulator page. A new self-contained
systems/_shared/genx-repo-link.jsinjects a bottom-centre note —GenX-DOS · source · licence— linking to the GitHub repo andLICENSE.TXT. It sits in a small dark pill so it reads over the wallpaper (bare amber text vanished into the busy pattern, the same reason the controls / save-load links carry their own background). Included on all 29 launch pages (26play.html+ the jsbeeb/jsvecx/webmsx wrappers). The text ispointer-events:noneso only the two links are clickable and it never steals a click from the emulator; it sits clear of the controls link (bottom-right) and save/load buttons (bottom-left).
Fixed
- DOS prompt — reduced Firefox horizontal text hairlines. The prompt grid is fitted to the bezel cutout with a non-uniform
transform: scale, which left every 12px row edge on a sub-pixel device position; Firefox antialiased those clip edges into a faint hairline across each text row.fitPrompt()now snaps each cell to a whole number of device pixels (floor12·scale·dpr, so the grid never overflows —.prompt-fit's black fill covers the small slack), and.font/.promptcarryimage-rendering: pixelated(nearest-neighbour sampling). The residual is now consistent with CRT scanline character rather than a rendering artifact. (A font-PNG cell-scaling rewrite was tried and reverted — the snapped transform looked better.) - BBC Micro wallpaper seam at the bezel's top edge. jsbeeb paints the 70s wallpaper on both
htmlandbody(it needs both — body's upstream background is black), and#cub-monitor { margin-top: 60px }collapsed through the block body, offsetting the body copy by 60px and seaming the tiled pattern right where the bezel meets the wallpaper. Fixed by addingbackground-attachment: fixedso both copies anchor to the viewport and tile from the same origin regardless of the margin offset. jsbeeb-specific — the other pages have no such margin offset. - Enforced 10 games per system — Atari 400 was 11. Star Raiders was listed on both the Atari 400 and Atari 800XL menus (different machine configs), so the 400 menu held 11 games. Removed it from the Atari 400 (it stays on the 800XL); the 400 now lists 10 games + Atari BASIC at #11, like every other system. Box re-aligned (45-wide) and the choice
.batfiles renumbered 1–11. Site-wide count verified: all 31 game menus are exactly 10 games, with built-in software (BASIC / Mine Storm / Woz Monitor) at #11 where present. - EmulatorJS console/handheld bundles — verified consistent (gamedoc ↔ controls.html). Swept NES, 2600, 7800, ColecoVision, Odyssey², Game Boy/Color, Game Gear, Lynx and the whole VICE family (C64, C128, C16, VIC-20, MAX, Plus/4): every gamedoc maps the controller keys exactly as its controls.html does (X=A/Z=B on NES/GB/Lynx, Z/X = left/right fire on 7800, Z/X = Button 1/2 on Game Gear, numpad joystick on the VICE family, etc.), and game-specific combos spot-check correct (Castlevania sub-weapon, Punch-Out dodge). No errors. One tidy-up: the Plus/4 gamedocs drive the joystick with the arrow keys + L Ctrl (the EmulatorJS RetroPad mapping, equivalent to the numpad), which its controls.html only documented as the numpad — added the arrow-key note so the two surfaces agree (c128 already documented both).
- PET — fixed four arcade ports' controls (verified from the games' own on-screen text). The PETSCII arcade homebrew used the PET numeric keypad, not the WASD/IJKL or comma/period the gamedocs claimed — confirmed by extracting the instruction strings embedded in the .prg files: Space Invaders = 4 left, 6 right, A fire; Frogger = "BUTTONS 2,4,6 & 8"; Pac-Man = "USE THE KEY PAD" 8/2/4/6; Crazy Balloon = "USE NUMBER KEYS" 8/2/4/6 (+ diagonals). The pet2001 emulator maps by character, so the top-row number keys work. The BASIC text games (Star Trek, Adventureland, Lunar, Hangman, Android NIM) are typed-input and were already correct; ComputerSpace 2001 had no extractable instruction text and was left as-is.
- MSX — aligned the secondary-fire key with controls.html. Eleven gamedocs (the Konami-heavy two-button games: Nemesis, Knightmare, Parodius, Aleste, Goonies, King Kong 2, Manbow, Metal Gear, Usas, F-1 Spirit, Yie Ar Kung-Fu) put the secondary action — sub-weapon / power-up / kick / weapon-select / gear-down — on Shift, but controls.html documents the second trigger (Trigger B) as L Alt. Changed all eleven to L Alt so the gamedocs match the platform's own controls page (the same inconsistency class as the CoCo and Apple ][ fixes). Single-button games (Antarctic Adventure, Athletic Land, etc.) already used Space = Trigger A correctly.
- BBC Micro — fixed seven games' controls. The set mostly uses the standard BBC Z/X + colon/slash scheme (correct for Repton, Snapper, Citadel, Uridium and the Master titles). Seven were wrong: Chuckie Egg (A/Z up-down, comma/period left-right, Space jump); Manic Miner (the alternating-column scheme Q/E/T/U/O left, W/R/Y/I/P right, Space jump — not Z/X); Jet Set Willy (Tynesoft: Z/X + the * key to jump — not O/P/Space); Exile (Q/W move, P/L jet-pack, Space fire, O/K/I aim — not Z/X/Shift/Return); Thrust (Caps Lock / Ctrl rotate, Shift thrust, Return fire, Space tractor beam — the gamedoc had A/S/;/ /Tab); and both Elite versions (pitch is S/X dive-climb, not "?"/"/", which also resolved "?" being listed as both pitch and decelerate). Verified via bbcelite.com, TCRF, stardot and the game docs.
- Amstrad CPC — fixed three games' controls. Most use the CPC cursor keys + Space (correct for Roland, Bruce Lee, Bomb Jack, Get Dexter, Chase H.Q.) and CPC Elite is accurate (S/X pitch). Three were wrong: Rick Dangerous (jump is ↑ / up-diagonal, not Space — Space is the fire button for stab/pistol/dynamite); Knight Lore (CPC keys are Z/X left-right, O/K up-down, 0 jump, Enter pick-up — not Q/A/O/P + Space); Head over Heels (CPC uses the cursor keys + Space jump, with fire on keypad f4–f6 and character-swap on f7–f9 — not Q/A/O/P). Verified via C64-wiki / CPCWiki / game manuals.
- Acorn Electron — fixed four games' controls. The set mostly uses the standard Acornsoft Z/X + colon/slash scheme (correct for Snapper, Repton 2, Citadel, etc.), but four were wrong: Chuckie Egg (BBC default is A/Z up-down, comma/period left/right, Space jump — not Z/X/;/.); Frak (Return throws the yo-yo and the up key jumps — the gamedoc had jump and yo-yo swapped); Boxer (Z/X move, Return punch, Shift jump — not the "high/low punch + duck" the gamedoc invented); and Elite (pitch is S/X dive/climb, which also resolves the gamedoc listing "/" as both pitch-down and decelerate). Verified via stardot/Acorn archives and the Elite key card. Fixed the matching prose.
- ZX81 — fixed three games' controls. Most of the set uses the ZX81 cursor keys (5/6/7/8 + 0), but three deviate and were wrong: 3D Monster Maze uses only 5 = turn left, 8 = turn right, 7 = step forward (no backward — the gamedoc had them scrambled); Night Gunner uses keyboard-row groups (top row up, 3rd row down, 2nd-row halves left/right, Space fire) not the cursor keys; Mazogs uses W/A/D/X to move and V for the map, with no fire key (you fight a Mazog by pushing into it with the sword) — the gamedoc invented "0 = strike". Fixed the matching prose (3DMM "chains of 7" to sprint; Mazogs combat). Verified via Wikipedia / the Night Gunner manual. The arcade ports (Galaxians, Frogger, Maze Death Race, 3D Grand Prix) keep the documented cursor scheme.
- ZX Spectrum — corrected all 10 games' controls. Another standalone set where every gamedoc guessed Q/A/O/P + Space. Verified each against the manuals: the Ultimate titles use Q/W/E/R/T (Atic Atac/Sabre Wulf/Underwurlde = left/right/down/up/fire; Pssst swaps E/R; Knight Lore uses keyboard-row groups — bottom-row turn, 3rd-row walk, 2nd-row jump, top-row pick-up); Manic Miner / Jet Set Willy use the alternating-column scheme (Q/E/T/U/O left, W/R/Y/I/P right, Space jump); Chuckie Egg = comma/period left/right, A/Z ladder up/down; Dizzy = Z/X; Skool Daze keeps Q/A/O/P but acts on F fire / H hit / J jump / S sit / W write (not Space). Rewrote all 10 tables, fixed the redefine note, and replaced controls.html's wrong "Q/A/O/P = Ultimate/Manic Miner" reference with the real per-family schemes.
- TI-99/4A — corrected eight games' controls. This standalone set had many guessed schemes. Hunt the Wumpus is the graphical joystick cart (move room-to-room, arm + push to shoot) not the text "type a room number" game; Parsec uses ←/→ decelerate/accelerate, 1/2/3 lift speed, P pause (no Z/X speed, no hyperspace — the "warp" is a crash easter-egg); Tunnels of Doom combat is W weapon, F ranged-fire, N negotiate, U use-item (not "C cast / M move / R run"); Microsurgeon is 1/2/3 treatments + 7/8 speed (not "1–5"); Car Wars' fire button accelerates (gamedoc wrongly said "unused, no weapon"); Alpiner has no jump (pure movement); Munch Man pauses on any key (not "R"). Removed the unverified "R = pause" rows from TI Invaders and Tombstone City. All verified against 4apedia / game manuals.
- Atari 800 — fixed Ballblazer and Rescue on Fractalus controls. Both LucasFilm titles had invented schemes. Ballblazer's rotofoil strafes left/right (the gamedoc claimed a "90° snap-rotate, only faces 4 directions") and the fire button is the push-field that shoots the Plasmorb (not an "auto-rotate toggle") — verified via StrategyWiki. Rescue on Fractalus uses D/E thrust, L Land, S Systems, A Air Lock, B Boosters (the gamedoc had made-up 1/2/9/0 keys) — verified from the Atari manual. Fixed both tables and the matching strategy prose. The other 18 titles (Star Raiders' full command set + the arcade ports) verified accurate against controls.html.
- Apple ][ — fixed controls.html's per-game key hints. The detailed per-game gamedocs are accurate (verified against manuals: Lode Runner, Aztec, Karateka, Castle Wolfenstein, Hard Hat Mack), but the controls.html "starting hints" table had lazy wrong guesses — it stamped
I J K Mon Lode Runner, Castle Wolfenstein and Hard Hat Mack. Corrected each to the real scheme (Lode Runner I/J/K/L; Aztec A/D move, W/R walk/run, J jump; Wolfenstein's 3×3 QWE/ASD/ZXC grid; Karateka Q/A/Z punch + W/S/X kick; Hard Hat Mack A/Z + arrows; Choplifter F1 fire / F2 facing). Apple 1 (text/BASIC type-ins) verified clean. - Vectrex controls — corrected the whole set against the game manuals. Every Vectrex gamedoc had guessed button maps (fire on Button 1, thrust on the stick); the real convention is Button 4 = fire, Button 3 = thrust, joystick = direction/rotation. Verified all 11 games from their manuals (Ozyr's archive, Vectrex Wiki, scanned GCE manuals) and rewrote each control table — e.g. Mine Storm (B2 = Escape/teleport), Solar Quest (B2 smart bomb, B1 transport), Cosmic Chasm (B1 drill, B2 shield), Spike (B4 jump, B2/B3 kick L/R — not "Speak/Punch"), Pole Position (B3/4 gas, B1/2 gears — no brake), Polar Rescue (stick dive/surface, B4 torpedo), Star Trek (B4 laser, B3 shield, B2 dock). Fixed matching prose errors (Star Castle has no hyperspace; Spike doesn't throw rocks) and rebuilt
controls.html's per-game table. No gameplay-affecting guesswork remains. - Gamedoc accuracy sweep (per-platform web verification). Intellivision: corrected two release years — BurgerTime is the 1983 Mattel/Data East port (not 1982) and Atlantis shipped 1982 (not 1981); fixed
games.json, both gamedocs, and the year-sorted menu (BurgerTime drops to #10). Controls were already accurate. (TRS-80 and Tandy CoCo corrected earlier in the sweep.)
Changed
- Name Clint Basinger in the LGR credit. The terminal-base credit (README + ATTRIBUTION) now records that Mike wrote it informally for LGR — Lazy Game Reviews (Clint Basinger), rather than the brand alone. ATTRIBUTION also names the original project (LGR-DOS — the "LGR-DOS Command Prompt") and cites LGR's own site metadata crediting Mike (
<meta name="Generator" content="Mike">). - ATTRIBUTION: refresh the Site-code licence note. Replaced the pre-LICENSE.TXT line ("No licence file in repo; treated as source-available…") with the current state — Retro-Jack's original code is CC BY-NC 4.0 (see LICENSE.TXT); the LGR terminal base is excluded from that licence and stays under LGR's own terms with the required credit.
- LICENSE: name LGR in the upstream-credit clause. The required credit now reads the original "LGR" (www.lazygamereviews.com) base terminal code framework, naming Lazy Game Reviews and its site rather than just "LGR base".
- Root launcher "0. Exit" now exits to the prompt with a sign-off. At the top level there's nowhere to go "back" to, so the entry (relabelled from "Back" to "Exit") used to just re-enter the launcher. It now clears the screen and prints "GenX-DOS by LGR and Retro Jack (2026)" with a "Type help or menu to continue" hint. (The category choosers' Back still steps up a level, unchanged.)
- Small menus (<5 items) now use blank-line spacing, consistently. Six parent choosers — Atari Consoles, and the Acorn / Apple / Atari / Sinclair / MSX "Computers" menus — listed their items on consecutive lines; brought them in line with the rule (one blank line between each item) already used by Handheld Consoles and the Tandy chooser. All 36 menu boxes re-verified at a 45-wide interior with aligned borders.
- Orphan + doc-sync audit (re-run after the controls work). No orphan files — every gamedoc resolves through its launcher (apple1
?tape=, jsbeeb?disc1=, webmsx / jsvecx?game=, the rest?game=); git tree clean, no stray/temp files; nothing added since the last audit. README and ATTRIBUTION verified current (19 engines / 32 sub-systems / 13 EmulatorJS bundles all hold; per-system "10 games" accurate). One stale wiki number fixed: File-Structure said the shared CSS serves 305 pages — it's now 350 (321 gamedocs + 29 controls.html); Roadmap gained a note on the controls re-verification. - Audit + doc sync (23/06/2026). Orphan-file + stale-text sweep. No orphan files — every
_sharedasset/bezel/texture has a runtime ref (PC.pngis the DOS-prompt bezel, not asystems/orphan), the TRS-80 bundle is clean, and every game maps to a gamedoc with no orphan gamedocs. No stale text: the dropped Windows installer and the abandoned SV-328/Blastar leave zero residue in any doc; counts are current everywhere (19 engines / 32 sub-systems / 13 EmulatorJS bundles). Wiki: filled the TRS-80 gaps the original sync missed — Roadmap scope list + shipped table + the gamedoc-count line (now 321 pages across 32 sub-systems), and the Project-Overview save-state list.
[1.0.0] - 2026-06-22
First tagged release. Everything below predates the 1.0.0 tag — the full build-up of the suite to 19 engines / 32 sub-systems, all bezeled, most with save/load state.
Added
- Tandy TRS-80 Model I — new platform (sdltrs WASM). New
systems/trs80/bundle on sdltrs (Mark Grebe / Jens Guenther, BSD-2-Clause), built from source to WASM via emscripten ASYNCIFY —emscripten_sleepreplaces sdltrs's blockingSDL_Delay/SDL_WaitEventso the continuous Z80 loop yields each timer tick; Model I Level II BASIC ROM embedded via--embed-file. 10 year-sorted Big Five / Adventure International.cmdarcade games (Galaxy Invasion → Crazy Painter), each entered directly viatrs_load_cmd. CRT bezel (TRS80.png), top-left CLEAR softkey (synthetic Home — most games start with CLEAR), 10 gamedocs + controls page. New TANDY parent menu groups the Model I with the Color Computer. Engines 18 → 19, sub-systems 31 → 32. - Save / load state on the Amstrad CPC (cpc) — rebuilt the tiny8bit WASM. floooh's chips library already has
cpc_save_snapshot/cpc_load_snapshot(a self-containedcpc_tstruct copy, noemscripten_sleep), but the stock build didn't export them. Rebuiltcpc.wasmfromfloooh/chips-testwithEMSCRIPTEN_KEEPALIVEgx_state_*wrappers added toexamples/emus/cpc.c, plusHEAPU8added toEXPORTED_RUNTIME_METHODSin the fibsemscripten.ts(the stock fibs config exports none — same gotcha as the o2em rebuild). The adapter is synchronous (no ASYNCIFY deferral — the chips snapshot has no nested sleep, unlike atari800);play.htmlmoves the raw struct bytes in/out viaHEAPU8. Verified mid-game on Bruce Lee. BUILDING-WASM.md documents the new patch. - Save / load state on the Atari 400/800XL (atari800) — rebuilt the WASM fork. atari800's
StateSav_*AtariStatereachemscripten_sleep(machine reinit) and the build runs a blocking ASYNCIFY main loop, so calling state save/load straight from a button (a second, concurrent asyncify op) corrupted the wasm memory. Fixed in theRetro-Jack/atari800fork by deferring the op through the frame loop: JS sets a request flag (gx_request_save/gx_request_load, no sleep),gx_state_poll()runs the actualStateSavonce per frame fromsdl/main.con the main-loop asyncify stack (where the nested sleep is safe), and JS pollsgx_state_status()then reads/writes the MEMFS state file.genx-savestate-std.jsnowawaits the adapter (sync engines unaffected). The F1 SDL menu's own save/load is dropped from the docs in favour of the GenX buttons. - Apple 1 CRT bezel — surplus security/CCTV monitor. Replaces the shared Apple Monitor /// for the apple1 bundle only (apple2 keeps
Apple.png). The Apple 1 shipped board-only with no monitor or RF/home-TV path, so in period it was almost always paired with a cheap B&W security monitor — thisApple1.png(731×757, screen hole6.16%/8.59%/87.96%×63.28%) is that look, knobs and all. Same player-in-hole recipe; the apple1js text canvas sits in the glass atscale(0.855). Not provenance-tracked (per bezel policy). - Odyssey² controls page.
systems/odyssey2/controls.htmlwas the only bundle missing one (its corner "controls" link 404'd when launched without a game) — added, documenting the joystick (arrows + Space) and the console's built-in 47-key keyboard, plus the save/load note. Sitewide check: 27/28 bundles already had a controls page; this completes the set. - Save / load state on the standalone (non-EmulatorJS) bundles — shared adapter core. New
systems/_shared/genx-savestate-std.jsadds the same amber save / load buttons (bottom-left) to engines that expose their own JS save-state API, driven by a per-bundlewindow.GenXStateAdapter(ready/getState/setState/refocus). State is deep-cloned on save and load — engines like js99er hand back live references (getState()returnsthis.ramdirectly), so the slot is frozen withstructuredClone(in-memory) + typed-array-tagged JSON (localStorage) to stop it tracking/aliasing the running machine. Bundles: js99er (TI-99/4A) —ti994a.getState()/restoreState(); jsbeeb (BBC Micro/Master) —window.processor.snapshotState()/restoreState(), the same complete state API jsbeeb's own rewind uses (verified mid-game on Elite); webmsx (MSX) —WMSX.room.machine.saveState(true)/loadState(), the API WebMSX netplay uses (its#wmsx-osdon-screen toasts like "AUTO: NTSC 60Hz" are a DOM overlay, hidden via CSS to keep the bezel chrome-free); xroar (Tandy CoCo) —Module._write_snapshot()writes a full-machine.snato the WASM FS, read back as the state and restored viawasm_load_file(the same path that loads games); and odyssey2 (Magnavox Odyssey²) — rebuilt the o2em WASM to expose state: the libretro core implementsretro_serialize/retro_unserializebut our customfrontend.cnever called them (so they were dead-code-eliminated), so frontend.c gainedgx_state_*EMSCRIPTEN_KEEPALIVEwrappers +HEAPU8added toEXPORTED_RUNTIME_METHODS. (atari800 + cpc didn't export state funcs from their WASM either — both since rebuilt to add them, see their own entries; jzIntv exports only a snapshot-preview; ElkJS'ssaveSnapshotis write-only with no restore reader; jsspeccy is worker-side load-only; apple1/apple2 don't expose the machine instance; jsvecx has no save mechanism at all — those would need bigger engine patches, so skipped.) - TI-99/4A CRT bezel (js99er) — completes the bezel set; every platform now framed. The TI now runs inside the shared vintage-TV
Sinclair.pngframe on the 70s wallpaper, same player-in-hole recipe as the MSX/CoCo/Spectrum. js99er sizes#canvasvia CSS, so it's pinned into the screen hole (8.08%/12.14%/65.35%×73.96%) and forced to fill;translate(8px,0) scale(0.9)to sit it in the glass,outline:none; border:noneto drop the canvas focus ring. No barrel/fisheye (the TI picture reads better flat). Black.screen-bgbehind hides the cutout edge. - CoCo CRT bezel (xroar). The Tandy Color Computer now runs inside the shared vintage-TV
Sinclair.pngframe on the 70s wallpaper, same player-in-hole recipe as the MSX/Spectrum. XRoar (SDL2) sizes#canvasitself, so it's pinned into the screen hole (8.08%/12.14%/65.35%×73.96%) and forced to fill (width/height:100% !important);translate(8px,0) scale(0.888)to sit it in the glass. No barrel/fisheye (the CoCo picture reads better flat). Black.screen-bgbehind hides the cutout edge. - MSX CRT bezel (webmsx). The MSX now runs inside the shared vintage-TV
Sinclair.pngframe on the 70s wallpaper, same player-in-hole recipe as the Spectrum/ZX81. WebMSX (SCREEN_RESIZE_DISABLED:false) sizes#wmsx-screen-canvasto fill the screen hole (8.08%/12.14%/65.35%×73.96%); canvastranslate(8px,-10px) scale(0.842)to sit it in the glass. No barrel/fisheye here (the MSX picture reads better flat). Black.screen-bgbehind hides the cutout edge. - GenX save / load state buttons on all 13 EmulatorJS bundles. The EmulatorJS toolbar is hidden site-wide (it would break the CRT-bezel aesthetic), which also hid save-state — so
systems/_shared/genx-savestate.js+genx-savestate.cssadd two amber save / load buttons (bottom-left, mirroring the bottom-rightcontrolslink) toc64/c128/c16/plus4/vic20/max/coleco/jsnes/stella/gbc/gamegear/lynx/js7800. State is kept in memory and mirrored tolocalStorage(per platform+game, survives reload); focus is handed back to the emulator after a click. Core gotcha: the bundled EJSsrcGameManager callsModule.EmulatorJSGetState(), but the mirrored cores are an older build that doesn't export it — they exposesave_state_inforeturning"length|pointer|status"(state read fromHEAPU8.slice(ptr, ptr+len)); load is FSgame.state+ theload_statecwrap. EJS's own save-state was silently broken by the same mismatch — these buttons are the only working save-state path. - Atari 7800: migrated to EmulatorJS + ProSystem, with the
80s.pngCRT bezel. The old JS7800 build managed its ownrequestAnimationFrameloop and couldn't be pinned into a CRT screen hole — constrained to the bezel it stalled on the 7800 BIOS splash. The 7800 now runs on EmulatorJS + theprosystemlibretro core (EJS_core: 'atari7800'), the same player-in-hole recipe as Stella/Coleco/NES, so it shares the80s.pngwood-cabinet TV with the Atari 800XL (screen hole15.4%/21.3%/46.4%×52.8%, canvasscale(0.95, 1.045)). Reuses the existing.a78ROMs +games.jsonunchanged; the oldjs7800/js/engine (JS7800 + bupboop, ~1 MB) is removed. Controls: arrows = d-pad,Z/X= the two fire buttons,Enter= Reset (starts a game from the title — EJS atari7800 button id 9, not START/3),Shift= Select (variations),P= Pause. Gamedocs (×10), controls page, and ATTRIBUTION updated. - NES CRT bezel — a maintainer-keyed real-room shot: a Sony Trinitron XBR with the Koopa Troop figures lined up on top and a console shelf (SNES / N64 / GameCube) below (
_shared/bezels/nes.png, 2888×2611, screen hole17.71%/21.48%/60.83%×51.73%). NES-specific (can't be shared like70s.png). EmulatorJS player-in-hole recipe (black.screen-bgbehind, canvasscale(0.88)to fit the glass). The set is bottom-anchored (align-items: flex-end !important, sized to100dvh) so the stand sits on the window floor and the figures reach the top. The bottom shelf cubbies are keyed through, so the wallpaper shows behind them naturally. - Odyssey² CRT bezel — reuses the wood-cabinet
70s.pngTV (now shared by the Atari 2600, ColecoVision, Intellivision and Odyssey²). Same#game-pinned-in-hole recipe as Intellivision (o2em's#canvasfills#game, grown 2px vertically to meet the glass). - Intellivision CRT bezel — reuses the wood-cabinet
70s.pngTV (shared with the Atari 2600 and ColecoVision). jzintv's#canvasstretches to fill#stage, so#stageis pinned into the screen hole and grown 2px vertically (centred) to meet the glass; black.screen-bgbehind,70s.pngon top. No EJS letterbox here (the canvas fills#stagedirectly), so no scale tuning needed. - ColecoVision CRT bezel — first of the eight remaining bare platforms. Reuses the wood-cabinet
70s.pngTV (shared with the Atari 2600), same EmulatorJS player-in-hole recipe (screen hole27.6%/13.1%/45.4%×51.6%, black.screen-bgbehind, canvasscale(1.08)to fill the glass). Wallpaper override carries!importanthere becausegenx-frame.cssloads after the inline<style>and resets body to black. - Sinclair TV bezel — completes the bezel set (10 wired, 0 staging). A shared vintage CRT television (
_shared/bezels/Sinclair.png, 1362×914, screen hole8.08%/12.14%/65.35%×73.96%) frames both the ZX Spectrum (jsspeccy) and ZX81 (jtyone) on the 70s wallpaper. The TV's screen cutout is curved, so the flat emulator canvas is given a barrel/fisheye distortion to bow into the glass: an SVGfeDisplacementMapfilter (#crtbulge) driven by a generated radial displacement map (_shared/textures/crt-barrel.png, R/G ∝ outward·r²).#jsspeccy/#emulator_canvasrunoverflow: visibleso the bulge spills past the rectangle and the bezel-on-top crops it to the screen shape;scale(1.155)+ an 8px right nudge centre it (the TV's screen sits left-of-centre with a thin left frame). Every other emulator's canvas is flat-on-flat, so this is the only bundle that needs the barrel. - Bezel for the Vectrex (jsvecx) — a keyed, portrait Vectrex console (
_shared/bezels/Vectrex.png, 1099×1399, screen hole16.4%/11.8%/58.7%×57.9%) floating on the 70s wallpaper, bottom-anchored so it sits on the frame. jsvecx (DrSnuggles' obfuscated build) sizes its own#vecscr/#overlay/#wrapperto the viewport via inline styles, so the bezel CSS pins them into the screen hole with!important(which beats inline styles); jsvecx'ssizer()→Quality()then reads the pinnedclientWidthand sets the canvas buffer to match, so it cooperates. Black.screen-bgbehind the canvas hides the cutout's anti-aliased edge. Bezels now 9 wired, 1 staging (Sinclair). - CRT bezel for the Apple ][ / ][+ / Apple 1 bundles — a front-on Apple Monitor /// (
_shared/bezels/Apple.png, 1583×1033) framing bothapple1jsandapple2json the 70s wallpaper, same player-in-hole recipe as the rest (screen hole13.3%/16.7%/55.3%×66.7%, black.screen-bgbehind, monitor PNG on top). These two bundles set their screens in collapsed-table /.overscanlayouts rather than EJS, so the CSS repurposes the upstream wrapper as the bezel frame and positions the canvas in the hole. Keyed on brightness (cream monitor vs darker wood) rather than hue — a front-on shot was the missing piece, since the earlier cream-on-white source had no edge contrast to key against. Newsystems/gamegear/bundle on EmulatorJS + the genesis_plus_gx libretro core (systemsegaGG; the 11thgenxBootEJSbundle). 10 year-sorted titles — Columns, Sonic the Hedgehog, Shinobi, Aerial Assault, Streets of Rage, Defenders of Oasis, Land of Illusion, Mortal Kombat, Mean Bean Machine, Tails Adventure — controls arrows = d-pad /Z= Button 1 /X= Button 2 /Enter= Start. Same device-over-classroom bezel style, bottom-anchored at 75%. The GG PSG is quiet, so this bundle runsEJS_volume = 1.5(EJS passes the value straight to a Web Audio gain node with no clamp, so >1.0 amplifies) — Game-Gear-only, not site-wide. Handheld Consoles submenu's Game Gear entry now live; all three handhelds (Game Boy, Lynx, Game Gear) done. Sub-systems 30 → 31; EJS bundles 11 → 12. - Atari Lynx — second Handheld Consoles platform. New
systems/lynx/bundle on EmulatorJS + the handy libretro core (the 10thgenxBootEJSbundle). Ships the 512-byte Lynx boot ROM (lynxboot.img, passed viabiosUrl) which the core needs to start games. 10 year-sorted titles leaning on the Lynx's colour + hardware sprite-scaling — California Games, Chip's Challenge, Electrocop, Blue Lightning, Warbirds, Gauntlet III, Klax, Slime World, S.T.U.N. Runner, Rampart — with controls arrows = d-pad /X= A /Z= B /Shift= Option 1 /Ctrl= Option 2 /Enter= Pause. Same handheld bezel style as the Game Boy: the Lynx held up in the foreground over the classroom photo (_shared/bezels/lynx.png, bottom-anchored, sized to 75%).handystable works (no nightly needed). TheHandheld Consolessubmenu's Atari Lynx entry is now live; only Sega Game Gear remains "coming soon". Sub-systems 29 → 30. - Handheld Consoles — new top-level menu category; first platform: Nintendo Game Boy / Game Boy Color. New
systems/gbc/bundle on the shared EmulatorJS framework (gambatte libretro core, GPL-2.0) — the 9thgenxBootEJSbundle. Runs both original GB and GBC games: gambatte boots in GBC mode (gambatte_gb_hwmode: 'GBC') so Colour-only carts work and mono GB games get auto-colourised. 10 titles, year-sorted — Tetris, Super Mario Land, Castlevania, Metroid II, Kirby's Dream Land, Link's Awakening, Donkey Kong, Pokémon Red, Wario Land 3, Shantae — controlsZ=B /X=A /Enter=Start /Shift=Select / arrows. Sub-systems 28 → 29. - New bezel style — device in the foreground over a photo. Instead of a CRT on the 70s wallpaper, the Game Boy Color is held up in the foreground (
_shared/bezels/gbc.png, bottom-anchored) over a classroom photo (_shared/textures/classroom.jpg) — the look of sneaking a handheld in class. EJS draws into the keyed screen hole; canvasscale(0.95). This is the template for the upcoming Atari Lynx + Sega Game Gear. nightlygambatte core: thestableEmulatorJS gambatte renders a blank white panel (no ROM ever displays) — same broken-stablepattern asvice_x128; we mirror thenightlybuild, which works.- Menu:
Handheld Consolesadded to the root launcher; its submenu lists Nintendo Game Boy + Atari Lynx + Sega Game Gear (the latter two "coming soon" until their bundles are built).
Changed
- Codebase beautified with Prettier + an auto-format standard. Ran Prettier over all GenX-authored JavaScript (
prompt/**, thesystems/**/genx-*.jshelpers) and every JSON data file; added.prettierrc(single-quote) and.prettierignore. Vendored/upstream emulator runtimes are deliberately left exactly as shipped — beautifying them broke EmulatorJS at runtime (the "Download Game Core" stall), so.prettierignoreexcludessystems/**/*.jsexcept our owngenx-*.js. Authored JS verified withnode --check; emulators smoke-tested. - Browser-tab titles now name the system — manufacturer + system, specs trimmed. Every emulator page's tab reads its system (e.g.
Commodore 64,Tandy TRS-80,Nintendo Entertainment System,Texas Instruments TI-99/4A) regardless of which game is loaded — previously most flipped the tab to the game's name once a game booted, and a few leaked the engine name (jsbeeb - Javascript BBC Micro emulator,Vectrex by DrSnuggles,Acorn Electron — ElkJS,Apple 1js …,TI-99/4A — GenX-DOS). Spec/model qualifiers are trimmed (Atari 800XL→Atari 800,TRS-80 Model I→Tandy TRS-80,Game Boy Color→Nintendo Game Boy,MAX Machine→Commodore MAX). Fixed once in the shared EJS boot (all 13 EmulatorJS bundles) plus each standalone page; the controls (×11) and gamedoc (×131) page tabs were brought in line with the same names (visible page headers unchanged). - Audit + doc sync (18/06/2026) — sweep after the atari800 + cpc save-state rebuilds and the Apple 1 bezel swap. No orphan files: every
_sharedbezel/texture/JS/CSS still has ≥1 runtime ref (save-state counts line up exactly — 13 EJS + 7 standalone = 20genx-savestate.cssrefs),Apple1.png(apple1) andApple.png(apple2) each have one ref so the bezel swap left no orphan, the rebuiltcpc.{js,wasm}+atari800.{js,wasm}left no stale artifacts (no demo-shellcpc.html), no backup/temp files. Stale-text fixed: README cpc line said "mirrored fromfloooh.github.io/tiny8bit/" — it's locally rebuilt from source; ATTRIBUTION's cpc row ("two-line patch") + build-recipe list + self-compiled-builds section now reflect the cpc fibs rebuild and the atari800/cpcgx_state_*wrappers; the README + Project-Overview save/load lists moved Atari 400/800XL + Amstrad CPC from "no buttons" to working (and added Intellivision to the unreachable list). Wiki: added save-state sections to the atari800 + tiny8bit-CPC emulator pages. Engine/sub-system/bundle counts unchanged (18 / 31 / 13 EJS). - Audit + doc sync (17/06/2026, #2) — sweep after the standalone-save-state + o2em-rebuild + Odyssey²-controls work. No orphan files (the three
genx-savestate*files are referenced by all 18 button-bearing bundles; the rebuilto2em.{js,wasm}left no stale artifacts; the/tmpo2em-check clone stayed out of the repo; no backup/temp files). Stale-text fix: save / load state — a user-facing feature now on 18 bundles — was undocumented, so added a "Save / load state" section to README, an o2emgx_state_*-wrapper note to ATTRIBUTION's self-compiled-builds entry, and synced the wiki (Project-Overview + the o2em/WebMSX emulator pages). Engine/sub-system/bundle counts unchanged (18 / 31 / 13 EJS). - Audit + doc sync (17/06/2026) — orphan-file and stale-text sweep after the 8-bezel + 7800-migration + save-state work. No orphan files: the JS7800 engine left no residue (no
js7800/js/, nobupboop/JS7800strings), all 11 mirrored EJS cores are referenced (VICEx64/xplus4each shared by two bundles;prosystemnow wired), every bezel PNG + texture + shared JS/CSS is referenced (PC.pngis used by the DOS prompt, not an orphan). README stale-text fixed: engine count 19 → 18 (JS7800 folds into EmulatorJS, same pattern as Javatari→Stella); "12 bundles share EJS" → 13; thejs7800bundle line, lineup-table row and licence bullet switched from JS7800 to EmulatorJS + ProSystem; WebMSX "single-file bundle/inlined" → stockwmsx.js+ wrapper (rebuilt 16/06); the EmulatorJS "shared across" list refreshed to all 13 bundles; duplicate## Licenseheading merged. ATTRIBUTION: added theprosystemcore row + mirroring note; the bezel-artwork section (stale "seven wired / three staging") trimmed to a policy-aligned note — every platform now bezeled, artwork not provenance-tracked per maintainer policy, with the one binding obligation (Amstrad.png, CC-BY-SA 2.5, Bill Bertram) retained. Wiki synced separately. - Console/handheld gamedoc Controls tables → 3-column Keyboard / Gamepad / Action. Every console & handheld gamedoc's Controls table now splits the PC key from the controller button into its own column (the SMB model, rolled out):
Keyboard→Gamepad→Action. 100 docs across 10 platforms — jsnes (NES), stella (2600), js7800, coleco, intv, odyssey2, gbc, gamegear, lynx, jsvecx. Mappings are explicit per platform, grounded in eachcontrols.html(andjzintv.datafor Intellivision'sLSHIFT/LCTRL/LALT→ action-button signals); no inferred fallbacks. Hand-done outliers: coleco/qbert (isometric hop table), intv/tron (three distinct disc-throw buttons), odyssey2/qrings ("Action controls" heading). Prose-only Controls (lynx/calgames — per-event California Games) left as text. Home-computer gamedocs keep their 2-column tables (no standard gamepad). - Docs scrubbed of every reference to the hidden EmulatorJS toolbar / in-emulator menus. The EJS toolbar + context menu, gear/Settings, on-screen keyboard, WebMSX control bar and JSVecX toolbar are all hidden site-wide (deliberate — they'd break the bezel aesthetic and invite users to ask for chrome that doesn't fit). So every controls page and gamedoc that pointed at them is rewritten: the per-bundle "EmulatorJS toolbar" sections are removed; "swap the joystick port / remap in the gear menu", "Control Settings", "save-state via the EmulatorJS toolbar", the WebMSX HUD-bar table, the JSVecX toolbar table, and apple1's "open the emulator menu" tape steps are replaced with what's actually available (port preset per game, the new save / load buttons, tapes auto-load by URL, reload-to-restart).
jsbeeb's hover toolbar andatari800's F1 SDL menu are left as-is (still reachable). Also merged the keyboard keys into the SMB gamedoc's controls table (Key → NES button → Action) as a model for the rest. - MSX: SD Snatcher → Quarth. SD Snatcher loaded as a disk set, so it opened on its English-translation sound-chip config screen ("SCC chip found in none of the slots…") — confusing as a first impression. Swapped it for Quarth (Konami, 1990) — a clean-booting cartridge "shoot-'em-up puzzle". Same year, so it keeps menu slot #10; the link switches from
?ANY=to?ROM=. ROM,fs.jsmenu, gamedoc, and the controls note updated. (MSX now has zero disk-based games — every title boots straight to play.) - Renamed
emulators/→systems/to shorten every URL (…/systems/c64/play.html). Repo-wide path rewrite — 778 references across 329 files (play.html, gamedocs,fs.jsmenu links, controls pages, README/CHANGELOG/ATTRIBUTION, OG/canonical URLs). Also shortened the two long bundle dirs —intellivision→intvandamstradcpc→cpc(their menu codes were already INTV/CPC) — and renamed the DOS-prompt's launcher dir + command fromcd emulatorstocd systems(virtualEMULATORSdir →SYSTEMS; the on-screen "EMULATOR LAUNCHER" heading is kept). Display names ("Intellivision", "Amstrad CPC") unchanged. Note: old/emulators/…,/systems/intellivision/…,/systems/amstradcpc/…URLs now 404 — update any bookmarks. - C64: International Karate → Uridium. International Karate is a two-player simultaneous fighter built around dual joysticks, which the single-keyboard-joystick setup can't serve well. Swapped it for Uridium (Hewson / Andrew Braybrook, 1986) — a single-player horizontal shoot-'em-up that plays cleanly on the one numpad joystick. Same year, so it keeps slot 8 and the year-sort. ROM (
.d64),games.json,fs.jsmenu and gamedoc updated. (Other VICE 2-player titles — Beach Head, Hustler, Clowns, Kikstart — are alternating two-player, fully playable on one stick, so they stay.) - VICE-family controls docs corrected. The six controls pages (
c64/c128/c16/plus4/vic20/max) now document the actual numpad joystick (vice_joyport_type='1': numpad 8/2/4/6 = stick, 0/5 = fire) and the real libretro VICE keyboard map (Tab=CTRL,L Ctrl=C=,Page Up=RESTORE,Delete=↑,Insert=£, backquote=←,[/]=@/*,\==) — the previous pages described a cursor-key joystick and an Alt-based C= key that the bundle doesn't use. - Scope rule loosened: "8-bit era" → "8-bit feel". The test is now the aesthetic (sprite-based, chiptune, low-res look-and-sound), not the calendar. This brings the handhelds cleanly in — Game Boy/GBC (into 1998), Game Gear, Atari Lynx, and games as late as Shantae (2002) all feel 8-bit even though they post-date the old ~1975-1990 cutoff. 16-bit home consoles/computers (Genesis, SNES, Amiga, ST) remain out. README + wiki scope wording updated.
- C128 game sweep — replaced two non-launching titles.
kquest(Knight's Quest) andtetris(Tetris 128) are ML-first homebrews: the disk's first file is machine code at$4001with no BASIC autostart loader, so VICE'sLOAD"*",8,1:RUNcan't start them (RUN only runs BASIC; they drop toREADY.). Swapped both for cleanly-bootable 80-col VDC titles whose first file is a$1C01BASIC loader: Invaders (homebrew Space Invaders —Ffire,1/2move,Ppause) and Uniquest (homebrew fantasy RPG — seven cities, dungeons, 88 weapons/armour, 110 monsters; typed-command parser). Both confirmed to autostart and play. Menu,games.json, ROMs (.d64→.prg) and gamedocs updated; the other nine C128 titles all verified launching. (The other ML-first checks: all eight remaining disk/.prgtitles have BASIC-loader first files, so they autostart fine.) - C128 per-video-mode canvas scale. The 80-col VDC picture sits smaller in the 1084S glass than the 40-col VIC-II one, so
perGamenow tags<html>(gx-vdc/gx-vicii) and CSS picks the fill scale: VIC-II keeps the familyscale(1.01), VDC getsscale(1.26).
Fixed
- MSX (webmsx) rebuilt from scratch — was completely broken. The old bundle was WebMSX's 5.26 MB standalone all-in-one with the GenX controls-link
<script>injected inside the inline engine's body-HTML string with a raw</script>; the browser read that as closing the inline engine ~120 KB in, dumping the rest as plain text — the emulator never ran (pre-existing; unrelated to theemulators/→systems/rename, which only touched two<meta>URLs). Rebuilt from the official WebMSX 6.0 embedded build:wmsx.jsis the stock engine (a separate file, never edited) andindex.htmlis a small GenX wrapper. Auto-load works viaWMSX.ALLOW_URL_PARAMETERS(the engine reads the menu's?ROM=/?M=/?ANY=and maps them itself:ROM→CARTRIDGE1_URL,M→MACHINE,ANY→AUTODETECT_URL); the controls link is a normal<script>element after the engine (nothing can leak into it); WebMSX's control bar is hidden (#wmsx-bar { display:none }). Menu links, ROM library, and controls page unchanged. (Self-inflicted footgun avoided: a</script>literal in the wrapper's own JS comment will close the wrapper script too — keep closing-script-tags out of inline<script>comments.) - C128 boots again — the
stablevice_x128libretro core cold-boots to uninitialised-RAM garbage (was live; the other VICE cores are unaffected). Swappedsystems/_shared-ejs/ejs/data/cores/vice_x128-legacy-wasm.datato thenightlyEmulatorJS build, which boots to BASIC 7.0 cleanly. Both video modes work — 40-col VIC-II and 80-col VDC (vice_c128_video_outputvalues stay the bare keysVICII/VDC; the core's"VIC-II (40 cols)"/"VDC (80 cols)"strings are display labels, not settable values). Commercial 80-col titles (Star Fleet I) play through. Also dropped the C128scaleYframebuffer hack — it compensated for the stable core's odd 856×288 buffer; the nightly core renders a normal framebuffer, so C128 now uses the same#game canvas { height: 100% !important; transform: scale(1.01) }fit as the rest of the family. (Known per-game quirk, not the core: ML-direct homebrew likekquestloads viaLOAD"*",8,1but the autostart'sRUNcan't start a non-BASIC image, so it drops toREADY.)
Changed
- jsbeeb CUB monitor breathing room — the BBC Micro/Master monitor was flush against the top of the viewport. Widened the sizing JS's vertical inset (
r68→120 indist/assets/index-*.js) and added#cub-monitor { margin-top: 60px }so the monitor centres with ~60px of wallpaper above and below. (One change, both BBC machines — they sharedist/.) - Electron bezel breathing room — matched the CUB spacing on
systems/electron/play.html: capped.bezel-wrapheight at100dvh - 120pxso the Acorn monitor centres with ~60px above and below instead of filling the full height. - Atari 2600 migrated from Javatari to EmulatorJS + Stella (
stella2014libretro core, GPL-2.0). Javatari sized its own canvas — so it couldn't take a CRT bezel like the other bundles — and put GAME SELECT / RESET on browser-reservedF11/F12, leaving its on-screen console panel as the only reliable control. The newsystems/stella/bundle runs on the shared EJS framework like the 8 other EJS bundles: GenX controls the canvas, and the 2600's switches map to plain keys viaEJS_defaultControls—Space= fire,Enter= GAME RESET,V= GAME SELECT, arrows = joystick. Existing.a26ROMs reused unchanged. Engine count 20 → 19 (the 2600 folds into EmulatorJS); EJS bundles 8 → 9; sub-systems unchanged at 28. Gamedocs movedgamedocs/javatari/→gamedocs/stella/and rewritten to the keyboard scheme;fs.jsmenu links repointed; oldsystems/javatari/bundle (Javatari.js, AGPL-3.0) deleted. - PET migrated from VICE xpet to Thomas Skibo's pet2001 (BSD-2-Clause, vanilla JS, no WASM/libretro/EJS).
vice_xpetships with a hardcoded Business UK keyboard mapper that novicercresource overrides — symptom wasEnter→Pand scrambled letters. Newsystems/pet/runtime is ~90 lines ofplay.htmldriving Skibo'spet2001/*.js(9 files), bumps RAM to 32 KB, auto-typesload"*",8+runvia the petkeys queue with a per-gameautostartoverride ingames.json. Sub-system count unchanged at 28.
Added
- Commodore 1084S CRT bezel wired across the whole VICE family —
_shared/bezels/Commodore.png(1223×1104) now frames all six machines (c64/c128/c16/plus4/vic20/max), which share one monitor and one screen hole (12.3%/12.5%/76.0%×63.9%). Same EJS player-in-hole recipe as Stella:#gamesits in the hole with a slightly-larger black.screen-bgbehind it andCommodore.pngon top; the canvas is height-stretched to close EJS's letterbox andscale(1.01)to fill the glass. C128 keeps its existingscaleYframebuffer hack (nowscale(1.01) scaleY(2.784/1.333)). The VICE NumLock / RUN-STOP softkey banners areposition:fixed, so the flex-centred bezel is unaffected.Commodore.pngmoves staging → wired (now seven wired, three staging). (Note: the C128'sx128core boots to uninitialised-RAM garbage — a pre-existing issue, identical on the live site, unrelated to the bezel; tracked separately.) - Atari 2600 CRT bezel wired into
systems/stella/play.html—_shared/bezels/70s.png, a maintainer-keyed wood-cabinet console TV with legs (1240×855, the set isolated from its photo and floating on the 70s wallpaper, with a transparent screen hole at27.6%/13.1%/45.4%×51.6%). First bezel on an EmulatorJS bundle — EJS owns the canvas, so the screen hole holds#game(the EJS player) and EJS draws into it. Three layers: a black.screen-bgslightly larger than the hole (stops wallpaper bleeding through the cutout's soft edge) →#gameat the hole → bezel PNG on top. EJS fits the canvas preserving aspect, leaving a top/bottom letterbox; closed and sized it with#game canvas { height: 100% !important; transform: translateX(-18px) scale(0.85) }(height-stretch + a left nudge to centre + a shrink to sit the picture inside the glass). Sets the pattern for eventually bezeling the rest of the EJS family.70s.pngmoves staging → wired (now six wired, four staging). - Atari 400/800 CRT bezel wired into
systems/atari800/play.html—_shared/bezels/80s.png, an early-'80s wood-cabinet TV (maintainer-keyed from the OBS bezel library: transparent background + screen hole, resized 3872×2592 → 1680×1125). The set floats on the 70s wallpaper. Two-layer order (.screenclip box at the measured hole15.4%/21.3%/46.4%×52.8%with a black backdrop → bezel PNG on top), bezel sized at*1.25of the height-based width. - Stretch-to-fill, not CSS-scaled: atari800 renders its visible TV area with integer scaling that's quantised and viewport-dependent, so a CSS canvas scale tuned to one window doesn't hold on another. Instead the canvas sits at a plain 100% of the cutout and atari800 is told to fill it directly via
-stretch full -fit-screen both -image-aspect none -horiz-area tv -vert-area tv(passed through the existingModule.argumentsbuilder). Picture now meets all four cutout corners deterministically at any window size, on every game in the bundle. Also reworked the arg builder to append cart/disk args rather than reassigning, so the video args survive. - Amstrad CPC CRT bezel wired into
systems/cpc/play.html— the licence-cleared_shared/bezels/Amstrad.png(CPC464 + CTM640 monitor, 1502×992). Standard three-layer order (black backdrop → tiny8bit canvas at the screen cutout → bezel PNG on top), canvas centred and stretched to fill the cutout (left 24.85%/top 4.8%/46.3%×66.4%),#loadingoverlay tracking it, bezel scaled +5% (*1.05on the height-based width), 70s wallpaper behind. Carries a real CC-BY-SA 2.5 attribution comment (Bill Bertram) since this bezel is properly source-cleared. Fourth bezel to go live. - Overlay removal (rebuilt WASM): floooh's stock binary unconditionally draws a sokol-debugtext status bar (JOYSTICK/DISC/MOTOR/TRACK + frame timing) and a suspended-audio muted-speaker icon. Rather than masking them, rebuilt
cpc.js/cpc.wasmfromfloooh/chips-test(fibs,emsc-ninja-release): commented outdraw_status_bar()and hardcodeddisable_speaker_icon = trueinexamples/emus/cpc.c. Recipe atsystems/cpc/BUILDING-WASM.md. Audio auto-unlock burst kept so sound resumes on load. Supersedes the earlier black-strip mask. systems/cpc/BUILDING-WASM.md— build recipe for the patchedcpc.js/cpc.wasm(source, two-line patch, fibs config + build, install paths).- PET 2001 CRT bezel wired into
systems/pet/play.html—_shared/bezels/Pet.pngreplaced with a higher-res blue-trimmed PET 2001 frame (1024×771, maintainer-keyed from the local OBS bezel library). Standard three-layer bezel order (black backdrop → canvas at the detected screen cutout left 30.3%/top 20.5%/37.3%×35.4% → bezel PNG on top), 70s wallpaper behind, generic photographer-unknown credit comment at the foot. Third bezel to go live after PC and Acorn. - Star Trek (1977) added to the PET bundle as the replacement headline title — Mike Mayfield's defining BASIC space game, sourced from zimmers.net.
gamedocs/pet/startrek.html— per-game instructions for the new headline title (the?game=startrekcontrols link was 404ing without it). Gamedocs sweep stays complete at 281 pages.
Removed
gamedocs/pet/petrobot.html— orphaned PETSCII Robots gamedoc, left behind when the title was dropped from the PET bundle. No launcher orgames.jsonkey referenced it.- PETSCII Robots Shareware (2022) dropped from the PET bundle. Skibo's emulator has no 1541 disk-image support, no BASIC 4 / PET 4032 ROM, and no multi-file disk loader — three hard blockers that all three of PETSCII Robots' boot requirements need. The title is no longer shipped on any sub-system; its ATTRIBUTION/README credits were removed accordingly. Documented in detail at
wiki/Emulator-pet2001-Skibo. systems/_shared-ejs/ejs/data/cores/vice_xpet-legacy-wasm.data(1.3 MB) — the libretro VICE PET core, no longer referenced by any bundle. VICE-family shared dir drops from 5 cores to 4.
Fixed
- jsbeeb per-game gamedocs wired — the 20
gamedocs/jsbeeb/*.html(BBC Micro + Master) were runtime orphans: the Vitedist/index.htmlhardcodes the corner link to../controls.htmland the menu launches keyless?disc1=URLs, so the per-game gamedoc never resolved. Addedsystems/jsbeeb/genx-gamedoc-link.js— maps the disc filename (e.g.EliteMaster→master-elite) to the gamedoc key and rewrites the corner link'shrefon load; keyless BASIC / blank-Master launches fall through tocontrols.html. Wired intodist/index.htmlvia a deferred<script>. All 20 keys verified to map to existing files and serve 200. - BBC Elite gamedocs — front-view key relabelled to PC
F10—gamedocs/jsbeeb/elite.htmlandmaster-elite.htmlshowed the front view asF0, which has no PC-keyboard equivalent. Verified jsbeeb's keymap (i(k.F10,O.F0),i(k.F1,O.F1)…): BBCf1–f9map to PCF1–F91:1, BBCf0maps to PCF10. RelabelledF0→F10and corrected elite.html's keyboard note (it had implied anf0–f9→F1–F10block shift). - On-screen overlay sweep — audited every emulator (visual capture of all 24 bundles) for stray chrome. JtyOne (ZX81) showed a live
FPS: nnreadout — hidden (#emulator_status). The EmulatorJS bundles (VICE family, ColecoVision, NES, Atari 2600) leaked their control bar (play/pause/settings/fullscreen/volume) on mouse-move plus a right-click context menu — hidden via.ejs_menu_bar, .ejs_context_menu { display: none }in the sharedgenx-frame.css(harmless on the non-EJS bundles that also load it). Everything else already renders clean: js7800/apple2/xroar/jsbeeb strip their upstream chrome, the bezel bundles frame the screen, and the Vectrex screen overlay + jsspeccy/intellivision start gates are intentional (not chrome). (The 2600's Javatari-specific chrome work was superseded by the Stella migration below.) - NES (jsnes) gamedocs — corrected the keyboard footer on all 10 — the "Default keyboard mapping" line read
Z = A, X = B … SHIFT = SELECT, butjsnes/play.htmloverrides the EmulatorJS controls to B=z/ A=x(so Z=B, X=A) and leaves SELECT at the EJS default of V (not Shift). Fixed both errors across every NES gamedoc so the A/B keys and SELECT key are right. - C64 Elite gamedoc — controls rewritten from the manual — the page had been cloned from the BBC layout: views/screens were listed on
F0–F8(the C64 has noF0, and its screens live on the number row), and flight was on the numpad. Rewrote against the Firebird 1985 C64 manual (cross-checked with c64-wiki): views on the four C64 function keysF1/F3/F5/F7, screens on the number row (4galactic chart,5local,6data,7market,8status,9inventory,1/2/3buy/sell/equip), keyboard flight (</>roll,S/Xdive/climb,Space/?speed). Translated the two C64-specific keys to what VICE actually delivers on a PC: energy bomb = Left Ctrl (the C64 Commodore key), intergalactic jump = Tab+H (the C64 CTRL key). (Left/right of theF5/F7side views left unstated — sources conflict.) - All five Elite gamedocs audited: jsbeeb Micro + Master (F0→F10, above), Amstrad CPC (number-key views — already correct), Acorn Electron (
Alt=FUNC, verified correct againstelectron/keyboard.js), C64 (this rewrite). - Audit + doc sync (12/06/2026) — post-Stella-migration sweep. No orphan files: javatari fully removed, all 7 EJS cores referenced, the
stella/bundle wired (10 gamedocs = 10games.jsonkeys), no junk/backups. Stale-text fixes: thegenx-ejs-boot.jsheader still said "7 VICE-family + Coleco bundles" (stale since the PET migration off VICE, and missing Stella) — corrected to "6 VICE + ColecoVision + Atari 2600 (8 genxBootEJS users; NES keeps its own boot)". Wiki had five stale EJS-bundle-count claims ("8 bundles share" / "Eight of these") — bumped to nine and the cores list given Stella; the File-Structure bezel line ("PC.png live; others staging") refreshed to the five wired. README/ATTRIBUTION verified current (19 engines / 28 sub-systems / 9 EJS bundles; bezel section five-wired). - Audit + doc sync (11/06/2026) — orphan-file and stale-text sweep. Findings: (1)
ATTRIBUTION.mdbezel section said "four wired" — corrected to five (80s.png→ atari800 shipped this session) and refreshed the80s.pngrow (it was swapped to the wood-cabinet OBS TV) with the no-graphic-provenance policy noted. (2) jsbeeb's 20 per-gamegamedocs/jsbeeb/*.htmlwere runtime orphans — now wired (see the entry above) rather than deleted. (3) The wiki's_genxGameKeycontrols-link mechanism is fictional — it exists nowhere in code; cpc/jtyone gamedocs actually resolve because their URL rewrite sits behind an awaitedfetch, so the deferredgenx-controls-link.jsreads?game=first. Wiki corrected separately. No orphan assets/cores/ROMs found elsewhere; README counts (20 engines / 28 sub-systems / 8 EJS bundles) verified current. - Amstrad CPC controls page rewritten — the old
controls.htmlclaimed the cursor keys/Space were mapped to the 9-pin joystick port. No game passes?joystick, so the port isn't emulated; keys arrive as the CPC's own keyboard. Reframed as host→CPC keyboard with the full mapping fromcpc.c(cursor keys, Space, Enter, Shift, Esc/BREAK, DEL/clear, F1–F10 keypad) and the F1 browser-intercept caveat. - Elite (CPC) gamedoc rewritten — the previous controls were BBC/C64-derived (F1–F4 views, F5–F9 charts). Transcribed the actual Amstrad CPC Firebird quick-key card: views
1–4, charts/trading on the number row (5–9,0,FFind Planet), flightS/X/</>or arrows,Jtorus /Hhyperspace /G then Hintergalactic, combatA/T/M/U/E/Tab/Esc, gameDel/Clr/@, plus the frozen-only option toggles. Also corrected the start state (begins docked,1to launch), the save-only-while-docked tip, and the single-planet-per-system mining note. - PET keyboard, full rewrite —
Enternow produces Return, letters type as themselves, no stuck keys, no input delay. (Root cause was upstream-libretro and unfixable without recompiling the core; the migration above sidesteps it.) - Frogger boot crash on PET — Skibo's
pet2001io.jsreads VIA timer-2 latch-low (via_t2ll) at line 679 but never declares it withvar. In sloppy mode the first write at line 552 would implicit-global it, but Frogger reads before writing, so the read crashes withReferenceError. Added the missingvar via_t2ll = 0xff;declaration plus a matching reset line. Two-line patch, fixes Frogger and any future title that reads T2 before writing. - Doc sync after PET migration —
README.md,ATTRIBUTION.md, the PET menu inprompt/javascript/fs.js(Star Trek slotted in at position 1, PETSCII Robots row removed, numbering shifted), and four wiki pages (Roadmap,File-Structure,Virtual-Filesystem,Emulator-EmulatorJS-NES-FCEUmm) all updated to describe PET as Skibo / 4 VICE cores instead of 5. - Audit doc sweep (10/06/2026) — the PET migration pushed the engine count 19 → 20 (pet2001 is now a standalone engine, no longer riding EmulatorJS). Corrected the lagging "19 emulators" / "5 VICE cores" / "nine bundles share EJS" claims across
README.md,Project-Overview,Home,Roadmap,Emulators,Emulator-VICE-family, andFile-Structure. Untracked staged bezel_shared/bezels/Pet.pngcommitted to complete the set. Refreshed the ATTRIBUTION bezel section: 10 bezels now,PC.png+Acorn.pngwired (the rest staging),Pet.pngrow added. Added the generic "original photographer unknown — open an issue if you recognise your work" bezel credit as an HTML comment at the foot ofprompt/index.html(PC) andsystems/electron/play.html(Acorn) — comment rather than visible text since both are fullscreen immersive pages.
Added
- Electron (ElkJS) bezel + audio auto-unlock —
systems/electron/play.htmlnow wraps the canvas in the standard three-layer order (.screen-bgz:1 → canvas z:2 →Acorn.pngz:3) inside a.bezel-wrapsized viamin(100vw, calc(100dvh * 835 / 719)). Body gets the 70s wallpaper. Sound:_autoUnlockSound()fireselkjs.soundToggle()at 0/100/500/1000/2000 ms on DOMContentLoaded; the original keydown fallback kicks in only if the burst missed the window.open activation window. Second emulator to validate the bezel pattern after jsbeeb. - jsbeeb dist chrome strip + bezel order + audio auto-unlock —
dist/index.htmlhides upstream#header-barand#leds; wallpaper paints on body; standard three-layer order inside#cub-monitor(black::beforeatinset: 5%z:1 → canvas z:2 → CUB PNG z:3,pointer-events:noneon the PNG so clicks reach the canvas). Audio unlock: jsbeeb only resumes itsAudioContextonmousedownto#audio-warning, so we (a) forward any page mousedown to the warning and (b) fire optimistic mousedowns at 0/100/500/1000/2000 ms onDOMContentLoadedso the user-gesture from the prompt'swindow.open()click can propagate through. Confirmed working 10/06/2026. - 70s tile wallpaper —
systems/_shared/textures/70s-bg.png(1016×960, seamless 70s arrow-arch pattern) tiled at 220px as the body background. Applied viagenx-controls.cssso the DOS prompt page + all gamedocs inherit. Surrounds the centred IBM PC bezel on the prompt view; sits behind the centred.wrapon gamedoc pages. body.controls-pageoverride ingenx-controls.css— suppresses the wallpaper on the 24 per-platformcontrols.htmlpages so the keyboard tables stay on a flat#0a0a0abackground. The class is set on each<body>directly. (Superseded — see "Wallpaper dropped from all doc pages" below.)- Centred menu boxes — all 38 menu screens in
prompt/javascript/fs.jsnow centre their box-drawing artwork in the 80-column grid (per-box indent computed from the box's max width). TheC:\>prompt line itself stays left-aligned. - IBM PC bezel for the DOS prompt —
prompt/index.htmlnow embeds the sharedPC.pngbezel and scales the 80×25 grid into the screen cutout. Non-uniformtransform: scale(sx, sy)stretches the 960×300 prompt to fill the cutout in both axes — period-accurate for VGA text mode which used non-square pixels. Auto-scroll via MutationObserver keeps the cursor row visible as new lines render. Resizes cleanly with the browser window. - Three explicit layers behind the bezel —
.screen-bg(back, 90% of the bezel-wrap, solid black) →.prompt-fit(canvas, sized to the cutout, the prompt grid lives here) →.bezel-img(front, PC.png on top). The black backdrop blocks the wallpaper from bleeding through the PNG's anti-aliased cutout boundary. - AMI Megatrends logo proportions match the stretched grid — sized to 205×51 (½ width, ⅜ height of the source 409×136) so it doesn't appear elongated when the rest of the screen is non-uniformly scaled.
Removed
- Tseng ET4000 video BIOS POST lines from the boot sequence —
init.jsnow goes straight from the AMI logo to the AMIBIOS system POST.
Changed
- Wallpaper dropped from all doc pages —
_shared/genx-controls.cssbody rule no longer paints the 70s tile. Removes the wallpaper from all 24controls.htmlpages and all 281gamedocs/*/*.htmlpages in one shot; keyboard tables and game instructions now sit on a flat#0a0a0abackground, which keeps the dense table content legible. The earlierbody.controls-pageoverride + class on each controls.html body is now redundant — both removed. Wallpaper still tiles on the DOS prompt, jsbeeb dist, and Electron play.html.
Fixed
- Electron function-key references in
gamedocs/electron/elite.html— the BBC Elite manual's f0–f9 labels were carried over wholesale, but the Electron has no F-keys at all. ElkJS already maps PC Alt → Electron FUNC (the orange key), which is how Electron software reaches f0–f9 in practice. Rewrote all 9 references in Elite to use Alt+N directly. controls.html keyboard table now spells out the Alt → FUNC mapping with the BBC f7 → Alt+7 example. - Electron sound (upstream
sound.soundInitmissing) —elkjs.js:143callssound.soundInit()on firstsoundToggle(), but the method was never defined insound.js— upstream's keydown path threwTypeErrorand audio never enabled for anyone. Addedself.soundInit = function () { if (audioContext.state === 'suspended') audioContext.resume(); }tosound.js. Combined with the_autoUnlockSoundburst from DOMContentLoaded, audio now starts on tab open via the prompt'swindow.openuser-activation propagation. - Controls-link readability over wallpaper —
genx-controls-link.cssdropped the element-levelopacity: 0.5+ translucentrgba(0, 0, 0, 0.55)background combo (which let the 70s pattern bleed through). Now solid#000background with a thin amber border, mutedrgba(255, 176, 0, 0.75)text. Hover brightens to full#ff8800on both text and border. Affects every emulator entry HTML site-wide. - Double prompt after closing an emulator tab —
commands-core.jsclose-handler now just re-runsmenuin place instead ofcd ..; menu. The old sequence trampolined through the parent's menu.bat (which itselfcds into the games dir and re-runsmenu), and the trailingecho.on each layer toggledbEchoOffplus triggered an extraprompt()at the end ofhandleCmd, producing two prompt lines on return. - Audit sync (09/06/2026) —
ATTRIBUTION.mdbezel section updated to reflect PC.png landing on the DOS prompt. Staleinit.jsPOST-flow comment that still referenced the (removed) Tseng line trimmed. No code-path changes.
Changed
- Site JS beautified —
prompt/javascript/*.js,systems/_shared/*.js,systems/_shared-ejs/genx-ejs-boot.js, and the inline controls-link injector inapple2/play.html. Run throughjs-beautify(4-space indent). No behaviour changes; same modules, same exports.
Fixed
- Vectrex focus-loss auto-resume — synthetic Escape
keyupdispatched onwindow.focustriggers the runtime's existingMu()handler, which closes the (internally-open) menu and callsstart()after 300 ms. No more manual ESC press needed after clicking away. - JS7800 F-key reference — platform
controls.html+ 10 gamedoc pages had F3 and F4 swapped. F3 is the Reset switch (= start the game on most carts); F4 is Pause. Corrected throughout.
Changed
- README rewritten in casual journey-style voice to match the wiki. No content removed; same lineup table, URL patterns, and licence list, just framed as a project narrative.
- CHANGELOG de-cluttered — trimmed verbose entries to release-note form. Deep recipes live in the wiki now.
Added
- Mobile-device block — touch-only devices see a full-screen "Desktop Only" overlay via
@media (pointer: coarse), (hover: none)+body::before. 24 emulator pages inherit it from_shared/genx-noscript.css; three outliers (root + prompt + jsbeeb dist index) get an inline copy. z-index 999999 sits above the corner controls link. - Loosened to comma (OR) shortly after first commit — iPadOS reports
pointer: coarse+hover: hoverso theandform was skipping iPads.
Removed
- js99er upstream-UI orphans (11 files, ~200 KB) at
systems/js99er/—ams.js,googledrive.js, four bootstrap variants,fileSaver.js,imageMapResizer.js, two unused zip features. Keptlib/zip/inflate.js(it's the.rpkworker).
Fixed
- Fourth doc-sync audit (08/06/2026) — README MSX line still mentioned MSX2+; bumped Virtual-Filesystem sub-system count 27 → 28; dropped TI-99/4A from Roadmap "Plausible" (now shipped).
Added
- Texas Instruments TI-99/4A at
systems/js99er/(Rasmus Moustgaard's Js99'er, vanilla-JS, GPL-2.0) + 10.rpkcarts. New HOMECOMP entry TEXAS / TI99 (1979). play.html falls back to the TI title screen when no cart is specified. - TI-99/4A gamedocs (10 pages). Parsec gets a laser-overheat note; Tunnels of Doom has a separate combat-key table; Microsurgeon gets a tool-select reference. Gamedocs sweep stays complete: 28 / 28 sub-systems, 281 pages.
Changed
- HOMECOMP parent menu — added row 9 "Texas (1979) TI99" between Tandy and the back-row sentinel. Column widths preserved at 45 chars.
Added
- Tandy CoCo gamedocs (10 pages) at
gamedocs/xroar/. Daggorath gets a dedicated typed-command reference. XRoar preserves?game=so nofs.jswiring needed. Gamedocs sweep complete: 27 / 27 sub-systems, 271 pages.
Added
- MSX2 gamedocs (10 pages) at
gamedocs/webmsx/— covers Konami's MSX2 peak (Vampire Killer, Metal Gear, etc.) through Compile's Aleste and SD Snatcher. Each.batlauncher appends&game=<key>so the lowercase resolver picks up the right page.
Changed
prompt/javascript/fs.js— appended&game=<key>to MSX2.batlaunchers (including SD Snatcher's?ANY=…disk-set variant). Pure documentation glue.
Added
- MSX1 gamedocs (10 pages) at
gamedocs/webmsx/— 10 Konami MSX cartridges covering the formative 1983-86 era..batlaunchers append&game=<key>because WebMSX's?ROM=is uppercase andURLSearchParams.get('rom')wouldn't match.
Changed
prompt/javascript/fs.js— appended&game=<key>to MSX1.batlaunchers (documentation glue).
Added
- Commodore 128 gamedocs (10 pages) at
gamedocs/c128/. Each page indicates VICII (40-col) vs VDC (80-col), matching thevideofield ingames.json. - Commodore Plus/4 gamedocs (10 pages) at
gamedocs/plus4/. Auto-linked from each game's controls badge.
Removed
- jsvecx upstream alternate entry points at
systems/jsvecx/—rtm.html,seamless.html,vectrex.html, two overlays + 7 JS/CSS dependents (~127 KB). Keptjs/rtm.js+css/rtm.css(Show Chips), fullbios//img//roms/. HTTP 200 onindex.html+ all menu URLs confirmed post-delete.
Added
systems/apple1/controls.html— Apple I keyboard / Woz Monitor / Integer BASIC reference. Resolves the 404 in the Woz Monitor prompt corner link.
Fixed
- Third doc-sync audit (08/06/2026) — ATTRIBUTION ElkJS jQuery row had wrong path + version; README Vectrex URL pattern missing
&game=<key>; wiki MSX list still mentioned MSX2+; MAX cart count, jsvecx ROM count, gamedocs progress numbers refreshed. - Second doc-sync audit (07/06/2026) — README atari800 "10 disk/cart titles" was 11 (Choplifter added); MAX line "8 .crt carts" → 10 carts (Mole Attack + Money Wars); atari800 AltirraOS clarified as embedded in WASM not separate ROM; EmulatorJS sharing line missing FCEUmm; ATTRIBUTION rows for the two nonexistent AltirraOS
.rompaths removed. - First doc-sync audit (07/06/2026) — README
_shared-ejs/missing FCEUmm; Vectrex "~100 ROMs" was ~500; ATTRIBUTION cores rows pointed at pre-dedupe path; ColecoVision BIOS path corrected; wiki Emulators intro 8 → 9 bundles; shared-dir size 9 MB → 11 MB. - PET menu BASIC label — said "BASIC 4 prompt"; the entry boots PET 3032 (BASIC 2). Swapped to "BASIC 2 prompt"; same 14-char length.
systems/pet/controls.htmlwas stale — described 4032/BASIC 4 withDIRECTORY/DLOAD"name"shortcuts that don't exist in BASIC 2. Rewritten for BASIC 2 with the PETSCII Robots 4032 override called out.systems/cpc/controls.htmlwas stale — described CrocoDS + EJS toolbar; actual bundle is tiny8bit. Rewritten to match the real bundle (PgUp/PgDn→Space remap, page-reload reset, no in-canvas reset button).
Changed
- Top-level EMULATOR LAUNCHER spacing — added a blank row between each entry. Previously only the WIKI entry had a separator above it.
Added
- MAX gets 2 more carts: Mole Attack + Money Wars — bank-extracted from the MultiMax EasyFlash compilation by screen-code PETSCII fingerprinting (bank 17 = "MOLE", bank 18 = "MONEY"). Wrapped as 8 KB Ultimax-mode
.crts. Commercial count: 8 → 10. Tried Mr. T.N.T. first (turned out to be a 1983 HesWare C64 cart, not MAX); Sea Wolf + Le Mans present on MultiMax but their banks lack identifiable strings.
Changed
systems/atari800/play.htmlcanvas fills viewport at 4:3 (width: min(98vw, calc(98vh * 4 / 3))) instead of rendering at native 336×240. Triedtransform: scale(2)first; canvas overflowedbody{overflow:hidden}and only a corner pixel showed.
Added
- Choplifter! added to Atari 400 — 16K Brøderbund cart (1982),
cartType: 2. 11th game in the Atari 400 menu. Newgamedocs/atari800/chopliftr.html(shared between 400 + 800XL). - Commodore 16, C64, MAX, VIC-20, PET gamedocs (10 each) — same template as the other platforms. C64 notable: Impossible Mission's "Stay a while" digitised sample puzzle, Elite's full Cobra Mk III keymap, Wizball's colour-mix mechanic, Last Ninja walk/combat toggle. PET notable: PETSCII Robots' per-game
model: 4032override and ~30 s authentic 1541 boot sound. - Amstrad CPC gamedocs (10 pages) at
gamedocs/cpc/. Each documents the autoboot behaviour (tiny8bit's sokol_argsinput=run"…pre-types the boot command)._genxGameKeystash not yet wired; corner link still resolves because original?game=is read before the rewrite.
Removed
- Orphan upstream doc files —
_shared-ejs/ejs/data/compression/README.md,localization/README.md,jsbeeb/dist/roms/README. Per the no-docs-in-bundles rule. - Half-done JtyOne ZX80 wiring — reverted. JtyOne's ZX80 mode has a display-sync bug (the
dstate machine is gated on0 != zx81opts.machine, so machine==0 never updates). zame-dev'sjs-zx8xworks but lacks an SPDX header.
Added
- ZX81 gamedocs (10 pages) at
gamedocs/jtyone/. 3D Monster Maze page notes the no-sound design; Chess (Psion) covers the coordinate-notation parser. Sinclair family now complete in the gamedocs sweep. - ZX Spectrum gamedocs (10 pages) at
gamedocs/jsspeccy/. Knight Lore documents the Filmation isometric engine; Skool Daze covers the four-teacher puzzle. - BBC Master gamedocs (10 pages) at
gamedocs/jsbeeb/, prefixedmaster-to avoid collision with BBC Micro pages in the sharedjsbeeb/platform dir. Acorn family now complete in the gamedocs sweep. - Acorn Electron gamedocs (10 pages) at
gamedocs/electron/. Filenames match the?game=<key>URL keys ElkJS uses (chuckie.htmlnotchuckegg.html). Electron-specific footer notes the single-ULA quirks vs the BBC original. - LGR attribution for the DOS terminal, virtual filesystem, and 12×12 CP437 font sprite system. The interactive prompt under
prompt/, thefs.jsvirtualC:drive, the command dispatcher, and the CP437 sprite font originate from LGR's DOS-prompt project; GenX-DOS extends that base. - BBC Micro gamedocs (10 pages) at
gamedocs/jsbeeb/. Elite gets the full F0-F9 + chart + missile/ECM/hyperspace reference; Thrust documents the gravity/pod-swing physics; Exile flags the open-world map-as-you-go nature. Wiring caveat: jsbeeb's?disc1=…&autobootURL carries no?game=, so the corner link still falls back tocontrols.html. - Atari 400 gamedocs (9 new pages) at
gamedocs/atari800/— Star Raiders already covered from the 800XL pass. Atari 8-bit family now complete in the gamedocs sweep. ATTRIBUTION.mdat the repo root — canonical record of every third-party emulator, BIOS, ROM, bezel, font, and dependency, with source URL + author + licence. README's## Licensestays as a quick-reference.- Atari 800XL gamedocs (10 pages) at
gamedocs/atari800/. First home-computer platform completed in the gamedocs sweep. - Vectrex gamedocs (11 pages) at
gamedocs/jsvecx/.fs.jsbat-links now pass&game=<key>(jsvecx ignores it) so the controls-link resolver picks up the clean key first instead of the messy?rom=Commercial/...path. - Atari 7800 gamedocs (10 pages) at
gamedocs/js7800/. js7800 preserves?game=alongside the auto-added?cart=so no extra wiring. - Atari 2600 gamedocs (10 pages) at
gamedocs/javatari/. - NES gamedocs (10 pages) at
gamedocs/jsnes/. - Intellivision gamedocs (10 pages) at
gamedocs/intv/. Console-specific footer documents the 16-direction disc + 3 side buttons + 12-key keypad. - ColecoVision gamedocs (10 pages) at
gamedocs/coleco/. - Odyssey² gamedocs (10 pages) at
gamedocs/odyssey2/. - Magnavox Odyssey² at
systems/odyssey2/via libretro-o2em compiled to WASM (GPL-2.0+). EJS path rejected first — vanilla libretro cores fail because EJS forks each core to add EJS-specific helpers (system_restart,simulate_input, etc.). Custom SDL2/emscripten frontend (frontend.c, ~200 LOC) statically linked. 10 first-party + Imagic titles.o2rom.binBIOS bundled. - Acorn Electron at
systems/electron/via ElkJS (Darren Coles). 10 UEF snapshots + Electron BASIC. CRT raster scanline effect removed fromdisplay.js(row doubling). - BBC Master 128 under ACORN — same jsbeeb with
?model=Master. 10 Master-enhanced titles (Elite Master uses DSD for*DRIVE 2). - Apple I restored under APPLE parent menu (Apple I + Apple ][+). Hint text overlay hidden via CSS.
- Per-game instruction pages at
gamedocs/<platform>/<key>.html.genx-controls-link.jsreads?game=/?tape=/?rom=and routes to the matching page, falling back tocontrols.htmlfor prompt entries. Completed: Apple I, Apple ][. - Amstrad CPC at
systems/cpc/via EmulatorJS + Caprice32 (later swapped to tiny8bit — see below). CPC 6128 + Locomotive BASIC 1.1. 10 first-in-series classics. - Mattel Intellivision at
systems/intv/via jzIntv WASM. EJS doesn't ship an Intellivision core, so this bundle has its own emscripten Module loader +Module.launchJzintv()API. Customdesk.kbdadds arrow→disc + numpad→keypad bindings the stock map omits. BIOS (exec.bin + grom.bin, ©1979 Mattel) bundle-local. - Commodore 128 at
systems/c128/via VICE x128 — seventh and final VICE-family sub-system. Native mode (vice_c128_go64: 'disabled'). Per-gamevideofield togglesVICII(40-col) vsVDC(80-col). CSSscaleY(2.088)hack on the canvas works around VICE x128's 856×288 framebuffer letterboxing inside the 4:3 container. _shared/genx-vice-softkeys.js— keyboard remap + soft button for VICE RUN/STOP. Browsers capture Esc before the libretro keyboard callback sees it, so synthetic Escape gets dispatched from three fallbacks: Scroll Lock, Pause/Break, and a top-left soft button. Wired into all 7 VICE play.html.- Commodore PET at
systems/pet/via VICE xpet. Default = model 3032 (BASIC 2 chargen); 4032 broke 9/10 bundled games with garbled PETSCII. PETSCII Robots gets a per-gamemodeloverride (needs BASIC 4 + 32K + ships TILESET.PET). 10 games sourced fromzimmers.net+ PETSCII Robots from the8bitguy.com. Skipped: Microchess 2.0, 3D Star Trek, Cosmiads (non-standard load addresses VICE doesn't autostart). - Commodore MAX Machine at
systems/max/via VICE x64 in Ultimax mode (vice_c64_model: 'ultimax') — 2 KB RAM, no built-in BASIC. 8 carts + MAX BASIC. Of the 8 carts, 5 were bank-extracted from the MultiMax EasyFlash compilation. Wrapped as proper Ultimax-mode.crts; 16K MultiMax banks split $8000+$A000 in EasyFlash addressing become $8000+$E000 in Ultimax mode. - Commodore 16 at
systems/c16/via VICE xplus4 in C16 mode (vice_plus4_model: 'c16pal') — 16K RAM. 10 first-in-series UK-budget titles from plus4world.com. Bundle structure cloned fromsystems/plus4/so the self-containment patches carry over for free. - Commodore Plus/4 at
systems/plus4/via VICE xplus4. 10 first-in-series classics. BASIC entry uses a Plus/4-specific empty.prg (load address$1001for BASIC 3.5). - Commodore VIC-20 at
systems/vic20/via VICE xvic. 10 cart classics.vice_vic20_memory_expansions: 'all'gives full 35K expansion. - Commodore 64 at
systems/c64/via EmulatorJS + VICE x64. 10.d64classics + BASIC. Replaces the prior archive.org-iframe wrapper. Long iteration history (vc64web → chips → IA iframe → EmulatorJS) recorded in memory. - Atari 400 — reuses the atari800 WASM build,
?machine=atariboots OS-B/AltirraOS-800 instead of XL's AltirraOS-XL. 10 cart-era classics distinct from the 800XL list. - Atari 800XL at
systems/atari800/— atari800 v5.2.0 built from source to WASM via emscripten. AltirraOS-XL 3.41 baked in (--enable-altirra_bios). 10 first-in-series classics. Star Raiders gotcha: thea8b_Star_Raiders_*_k_file8.7 KB.atris a cart-in-disk wrapper that boots to a CIM; switched to raw 8 KB.rom+-cart-type 1. - Per-emulator controls reference pages at
systems/<name>/controls.html. Shared dark-amber DOS-flavoured style. - Corner controls link on every emulator's entry HTML — fixed bottom-right, semi-transparent, amber, Wikipedia-style external-link SVG icon. Single shared
.gx-controls-linkclass. - Atari ST at
systems/estyjs/via EstyJS 2.0 (later removed in scope tightening). EmuTOS bundled. 14 JS modules inlined in upstream order, thenestyjs.openFloppyFile('A', urlString)after 1.5s. - ATARI\ST submenu with 10 first-in-series ST classics (later removed).
- Sinclair ZX81 at
systems/jtyone/via JtyOne. Three gotchas: custom.hextape format (xxd -p | tr -d '\n');FileToLoadopens ROM URLs with a hardcoded leading slash; the error path references an undefinedstatusLabel. - ZX81 submenu — 10 native classics from
zx81stuff.org.uk(~140 KB total). - Sinclair Spectrum at
systems/jsspeccy/via JSSpeccy 3 v3.2 (WASM Z80 in Web Worker). 5 ROMs + 5 tape-loader SZX snapshots. Quirk: despiteautoStart: true, JSSpeccy3 always shows a play-button overlay because Web Audio needs a user gesture. - SPECTRUM submenu — 10 first-in-series
.z80snapshots (instant boot past the tape-loading screen). - Atari 7800 at
systems/js7800/via JS7800 v0.0.9. Gotcha: upstream shipsbupboop.wasm(~590 KB YM-2151 emulator) referenced bybupboop.jsbut not listed in the<script>tags — easy to miss; without it,RuntimeError: aborton every cart load. - ATARI 7800 sub-system restored under CONSOLE\ATARI. 10 first-in-series / arcade-port classics.
- Tandy Color Computer at
systems/xroar/via XRoar v1.10. Three gotchas: (1) WASM doesn't ship system ROMs — mirror them alongside; (2) requests use absolute paths like/d64_1.rom, needs aModule.locateFileshim; (3) upstream defines 15ui_*callbacks the WASM invokes — without them, silent halt. Stubbed all 15 as no-ops. - COCO menu — 10 cartridge classics + PROMPT. Gotcha: CCA's
xroar-online/deploy is CORS-locked to6809.org.ukso we mirror, never hotlink. - Acorn Archimedes at
systems/archimedes-live/(later removed in scope tightening). Local-domain fallback paths meant no patches needed. - ARCHIMEDES menu with 10 titles + DESKTOP entry (RISC OS is GUI, not PROMPT). Lander = the first-ever Archimedes game.
- MSX at
systems/webmsx/via WebMSX. Single 5 MBindex.htmlwith engine + UI + BIOSes inlined. Stripped Google Analytics. - MSX menu, later split into MSX1 + MSX2 sub-systems (10 + 10 Konami carts).
- DUKE submenu under EMULATORS\DOS — Duke Nukem 1/2/3D (later removed in scope tightening).
- KEEN submenu under EMULATORS\DOS — Commander Keen 1-6 + Keen Dreams (later removed in scope tightening).
- SMITH ENGINEERING category under CONSOLE — Vectrex at
systems/jsvecx/. 10 commercial classics. - Javatari at
systems/javatari/(AGPL-3.0, pure-JS Atari 2600). 10-entry catalogue. - lrusso/Genesis at
systems/genesis/(later removed in scope tightening). 15-entry Genesis catalogue. - JSBeeb at
systems/jsbeeb/v1.12.0;dist/built locally. 15 BBC discs same-origin (nostairwaytohell.comruntime fetches). - JSNES at
systems/jsnes/v2.1.0. 18 NES ROMs. EmulatorJS attempted first and dropped — its loader's"../"path-prepend rendered a blank screen. find <word>/find "<phrase>"— walks the virtual FS recursively, parses eachmenu.batfor human-readable titles, reportsGAMES+MENUSsections.serve.sh— picks port 8765, traps SIGINT, opens browser to/prompt/.<noscript>overlay on all HTML entry points — fixed-position black-on-grey monospace.- Single-page boot animation — AMIBIOS POST, 4 s pause, System Configuration table, EMULATOR LAUNCHER drawn below (no
cls, table stays on screen alongside the menu like a real DOS boot). Tseng Labs ET4000 video BIOS line prepended; memory test animates as a 4-digit counter every 32 ms to8064 KB OK.
Changed
- ATTRIBUTION.md bezel section expanded — the 8 OBS bezels were sourced via Reddit/forums; EXIF stripped, original photographers unreachable. Hardware identified by visible markings (Microvitec CUB, IBM 5153 CGA, Commodore 1084S, Apple Monitor ///). Wikimedia replacement candidates logged where available.
- Amstrad bezel — desk-shot swapped for a tight CTM640 cutout (Wikimedia Commons CC-BY-SA 2.5, Bill Bertram). Screen cutout now dominates the frame.
- Bezel staging — replaced 8 auto-named stock images with 9 cleanly-named PNGs. Pure asset swap.
- NES Duck Hunt → Super Mario Bros. 2 (1988) — Duck Hunt needs the Zapper, which
play.htmldoesn't wire. commands-core.jsfind()comment — example string referenced the removed Genesis bundle. Swapped to "Cybernes".- Scope rule formalised: 8-bit era only. Cutoff is era, not strict bit-width. Intellivision (CP1610 16-bit ALU) is in; Genesis/SNES/ST/Amiga/Mac/Archimedes are out.
- Vectrex
#menuoverlay hidden via CSS. Focus-loss pause documented incontrols.html+ 11 gamedoc footers (runtimestartsymbol isn't reachable from outer scope). - Vectrex fs.js bat-links now append
&game=<key>so the gamedocs resolver gets a clean key. - All game menus reformatted to 4-column
# Title (Year) CODE, sorted by year ascending, alphabetical within year. 600 echo rows verified at exactly 45 chars across 26 platforms. - ZX81, NES, Vectrex, ColecoVision, Intellivision, CoCo, Atari 2600, Atari 7800 menus — reformatted with researched release years, re-sorted, bat-file order remapped.
- BBC Master "By Fair or Foul" → "Fair or Foul" — single-distinctive-form style match.
- Duke Nukem + Commander Keen submenus — inline
(YYYY)moved to year column. - Top-level HOMECOMP + CONSOLE menus gained
(YYYY)column — earliest 8-bit machine per manufacturer. - HOMECOMP + CONSOLE sorted alphabetically (non-recursive).
- Platform parent menus normalised to
(YYYY) CODE—[GAMES]markers removed; Sinclair reordered so ZX81 (1981) precedes Spectrum (1982). - Master-Enhanced Titles masthead — was 46 chars; back to 45.
- Vectrex Mine Storm row — was 44 chars; back to 45.
- C128 indie release dates researched —
(home)→(indie). 128 Crush 1985, Knight's Quest 1991, Tetris 128 1991 confirmed from internal stamps. Phazer, Rockfall 128, Wumpus 2.0, World at War have no stamp — fall back to zimmers.net mtimes. - ACORN parent menu created — BBC Micro, Electron, Master grouped under one ACORN entry.
- HOMECOMP grouped by manufacturer, sorted by release date. "Atari Consoles" / "Atari Home Computers" shortened to "Atari".
- CONSOLE sorted by release date.
- Vectrex Mine Storm moved to built-in slot (#11) since it's the bundled ROM. Scramble (1982) added as game #10 to fill the freed slot.
- 7 off-centre menu mastheads fixed — Commander Keen, Master-Enhanced, PET, C128, Atari 400, MSX1, MSX2.
- Amstrad CPC core swapped: EmulatorJS + Caprice32 → floooh/tiny8bit (MIT). cap32 aborted with
getControllerPortInfo undefined; crocods autobooted but exposed no skip-catalog API; cpcbox was minified+obfuscated. tiny8bit takes?file=+?input=URL params via sokol_args; play.html rewrites our?game=before WASM init. PgUp/PgDn remapped to fire (synthetic Space). - CPC Sorcery → Elite (1985 Firebird). Sorcery is French-only.
- Drive-change commands (
A:,D:, etc.) now reply "Drive not ready." Period-correct DOS message;C:stays silent. - NES emulator swapped:
bfirsh/jsnesv2.1.0 → EmulatorJS + FCEUmm. Audio quality (jsnes usedScriptProcessorNode). Dir name kept to avoid everyfs.jslink changing.EJS_defaultControlsswaps B/A onx/zto preserve previous muscle memory. - Flattened single-platform manufacturer menus in CONSOLE/HOMECOMP — removed the pass-through middle level for NES, GENESIS, INTV, CVISION, ODYSSEY2, VECTREX, COCO.
- "Odyssey 2" → "Odyssey²" in all CONSOLE menus. The renderer maps JS char codes to sprite indices directly, so the menu strings store
ý(U+00FD = 253) which renders as the CP437 superscript-2. find odyssey…matches the Odyssey² entry regardless of suffix.- Investigated suppressing the visible
RUN+ duplicateREADY.on VICE BASIC entries. Tried 6 approaches (libretrovice_autostart='disabled', EJS null-EJS_gameUrlguard,disableLocalStorage,PRINT CHR$(147),10 SYS <reset-vector>). All 6 broke a different machine. Reverted to the 4-byteempty.prgstub. - EmulatorJS framework deduplicated to
systems/_shared-ejs/ejs/data/across 7 VICE bundles. Cores deduplicated too: c64+max sharevice_x64, plus4+c16 sharevice_xplus4. Saved ~12.6 MB (later grew to ~25 MB once Coleco + NES joined). - VICE keyboard + joystick now coexist across all six CBM bundles.
keyboardInput: 'enabled'+altKeyboardInput: 'enabled'(typed keys → VICE) +vice_joyport_type: '1'(Numpad → VICE joystick port). Disjoint key sets.genx-numlock-warn.jswarns on the first keydown if NumLock is off. localStorage caveat: anyone who tested earlier broken builds needslocalStorage.clear()+ IndexedDB delete. - Site is now fully self-contained at runtime. Audit eliminated three external references: EmulatorJS version check (
checkForUpdates()→return;), Javatari NetPlay relay (SERVER_ADDRESS = ""), jsbeeb Google Fonts@import(stripped from the Vite-built CSS). - All game files locally hosted across 16 emulator bundles (audit verified each
games.json+ URL-param launchers). No external image/audio/video/iframe/service-worker/web-font remains. - C64 loading audible and real-time.
vice_drive_true_emulation=enabled,vice_drive_sound_emulation=1000%,vice_autoloadwarp=disabled. ~30 s of period-authentic IEC activity. Three discoveries from the runtime log: the sound option is a PERCENTAGE not on/off; warp-during-autoload isvice_autoloadwarpnotvice_autostart_warp; no separate volume knob exists. - C64 cold load no longer falls through to
cdn.emulatorjs.org. EJS picks the-legacy-variant by default when no per-corereports/JSON ships; mirroring only the non-legacy file 404s and falls through. Mirror the legacy variant. Net delta: -300 KB. - Menu column order flipped — every row now reads
N. Title text CODE ║(title first). 228 entry rows across 37 menus. - Shared CSS extracted to
systems/_shared/genx-controls.css+genx-controls-link.css. ~30 KB of repeated bytes removed. - WebMSX social-card metadata repointed at the GenX-DOS Pages URL. Upstream WebMSX logo link kept.
- Root-level menu skipped —
c:\menu.batnow doescd emulators\nmenudirectly. Boot drops straight into EMULATOR LAUNCHER. echo on→echo.in fs.js batches (53 occurrences). DOS shorthand for "print blank line".COMMODORE→COMMODRE,ARCHIMEDES→ARCHIMDSso the displayed code matches the typeable command.- Project renamed DOS-Site → GenX-DOS. GitHub repo moved; local clone relocated; old URLs auto-redirect.
- GAMES menus trimmed to top-10 most popular titles. NES dropped 8, Genesis 5, BBC 5, Atari 2600 8.
PROMPTentry added to BBC GAMES menu — links todist/with nodisc1/autoboot. Other home computers got the same treatment as they were added.- AMIBIOS POST rebrand —
AMIBIOS (C) 1985-1991 American Megatrends Inc.,,80486SX,8064 KB OK,Hit <DEL> if you want to run SETUP,40-0102-001102-00101111-121291-i486-K8footer. Tseng Labs ET4000 video BIOS line prepended; memory test animates as a 4-digit counter. - Drive + port specs added to POST + Configuration table: Floppy A
1.44mb (3.5"), B360kb (5.25"), HDD C/D, COM1, LPT1. Detection lines stream at 500 ms intervals. - After the Configuration table renders: two blank lines,
Starting GenX-DOS . . ., 1 s pause,Press F1 for help, then the menu. Boot-end hint readsType "help" <enter> for assistance.(F1 hijack is unreliable cross-browser). systems/jsbeeb/optimised: 71 MB → 27 MB. Removed upstream dev infrastructure (src/,public/,tests/,tools/,docs/,docker/,Dockerfile,Makefile, dot-folders) and 18 sample/test discs not referenced.- README rewritten to reflect all emulators. Wiki refreshed end-to-end.
Removed
- Sega Genesis (
systems/genesis/+ GENESIS submenu) — 16-bit (68000), outside 8-bit focus. ~20 MB. - Prince of Persia from CPC bundle — replaced by 3D Construction Kit (1991 Freescape).
systems/jsbeeb/package.json— npm build manifest not used at runtime.- 8 unused Apple I tape files (cell, codebreaker, little_tower, matrix, shut, slots, startrek2003, wumpus). ~256 KB.
- Acorn Atom (jsbeeb Atom mode + tape files) — didn't meet quality bar. Reverted JS patch.
-
Macintosh, Acorn Archimedes, Atari ST, Commodore Amiga 500 — all 16-bit GUI-era removed under the scope tightening.
-
Apple ][+ at
systems/apple2/via apple2js (Will Scullin, MIT) — pure JS, no WASM. Apple ][+ 48 KB + Applesoft + Disk II. webpack 5 production build; CSS overlay hides every chrome element;?game=rewritten to apple2js's?disk=. 10 first-in-series classics + Applesoft BASIC, converted viabin/dsk2json. systems/_shared/genx-frame.css— universal frame styles (page reset, body flex-centring,.err,.loading) extracted from 11 play.html files. Bundles with custom body layouts (atari800, jsspeccy, jtyone, genesis, javatari, js7800, xroar) keep their inline CSS unchanged.- BASIC prompt entries for Spectrum / ZX81 / CPC. cpc/play.html needed a no-game branch (skip
genxLoadGame(), let cpc.js init with empty sokol_args). Coverage: 11 platforms. - 168 external game-link
.bats removed and replaced with bundled emulators. - Upstream-only files from copied bundles (~1.85 MB reclaimed):
.claude/,.gitignore,README.md,.js.map× 3 source maps (1.77 MB),LICENSE.txt. LICENSE/COPYING kept where present for GPL/MIT compliance. - Stale
c:\changes.bat— never referenced; superseded by this file. systems/jsbeeb/index.htmlGoogle Analytics —gtagsnippet forG-Z9ZN3S7XREstripped; CSP tightened.dist/rebuilt.
Fixed
- C64 Elite stuck on Lenslok purple-screen loop — bundled
elite.d64was the original 1985 Firebird release, which hangs on its Lenslok protection screen. Swapped for a protection-free, flicker-free build. - 5 disk-swap-requiring games swapped for single-disk alternatives. Surfaced by user reporting Trinity (C128 D71 dual-sided) prompted for disk B mid-session.
- C64: Bard's Tale → Boulder Dash (Bard's Tale was just the boot disk of a 4-side RPG).
- C128: Trinity → Knight's Quest, Beyond Zork → Wumpus 2.0 (both D71 dual-sided).
- ST: Monkey Island → Marble Madness (only 5 LFL files = most rooms missing); Carrier Command → Predator (unreadable root directory).
- Defender of the Crown (ST) flagged but kept (158 KB with
PICS/+P/subdirs that may contain the rest). vice_drive_sound_emulationupdated 1000% → 100% — May 2026 VICE 3.9 build capped the option enum at 100%. Older value silently fell back to 20% default. Cross-checked against the libretro-vice master source.- C64 + VIC-20 BASIC entries now boot to
READY.Previous wiring (play.htmlwith no?game=) hit a broken EJS code path (download(undefined, ...)→startGameFromDownload(undefined)throws inside an async IIFE, silent). Fix: ship 4-byteempty.prg+ register as"basic"+ point.batat?game=basic.
Documentation
- Top-level
README.mddescribing the site layout, emulator integration recipes, menu structure, and jsbeeb URL semantics.