Bomber Man

Eight kilobytes from 1983, the smallest cartridge in the series, and the whole game fits inside without using a single sprite: the bomber, the monsters, the bombs and the flames are all name-table tiles. Its cartridge header is code, and the names of its two programmers are inside.

Hudson Soft · 1983 · An 8 KB cartridge · MSX1 · page 1 · Dump eab39bab…

There is not one illustration or capture here. The wordmark, the title screen and the in-game screen are drawn from the bytes of the ROM, by running in Python the same steps the Z80 runs, and checked against openMSX's VRAM: zero differences in everything that is not left to chance. The listing and the numbers come from the binary and are reproducible with make.

The cartridge in numbers

100%of the binary explained
50.2%of instructions commented
0routines left unexplained
3,557bytes of code
4,635bytes of data
64automatic checks

What turned up when we took it apart

The cartridge header is code

An MSX cartridge starts with AB, the INIT address, and then STATEMENT, DEVICE, TEXT and six reserved bytes. Here INIT is 0x4004, which is exactly where those fields should begin. Read as instructions they are the start of the game:

4004  31 00 F0     ld sp,0F000h
4007  CD D1 4F     call 4FD1h
400A  CD 62 50     call 5062h
400D  CD 4E 40     call 404Eh

Only the first four bytes of the cartridge are really a header. The other nine are the first four instructions.

Two programmers, and a typo by Hudson

The title screen, drawn from the ROM, reads PROGRAMMER:Y.TANAKA and below it T.SASAGAWA. Two of them, not one. And the last line reads PUSH SPACE-KEY OR TORIGER: TORIGER, not TRIGGER.

The texts cannot be read by looking at the bytes: the cartridge's font is not quite ASCII and, on top of that, changes halfway through the game. Byte 0x21, which in ASCII would be a !, is the colon here; that is why reading it raw looked like "PROGRAMMER!". The only way to quote a text out of this cartridge is to draw it.

Every fourth stage the game drops the bombs for you

pon_una_bomba (0x491C) checks the stage number with an and 003h: on multiples of four it does not ask for the trigger and the bomb drops by itself. And there is a label announcing it, blinking at the bottom sixteen frames on and eight off, under exactly the same condition (0x4D37): BOMB AUTO SETTING STAGE.

A whole game mode hidden in two instructions.

The blast reaches two cells and only breaks the bricks in one

Each arm of the blast is four screen tiles, that is two board cells. But the loop is unrolled on purpose and the four are not treated alike: the first two call pinta_una_llama_y_gasta_el_ladrillo (0x4B21), which crumbles the brick over eight frames; the third and fourth call pinta_una_llama_sin_gastar (0x4B5A), which returns without writing if what it finds is a brick.

Measured in openMSX, not deduced: two bombs written by hand into the list, one with a brick right next to it and one with the brick two cells away. Both of the first one's fall; the second one's is still standing.

Eight prizes, and the auto-bomb stage does not get the same one

Under the first brick dealt there is a prize, and not always the same one. The sixteen words of the table at 0x419B point at two-tile blocks, and the destinations say it all: the even ones go to tile 0x0A and the odd ones to 0x1A, which are exactly the four that pinta_el_premio paints.

0x4167 loads a pair of consecutive words — one top half and one bottom half — so the sixteen blocks are eight whole prizes: a telescope on its tripod, a money bag, a penny-farthing, a carriage, a steaming cup, a cocktail glass, a red soda can and a cigarette pack. And which one it is comes from two masks on the stage number, one of them the very same and 003h as the auto-bomb mode: that stage's prize is not the one the following three get.

The monster turns red when it is coming for you

The same byte of the enemy's record does two things: it picks the drawing (0xC0 + frame*4) and it decides the behaviour. When it is zero, the enemy chases the bomber (0x477B) instead of wandering. And zero is precisely the red frame: the other three are purple.

So the game is telling you when you are being hunted, and it does not spend one byte on saying it.

Not a single sprite in the whole cartridge

0x5062 writes a 0xD0 into the first sprite attribute — the "no more" marker — and never touches the list again. Everything that moves is a name-table tile, and everything is two by two.

That explains the whole architecture: the game keeps two 768-byte screens in RAM, one for what is seen and one for what stays, and instead of a map data structure it reads the tile number. The three comparisons that repeat all over the listing are cp 020h ("free"), cp 0e0h ("there is a flame") and cp 0c0h ("there is something that kills"), and the last one covers both flames and monsters because they are laid out next to each other on purpose.

The randomness leans on the memory refresh register

numero_al_azar (0x4EF9) feeds back a sixteen-bit seed and mixes in the Z80's R register. That is not a decoration: if R advanced by the same amount between two draws, the series of cells collapses into three to five values and repeats — a test in the repository checks it, with four different steps.

On the machine that does not happen, because between two draws a varying number of instructions runs depending on how many times the draw had to be repeated. The consequence is that a stage's layout cannot be reproduced from outside: it depends on the instant the trigger was pressed.

Four pieces of code nobody reaches

Three whole routines — 0x4EF0 (clear a board cell), 0x4F84 (a short wait) and 0x50D6 (write VDP register 7) — without a single call naming them anywhere in the 8 KB. And a fourth: the cp 089h at 0x4AC9, which would check for the pillar on the first tile of each arm, and which an unconditional jr steps over.

That last one changes nothing, and that is why nobody ever fixed it: the next tile hits the other half of the same pillar and the flame stops there anyway. They are declared as code, because instructions is what they are.

And there are six bytes at 0x4864 that do run and do nothing: an ld c,a and four ld b,.. that nobody reads back. In the cartridge's own font they read OBADD.

Blowing up the door is expensive, and running out of bonus worse

If a flame reaches the door or the prize, the game notes the spot and brings out four more enemies there (0x453B) as soon as the cell is clear. The door gets uncovered again; the prize is lost.

And if the bonus reaches zero, se_agoto_el_bonus (0x449F) wipes the whole board: the thirty-five bricks, the prize and the door all vanish at once, and with both "already found" flags set they are never looked for again. The stage is left with no way out and can only be finished by killing everything.

What the cartridge draws

Under each picture is where it comes from and what is on it.

<b>The title screen</b>, built the way the cartridge builds it and in its order: six rows of brick, the BIG wordmark on row 2 — nine (tile, row, column) triples at 0x446E —, the nineteen labels at 0x4323, the score and the sample row with the bomber, the monster, the prize and the door. Checked against openMSX's VRAM: <b>0 of 768 tiles differ</b>
The title screen, built the way the cartridge builds it and in its order: six rows of brick, the BIG wordmark on row 2 — nine (tile, row, column) triples at 0x446E —, the nineteen labels at 0x4323, the score and the sample row with the bomber, the monster, the prize and the door. Checked against openMSX's VRAM: 0 of 768 tiles differ
<b>A game in progress</b>, dealt here with the three rules of <code>siembra_la_fase</code> (0x4E35) and painted with the cartridge's own routines, in the main loop's order. The frame and the thirty-five pillars are where 0x4DB7 puts them, checked against the emulator; the bricks are <b>one of the possible deals</b>, because the real one is decided by the R register. There is a bomb with its fuse starting, another about to go, and a blast already open
A game in progress, dealt here with the three rules of siembra_la_fase (0x4E35) and painted with the cartridge's own routines, in the main loop's order. The frame and the thirty-five pillars are where 0x4DB7 puts them, checked against the emulator; the bricks are one of the possible deals, because the real one is decided by the R register. There is a bomb with its fuse starting, another about to go, and a blast already open
<b>The bomber.</b> The first two are standing still: the left one shows only on the frame after dropping a bomb — it is holding one — and the other the rest of the time. The next eight are walking: four directions times two steps, starting at tile 0xA0. Seen from behind even the cap changes colour
The bomber. The first two are standing still: the left one shows only on the frame after dropping a bomb — it is holding one — and the other the rest of the time. The next eight are walking: four directions times two steps, starting at tile 0xA0. Seen from behind even the cap changes colour
<b>The eight frames of dying</b>, and they run BACKWARDS: 0x4E, 0x4C, 0x4A… down to 0x40. The last one is not a drawing of the bomber, it is a green <b>OUT</b> on top of what is left of him
The eight frames of dying, and they run BACKWARDS: 0x4E, 0x4C, 0x4A… down to 0x40. The last one is not a drawing of the bomber, it is a green OUT on top of what is left of him
<b>The monster alive</b>: four frames times two of blink. The first two are frame <b>0</b>, which is exactly when the enemy chases the bomber — and the only red one
The monster alive: four frames times two of blink. The first two are frame 0, which is exactly when the enemy chases the bomber — and the only red one
<b>The seven frames of blowing up</b>, tiles 0x22 to 0x2E. On the title screen, with the other graphics block loaded, those same tiles are the letters of the big BOMBER MAN wordmark
The seven frames of blowing up, tiles 0x22 to 0x2E. On the title screen, with the other graphics block loaded, those same tiles are the letters of the big BOMBER MAN wordmark
<b>The bomb</b>: four fuse states times two of blink, from 0x60 to 0x6E. It shrinks as the fuse runs out
The bomb: four fuse states times two of blink, from 0x60 to 0x6E. It shrinks as the fuse runs out
<b>The flame</b>, eight states from 0xE0 to 0xEE, thinning out until there is nothing left. The arms always use the centre's drawing <b>plus two</b>, so they go out a couple of states earlier
The flame, eight states from 0xE0 to 0xEE, thinning out until there is nothing left. The arms always use the centre's drawing plus two, so they go out a couple of states earlier
<b>The board</b>: the <b>eight frames</b> of the brick crumbling, from 0x80 to 0x87, and behind them the border wall and the fixed pillar, the two that cannot be broken. All three are painted by repeating the SAME tile four times (0x4B8C), unlike the prize — a chest — and the door with its <b>EXIT</b>, which are four consecutive tiles of the sheet (0x4B7B)
The board: the eight frames of the brick crumbling, from 0x80 to 0x87, and behind them the border wall and the fixed pillar, the two that cannot be broken. All three are painted by repeating the SAME tile four times (0x4B8C), unlike the prize — a chest — and the door with its EXIT, which are four consecutive tiles of the sheet (0x4B7B)
<b>The title screen's font</b>, from tile 0x20 to 0x5D. The big letters in the middle are the BOMBER MAN wordmark; during the game those same slots are taken by the monsters
The title screen's font, from tile 0x20 to 0x5D. The big letters in the middle are the BOMBER MAN wordmark; during the game those same slots are taken by the monsters
<b>The 256 tiles of the title screen</b>, that is the whole graphics block at 0x514C. It is the sheet everything else comes from
The 256 tiles of the title screen, that is the whole graphics block at 0x514C. It is the sheet everything else comes from
<b>And the in-game ones</b>, with the two patches on top: the block at 0x5B26 puts the letters of SCORE and BONUS at tile 0x10, and the one at 0x5B7C the digits, the monsters and the bomber from 0x20 on. Everything from 0x90 up <b>is left over from the title screen</b>, and that is where the H, D, F, A, M and I needed at the bottom come from
And the in-game ones, with the two patches on top: the block at 0x5B26 puts the letters of SCORE and BONUS at tile 0x10, and the one at 0x5B7C the digits, the monsters and the bomber from 0x20 on. Everything from 0x90 up is left over from the title screen, and that is where the H, D, F, A, M and I needed at the bottom come from
<b>The eight prizes.</b> What changes with the stage is not the monster: it is what sits under the first brick. The sixteen words of the table at 0x419B point at two-tile blocks, the even ones at tile 0x0A and the odd ones at 0x1A — the four that <code>pinta_el_premio</code> paints — and 0x4167 loads one pair per stage. A telescope on its tripod, a money bag, a penny-farthing, a carriage, a steaming cup, a cocktail glass, a red soda can and a cigarette pack. two more. The one for the first three stages, a chest, comes in the big block and is not here
The eight prizes. What changes with the stage is not the monster: it is what sits under the first brick. The sixteen words of the table at 0x419B point at two-tile blocks, the even ones at tile 0x0A and the odd ones at 0x1A — the four that pinta_el_premio paints — and 0x4167 loads one pair per stage. A telescope on its tripod, a money bag, a penny-farthing, a carriage, a steaming cup, a cocktail glass, a red soda can and a cigarette pack. two more. The one for the first three stages, a chest, comes in the big block and is not here