Konami's Soccer

A 1985 football game that calls offside -and only from level 3 up when you play the machine-, twelve players that are not sprites but three-by-three tile patches over an eighty-column pitch held in RAM, and an aim that is never computed: it is looked up in two tables.

Konami - (c) Konami 1985 - An RC-732 32 KB cartridge - MSX1 - pages 1 and 2 - Dump b9536809...

Not one capture here. Every picture is drawn from the bytes of the ROM, by running in Python the same decompressor and label interpreter the Z80 runs, and then checked byte for byte against openMSX's VRAM: the title screen comes out with zero differences, and so does the pitch. The listing and the numbers are reproducible with make, and reassembling gives back the ROM byte for byte.

The cartridge in numbers

100%of the binary explained
1213named routines
36.5%of the listing commented
20,116bytes of code
12,652bytes of data
0bytes unidentified

What turned up when we took it apart

One instruction out of 9,755 separates this cartridge from Konami's Football

The same game also came out as Konami's Football, with the same RC-732 catalogue number. Compared byte by byte they differ in 28,586 of the 32,768, that is 87 %, and that number is worth nothing: the second build is SHIFTED. Football's logo takes less room, everything behind it moves and every call points somewhere else even though it calls the same thing.

Aligning the two ROMs, the shift changes only four times in 32 KB -from 0 to -46, -44, -40 and -38- and with that map both can be disassembled and one's addresses translated into the other's space. Then the real number comes out: of 9,755 instructions, ONE differs. The ld c,005h at 0x4CDB, which in Football is 4: the rows of tiles the title logo is tall.

In the data, 97 of the 125 blocks are identical byte for byte. Of the other twenty-eight, twenty-four are pointer tables moved by the relocation, and the four that remain are the same change: the logo, one more tile in the pitch's set, its colour and seven tiles of the map -the advertising hoarding-. Even Konami's hidden mark is the same: the katakana title inside still reads サッカー.

It calls offside

A 32 KB cartridge from 1985, and the rule is in there. 0xB667 runs the moment the pass is made, and it asks for three things at once: that the ball is heading for the opposing goal -the sign of the high byte of (0xE2A8)-, that the receiver is in the opponents' half -past pixel 0x140 of the 640 the pitch is wide- and that he is ahead of all six opponents, one by one.

The referee does not blow there: he waits. 0xB6F2 lets the ball land -(0xE2AB), its vertical speed, at zero- and then checks (0xE546): if it bounced off anyone on the way, the call is dropped. Only if the pass arrived and was controlled does sound 0x25 play and the OFFSIDE banner appear.

And there is one more condition, and it changes how the game plays: with two players it is called always; with one, only from level 3 up (cp 003h at 0xB671). At levels 1 and 2 the rule does not exist.

Six players are tiles and six are sprites

An MSX1 shows only four sprites per scanline. With twenty-two figures on the pitch that is hopeless, so the cartridge splits the problem in half and draws each side a different way. It is there in the order of the frame, at 0x5882..0x5892:

  1. guarda_el_fondo_del_bando notes the 3x3 tiles each player is about to cover
  2. estampa_el_bando_en_el_mapa stamps the six patches onto the pitch map, which lives in RAM
  3. pon_el_bando_en_sprites draws the other side with five sprites per player
  4. vuelca_el_campo throws the whole map at the VRAM
  5. devuelve_el_fondo_al_mapa puts the grass the patches covered back

That is why the RAM map, looked at in the emulator at any other moment, is clean: its 1,840 tiles match the ones that come out of decompressing 0x853E, and the only two that differ are the two goalkeepers.

The poses are not stored sprites: they are a two-level tree -(ix+0x0C) picks the group and (ix+0x0D) the pose- with eleven-byte leaves, two of correction and the nine tiles. There are 26 poses for one side and 25 for the other, and they are all drawn below.

The aim is never computed: it is looked up

The Z80 has neither multiply nor divide, and here you have to decide how hard a pass leaves so that it lands where you want. 0x92E2 solves it by computing nothing.

The two distances to the target are measured and split into steps of sixteen, which is keeping the high nibble of each: that gives a number from 0 to 15 for the horizontal and one from 0 to 11 for the vertical. Those two index two two-level tables at the end of the cartridge: the one at 0xBF0F gives the vertical impulse and the one at 0xBD6F the two ground components. The whole trajectory is tabulated.

Two corrections sit on top. On a throw-in the kick is softened to three quarters -or to a half if the target is under three steps away in both directions- and on the kick-off the vertical impulse and gravity are doubled.

One compressed block, two kits

Both teams share the same drawings. What changes is the COLOUR table, and the same decompressor writes it, passing every byte through 0x4846, which splits the byte into its two nibbles -ink on top, paper below-, runs each through a five-entry palette and puts them back together. Where the palette points is held in (0xE52A).

0x6F31 leaves four pattern dumps at 0x2320, 0x2458, 0x2590 and 0x26C8 -two straight and two mirrored- and 0x742D paints them: the first two with the palette at 0xE051 and the last two with the one at 0xE056.

The palettes are built in two steps, and skipping the second is expensive: 0x5A45 copies 39 factory bytes to 0xE050, and then 0x5C02 overwrites entries 2, 3 and 4 of each with the set of three tones chosen in the menu. Building the screen without that second step gets the COLOUR table wrong in 4,092 of its 6,144 bytes.

A hand-written `jp (bc)`, with 283 bytes of code behind it

The Z80 has jp (hl), but no jp (bc). At 0xB2DA the cartridge writes one by hand: it pushes BC and does ret. To any tracer that is the end of a routine, and that is where it stopped: behind it were 283 bytes nobody reached, with their five-entry table at 0xB2DC.

What fixes the count at five and not six is that the sixth word already falls outside the cartridge. It is the only push bc / ret in the 32 KB; there are twenty-seven push hl / ret, and those have not been gone through one by one.

Two scores compared with a single subtraction

At the end of the match you have to know whether there were penalties, that is, whether the two teams finished level. Each score is two bytes: the BCD digit and the carry. Comparing two pairs takes two subtractions.

0xB903 does one. It builds two crossed pairs -one low digit from each team with one carry from each team- and subtracts them with a single 16-bit sbc hl,bc. The result is zero exactly when both comparisons hold at once.

The tackle that fails ends in a collision

Winning the ball depends on the angle you come in at. 0xABCA compares the tackler's heading with the carrier's, and if they match -or are five apart- the tackle works, with its whistle. If not, they crash.

And the crash is written out in detail. The carrier gets 16 frames frozen; the tackler has his heading rounded to the next diagonal, is given drawing 4 -on the ground- and slides twice, eight pixels each time and eight frames apart, with the ball following at his feet. He gets up with it.

While it lasts, the ball physics do not run: entries 6 and 7 of the table at 0x8C70 -the collision and the offside- are a bare ret.

What the cartridge draws

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

The whole pitch: 80 columns by 23 rows, 640 by 184 pixels. Not a capture nor a montage of captures: it is the map 0x8538 decompresses into 0xE600, drawn tile by tile with the patterns and colours the ten graphics batches at 0x4279 leave behind. The screen only ever shows 32 of those 80 columns.
The whole pitch: 80 columns by 23 rows, 640 by 184 pixels. Not a capture nor a montage of captures: it is the map 0x8538 decompresses into 0xE600, drawn tile by tile with the patterns and colours the ten graphics batches at 0x4279 leave behind. The screen only ever shows 32 of those 80 columns.
The 51 player poses, taken from the patch tree: 26 for one side and 25 for the other, each of them nine 8x8 tiles. They are the same drawings with two different colour tables. The grass behind is tile 0x01, the same one the map fills the pitch with.
The 51 player poses, taken from the patch tree: 26 for one side and 25 for the other, each of them nine 8x8 tiles. They are the same drawings with two different colour tables. The grass behind is tile 0x01, the same one the map fills the pitch with.
The title screen with its menu, assembled step by step the way the cartridge does it. The big logo is not a stored image: it is five rows of fourteen CONSECUTIVE patterns that 0x4CD3 stamps from 0x40 on. Checked against the emulator's VRAM: zero bytes different across all three tables.
The title screen with its menu, assembled step by step the way the cartridge does it. The big logo is not a stored image: it is five rows of fourteen CONSECUTIVE patterns that 0x4CD3 stamps from 0x40 on. Checked against the emulator's VRAM: zero bytes different across all three tables.
The same screen, built from the OTHER build: Konami's Football, the same RC-732 cartridge under another name. Of its 9,755 instructions only one differs from Soccer's, and it is exactly the one saying how many rows of tiles this logo is tall: five in Soccer, four here. Checked against the emulator's VRAM: zero bytes different across all three tables.
The same screen, built from the OTHER build: Konami's Football, the same RC-732 cartridge under another name. Of its 9,755 instructions only one differs from Soccer's, and it is exactly the one saying how many rows of tiles this logo is tall: five in Soccer, four here. Checked against the emulator's VRAM: zero bytes different across all three tables.
The 44 tiles of the font, from 0x10 to 0x3B, laid out in a row so they can be looked at. The layout explains the labels: the ten digits start at 0x10, 0x20 is the dash between the two goal counts, the letters run from 0x21 to 0x3A, and 0x3B is the diamond the final screen's frame is hand-drawn with.
The 44 tiles of the font, from 0x10 to 0x3B, laid out in a row so they can be looked at. The layout explains the labels: the ten digits start at 0x10, 0x20 is the dash between the two goal counts, the letters run from 0x21 to 0x3A, and 0x3B is the diamond the final screen's frame is hand-drawn with.