Aqui no hay ninguna captura. Todas las imagenes estan dibujadas desde los bytes de la ROM, ejecutando en Python los mismos interpretes que corre el Z80, y comprobadas contra la VRAM del emulador: cero diferencias en las tablas de color y de patron, 12.288 bytes. El listado y las cifras se reproducen con make.
De Yie Ar Kung-Fu hay dos cartuchos distintos circulando, y no es un rumor: aqui estan los dos, y tools/coteja_builds.py los compara instruccion a instruccion. Son el mismo programa -comparten el 97,0 % de las instrucciones- pero no se juegan igual.
| FACIL | DIFICIL | |
|---|---|---|
| sha256 | 644c78c7... | 61c86ad4... |
| cada cuanto reacciona el oponente | siempre 1 cuadro de cada 32 | 1 de cada 32, 16 u 8 segun el nivel |
| el arma larga de CHEN | dura 18 cuadros y crece hasta 8 | dura 22 y crece hasta 10 |
| la marca oculta de Konami | NO la lleva | SI: RC-725 y el titulo en katakana |
| el listado de este repositorio | este | solo cotejada |
O sea: en el cartucho dificil, al nivel mas alto el oponente reacciona cuatro veces mas a menudo que en el facil, y eso en el facil no pasa nunca. Lo demas son cinco constantes del arma de CHEN y un cambio de forma en tres umbrales de altura.
De este cartucho circulan dos volcados, que los archivos llaman easy y hard. Byte a byte se parecen en nada: 15.618 de 16.384 bytes distintos, el 95,3 %. Esa cifra no vale para nada, porque las dos estan relocalizadas: un byte de mas en un sitio desplaza todo lo que va detras y con ello todas las direcciones absolutas.
Cotejadas por INSTRUCCION -sustituyendo por un comodin todo operando de 16 bits que caiga dentro del cartucho- comparten 3.798 de las 3.917 instrucciones, el 97,0 %. Son el mismo programa.
La version facil deja pasar un cuadro de cada 64 y de cada 32 con mascaras escritas dentro del codigo (and 03fh, and 03eh). La dificil mete delante, en esos dos sitios exactos, ocho instrucciones que no aparecen ni una vez en la facil:
ld b,03eh / ld a,(0e056h) / and a / jr z,+7 ld b,01eh / dec a / jr z,+2 / ld b,00eh
y cambia el and 03fh por un and b. La mascara la elige el nivel: 0x3E, 0x1E o 0x0E. En el nivel mas alto el oponente reacciona cuatro veces mas a menudo, y en la version facil eso no pasa nunca.
Lo demas son cinco constantes, todas del arma larga del tercer oponente: dura 22 cuadros en vez de 18 y se estira hasta 10 en vez de hasta 8.
Konami escondia su numero de catalogo y el titulo en katakana al final de muchos cartuchos; lo descubrio Manuel Pazos (@ManuelPazosMSX). La version dificil la lleva: RC-725 y el titulo en katakana, cerrando en el ultimo byte.
La version facil no. En ese mismo hueco tiene el titulo en ASCII latino, YIE AR KUNG FU, que no lo lee nadie: el cartucho no sabe leer ASCII, porque su alfabeto empieza la A en el tile 0x21. Lo que eso quiera decir sobre cual salio antes no lo dice el binario, y aqui no se supone.
El cartucho tiene dos interpretes de dibujo. El de GUIONES (0x442c) escribe por el puerto de datos del VDP y se usa para patrones y colores; el de LISTAS (0x44a6) escribe tiles con WRTVRM. De los catorce guiones largos del cartucho, uno solo escribe en 0x3800: el de 0x5da4, y lo que pone ahi es el templo entero -las columnas, las lamparas, el cartel de los dos kanjis, el gong, las ventanas y el suelo de ladrillo-, 327 bytes.
Las tablas de 0x4b9c y 0x4ba6 dan un guion de patron y otro de color por cada valor de 0xE054, y se dibujan al montar la pantalla, asi que parecen cinco fondos. No lo son: montando la pantalla con los cinco y comparandolas cambian unos 4.000 bytes de VRAM, pero ninguno de los tiles que cambian esta en uso en la tabla de nombres del fondo. El templo se ve igual con los cinco.
Lo que cambia es la figura del oponente: WANG, TAO, CHEN, LANG y WU, en el mismo orden que sus nombres en 0x6c35.
El MSX no sabe reflejar ni un sprite ni un tile, asi que un luchador que mira a los dos lados necesita las dos versiones guardadas. 0x4c3e copia los tiles del oponente de la VRAM 0x2880 a la 0x2440 dandole la vuelta a cada byte: del tile 0x10 al 0x88, o sea 0x78 mas alla.
Y el descompresor de poses, cuando le toca espejar un bloque (0x5454), cambia cada tile por su gemelo sumandole 0x78. Las dos mitades del truco, a 10 KB de distancia una de otra.
La lista de 0x47cc dice PERFECT 3000 y se dibuja en la fila 16 por la puerta normal, 0x449e, que se lee sus dos primeros bytes como direccion de VRAM.
Pero 0x48ad entra por 0x449a, que no lee direccion, con DE dos bytes mas alla -saltandose justamente esa direccion- y HL en la fila 4. Y acto seguido escribe el tile del digito 5 encima del 3. El mismo texto pasa a decir PERFECT 5000, y lo que se suma son 0x5000 en BCD.
Los trece guiones de 0x596f van pegados, pero la tabla de 0x4cf0 no apunta al principio de cada uno: apunta dos bytes mas alla. Esos dos bytes son una direccion de VRAM.
No es un descuadre: el bucle de 0x4ca4 entra por la puerta que quiere el destino en HL y por eso empieza pasados los dos bytes, y el de 0x5098 entra por el cuerpo del comando 0x80, que lee el destino del propio guion. Lo demuestra una cuenta: veinticuatro palabras del bloque de recetas valen exactamente una de esas trece direcciones menos dos, y ninguna vale una de la tabla.
La regla para saber cuantas entradas tiene una tabla de punteros -leer palabras mientras caigan dentro del cartucho- da seis para la de 0x6b4b. Son cinco: la sexta, 0x583A, cae dentro de un guion de dibujo, y seguirla como codigo llenaba el listado de rst 18h y sbc a,a.
Cinco es lo que dice el indice, que es el oponente, y de esos hay cinco. Y la prueba de que la tabla acaba en 0x6b55 es que 0x4182 hace call 0x6b55: ahi empieza codigo al que se llama por su nombre.
El jr z de 0x4625 tiene desplazamiento 8, o sea que salta a 0x462F. Y 0x462F no es el principio de nada: es el tercer byte del jp 0x46cf que empieza en 0x462d.
Cayendo ahi, el Z80 se encuentra el byte 0x46 suelto y lo ejecuta como lo que es, ld b,(hl), y luego cae en el call de 0x4630. El byte alto de una direccion haciendo de instruccion de paso, y dos bytes ahorrados. Que es asi y no un fallo del trazado lo dice el desplazamiento: es 0x08 y no 0x09.
0x6d2c corre un registro de desplazamiento de diez bytes, de 0xE135 a 0xE13E: saca el bit por arriba, lo arrastra por los nueve de abajo y lo vuelve a meter por arriba, dos veces por llamada. Devuelve los dos bits bajos, un numero de 0 a 3.
La semilla son diez bytes de la ROM, y hay cuatro juegos distintos elegidos por el nivel. Con eso el oponente no se repite pero tampoco depende de nada de fuera: la partida sale igual jugada igual, que es justo lo que hace falta para poder comprobarla.
Veintiseis bytes en 0x73b3, tres en 0x73df y ocho en 0x74ae decodifican como codigo Z80 coherente. No los alcanza nadie, y no es una impresion: se busco la palabra de 16 bits en los 16.384 bytes del cartucho, no solo en el listado, y ninguna direccion cae dentro. Delante de los tres hay un salto que pasa por encima.
Debajo de cada imagen esta de donde sale y que se esta viendo.
00 10 E3 FF 11: un hueco, la cabeza, tres huecos y quince tiles correlativos. Veinte, que es 5 x 4