Yie Ar Kung-Fu II

El juego busca el Yie Ar Kung-Fu (RC-725) en la segunda ranura. Antes de instalar el gancho de interrupcion rastrea las cuatro ranuras, conmuta la pagina 1 de cada una y le toma dos sumas de 16 bytes; si dan lo que espera, del nivel 3 en adelante aparece un refresco que rellena la barra cuando los dos luchadores estan bajo minimos. Y la sopa que deja invulnerable no sale sola: hay que pegar en un sitio distinto en cada ronda, los ocho de la tabla de 0x507A.

Konami - (c) Konami 1985 - Cartucho RC-737, 32 KB - MSX1 - paginas 1 y 2 - Volcado bcb41b35...

Aqui no hay ninguna captura. Todas las imagenes estan dibujadas desde los bytes de la ROM, ejecutando en Python los mismos guiones, espejos y lectores de figuras que corre el Z80, y cotejadas byte a byte contra la VRAM de openMSX: nueve pantallas volcadas del emulador dan cero diferencias en color (6.144 bytes), patrones (6.144) y patrones de sprite (1.792), y la del titulo cuadra ademas 768 de 768 casillas. El listado y las cifras se reproducen con make, y el reensamblado devuelve la ROM byte a byte.

El cartucho en cifras

100 %del binario explicado
1027bloques de codigo medidos
40,9 %del listado comentado
13.725bytes de codigo
19.043bytes de datos
0bytes sin identificar

Lo que aparecio al desmontarlo

La sopa: hay que PEGAR en un sitio distinto en cada ronda

Esto lo pregunto theNestruo en el issue #1, y de memoria dijo que hacia falta un movimiento concreto en un punto concreto. Es exactamente lo que resulto ser, hasta en la palabra movimiento. La tabla de 0x507A estaba aqui desde el principio con una nota diciendo que no se sabia de que era.

El cuenco humeante que deja invulnerable un rato no sale al azar. Al empezar la ronda, 0x5027 copia a 0xE300 la pareja que le toca de una tabla de ocho, en 0x507A, dos bytes por ronda: fila y columna. En el listado esa tabla estaba, sin saber de que era.

Despues, un cuadro de cada dos, 0x73FD pregunta si el jugador esta ahi. Pero no mira donde esta el muneco: mira 0xE12C, que es la CUARTA de las cuatro cajas que monta 0x684A -la caja del golpe, la misma que 0x53B3 usa para saber si el jugador alcanza al rival-. Tiene que caer dentro de una ventana de 11x11 que empieza dos mas alla de la pareja.

Y esa cuarta caja no existe en todos los fotogramas. De los diez dibujos de 0x6C83 solo la llevan el 1, el 3, el 5 y el 6, que son los cuatro ataques; en los otros seis el guion trae 0x80, 0x684A deja la caja a cero y el and a de 0x65C6 la tumba. O sea que no basta con ponerse en el sitio: hay que pegar ahi. Eso es el movimiento particular en el punto particular.

Las ocho parejas (fila, columna): (0x7E,0x80) (0x8E,0xE0) (0x68,0xD8) (0x8E,0x03) (0x9E,0x90) (0x68,0x10) (0x68,0x80) (0x8E,0x80). Solo en la fase 3 de la ronda -0x733E exige (0xE107) = 3- y con un solo jugador (0x732F).

Lo que da: (0xE29E) = 0xA8, que baja de uno en uno un cuadro de cada dos: seis segundos y medio a 50 Hz. Mientras no valga cero, el golpe del jugador no cuenta (0x53F4), el rival no lanza nada (0x5588), lo que ya volaba se queda agarrado en vez de tocar (0x566F), no se rompen las ranuras (0x7734), nada toca al jugador (0x798C) y el muneco parpadea (0x6C1E). Ademas suma 500 puntos. Y una sola vez por ronda: al agotarse, 0x7496 deja (0xE261) = 1 y la escena 0 se planta.

Comprobado en openMSX: en la demostracion (0xE300) = (0x7E, 0x80), la primera pareja de la tabla. Moviendo el sitio encima del jugador el cuenco cae, y al tocarlo 0xE29E se pone a 0xA8 y baja hasta cero.

El juego busca el Yie Ar Kung-Fu (RC-725) en la segunda ranura

Lo primero que hace INIT, antes incluso de instalar el gancho de interrupcion, es llamar a 0xBF6C. Ahi hay un rastreo de ranuras: recorre las cuatro primarias de 0xFCC1, entra en las subranuras cuando el bit 7 lo pide, conmuta la pagina 1 de cada una con ENASLT y le toma dos sumas de 16 bytes, una desde 0x5300 y otra desde 0x6700.

Las compara contra las dos parejas escritas en 0xBFD9: 5A 47 y 23 70. Son las dos compilaciones del Yie Ar Kung-Fu original (RC-725), reconocidas por separado. Pasadas esas dos sumas por las demas ROM de la serie no cuadra ninguna, asi que la identificacion no es una suposicion.

Si lo encuentra, (0xE450) = 1. El unico sitio del juego que mira esa marca es 0x74A3, y ademas exige nivel 3 o mas (0xE053), un solo jugador (bit 5 de 0xE002) y la fase 3.

Que da, medido. Sale cuando las dos barras estan bajo minimos -la del jugador por debajo de 9 y la del rival por debajo de 13, de 0x24 que es el tope-: un cartel de 4x3 casillas (0x7525, fila 6 columna 14) y un refresco que baja, el sprite de los cuatro bytes de 0x74F1. Cogerlo salta a 0x738C con B = 1, y al agotarse los 0x10 cuadros de descanso 0x7356 deja la barra del jugador otra vez a 0x24. La del rival no se toca y nadie pierde una vida. En openMSX las barras pasan de (0x08, 0x0C) a (0x24, 0x0C).

Y no tiene nada que ver con la sopa: son dos piezas distintas, en dos atributos distintos -0xE250 la sopa y 0xE254 el refresco-, y la marca del vecino no entra en el camino de la sopa por ningun sitio.

Media pantalla y un espejo

0x597F monta la pantalla de combate con cuarenta guiones apuntados por cuarenta punteros repartidos en seis tablas contiguas, de 0x592F a 0x597E. Pero solo se dibuja la mitad: 0x5A4D copia tres tramos de la tabla de patrones sobre si mismos pasandolos por vuelve_los_bits, y la mitad derecha del decorado son los mismos dibujos del reves.

De ahi sale una rareza que se ve leyendo el codigo: el color se escribe dos veces y el patron una sola. El espejo no toca colores. Y las cuentas cuadran en las tres bandas: 0x0560-0x0260 = 0x300 y las otras dos 0x3C0, que es exactamente el desplazamiento de cada copia.

Una pantalla de oleadas son cuatro bytes

Las pantallas donde llegan enemigos en fila no estan dibujadas. La tira de 0x5BE8 que le toca al decorado trae ocho nibbles en cuatro bytes; cada nibble elige una de las treinta figuras de 0x5C64, y las ocho se pintan en fila, de cuatro en cuatro columnas. Las pares van en el nibble bajo y las impares en el alto, que es lo que dice el bit 0,b de 0x5B9F.

Dos lectores de figuras que se parecen y no son iguales

0x67F5 y 0x67A7 leen el mismo formato de figura salvo en la orden 0xE0..0xEF, y ahi cambian de las dos maneras a la vez: el primero repite el byte que viene detras y ocupa dos, y el segundo escribe ceros y ocupa uno. Confundirlos no revienta el listado: da una figura que casi encaja y se pasa por dos o tres bytes.

Los dos estan en tools/formatos.py, y lo que lo prueba es que las treinta figuras de las oleadas encajan solo con el primero y las de los rivales solo con el segundo.

Los ocho rivales, y el fotograma impar que no es un dibujo

Cada escenario tiene su rival, y cuelgan de dos tablas de ocho que se indexan igual: 0x6922 los fotogramas y 0x7FDB el comportamiento. Cada bloque son 22 punteros que cierran a 44 bytes, y los 168 tramos entre entradas consecutivas teselan sin un hueco ni un solape.

El fotograma impar es el par mirando al otro lado: el bit 0,a de 0x677C sigue un puntero de dos bytes en vez de leer el dibujo, y el mismo bit niega la x en 0x686A. Los ocho rivales se llaman YEN-PEI, LAN-FANG, PO-CHIN, WEN-HU, WEI-CHIN, MEI-LING, HAN-CHEN y LI-JEN (0x4497); el que se maneja es LEE YOUNG (0x447B).

El truco de las vidas: arriba, izquierda, abajo, derecha

0x43B8 va guardando las diez primeras pulsaciones desde el encendido y las compara contra los diez bytes de 0x43ED: 01 04 04 02 02 02 08 08 08 08. Con el reparto de bits del PSG eso es arriba una vez, izquierda dos, abajo tres y derecha cuatro, un 1-2-3-4. Si cuadra, (0xE055) pasa de 3 vidas a 0x95.

El muneco no es un sprite: son doce, y la mitad se calcula

Un fotograma de LEE YOUNG son cuatro sprites de cabecera mas hasta ocho trios [y][x][patron], colgados de los veinte punteros de 0x6C83 -diez dibujos en las entradas pares y diez remisiones de dos bytes en las impares-.

Y ahi esta el ahorro: mirando a un lado, los ocho sprites usan los patrones 0 a 7, que 0x6BE6 acaba de subir a 0x1800 siguiendo los guiones del propio fotograma; mirando al otro, los trios traen numeros de patron que caen en el banco espejado que dejo espeja_sprites (0x490C). Un dibujo, dos direcciones, y solo una mitad guardada.

La marca oculta de Konami, y la segunda cabecera

Los ultimos quince bytes del cartucho, cerrando en 0xBFFF, llevan RC-737 y el titulo en katakana escrito del reves. Es la marca que Manuel Pazos descubrio en los cartuchos de Konami, y este la lleva.

Y hay una segunda cabecera en 0x4010, con su AB y los bytes 07 37: la que lee el Konami Game Master desde la otra ranura.

Codigo que no llama nadie

Cinco rutinas -0x47B0, 0x4875, 0x488A, 0x544F y 0x6EB5- no las nombra ni un call, ni un jp, ni ninguna tabla. Estan declaradas como puntos de entrada para que salgan como codigo y no como datos, y su justificacion esta escrita en src/yiear2.entries.

Una fila menos de la que se pide

pon_la_figura_en_la_pantalla (0x66F1) baja 32 casillas fila - 1 veces, por el dec a de 0x66FB. Una figura pedida en la fila 4 empieza en la 3, y la fila 0 es la excepcion porque el jr z de 0x66F9 se salta el bucle entero. Sin eso, el logotipo del titulo sale cuatro filas mas abajo y tres columnas a la izquierda de donde va.

Lo que el cartucho dibuja

Debajo de cada imagen esta de donde sale y que se esta viendo.

La pantalla del titulo, montada por 0x4CE9 y colocada por 0x4D10. Cotejada contra la VRAM de openMSX: <b>768 de 768 casillas iguales</b>.
La pantalla del titulo, montada por 0x4CE9 y colocada por 0x4D10. Cotejada contra la VRAM de openMSX: 768 de 768 casillas iguales.
Las diez poses de LEE YOUNG, cada una montada con sus cuatro sprites de cabecera, sus trios y los guiones que suben sus patrones.
Las diez poses de LEE YOUNG, cada una montada con sus cuatro sprites de cabecera, sus trios y los guiones que suben sus patrones.
Las mismas diez poses, con una cruz en la CUARTA caja del guion: el punto por el que ese golpe toca. Solo la tienen cuatro -los cuatro ataques-, y es el punto que 0x7402 compara con el sitio de la sopa. La cruz la ponemos nosotros; el punto sale del guion.
Las mismas diez poses, con una cruz en la CUARTA caja del guion: el punto por el que ese golpe toca. Solo la tienen cuatro -los cuatro ataques-, y es el punto que 0x7402 compara con el sitio de la sopa. La cruz la ponemos nosotros; el punto sale del guion.
Las dos piezas que caen, dibujadas desde la ROM: el <b>cuenco de sopa</b> (patron 0xDC, el de la invulnerabilidad) y el <b>refresco</b> (patron 0xE0, el del cartucho hermano). Los sube el guion suelto de 0xA7D1, no los dieciseis del muneco.
Las dos piezas que caen, dibujadas desde la ROM: el cuenco de sopa (patron 0xDC, el de la invulnerabilidad) y el refresco (patron 0xE0, el del cartucho hermano). Los sube el guion suelto de 0xA7D1, no los dieciseis del muneco.
El cartel del premio del cartucho hermano: la figura de 4x3 casillas de 0x7525, que 0x751B pone en la fila 6, columna 14.
El cartel del premio del cartucho hermano: la figura de 4x3 casillas de 0x7525, que 0x751B pone en la fila 6, columna 14.
Escenario 1, contra YEN-PEI. El decorado, el suelo y el rival salen de tablas distintas indexadas por la ronda.
Escenario 1, contra YEN-PEI. El decorado, el suelo y el rival salen de tablas distintas indexadas por la ronda.
Escenario 2, contra LAN-FANG: mismo decorado que el 1, otro suelo.
Escenario 2, contra LAN-FANG: mismo decorado que el 1, otro suelo.
Escenario 3, contra PO-CHIN.
Escenario 3, contra PO-CHIN.
Escenario 4, contra WEN-HU. Es el unico que lleva marcador de fase: el <code>cp 003h</code> de 0x5A7A.
Escenario 4, contra WEN-HU. Es el unico que lleva marcador de fase: el cp 003h de 0x5A7A.
Escenario 5, contra WEI-CHIN.
Escenario 5, contra WEI-CHIN.
Escenario 6, contra MEI-LING.
Escenario 6, contra MEI-LING.
Escenario 7, contra HAN-CHEN: el nocturno, con los faroles.
Escenario 7, contra HAN-CHEN: el nocturno, con los faroles.
Escenario 8, contra LI-JEN, el emperador Yie-Gah.
Escenario 8, contra LI-JEN, el emperador Yie-Gah.
Primera oleada del decorado de los escenarios 1-2: ocho tiras verticales de paisaje de cuatro casillas, elegidas por los ocho nibbles de 0x5BF0. Sus casillas son las bandas del propio combate.
Primera oleada del decorado de los escenarios 1-2: ocho tiras verticales de paisaje de cuatro casillas, elegidas por los ocho nibbles de 0x5BF0. Sus casillas son las bandas del propio combate.
Segunda oleada, escenarios 1-2.
Segunda oleada, escenarios 1-2.
Tercera oleada, escenarios 1-2.
Tercera oleada, escenarios 1-2.
Primera oleada, escenarios 3-4.
Primera oleada, escenarios 3-4.
Segunda oleada, escenarios 3-4: el paisaje entero en orden, tiras 0 a 7.
Segunda oleada, escenarios 3-4: el paisaje entero en orden, tiras 0 a 7.
Tercera oleada, escenarios 3-4.
Tercera oleada, escenarios 3-4.
Primera oleada, escenarios 5-6.
Primera oleada, escenarios 5-6.
Segunda oleada, escenarios 5-6.
Segunda oleada, escenarios 5-6.
Tercera oleada, escenarios 5-6.
Tercera oleada, escenarios 5-6.
Primera oleada, escenarios 7-8: el paisaje se corre ocho columnas a la derecha en cada pantalla.
Primera oleada, escenarios 7-8: el paisaje se corre ocho columnas a la derecha en cada pantalla.
Segunda oleada, escenarios 7-8.
Segunda oleada, escenarios 7-8.
Tercera oleada, escenarios 7-8.
Tercera oleada, escenarios 7-8.
YEN-PEI, sus once figuras. Los rivales no son sprites: son CASILLAS, y cada figura trae su alto, su ancho y sus casillas comprimidas.
YEN-PEI, sus once figuras. Los rivales no son sprites: son CASILLAS, y cada figura trae su alto, su ancho y sus casillas comprimidas.
LAN-FANG.
LAN-FANG.
PO-CHIN.
PO-CHIN.
WEN-HU.
WEN-HU.
WEI-CHIN.
WEI-CHIN.
MEI-LING.
MEI-LING.
HAN-CHEN.
HAN-CHEN.
LI-JEN, el emperador Yie-Gah.
LI-JEN, el emperador Yie-Gah.
La fuente de la casa, subida por 0x4A8D a los tres tercios: el espacio en 0x00, las cifras desde 0x10 y las letras desde 0x21.
La fuente de la casa, subida por 0x4A8D a los tres tercios: el espacio en 0x00, las cifras desde 0x10 y las letras desde 0x21.
Las 256 casillas del primer escenario en sus tres bancos, tal y como quedan en la VRAM despues del espejo.
Las 256 casillas del primer escenario en sus tres bancos, tal y como quedan en la VRAM despues del espejo.