Hyper Rally

Un rally de doce etapas en un cartucho de 16 KB: una carretera en falso 3D, un salpicadero con cuentakilómetros, gasolina, marcha y reloj, coches rivales que colisionan por profundidad, y todo movido por la interrupción de cada cuadro.

Konami · © Konami 1985 · Cartucho RC-718, 16 KB · MSX1 · página 1 · Volcado eca2c0d6…

Aquí no hay ninguna ilustración ni captura. La fuente y los tiles están dibujados desde los bytes de la ROM, ejecutando en Python el mismo descompresor de guiones que corre el Z80; hasta la escena de la carretera se monta así, ejecutando los descompresores del cartucho y pintando los coches con sus propios patrones. El listado y las cifras salen del binario y se reproducen con make.

El cartucho en cifras

100 %del binario explicado
428rutinas identificadas
12etapas del rally
6.446bytes de código
9.938bytes de datos
0bytes sin identificar

Lo que apareció al desmontarlo

Lleva la marca oculta de Konami

Al final de la ROM, detrás del relleno, Konami escondía en muchos cartuchos su número de catálogo y el título en katakana; lo descubrió Manuel Pazos (@ManuelPazosMSX). Aquí está: los últimos once bytes de 0x7FF5 son el título al revés, su longitud, el 18 del RC-718 en BCD y el 0xAA que la cierra.

Un solo bucle muerto y toda la máquina en la interrupción

INIT engancha la interrupción a 0x4051 y cae en un jr a sí mismo. A partir de ahí el programa principal no hace nada: cada cuadro, la interrupción lee 0xE000 (el estado, de 0 a 8), salta por una tabla de nueve manejadores, y dentro de cada uno el byte 0xE001 reparte los subestados con cadenas de djnz.

La carretera es una tabla de formas indexada por la curvatura

No hay geometría: 0x68D0 lee 0xE074 —la curvatura y la posición del trazado— e indexa la tabla de 0x767C para elegir qué forma de carretera dibujar. Las rayas se mueven hacia el jugador desplazando un buffer (0x707A) al ritmo de la velocidad, y el escalado de los objetos por profundidad sale de las tablas de 0x6CD5.

Doce etapas de ocho compositores, y dos son de noche

0xE060 va de 1 a 0x0C y con él se elige, por la tabla de 0x481A, el compositor de fondo de cada etapa: ocho rutinas cubren las doce, y el compositor de la 12 llama al de la 5. El parámetro 0xE061 (tabla 0x4372) es un campo de bits con lo que cada etapa tiene de particular: el bit 1 es el suelo resbaladizo de la nieve, 0x01 el túnel, 0x10 la tormenta y 0x08 la noche. En las dos nocturnas, 0x71AC corre un campo de dieciséis estrellas por el cielo, a precisión de píxel y al ritmo de la velocidad del coche.

El sonido es el reproductor de tres canales de la casa

El motor de 0x5FB7 recorre tres fichas de catorce bytes (0xE010), lee las melodías con su intérprete de órdenes y escribe el PSG por la BIOS. Es el mismo armazón de reproductor que Konami repartía entre sus cartuchos de MSX; 0x5ED9 arranca una melodía o un efecto por su número, mirando antes la prioridad para no pisar lo que ya suena.

El coche del jugador son seis sprites, y los rivales colisionan por profundidad

El coche se monta con seis sprites (plantilla en 0x66E2) que 0x65FA recoloca cada cuadro según el volante. Los tres rivales llevan sus fichas en 0xE138/48/58; 0x7C34 los ordena por cercanía antes de dibujarlos, y 0x7F89 parte la velocidad por la mitad al chocar contra uno.

Un rival no tiene recorrido propio

0x7CCB estaba en el listado como el impacto, y no toca tu velocidad: lo único que escribe es la posición del rival, y le suma (la velocidad del rival − la tuya) / 16. En una carrera de 45 segundos sin un solo golpe corrió 1329 veces. Y 0xE09C, que el listado llamaba el color del rival, es su velocidad: forzado a 0 te los comes a todos, forzado a 255 se te escapan todos. La cuenta rehecha en Python reproduce 102 de 102 casos leídos dentro de la propia rutina.

No hay ninguna pirámide dibujada en la ROM

En el desierto la carretera no scrollea: 0x707F desvía el scroll a SUBEN_PIRAMIDES. Y no hay una pirámide guardada en ninguna parte: hay una ventana de 32 bytes en 0x7351 —dieciséis ceros y luego el triángulo— que se desliza una posición cada vez que 0xE071 llega a uno de los dieciséis umbrales de 0x7371. La mitad derecha del patrón es la izquierda pasada por INVIERTE_BITS, el mismo truco del coche rival.

Un rival que se acerca cambia de material por el camino

No crece: deja de ser sprites y pasa a ser pantalla. La tabla 0x7D94 da veinte escalones, y los dos bits bajos de cada patrón dicen cuántos sprites se encienden —uno de lejos, dos más cerca, y cuatro en dos capas de color superpuestas, que es como se pinta un coche de dos colores con sprites de un color cada uno—. Cuando el byte 0 de la ficha baja de 0x28, 0x7B21 pone Y = 0xE0 en los cuatro sprites y RIVAL_MEDIO (0x7AD1) lo repinta con doce casillas de la tabla de nombres.

Y de esas doce, el cartucho sólo guarda la mitad: 0x2A es 0x24 con los bits del revés, y así hasta 0x2E. La otra mitad la pone DESC_DOBLE (0x44B0), que pasa el mismo bloque dos veces y la segunda por el núcleo reubicado de 0xE310, que cae en INVIERTE_BITS.

Lo que el cartucho dibuja

Debajo de cada imagen está de dónde sale y qué se está viendo.

La pantalla del título, montada con los mismos pasos del cartucho: DIBUJA_MARCO (0x4D8E) descomprime la fuente en la tabla de patrones y reparte los colores, DIBUJA_PANEL_JUEGO (0x4878) llena el resto de la tabla de color, y el guión de 0x4C9E -el que vuelca PREPARA_PANTALLA_CARRERA- pinta el rótulo en las filas 5 a 7 y las dos líneas de texto con los glifos de la fuente
La pantalla del título, montada con los mismos pasos del cartucho: DIBUJA_MARCO (0x4D8E) descomprime la fuente en la tabla de patrones y reparte los colores, DIBUJA_PANEL_JUEGO (0x4878) llena el resto de la tabla de color, y el guión de 0x4C9E -el que vuelca PREPARA_PANTALLA_CARRERA- pinta el rótulo en las filas 5 a 7 y las dos líneas de texto con los glifos de la fuente
La fuente del cartucho, dibujada desde la ROM por <code>tools/graficos.py</code>, descomprimiendo el guión de 0x4DEA con el mismo formato que el Z80. Digitos, símbolos y el alfabeto con el que se escribe todo el juego, incluida la unidad km/h del cuentakilómetros
La fuente del cartucho, dibujada desde la ROM por tools/graficos.py, descomprimiendo el guión de 0x4DEA con el mismo formato que el Z80. Digitos, símbolos y el alfabeto con el que se escribe todo el juego, incluida la unidad km/h del cuentakilómetros
Los tiles de la carretera y el decorado que van detrás de la fuente en el mismo bloque, descomprimidos igual. Son las piezas con las que se arman los bordes del trazado y el paisaje de cada etapa
Los tiles de la carretera y el decorado que van detrás de la fuente en el mismo bloque, descomprimidos igual. Son las piezas con las que se arman los bordes del trazado y el paisaje de cada etapa
Cómo se acerca un rival, sobre la pantalla de carrera montada ejecutando los descompresores del cartucho. El mismo coche a cuatro distancias: de lejos son sprites -uno, luego dos, luego cuatro en dos capas de color- y en el último escalón el cartucho los apaga (0x7B21, Y = 0xE0) y lo repinta con doce casillas de la pantalla
Cómo se acerca un rival, sobre la pantalla de carrera montada ejecutando los descompresores del cartucho. El mismo coche a cuatro distancias: de lejos son sprites -uno, luego dos, luego cuatro en dos capas de color- y en el último escalón el cartucho los apaga (0x7B21, Y = 0xE0) y lo repinta con doce casillas de la pantalla
Los escalones de un rival, leídos de la tabla 0x7D94: el patrón base y su altura en pantalla. Los dos bits bajos de ese patrón dicen cuántos sprites se encienden, porque 0x7A73 apaga los que sobran; el último ya no es un sprite, son cuatro por tres casillas
Los escalones de un rival, leídos de la tabla 0x7D94: el patrón base y su altura en pantalla. Los dos bits bajos de ese patrón dicen cuántos sprites se encienden, porque 0x7A73 apaga los que sobran; el último ya no es un sprite, son cuatro por tres casillas
Las doce etapas del rally, montadas ejecutando los descompresores del cartucho. Ocho rutinas de fondo cubren las doce, y la dirección de cada una es la que elige la tabla 0x481A. Cotejadas contra doce volcados de VRAM de openMSX, las doce cuadran: lo único que baila es lo que el juego repinta cuadro a cuadro
Las doce etapas del rally, montadas ejecutando los descompresores del cartucho. Ocho rutinas de fondo cubren las doce, y la dirección de cada una es la que elige la tabla 0x481A. Cotejadas contra doce volcados de VRAM de openMSX, las doce cuadran: lo único que baila es lo que el juego repinta cuadro a cuadro
Los dos efectos que van encima del fondo. En el desierto la carretera no scrollea: suben pirámides, y no hay ninguna pirámide dibujada en la ROM —hay una ventana de 32 bytes en 0x7351 que se desliza una posición por umbral—. Y en la tormenta caen tres formas de rayo, pintadas por PINTA_ROTULO desde la fila 2
Los dos efectos que van encima del fondo. En el desierto la carretera no scrollea: suben pirámides, y no hay ninguna pirámide dibujada en la ROM —hay una ventana de 32 bytes en 0x7351 que se desliza una posición por umbral—. Y en la tormenta caen tres formas de rayo, pintadas por PINTA_ROTULO desde la fila 2
El rival de cerca y sus doce casillas una a una. Los doce números están literales en la ROM en 0x7BF3, pero los patrones sólo a medias: 0x2A es 0x24 con los bits del revés, y así hasta 0x2E. El cartucho guarda medio coche, y la otra mitad la pone DESC_DOBLE (0x44B0) pasando el mismo bloque por INVIERTE_BITS
El rival de cerca y sus doce casillas una a una. Los doce números están literales en la ROM en 0x7BF3, pero los patrones sólo a medias: 0x2A es 0x24 con los bits del revés, y así hasta 0x2E. El cartucho guarda medio coche, y la otra mitad la pone DESC_DOBLE (0x44B0) pasando el mismo bloque por INVIERTE_BITS