El cartucho

16.384 bytes en la página 1, de 0x4000 a 0x7FFF. La BIOS lee la cabecera AB y llama a INIT.

La cabecera

Los diez primeros bytes son 41 42 10 40 00 00 00 00 00 00: declara solo INIT, y aquí INIT está pegado a la cabecera, en 0x4010. Ni STATEMENT, ni DEVICE, ni TEXT.

El reparto de los 16.384 bytes

bytes
código trazado7.49445,7 %
datos identificados8.89054,3 %
sin explicar00,0 %

Lo cuenta tools/presupuesto.py, que cruza el trazado del flujo con los rangos declarados en las notas. La comprobación no es que las cifras cuadren: es que cada rango tenga nombre y explicación.

El mapa de VRAM

Los ocho valores de 0x4503, de R0 a R7, son 02 E2 0E 7F 07 76 03 E0, y de ahí sale el mapa entero:

dóndede qué registro
COLOR0x0000R3 = 0x7F
PATRONES DE SPRITE0x1800R6 = 0x03
PATRONES0x2000R4 = 0x07
NOMBRES0x3800R2 = 0x0E
ATRIBUTOS DE SPRITE0x3B00R5 = 0x76

R3 y R4 no son direcciones: son un bit de base y una máscara. Lo que dicen es color abajo y patrón arriba, al revés de lo habitual. Y R1 = 0xE2, con el bit 1 puesto y el 0 a cero, quiere decir sprites de 16x16 sin ampliar.

Estos ocho valores son los mismos que los de otros dos cartuchos de la misma familia salvo R7, el color de borde.

Los dos intérpretes de dibujo

El cartucho no guarda volcados de VRAM: guarda programas cortos que se interpretan. Hay dos, y conviene no confundirlos.

GUIONES (el intérprete de 0x442C). Escriben por el puerto de datos del VDP, byte a byte, con dos comandos:

0x00           fin
0x80           encadena: los dos bytes siguientes son una dirección
               de VRAM nueva, BYTE BAJO PRIMERO
n (bit 7 a 0)  relleno: el byte siguiente, repetido n veces
n (bit 7 a 1)  copia cruda de (n and 0x7F) bytes

LISTAS DE TILES (el de 0x44A6). Escriben en la tabla de nombres con WRTVRM, un tile por byte, pasándolo por una máscara que decide si se dibuja o se borra:

0xFF   fin
0xFE   encadena, igual que el 0x80 del otro
resto  el byte es un tile

Y toda lista empieza por su dirección, porque 0x449E —la puerta normal— solo pone la máscara y cae dentro de 0x44A0, que es el cuerpo del comando 0xFE: lo primero que hace es leerse dos bytes. La única entrada que se salta eso es 0x449A.

El alfabeto

No es ASCII. La A es el tile 0x21 y de ahí seguidas hasta la Z en 0x3A; los dígitos van del 0x10 al 0x19, el espacio es el 0x20 —y el 0x00, el tile vacío, hace el mismo papel— y el círculo del copyright es el 0x1A.

No hace falta suponerlo: KONAMI, PERFECT y GAME OVER se leen solas con ese reparto y ninguna otra alineación las da.

Las quince tablas de despacho

El cartucho despacha de dos maneras. La primera, 0x4071, tiene la tabla escrita detrás del propio call: pop hl la coge de la pila, A por dos entra en ella, y el puntero que salga se ejecuta con jp (hl). Como el retorno se ha sacado de la pila, eso no vuelve.

La segunda, 0x7375, indexa una tabla de tablas por el oponente y despacha la que salga.

Sin declarar las quince, el trazado estático se queda muy corto: solo las seis del reparto por oponente esconden 315 bytes de código.

Las dos compilaciones

Hay dos cartuchos distintos de Yie Ar Kung-Fu, y no se juegan igual. Esto es lo que lleva cada uno:

fácildifícil
sha256644c78c7…61c86ad4…
cada cuánto reacciona el oponentesiempre 1 cuadro de cada 321 de cada 32, 16 u 8, según el nivel
el arma larga de CHENdura 18 cuadros y crece hasta 8dura 22 y crece hasta 10
los tres umbrales de alturatres cp en líneauna tabla de tres bytes, con un valor cambiado
la marca oculta de Konamino la llevala lleva: RC-725 y el título en katakana
este repositorioes el que está desensambladocotejada instrucción a instrucción

En el nivel más alto, el oponente del cartucho difícil reacciona cuatro veces más a menudo que el del fácil, y en el fácil eso no pasa en ningún nivel. Lo demás son cinco constantes y un cambio de forma.

Byte a byte las dos difieren en 15.618 de 16.384, el 95,3 %. Esa cifra no vale nada: las dos están relocalizadas. Por instrucción comparten el 97,0 %. El detalle de cada diferencia está en Hallazgos, y lo produce tools/coteja_builds.py.