The code

How the listing is made and why you can trust it.

The listing is generated

Nobody edits the .asm. tools/mkasm.py generates it from three things:

That way the comments survive a re-trace: if tomorrow a block turns out to be code, you re-trace and the comments stay where they were.

What decides: reassembling

make verify

assembles the listing with pasmo and compares the result to the ROM. Byte for byte, the same sha256. Without that, everything else is decoration.

What reassembling does NOT catch

Reassembling cannot tell bytes read as code from the same bytes read as data: the binary comes out the same. So there are three more checks:

The entry points that cannot be deduced

Static tracing does not reach everything. The ones that have to be declared by hand live in src/holeinonepro.entries, each with its justification:

The numbers

traced code14,186 bytes (43.3%)
identified data18,582 bytes (56.7%)
unaccounted for0
instructions7,133
line comments3,169
density44.4%
routines below 10%0
call targets left unnamed0

The last three are the series' bar, and all three are cleared.

The arithmetic library

Between 0x6485 and 0x6564 there is a small, well-made library, and at 0x6564 the routine that builds its tables in RAM at boot:

That is enough for everything: the angle between two points, the distance, the decomposition of a velocity into its two components, and friction.

The sound

Twelve PSG tracks, with the pointer table at 0x6B55 and the interpreter at 0x6B83, which runs once per interrupt.

The rules, read off the code: a byte with bit 7 or bit 6 set is a note — the bottom six bits index, doubled, the tone table at 0x6C0D; with bit 5 clear it is a wait in frames; and the rest are commands: 0x2D stores the envelope shape, 0x33 is a jump, 0x3D is the stop and 0x3E zeroes registers 0 to 5.

Where each track ends is not written down. Following them with that same interpreter (tools/pistas.py) gives twelve runs that fit without a gap, and two things turn up: five tracks share a tail — 5 runs into 6, 6 into 0, 0 into 1, 1 into 7, and all five end at the same stop at 0x6D7A — and track 11 is the only one that loops, because it ends in a jump to itself. The highest note the twelve use is 43, which is exactly where the tone table ends.

This reading reproduces the cartridge's interpreter, but it is not corroborated against the emulator. The boundaries are measured; that it sounds like what is described here is not claimed.