[Unreleased]
Changed
- The MS-DOS launcher in the filesystem is
MSDOS4.COM, notMSDOS4.EXE. It is the one entry on the shelf that is a DOS system rather than a game, and a.COMis what that would have been. The prompt already knew the difference —TYPEprints anMZheader for an.EXEand a headerless image for a.COM, because DOS loaded one at offset 0x100 and jumped straight in — so two places needed teaching that a launcher can be a.COMas well:TYPEwould otherwise have printed the link's URL, andFINDindexed.exeonly, so the machine would have quietly stopped being findable. Running it is unaffected either way; the prompt matches a command on the name before the dot.
Fixed
- MS-DOS 4.00 sat in the IBM PC menu as though it were a game. It was added as row eleven inside the numbered games, carrying a
(1988)after Commander Keen's(1990)— which broke the year order the list is sorted by, and read as an eleventh game on a shelf of ten. Every other machine that offers its own firmware already had the answer: seventeen of them put it at row eleven, below a blank row, with no year —BBC BASIC prompt,Woz Monitor prompt,Applesoft BASIC. The IBM row now readsMS-DOS 4.00 promptin that position, and the menu is row-for-row identical in shape to the BBC Micro's. The year is off the page title too, so the tab readsMS-DOS 4.00as the other elevenths do.
[1.11.0] - 2026-09-24
Added
- MS-DOS 4.00 itself, as the eleventh entry on the IBM PC shelf. Not a game: the operating system, booting from a 720K floppy to a bare
A>and waiting for you to type something. Microsoft released the MS-DOS 4.00 source under the MIT licence in 2024, and unlike the v1.25 and v2.0 releases — which ship the kernel but not the machine-specificIO.SYS, so nothing can be booted from them — that tree is complete. Everything on the disk is our own build of it: the boot sector,IO.SYS,MSDOS.SYS,COMMAND.COMand thirty utilities, compiled with the period tools the release itself includes. The three-lineCONFIG.SYSis ours; there is deliberately noAUTOEXEC.BAT, so the machine names itself, asks for the date and the time and leaves you at a bareA>— which is what booting a floppy looked like in 1988. Pipes, redirection, batch files,DEBUG,EDLINandMEMall work; the programs that want a printer, a second drive or a hard disk are on the disk because they shipped with DOS, not because they will do anything here. The image is not in this repository or the zip, the same as every game —ROMS.txtnames it, thedosbox.confis ours and stays. - The published source needed two repairs first, both artefacts of how it was packaged rather than anything wrong in 1988. Its line endings had been normalised to LF, and the DOS tools are not equally forgiving:
nmakeand MASM never complain, which is why a build gets 55 objects in before anything goes wrong, butnosrvbldparses a.sklexpecting CRLF and reportsCan not find in index filewith the name it was looking for missing, and the linker reads four modules out of a response file and then sits at a prompt waiting for a keyboard that is never coming. AndSETENV.BATpointsINCLUDEandLIBat two directories that do not exist, which every assembler component survives and every C one does not. With both fixed the whole tree builds. - It is not counted as a game. It has a page like everything else on the shelf, but the site's tally is of games and this is an operating system, so
check-doc-counts.shand the social card both hold a named list of pages that are not games and subtract it. The landing page and the article still read 438. The one number that did move is the page count inFile-Structure.md, which counts pages rather than games and is now 474. - The boot sector wants
IO.SYSandMSDOS.SYSas the first two root directory entries, so the image is formatted without a volume label — a label takes entry zero, and the disk answersNon-System disk or disk error, which is pleasingly the exact message the line-ending fix had just restored.
Changed
- Three DOS games offer a joystick, and their pages now say it leads nowhere. Alley Cat asks outright — Do you want to use a joystick (Y/N)? — and Paratrooper and Captain Comic each name one as an option, Comic with a calibration screen that will sit waiting for a stick that never answers. Nothing can be done about it at our end: the layer the DOS games run through can send keys and a mouse and has no path for a joystick at all. Each page now says so in its own words, at the step where you meet it. Sopwith is not among them — it names joysticks too, but on a screen it is launched past.
- The IBM monitor has been redrawn. Same photograph, cleaner edges. The screen cutout is unchanged to two decimal places in both bounds, so the prompt and the IBM PC bundle need no adjustment and arriving at a game from the launcher still moves nothing.
- ATTRIBUTION links the people it names. js-dos's author was credited by his GitHub handle without that handle being a link, and Sopwith's row pointed at our fork without pointing at the source it was forked from. Both now go where a reader would expect.
- Doc audit: two listings had gone stale by omission, and one described a mechanism we replaced.
File-Structure.mdhad never been told about the Arcade or IBM PC bundles, was missing two shared scripts, and still named one —gamepad-browser-notice— that no longer exists anywhere but in that sentence. The IBM PC engine page described the start-up banner being hidden by withholding frames, which is not how it works any more, and quoted a CSP split of nineteen narrowed pages where the number is now seventeen. The feature article had never mentioned the IBM PC at all, which is a strange omission for the one machine the site has always dressed as. Counts, orphans, bezels, textures, badges, game files againstgames.jsonin both directions and gamedocs against game keys were all clean. - Sopwith can be flown with the cursor keys. Up climbs, Down descends, Left slows and Right accelerates — and
,/XZand.still do exactly what they always did, so the game's own manual stays correct. This is not a translation laid over the game: it is twelve lines in the game, in the keyboard interrupt handler, compiled with Turbo C 2.01 and A86 the way it was in 1984 and linked into a DOS executable. The source is GPL — David Clark released it and later relicensed it — so the modified source, notices saying what changed and when, and the recipe for building it are published atRetro-Jack/sopwith-genx. It starts straight in a single-player game now, rather than asking twice first, and the sound is on from the first frame, which is the source's own default. .htaccesssays what the host actually does about compression. The block naming the types to compress is not what compresses them here: this host runs LiteSpeed, which uses its own server-wide list — hence CSS and JS arriving as brotli rather than deflate, andapplication/wasmnot being compressed at all despite being named. The directives stay — the release zip is meant to be served by whatever the person downloading it has, Apache included, where they do work — with a note so the next reader doesn't take them at face value here.
Fixed
- The picture is painted whether or not it is being shown yet. The start-up banner is hidden by covering the screen rather than by withholding the frames, so a decision to uncover it that arrives late — which a browser makes likely, since it throttles timers in a tab you are not looking at — finds the right picture already there instead of an empty canvas waiting for a frame that may never come.
- Sopwith sat on a black screen. It was running the whole time, waiting at its own menu — the screen was simply never drawn. The emulator sends a frame when the picture changes, so a game that draws a menu and waits for a key sends a couple of frames and then nothing at all; the start-up banner, the clear and the menu all landed inside those, none of them was the blank screen we were waiting for, and once they stopped there was never another frame to draw. The last frame is now kept and drawn the moment the picture is shown, and a picture that has been still for a moment is taken as ready. Anything that keeps moving, like Paratrooper's title, was never affected.
- The bigger DOS games took half a minute to start. Each game's files were fetched one after another, and while the games are small — a quarter of a megabyte at worst — Captain Comic is 54 separate files and Commander Keen 42. A round trip to the host costs far more than the bytes do, so the wait was almost entirely spent asking. They are now all requested together and arrive down one multiplexed connection: Captain Comic's 54 files took 29 seconds in turn and now take under half a second.
- A blank line under the IBM games menu. IBM was entered the way a maker with several machines is — into the maker directory, then its menu — but IBM has one machine and no machine-chooser, so that menu only forwarded to the games list and left its own trailing blank line behind. It is now entered the way the site's other two single-machine makers are, straight into the games directory.
- The IBM games menu sat a column right of every other menu. Its box was indented eighteen spaces where the site's other 896 box rows use seventeen, so the frame jogged sideways as you moved between it and any other list. Twenty rows, now in step.
- The IBM menu's batch files ran as one line. Every
.batin the IBM directory had its newlines written as the two characters\andnrather than as line breaks, so the DOS prompt read each file as a single command and echoed the rest back:off\ncd games\nmenu\necho.\n. Picking IBM from the Personal Computers menu printed that instead of opening the games list. Twelve files, all of them in the IBM directory added with the DOS games; the site's other 662 batch files were written correctly and are untouched.
[1.10.0] - 2026-09-22
Added
- The IBM row reads IBM / IBM Compatible. Almost nothing on that shelf was written for an IBM-badged machine specifically, and by 1985 most of the people playing these were doing it on something built by someone else.
- The IBM PC, and ten DOS games. The machine the site has always dressed as — the prompt boots into an IBM 5153 and, until now, nothing ran behind it. Paratrooper (1982), Digger (1983), Beast (1984), Alley Cat (1984), Sopwith (1984), Rogue (1986), Round 42 (1986), Kingdom of Kroz (1987), The Adventures of Captain Comic (1988) and Commander Keen: Marooned on Mars (1990), reached through IBM on the Personal Computers menu. Each game is given the machine it was written for rather than one setting for all ten: CGA for eight of them, EGA for Captain Comic and Commander Keen, and a slowed processor for the five that are timing-dependent and unplayably fast otherwise. The monitor does not move when a game starts — the bundle takes the prompt's own wrap expression and screen coordinates rather than deriving its own, so coming from the launcher changes nothing but what is on the glass. The screen stays dark until the program takes the machine over, because the emulator's own start-up banner cannot be turned off in this build and is not something anyone needs to see. Ten gamedocs and a controls page, with every key taken from the game's own instructions screen, its shipped documentation or its manual — Paratrooper, Round 42, Kroz and Beast all state their controls on screen, and that is where theirs came from. The games themselves are not in this repository or the zip, as with every other system here —
ROMS.txtnames each file and where it goes, and each game'sdosbox.confis ours and stays. - A
menulink in the credit pill. It sits between the wordmark andsource, and goes back to the prompt. The two are different journeys: the wordmark leaves for the landing page,menuhands the window back to the launcher you came in by — and deliberately does not reload it, so whichever directory you had navigated to is still there. The prompt carries the pill too, where the link would point at itself, so it is left off there. deploy.shcan overlay the footer. It already appended a fragment to the pill script and spliced one into the home page's card list; it now also splices one into the footer, anchored on the closing line so the fragment lands above the licence notes. A no-op when the file is absent, so a fresh clone still builds exactly the repo and the release zip is untouched.
Changed
- The documentation caught up with the IBM PC. The feature article still counted thirty-four machines and named the launcher's first entry Home Computers; it now counts thirty-five, says Personal Computers, and has a paragraph on the machine the site had been impersonating all along. The README lists the bundle and the engine in both its tables, the AI disclaimer's engine count was one behind, and the wiki gained Emulator-js-dos-IBM-PC — why the js-dos player is not used, how the banner is hidden, the per-game machine settings, and the CSP it needs. The TI-99 controls page was the last page anywhere still headed Home Computer.
- The maker menus show how long each machine was made for. A maker row used to carry the year its earliest machine appeared, which is the span of its launches rather than of its manufacturing. Each row now runs from the first of our machines going on sale to the last of them leaving production — only the machines actually on the shelf, so Apple reads 1976-1982 for the Apple I and the ][+ rather than 1993 for an Apple II line we don't run, Atari reads 1979-1985 for the 400 and the 800XL, and Texas Instruments reads 1981-1984 for the 99/4A rather than 1979 for the 99/4 before it. Where one machine sold in several regions, the widest is used: the Master System's 1996 is its European tail, and the Famicom's 2003 is a decade after the NES left the West. Sourced per machine rather than recalled — Wikipedia's own infobox for the TI-99/4A gives June 1981, which belongs to the 99/4. The arcade rows are unchanged: a cabinet's production run is the game, and they already said so.
C:\\HOMECOMPisC:\\PC. The directory was renamed twice in a day: first toPERSCOMPalongside the Personal Computers label, then toPC, which is what anyone would type. The batch file behind the launcher's first entry still saidcd homecompafter the first rename —cdlowercases both sides before comparing, so it matched nothing and the menu's first option quietly did nothing. Both are fixed, and the filesystem page's tree is realigned around the shorter name.- "Home Computers" is now "Personal Computers". The category had to widen to hold a machine that was never a home computer, so the launcher's first entry, the section header above the makers, and the line at the top of all 177 computer gamedocs now read Personal Computer. The directory changed with the label —
C:\PERSCOMPin place ofC:\HOMECOMP— since the menu saying one thing and the path another helps nobody; the wiki's filesystem, emulator and command pages follow. Every menu row still measures exactly 45 characters, so the boxes close where they always did. Prose that uses home computer as the period term for the era — a handful of gamedocs, two controls pages — is left alone, because there it is the right words rather than a category name. - The social card has a generator, and lists the arcade.
tools/social-card.pydraws the card's menu rows and stats line in the prompt's own CP437 font sheet — which reproduces the existing rows pixel for pixel — and measures the stats fromdocs/games/, socheck-doc-counts.shnow checks the card (and--writeredraws it) instead of only restating what it should say. Row 7 reads Arcade (Coin-op) in place of Amstrad CPC, and the home page's description of the card follows. - The wiki caught up with the forks and the Commodore 128's departure. The apple1js page had the wrong licence (it is MIT), the wrong launch parameter (
?tape=) and no word of the fork; File-Structure, Virtual-Filesystem and the Roadmap now name the Apple I and PET forks, and the PET page's size is current. The Roadmap's scope list still named the C128, dropped on 03/09/2026; it now has a Rejected entry saying why. - ATTRIBUTION records PETSCII Robots and the new forks. The shareware game ships on the C64 and the PET but had no entry among the titles released by their authors; it has one now. The Apple I and PET rows name their forks.
systems/apple1/LICENSEcarries apple1js's MIT notice, taken from the fork, and the note on notice files now says the PET's travels in its source headers. - The README credits every engine and names its forks. The licence list had no line for apple1js, JSVecX or VirtualT; the Apple I, jsbeeb and PET lines now say they are built from our forks, the PET's layout line counts nine
.prgand a.d64, and the Apple I's upstream was misnamedscullin. - The feature article's size and TRS-80 were out of date. Its prose said 138 MB beside a numbers box reading 186, and the rebuilt-by-hand box named the TRS-80 Model I where the site runs a Model III. The prose figure is now a slot
check-doc-counts.shkeeps in step with the tree. - The PET and the Apple I share one phosphor green,
#11cf00. The PET's screen was a softer#60d0a0; the Apple I's text was near-white, and now starts in green (Green Screen ticked, still switchable). The Apple I's emulator is a fork now,Retro-Jack/apple1js: its two older changes — reset on Pause/Break instead of F1, and a reset shortly after start-up so the monitor runs — had been hand edits to the built file, and are now source in the fork beside the colour. - The PET gamedocs describe the games we actually ship. Several were written from the famous original instead of the PET program. Star Trek is Version 17 (23/07/78), not Super Star Trek: six one-letter commands (N, T, L, M, S, R), courses in degrees, 40 stardates, no phasers — and it's 1978, not 1977. Its page also warns that Return on its own at a prompt stops a PET BASIC program, which the old page told you to do. Lunar Lander is a real-time game: the number keys set a thrust that stays set, 5 balances gravity, and you start around 52,800 ft with about 2,500 fuel — not typed burn rates from 120 miles with 16,000 lb. Years with no source anywhere (Lunar Lander, Space Invaders, Crazy Balloon, PET-MAN) keep their place in the menu and say so on their pages. Android NIM is by Don Dennis of Toronto (1979), not a Commodore bundle game, and it is ordinary Nim — whoever takes the last android wins — played with single keys for the row and the count. Hangman allows ten wrong guesses, not eight; guesses are single keys with no Return; a repeated letter costs nothing; and there is no guess-the-word option. Crazy Balloon reads the keyboard directly, so it now uses held keys too — the balloon moves only while a key is down, and the diagonals need two keys held at once, which the old tap-and-release keyboard couldn't do. Its page gains the real scoring, the extra balloon and level thresholds, and the balloon's habit of bursting if left still. Pac-Man is PET-MAN, by Paul Gummersall with coding changes by Jim Butterfield, and is now listed under its own name (
PETMAN.EXE): one life, four guards, energizers that last ten seconds, Easy/Hard/No Chance — none of the arcade's ghost personalities, fruit or speed-ups the old page described. Adventureland stores its treasures at the stump — the magic mirror is one of the treasures, not the place to take them — and its page now lists the game's own words and HELP, and warns that SAVE GAME wants a cassette this emulator doesn't have. Space Invaders uses held keys; its page gains the real score table (30, 20 and 10, a mystery ship, an extra base at 1,500) and loses the arcade mothership scoring and a claim that other key layouts exist. The PET controls page now explains held keys and the Return-at-a-question trap, and drops a generic key guide that fitted none of the games. - The PET's ComputerSpace 2001 is replaced by Attack of the PETSCII Robots (2021). ComputerSpace 2001 was a 2017 homebrew listed as 1981. David Murray's shareware release of PETSCII Robots — the PET is the machine it was written on — runs from its own
.d64: drive 8 in the emulator fork now reads disk images, so the game loads its tile set and maps by name as it goes. It spots BASIC 2 and adapts by itself, so the old "needs BASIC 4" blocker never was one. Esc is now the PET's RUN/STOP — the game's pause, and a way to stop a running BASIC program where the controls page used to say refresh the tab (a program waiting at a question ignores it, as on a real PET) — and in held-key games Shift+comma and Shift+full stop reach the PET's own<and>keys, which change weapon and item. Menu: PETSCII Robots at 10, BASIC 2 prompt at 11. Its page is written from the game's code, its key set-up screen and the manual, and tested on staging. It also names the total the game itself states: the shareware disk carries two of the PET version's nine maps. The C64 page's "13 levels" is not a contradiction — each build's own shareware screen states its own total, and the C64 game has more. Two claims on the PET page were narrowed to what can be shown: the difficulty setting is a face rather than a named level (the manual supplies easy/normal/hard), and the elevator is described by its own on-screen panel — left and right choose the floor, down opens the door — with the standard keys given after it. - PET arcade games hold their keys. The emulator used to press every key for 50 ms and let go, so games that glance at the keyboard only now and then missed quick presses, and a SHIFT key could not be pressed on its own — the fire button in many PET games. Games that set
heldKeysnow keep a key down for exactly as long as it is held, and either Shift key is the PET's SHIFT; Space Invaders, Crazy Balloon, Frog and PETSCII Robots use it. Typing games keep the old behaviour. The idea came from the PET emulator at commodoregames.net; the code, in our emulator fork, is our own. - Crazy Balloon's instructions read the right way up. The PET's original character ROM and the later one swap the case of letters in text mode, and Crazy Balloon was written for the later ROM, so its instructions showed as
mOVE THE SWAYING BALLOON TO THE gOAL. The emulator fork now carries both ROMs and a game can ask for the later one (newCharRomingames.json); Adventureland, written on an original PET, keeps the original. - The PET's "Frogger" is Frog, by P.J. Fellner, and its page now describes it. The title screen says FROG — BY P.J. FELLNER; the old gamedoc described Konami's arcade game instead. Rewritten from the game's own instruction screens and code — road and stream, ten home bays, its real points table, one or two players,
]to skip the instructions. LauncherFROG.EXE, filefrog.prg. No source dates it, so it keeps 1981 and its menu place, marked unconfirmed. - The WebAssembly glue we compile ourselves can be read. Emscripten writes its JavaScript as a few minified lines; the Model 100, Atari 400/800, Odyssey², TRS-80 and CPC glue is now formatted, with a banner at the top saying where it was built from and how to rebuild it.
tools/beautify-glue.shdoes it, is safe to re-run, and refuses anything we did not build — XRoar's and jzIntv's glue came ready-made upstream and stays as shipped, as does EmulatorJS. The m100 and odyssey2 build scripts run it themselves. Layout only: each file minifies to the same bytes as before, and none of them reads its own source text. - The DOS prompt's scripts explain themselves. New and corrected comments across the terminal: how the font sheet is indexed by character code, why the boot table is written as
É/Í/º, that all output is typed through the keypress handler, whatpromptMode,kUpand the Dopefish array are. Several banners inglobals.jsdescribed functions that had moved to other files, and one named aCOLORcommand that is reallySETCOL. Comments and formatting only — every file minifies to the same bytes as before. - The shared save-state and game-loader scripts are signposted the same way. Both save-state scripts gain matching section comments; the EmulatorJS one had the core's
save_state_infofields in two different orders a few lines apart, and now gives the right one (len|ptr|status) in both. The game loader's header now mentions thefailit also returns. Comments only, same minified bytes. - Nineteen pages can compile WebAssembly but no longer evaluate strings as JavaScript. The DOS prompt, Apple I, Apple ][+, Atari 400 and 800, Commodore PET, CPC, Electron, Intellivision, MSX1, MSX2, Odyssey², TI-99/4A, TRS-80, Vectrex, XRoar, ZX81, ZX Spectrum and Model 100 now carry
'wasm-unsafe-eval'in place of'unsafe-eval', each booted to a running game under the narrower policy. Sixteen keep'unsafe-eval'. The EmulatorJS bundles need it because their.7zand.zipunpackers calleval()inside a worker, so a core that is not already cached stalls at "Download Game Core 100%" with nothing in the page's console — which is also why an earlier attempt at this looked safe on a browser that had the cores cached. jsbeeb builds its CPU from strings, so both BBC bundles keep it too. - The PET's emulator is a fork now, and its timers are functions. Skibo's code handed
setTimeoutstrings of code, which the narrower policy blocks: the PET reachedREADY.and the autostart'sLOADandRUNnever arrived. The fix, the oldervia_t2llfix for Frog and our green screen used to be edits to the copied files; all three now live inRetro-Jack/pet2001with their reasons, and the bundle copies from it.petkeys-600.jsandpet2001video-mod.jstake Skibo's own names back. - The PET's chip reset clears timer 1's underflow flag. Skibo's reset routine wrote
var_t1_undfwhere it meantvia_t1_undf, so the flag survived a reset while timer 2's was cleared. Fixed in the fork, and offered back to Skibo with the timer andvia_t2llfixes as skibo/skibo.github.io#1. ROMS.txtsays which MAME the arcade sets are for. Anyone completing a copy of the site had the hundred filenames and no way to know that a current MAME set will not load: the cabinets run MAME 2003-Plus, the libretro port of MAME 0.78, and a modern set disagrees with it on filenames and on which archive a chip belongs in. The Arcade section now says so, names the metadata the sets were built and verified against (metadata/mame2003-plus.xmlat commitd3ac6c95), and notes the one clone set among them —sitv, whose four files are all in its own zip, so the parent is not needed. The Atari XL/XE firmware line gains its revision, which every other firmware line already carried.
[1.9.0] - 2026-09-13
Added
-
COMMAND.COMis on the drive, and it credits LGR. The interpreter was the one file a DOS C: root always had and ours did not. It sits in the root now, and running it prints the start-up banner:GenX-DOS Version 1.8.1, then(☺)Copyleft Mike @ LGR - Lazy Game Reviews, then a blank line — where the "C" of "(C)" is the font sheet's smiley, character 1, the sheet being indexed by character code. The credit is the point of it: the terminal, the virtual filesystem and the font system are the LGR base written by Mike for Lazy Game Reviews, not our work, and the interpreter's own banner is where DOS always put that line.TYPE COMMAND.COMgives the same seeded garbage the launchers give, minus theMZ— a .COM has no header at all; DOS loaded one at offset 0x100 and jumped straight in, so the first byte on screen is already code. The copyright line is indented under the version line, the way MS-DOS set its own banner out. It answers from any directory because there is a PATH now:GENX_PATHholds the drive root, andattemptExecsearches the current directory first and then each entry on it, which is the order DOS searched in.VER.COMsits beside it and prints the version line alone, then a blank line — in real DOS, VER was internal to COMMAND.COM rather than a file, but every other program on this drive is a file. Both carry acomkey naming what they run, so adding a third is a line in the filesystem and a function beside the other two. The wiki's filesystem page carries the newcomshape alongsidelinkanddata, since that page is what anyone editingfs.jsreads. The version is a constant,GENX_VERSION, and two things keep it honest.check-doc-counts.shcompares it to the newest release heading here, andbuild-portable.shrefuses to build if they differ — which is the choke point for everything that leaves the repository:deploy.shbuilds through it for staging and live, the portable copy comes from it, and so does the release zip. Nothing else in the tree derives that number, and it is exactly the kind of thing that sits a release behind unnoticed. -
The legal position is a page now, and the pill points at it. The reasoning behind the licences, the ROMs, the artwork and the data was spread across five documents, none of which said how the parts fit together; the wiki's Legal position page does. The credit pill on every play page used to read removal and open the removal section inside the attribution file — it now reads legal and opens that page, because someone who has just found their own work here wants to know where we stand as well as how to ask, and the page opens with the position and links the procedure. It is also honest about the gaps, which is the point of publishing it: no robots policy, graphics attribution left to a single share-alike case, and no lawyer behind any of it.
-
REMOVAL.md— the removal procedure on its own page. It has always been inATTRIBUTION.md, which is the right place for the record but a poor one to land on if you are a rights holder in a hurry. The standalone page says what is covered, the three things a request needs, where to send it, and what happens next — and adds what we can and cannot reach: the site and the repository including its history, but not other people's copies of the repository or third-party archives. It is in the wiki sidebar, andATTRIBUTION.mdpoints at it. -
An ARCADE branch: ten makers, ten games each.
C:\SYSTEMS\ARCADE\<MAKER>\GAMES, the same shape asCONSOLE\NES\GAMES, sitting at row 4 of the EMULATOR LAUNCHER with the wiki moved to 5. Makers are listed alphabetically, matching the CONSOLE menu — a menu ordered by a private ranking isn't self-evident to anyone but its author. Games run year ascending within each maker, and every launcher is named after its romset as the site's other launchers are. All 100 romsets are built and verified byte-exact against the core's own metadata — every member decompressed and its CRC recomputed, with no absent, wrong or extra file in any of them. They were built by CRC rather than by filename, because the core wants exactly what its own data file lists, and a current MAME set disagrees with it constantly on filenames and occasionally on which archive a chip lives in. Pairing the title list against the romset list by position would have filed four games under the wrong ROM — Battlezone asmissile, Marble Madness aspaperboy, Sheriff asspacefev, Bionic Commando asblktiger. Both lists were year-ascending but broke ties differently. Matched on each set's own recorded title instead. All 100 carry marquee artwork. The libretro set covers 97; the last three are Irem cabinets, and LaunchBox holds proper 3840px scans of the Image Fight and Ninja Spirit marquees that it does not. Traverse USA has no marquee of its own anywhere — every scan is the Williams "MotoRace USA" retitle, which is a wrong title rather than wrong branding, so re-badging it the way Moon Patrol was re-badged would not have been enough. Its marquee is instead built from the untitled artwork with the game's own title lockup lifted from its attract screen: snapped to the five colours the screen actually uses, the triangle refitted from its unobstructed right edge because the lettering fragments the rest, and cropped to the picture and its pinstripe frame — losing the red bands takes it from 3.0:1 to 4.0:1, which fills the cabinet’s marquee hole instead of letterboxing in it — and set in the starfield above the Gateway Arch — the artwork is St Louis, and the logo is sized to leave the arch clear — and toned down to the banner’s own levels. That last step is an exposure scale rather than a gamma curve: the screenshot’s colours run to 238-255 against printed card that peaks near 165, and no exponent moves a channel that is already at 255. The result matches what the machine puts on screen when it boots. Formerly, 97 of the 100 carried marquee artwork, normalised to the same 674x145 canvas as the originals. Gauntlet's is the one that needed cutting: the scan is a blank marquee, the version with an empty white instruction panel below the logo, so it is clipped to the wordmark. Every other candidate turned out to be legitimate artwork whose whiteness is clouds, star fields or a white ground — a whiteness test flags nine of them, and cropping on that basis removed Space Fever's title outright. What actually distinguishes a blank panel is a large featureless white block low down on a coloured ground with the art above it, and exactly one of the 91 matches that. The three without are all Irem — Traverse USA, Image Fight, Ninja Spirit — and a cabinet with no art shows an unlit marquee, which is a thing you actually saw in an arcade, rather than a broken-image icon, which is not.
Removed
- Three unreferenced images from the Apple ][+ bundle.
img/logoicon.pngand the twowebapp-*.pngtouch icons came with apple2js and are reached only from its ownindex.html, which we do not ship. Nothing in the tree names them. The bundle's other six images are all referenced byplay.html, the stylesheet or the app bundle, and stay.
Changed
-
The wiki had never heard of the arcade. Three pages that describe the whole site — Project Overview, Virtual Filesystem and the
C:tree on it — went two days without a word about the hundred cabinets, which is the largest thing on the site. The launcher listing still read 4 WIKI, where the arcade has sat at 4 since it launched; theC:tree had no ARCADE branch, and the menu-to-emulator table had no arcade row. All three now do, with the ten makers named. Four more omissions surfaced in the same pass, each of them a row or a word rather than a wrong number: theC:tree left VECTREX out of CONSOLE and M100 out of TANDY, though both have been infs.jsfor months and the table below it lists M100; the Vectrex had no row in that table at all; the Tandy line in the overview still said TRS-80 Model I, a month after the bundle became a Model III; and the sentence naming the EmulatorJS bundles said the six VICE bundles — there have been five since the C128 went — and forgot the arcade, which is how it still totalled fourteen while being wrong twice. The overview also counted 20 emulators where every other document says 19 engines; it says engines now, which is the phrasing the count checker can see. The wiki's own index was missing Legal and Your Data, both of which exist and are both in the sidebar. The root listing gainedCOMMAND.COMandVER.COM, and theTYPEparagraph notes that a.COMprints without theMZ. -
The landing page said 33 systems. Twice — in the meta description search engines quote, and in the line under the feature-article link — on the first page anyone sees, two days after the arcade made it 34. No generated slot reached either, because both are prose; the count checker now reads them.
-
The EJS bundle count was a release behind in three places. The arcade joined the fourteen bundles sharing
systems/_shared-ejs/on 06/09, andREADME.md,ATTRIBUTION.mdand the wiki's Roadmap still said thirteen. The count checker only looked for the two exact phrasings it was taught, so three other wordings of the same number drifted unseen; it now checks the number wherever it appears next to the word bundles. -
Both favicons are LGR's, and now say so.
favicon.icoandanimated_favicon1.gifcame in with the terminal on day one and had never been credited.ATTRIBUTION.mdand the README name them now, and the GIF turns out to have been doing the job all along: its six frames hold onC:\for two seconds, cross-fade to LGR for two, and fade back — the tab icon has been a credit since the beginning. -
The legal page stops calling the prompt ours. Its list of what stays NonCommercial opened with the prompt, which is the one part of the site that is not ours to license: the terminal, the virtual filesystem and the font system are the LGR base. The list now names the menu trees and the POST animation, and the paragraph below it says plainly why the prompt is not in it. Same correction in the local legal-position document.
-
Batch files open
@echo off, the way they always did. A line may start with@now: it is accepted and dropped, and the line then runs exactly as it would have without it. In DOS the@suppressed the echo of that one line — without it theecho offline itself printed before taking effect — and nothing echoes a batch line here, so there is nothing left for it to suppress. It is accepted because that is how a batch file is written, and all 127echo offlines in the filesystem are@echo off. Proved rather than assumed: every one of the 659 batch files in the tree was run through the realexecuteBatchandhandleCmd, before and after, with everything reaching the screen recorded — the newline keypresses included. All 659 produce identical output. -
The launcher's Exit sign-off runs
VER.\SYSTEMS\0.batprinted its own hand-written header —GenX-DOS (2026)and a rule under it — which was a second place for the project's name and year to go stale. It callsverinstead, so the sign-off is the real version line from the one constant that has to be right, and the hard-coded year is gone. What is left is the version, a blank line, "Type help or menu to continue.", and the blank line that clears the cursor. -
Leaving the launcher leaves a blank line.
\SYSTEMS\0.bat— the menu's Exit — printed its title, its rule and "Type help or menu to continue" and then dropped straight onto the prompt. It ends onecho.rather thanecho onnow, which prints the blank line and re-enables the prompt in one, so the three lines read as a block with the cursor clear of them. -
Doc accuracy pass. Four things the tree had moved past: the prompt's own comment still called the credit strip licence · source, hours after the licence came off it; the wiki's file map still had 13 bundles sharing the EmulatorJS framework, where the arcade made 14 six days ago; and neither root listing named
REMOVAL.md. The arcade page now says where the analogue cabinets stand — five played, three to go — rather than leaving Star Wars as the only one anyone had checked.check-doc-counts.shgained the bundle count, since that is exactly the kind of number that goes stale quietly. -
The credit pill drops licence. Four links plus the wordmark was more than a strip of 10px text can carry, and the licence was the one nobody needed at the moment they were playing: it sits on the legal page the pill already links, one click further on. The pill now reads GenX-DOS · source · readme · legal.
-
The removal route leads with the email now. Every document listed the GitHub issue first and offered the address as the option for people who wanted it kept private, which reads as though an account is the normal way in — and a rights holder is often a brand or a representative who has no account and will not make one.
REMOVAL.md,ATTRIBUTION.md,README.md,SECURITY.mdandCONTRIBUTING.mdnow put admin@genx-dos.fun first and say no account is needed anywhere, with the issue kept for anyone who would rather it were public. The issue chooser carries the same route as its first entry, so it is visible before a form is started, and the removal template says an email saying the same things is equally good. That template also said the repository bundles the software, which the site does now, and promised removal immediately where the page says hours rather than minutes — both corrected. -
The legal and policy documents describe the project as it is now. They had not been touched since 17/08, and the arcade section and the ROM-free repository both landed after that. Your Data lists the one file the arcade writes — a 20-byte input config that gives Hang-On's brake a pad axis, written into the emulator's save storage at boot — so the page is again the complete list it claims to be, and the clearing note names it. Removal upon request now covers the site as well as the repository, and says plainly that the games and the firmware we supplied are served by genx-dos.fun and are not in the repository at all. SECURITY points removal requests at that section, with the private email route, rather than at the issue tracker alone. CONTRIBUTING warns that a clone boots the machines but not the games until the files in
ROMS.txtare in place. The licence names the game files and system ROMs as served by the site. The AI note said 33 systems, six days after it became 34 —check-doc-counts.shnow checks that line too. The arcade had slipped through attribution as well: the bundle, and the hundred romsets it serves — 1976-1989, ten manufacturers — had no row of their own, though the core did. Removal upon request now names sound among the things it covers, for completeness — the one sound the site plays, the coin effect, is licensed for this project and bought from its vendor, and the attribution says so. -
Section headings are a smaller page title, not a stretched label.
h2had been uppercase Michroma at label size with wide tracking, which sets an uneven line — the face draws its caps to different heights, and the tracking pulls them apart. It is now the same face, case and tracking as the page title at 1.1rem, one step down in size, keeping the rule that runs off to the right. Every document on the site uses the one stylesheet, so the gamedocs, the controls pages and the wiki all follow. -
Possessives that read as plurals. A sweep of the site text, the wiki source, the gamedocs and the code comments found 21 places where a possessive had its noun dropped and the bare
'swas left to stand for it — "the last three are Irem's", "higher than the dealer's", "copy the two artifacts over the bundle's", and an arcade wiki heading that read "Romsets are the core's, not a modern set's". Each has its noun back. The apostrophes that remain are possessive or contractions; the plural-looking acronyms (the BBC's screen,MAME's own data) were checked and are possessive. -
Hang-On has a throttle and a brake. The cabinet was a motorbike: handlebars, a twist-grip throttle and a brake lever, all analogue (MAME's AD Stick X, Y and Z), and no buttons. Its gamedoc had said it had no buttons and a stick that moved; it now lists steering on the left stick, the throttle on RT and the brake on LT, or the arrows, up and K on the keyboard. The brake needed a config file. This MAME assigns AD Stick Z to nothing, and no core option changes that, so the page writes a 20-byte MAME
default.cfgat boot with one record, "AD Stick Z = right stick down", and LT stands in for that. EmulatorJS's ownexternalFilescould not place it, since it mounts the persistent save storage over/data/savesafter writing them, sogenx-ejs-boot.jsgains a hook that writes a page's files on EmulatorJS'ssaveDatabaseLoadedevent, straight after that mount and before the game starts. Play-testing found the bike slowing with RT held flat: the left stick's down still shared the throttle's axis, so a hand steering the stick eased off without meaning to. On Hang-On the left stick now steers and nothing else. Also tested: Paperboy centres, steers proportionally and the right way, and throws on A, as its page says; the core's labels put Throw on button 2. -
A coin you can hear. A coin dropping through the slot mechanism plays when a coin goes in, from the coin door's slot or the 5 key. It is a licensed library sound (Hollywood Edge's Foley Sound Library, via SoundDogs.com), so it exists only on the web host: uploaded to the live and staging sites by hand, kept out of the repository and the release zip, protected in
deploy.shfrom the cleanup that would otherwise delete it, and credited in ATTRIBUTION. Without the file, the coin still goes in silently. Wiring the sound to the 5 key showed that the key could insert nothing at all. EmulatorJS reads keys only when they land inside its own game element, and focus is often elsewhere, including straight after the coin button itself, which gives up focus on purpose. A 5 pressed outside the game is now inserted by the coin door, through the same path as the slot; one pressed inside is left to EmulatorJS, so a coin is never counted twice. -
I, Robot's camera is on the pad. The cabinet fired from the stick. Its two panel buttons were marked VIEW, and the game reads them through the start inputs: in play, 1P lowers the camera and 2P raises it. The game leans on them, too, since its Point of View killers cannot be shot and destroy a robot whose player has not moved the camera in time. Coin and start stay keyboard-only everywhere else, but on I, Robot X lowers the view and Y raises it. Y has to be pressed from code, because EmulatorJS reads player 2's start from a second pad. The gamedoc had said the panel's second button did nothing and listed Fire alone; it now lists the camera, with two strategy tips that depend on it. Also tested: I, Robot's stick centres on the core's defaults, so the Star Wars centring fix stays scoped to Star Wars, and button 2 is dead, as the core's data says.
-
The arcade gamedocs can be rebuilt from a clone. The builder had depended on control data that lived only outside the repository.
tools/build-arcade-controls.pynow reads it from the core's owncontrols.cand metadata XML at a pinned upstream commit intotools/arcade-controls.json, andtools/build-arcade-gamedoc.pyruns on its own: it rebuilds every page around the copy the page already carries, or, by default, just reports any page that has drifted. The seventeen pages whose controls were set by hand keep those blocks, listed with the reason for each intools/arcade-gamedoc-overrides.json. The first check found the stick type wrong on two pages, because the data they were built from predated the core's drivers: Ghosts'n Goblins is a 4-way stick and Kung-Fu Master an 8-way, the other way round from what the pages said. A label that already carried an entity was also being escaped twice, which no page had shipped only because those labels had all been set by hand. -
The docs caught up with the arcade section and the handhelds. ATTRIBUTION now credits the MAME 2003-Plus core and its licence, the classic MAME non-commercial terms of 0.78, which had shipped since the arcade section landed with no entry. README's engine table gains the Game Boy, Lynx, Game Gear / Master System and arcade rows it had been missing since the handhelds arrived, and its licence summary the gambatte, handy, Genesis Plus GX and MAME cores. The wiki has a MAME 2003-Plus page, and its EmulatorJS paragraph counts five VICE bundles rather than six. README and the wiki's file map list
ROMS.txtand the three arcade tools, and the wiki's home page no longer calls the release zip the whole site.docs/arcade-menu.md, a planning note that nothing linked to, is gone. -
ROMS.txtreads as one list. Every game isTitle (Year), the year taken from the system's own menu, where some sections had carried a publisher and some had carried nothing; titles sit in one column; the BBC discs use their menu names rather than ones built from filenames (Bonecruncher,Palace of Magic, and plainElitefor the Master disc); and TRSDOS and LDOS are labelled system disks rather than firmware. README and ATTRIBUTION now describe what the repo leaves out as what didn't come with its emulator. -
The docs describe the tree as it is now. The social card's stats line reads
428 games · 34 systems · 100% self-hosted; it had been left at328 · 33since the arcade section landed, and was the one count the checker can flag but not fix, since it cannot read a PNG. Redrawn in the card's own font rather than a substitute — the digits were lifted from the menu row that already carried a4, so the glyphs are the card's own. The changelog entry describing that card was wrong too, quoting327for a line that has always said328. The wiki's file listing gainedgenx-doc.cssand now describes what each stylesheet is for, and its emulator page no longer sends readers tosystems/_shared/styles/genx-controls.css, which was deleted when the document language was consolidated. -
Three panels that were laid out in space now use the pad's diamond, and Tutankham uses the right stick. X, Y and B sit in a diamond — X left, B right, Y above between them — and some of these cabinets numbered their buttons only because a panel has to: Gun.Smoke fires down the left, the centre or the right of the street; Missile Command fires from the left, centre or right missile base; Punch-Out!! throws a left blow and a right blow with the uppercut above them. Those three now sit where they point. Tutankham fires left or right along one corridor and nothing else, so it takes the right stick instead — pushed the way you want the shot to go. Which button is which was measured, not read off the numbering, and the numbering is wrong. MAME's button order is not panel order: on both Gun.Smoke and Missile Command, buttons 1 and 2 are the two outer positions and button 3 is the middle one. Missile Command prints LOW under a base that is nearly spent, so firing one button repeatedly names the base it belongs to; Gun.Smoke's shots visibly leave the sheriff to one side. This corrects a real error in two gamedocs, which had taken the numbering at face value and so had Gun.Smoke's centre and right shots the wrong way round, and named Missile Command's three bases in an order nothing had checked. Missile Command's rows now describe the bases by position, which is what was actually verified and what a player picks a base by anyway. Each of these cabinets has three buttons, so MAME 4 and 5 are cleared on them. They are unused by the board but still carried the bundle's default Y and B, and leaving them there would have put those two pad buttons on two inputs at once. Track & Field was looked at and left alone: its panel is run-action-run, which suits the diamond, but its two Run inputs are interchangeable and which one carries the action was not confirmed, so it keeps what it had. This needed per-game controls, which the shared EmulatorJS boot glue could not do: it had a
perGamehook for core options only. That hook now also receives a private copy of the control map and the game's key. The copy is one level deeper than the options copy, because what a hook rebinds is an individual input's binding object — a shallow copy would have it writing into the page's own literal, and the change would then follow every game loaded afterwards in the same tab. -
The coin door sits in a box beside the Gameplay controls link. It was floating loose on the carpet under that link, in the site's usual soft-key spot, which on this bundle is the one place a soft key does not belong: the cabinet is sized to the full viewport height, so those three buttons had wallpaper behind them and nothing to sit on. They now share the corner with the controls link as a matching box — same brown ground, same amber rule, same radius, same top edge. Its height is measured off that link rather than written down, because the label is two lines of a webfont and its height changes when the font arrives. The slot moved to the middle of the three, where the coin door is on the cabinet: 1P to its left, 2P to its right, so the button you want is on the side you are standing. Also drops a stale offset: the buttons were pushed down to clear the audio banner, which has since moved to the bottom of the screen, so the offset was pushing them towards it.
-
The five twin-stick cabinets use both sticks. Robotron: 2084 and Splat! move with one hand and fire with the other; Battlezone and Sheriff drive a tank tread with each; Inferno moves and aims. The core reads those as a separate second joystick fed from the pad's right analogue stick, so a D-pad alone could never reach them — on Battlezone the tank drove but could not steer. The right stick is now bound (and I/J/K/L on the keyboard), and the arrow keys drive the left stick as well as the D-pad, so movement is the arrow keys on all hundred machines. Verified on both: holding one tread on Battlezone pivots the tank, and the right stick on Robotron kills robots.
-
Manufacturer rows carry a date range. A maker that spans several machines — Acorn 1981-1986, Commodore 1977-1984, Atari 1977-1986 on the console side — was showing a single year, which was really just its earliest machine. Eight rows across the HOME COMPUTERS and CONSOLE menus now show the span; a maker with one machine keeps its one year. The year field widened to hold a range and is right-aligned, so all 479 dated rows on the site still close their bracket in the same column.
-
Gamedocs for the arcade section, all one hundred.
systems/arcade/controls.htmlcovers the shared panel — six buttons, the coin door, the two-stick machines, and the cabinets whose control was a trackball or a spinner — and indexes all 100 games by maker. All 100 gamedocs are written: controls on every one, a strategy section on every one, and scoring on 58. The 42 without scoring say so and why, rather than carrying invented numbers — Irem's ten have no guides with point values at all, and the early Nintendo cabinets (Radar Scope, Sky Skipper, HeliFire, Space Firebird, Space Fever, Sheriff) are too obscure to be documented anywhere on the site. GameFAQs has no arcade entry whatsoever for Gauntlet, Green Beret, Gun.Smoke or Strider. The controls in them are not recalled: the core ships its own per-game control labels, and they name the controls for 78 of the 100. That is why Asteroids reads Rotate Left / Rotate Right rather than a stick (its metadata claims an 8-way; the game has no up or down), Missile Command's three buttons read as its three missile bases, and Tempest's second button is the Superzapper.tools/arcade-labels.pycorrects that data where it shouts in capitals, spells hyperspace three ways, or names a control the machine does not have — as an explicit list, so a wrong correction is visible in one place. Scoring comes from GameFAQs, which refuses anything but a real browser session;tools/gamefaqs-lookup.jsruns inside one. The guides are twenty years of different authors and have no common shape — ASCII tables in<pre>, real HTML tables that run their cells together when flattened, and prose with no scoring at all — so it tries a heading, falls back to any cluster of "N points" lines, and reports failure rather than guessing. Those guides carry explicit no-reproduction notices, so only the values are taken; every sentence on the pages is written here. Where GameFAQs had nothing, the manufacturers did. Operator's manuals carry the factory settings — lives per credit, the score a spare is awarded at — which is scoring information even when the manual never prints a point table, and arcarc.xmission.com holds 1,416 of them. They are image-only scans, so they are rendered and OCR'd; the DIP tables usually sit ten to twenty pages in, past the installation instructions. That produced eleven games' worth: Space Firebird's full point table from Nintendo, Green Beret's four-row bonus-life table from Konami, Arkanoid's and Red Alert's factory switch positions, Strider's extend table, Defender's setup booklet, and the lives-and-bonus settings for Rolling Thunder, Narc, HeliFire and Kid Niki. Chase H.Q.'s manual gave the rules instead — catching the suspect extends the timer by exactly 60 seconds, and there are three turbo bursts a round. The best source turned out to be the one furthest from the arcade: the manual for the home conversion. An arcade service manual is written for the operator — wiring, switches, parts — while the cartridge manual is written for the player and prints the point table. That is where Gauntlet's scoring came from, a game with no arcade GameFAQs entry at all, along with R-Type's thirteen-enemy bestiary, Space Harrier's ground-and-sky values and Kung-Fu Master's extra life. Each is labelled as the port's figures, because a port's manual is authoritative for the port and not necessarily for the coin-op — Arkanoid proves it, awarding a spare Vaus at 30,000/60,000/90,000 at home against the cabinet's own 20,000/60,000, so that page keeps the two apart. Flyers turned out to be the weaker source for scoring but the better one for mechanics: Irem's own sheets rewrote R-Type and Image Fight, and Moon Patrol's Japanese flyer had the checkpoint table nothing else did. Nothing from a cheats, codes or secrets section was used: Space Invaders' saucer trick and Ghosts'n Goblins' tombstone exploit were both found and both left out, and the extractor skips those sections outright.
Fixed
- Every arcade cabinet had MAME's buttons 2 and 3 the wrong way round. The core binds MAME buttons 1-6 to retropad B, A, Y, X, L, R — not in pad-button order, which is the trap: retropad index 1 is Y, and Y carries button 3. The page bound MAME 2 as though it arrived on index 1, so for a week the button all 44 affected pages called RB was really MAME 3, and MAME 2 answered on X. Found when Sinistar's Sinibomb would not fire on the RB its page named.
The binding moved rather than the pages, because the pages were right about the intent: the arcade help page has always said button 2 sits under the index finger on RB, since the cabinets that use it tend to hold it down. One line in
systems/arcade/play.htmlfixes all hundred cabinets, and every gamedoc goes back to saying what it said. Sinistar is then deliberately different: its Sinibomb is on B, under the thumb, because it is thrown in a hurry while the other hand is still flying the ship. MAME 5's default claim on B is cleared for that game, which has no fifth button to lose. - The last three analogue cabinets are played, and Sinistar's second button was wrong. Blaster, Space Harrier and Sinistar were the three of the eight analogue-stick cabinets nobody had sat down with. All three centre correctly on the core's defaults and steer proportionally, so none of them needs the settings Star Wars needed — that makes six of the eight fine as they are, against Star Wars alone. Each is recorded in
tools/arcade-gamedoc-overrides.jsonwith what was tested, so none of them comes back as an open question. Two documented controls were wrong, and the pad found both. Sinistar's Sinibomb was on RB, where it does nothing: the core binds this game's Button 2 to retropad L, which the arcade pad map sends to B on the pad and C on the keyboard. It was read out of the core's own input list, in MAME's setup menu, and then confirmed at the pad. Blaster's third button, which the core's data cannot name, is a second Thrust, so it has a row instead of being left off. Space Harrier's three buttons are one: the core labels all three Shot and only the first fires, matching the cabinet's single trigger, so the page lists it once rather than three times. Both proportional cabinets also lose the generic hold a direction rather than tapping step, which is advice for a cabinet whose analogue port is driven from a D-pad and is simply wrong for a stick that reads how far you push it. -
Blaster stopped on its own power-on error, every single time. The cabinet opened on
HIGH SCORE TABLE RESET / FACTORY SETTINGS RESTOREDand stayed there: the board fails its settings checksum, writes itself a fresh CMOS, and waits. A reload did not help, because nothing was kept to clear — Blaster has no NVRAM handler in this 0.78-era core at all. Defender, Robotron and Sinistar each leave a.nvfile behind; Blaster leaves none, whatever you ask the core for, including the runtime's own shutdown sequence. A soft reset is what the board wants, so the page gives it one, twenty seconds after the game starts — measured, not guessed: at three and at six seconds it lands mid power-on and the board simply repeats itself, and two resets do no better than one. The reset skips itself the moment anyone presses a key, a mouse button or a pad button, so it can never restart a game already under way. The delay runs from the runtime's own start event, after the core and ROM have loaded, so a slow connection does not shorten it. -
Cores were losing their save files on tab close. The runtime asks a core to write out its save files on its own
exitevent and nowhere else, and closing a tab never fires that — so a cartridge's battery-backed save or a board's NVRAM lived in memory and died with the page./data/savesis IDBFS with autoPersist, so the storage was always willing; nothing was handing it the bytes. The shared boot glue now flushes when the page is hidden, when it is being left, and on a thirty-second backstop for a tab that crashes. This is not what ailed Blaster, whose core writes nothing to flush, and it is not yet confirmed end-to-end on a cartridge save. - The Vectrex asked for two files that were not there.
js/input.jsregistered atouchstartlistener that, on the first touch anywhere on the page, fetchedcss/touch.cssandoverlay_touch.html— both pruned with the rest of the upstream chrome in June, so both 404s. A desktop never triggered it and a touchscreen got nothing either way, since the site does not offer itself to touch devices. The listener is no longer registered, which removes the whole touch path in one line: nothing downstream runs until it fires. The line is left in place, commented, with the reason beside it, so restoring touch controls is a matter of putting back two files and uncommenting one line. The fork keeps its own copies of both files and is untouched — the breakage was ours, from the prune. Testing that with a cartridge rather than the built-in Mine Storm found a second one, on a path that runs every time.loadNotice()fetched a<key>.txtbeside each ROM — upstream's optional pre-game notice — and we ship no notices, so every Vectrex game load 404'd. A missing notice was always handled, so the function returns the same state without asking. Verified on Spike and Berzerk: ROM 200, cart loaded, overlay up, frame changing, and no failed request of any kind. -
helpran off the top of the screen. The prompt is a fixed 80x25 grid that rolls up like VGA — the buffer keeps growing but only the last 25 rows are ever visible, and there is no scrollback to reach the rest — and the reference was 31 rows one command per line, so a third of it had gone before the reader saw it. It is two columns now, the whole thing on one screen with the prompt still under it: NAVIGATION beside DISPLAY, FILES beside KEYBOARD, under a title that carries the two rules of the prompt on one line and a full-width rule in the menus' ownÄ. It clears the screen first, so it reads as a page of its own and always lands in the same place, and leaves a blank line before the prompt returns. The columns are padded in code rather than typed as spaces, so a longer description cannot quietly knock them out of line. -
Short wiki tables sat in a full-width box with an empty strip beside every row. The Commands page's Navigation and Keyboard tables were the clearest case: eight short rows, then half the column's width of nothing. A wiki table is
display:blockso a wide one can scroll inside its own box rather than squeezing the page — but a block box takes the full width the shared stylesheet gives a table, while the rows inside shrink to their content, so the border ran on long after the cells stopped. The box is sized to its content now and capped at the column, which leaves the wide ones exactly as they were, still scrolling when their content will not fit. -
Three Intellivision menu numbers started the wrong game. Rows 8, 9 and 10 named Lock 'N' Chase, Night Stalker and BurgerTime, but the numbers behind them launched BurgerTime, Lock 'N' Chase and Night Stalker; typing a launcher's name always worked. Each row now starts the game it names. Cloudy Mountain's year moves from 1981 to 1982, its cartridge date, which re-sorts the menu. The NES menu's row 7 had named Link's Awakening, the Game Boy game, over the NES Legend of Zelda it launches, and the Atari 800XL Pole Position title said 1984 for a 1983 cartridge. Every framed menu was then checked row by row against the game its number launches, and nothing else disagrees.
-
Star Wars' yoke would not return to centre. It is one of eight cabinets whose control the core's own data calls a stick rather than one of the joyNway kinds, and the first of them tested, so the pad's left stick flies it proportionally, how far you push being how far the crosshair goes. Released, though, the crosshair sprang back to a point about a quarter of the way across the screen rather than to the middle. The axis was never the problem: held hard over, the two extremes sit symmetrically either side of centre, so only the rest position was wrong. That is set by the core's "Digital Joystick Centering", which exists for driving an analogue port from a digital stick and, with a real analogue stick on the port, pulls the rest position off centre instead. Off, the crosshair rests dead centre on both axes and the yoke behaves as the sprung one did. The mouse comes off the same game while we are there. The core drives an XY device from the mouse by default, and a mouse is relative — it has no centre to return to — which is not something a sprung yoke wants sharing its input. Both are scoped to Star Wars alone. The controls page had listed it with the trackball and spinner cabinets as "digital rather than proportional", which was true of the D-pad and the keyboard but not of the stick; it and the gamedoc now say so.
-
The Intellivision menu never got the column treatment. It is the one menu on the site whose
echois padded 16 spaces rather than 17, so the sweep that dropped the code column sitewide matched not one of its rows: it kept a four-column layout nothing else had, and sat a character to the left of every other box. Re-columned and re-indented; all 1,134 frame lines now share an indent, pair their corners correctly and run a uniform rule. -
findcould not see Capcom's 1942. It skipped launchers whose name is all digits, to avoid the numbered menu aliases — but those carrydataand the loop already requires alink, so the test only ever hid the one game whose name really is a number.
[1.8.1] - 2026-09-11
Changed
-
The repository no longer carries games, BIOS or firmware that didn't come with an emulator. genx-dos.fun is unchanged and still has every one. The repo, its whole history and the release zip now hold the emulators, plus anything an emulator's own maintainer shipped with it. 382 files leave the tree and 544 file versions leave history, 644 MB in all. "Shipped by the maintainer" was settled by content, not by folder. Every candidate was hashed against the emulators' own repositories and hosted builds, and only a byte-identical match counts. That keeps jsbeeb's Acorn ROMs and the 31 BBC discs its Stairway to Hell browser serves, the whole Vectrex library jsvecx ships, the TI-99 carts in Js99'er, the Apple I tapes, VirtualT's Model 100 ROM, the nine XRoar ROMs that XRoar Online serves, and jtyone's ZX81 ROM plus the 12 tapes in its own library, once decoded from hex. Our padded Master discs, our patched 3D Monster Maze and every BIOS that didn't come with its emulator (Atari, ColecoVision, Intellivision, Lynx, Odyssey², TRS-80) go, and so, from history, do the Amiga Kickstart and the retired Mac Plus's ROM and disks. The files stay in the working tree, untracked and listed in
.gitignore, sodeploy.shships exactly what it did.build-portable.sh --no-romsbuilds the release zip without them, and it addsROMS.txt, which gives every missing file's exact path and title and says we won't discuss sourcing.sdltrs.wasmhad a Tandy Level II ROM embedded from its Model I build. The Model III never reads it, so its 12 KB are zeroed in place; the engine is otherwise byte-for-byte the same, and it stays in the repo. -
The removal route is on every page a rights holder would actually land on. The site has always promised that anything bundled will be removed upon request, but that promise was linked from one place — the landing page's footer. Someone who holds rights in a game arrives at that game: its play page, its gamedoc, its machine's controls page. None of those offered any route to us, which left the one person we most want to hear from with the least obvious way to reach us. The link now sits in the credit bar on every play page, in the footer of every controls page, and in a new footer on all 428 gamedocs, which previously had none. The arcade gamedoc generator emits it too, so a regenerate cannot drop it.
-
One design language for everything you read, in one file.
styles/genx-doc.cssnow sets the type on the controls pages, the hundred-odd gamedocs and all forty-three wiki pages: the landing page's Michroma amber headings with the rule running off the end of a section label, its serif body on the dark CRT ground, its green mono table headers. There had been two of these, and they had drifted apart without anyone choosing it — the controls sheet and the wiki sheet were parallel implementations of the same idea, at section headings of .85rem against 1rem, table headers green against amber, table type at .92rem against .88rem, and two different paragraph rhythms. The link rule alone existed in four copies, at two different border weights and two different focus rings, one of them with no focus ring at all; three of those then re-coloured links per context, so a gamedoc's cross-link was amber while the link in the sentence below it was cyan. Lists, block quotes, horizontal rules and inline code had been styled for the wiki only, so a gamedoc's bullets were whatever the browser felt like. The docs are also in the landing page's face now. They had been set in IBM Plex Serif — a second voice nothing else on the site spoke, and the reason the two halves of the site never quite looked related. Everything a reader meets is IBM Plex Mono at the landing page's 16px/1.65, with Michroma still carrying the headings. The one remaining serif, on the closing aside of every controls page, went with it. A document now loads one stylesheet.systems/_shared/styles/genx-controls.cssis gone, its page frame folded intogenx-doc.css, and all 463 gamedocs and controls pages link the shared sheet directly. The wiki keeps a second file for its sidebar, top bar, search box and hit list, which no other page has any use for. The one rule that could not simply move is the key/action column behaviour — a controls table shrinks its first columns to fit and gives the rest to the last one, which would have wrecked a wiki table, where every column is prose; it is scoped to the page frame those tables actually sit in. The feature article came onto the same sheet last. It had been the one document still setting its own type — serif, its own size, its own justification — and it keeps everything that makes it a feature: the measure, the kicker, the drop cap, the pull quotes and the boxout rail. Only the type is shared now. That leaves no document on the site setting its own face, and body copy is justified with hyphenation throughout, which is what the article had been doing alone. Body copy and subheadings are set the way the landing page sets its cards — subheadings in mono amber at reading size rather than shrunk into another uppercase label, and prose a shade back from--paperso that bold, links and table data carry the emphasis instead of every sentence competing for it. That colour is now a token,--prose, rather than a hex literal repeated per sheet. The controls version is the one kept, because it is the one that follows the landing page — its section heading is the landing page's.sec-label, rule and all. The wiki keeps its frame, sidebar, search box and its scrolling tables, because a wiki table is prose and can be wide; a controls table is a key/action grid and keeps its own column behaviour. Page furniture that happens to be an anchor — the masthead, the sidebar buttons, the BOOT button — is styled by its own class and is untouched. -
The menus lost their code column. Every framed menu on the site ran four columns — number, title, year, and the DOS command that launches it — and the fourth was eating the space the titles needed. Dropping it freed eleven characters, so sixteen titles that had been squeezed to fit are now written out in full, and the year sits one space off the border instead of two. 359 dated rows and 29 yearless ones changed across 708 framed rows, every one still exactly 45 characters wide. The codes were never decorative —
berzerkis a real command, and typing it still works. What's gone is the column that advertised them, which is the sort of thing a DOS user found out by typingdiranyway. -
The game launchers are
.exefiles now. A launcher opens a program, so calling itberzerk.batwas describing it as a batch script, which it never was. The 351 named launchers — the ones carrying alink:— are now.EXE; the 408 numbered shortcuts and themenu.batscripts genuinely are batch files and keep the extension. Nothing about running them changed:BERZERK,berzerk.exeand the menu number all still work, because the shell matches on the base name and checks for a link before it ever looks at the extension.TYPE BERZERK.EXEnow does what DOS did — prints the program's bytes as CP437 glyphs, startingMZ, and stops dead at the first Ctrl-Z, which is why you get a short burst of noise rather than a screenful. The bytes are generated from the filename rather than stored, so each program has its own stable garbage andfs.jsdoesn't gain 351 blobs of it. Five byte values are shifted into printable range because the console acts on them instead of drawing them — bell, backspace, tab, linefeed, carriage return — exactly the five DOS's own console consumed. Deliberately absent: This program cannot be run in DOS mode. That string belongs to the Windows PE stub, and a machine pretending to be a DOS box has no business printing it.
Fixed
-
Twelve vendored images that nothing used were shipping to every BBC visitor. jsbeeb's own web UI has an example screenshot, a sidebar, a bottom bar, two disc-drive icons and an app icon; our embedded build uses none of them — its page asks only for the cub monitor and a placeholder — but all six were in the tree twice, once per BBC machine, and all twelve reached the web host. Removed. They will come back if the fork is ever re-vendored, so the re-vendor recipe should strip them.
-
We were sending Chrome, Edge, Brave and Opera players to another browser over a fault on one machine. An orange banner on the CoCo and Vectrex pages told every Chromium visitor that "USB controllers are not recognised" and to use Firefox instead; six Vectrex gamedocs, two CoCo gamedocs, the Vectrex controls page, the README and two wiki pages all said the same. None of it was true. The cause was local: the browser those findings were made in is a Flatpak, and the sandbox had no
/run/udev. A browser enumerates gamepads through udev on Linux, so it found none — on every site, in every emulator, focused or not. The device node itself was readable the whole time, which is why it looked like an emulator problem: the pad was plainly there, and nothing could see it. Two engines were blamed for it in turn, one of them twice. With udev visible, the same pad drives Vectrex Berzerk and CoCo Galactic Attack in Chrome, on the same pages, over plain HTTP — full analogue range on the Vectrex's stick, which is the control that machine is actually about. The banner and its script are gone, and the pages now say the one thing that is true of every browser: a pad is only handed over once a button is pressed on a focused page, so click the game area and press again. -
Every EmulatorJS bundle was booting its core with an empty options file. The arcade cabinet opened on MAME's copyright warning however
skip_disclaimerwas set, and the reason turned out to be sitewide: EmulatorJS writes the core's option file fromgetCoreSettings(), and that function consults the page's defaults only when the browser has no localStorage or when this game already has a saved settings entry. The entry is keyed per ROM URL and is only written once a player changes something, so on a first visit — every visitor's first visit to every one of the site's EmulatorJS games — the file was written empty and the core ran on its own factory settings. The C64's true drive emulation, the arcade's two skip options, the joyport type: none of them were reaching a core until the player had been into the settings menu and changed something at random. The page's defaults are now appended to whatever EmulatorJS writes, in its own format, for any option it did not write itself. A saved setting still wins, which is the point of a saved setting. Done in our own boot glue rather than by editing the vendored runtime, hooked through a property setter so it lands the moment the emulator is constructed — well before the core asks for the file. -
findhas never once printed a game's title. It parses each menu's rows to learn what a launcher is called, and its pattern expected theechoand the box border to be adjacent — but the menus are padded out to centre the box, so the pattern matched no row anywhere on the site. Every result fell back to the launcher name printed twice:DEMON DEMON. The wiki's example output showed titles because it had been written from intent rather than from a run; it is now generated from the real thing. Fixing the pattern exposed the second half: with the code column gone there was nothing left to key titles on, so the index is rebuilt on the row number instead, which the numbered.batbeside each row resolves to a launcher (smb) or a sub-directory (cd bbc). That last part is new — directory rows never resolved before, sofind acornsaidACORN ACORNand now saysAcorn (1981). -
Pokémon Red had a Greek capital theta in it. The font sheet is indexed by character code —
charCodeAtpicks the sprite directly, with no Unicode translation — so a glyph is written as whatever character sits at that code, which is why the box borders are spelledÉÍ»º. The title had been written with a realé(U+00E9 = 233), and sprite 233 is CP437'sΘ. It now holds char 130, CP437's actualé, written as\x82rather than the invisible control character that lives at U+0082. Swept the other 397 menu titles for the same mistake:Odyssey²is the only other non-ASCII one and it was already right. Nothing else on the site renders a character it doesn't mean to. Searching for it was fixed properly rather than patched.findhad a special case truncating any query starting withodyssey, becauseOdysseyýcould never match what a person types; that is replaced by a fold applied to the title before matching — CP437's accented-letter block back to plain letters, 253 to2— plus a retry with spaces stripped from both sides. Sofind pokemonandfind "odyssey 2"both land, and the next title that needs a trick glyph needs no code at all. -
dirandfindcrashed on the three handhelds. The Game Boy, Lynx and Game Gear directories were written without the emptyfilesanddirectoriesarrays every other directory has, and both commands index those arrays without checking.cd gameboyfollowed bydirthrew, andfindthrew on any query, because it walks the whole tree and always reached them. Nothing about the games was wrong — six missing[]s.
[1.8.0] - 2026-09-05
Added
- The wiki has search. Forty-three pages had no way to find anything in them but the sidebar and guesswork.
build.pynow indexes every page by section — 505 of them — and generates aSearch.htmlthat filters as you type, ranks a heading match above a body match, and links each hit straight to the section anchor it came from. The interesting part is the content policy. These pages rundefault-src 'none'with noscript-src, which is why not one of them has ever executed a line of JavaScript, and that is a property worth keeping. So the search page carries the standard policy plus the SHA-256 of exactly the script it contains — not'unsafe-inline', which would permit any inline script on the page. The hash is computed as the script is written, in the same function, so the two cannot drift apart. Every other page in the wiki is untouched and still runs nothing. The index is inlined rather than fetched, so the page needs noconnect-srcand works from a downloaded copy with no server at all —fetch()of a local JSON would be blocked as cross-origin fromfile://. Section text is capped at 700 characters, which took the page from 224 KB gzipped to 107 KB while leaving every section findable by its heading and its opening. Two bugs on the way there, both worth recording. The wiki's WebMSX page discusses the</script>footgun, so those characters were in the index — and an HTML parser ends a script element at `