Pac-Man's Last Level Is Drawn by Its Fruit
Pac-Man has no ending either. Clear 255 mazes and the 256th comes up broken: the left half looks normal, but the right half is a wall of letters, numbers, scraps of fruit and odd colours. Pac-Man can wander into it, but the level can never be finished. Players call it the split screen.
Like Donkey Kong's kill screen, nobody designed it. It comes from a few lines of code that draw the little row of fruit in the bottom right corner, the one that shows how far you have come. This article walks through that code in the original Midway arcade program.
The fruit row
The bottom right of the screen shows a fruit for each level you have reached, one on level 1, two on level 2, and so on. There is room for seven. Once you are past level 7 it shows the seven most recent, and late in the game the row stops changing.
The game keeps the level in a single byte of memory at $4E13, counting from
0. Level 1 is stored as 0, level 2 as 1, and level 256 as 255, the largest
number a byte can hold. Nothing stops the count there. It is simply never
asked to go higher, because nobody gets further.
The routine that draws the row, at $2BEA in the program ROM, starts by
working out how many fruit to show. Since the level counts from 0, that is
the level byte plus one:
ld a,(level) ; the level, counting from 0
inc a ; + 1 = how many fruit to draw
cp 8 ; 8 or more?
jp nc,capped ; yes: draw the seven most recent instead
ld de,fruits ; no: start at the top of the fruit table
ld b,a ; B = how many times to go round the loop
Fewer than 8, draw that many from the start of the fruit table. Eight or more, take a separate path that picks the last seven. It works perfectly for 255 levels.
Two numbers that wrap
On level 256, two small things go wrong in a row.
First, the count wraps. The level byte holds 255. Adding one gives 256, which does not fit in a byte, so it wraps around to 0. The game has just worked out that level 256 needs zero fruit.
Then the check lets it through. Is 0 eight or more? No. So the game takes the path meant for levels 1 to 7 and sets up a loop to draw "zero" fruit.
Then the loop counts the wrong way round. The loop uses the Z80's DJNZ
instruction: subtract one from B, and go round again unless B is now zero. It
subtracts first, then checks. Starting from 0, the first subtraction gives
255, not zero, so the loop keeps going: 254, 253, all the way down. It
finally stops when B reaches zero again, 256 trips later.
A loop told to draw nothing draws 256 fruit.
Where 256 fruit go
There are only seven fruit in the row and only 19 entries in the fruit table. The loop does not know that. Each trip it reads the next two bytes from the table, a picture number and a colour, and draws a two-by-two block of screen cells, two cells further along than the last one. After the 19th entry it just keeps reading whatever comes after the table in the program ROM, 512 bytes in all, and drawing them as if they were fruit.
Where those blocks land is down to how Pac-Man's screen is laid out in memory. The fruit row lives in the bottom two rows of the screen, stored right to left. The byte after the end of those rows is not the next row. It is the top of the maze's rightmost column. The maze is stored a column at a time, top to bottom, working from right to left.
So the runaway loop runs off the left end of the fruit row, reappears at the top right of the maze, and eats its way down one column after another:
256 blocks is enough to cover the 15 rightmost columns of the maze completely and the top of a 16th. The maze is 28 columns wide, so that is the right half and a little more, which is exactly where the garbage sits. After the loop, the routine blanks out what it thinks are the seven unused fruit slots. Its slot counter has also wrapped all the way round to where it started, so it blanks seven more blocks, and those land right by the middle of the screen as a black stripe.
Every write, counted
The original program was run under a test script that set the level byte to 254 and the dot count to one short of finished, then let the game finish level 255 and set up level 256 by itself, recording every write the fruit routine made to the screen.
| What the code predicts | What was recorded |
|---|---|
| The level byte reads 255 | 255 |
| 256 fruit blocks | 256, with the loop counter going 0, 255, 254, … 1 |
| Seven blank blocks afterward | 7 |
| 512 bytes read from the fruit table and beyond | 512 |
| Writes run off the fruit row into the maze, right to left | Every write landed in the area shaded on the map above |
For comparison, the same run on level 255 drew seven blocks, all keys, and touched nothing outside the fruit row.
Why it can't be finished
A level ends when Pac-Man has eaten 244 dots and energizers. The game counts a dot when Pac-Man moves onto a screen cell that holds the dot picture or the energizer picture, nothing else.
On level 256, most of the dots were on the right side, under the garbage. Counting the screen just before play started:
| Part of the maze | Dots | Energizers |
|---|---|---|
| Left alone | 112 | 2 |
| Written over | 9 (garbage that happens to be the dot picture) | 0 |
That is 123 dots to eat, against the 244 needed.
There is a twist that makes it worse and better at once. When Pac-Man dies, the game redraws the fruit row, so the whole runaway loop runs again and the garbage, including those 9 stray dots, comes back. With the 9 junk dots removed by hand, Pac-Man died, and all 9 came back. The real dots he had eaten on the left side stayed eaten, and so did the count.
So the best a player can do is the 114 dots and energizers on the good side, plus 9 more for every life. Getting to 244 that way would take 15 lives. A machine can be set to give you at most 5 to start with. Even that best case assumes all 9 junk dots can be reached through the garbage, which was not tested.
Level 256 is the end.
Credits and further reading
- Don Hodges, "Pac-Man's Split Screen Level Analyzed and Fixed", the classic write-up of this bug, with a patch that fixes it. This article's analysis was done from the ROM first and compared with Hodges' afterwards; they agree.
- The MAME project's Pac-Man driver, for the hardware memory map.