Pippols (1985)

A 16 KB cartridge from 1985 that moves the screen one pixel at a time in a video mode with no scrolling at all. It manages it by keeping the background in video memory eight times over and repainting the whole screen every frame, and that takes three quarters of the machine's time.

Konami · 1985 · An RC-729 16 KB cartridge · MSX1 · page 1 · Dump ad011203…

There is not one screenshot here. Every picture is drawn by repeating what the cartridge does: video memory is rebuilt with its own copies and the characters and the map are put back together with its own tables. Everything else —the listing and the numbers— comes from the binary and is reproducible with make.

The game in numbers

100%of the binary explained
18screens in the world
192characters for the scroll
9,099bytes of code
7,285bytes of data
0bytes unidentified

What turned up when we took it apart

The background is in video memory eight times over

SCREEN 2 has no scroll register, so Pippols builds one: VRAM holds 192 characters (0x40 to 0xFF) that are eight copies of the same set of 24, each one a pixel lower. Scrolling the screen by a pixel means adding 24 to the character number and writing the whole name table again, 24 rows by 22 columns, every frame; not one pattern is touched.

Of the twelve characters in each half, four are seams (0x56ED): the end of one strip on top and the beginning of another underneath. Without them the drawing would split halfway down as soon as the offset was not zero.

The game's entire map fits in 328 bytes

A stage is thirteen stretches of 24 rows; a stretch, six pieces of four columns; and the 44 pieces are built in RAM by gluing groups of three rows from a dictionary of 25 (0x54C0). The index list —eight per piece— is 328 bytes, and that describes the whole road.

The loop at 0x5496, though, reads 352 indices: the last 24 reads land inside the code at 0x5653, and out of that come three junk pieces. It does not matter, because no stretch points at them. Nor at pieces 0 and 1, which are properly built.

What it costs, measured in the emulator

In openMSX, on a Philips VG-8020 (PAL, 71,591 cycles per frame) over 1112 frames of the demo: repainting the name table takes 32,557 cycles on average, 45.5 % of the frame, and the whole interrupt 52,533, or 73.4 %. That is 732.7 writes to the VDP port per frame.

Which is why the main program does nothing: it sits in a two-byte jr $ at 0x4074 and the entire game runs inside the interrupt, one step per frame.

The score lies by a factor of ten

The score is three BCD bytes, but the panel paints the six digits and then a fixed zero behind them. What you see is ten times the counter, which is why every score ends in zero. The first extra life comes at 20,000 and then every 60,000.

A jump that lands inside another instruction

At 0x717D there is a jr nz,$+4 that ends up at 0x7181, and 0x7181 is not the start of anything: it is the displacement byte of the jr z on the line above. It executes as dec b, which does not matter there because the creature loop keeps BC on the stack, and carries straight on. It is the only place in the cartridge where an instruction is entered halfway through.

Eighteen screens and five drawings

The 18 world screens share the background drawings: there are eight stages but only five sets of strips, and what changes from one screen to another is a swap of three pairs of inks (0x577D) over the 96 colour bytes. The same flower comes out red or pink, the same tree green or blue.

And the route is not a line: the table at 0x7B62 gives two destinations per screen, and one or the other is taken depending on whether you are going up or down.

The boot and the shield are the same drawing

In the table at 0x785A each object carries its (pattern, colour) pair. Object 8 —the boot, which makes you walk one and a half times faster— and object 9 —the shield— carry the same pattern, 0xC0, and differ only in colour. Objects 1 and 4 do the same with pattern 0xA4.

What the cartridge draws

Each of these pictures is the cartridge replayed outside it: the background strips are decompressed the way the ROM decompresses them, the 192 characters are generated with the same loop and the map is assembled from the same tables. Under each caption is the address of the routine it comes from.

0x569E — the same window of background at the eight offsets. Between one and the next only the character number changes, by 24
0x569E — the same window of background at the eight offsets. Between one and the next only the character number changes, by 24
0x56B5 — one stage's 192 characters: each row is one offset, and the last four of each half are the seams that keep the drawing continuous
0x56B5 — one stage's 192 characters: each row is one offset, and the last four of each half are the seams that keep the drawing continuous
0x571E — the eight background stages side by side: five sets of strips and an ink swap (0x577D) for the 18 screens
0x571E — the eight background stages side by side: five sets of strips and an ink swap (0x577D) for the 18 screens
0x5384 — stage 0, the flowers. A whole screen assembled from the map tables: thirteen stretches of six four-column pieces
0x5384 — stage 0, the flowers. A whole screen assembled from the map tables: thirteen stretches of six four-column pieces
0x5384 — stage 1, the green trees
0x5384 — stage 1, the green trees
0x5384 — stage 4: the same trees with different inks, without one new byte of drawing
0x5384 — stage 4: the same trees with different inks, without one new byte of drawing
0x5384 — stage 2, the tall trees in blue
0x5384 — stage 2, the tall trees in blue
0x5384 — stage 5: the same ones, in red
0x5384 — stage 5: the same ones, in red
0x5384 — stage 3, the moai, with the road opening up in the middle
0x5384 — stage 3, the moai, with the road opening up in the middle
0x5384 — stage 6: the moai in green
0x5384 — stage 6: the moai in green
0x5384 — stage 7, the two-colour flowers; the only set of strips with all four different
0x5384 — stage 7, the two-colour flowers; the only set of strips with all four different
0x5312 — the same stage 0, four pixels lower. That is all it takes to scroll the screen: the character number
0x5312 — the same stage 0, four pixels lower. That is all it takes to scroll the screen: the character number
0x5E67 — the 64 16x16 sprites as they end up in VRAM: the little fellow, the twelve creatures, the objects, the points labels and the shots
0x5E67 — the 64 16x16 sprites as they end up in VRAM: the little fellow, the twelve creatures, the objects, the points labels and the shots