El cartucho

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.

La cabecera

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.

Lo que hace INIT, y por qué no vuelve

INIT se prepara la casa y se va:

  1. engancha la interrupción en H.KEYI (0xFD9A) con un jp a 0x4010;
  2. limpia 0xE000-0xE3FE y pone la pila justo encima, en 0xE3FE;
  3. calla el PSG poniendo a cero sus registros 8, 9 y 10, que son los tres de volumen: no los de tono, que a cero no callarían nada;
  4. fija en el VDP la dirección de escritura 0x81A2 —y no escribe nada detrás; ver Preguntas abiertas—, y pone el registro 15 del PSG, el puerto de salida, a 0xCF;
  5. apaga el piloto de CAPS;
  6. copia los cuatro récords del mundo de 0x517B a 0xE040;
  7. coloca la flecha del menú en la primera línea.

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.

El mapa de la memoria

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:

tramoqué es
0xE000-0xE001contador de cuadros y espera en unidades de 32
0xE002-0xE017el estado de la partida: quién juega, con qué, ronda y prueba
0xE019-0xE01Cel menú: dónde está la flecha y qué línea elegida
0xE01D-0xE01Elos dos semáforos de la interrupción
0xE020-0xE02Eel estado del intento y de la prueba, bit a bit
0xE040-0xE04Blos cuatro récords del mundo, tres bytes BCD cada uno
0xE051-0xE052la marca a batir de esta ronda
0xE060-0xE09Flos marcadores que se pintan
0xE0A0-0xE0FFlos dos atletas: velocidad, ángulo, marca y postura
0xE120-0xE15Fcuatro fichas de actor de 16 bytes
0xE160-0xE190los tres canales del reproductor de sonido
0xE200-0xE22Fel estado de la jabalina y del salto de altura
0xE230-0xE2CFel papel donde se montan las figuras antes de subirlas

Los dos semáforos de la interrupción

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.

La pantalla

SCREEN 2, con los tres tercios:

tabladirección
nombres0x3800
patrones0x2000
color0x0000
atributos de sprite0x3B00
patrones de sprite0x1800, 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.

Veintiséis sprites, no treinta y dos

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.

Cinco tablas indexadas desde uno

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.

tablalo que dice el códigodónde empieza de verdad
rótulos de la prueba0x4F1C0x4F1E
pantallas de la prueba0x4F240x4F26
marcadores de la prueba0x4F2C0x4F2E
punteros de melodía0x6E620x6E64
fichas de la prueba0x7B6B0x7B6D

No es un error: la casilla cero no se usa nunca.

La valla se dibuja en dos papeles

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.

Los actores se empujan unos a otros

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.

Doce bytes que no lee nadie

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.

Lo que no lleva

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 la encuentra en otro cartucho de la casa, así que el método funciona.