Twin Bee

Los sprites de Twin Bee estan a medias en la ROM. De cada uno solo se guarda la mitad izquierda: la derecha la calcula el cartucho invirtiendo cada byte bit a bit, y por eso todo lo que vuela en este juego es simetrico. El mismo espejo monta el decorado, y el descompresor -que solo sabe escribir en la VRAM- llega a usar la memoria de video de mesa de trabajo para dejar una tabla en la RAM.

Konami - (c) Konami 1986 - Cartucho RC-740, 32 KB - MSX1 - paginas 1 y 2 - Volcado 02bdce8c...

Aqui no hay ninguna captura. Todas las imagenes estan dibujadas desde los bytes de la ROM, ejecutando en Python el mismo descompresor, el mismo espejo y el mismo montador de filas que corre el Z80, y cotejadas byte a byte contra la VRAM de openMSX: la pantalla del titulo da cero diferencias en los 16.384 bytes enteros, y las cinco fases dan cero en sus 900 casillas de decorado y en los 2.048 bytes de patrones de sprite. 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
1000bloques de codigo medidos
41,4 %del listado comentado
14.406bytes de codigo
18.362bytes de datos
0bytes sin identificar

Lo que aparecio al desmontarlo

En la ROM solo esta media nave

De cada patron de sprite, el cartucho guarda la mitad izquierda: dieciseis bytes. La derecha la calcula sube_patrones_de_sprite (0x4743) invirtiendo cada byte bit a bit con los ocho rr l / rla de 0x4793. Por eso todo lo que vuela en Twin Bee es simetrico: las dos naves, los disparos, las campanas y los enemigos. El mismo espejo se usa en el decorado, donde sube_espejado (0x4695) sube el bloque con el bit 0 de C puesto. Comprobado: los 2.048 bytes de la tabla de patrones de sprite salen identicos a los del emulador en las cinco fases.

La demostracion es una partida grabada, y por eso el azar es cero

arranca_la_demostracion (0x5FBF) monta una partida de verdad -misma RAM, misma fase, mismo codigo- y le mete el mando por la misma puerta por la que entra el del jugador. Lo que se juega son los 28 valores de 0x6016, uno cada 32 cuadros, hasta el 0xFF que corta la partida. Y para que la misma tira de pulsaciones de siempre la misma partida hace falta que el azar tambien sea el mismo: por eso 0x5FCF pone a cero el registro R del Z80, que es de donde el juego saca sus numeros al azar en los cinco ld a,r de 0xAF75, 0xB2CE, 0xB757, 0xBE0C y 0xBE36. Sin ese ld r,a la demostracion se descarrilaria sola.

La tabla de coseno es la de Knightmare, con dos erratas arregladas

Los 65 valores de 0xB950 son 255 × cos(k × 90/64), y son la misma tabla que la de Knightmare (RC-739): de los 65 bytes solo se diferencian tres. Y esos tres son justo los que Konami arreglo. En Knightmare, k=58 vale 47 cuando la anterior vale 43 -o sea que la tabla sube, que es lo unico que un coseno de un cuadrante no puede hacer-; aqui vale 37, que es lo que toca. La que sobrevive es la de k=46: 105 donde tocaria 109, cuatro unidades de menos en un angulo de 64,7 grados. No rompe la monotonia, y por eso nadie la vio.

Una tira de 1.761 filas, y las cinco fases la recorren seguidas

El guion de 0x6D74 encadena tramos de la tabla de 0x6E01, y de ahi salen 1.761 codigos de fila. Cada codigo indexa uno de los 248 bloques de 32 casillas de 0x6F8F, que es una fila entera de la pantalla, y 0x6D17 lo copia con treinta y dos ldi seguidos. La cuenta cierra sola: entre 0x6F8F y 0x8E8F hay 0x1F00 bytes, que son 248 filas exactas, y el codigo mas alto que gastan los tramos es 0xF7 = 247. La tira no es una fase: la tabla de 0x6132 pone los jefes en las filas 261, 585, 945, 1272 y 1760, y al caer uno 0x613C sube las casillas de la fase siguiente sin mover la pantalla. O sea que cada fase juega su tramo con sus dibujos. Comprobado en openMSX: la lista que el juego deja en 0xE400 es esta, byte a byte, y la tabla de nombres son los bloques de (0xEBF0)-r.

La fase 3 no tiene color propio: se lo permutan

sube_el_color_comun (0x9F41) mira la fase y, si es la tercera, sube el mismo bloque de color que las demas pero con el bit 7 del registro C puesto. Ese bit enciende la permuta de 0x47B5, que cambia los nibbles uno a uno: el 12 pasa a 6, el 6 a 12 y el 5 a 9. Con eso, la misma hoja de casillas sale con otra paleta y el cartucho se ahorra un juego entero de color.

La VRAM como mesa de trabajo

El descompresor de este cartucho solo sabe escribir en la VRAM: saca los bytes por el puerto 0x98 y no tiene forma de dejarlos en la RAM. Asi que cuando hace falta una tabla comprimida en memoria -la de 81 valores que decide como se dan la mano las dos naves- el juego la descomprime en 0x3B80, un hueco de la tabla de atributos de sprites que nadie usa, y la trae de vuelta a 0xEB00 con LDIRMV (0x5E0F). La memoria de video hace de banco de trabajo.

Los sprites se turnan para no desaparecer siempre los mismos

El TMS9918 pinta cuatro sprites por linea y descarta los de indice mas alto, asi que un juego con muchos enemigos parpadea siempre en los mismos. sube_los_sprites (0x46CE) deja los cuatro primeros fijos -las naves y sus disparos- y sube los veintiocho restantes en un orden que rota: (0xE00F) avanza 0x10 en cada cuadro y da la vuelta al llegar a 0x1E, y dentro del bucle el paso es 0x44. Ningun enemigo se queda sin pintar dos cuadros seguidos, y lo que se ve no es una desaparicion sino un parpadeo repartido.

Tres escrituras a la propia ROM que no llegan a ninguna parte

0x4028, 0x4055 y 0x40FE escriben en 0x4195, 0x41A1 y 0x47F7, que estan dentro del propio cartucho: el ld sale al bus y se pierde. De tener efecto, la primera dejaria un pop hl / ret donde hay un djnz, la segunda un jp 0x0000 -o sea un reinicio- y la tercera apagaria la pantalla tocando el byte de R1 de la tabla de registros. Las dos primeras estan iguales en Knightmare (RC-739) y en The Goonies (RC-734), en las mismas posiciones relativas: vienen del armazon, no de este juego.

Veintisiete bytes de codigo al que no llega nadie

Cuatro trozos -0x60CD, 0xBB18, 0xBB25 y 0xBB38- son instrucciones validas y coherentes a las que ningun salto entra. En 0x60CD se ve bien: el jr z de 0x60C9 cae en 0x60D2 y el jr de 0x60CB en 0x60D6, o sea justo por debajo y por encima. Hace lo mismo que 0x60DB, que si se usa. Los otros tres son las variantes de 0x10 de codigo que si esta vivo. Se comprobo tambien que la palabra de esas direcciones no aparece en ninguna tabla del cartucho.

La campana no da lo que parece: da lo que toca por turno

El premio de una campana no sale del color que se ve. Sale de un contador de 32 pasos, (0xE364), que avanza una posicion cada vez que se recoge una y entra en una tabla de 32 casillas que empieza en 0xEB88. Esa tabla no esta en la ROM: la escribe a mano empieza_la_partida con cinco ld y cuatro rlca (0x5D41–0x5D51), o sea que solo cinco de las treinta y dos posiciones traen premio -1 potencia, 2 doble disparo, 4 el brazo, 8 el arma y 0x10 el escudo- y las otras veintisiete solo dan puntos. Leido en el emulador: en 0xEB88 hay 00 00 00 00 01 00 00 00 02 … 04 … 08.

Noventa y nueve fases, cinco escenarios

(0xE07D) es el numero de fase que se ve, en BCD, y sube de uno en uno hasta 99. (0xE076) es el escenario, y cuando su nibble bajo llega a seis vuelve a 0x11, o sea a la primera con el nibble alto a uno (0x6169). De ahi en adelante el juego da vueltas a los mismos cinco escenarios contando vueltas en el nibble alto. Llegar a la fase 99 es la unica manera de terminar Twin Bee: 0x618E pone la marca de partida acabada.

La segunda cabecera, y la marca que Nemesis busca

En 0x4010 va la cabecera del Konami Game Master, el cartucho de trucos de la casa: "CD" 07 40, o sea RC-740. Los bytes que siguen se reparten con un byte de banderas y el reparto cuadra: acaba en 0x4025, justo donde vuelve a haber codigo. Declara la escena, la fase y cuantas hay, las vidas, el record, la puntuacion, los bits de modo y una rutina de este cartucho (0x4103) que el Game Master llama entre ranuras. Y al final del todo, en 0xBFF7, esta la marca oculta de Konami: ba b7 9a ac 81 91 06 40 aa, el titulo en katakana mas el RC-740. Sus seis ultimos bytes son exactamente los que Nemesis (RC-742) va buscando por las ranuras 0, 0x80, 0x84, 0x88 y 0x8C para saber si Twin Bee esta enchufado al lado.

Las cinco fases, cada una con su tramo y su paleta

El escenario de Twin Bee es una tira de 1.761 filas que las cinco fases recorren seguidas: cada mapa es el tramo de su fase, con los jefes en las filas 261, 585, 945, 1272 y 1760. Tres columnas, de arriba abajo y de izquierda a derecha, con el fondo negro de partida.

<b>Fase 1.</b> Las filas 0 a 261 de la tira, once pantallas: el mar con islas y faros del arranque -abajo a la derecha- y la costa verde con su monte al final. Tres columnas, de arriba abajo y de izquierda a derecha; ninguna es una captura.
Fase 1. Las filas 0 a 261 de la tira, once pantallas: el mar con islas y faros del arranque -abajo a la derecha- y la costa verde con su monte al final. Tres columnas, de arriba abajo y de izquierda a derecha; ninguna es una captura.
<b>Fase 2.</b> Filas 238 a 585, catorce pantallas y media, con su propio bloque de casillas a partir de la 0xC0; de la 0x3C a la 0xBF son las mismas en las cinco fases.
Fase 2. Filas 238 a 585, catorce pantallas y media, con su propio bloque de casillas a partir de la 0xC0; de la 0x3C a la 0xBF son las mismas en las cinco fases.
<b>Fase 3.</b> Filas 562 a 945, dieciseis pantallas. La que no tiene color propio: es el color de las demas pasado por la permuta de <code>0x47B5</code>.
Fase 3. Filas 562 a 945, dieciseis pantallas. La que no tiene color propio: es el color de las demas pasado por la permuta de 0x47B5.
<b>Fase 4.</b> Filas 922 a 1272, catorce pantallas y media, con la hoja de casillas mas corta: su bloque propio acaba en la 0xC5.
Fase 4. Filas 922 a 1272, catorce pantallas y media, con la hoja de casillas mas corta: su bloque propio acaba en la 0xC5.
<b>Fase 5.</b> Filas 1249 a 1760, veintiuna pantallas, la mas larga y la mas cargada: llega hasta la casilla 0xEA. Las sombras negras de los acantilados son casillas transparentes sobre el borde negro de partida (registro 7 a 0xE0), y solo se ven bien pintadas asi.
Fase 5. Filas 1249 a 1760, veintiuna pantallas, la mas larga y la mas cargada: llega hasta la casilla 0xEA. Las sombras negras de los acantilados son casillas transparentes sobre el borde negro de partida (registro 7 a 0xE0), y solo se ven bien pintadas asi.

Lo que el cartucho dibuja

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

La pantalla del titulo, montada ejecutando los pasos de <code>monta_el_titulo</code> (<code>0x4BD3</code>). El cotejo contra la VRAM del emulador da <b>cero</b> diferencias en los 16.384 bytes.
La pantalla del titulo, montada ejecutando los pasos de monta_el_titulo (0x4BD3). El cotejo contra la VRAM del emulador da cero diferencias en los 16.384 bytes.
El cartel de KONAMI de la presentacion, en el sitio al que llega tras sus catorce pasos de <code>baja_un_paso</code> (<code>0x4B0A</code>).
El cartel de KONAMI de la presentacion, en el sitio al que llega tras sus catorce pasos de baja_un_paso (0x4B0A).
La primera pantalla del escenario: las 24 filas que <code>monta_las_veinticuatro_filas</code> copia al buffer, empezando por la fila 23 del mapa y bajando.
La primera pantalla del escenario: las 24 filas que monta_las_veinticuatro_filas copia al buffer, empezando por la fila 23 del mapa y bajando.
El rotulo <i>TwinBee</i>, que son <b>27 casillas</b> comprimidas en <code>0x4B3C</code> y escritas en tres filas de once desde la casilla 0xC0 (<code>0x4BF9</code>).
El rotulo TwinBee, que son 27 casillas comprimidas en 0x4B3C y escritas en tres filas de once desde la casilla 0xC0 (0x4BF9).
La fuente entera. No es un alfabeto completo: hay 0 a 9, el simbolo de copyright, un punto, una admiracion y solo las letras <b>A B C D E F G H I K L M N O P R S T U V W Y</b>, que son las que hacen falta para los rotulos de este cartucho.
La fuente entera. No es un alfabeto completo: hay 0 a 9, el simbolo de copyright, un punto, una admiracion y solo las letras A B C D E F G H I K L M N O P R S T U V W Y, que son las que hacen falta para los rotulos de este cartucho.
La hoja de casillas del decorado de la fase 1, de la 0x3C a la 0xD1. Cotejada contra la VRAM del emulador: <b>cero</b> diferencias en las 150 casillas, patron y color, en los tres bancos.
La hoja de casillas del decorado de la fase 1, de la 0x3C a la 0xD1. Cotejada contra la VRAM del emulador: cero diferencias en las 150 casillas, patron y color, en los tres bancos.
La misma hoja de la fase 3. Los patrones son los mismos que arriba; lo unico que cambia es el color, permutado nibble a nibble.
La misma hoja de la fase 3. Los patrones son los mismos que arriba; lo unico que cambia es el color, permutado nibble a nibble.
Los sprites que no dependen de la fase, los 176 patrones de <code>0x1800</code> a <code>0x1D80</code>: las dos naves, el brazo que se estira, los disparos, las bombas, las campanas, las nubes, los avisos de puntos y el GAME OVER. Todos salen de media plantilla, con la mitad derecha calculada por el espejo de <code>0x4743</code>.
Los sprites que no dependen de la fase, los 176 patrones de 0x1800 a 0x1D80: las dos naves, el brazo que se estira, los disparos, las bombas, las campanas, las nubes, los avisos de puntos y el GAME OVER. Todos salen de media plantilla, con la mitad derecha calculada por el espejo de 0x4743.
Los enemigos de la fase 1, subidos por <code>0x9177</code> a partir del patron <code>0xB0</code> desde el bloque que le toca de la tabla de <code>0x9191</code>.
Los enemigos de la fase 1, subidos por 0x9177 a partir del patron 0xB0 desde el bloque que le toca de la tabla de 0x9191.
Y los de la fase 5. Cada fase trae los suyos, y el primer byte de su bloque dice cuantas parejas de 16 bytes vienen detras.
Y los de la fase 5. Cada fase trae los suyos, y el primer byte de su bloque dice cuantas parejas de 16 bytes vienen detras.
El jefe de la fase 1, en el MISMO sitio: sus patrones <b>pisan</b> a los de los enemigos en <code>0x1D80</code>, porque cuando aparece ya no hacen falta.
El jefe de la fase 1, en el MISMO sitio: sus patrones pisan a los de los enemigos en 0x1D80, porque cuando aparece ya no hacen falta.