Dieciséis kilobytes en la página 1, sin un solo cambio de banco. Todo lo que hace el juego cabe entre 0x4000 y 0x7FFF.
Los dieciséis primeros bytes son la cabecera que lee la BIOS: la firma AB y cuatro punteros. Solo INIT tiene valor (0x4081); STATEMENT, DEVICE y TEXT van a cero. O sea que el cartucho no añade órdenes al BASIC ni se declara como dispositivo: arranca y se queda con la máquina.
INIT se prepara la casa y se va:
jp a 0x4010;A partir de ahí el programa principal y la interrupción se reparten el trabajo. La interrupción lleva el reloj, los mandos y lo que tiene que ir a ritmo de pantalla; el principal, la máquina de estados del juego.
La RAM de trabajo es 0xE000-0xE3FE, con la pila arriba del todo. Está repartida por zonas, y cada una tiene su explicación en el listado:
| tramo | qué es |
|---|---|
| 0xE000-0xE001 | contador de cuadros y espera en unidades de 32 |
| 0xE002-0xE017 | el estado de la partida: quién juega, con qué, ronda y prueba |
| 0xE019-0xE01C | el menú: dónde está la flecha y qué línea elegida |
| 0xE01D-0xE01E | los dos semáforos de la interrupción |
| 0xE020-0xE02E | el estado del intento y de la prueba, bit a bit |
| 0xE040-0xE04B | los cuatro récords del mundo, tres bytes BCD cada uno |
| 0xE051-0xE052 | la marca a batir de esta ronda |
| 0xE060-0xE09F | los marcadores que se pintan |
| 0xE0A0-0xE0FF | los dos atletas: velocidad, ángulo, marca y postura |
| 0xE120-0xE15F | cuatro fichas de actor de 16 bytes |
| 0xE160-0xE190 | los tres canales del reproductor de sonido |
| 0xE200-0xE22F | el estado de la jabalina y del salto de altura |
| 0xE230-0xE2CF | el papel donde se montan las figuras antes de subirlas |
Merecen párrafo aparte porque son la clave de que esto no se rompa.
Ese segundo es el truco fino. Fijar una dirección en el VDP son dos escrituras al puerto de control, y si la interrupción se cuela entre ellas —y ella también escribe en el VDP— lo que venga detrás se escribe en el sitio equivocado. En vez de prohibir la interrupción, se deja pasar y se comprueba después.
SCREEN 2, con los tres tercios:
| tabla | dirección |
|---|---|
| nombres | 0x3800 |
| patrones | 0x2000 |
| color | 0x0000 |
| atributos de sprite | 0x3B00 |
| patrones de sprite | 0x1800, de 16x16 |
Los ocho registros del VDP salen de registros_del_vdp (0x4E5C), y son byte a byte los mismos que en el cartucho hermano.
En el listado, las direcciones de VRAM aparecen con el bit 14 puesto (sumado 0x4000) cuando se va a escribir, que es como lo pide el VDP: por eso 0x7800 es la tabla de nombres y 0x5800 los patrones de sprite. Al leer un volcado conviene tenerlo presente o los números no cuadran.
SUBE_LOS_COLORES_DE_LOS_SPRITES (0x4388) sube colores_de_los_sprites (0x5161) a la tabla de atributos con la fila a 0xD1, o sea escondidos fuera de la pantalla, y son veintiséis: ld bc,01afeh. En Hyper Olympic 1 la misma rutina sube treinta y dos.
Y la tabla de posturas (posturas_del_atleta, 0x713C) tiene dieciocho entradas contra las veinticinco de allí. Estas cuatro pruebas necesitan menos figuras que aquéllas.
Un patrón que se repite y que despista al leer el listado: hay tablas cuya dirección registrada cae dos bytes por delante de la primera casilla útil, porque el índice empieza en uno y el código avanza 2*indice antes de leer.
| tabla | lo que dice el código | dónde empieza de verdad |
|---|---|---|
| rótulos de la prueba | 0x4F1C | 0x4F1E |
| pantallas de la prueba | 0x4F24 | 0x4F26 |
| marcadores de la prueba | 0x4F2C | 0x4F2E |
| punteros de melodía | 0x6E62 | 0x6E64 |
| fichas de la prueba | 0x7B6B | 0x7B6D |
No es un error: la casilla cero no se usa nunca.
Un actor normal monta su figura en 0xE230 y la sube de una vez. La valla no cabe en una fila: 0x7AB3 monta la mitad de arriba en 0xE230 y la de abajo en 0xE270, y las sube por separado, cada una a su fila de la tabla de nombres. Es el único actor del cartucho que hace esto.
Las cuatro fichas de actor viven seguidas en 0xE120, 0xE130, 0xE140 y 0xE150, de dieciséis bytes cada una. Y eso no es casualidad: el bit 2 de una ficha hace que ese actor suba el contador de la que tiene 0x11 bytes por detrás, y el bit 3 el de la que tiene 0x0F por delante.
Así el decorado se arrastra en cadena sin que nadie lleve una lista de quién empuja a quién: la relación está en la distancia entre las fichas.
En 0x4E64, pegados a los registros del VDP, hay tres grupos de cuatro bytes con pinta de filas de la tabla de atributos de sprite: 00 70 38 70 / 00 A0 38 70 / 00 F0 38 F0. Ningún puntero de la ROM cae ahí y nadie los lee.
Están también en Hyper Olympic 1, byte a byte iguales y tan muertos como aquí. Los dos cartuchos heredaron el mismo cadáver.
La marca oculta de Konami no está. Muchos cartuchos de la casa esconden al final de la ROM su número de catálogo RC-7xx y el título en katakana, detrás del relleno; lo descubrió Manuel Pazos (@ManuelPazosMSX). Aquí los dos últimos bytes son 0xFF y delante hay código del reproductor de sonido. Se comprobó con tools/marca_konami.py, que en el mismo tiro sí la encuentra en otro cartucho de la casa, así que el método funciona.