De todos son bien conocidos los llamados “cutreports” venidos del ZX Spectrum. Nos referimos a ellos como aquellas conversiones de videojuegos directas del maravilloso ZX Spectrum al MSX hechas de una forma rápida, con bastantes errores y que no aprovechaban en absoluto las capacidades extra de la norma MSX.

Este tema siempre ha sido polémico debido a que muchos usuarios de MSX se sintieron de alguna manera “estafados o engañados” al no recibir productos de calidad. Pero nos guste o no, es parte de la historia de nuestro sistema y gracias a ellos pudimos acceder a títulos que ni por asomo serían llevados a nuestro ordenador (luego cada uno decidía si comprarlos o no).

Todo este tema es muy subjetivo y no quiero tratar los motivos, sensaciones, nivel de calidad que podrían haber tenido, etc. Solo voy a intentar explicar de una manera lo menos técnica posible cómo se hacían los “cutreports”. Después de haber buscado bastante tiempo por internet, me di cuenta de la poca información real que había sobre el tema, y después de haber hecho unos cuantos ports (que guardo solo para mí como pruebas de concepto), espero derramar un poco de luz sobre este tema, para despejar algunas falacias y pocas realidades sobre la “facilidad” de cómo hacerlos.

Primero señalar que desde mi punto de vista NO TODAS LAS CONVERSIONES a nuestro sistema MSX venidas desde ZX Spectrum son “cutreports”. Muchas de ellas fueron convertidas con un buen gramaje de calidad desde posiblemente el código fuente original o en su defecto, con soporte de los autores originales, como por ejemplo el Gauntlet para MSX (os aseguro que es un trabajo fino fino bajo el sello de USGold pero posiblemente convertido por Gremlin Graphics). Más títulos con cierta calidad de conversión podrían ser el Robocop de Ocean, por ejemplo. Estos juegos tuvieron reescritos de una buena cantidad de código, para que fuesen más fluidos o suaves, al menos.

Luego podríamos hablar de otro nivel de conversiones como por ejemplo las de algunos juegos de Dinamic, como el AbuSimbel Profanation o Camelot Warriors, que aparte de probablemente reescribir parte del código de manera específica para MSX, usaron alguna característica propia de este (como sprites por hardware).

Hasta aquí todo bien. Tengamos en cuenta que estas conversiones que he citado son muy particulares cada una, reestructurando parte del código de la misma manera que se podría adaptar a un MSX el traje hecho por un sastre, con mayor o menor éxito. Pero tenemos otras, los cutreports, que usaban una forma relativamente genérica de conversión, con la ventaja de que eran medianamente rápidas de hacer pero con resultados más que discutibles, como por ejemplo, Double Dragon o Alien Syndrome.

¿Cómo se realizaban estas conversiones? Bueno, naturalmente habría varias formas de hacerlas, pero los ingredientes del concepto general eran los siguientes:

  • Tener un conocimiento razonable de la arquitectura de un ZX Spectrum.
  • Tener un conocimiento bastante más que razonable de la arquitectura de un MSX.
  • Hacer totalmente accesible la RAM en el MSX y recolocar bloques de código original en la RAM del MSX.
  • Parchear distintos temas: sonido, teclado… y sobre todo la parte de video (¡aquí está la clave!)


Vamos a ir desgranando sin meternos en exceso, cada uno de los ingredientes: para simplificar, hablaremos del modelo más común y extendido de sir Clive Sinclair, el ZX Spectrum de 48 KB, los MSX de primera generación con 64 KB (Sony HitBit 10P por ejemplo) y juegos no multicarga.
Lo primero es preguntarse: ¿qué tenían en común el Spectrum y el MSX? Entre otras cosas, la misma CPU (Z80 de Zilog) a 3,5 MHz (aunque no tiene por qué ir exactamente a la misma velocidad la ejecución de código, debido a wait states extra en el MSX). Muchos modelos de MSX1 tenían una cantidad similar o mayor de RAM que un ZX Spectrum (48 KB en ZX Spectrum y 64 KB para muchos modelos de MSX1). Si nos metemos en ZX Spectrum +2, incluso compartían el mismo chip de sonido (PSG).
 

ARQUITECTURA DEL ZX SPECTRUM

Algo de arquitectura general sobre el ZX Spectrum para una conversión: el Z80 de Zilog tiene acceso a 65536 posiciones de memoria, sea ROM (solo escritura) o RAM (lectura y escritura), donde cada posición almacena un simple byte (valor numérico entre 0 y 255). Entre esas posiciones, un rango de ellas, los primeros 16384 bytes o posiciones (16 KB) está la ROM y el resto es RAM. Las posiciones de la ROM contienen rutinas que vienen de fábrica para ayudar a la ejecución de cualquier software (un juego por ejemplo) simplemente llamándolas. Esto ahorra que cada programa tenga que incluir rutinas comunes (por ejemplo acceso a teclado).




Es decir, que el juego que esté funcionando en un ZX Spectrum, ha sido cargado en la zona de RAM y se ayuda de las rutinas de la ROM (esto no es obligatorio, ¡algunos pasan olímpicamente de la ROM!). Ahora viene algo importante: desde la posición de RAM 16384 (en hexadecimal #4000) hasta 23295 (#5aff) todos los valores de allí serán interpretados por la ULA (chip encargado de la parte de video entre otros cometidos) como gráficos y sus colores en la pantalla. Quédate con esto.
 

ARQUITECTURA DEL MSX

Algo sobre el MSX1 de 64KB para una conversión: el MSX es más complejo debido a múltiples razones. Una de ellas es la cantidad diferente de fabricantes y modelos, siendo los modelos internamente distintos entre ellos (pero se supone que compatibles siguiendo ciertas normas). Los MSX tienen un sistema muy interesante de slots/subslots que en resumen, permite presentarle al Z80 (dentro de su rango de direccionamiento de 65535 posiciones de memoria), una combinación cambiante de ROM/RAM y más según convenga (chip de sonido SCC, por ejemplo). Configurando correctamente el sistema de slots/subslots podemos hacer que el Z80 vea solamente RAM en sus 64 KB de todo su rango de direcciones.




Un último detalle común al ZX Spectrum y MSX debido a utilizar la misma CPU, son los puertos de entrada/salida. El Z80 se puede comunicar con periféricos mediante sus 256 puertos de entrada/salida, que puedes inicialmente pensar que son 256 canales por los que se puede enviar o recoger información byte a byte de forma secuencial (o serie, uno tras otro, ¡no varios a la vez!). En la práctica, se usan solo unos pocos de estos en ambos sistemas.
 

LA RAM EN EL MSX

Obtener RAM en todo el rango de direcciones vistas por la CPU. Esto se puede hacer, como comenté anteriormente, posicionando adecuadamente el sistema de slots/subslots del MSX. Debido a que los modelos de MSX no son todos internamente idénticos, las rutinas destinadas a realizar este trabajo podrían no hacerlo correctamente, y es una de las razones principales por las que muchos ports no llegaban a funcionar en ciertos modelos de MSX.

PARCHEOS

En el caso de los cutreports, lo que se hacía era remendar, parchear o alterar de alguna manera (elige tú mismo el término) el código máquina original en ciertas partes. Veamos los principales parcheos:
 

RECOLOCACIÓN DEL CÓDIGO Y GRÁFICOS

Después de un análisis inicial del código y datos del juego a portar, se debería tomar la decisión de dónde se van a dejar todos estos recursos en la RAM del MSX.

LOS MODOS DE INTERRUPCIÓN

El Z80 tiene varios modos de interrupción y no me voy a extender con ellos. Básicamente, tenemos una interrupción cuando el programa que se está ejecutando se para durante un tiempo para ejecutar otro trozo de código que da servicio a esa interrupción, y luego continúa con lo que estaba antes de ser interrumpido. De tres tipos, dos principalmente son un tipo de interrupción que siempre salta a ejecutar la misma posición de direccionamiento, y otra que es programable donde lo va hacer. Esto hay que tenerlo en cuenta según el tipo de juego que se quiera portar, lo que implica que hay que hacer un análisis (desensamblado) mínimo del juego a portar.
 

SONIDO

Si es un juego de ZX +2, usa el mismo chip de sonido que el MSX (¡el famoso PSG!), así que básicamente sería cambiar las direcciones de los puertos de entrada/salida del PSG (puesto que son distintos en el ZX Spectrum), tanto para la música como para los efectos sonoros. Esto implica buscar estas llamadas dentro del código. Otra vez más análisis.
 

TECLADO / JOYSTICK

Los controles en general suelen ser accedidos mediante alguna rutina general que debería ser sustituida por una propia, que en la mayoría de los casos suele ser prácticamente la misma y reutilizada en gran cantidad de previos cutreports.
 

VIDEO

Como hemos visto anteriormente, el Spectrum “dibuja” en un área de su RAM accesible por la CPU, y de cierta manera concreta organiza los bytes como imágenes (ver dibujo). Hay que localizar qué parte del programa ha terminado de pintar/actualizar la pantalla e invocar una rutina de adaptación o traducción de video hacia el MSX. Esta rutina se mirará todo el buffer de video del Spectrum (esa zona de RAM con datos) y los tendrá que enviar (mover) a la VRAM del MSX, además de colocar los datos de una manera diferente (ver dibujo). Tanto el proceso de leer los datos originales y enviarlos a la VRAM del MSX (se hace a través del VDP con puertos de entrada/salida, la CPU no es capaz de acceder directamente a la VRAM), como el de colocarlos de una manera distinta debido a la organización de la VRAM, es un tiempo extra que se pierde con esta traducción y una de las principales causas de por qué los cutreports van lentos como ellos solos.

Una conversión más decente, debería buscar qué partes de la pantalla se van a actualizar y mandar a la VRAM del MSX solo aquellas partes que han cambiado desde la última vez, haciendo que la velocidad de este proceso aumente en gran medida. Esta búsqueda requiere tiempo e investigación dependiendo de cada juego, pues cada uno puede ser internamente bastante distinto (ver dibujo). De nuevo, más análisis.
 

OTROS PROBLEMAS

Hay una serie de problemas que muchas conversiones no tuvieron en cuenta y hacen que fallen dependiendo del modelo de MSX. Las razones son de todo tipo: desde que no tendrían más equipos donde probar, falta de tiempo para revisar más a fondo el código, o que no tenían en cuenta especificaciones concretas de MSX2 o superior debido a que simplemente aún no habían salido estos equipos al mercado. Algunos ejemplos:

  • Puerto de subslots. Si el MSX está sin subslots, no hay ningún problema en escribir en la última dirección de RAM (#ffff). El problema viene cuando hay disponibles subslots, puesto que es una parte muy sensible, debido que ahí se accede a la configuración de subslots de la máquina.
  • Banco de RAM. En un ZX Spectrum es muy utilizada la llamada al puerto #FE para acceder al teclado, colores, etc. En un MSX con RAM mapper, acceder a ese puerto en concreto puede cambiar la página de RAM que se está utilizando en cierto slot/subslot.

No tener en cuenta estos temas entre otros, haría que en algunos equipos, el port no funcionase correctamente.
 
En resumen, incluso los cutreports más simples requieren un tiempo de investigación por parte del 'cutreportador' para saber dónde colocar sus rutinas de adaptación, aunque ya tenga previamente diseños de otros cutreports, como las de volcado de video, búsqueda de puertos, etc. Cabe remarcar que en el tiempo comercial del MSX, las herramientas para realizar esto eran muy limitadas, lo que dificultaba mucho más aún el trabajo de portado.

Cuanta más experiencia, sobra mencionar que más rápido se harían los ports debido a que estas rutinas serían más fácilmente adaptadas a circunstancias concretas. El tan famoso mantra de “la máquina de hacer conversiones como churros” no existe realmente... Requiere intervención cualificada humana, es decir, alguien con ciertos conocimientos que analice el código y datos del juego original. No es ningún proceso automático.