Blog | Archivo | Contacto | Administración |
Creo que ya he contado alguna que otra vez mi gusto por el software independiente; puede ser un soplo de aire fresco en el mejor de los casos, y pura ponzoña en el peor (lo cual también es disfrutable a su manera). Esto viene de lejos, en la época ya disfrutaba de publicaciones como VideoSpectrum o de los programas enviados por lectores en revistas como MicroHobby.
Y de uno de éstos últimos voy a hablar hoy; en su tercera época dicha revista empezó a distribuirse mensualmente y a incluir cintas (MicroHobby Selección) con demos, juegos completos, cargadores y los programas y ejemplos publicados, incluyendo los juegos de lectores, para no tener que teclearlos.
A muchos de ellos jugué más horas de las que quisiera admitir. Algunos estaban inspirados en juegos comerciales, como Silver Gun (aunque en el menú pone The Bang Bank), similar a West Bank; ambos claramente inspirados en la recreativa Bank Panic!. Zhak, con una estética muy a lo Camelot Warriors. Yucan, de disparos con aviones, con buen nivel técnico...
Otros eran más personales, como Gnoni (aventura plataformera muy simpática a la par que recomendable) o ParapShock (otra videoaventura, con un mapeado enorme). Y otros eran extravagantes como el que hoy os traigo. Y es que hace poco, leyendo los títulos de las cosas publicadas no me sonaba para nada un tal "Rio Blanco", pero en cuanto fui a mirar una captura lo recordé de golpe: "¡es el juego del niño gamba!", pensé, pues así le llamaba yo; y quizás por no recordar su nombre real no lo había vuelto a tocar desde entonces.
El juego está rodeado de un cierto halo de misterio. Unas instrucciones escuetas por parte de MH, sin portada, un juego que no tiene menú (pero sí un flasheo negro / magenta desagradable y un zumbido más desagradable aún), y del cual no existe RZX o siquiera un mapa completo (en el que hay, se pide ayuda para poder terminarlo) pese a existir pokes.
He dejado lo mejor para el final: el indescriptible protagonista (al que yo bauticé como niño gamba), supuestamente un "sistema robótico" (?) llamado Hunter MKII, pero que yo veo como una especie de híbrido humano / crustáceo con lanzallamas montado en monociclo. Saquen sus conclusiones (del personaje y de mí), y de regalo maravíllense con las posibilidades de la IA generativa.
En fin, que demasiados misterios. Así que tuve que desensamblarlo y mirar por dentro, descubriendo varias cosas:
Se nos acumulan los misterios.
¿Llegó el creador del mapa hasta la rutina de carga y pensó que se había colgado?
Y con respecto al bloque excluido, no es una omisión por parte de los preservadores. No estaba en la cinta de MH, he hecho la prueba; no hay final feliz salvo que alguien localice al autor.
Es probable que estuviese en la cinta original y que en la redacción de MH lo omitiesen por pensar que se trataba de otra cosa (el juego ya había cargado), máxime si vino con instrucciones mínimas. Me resultaría raro que faltase de origen, pues el resto es perfectamente funcional.
Por lo menos ahora tengo el mapa e instrucciones, y sé que es jugable y terminable, pese a no tener un menú o cierre.
Otro final agridulce.
Los píxeles cuadrados son un lujo moderno. Los microordenadores antiguos sacaban una imagen analógica como buenamente podían, y el resultado eran píxeles no del todo cuadrados.
Empecemos por analizar la señal de vídeo PAL.
En vertical tenemos 625 filas, es decir, 312,5 por campo o 312 a secas si usamos un modo progresivo que es el caso que nos interesa, con lo que pasamos de 50 Hz a 50,08. En cualquier caso, tenemos 576 filas visibles (18,4 ms), unas 288 por campo y ese es el valor que nos interesa.
En horizontal tenemos una zona de sincronismos de 12,05 us (1,65 porche A, 4,7 sincronismo y 5,7 porche B) y una zona visible de 51,95 us. De nuevo, ese es el valor que nos interesa.
Los ordenadores de los que hablamos no aprovechan al completo la zona visible, sino que ocupan una zona activa centrada y dejan una el resto como overscan (borde) por seguridad y por simplificar hasta rellenar la visible. Esto no nos va a afectar pues vamos a analizar las frecuencias del reloj de píxeles, pero bueno es saberlo.
Sabiendo que la pantalla CRT clásica tiene una relación 4:3, entonces las cuentas son fáciles. Asumimos cada fila de igual alto con lo que tenemos 4/3*288=384 píxeles visibles en horizontal en cada una. Si ahora dividimos por el tiempo que pasamos en su zona visible (los 51,95 us) nos salen unos 7,3917… Mhz en nuestra zona visible.
Comparemos ahora algunos ordenadores y sus relojes:
Un caso interesante es el de los Spectrum 128: tienen un reloj de 2*3,5469=7,0938, con lo que tenemos un error del 4,03%. Aunque no nos influye para esto, el tiempo horizontal total son 456 px totales en vez de los 454 teóricos (228 ciclos del Z80 vs 227) que debieran ser; a cambio, sacan una fila menos (311 totales vs 312) para compensar.
Todos estos errores son relativamente pequeños, y en los emuladores se suele "arreglar" el tamaño final escogiendo la zona visible que convenga (bordes distintos a los originales para encajar en el aspecto deseado).
Mención especial a la burrada de hacer píxeles cuadrados en el modo VGA 320x200 (400 doblados vs 480 doblados nativos) que comete un error de 16,7%, claramente visible. ¿Por qué DOSBox o ScummVM no aplican el reescalado por defecto y hay que modificar la configuración? Todos los juegos se ven terribles por defecto, causando sangrado de ojos.
Y hablando de burradas, otra es ajustar el aspecto de la imagen a la del monitor en vez de mantenerlo (4:3 en 16:9 se ve un 25% más ancho, causando ya daños cerebrales).
En conclusión: aparte de haber compartido este TOC mío, si todo el mundo tuviese pantallas con muchos DPI se podría hacer un buen reescalado (y buenos efectos CRT) que mantenga el aspecto sin perder definición, pero supongo que de momento no es el caso.
Algún día tenía que llegar este momento; por fin me he decidido a portar un juego desde Spectrum al PCW, con lo que ahora debiera resultarme más fácil el volver a hacerlo.
Las diferencias entre sus arquitecturas son múltiples: diferente velocidad, sistema de contención, vídeo, matriz de teclado, mapa de memoria, frecuencia de interrupciones, altavoz en vez de zumbador, etc. Y todo eso son inconvenientes.
Pero también hay ventajas si nos lo trabajamos: partimos de pixeles cuadrados siempre (no tengo por qué buscar juegos en modo 1), modo fijo 256x192 (con lo que podemos usar siempre el modo reducido), ROM en el marco inferior (16KB de gratis para mis cosas), memoria de vídeo en posición fija (de nuevo, espacio gratis), se puede reproducir el audio por el zumbador interno del PCW (con alguna restricción), mucho monocromo gracias a los atributos (sprites o directamente la pantalla), su catálogo de exclusivos, etc.
Así que allá vamos.
Análisis:
Mirando juegos, me decido por el Movie. Ya había estudiado su versión de CPC para portarla, pero comparando con la original para localizar ciertas rutinas me decido a portar la de Spectrum como experimento.
Es una aventura isométrica interesante, con objetos, personajes, iconos de acciones y elementos conversacionales. En su día no lo tuve, pero fue uno de los primeros juegos en probar en cuanto tuve acceso a internet.
Crea en general una atmósfera bastante inmersiva. La programación es buena, la isométrica bien resuelta, el volcado de los sprites es similar a como lo hace la Abadía.
Infraestructura:
La mayor parte de mi infraestructura habitual se conserva, el mayor cambio es que utilizo mi emulador de Spectrum en vez del de CPC. Al estar mucho más pulido, puedo poner puntos de ruptura en accesos a la ULA o la memoria de vídeo, y localizar así las rutinas que necesitan parche de forma automática, medir ciclos de rutinas, veces ejecutadas, desde dónde, ...
El resto sigue siendo lo mismo, quizás mencionar que desde hace varios ports utilizo la habilidad del emulador de cargar binarios en memoria y ejecutar arbitrariamente desde línea de comandos. Con eso y mis ficheros BAT puedo probar las cosas inmediatamente sin tener que crear imágenes de disco ni cargadores.
Cargador:
No hay mucho que contar por aquí, utilizo mi cargador típico. Por cacharrear, le meto un par de efectos básicos basados en la Roller RAM con la pantalla de carga, la cual tengo comprimida dentro del propio cargador.
Frecuencia / contención:
En un Spectrum el Z80 va a unos 3,5 Mhz (3,5469 en los modelos de 128 KB), con ciclos de espera en la RAM controlada por la ULA (dos ciclos seguidos libres de cada 8, pero sólo cuando está pintando la pantalla, si no nada). La contención es por CLOCK en vez de WAIT en los modelos clásicos.
El PCW lo hace a 4 Mhz, con ciclos de espera (WAIT) en cualquier acceso a memoria (uno libre de cada cuatro); esto tiende a alinear los ciclos máquina a múltiplos de 4 ciclos de reloj.
Es difícil evaluar cuánto se pierde exactamente al desdoblar gráficos (el resto son más o menos los mismos ciclos) porque son sistemas muy distintos. No queda mal, es muy jugable, pero hago algún retoque menor para compensar.
Memoria:
Afortunadamente el PCW tiene un sistema de paginado muy potente, y nos permite comportarse casi como cualquier ordenador de la época basado en Z80. Podemos poner cualquier página de RAM en cualquier marco, así como escoger de forma separada las páginas en las que se lee y escribe en cada marco. Con esto podemos tener rutinas sobre memoria de vídeo o cosas igual de bizarras.
Originalmente tenía en escritura la VRAM del PCW y mis rutinas y teclado en lectura en la zona de la ROM ($83/$34, $80, $81, $82), pero una vez se parchearon todas las rutinas necesarias las nuevas se movieron a la zona de VRAM del ZX. De esa forma tenemos VRAM + teclado en la zona de ROM ($83, $80, $81, $82) y nos simplifica la lógica para tener código automodificable. Nos entra el juego entero + parches en 48 KB.
Acceso a ROM / FW:
Ya que la ROM del Spectrum está siempre paginada algunos juegos hacen uso de esta; y en este caso es así, aunque muy ligero.
Básicamente se usa para la lectura del teclado (escribir texto en los bocadillos y las teclas del “menú”) y cálculo de direcciones de vídeo. En ambos casos, basta con redireccionar a mis propias rutinas.
Por otro lado, hay un acceso insistente (y un tanto camuflado) al punto de entrada de la rutina de carga, entiendo que como medida de protección contra algún tipo de transfer. De nuevo, fácil arreglo.
Finalmente, se usa de nuevo en una rutina para generar aleatorios que se usan para el efecto de los pasos, por ejemplo. Al no ser aleatorios críticos (eso se hace en otra rutina), hago que mire en las 16KB superiores, donde hay más variedad de valores y el efecto es prácticamente el mismo.
Interrupciones:
Otro punto en el que se difiere; el Spectrum genera una interrupción al inicio del vídeo, mientras que el PCW tiene 6 a lo largo de cada frame PAL. Un arreglo simple sería comprobar VSYNC y si es el caso continuar el código.
Aunque en este juego no hace falta nada de esto; curiosamente, no usa las interrupciones para nada. Esto tiene sus cosas malas, como veremos cuando hablemos del teclado; por el lado positivo, tiene rutinas optimizadas que usan los registros SP e I a pelo.
Sonido:
Aunque pueda parecer que ambas máquinas son similares en este aspecto (“1b de audio”), eso no es del todo así. El Spectrum controla directamente un altavoz, mientras que el PCW tiene un zumbador (suena automáticamente a una cierta frecuencia).
Se puede encender y apagar el zumbador y el resultado es casi el mismo mientras que las frecuencias sean mayores que la del zumbador; si son menores se nos apagará y encenderá entre medias, causando una distorsión claramente audible (los que hayan escuchado la melodía del Bat-Man saben de lo que hablo).
Otro problema es que el oído detecta únicamente cambios de presión, le da igual el estado de la membrana del altavoz (encendido o apagado). Sin embargo, no puedo dejar encendido el zumbador pues seguiría sonando, algo que pasa en este juego.
Finalmente hay que aclarar que, aunque no es el caso de este juego, en un Spectrum normalmente se usa EAR para reproducir audio, pero también puede usarse MIC… ¡y ambos a la vez! Lo cual nos da una especie de 2 bits de audio, pues MIC suena más bajo que EAR.
En algunos modelos / clones esto no se lleva muy bien. Por ejemplo, en un Inves+ que los combina con XOR no hay audio en la carga, o en un Leningrad que no tiene audio por MIC se pierde la voz sintetizada del Cobra’s Arc, por ejemplo.
En cuanto a las temporizaciones, al no usar música no son críticas, así que las dejo tal cual. Si el juego hiciese uso del AY, algo que de nuevo no es el caso, hubiese sido necesario convertir las frecuencias de los osciladores (1,7735 -> 1,0 Mhz).
Vídeo:
En esta sección tampoco hay mucho que contar; uso el típico modo solapado 512x192 + fila en blanco en la página 3 para tener además el teclado, y ajuste vertical por Roller. Lo mapeo en la zona de ROM donde no estorba.
Las rutinas que acceden a la pantalla son pocas en este caso, afortunadamente. Anulo todo lo que tenga que ver con los atributos y desdoblo los gráficos al vuelo con mis rutinas. Para indicar que ocurre algo en los modos de pausa y abortar (que requieren otra pulsación para volver al juego o confirmar la salida) invierto el vídeo en el PCW.
Teclado / entradas:
Ambas matrices de teclas son completamente distintas, así que básicamente uso mis rutinas y luego tablas para convertir.
Aprovecho y le cambio las teclas raras que tiene por defecto a un clásico Q-A-O-P-Espacio, con opción de cursores. También se puede utilizar el joystick Kempston y el DkTronics.
Internamente, los controles se codifican en un byte, así que una tabla para cada caso menos el base (Kempston) y listo.
El teclado se lee en varios puntos dentro del bucle principal del juego, no por interrupciones, ya que no se usan. Esto hace que en ocasiones los controles no vayan muy finos cuando hay bastante carga de CPU. Es algo que ocurre en todas las versiones.
Fin:
Con esto llegamos al final; tenemos una versión para PCW clásico y la experiencia de portar juegos directamente desde Spectrum.
Como corolario de todo lo anterior: en este caso nos funcionan los POKEs de Spectrum en vez de los de CPC.
En algún momento tenía que dar el paso y hacer algo de software para PcW16; aprovechando las vacaciones y que tenía relativamente fresco el port del Knight Lore a PCW me pareció el momento adecuado. Es una máquina bastante más puñetera, pero bastante más potente.
Análisis:
Utilizando de nuevo como base la versión de CPC, el Knight Lore entra en 48 KB + 16 KB de memoria de vídeo, mucho más fácil para empezar que la Abadía o el Hero Quest.
Desgraciadamente, el PcW16 no tiene un modo de paginado que separe lecturas de escrituras (modo ANT), lo cual complica el parcheo: en el caso de PCW pongo en lectura una página sobre la de escritura de vídeo, dándome 16 KB extras para mis parches y tablas para acelerar, cargador, roller, etc.
Otra complicación es el teclado; al contrario que la mayoría de ordenadores de 8 bits no se leen las filas / semifilas en ciertos puertos / rangos de memoria, sino que funciona como un PC (una especie de puerto serie e interrupciones).
Por el lado positivo, el vídeo es más normal. De hecho, puedo colocarlo de la misma forma que en un CPC, con entrelazado y desperdicio de memoria incluido. Sin embargo, manteniéndolo sin entrelazar y seguido me simplifica las rutinas de volcado y me deja espacio para meter algunas de mis cosas al final.
Entorno:
Para hacer pruebas rápidas es muy cómodo usar las opciones -Y y -@ del emulador, para colocar los datos / código que quiera en la memoria y definir el mapeo y punto de entrada respectivamente. De esta forma puedo probar sin tener que hacer imágenes de disco ni crear un cargador, y puenteo completamente el sistema operativo (no hay que esperar que arranque, seleccionar la opción de ejecutar programa externo, etc.).
El resto sigue siendo similar a mi entorno de desarrollo habitual para PCW: Notepad++, Pasmo y ficheros .bat para automatizar todo. Al tener que trabajar con discos con sistema FAT añado mtools a la lista de aplicaciones.
Memoria:
Primero vamos a reservamos las 64 KB que necesitamos. No es necesario que sean contiguas, y sólo es necesario que la de vídeo esté por debajo de las primeras 256 KB. Aun así, las elijo consecutivas 4-5-6-7, y uso la 3 para el cargador, la roller (no puede estar en otro sitio en el PcW16) y los parches que no me entren en la zona principal.
Al igual que el port de PCW, la sitúo en el marco $C000-$FFFF, en el mismo sitio que la memoria de vídeo. Afortunadamente, las rutinas de vídeo parcheadas nos entran en la memoria principal en este caso, con lo que no hay problema. Al contrario que en PCW, nos toca paginar y despaginar cada vez que se llame a una de dichas rutinas, con especial cuidado de las interrupciones (que a su vez llaman a rutinas de esa área).
Video:
Lo más fácil de todo, al contrario que en PCW: en la roller podemos escoger dónde comienza cada fila de vídeo, con una granularidad de 16 bytes. Y en cada palabra de la misma tenemos además 2 bits para indicar el modo de vídeo de dicha fila.
Una curiosidad del PcW16 es que tiene los modos de video del CPC. Normalmente está en “modo 2”, pero con más del doble de filas (imagen “casi” VGA progresiva, 640x480). En este caso, usamos el modo 1 para tener 320 en horizontal con 4 colores.
Como ya he contado, la memoria va seguida y sin entrelazar. Además, las filas están dobladas (tenemos 480 en vez de 192) y con la misma vacía arriba y abajo repetida para hacer de borde en las 80 restantes.
El formato de pixeles no es el mismo que en el caso del CPC, pero es el mismo que en el caso del PCW y PCW en color, así que trabajo de conversión ahorrado.
Paleta:
Además de los modos de vídeo, también tiene el mismo sistema de paleta triestado, para un total de 27 colores distintos (aunque con diferentes valores). Sin embargo, en un PcW16 sin modear conecta sólo la componente verde al monitor monocromo, con lo cual sólo tenemos 3 tonos de gris.
No es un problema, pues en el port de PCW ya lo tuve en cuenta para el parcheo en modo mono; al fin y al cabo, un patrón %10101010 se ve igual que uno %01010101 en el monitor monocromo, pese a ser “4 pixeles de colores distintos”. Aprovechamos esa parte y es aún más sencillo, pues no hay que modificar tablas y se puede hacer directamente con la paleta, haciendo que el color 2 sea igual al 3 para que tenga más contraste en el área de juego.
Sonido:
En este caso, aprovecho la interfaz AY por el puerto paralelo para PcW16 que hice y que además tengo implementada en el emulador. A ver si saco un rato para hacer placas como Dios manda de la misma. Hereda la interfaz de joystick y DAC de la versión para PCW.
Básicamente, se usan los 8 bits de datos del puerto de forma bidireccional junto con otras 3 señales para control (lectura / escritura, datos / latch, acceso). Pero las rutinas son prácticamente las mismas.
Aprovechando que tengo que regular la velocidad del juego hago que suene el tempo de la música como en el Spectrum, un poco más despacio que en CPC (la cual me parece bastante atropellada).
Velocidad:
El PcW16 tiene un núcleo Z80 de NEC integrado en su ASIC, funcionando a unos 16 Mhz y con una contención más relajada que el CPC, lo que hace que sea aproximadamente unas 4 veces más rápido. Esto significa que el juego sin compensar es demasiado rápido.
En vez de compensar con una pausa fija en cada “fotograma” del juego, aprovechamos el sistema de compensación de velocidad por sprites no dibujados del propio juego, calibrándolo. De esta forma, logramos una velocidad casi constante independientemente de la carga gráfica. Es algo muy sencillo de implementar en este caso, pero requiere conocer el funcionamiento interno del juego.
Interrupciones:
Aquí empezamos a meternos en temas escabrosos. El PcW16 tiene en parte una arquitectura de PC; en concreto, tiene un SuperIO como los que se ponían en placas de la época. Todos sus IRQs se enrutan al ASIC, el cual genera una interrupción del Z80 en el momento que exista alguna, sea interna (video, teclado) o externa (serie 1 y 2, paralelo, disco, IDE / externo).
Afortunadamente, las externas pueden deshabilitarse (mayormente) en el SuperIO por separado, pero la existencia de la interrupción de teclado nos obliga a cambiar la lógica del gestor del juego. Además, la frecuencia de las de vídeo es de 3 por fotograma (60 Hz) en vez de 6 por fotograma (50 Hz).
Ya que comprobamos más de una cosa en el gestor, comprobamos además el botón de encendido del PcW16; si se pulsa, hacemos un warm start (además hemos conservado la página 0 de RAM), volviendo al SO.
Teclado:
Cada vez que hay al menos una tecla en el buffer del teclado, ésta se envía vía protocolo PS/2 al ASIC, dentro del cual hay un registro de desplazamiento. Cuando se recibe un byte, se genera la interrupción correspondiente y debe ser leído. Para perder la menor cantidad de tiempo, se almacena en una tabla de pulsaciones por código de tecla.
Una vez se llama a la rutina que lee las semifilas, se llama a un parche que traduce a scancodes set 2 de PC, lee las teclas correspondientes y conforma el byte. Además, si la semifila corresponde al joystick hace la lectura correspondiente del AY (a través del puerto paralelo como vimos).
Mandar de vuelta datos al teclado es un jaleo importante en el caso del PcW16, pero afortunadamente no es algo que vayamos a hacer en este juego.
Por último, y al igual que en la versión de PCW, le añado los cursores (es cómodo jugar con ellos) y el espacio como teclas de control.
Cargador:
Finalmente, con todo funcionando, hay que hacer un cargador para que el juego cargue de forma externa desde un disco. En contra de lo que alguna gente piensa, el PcW16 es capaz de ejecutar programas de forma externa.
Basta crear un fichero de hasta 16KB con extensión PRG que se carga en $4000 y ejecuta en $4100. Esos primeros bytes pueden contener lo que se quiera, pero serán machacados en memoria en el caso de la carga desde disco.
Básicamente, se reserva memoria, se cargan los datos y se muestra un diálogo para escoger monocromo o color (con el mod correspondiente, y apagando la pantalla integrada). A partir de ahí se toma el control, anula las interrupciones que genera el ratón, se pone todo en su sitio, y lanza el juego.
Fin:
Quedan cosas menores que no merece la pena casi ni mencionar, como la anulación del flag de interrupciones, saltar la inicialización de las tablas (las pongo directamente y no cambian; además, así ganamos el espacio de esa rutina para parches), las optimizaciones que hice para PCW (como la reflexión con tablas), etc.
Otra cosa que he tenido en cuenta a la hora de generar el fichero .dsk ha sido el crearle un interleave 2:1, que acelera la carga casi 10 veces. No entiendo como los discos formateados en la propia máquina no tienen esto en cuenta.
En cualquier caso, espero que disfrutéis este juego, posiblemente el primero nativo para PcW16.
Feliz año nuevo, felices fiestas, y cosas de esas.
Últimamente he estado liado con la emulación del PcW16. Hace tiempo saqué una versión muy alfa de su emulador, basada en la que tenía por aquel entonces del emulador de PCW.
Como este último ha avanzado mucho desde entonces me he decidido a empezar de nuevo, tomando como base de nuevo el actual. Prácticamente está listo, a falta de evaluar si merece la pena implementarle un mapeo de directorio o no, así que es posible que publique una beta decente en breve.
Quizás le cambie el icono. Quizás.
Pero el caso es que depurando el emulador he tenido que analizar parte del código del sistema operativo, y ahí he vuelto a ver el "mensaje" que está almacenado cerca del principio de la Flash del PcW16, dentro de las primeras 64 KB (bloque de arranque, protegido por seguridad):
Y el caso es que su desplazamiento está incluido en la tabla de saltos del propio sistema de arranque:
Siempre he sospechado que era un huevo de pascua, visible desde algún lugar del sistema operativo bajo las circunstancias oportunas. Pues bien, estas sospechas se han confirmado hoy:
Más claro, agua; así que vamos a investigarlo.
- 0 -
Lo primero es localizar el lugar donde se hace referencia a esto último; dado el funcionamiento del SO lo más probable es que se encuentre en la misma página (16 KB), la número 4 de la Flash (página dedicada al puerto paralelo en general, al LocoLink y la impresión en particular).
Desensamblando a mano donde parece haber código y haciendo referencias cruzadas encontramos la rutina que imprime el diálogo propiamente dicho, junto con otra la cual es la única rutina que llama a la anterior. Y esa rutina es en sí misma la del huevo de pascua, con sonido inicial incorporado.
Desgraciadamente, aquí se pierde la pista: nadie la llama en dicha página.
- O -
Una particularidad del Z80 es que tanto los saltos "lejanos" como las llamadas a subrutinas son absolutas; y además ocurre que el API de llamadas "largas" (24 bits) de este SO también lo es, como es lógico.
Así pues, vamos a hacer una búsqueda binaria con dicha dirección:
Y bingo; porque justo por delante tenemos el código de un RST $30 (FarCall) y por detrás la página en la que se halla, con lo que en efecto se confirma que hay llamada desde ahí.
Toca desensamblar por tanto la página 9: el escritorio, rutinas en coma flotante y sistema de ayuda. Y justamente en ese último lugar encontramos la llamada.
Tirando hacia arriba, vemos que se llama desde la página de ayuda cada vez que se pulsa una tecla, y que los hace coincidir con una lista de caracteres “encriptada” (dan igual mayúsculas y minúsculas). Y así obtenemos la contraseña, que por otro lado era bastante obvia: "Anne Team". Sin comillas y con el espacio, dan igual mayúsculas o minúsculas.
- ∅ -
Lo único que nos resta es arrancar el PcW16, irnos a la ayuda, y teclear dicha contraseña:
Todos los secretos serán revelados.
Hace tiempo jugué a un videojuego muy interesante llamado "Moirai". Era indie, gratuito, completable en menos de 10 minutos. Quizás su aspecto visual, de Doom venido a menos, pudiese echar para atrás a más de uno. Pero el juego brillaba de otras maneras; su atmósfera, su efecto cadena (¿experimento social?) para con los jugadores, las decisiones moralmente cuestionables. No voy a aclarar más al respecto porque odio los spoilers.
Recientemente he estado probado la beta del cliente de Steam, y ahora en mi biblioteca puedo ver todos los juegos a los que he jugado, los haya comprado o no. Y entre ellos vi el Moirai. Pero cuando fui a darle un tiento de nuevo me encontré con lo siguiente:
El juego ya no existe. Ataques a la BBDD llevaron a terminar su existencia hace algún tiempo. Y me sentí mal, me hubiese gustado jugarlo una vez más.
Así que me propuse hacerlo, aunque fuese de mala manera.
Primero busqué la versión original, por si la de Steam estuviese capada con el cartelito. Al ser ejecutada, el mensaje fue, afortunadamente, distinto:
Bien. Ahora es cuando desensamblamos, y miramos desde dónde se llaman a las funciones de libmysql: hay 3 procedimientos, para emparejar, enviar respuestas, etc.
Y también hay un par de comprobaciones con ciertas constantes, aparentemente para depurar. Una de ellas hace que en vez de usar la BBDD en el sitio del autor (la cual estaba desprotegida, y con el usuario y contraseña dentro del ejecutable sin encriptar; no me extraña que les petasen la BBDD) se use una BBDD local con parámetros por defecto (localhost / root / root).
La otra es más interesante: se salta todas las consultas y proporciona valores a huevo. Cambiando dicha constante, el juego vuelve a ser jugable sin necesidad de volver a montar una BBDD local o modificar la ruta de la de internet.
Sólo tiene un inconveniente (esta imagen no tendrá mucho sentido para quienes no lo hayan jugado):
No creo que a nadie le interese, pero por si acaso:
Supongo que más vale una victoria agridulce que una derrota amarga.
We're gonna celebrate...