Trailblazer

Una pista en perspectiva que no esta dibujada en ninguna parte: la rutina que la pinta se reescribe a si misma cada fila con los pixeles que le tocan, y lo que hay guardado son catorce listas de indices a una tabla de filas. Cinco bandas repintadas a cinco velocidades distintas hacen la profundidad, y las estrellas del fondo se mueven con treinta y dos rl (hl) seguidos, sin bucle.

Gremlin Graphics - Mr Chip 1986 - MSX1 - cinta, 38.458 bytes - Cinco piezas, un cargador propio - Volcado 779b6627...

Aqui no hay ninguna captura. Todas las imagenes estan dibujadas desde los bytes de la cinta, ejecutando en Python los mismos pasos que hace el Z80: estirar el color comprimido, deshacer la transposicion de los patrones y recorrer las pistas fila a fila. El listado y las cifras se reproducen con make, y reensamblar las cinco piezas y volver a envolverlas devuelve el .cas entero, byte a byte.

El cartucho en cifras

100 %del binario explicado
355rutinas con nombre
30,8 %del listado comentado
6.556bytes de codigo
31.743bytes de datos
0bytes sin identificar

Lo que aparecio al desmontarlo

La rutina que dibuja la pista se reescribe a si misma

La pista en perspectiva no esta dibujada en ninguna parte, y el motor que la pinta no lee los pixeles de una tabla: se los escribe encima. Por cada fila, 0x8BAE saca cinco bytes de la tabla de 0x7800, los pasa por dos tablas de traduccion y mete el resultado dentro de los seis ld a,000h que hay repartidos por la rutina de dibujo, en 0x8C2D, 0x8C42, 0x8C56, 0x8C81, 0x8C95 y 0xC8A9.

Un cuadro despues, esos mismos ld a,nn sacan su valor por el puerto del VDP. La rutina no consulta: ya trae el dibujo dentro. Y hay un septimo operando escrito a mano, el de 0x8C01, que elige la pagina de la tabla de perspectiva.

Cinco bandas a cinco velocidades: la profundidad, gratis

El avance de la pista no calcula ninguna proyeccion. 0x8AD3 reparte la pantalla en cinco bandas y repinta cada una a un ritmo distinto: la de delante dos veces por paso, la siguiente una, la tercera una de cada dos, la cuarta una de cada cuatro y la del horizonte una de cada ocho.

Eso es todo. No hay division, ni tabla de perspectiva, ni multiplicacion: cinco contadores con su mascara -and 001h, and 003h, and 007h- y la carretera se aleja.

Catorce pistas en seis kilobytes, porque no guardan casillas

Las catorce pistas suman 3.494 filas de cinco casillas, que serian 17.470 bytes. Ocupan 3.494: una pista no guarda sus casillas, guarda una lista de indices a una tabla de filas.

La tabla vive en los ultimos 0x800 bytes de la carga -0x7800 en la RAM- y es lo que 0x8BB9 indexa con fila*5. Cada pista es una lista de bytes cerrada con 0xFF, y el bucle de 0x93A4 avanza de una a la siguiente buscando ese 0xFF.

Las casillas son ocho: agujero, pista de dos colores, acelera, frena, rebota y dos que invierten los mandos. Lo dice el despachador de 0x8E65, que compara la casilla contra esos valores y contra ningun otro.

El cargador no lee la cinta: monta un puente en la pila

El BIOS del MSX solo carga la primera pieza, la de 0xD800. Las otras cuatro las lee ella, y lo hace con un truco: 0xD850 pone la pila en 0xFCA4 y empuja cinco words que no son datos sino instrucciones -0xC961, 0xEDD9, 0x00E1, 0xCDD9, 0x69ED-. Lo que queda escrito en 0xFC9A es esto:

out (c),l     ; conmuta la ranura: entra la ROM del BIOS
exx
call 000E1h   ; TAPION
exx
out (c),h     ; y devuelve la ranura que habia
ret

El juego necesita RAM en todas las paginas, pero para leer cinta hace falta la ROM. El puente vive en 0xFC9A porque la pagina 3 es RAM con las dos configuraciones, y por eso sobrevive al cambio. Antes de montarlo se guarda lo que habia ahi -doce words de variables del BIOS- y al acabar se devuelve.

Y luego se reescribe dos veces: 0xD871 le cambia el call a 0x00E4, que es TAPIN, para leer los bytes; y 0xD8B5 a 0x00F3, que es STMOTR, para parar el motor. Un solo puente para las tres llamadas.

La barra de carga es el borde de la pantalla

Mientras lee, 0xD8A7 saca el byte bajo de lo que queda por el registro 7 del VDP. No hay barra dibujada ni casillas que pintar: el color del borde va cambiando solo, y eso es todo el indicador de progreso.

El color de la pantalla de carga va comprimido ocho a uno

En SCREEN 2 la tabla de color son 0x1800 bytes, uno por cada fila de cada patron. La pantalla de carga guarda 0x300: un byte por patron, porque las ocho filas llevan el mismo color, y 0x889C lo escribe ocho veces seguidas.

Y dentro de ese byte caben los dos colores: los bits 0 a 2 son la tinta y los 3 a 5 el papel, indices de una paleta de ocho que esta dos veces en la ROM, una en el nibble alto y otra en el bajo, para poder pegarlos con un or. Los bits 6 y 7 no se usan.

La misma paleta esta en el juego, en 0x9593, byte por byte.

Los patrones van transpuestos

El bucle que vuelca los patrones a la VRAM lee ocho bytes con inc h, no con inc hl: saltando de 256 en 256. Y solo despues pasa al patron siguiente con pop hl / inc l.

O sea que en la memoria el byte (base + fila*0x100 + patron) es la fila fila del patron patron, y no las ocho filas seguidas. Leido del modo obvio, la pantalla de carga sale a ruido. Pasa igual en la portada (0x8858), en el juego (0x9522) y en el bufer del rotulo que desfila (0x961A).

Las estrellas se mueven con treinta y dos rl (hl)

0x9BB1 desplaza una fila entera de la pantalla un pixel a la izquierda, y lo hace sin bucle: treinta y dos rl (hl) escritos uno detras de otro, con el acarreo pasando de un byte al siguiente. Cada ocho hay un dec hl en vez de un dec l, que es el salto a la banda de arriba.

Y las estrellas de delante no son esas: son siete puntos que 0x8F65 mueve con velocidad y aceleracion propias, abriendose hacia los bordes como si vinieran de frente. El color de cada una sale del registro R, el contador de refresco de la DRAM, que va cambiando con cada instruccion (0x90DE).

Una sola rutina mira las ochenta teclas, fabricando el opcode

0xBF62 recibe un codigo de tecla, saca de sus tres bits bajos el numero de bit, lo sube al hueco que le toca y le pega un 0x47, que es el opcode de bit 0,a. Y entonces lo escribe en 0xBF85, que es la instruccion que va a ejecutar dos lineas mas abajo.

Sin tabla, sin bucle y sin ocho ramas: la instruccion se fabrica al vuelo. Lo mismo hace 0x9695 con el color de una linea de texto, escribiendo un or encima de un nop (0x9808).

El juego dice quien lo hizo, y con quien se llaman las pistas

El rotulo que desfila en el titulo -de 0x9E69 a 0xA29D- da los creditos enteros: el original es de Mr Chip Software (1986) y lo escribio Shaun Southern en el Commodore; esta version la firman Shaun Hollingworth, Colin Dooley, Peter Harrap, Chris Kerry y Greg Holmes de Gremlin Graphics, con el diseno de Terry Lloyd.

Y luego estan los catorce nombres de pista, en 0xA4CB: TERRY'S TEST, PETE STREET, GREG THE NIPPER, SHAUN NOT SEAN!!, CHRIS'S CUL-DE-SAC... las pistas llevan el nombre de quien las hizo.

El rotulo bromea con que puede que haya un modo de trampas, pero lo dudo. Lo hay: en 0x9CE6 esta su cartel, FOOLED YOU! YOU ARE NOW IN CHEAT MODE. Y la pantalla de carga lleva firma: STEVE., abajo a la derecha.

Dos kilobytes de memoria vieja, grabados en la cinta

La pieza que trae las pistas mide 10.240 bytes pero solo usa la mitad de arriba: lo unico que hace su codigo es llevar los 0x2000 de 0x9000 a la RAM en 0x6000, y el juego, que se carga despues, pisa 0x8800..0x9000 sin que nadie lo haya leido.

Y se sabe de donde salen esos dos kilobytes: 231 bytes seguidos, de 0x8815 a 0x88FC, son identicos a los que el juego trae para esas mismas direcciones, y detras sigue el mismo codigo de arranque. De los 2.048, la mitad justa coinciden. El que grabo la cinta volco 0x8800..0xB000 de un tiron y se llevo de propina dos kilobytes del juego que ya estaban en memoria.

Lo mismo pasa, mas pequeno, con las colas del cargador (143 bytes) y del buscador de RAM (175): ninguna instruccion las lee.

Lo que el cartucho dibuja

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

La pantalla de carga, montada como la monta la cinta: los patrones deshaciendo su transposicion y el color estirado ocho a uno desde los 0x300 bytes que lo guardan. Abajo a la derecha, en letra pequena, la unica firma de toda la cinta: <b>STEVE.</b>
La pantalla de carga, montada como la monta la cinta: los patrones deshaciendo su transposicion y el color estirado ocho a uno desde los 0x300 bytes que lo guardan. Abajo a la derecha, en letra pequena, la unica firma de toda la cinta: STEVE.
La primera pista, EASY GOING, entera y tumbada: la salida a la izquierda. Azul es pista, negro agujero, verde acelera, rojo frena y blanco rebota. Son 219 filas de cinco casillas, y la cinta las guarda en 219 bytes.
La primera pista, EASY GOING, entera y tumbada: la salida a la izquierda. Azul es pista, negro agujero, verde acelera, rojo frena y blanco rebota. Son 219 filas de cinco casillas, y la cinta las guarda en 219 bytes.
Y la ultima, LAST BUT NOT LEAST!, con la misma escala. La comparacion con la primera se ve de un vistazo: la dificultad no esta en el largo sino en cuantos agujeros hay por fila.
Y la ultima, LAST BUT NOT LEAST!, con la misma escala. La comparacion con la primera se ve de un vistazo: la dificultad no esta en el largo sino en cuantos agujeros hay por fila.
Las filas distintas de la tabla de 0x7800, las 176 primeras. Una pista no guarda casillas: guarda una lista de indices a esta tabla, y por eso catorce pistas de 3.494 filas caben en 3.494 bytes.
Las filas distintas de la tabla de 0x7800, las 176 primeras. Una pista no guarda casillas: guarda una lista de indices a esta tabla, y por eso catorce pistas de 3.494 filas caben en 3.494 bytes.
Los 0x400 bytes que el arranque vuelca a la VRAM: la bola, en las tallas que necesita la perspectiva, y sus mascaras. Cotejados contra la VRAM de openMSX: <b>cero bytes distintos</b>.
Los 0x400 bytes que el arranque vuelca a la VRAM: la bola, en las tallas que necesita la perspectiva, y sus mascaras. Cotejados contra la VRAM de openMSX: cero bytes distintos.
La fuente del juego, de 0xBB25 a 0xBE0E. Es la hoja que el arranque deja en (0xA41E), el puntero del que tira la rutina de texto; para el rotulo grande de las opciones se cambia por otra y se devuelve.
La fuente del juego, de 0xBB25 a 0xBE0E. Es la hoja que el arranque deja en (0xA41E), el puntero del que tira la rutina de texto; para el rotulo grande de las opciones se cambia por otra y se devuelve.