Aquí no hay ninguna ilustración ni captura. El rótulo, la portada y la pantalla de partida están dibujados desde los bytes de la ROM, ejecutando en Python los mismos pasos que corre el Z80, y cotejados contra la VRAM de openMSX: cero diferencias en todo lo que no decide el azar. El listado y las cifras salen del binario y se reproducen con make.
Un cartucho de MSX empieza por AB, la dirección de INIT y luego STATEMENT, DEVICE, TEXT y seis bytes reservados. Aquí INIT vale 0x4004, que es justo donde deberían empezar esos campos. Leídos como instrucciones dan el arranque del juego:
4004 31 00 F0 ld sp,0F000h 4007 CD D1 4F call 4FD1h 400A CD 62 50 call 5062h 400D CD 4E 40 call 404Eh
Sólo los cuatro primeros bytes del cartucho son cabecera de verdad. Los otros nueve son las cuatro primeras instrucciones.
La pantalla de título, dibujada desde la ROM, dice PROGRAMMER:Y.TANAKA y debajo T.SASAGAWA. Son dos, no uno. Y la última línea dice PUSH SPACE-KEY OR TORIGER: TORIGER, no TRIGGER.
Los textos no se pueden leer mirando los bytes: la fuente del cartucho no es ASCII del todo y encima cambia a mitad de juego. El 0x21, que en ASCII sería un !, aquí son los dos puntos; por eso leyendo en crudo parecía poner «PROGRAMMER!». La única forma de citar un texto de este cartucho es dibujarlo.
pon_una_bomba (0x491C) mira el número de fase con un and 003h: si es múltiplo de cuatro, no pide el disparo y la bomba cae sola. Y hay un rótulo que lo anuncia, parpadeando abajo dieciséis cuadros sí y ocho no, con exactamente la misma condición (0x4D37): BOMB AUTO SETTING STAGE.
Es un modo de juego entero escondido en dos instrucciones.
Cada brazo de la explosión son cuatro casillas de pantalla, o sea dos casillas de tablero. Pero el bucle está desenrollado a propósito y no todas se tratan igual: las dos primeras llaman a pinta_una_llama_y_gasta_el_ladrillo (0x4B21), que desmorona el ladrillo en ocho cuadros; la tercera y la cuarta llaman a pinta_una_llama_sin_gastar (0x4B5A), que se vuelve sin escribir si lo que hay es un ladrillo.
Medido en openMSX, no deducido: dos bombas metidas a mano en la lista, una con ladrillo pegado y otra con el ladrillo a dos casillas. Los dos de la primera caen; el de la segunda sigue en pie.
Debajo del primer ladrillo que se reparte hay un premio, y no siempre el mismo. Las dieciséis palabras de la tabla de 0x419B apuntan a bloques de dos casillas, y los destinos lo dicen todo: las pares van a la casilla 0x0A y las impares a la 0x1A, que son exactamente las cuatro que pinta pinta_el_premio.
0x4167 carga una pareja de palabras consecutivas —una mitad de arriba y una de abajo—, así que los dieciséis bloques son ocho premios enteros: un telescopio sobre su trípode, un saco de dinero, un velocípedo, un carruaje, una taza humeante, una copa de cóctel, una lata roja de refresco y un paquete de tabaco. Y cuál toca lo eligen dos máscaras sobre el número de fase, una de ellas la misma and 003h de la bomba automática: el premio de esa fase no es el de las tres que van detrás.
El mismo byte de la ficha del enemigo hace dos cosas: elige el dibujo (0xC0 + cuadro*4) y decide el comportamiento. Cuando vale cero, el enemigo persigue al bombero (0x477B) en vez de andar a lo suyo. Y cero es justo el cuadro de dibujo rojo: los otros tres son morados.
O sea que el juego te está avisando de cuándo te persiguen, y no hace falta ni un byte para ello.
0x5062 escribe un 0xD0 en el primer atributo de sprite —la marca de «no hay más»— y no vuelve a tocar la lista nunca. Todo lo que se mueve son casillas de la tabla de nombres, y todo ocupa dos por dos.
Eso explica la arquitectura entera: el juego lleva dos pantallas de 768 bytes en la RAM, una para lo que se ve y otra para lo que permanece, y en vez de tener una estructura de datos del mapa lee el número de casilla. Las tres comparaciones que se repiten por todo el listado son cp 020h («libre»), cp 0e0h («hay llama») y cp 0c0h («hay algo que mata»), y esta última vale para las llamas y para los bichos porque están puestos seguidos a propósito.
numero_al_azar (0x4EF9) realimenta una semilla de dieciséis bits y le mezcla el registro R del Z80. No es un adorno: si R avanzara siempre lo mismo entre dos sorteos, la serie de casillas se cierra en tres a cinco valores y se repite —lo comprueba un test del repositorio, con cuatro pasos distintos—.
En la máquina no pasa porque entre dos sorteos se ejecutan más o menos instrucciones según cuántas veces haya habido que repetir el sorteo. La consecuencia es que el reparto de una fase no se puede reproducir desde fuera: depende del instante en que se pulsó el disparo.
Tres rutinas enteras —0x4EF0 (borrar una casilla del tablero), 0x4F84 (una espera corta) y 0x50D6 (escribir el registro 7 del VDP)— sin un solo call que las nombre en los 8 KB. Y un cuarto: el cp 089h de 0x4AC9, que comprobaría el pilar en la primera casilla de cada brazo, y por encima del cual pasa un jr incondicional.
Ese último no cambia nada, y por eso nadie lo arregló: la casilla siguiente da con la otra mitad del mismo pilar y la llama se para ahí igual. Se declaran como código, porque instrucciones son.
Y hay seis bytes en 0x4864 que sí se ejecutan y no hacen nada: un ld c,a y cuatro ld b,.. que nadie vuelve a leer. En la propia fuente del cartucho se leen OBADD.
Si una llama alcanza la puerta o el premio, el juego apunta el sitio y saca cuatro enemigos más por ahí (0x453B) en cuanto la casilla queda limpia. La puerta se vuelve a descubrir; el premio se pierde.
Y si el bonus llega a cero, se_agoto_el_bonus (0x449F) borra el tablero entero: los treinta y cinco ladrillos, el premio y la puerta desaparecen de golpe, y con las dos banderas de «ya está descubierto» puestas a uno ya no se vuelven a buscar. La fase se queda sin salida y sólo se puede terminar matándolos a todos.
Debajo de cada imagen está de dónde sale y qué se está viendo.
siembra_la_fase (0x4E35) y pintada con las rutinas del cartucho, en el orden del bucle principal. El marco y los treinta y cinco pilares están donde 0x4DB7 los pone, comprobado contra el emulador; los ladrillos son un reparto de los posibles, porque el de verdad lo decide el registro R. Se ven una bomba con la mecha empezando, otra a punto y una explosión ya abiertapinta_el_premio—, y 0x4167 carga una pareja por fase. Un telescopio sobre su trípode, un saco de dinero, un velocípedo, un carruaje, una taza humeante, una copa de cóctel, una lata roja de refresco y un paquete de tabaco. El de las tres primeras fases, un cofre, viene en el bloque grande y no está aquí