Portando código preexistente de MSX
Valoración de usuario: / 7
PeorMejor 
Sábado, 11 de Octubre de 2008 05:30

Esta sección no pretende ser una guía exhaustiva sobre cómo portar aplicaciones desde el entorno MSX al Spectrum. De todas formas, el código usado puede servir como punto de partida para portar proyectos más grandes. Todo el código fuente descrito aquí está disponible en la página web del autor sobre este proyecto, así como videos con el software descrito en acción.

English version is in progress. In the meanwhile, please use this Google automated translation version. It may be a little odd to read, but at least, you will get an idea of what's going on, if you can't read spanish.

Aunque esta interface use los mismos puertos que el MSX emplea para comunicarse con su chip de video, por lo general y salvando contadísimas excepciones, no se podrá ejecutar directamente código compilado en una plataforma MSX en el Spectrum. Si no se tiene el código fuente de la aplicación, será necesario parchear el binario para desviar las llamadas a la BIOS del MSX, hacia rutinas que hagan las mismas tareas en el Spectrum.

Sin embargo, si se dispone del código fuente, y la aplicación no requiere de los servicios de disco del MSX u otros aparte del teclado, el joystick, el PSG y el video, la tarea es casi siempre muy sencilla.

Para ayudar en la tarea, existe un proyecto denominado C-BIOS, de código abierto, que provee de una implementación de la BIOS del MSX, incluyendo el código fuente en ensamblador del Z80A. Esta BIOS puede ser estudiada, y las rutinas que necesite nuestra aplicación podrán ser añadidas a la misma, sustityendo los CALL's a direcciones absolutas de la ROM a CALL's a las direcciones equivalentes proporcionadas por las rutinas que se añadan.

Sprites y entrada de datos

Así, para la primera demostración realmente útil de la interface de video, hemos tomado el código fuente de un pequeño juego-demo, Snowclimber, de Vincent Van Dam, para la prueba MRC Challenge "Snowfall" de Msx.org. Este juego tiene una estructura muy simple, y además aglutina en un único fichero "crumbs.asm" todas las dependencias de la BIOS (rutinas y variables del sistema usadas). Por si fuera poco, es un ejemplo estupendo para probar qué tal funcionan los sprites hardware del MSX. En la pantalla de juego, cada copo de nieve es un sprite, así como los dos pingüinitos protagonistas del juego.

Para que funcione en el Spectrum, lo que se ha hecho es añadir al conjunto de ficheros de ensamblador otro más, "bios.asm" que contiene todas las rutinas de la BIOS que este juego necesita tomadas del proyecto C-BIOS: inicialización de la pantalla en modo SCREEN y, borrado de la pantalla. Para la lectura de teclado y joystick se ha reescrito desde cero, al manejarse de forma diferente en ambas arquitecturas. MSX "conoce" tres controladores de juego: los cursores del teclado, y los dos puertos de joystick. En la implementación escrita en el fichero "bios.asm", se han sustituido los cursores por las teclas QAOP y SPACE para el disparo, y los dos joysticks corresponden a los dos puertos del Interface II.

Respecto a las variables del sistema, el MSX las aloja en los últimos bytes de memoria física, así que hemos decidido no cambiarlos de lugar. La definción de dichas variables se encuentra en los ficheros "systemvars.asm" y "hooks.asm". La implementación incluye los 2048 bytes con la definición original del set de caracteres del MSX, que se cargan en el TMS al ejecutarse la rutina que cambia el modo de pantalla.

El bucle de juego se realiza en la rutina de interrupciones, dentro de "game.asm" y ésta es de hecho la única parte del código fuente original que ha tenido que ser retocada, para implementar el sistema de manejo de interrupciones descrito en este mismo artículo.

Una vez cargado el juego (con LOAD "", como siempre), la pantalla original del Spectrum no registra ningún cambio: toda la acción se desenvuelve en el nuevo chip de video. Se muestra una pantalla de presentación que invita al jugador a pulsar FIRE (barra espaciadora si se usa el teclado).

El juego es para dos jugadores, que están al pie de una colina. El objetivo de cada uno es trepar por la colina hasta llegar a la cima, mientras cae una nevada. Pero ¡cuidado! Porque si el viento arrecia, los jugadores resbalarán colina abajo, a no ser que lo eviten agachándose para evitar la ventisca. Gana el primer jugador que llega a la cima.

!!WARN_FL!!

Un Spectrum 48K+ con el adaptador de teclado PS/2 interno instalado, y la interface de video MSX. La señal de video de la ULA se muestra en una pequeña TV en blanco y negro. La señal de video (en este ejemplo, también blanco y negro) proveniente de la interface de video se muestra en otra TV portátil LCD. Se usa un teclado PS/2 enrollable para manejar el Spectrum. El juego no tiene sonido.

Como curiosidad, nótese que los caracteres que forman los mensajes del juego no usan el set de caracteres original de MSX, sino que se ha recompilado para que use la fuente de letras estándar de Spectrum. El juego al iniciar la pantalla, rediseña la fuente de caracteres para que aparezca en negrita. Si se observa una captura de pantalla del juego original (ver enlaces) notará que falta una línea horizontal justo debajo de los títulos PLAYER 1 y PLAYER 2. Esto es porque esa línea está formada por un carácter que en la fuente del MSX es una línea horizontal, pero que no existe en el juego de caracteres del Spectrum. En las capturas de pantalla a continuación, podrá observar las diferencias. En ambos casos, el juego se está ejecutando en un Spectrum con la interface de video: la diferencia es que en un caso se ha incluido en el ejecutable la definición de los caracteres originales del MSX, y en el otro, se usa el set estándar del Spectrum.

Pantalla de presentación de Snowclimber, usando la fuente del Spectrum (el programa la modifica para que aparezca en negrita)

La misma pantalla, pero esta vez incorporando al programa la definición de los caracteres del MSX tomados de un volcado de la ROM de un MSX real.

Pantalla con el escenario de juego. El marcador para cada jugador aparece en la primera línea de texto. Usando el set de caracteres del Spectrum, la línea que separa los marcadores del resto del escenario no existe.

La misma pantalla, pero usando el set de caracteres del MSX. Cada copo de nieve es un pequeño sprite de 8x8. Dado que cada pingüino necesita 4 sprites en su definición, esto nos deja con un máximo de 24 copos de nieve en la pantalla.

A todo color

Uno de los atractivos de usar este chip es la posibilidad de tener más variedad de color, en lugar de la limitación de dos colores por cada bloque de 8x8 píxeles. La siguiente demostración llegó de la mano de "decicoder", quien ha estado trabajando en ultracargas para MSX. Tenía una de ellas, pero en formato "cargable" por un Spectrum, aunque, claro, al ejecutar el código, no pasaba nada "excepto rayas en el borde durante un instante" según me contó. Esas rayas no son más que la ráfaga de escrituras al puerto 152 para escribir valores en VRAM; recordemos que en un Spectrum sin esta interface, el puerto 152 activa a la ULA como si fuera el puerto 254.

Decicoder me proporcionó un fichero TAP con la carga de la pantalla, es decir, todo ya compilado, en binario. En esta demo, el bloque ejecutable comienza en la dirección 40600, que fue el que supongo, fijaría este hombre. El único CALL que al parecer hay, está precisamente en esta posición de memoria, y llama a la rutina "inigrp" de la BIOS del MSX, que inicializa el modo SCREEN 2 del MSX. El porte de esta rutina a Spectrum consistió en el siguiente código fuente ensamblador, que simplemente parchea el argumento de ese CALL para que llame a nuestra versión de "initgrp", y seguidamente, le cede el control al programa original. Este por tanto, es el primer ejemplo de programa que casi casi funciona sin cambios en Spectrum y MSX:

          org 40600
                        
          ;incluimos el bloque de decicoder en su posicion original.
          incbin "pantallamsx.bin"

Main      proc
          call msx_on      ; primera inicializacion del TMS
          ld hl,inigrp       ; Se pokea la direccion de la rutina
          ld (40601),hl      ; inigrp en la posicion 40601 (justo
                               ; a continuación del código de CALL)
          call 40600           ; saltamos a ejecutar el bloque
          call msx_off      ; Volvemos al entorno "Spectrum"
          endp
                        
          include "bios.asm" ; definición de las rutinas BIOS-MSX usadas
                       
          end Main

El resultado, visto a través de una VGA-Box, es éste:

Fotografía tomada a un monitor VGA mostrando la pantalla de carga del Game Over II, desde el Spectrum con la interface de video, conectada a una VGA-Box de Farmer.

A modo de curiosidad, se incluye la captura de pantalla generada en esta misma interface, pero con el TMS9918A, con salida en video compuesto NTSC. La captura se ha realizado mediante una tarjeta de captura de video para PC basada en el popular BT878, más la aplicación Dscaler. La distorsión cromática es evidente, incluso después de haber hecho un ajuste fino a la frecuencia del oscilador.

!!WARN_FL!!

Pantalla de carga del Game Over II, proporcionada por Decicoder. En esta ocasión se han usado las tres salidas de video (video por componentes) que se ha convertido a una señal VGA mediante un adaptador de Farmer. El resultado se muestra en el monitor TFT de la izquierda, mientras la pequeña pantalla de TV balnco y negro sigue mostrando la imagen original del Spectrum.

Añadiendo sonido.

A estas alturas, más de uno habrá recordado que el Spectrum y el MSX en realidad comparten un periférico: el chip de sonido (PSG) que en ambos es un AY-3-8910 (en realidad, es un 8912 para el Spectrum, y un 8910 para el MSX, pero esto no influye en las capacidades sonoras de ambos micros). Un prototipo anterior al presentado incluyó un AY-3-8910 en los mismos puertos que se usan en el MSX: A0h, A1h y A2h, con la idea de poder usarlo en un Spectrum 48K, que no tiene chip de sonido. Sin embargo, para el prototipo final se decidió suprimirlo para no hacer la placa más grande y complicar el rutado, que debe hacerse manualmente si se quiere minimizar el número de vías y asegurarse de que todos los pads de los circuitos integrados DIP caigan en la cara de pistas. No obstante, la GAL mantiene en su programación original la parte que decodifica estos puertos y genera las señales apropiadas para el PSG.

Así, la próxima aplicación de esta sección es una mini-demo, "Farting Fish", presentada para uno de los MRC Challenge: "Under water", en Msx.org, y que incluye música a través del AY-3-8910. Su autor, Jussi Pitkanen suministra el código fuente.

Esta demo, a diferencia de los ejemplos anteriores, no usa llamadas a la BIOS, por lo que en el porte a Spectrum no ha hecho falta incluir "bios.asm".

Las modificaciones han consistido en reescribir una macro que lee el teclado, reescribir la rutina que asigna un nuevo gestor de interrupciones, y por supuesto, cambiar las referencias a los puertos A0h y A1h en el fichero "player.asm" por los correspondientes puertos en el ZX Spectrum 128K: FFFDh y BFFDh respectivamente.

La máquina usada para ejecutar la demo es un ZX Spectrum 128K modelo "heatsink". Previamente se aplicó la modificación descrita en este artículo, para habilitar IORQGE en el bus trasero. La demo se ejecutó en el modo de 48K. En este modo, el AY-8912 sigue estando disponible, pero la paginación se bloquea. Si hubiera implementado al 100% la modificación que sugiere Yarek para habilitar IORQGE, no habría hecho falta este detalle, pero en mi caso, sólo usé un transistor, para deseleccionar la ULA, dejando intacta la lógica de selección de bancos de memoria.

Equipo de pruebas para todas las demos de este artículo.

Tiene tres partes: la primera, que presenta un efecto de barras de colores horizontales con un ciclo de color, asemejando el fondo marino, mientras unas burbujas, implementadas con sprites, van deambulando lentamente hacia arriba.

La segunda parte es un plasma usando el modo multicolor de 64x48 píxeles.

La tercera parte es un bitmap que presenta un pez sonriente (aunque por la emisión de burbujitas de su parte posterior habría que pensar que es un poco gamberrete). Un "sinuscroll" de burbujas atraviesa la pantalla de lado a lado. Dentro de cada burbuja hay una letra, y la ristra de burbujas va presentando al espectador los mensajes de "greetings" del autor a otros grupos.

Los dos últimos ejemplos muestran las capacidades de manejo de sprites del MSX, concretamente, la carácterística de "zoom". Son dos pequeños juegos en los que se ha recurrido a esta prestación del TMS para que los gráficos destaquen más en pantalla.

El primero de ellos es To Be Slender ("Estar en forma"). Un juego con una mecánica parecida al "Dance Dance Revolution": tenemos que hacer mover un sprite "gordito" al ritmo de la música para que queme grasas. El programa hace sonar un ritmo con bombo y caja, y cada vez que se escucha el "¡pam!" de la caja, hay que mover al personaje usando alguna de las teclas de dirección. Pero hay que hacerlo de forma que no siempre se pulse la misma tecla, sino que hay que hacer algo de "coreografía". Si no se pulsa a tiempo, o no se sigue la coreografía, un marcador de fallos avanzará más y más hacia la izquierda, hasta que lleguemos a la marca OUT.

El juego tiene varios niveles, cada vez más difíciles. Su autor, "GW's-Workshop 2000", lo escribió para el "HispaMSX 4KB game programming contest", concurso que según él, nunca se llegó a celebrar. En una pequeña página web se exponen el juego listo para ser cargado en MSX, y el código fuente, gracias a lo cual se ha podido incorporar a la pequeña lista de títulos portados.

Dos instantáneas de juego de "To be slender". En la segunda, nuestro sprite gordito no puede más y se ha dado por vencido.

El último juego de este artículo es una entretenida versión del Pong, denominada XPong, escrita por José Luis Tur Santolaria. XPong ofrece como novedad sobre la versión original el aumento progresivo de dificultad en cada punto que se juega, acelerando la velocidad de la bola, pero no queda ahí: llega a tener más de una bola en juego para aumentar aún más este nivel de dificultad. Además, permite jugar entre dos jugadores, o sólo uno contra el ordenador.

La versión original del juego tiene sonido, pero el autor ha usado una llamada al parser del comando PLAY del BASIC del MSX. Esta parte de la BIOS no está incluida dentro de C-BIOS, con lo que, de momento, hemos tenido que dejar este porte a Spectrum sin sonido.

Pantalla de menú de XPong para elegir 1 ó 2 jugadores, e instantánea de juego con dos bolas a la vez en la pista.

José Luis es también el autor de "Caverns of Titan", un plataformas al estilo de Manic Miner, pero con todo el colorido y suavidad de movimientos propios del MSX. Su autor ha mostrado su interés en dejar accesible el código fuente de este juego, con lo que, muy seguramente, tendremos otro juego más portado a Spectrum.

 
ZX Projects, Powered by Joomla! and designed by SiteGround web hosting