Aqui no hay ninguna captura. Todas las imagenes estan dibujadas desde los bytes de la ROM, ejecutando en Python los mismos interpretes que corre el Z80, y comprobadas contra la VRAM del emulador: cero diferencias en 137.260 bytes. El listado y las cifras se reproducen con make.
SCREEN 2 son tres tercios independientes, y para que los tres tengan lo mismo hay que escribirlo tres veces. 0x442D copia de VRAM a VRAM byte a byte, y le mandan 4.095 bytes de 0x0000 a 0x0800: como el destino va 0x800 por delante, pasado el primer bloque esta leyendo lo que el mismo acaba de escribir. Un bucle, tres tercios iguales, 4 KB ahorrados. Se hace dos veces: colores y patrones.
En SCREEN 2 el TMS9918 no lee R3 y R4 como una direccion, sino como un bit de base y una mascara. Con R4 = 0x07 los patrones quedan en 0x2000 y con R3 = 0x7F los colores en 0x0000, al reves de lo habitual.
Leerlo del otro modo tiene un sintoma que engana: las formas se siguen reconociendo -los dos bloques son simetricos- pero los colores salen a franjas.
No es un sprite: son 2x2 tiles de la tabla de nombres. 0x6ED2 mira donde esta la pelota, parte la pista en tres con 0x48 y 0x78, y elige una de las tres caras de 0x715D. Solo cambian los ojos.
Cada postura son cinco sprites de 16x16 apilados. La tabla de 0x5961 tiene 58 entradas que apuntan a 37 descripciones de doce bytes -cinco punteros a patron y uno a las cinco parejas (y,x)-, y entre todas gastan 189 patrones.
El color no esta ahi: sale de la ficha del jugador, y por eso las jugadoras 3 y 4 llevan el pelo magenta donde las 1 y 2 lo llevan negro.
0x6BE9 hace ld a,r. R es el contador de refresco de la DRAM, que el Z80 adelanta en cada instruccion, asi que no se puede predecir. Rotado dos veces, es el temblor de la punteria del rival -y 0x6BEE lo deja a cero en la mitad de los cuadros.
0xE20A cuenta los golpes del punto. 0x6E3B lo divide por dos, lo topa en quince y lo busca en una de las tres curvas de dieciseis pasos de 0x6E67, una por opcion del GAME SELECT. Cuanto mas se alarga el punto, mejor juega la maquina; pasado el golpe treinta ya no sube.
0x4272 pide 22 bytes de atributos desde 0x7890, donde solo hay 16 de datos: lo que sigue en 0x78A0 ya es codigo. Asi que los seis primeros bytes de esa rutina acaban en la VRAM 0x3B3C, y ahi se quedan toda la partida. No se nota porque los patrones a los que apuntan estan vacios.
Nueve bytes en 0x61F5 se descomprimen a un sprite valido de 16x16. No la apunta nadie, y no es una impresion: la palabra 0x61F5 no aparece en toda la ROM en ninguno de los dos ordenes de byte, y todos los punteros a patron son palabras de 16 bits. Tampoco coincide con ninguno de los 189 patrones que si se dibujan.
Los guiones estan llenos de longitudes a cero, y no son bloques vacios: el Z80 decrementa antes de comprobar, asi que un djnz con B a cero da 256 vueltas. Es como se escribe 256 en un byte. Leerlas como ceros descuadra el guion a los pocos bloques.
Con un jugador pone PLY y MSX; con dos personas, 1UP y 2UP -los seis tiles de 0x7760 y los seis de 0x7766. El guion de la pista deja escrito CPU ahi, y el juego lo tapa despues.
El alfabeto tampoco es ASCII: la A es 0xD1 y de ahi seguido, sin la Q, y con la X fuera de orden en 0xE8, detras de la Y.
Lo llamativo no es que la lleve -Konami la ponia en muchos de sus cartuchos, y el RC-701 gasta la misma idea con un ldir- sino cuando salta. La comprobacion no esta en el arranque, donde se esperaria: esta en 0x7A31, dentro de la rutina que apunta un juego ganado. O sea que una copia arranca bien, ensena el titulo, deja elegir y deja jugar, y solo se rompe cuando alguien se lleva el primer juego. Para entonces quien la ha copiado ya la ha dado por buena.
El mecanismo es de una sola instruccion: escribe un cero en 0x409A, que es el ret con el que acaba el manejador de interrupcion, y en 0x409B empieza INIT. En ROM no hace nada, porque no se deja escribir; en RAM ese ret se vuelve un nop, la interrupcion sigue de largo y cae en INIT, con lo que el juego se reinicia en cada cuadro. Es la unica escritura de toda la ROM a su propia pagina, y aqui esta sin parchear.
Konami escondia su numero de catalogo y el titulo en katakana al final de muchos cartuchos, en el offset 0x3FF0; lo descubrio Manuel Pazos (@ManuelPazosMSX). Este no la lleva, y no por no mirar: se rastrearon las 16.384 posiciones con un buscador validado antes contra cartuchos de la misma familia que si la llevan, que es la unica manera de fiarse de un negativo.
Debajo de cada imagen esta de donde sale y que se esta viendo.