How it is done

Four small tools, each checked against cartridges of our own before it touched anybody else's.

The listing is the record

A cartridge holds a program and its pictures. The listing writes both as text an assembler could take: labels, instructions, and plain bytes for everything not known to be code. Whatever we learn goes into the comments as marks, and each mark says who found it: the walk from the address the console starts at, a run of the game, a rule, or a person. There is one check, and it is strict: the file assembles back to the cartridge byte for byte. A wrong guess about what is code shows up as a failure, not as a plausible page.

The format is written down where the tool lives: github.com/tinymachines/public/blob/main/wasm/listing/FORMAT.md.

The crawl plays the game for us

Reading a cartridge from its starting address finds only what that address leads to, and most of a game is reached through tables the reading cannot follow. So a program plays it. From a saved position it holds each combination of buttons for a moment, watches which instructions ran, and keeps the position if any of them had never run before. When nothing new runs, it prefers positions where memory took values it had not held, because a level has to be walked through before its next routine runs. Every position it keeps comes with the button presses that reach it, so any finding can be played again.

The survey on these pages used 400 steps of crawling for each game.

A run says what each routine did

Each path the crawl kept is played once more with the console recording every access the processor made. From that we know where each routine was entered and how, the memory and the hardware it touched, where the beam was on the screen when it touched them, and which calls chose their destination from a table. We also follow every value from the byte of memory it was loaded from, through whatever the game copies it into, so we can say which bytes end up as a position on the screen, where two of them are compared, what gets added into a position, and which byte picked the way through a jump table.

The rules read what ran

A rule names a routine by what it did, never by what its bytes look like. No evidence, no name. Each name carries the numbers the rule saw, so a reader can disagree with it. The patterns, and how each is told.

The model is the listing, read back

Everything on these pages comes from one file for each game that holds the listing’s marks and none of its bytes: the routines with their names, the tables, the memory they share, and how much of the program ran.

The bytes stay on our machine

The cartridges are ours, read from carts we own, and their bytes do not leave the machine they are on: not the listings, and not the recordings of the runs. What is published is shape.

What it cannot see yet

  • A short crawl from power-on reaches a small part of a big game. Longer crawls, started past the title screen, are what move the numbers.
  • Code a game copies into memory and runs there has no place in a listing of the cartridge, so it is left out.
  • A routine reached by returning to an address the game put on the stack itself is followed as a return, not as a jump through a table.
  • We name the routine where two positions are compared, but not what the comparison is for. A test for two things touching, an enemy asking which side the player is on and a sort by depth all look the same to the rule.

The desk does this to a run of your own

On the desk at Create, record a run of a game from your own disk, read it, and open the Listing window. It writes that cartridge’s listing in your browser and shows what these pages show. Nothing is sent anywhere.