Hyper Olympic 1

Sixteen kilobytes of track and field in which almost nothing is drawn: the screens are scripts that get interpreted, the large letters are manufactured by stretching the small ones, and the stopwatch —worked out for a 60 Hz machine— runs short all over Europe.

Konami · © Konami 1984 · An RC-710 16 KB cartridge · MSX1 · page 1 · Dump 0cd8a792…

There is not one illustration here. The screens are captures of the cartridge running in openMSX, taken by a script that only changes the event number the game itself uses as an index; the logo and the font sheet are drawn from the bytes of the ROM, by running in Python the same script interpreter the Z80 runs. The listing and the numbers come from the binary and are reproducible with make.

The cartridge in numbers

100%of the binary explained
569routines identified
4track and field events
9,335bytes of code
7,049bytes of data
0bytes unidentified

What turned up when we took it apart

A new event for the price of one character

The cartridge has four events and the 400 metres does not exist in the arcade it comes from. It shows up here at almost no cost: event 4 reuses event 1's screen list and scoreboard, and the only thing that changes is the label on the board.

That label, at 0x6332, is the 100 metres one with its first glyph changed from “1” to “4”. One byte.

The stopwatch was worked out for 60 Hz

0x5695 adds 1.665 hundredths to the event clock every frame, which is one sixtieth of a second. Measured in openMSX on two machines, with the same script:

Philips VG-8020 (PAL)   50 Hz   0.8325 s of game time per real second
C-BIOS MSX1 JP (NTSC)   60 Hz   0.9990 s of game time per real second

On a European MSX a “12.00” is really 14.4 seconds. And mind reading that backwards: it is a period, not a speed. The game is not running slow; the stopwatch is counting short. The qualifying marks and the records are meant for the Japanese machine.

The record table was compiled before the 1983 season

0x5174 holds 00 09 95 / 00 08 90 / 00 83 98 / 00 43 86, which INIT copies to 0xE040: 9.95 in the 100 m, 8.90 in the long jump, 83.98 in the hammer and 43.86 in the 400 m. All four are real world records, but two had already been beaten by the time the cartridge reached the shops: Calvin Smith ran 9.93 on 3 July 1983 and Litvinov took the hammer to 84.14 that same year.

The two that were still standing were the Mexico 68 marks, untouched for fifteen years. The dates do not come from the cartridge: they are a cross-check against the published progressions. What comes from the cartridge is the figure.

The font ran out of X and Z, and the Q arrived late

The 51 glyphs at 0x6002 are in order: 0..9, the space, and then the alphabet from A to Y skipping Q, X and Z. With A at index 0x0B, P falls at 0x1A and the next one is already R.

And yet the Q exists: it sits at the end, at index 0x2C, outside the alphabet and among the symbols. The reason is the one word in the game that needs it, the scoreboard's QUALIFY, which at 0x5F87 is the string 2C 1E 0B 16 13 10 21. Somebody laid out an alphabet without the three letters that were not needed, and then had to add one back.

This is the kind of thing you only see by drawing it: read as a block, the 51 glyphs are 408 bytes that all look alike. The sheet is further down.

The large letters are not stored: they are manufactured

0x4C49 copies the normal 8x8 glyphs into a scratch area in RAM, and 0x4CAB makes three passes pulling the top two bits out of each byte and pushing them into the byte eight positions earlier. A row of eight glyphs yields four rows of pattern: the letter comes out twice the size without taking twice the ROM.

The saving has a price, and it is measured: three labels declare twenty-four bytes of length and only carry sixteen of their own, so they take eight from the block behind.

The demo's pilot mashes the button at random

The demo does not carry a recorded game: the interrupt plays it. With 0xE002 at 1, 0x4030 drops into 0xE00B a value from ld a,r —the memory refresh register— masked to two bits, once every four frames. That is the whole pilot.

And there is a trap only the emulator catches. Bit 7 of 0xE029 looks like the demo switch, because 0x5849 sets it and 0x4030 reads it; but sampled in both situations it holds the same value in the demo and in a real game. The one in charge is 0xE002.

The actors shove each other by where they sit in RAM

The four actor records live back to back at 0xE120, 0xE130, 0xE140 and 0xE150, sixteen bytes each. Bit 2 of a record makes that actor bump the counter of the one 0x11 bytes behind it, and bit 3 the one 0x0F ahead.

That is how the scenery drags itself along in a chain with nobody keeping a list of who pushes whom: the relationship is the distance between the records.

It belongs to neither of the two Konami families already measured

Comparing the code with all sixteen-bit operands zeroed —so that a routine reassembled somewhere else still shows up— this cartridge shares 6,298 bytes, 67.5 %, with its sibling cartridge. With any other Konami MSX cartridge in this series it does not reach 2 %, and their longest common runs go from 21 to 42 bytes, against the 681 consecutive ones it shares with the sibling.

So the two Hyper Olympics are neither one framework nor the other. They are a third, and so far it has just two members. The full figures, one row per cartridge, are in Findings.

It does not carry Konami's hidden mark

Many cartridges from the house hide their RC-7xx catalogue number and the game's title in katakana at the end of the ROM, behind the filler; it was Manuel Pazos (@ManuelPazosMSX) who found that out.

Not here: the last useful byte is sound player code and only one 0xFF of filler is left. It was checked with tools/marca_konami.py, which in the same run does find it in another cartridge from the house, so the method works. The RC-710 comes from the catalogue, not from the binary.

What the cartridge draws

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

The title screen, with the logo assembled by the <code>pantalla_del_menu</code> script and the four menu lines. Whichever you pick leaves a number from 1 to 4 in 0xE01B, and from that come the number of players and the controller
The title screen, with the logo assembled by the pantalla_del_menu script and the four menu lines. Whichever you pick leaves a number from 1 to 4 in 0xE01B, and from that come the number of players and the controller
Event 1, the 100 metre dash, showing the world record the cartridge keeps: 09 SEC 95. It is the only event where both athletes run at once, and they move on alternating frames
Event 1, the 100 metre dash, showing the world record the cartridge keeps: 09 SEC 95. It is the only event where both athletes run at once, and they move on alternating frames
Event 2, the long jump, with Beamon's 08 M 90. The run-up is the very routine used by the 100 metres; what belongs to the jump is the take-off and the flight, which comes out of the only real piece of arithmetic in the cartridge
Event 2, the long jump, with Beamon's 08 M 90. The run-up is the very routine used by the 100 metres; what belongs to the jump is the take-off and the flight, which comes out of the only real piece of arithmetic in the cartridge
Event 3, the hammer throw, with 83 M 98. The athlete spins while the button is held and lets go at the angle the bar shows; the flight is computed by the same piece of code as the jump
Event 3, the hammer throw, with 83 M 98. The athlete spins while the button is held and lets go at the angle the bar shows; the flight is computed by the same piece of code as the jump
Event 4, the 400 metres, with 43 SEC 86. This one does not exist in the arcade: it reuses event 1's scenery and scoreboard whole, and its label is the 100 metres one with the first glyph swapped
Event 4, the 400 metres, with 43 SEC 86. This one does not exist in the arcade: it reuses event 1's scenery and scoreboard whole, and its label is the 100 metres one with the first glyph swapped
The 51 glyphs of the font, drawn straight from the ROM by <code>tools/graficos.py</code>. You can see at a glance what the listing claims: there is no X and no Z, and the Q sits at the end, outside the alphabet
The 51 glyphs of the font, drawn straight from the ROM by tools/graficos.py. You can see at a glance what the listing claims: there is no X and no Z, and the Q sits at the end, outside the alphabet