Yie Ar Kung-Fu

The temple backdrop written as TILES by a script, the opponent drawn with tiles and the player with sprites, and the cartridge's two builds collated instruction by instruction.

Konami - (c) Konami 1985 - An RC-725 16 KB cartridge - MSX1 - page 1 - Dump 644c78c7...

Not one capture here. Every picture is drawn from the bytes of the ROM, by running in Python the same interpreters the Z80 runs, and checked against the emulator's VRAM: zero differences across the colour and pattern tables, 12,288 bytes. The listing and the numbers are reproducible with make.

THE TWO BUILDS

There are two different Yie Ar Kung-Fu cartridges in circulation, and this is not hearsay: both are here, and tools/coteja_builds.py collates them instruction by instruction. They are the same program -they share 97.0 % of the instructions- but they do not play the same.

EASYHARD
sha256644c78c7...61c86ad4...
how often the opponent reactsalways 1 frame in 321 in 32, 16 or 8 depending on the level
CHEN’s long weaponlasts 18 frames, grows to 8lasts 22, grows to 10
Konami’s hidden markdoes NOT carry itYES: RC-725 and the title in katakana
the listing in this repositorythis onecollated only

So: on the hard cartridge, at the highest level the opponent reacts four times as often as on the easy one, and on the easy one that never happens. The rest is five constants of CHEN’s weapon and a change of shape in three height thresholds.

The cartridge in numbers

100%of the binary explained
569named routines
44.0%of the listing commented
7,494bytes of code
8,890bytes of data
0bytes unidentified

What turned up when we took it apart

The two builds differ in 95% of their bytes and share 97% of their instructions

Two dumps of this cartridge circulate, which the archives call easy and hard. Byte for byte they look nothing alike: 15,618 of 16,384 bytes differ, 95.3%. That number is worth nothing, because both are relocated: one byte more in one place shifts everything behind it, and with it every absolute address.

Collated by INSTRUCTION -replacing with a wildcard every 16-bit operand that falls inside the cartridge- they share 3,798 of the 3,917 instructions, 97.0%. They are the same program.

What actually changes: a fixed mask that becomes variable

The easy build lets one frame in 64 and one in 32 through with masks written into the code (and 03fh, and 03eh). The hard build puts eight instructions in front, at those two exact spots, that appear nowhere in the easy one:

ld b,03eh / ld a,(0e056h) / and a / jr z,+7
ld b,01eh / dec a / jr z,+2 / ld b,00eh

and swaps the and 03fh for an and b. The level picks the mask: 0x3E, 0x1E or 0x0E. At the highest level the opponent reacts four times as often, and in the easy build that never happens.

The rest is five constants, all of the third opponent's long weapon: it lasts 22 frames instead of 18 and stretches to 10 instead of 8.

Only one of the two carries Konami's hidden mark

Konami hid its catalogue number and the title in katakana at the end of many cartridges; Manuel Pazos (@ManuelPazosMSX) found it. The hard build has it: RC-725 and the title in katakana, closing on the very last byte.

The easy build does not. In that same gap it carries the title in Latin ASCII, YIE AR KUNG FU, which nothing reads: the cartridge cannot read ASCII, because its alphabet starts A at tile 0x21. What that says about which came first the binary does not tell, and it is not assumed here.

The temple backdrop is not in the pattern table: it is in the name table

The cartridge has two drawing interpreters. The SCRIPT one (0x442c) writes through the VDP data port and is used for patterns and colours; the LIST one (0x44a6) writes tiles with WRTVRM. Of the cartridge's fourteen long scripts, only one writes at 0x3800: the one at 0x5da4, and what it puts there is the whole temple -the columns, the lanterns, the two-kanji sign, the gong, the windows and the brick floor-, 327 bytes.

The tables that looked like five stages are the five opponents

The tables at 0x4b9c and 0x4ba6 give a pattern script and a colour script per value of 0xE054, and they are drawn while the screen is being built, so they look like five backdrops. They are not: building the screen with all five and comparing them, some 4,000 bytes of VRAM change, but none of the tiles that change is in use in the backdrop's name table. The temple looks identical with all five.

What changes is the opponent's figure: WANG, TAO, CHEN, LANG and WU, in the same order as their names at 0x6c35.

The 0x78 proof: the player is sprites and the opponent is tiles

The MSX cannot mirror a sprite or a tile, so a fighter who faces both ways needs both versions stored. 0x4c3e copies the opponent's tiles from VRAM 0x2880 to 0x2440 flipping every byte: from tile 0x10 to 0x88, that is 0x78 further on.

And the pose decompressor, when it has to mirror a block (0x5454), swaps each tile for its twin by adding 0x78. The trick's two halves, 10 KB apart.

The same twelve-byte caption, two different prizes

The list at 0x47cc reads PERFECT 3000 and is drawn on row 16 through the normal door, 0x449e, which reads its first two bytes as a VRAM address.

But 0x48ad comes in through 0x449a, which reads no address, with DE two bytes further on -skipping exactly that address- and HL on row 4. And right after it writes the tile for digit 5 over the 3. The same text now reads PERFECT 5000, and what is added is 0x5000 in BCD.

Each of the fighter's figures carries its destination in front, and is drawn two ways

The thirteen scripts from 0x596f run back to back, but the table at 0x4cf0 does not point at the start of each one: it points two bytes further on. Those two bytes are a VRAM address.

It is not a misalignment: the loop at 0x4ca4 comes in through the door that wants the destination in HL and so starts past the two bytes, and the one at 0x5098 comes in through the body of command 0x80, which reads the destination out of the script itself. A count proves it: twenty-four words of the recipe block equal exactly one of those thirteen addresses minus two, and none equals one from the table.

A dispatch table with one entry too many put 178 bytes of rubbish in the listing

The rule for how many entries a pointer table has -read words while they land inside the cartridge- gives six for the one at 0x6b4b. There are five: the sixth, 0x583A, falls inside a drawing script, and following it as code filled the listing with rst 18h and sbc a,a.

Five is what the index says, which is the opponent, and there are five of those. And the proof that the table ends at 0x6b55 is that 0x4182 does call 0x6b55: code that is called by name starts there.

A jump that lands inside another instruction

The jr z at 0x4625 has displacement 8, so it jumps to 0x462F. And 0x462F is not the start of anything: it is the third byte of the jp 0x46cf that begins at 0x462d.

Landing there, the Z80 finds byte 0x46 on its own and runs it for what it is, ld b,(hl), and then falls into the call at 0x4630. The high byte of an address doing duty as a filler instruction, and two bytes saved. That this is so and not a tracing slip is settled by the displacement: it is 0x08 and not 0x09.

The opponent's randomness is a ten-byte register with a fixed seed

0x6d2c runs a ten-byte shift register, 0xE135 to 0xE13E: it takes the bit off the top, drags it through the nine below and feeds it back in at the top, twice per call. It returns the two low bits, a number from 0 to 3.

The seed is ten bytes of ROM, and there are four different sets picked by the level. With that the opponent does not repeat but does not depend on anything outside either: the same play gives the same match, which is exactly what you need to be able to check it.

Three pieces of code nothing reaches

Twenty-six bytes at 0x73b3, three at 0x73df and eight at 0x74ae decode as coherent Z80 code. Nothing reaches them, and that is not an impression: the 16-bit word was searched across all 16,384 bytes of the cartridge, not just the listing, and no address falls inside. In front of all three there is a jump that steps over them.

What the cartridge draws

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

<b>The player, assembled.</b> He is not one sprite: he is <b>SIX</b>, and his six pattern numbers -04 08 0C 10 14 18, the ones at 0x50A6- never change. What changes in each pose is WHERE each goes and WHAT it holds, and the recipe at 0x50AC says both. The offsets and colours here are checked against the sprite attribute table of a running machine: <b>twelve dumps, twelve poses recognised</b>
The player, assembled. He is not one sprite: he is SIX, and his six pattern numbers -04 08 0C 10 14 18, the ones at 0x50A6- never change. What changes in each pose is WHERE each goes and WHAT it holds, and the recipe at 0x50AC says both. The offsets and colours here are checked against the sprite attribute table of a running machine: twelve dumps, twelve poses recognised
<b>The title screen</b>, built with the cartridge's own steps: the flat colour of the first sixteen tiles (0x560f), the font script into VRAM 0x2080, the 0xF0 fill and the two wordmark scripts, and on top the tile lists at 0x5909 and 0x559b, which bring the logo, the PUSH SPACE KEY and the copyright
The title screen, built with the cartridge's own steps: the flat colour of the first sixteen tiles (0x560f), the font script into VRAM 0x2080, the 0xF0 fill and the two wordmark scripts, and on top the tile lists at 0x5909 and 0x559b, which bring the logo, the PUSH SPACE KEY and the copyright
The same backdrop with the <b>other list</b>, the one at 0x55c8: the <b>VIDEO CARTRIDGE</b> that scene 0 draws one frame in two before handing over to the logo
The same backdrop with the other list, the one at 0x55c8: the VIDEO CARTRIDGE that scene 0 draws one frame in two before handing over to the logo
<b>The fighting screen</b>. The temple -the columns, the lanterns, the sign, the gong, the windows and the brickwork- is written as tiles by the script at 0x5da4 into the NAME table; the patterns and colours come from 0x605b and 0x6207. Compared against the emulator's VRAM 120 seconds into a game: <b>zero differences</b> in colour and pattern
The fighting screen. The temple -the columns, the lanterns, the sign, the gong, the windows and the brickwork- is written as tiles by the script at 0x5da4 into the NAME table; the patterns and colours come from 0x605b and 0x6207. Compared against the emulator's VRAM 120 seconds into a game: zero differences in colour and pattern
<b>WANG</b>, the first opponent, in his seven poses. The opponents are NOT sprites like the player: they are <b>tiles</b> written into the name table, and each pose is a RECTANGLE of height by width with its tiles compressed inside the pose block itself. WANG’s idle is <code>00 10 E3 FF 11</code>: a gap, the head, three gaps and fifteen consecutive tiles. Twenty, which is 5 x 4
WANG, the first opponent, in his seven poses. The opponents are NOT sprites like the player: they are tiles written into the name table, and each pose is a RECTANGLE of height by width with its tiles compressed inside the pose block itself. WANG’s idle is 00 10 E3 FF 11: a gap, the head, three gaps and fifteen consecutive tiles. Twenty, which is 5 x 4
<b>TAO</b>, the second. Each opponent has his own pose width -TAO 4 tiles, WANG 5, CHEN and LANG 5, WU 4- which is why laying them all four to a row, as this site did until 2026-09-04, cut the figures to pieces
TAO, the second. Each opponent has his own pose width -TAO 4 tiles, WANG 5, CHEN and LANG 5, WU 4- which is why laying them all four to a row, as this site did until 2026-09-04, cut the figures to pieces
<b>CHEN</b>, the third, the one with the chain. He is the only one whose constants the hard build changes -five of them- all belonging to his long weapon
CHEN, the third, the one with the chain. He is the only one whose constants the hard build changes -five of them- all belonging to his long weapon
<b>LANG</b>, the fourth, with eight poses
LANG, the fourth, with eight poses
<b>WU</b>, the fifth and last, also with eight. His pose table has TWENTY entries, two more than the other four
WU, the fifth and last, also with eight. His pose table has TWENTY entries, two more than the other four