Q-bert (USA)
Q-bert (USA) is on a CNROM board with 32,768 bytes of program. A crawl of 400 steps from power-on kept 17 paths that found new code. Played back over 20,757 frames, they executed 4,409 bytes of it, 13 percent.
What the rules named
- The poll: 2
- The idle spin: 1
- The game inside the interrupt: 1
- The jump engine: 1
- The bank switch: 3
- The picture writer: 1
- The palette writers: 1
- The sprite writers: 5
- The scroll writer: 1
- The sound driver: 1
- The random byte: 1
The 123 routines the runs entered
Every place the game's code was entered, by a call, an interrupt or a jump through a table. The ones a rule named come first, with what the rule saw.
| at | entered by | times | what it is, and the evidence |
|---|---|---|---|
| $911E | a call | 161,477 | The sprite writers: frames it ran in 10,092, writes to the sprite page 243,315 |
| $91EC | a call | 81,105 | The sprite writers: frames it ran in 5,932, writes to the sprite page 81,103 |
| $8207 | a call | 22,502 | The jump engine: tables 9, jumps through them 22,502 |
| $CC12 | a call | 20,194 | The poll: port $4016, reads a frame 16, strobes a frame 4 The poll: port $4017, reads a frame 16, strobes a frame 4 |
| $CE58 | a call | 13,960 | The sound driver: frames it ran in 3,528, writes 1,067 |
| $CAF5 | each frame (NMI) | 10,138 | The game inside the interrupt: frames it ran in 10,138, frames in all 10,257, the spin is at $CAF2 |
| $90A5 | a call | 10,109 | The palette writers: frames it ran in 10,109, writes 1,440 The picture writer: frames it ran in 10,109, writes 19,680, in the blank 19,680, while drawing 0 |
| $CB69 | a call | 10,109 | The scroll writer: frames it ran in 10,109, writes in the blank 20,218 |
| $8000 | a call | 10,097 | The random byte: frames it ran in 9,935, bytes $003C,$003D, rotates 2, exclusive-ors 1 |
| $9292 | a call | 10,095 | The sprite writers: frames it ran in 10,092, writes to the sprite page 564,785 |
| $E88D | a call | 116 | The sprite writers: frames it ran in 116, writes to the sprite page 116 |
| $CC3B | a call | 40 | The bank switch: writes 80, in the blank 0, while drawing 80 |
| $CA85 | power-on | 17 | The bank switch: writes 34, in the blank 34, while drawing 0 The sprite writers: frames it ran in 10,172, writes to the sprite page 4,352 |
| $CC37 | a call | 17 | The bank switch: writes 34, in the blank 0, while drawing 34 |
| $8452 | a call | 128,000 | |
| $9329 | a call | 91,197 | |
| $D3CD | a call | 13,960 | |
| $CB9F | a call | 10,109 | |
| $CBB5 | a call | 10,098 | |
| $CD6C | a call | 10,098 | |
| $CDDA | a call | 10,098 | |
| $CE3C | a call | 10,098 | |
| $CBDB | a call | 10,097 | |
| $CBF7 | a call | 10,097 | |
| $84FD | a call | 10,092 | |
| $D430 | a call | 7,147 | |
| $CE35 | a call | 6,719 | |
| $D4C9 | a call | 6,355 | |
| $8132 | a call | 5,698 | |
| $811C | a table | 4,111 | |
| $8220 | a call | 3,871 | |
| $D20E | a call | 3,316 | |
| $D237 | a call | 3,316 | |
| $802D | a table | 3,180 | |
| $9C73 | a table | 2,748 | |
| $9CDC | a table | 2,736 | |
| $E510 | a call | 2,736 | |
| $E8B9 | a call | 2,572 | |
| $E5D4 | a table | 2,513 | |
| $D1A7 | a call | 2,483 | |
| $D1C6 | a call | 2,483 | |
| $E611 | a table | 2,396 | |
| $E85F | a call | 2,396 | |
| $E8E0 | a call | 2,396 | |
| $D252 | a call | 1,970 | |
| $84F4 | a call | 1,914 | |
| $84A1 | a call | 1,870 | |
| $81B5 | a call | 1,570 | |
| $C272 | a call | 934 | |
| $D0B7 | a call | 924 | |
| $D1D3 | a call | 833 | |
| $C28E | a table | 705 | |
| $C29D | a call | 705 | |
| $C4FF | a call | 705 | |
| $C54A | a call | 667 | |
| $C286 | a table | 594 | |
| $C55F | a call | 358 | |
| $CC8E | a call | 352 | |
| $C56A | a call | 347 | |
| $D3E7 | a table | 302 | |
| $C243 | a call | 294 | |
| $D2BA | a table | 292 | |
| $C268 | a call | 229 | |
| $84EE | a call | 185 | |
| $84F6 | a call | 185 | |
| $E59A | a table | 176 | |
| $E5AF | a table | 176 | |
| $C145 | a call | 147 | |
| $C190 | a call | 147 | |
| $C196 | a call | 147 | |
| $E81A | a call | 147 | |
| $CB89 | a call | 102 | |
| $D370 | a table | 102 | |
| $D1FD | a call | 92 | |
| $D39C | a call | 90 | |
| $D38F | a call | 86 | |
| $C4E3 | a call | 82 | |
| $D2C1 | a table | 67 | |
| $E575 | a call | 60 | |
| $E5DF | a table | 60 | |
| $E5FA | a table | 57 | |
| $C1F1 | a call | 49 | |
| $C216 | a table | 49 | |
| $C21F | a table | 49 | |
| $C4C4 | a call | 49 | |
| $CEBE | a call | 49 | |
| $E51D | a table | 47 | |
| $83E4 | a call | 45 | |
| $CD57 | a call | 45 | |
| $E94D | a call | 42 | |
| $814C | a call | 40 | |
| $83E0 | a call | 40 | |
| $D2D4 | a table | 40 | |
| $C555 | a call | 38 | |
| $CBC3 | a call | 37 | |
| $8143 | a call | 34 | |
| $C23C | a call | 33 | |
| $C2AF | a table | 33 | |
| $C2F7 | a call | 33 | |
| $C33E | a call | 33 | |
| $CC56 | a call | 33 | |
| $E940 | a call | 31 | |
| $81D4 | a call | 28 | |
| $9E2B | a table | 23 | |
| $9E1F | a table | 22 | |
| $E918 | a call | 20 | |
| $8157 | a table | 17 | |
| $8174 | a table | 17 | |
| $817F | a table | 17 | |
| $CA8A | an interrupt (IRQ) | 17 | |
| $CB53 | a call | 17 | |
| $83BA | a call | 16 | |
| $D340 | a table | 15 | |
| $80F2 | a table | 12 | |
| $8107 | a table | 12 | |
| $81CF | a call | 12 | |
| $81D8 | a call | 12 | |
| $9CA8 | a table | 12 | |
| $9CE7 | a table | 12 | |
| $E645 | a call | 9 | |
| $9E27 | a table | 4 | |
| $D3DA | a call | 4 | |
| $E908 | a call | 2 |
Where it waits
Loops a rule named that sit inside a routine and are not themselves a place the code is entered.
| at | what it is, and the evidence |
|---|---|
| $CAF2 | The idle spin: turns 74,970,040, turns a frame 7,309 |
The jump engine's tables
Each table sits right after a call to the engine. An entry is counted as far as the runs saw one taken; the true table may be longer. The last column is the byte of memory whose value picked the entry, where we could follow it: the game's mode, or what one of its objects is doing.
| at | entries | taken | chosen by the byte at |
|---|---|---|---|
| $801B | 9 | 7 | $0018 |
| $8179 | 1 | 1 | $0090 |
| $9C8A | 2 | 2 | $0034 |
| $9CE1 | 2 | 2 | $0090 |
| $C1F8 | 11 | 5 | $0053 |
| $E515 | 3 | 3 | $008E |
| $E59F | 1 | 1 | $008F |
| $E5D9 | 3 | 3 | $008F |
| $E885 | 3 | 3 | $002E |
The memory its routines share
262 bytes of memory were written by one routine and read by another, and 60 places were reached through an index, which is what a table or a set of object slots in memory looks like.
Reaches through an index: those that hold positions, then the longest
| from | bytes reached | instructions | positions it holds |
|---|---|---|---|
| $0300 | 256 | 14 | |
| $0700 | 256 | 7 | |
| $0400 | 256 | 1 | |
| $0500 | 256 | 1 | |
| $0200 | 253 | 2 | |
| $0201 | 253 | 1 | |
| $0202 | 253 | 1 | |
| $0203 | 253 | 1 | |
| $0000 | 152 | 4 | |
| $0600 | 128 | 1 | |
| $040F | 17 | 1 | |
| $0460 | 16 | 3 |
The 24 busiest shared bytes
| byte | reads and writes | routines writing | routines reading |
|---|---|---|---|
| $0000 | 984,210 | 6 | 6 |
| $0001 | 824,556 | 6 | 6 |
| $0008 | 778,447 | 4 | 5 |
| $0009 | 753,799 | 2 | 3 |
| $0003 | 600,520 | 6 | 6 |
| $0002 | 559,512 | 6 | 6 |
| $000E | 263,497 | 2 | 3 |
| $000C | 214,034 | 2 | 3 |
| $000B | 172,316 | 2 | 2 |
| $00AB | 88,058 | 2 | 6 |
| $0022 | 82,095 | 2 | 3 |
| $00F7 | 60,616 | 2 | 3 |
| $009A | 41,813 | 6 | 6 |
| $000D | 37,429 | 2 | 3 |
| $0032 | 35,358 | 6 | 6 |
| $0030 | 35,145 | 3 | 4 |
| $00F5 | 33,465 | 2 | 4 |
| $00A5 | 32,458 | 6 | 6 |
| $001E | 31,592 | 6 | 6 |
| $0098 | 27,530 | 3 | 6 |
| $0099 | 27,530 | 3 | 6 |
| $00AC | 24,092 | 1 | 3 |
| $00FF | 22,567 | 4 | 4 |
| $001D | 21,267 | 5 | 3 |
This page shows none of the game's bytes. The listing these figures were read from stays with the cartridge.