#1 Z80A a 3.58 Mhz

#2 Memoria

Dado que el Z80A puede direccionar hasta unos 64KB de memoria RAM y que esta vez el adaptador gráfico tiene unos 16KB dedicados en vez de tomarlos de la memoria principal el sistema tiene acceso hasta unos 64KB de memoria que se distribuyen entre RAM y ROM, en el caso de la RAM la capacidad puede ser de 8, 16, 32 y 64KB pero si se utiliza una ROM (ya sea un cartucho de juegos o para utilizar el MSX Basic) entonces la RAM del sistema se va los 32KB dejando los otros 32KB para la ROM aunque es posible utilizar bancos múltiples de memoria con tal de aumentar artificialmente la memoria disponible, en especial de los cartuchos que en el MSX2 llegaron hasta 1 Megabit de memoria aunque el mínimo eran 32KB y los primeros modelos del ordenador se vendieron con un slot de cartuchos.

La distribución de la memoria en el MSX es diferente a la del SPECTRUM ya que divide la memoria en cuatro bancos distintos de 64KB cada uno de ellos, por lo que previamente se ha de escoger cual de los cuatro bancos utilizar para trabajar con este.

Banco 0 1 2 3
Uso ROM Slot 1 Cartuchos Slot 2 Cartuchos RAM
0000-3FFF BIOS Datos Datos Datos (solo si hay 64KB de RAM)
4000-7FFF BASIC Datos Datos Datos (solo si hay 48KB de RAM)
8000-BFFF Datos Datos Datos (solo si hay 32KB de RAM)
C000-FFFF Datos Datos Datos (solo si hay 16KB de RAM)

El MSX1 no llevaba unidad de discos integrada pero era requisito un slot de cartuchos por lo que en muchos modelos el Banco 2 estaba inactivo, el hecho de poder escoger entre varios bancos le daba una ventaja enorme al MSX respecto a otros sistemas de la época ya que le permitía tener cartuchos de 64KB y por tanto de juegos más complejos. El banco de memoria se seleccionaba activando los bits en concreto de la dirección 0A8h que esta reservado para esta tarea y la forma de asignar banco y dirección de memoria utilizada en cada momento se hacía de la siguiente manera:

msxmemorybank

Pero el cartucho no era el único formato en que los juegos se distribuyeron y ya desde el inicio los MSX tuvieron una unidad de disco como periférico.

hitbitmsx

Los juegos del MSX con disquera no hacen uso de los bancos 1 y 2 dado que los datos de los juegos se vuelcan sobre el banco 3 y se trabaja desde allí. En el MSX2 la disquetera se estandarizo y con dicho modelo llego una nueva BIOS llamada SUB-ROM que era una expansión de las funciones de la BIOS original que para poder tener acceso a ella necesitaba estar mapeada en algún banco pero en el modelo original no quedaban bancos por lo que en los MSX2, la dirección FFFF es utilizada para dividir el banco 3 en cuatro sub-bancos distintos.

Sub-banco 0 1 2 3
0000-3FFF SUB-ROM Datos (solo si hay 64KB de RAM)
4000-7FFF Disquete Datos (solo si hay 48KB de RAM)
8000-BFFF Datos (solo si hay 32KB de RAM)
C000-FFFF Datos (solo si hay 16KB de RAM)

No es que el disquete solo tenga unos 16KB de capacidad sino que los datos a utilizar se copian en ese sector y si lo pensáis bien el MSX en cada momento solo puede utilizar 16KB de RAM en total y esto es importante si tenemos en cuena que el Z80A no tiene acceso directo a la memoria local del TMS9918A pero para entender realmente como funciona el sistema gráfico del MSX y del MSX2 hemos de entender como funciona el TMS9918A y su versión mejorada para el MSX2, el V9938.

#3 El TMS9918A

#2.1 Versión Corta

Estos dos videos explican muy bien el funcionamiento del TMS9918A y sus limitaciones.

El TMS9918A fue un procesador gráfico utilizado en diferentes sistemas de la historia, en su versión sin modificaciones formo parte de sistemas como el MSX, los SG-1000 y SC-3000 de Sega y la Colecovision y tuvo variaciones a la largo de la historia en forma de versiones a medida con mejoras para NES, Master System, Game Gear, Mega Drive, SNES y el V9938 del MSX2.

La arquitectura general de todos los sistemas con el TMS9918A era la siguiente:

tms9918adiagram

Si os fijáis la CPU no tiene acceso directo a la VRAM por lo que tiene que enviar los datos al TMS9918A a través de un puerto especial y generar primero la tabla de carácteres o Nametable en la memoria principal y luego volcarla durante el periodo de overscan donde el TMS9918A no esta generando ninguna imagen por lo que la matriz de carácteres se tiene que generar por la CPU.

El TMS9918A tiene principalmente dos modos de funcionamiento distintos (en realidad tiene cuatro) pero lo más utilizados son el 1 (modo texto) y el modo 2 (modo sprites) y un modo combinado de ambos.

No voy a profundizar mucho en el modo texto, solo que no tiene nada de especial y se puede resumir en:

  • No puede dibujar sprites.
  • 240 pixeles de resolución horizontal divididos en 40 caracteres de 6×8 cada uno.
  • La resolución vertical es de 192 pixeles.
  • Solo puede mostrar dos colores en pantalla.
  • No puede mostrar sprites.

Pero lo que nos interesan son los modos gráficos, los cuales voy a relatar a continuación.

Tenemos por tanto la pantalla no dividida por pixeles sino por celdas “M”, cada celda “M” corresponde a un espacio de 8×8 pixeles en la pantalla, a cada celda le toca una posición de la Name Table la cual va desde la posición 0 (patrón/sprite en la parte superior izquierda), hasta el patrón/sprite 768. Dado que la resolución de la Colecovision/MSX/SG-1000 era de 256×192 pixeles estos se traduce en 32×24 celdas, que son 768 celdas en la Name Table. El contenido de cada una de las posiciones de la Name Table es un apuntador, no contiene los datos del patrón/sprite sino que le dice al TMS9918A donde se encuentra la información del patrón/sprite dentro de la memoria de video así como el color que ha de cargar para dicho patrón/sprite. Todo esto sirve para generar la Sprite Attribute Table.

sat

La Sprite Attribute Table es una tabla de 4 bytes que almacena la información de cada uno de los carácteres/patrones/sprites que componen la escena. Los dos primeros byte son la posición vertical y horizontal marcan la posición del pixel superior izquierdo del patrón/sprite en pantalla, dado que el tamaño es de un byte estamos hablando de una pantalla de 256×256 pixeles como mucho, Name apunta a la Sprite Generator Table donde se encuentra la información sobre que pixeles son visibles en la actual linea de escaneo y cuales no. Dado que el TMS9918A solo podía cambiar el valor de color cada 8 ciclos de reloj y estos se escribían cada 8 ciclos de reloj de este entonces el número de colores cada 8 pixeles solo podían ser dos, el asignado o el transparente (fondo), por lo que la sprite generator table solo tenía dos valores en el TMS9918A, 0 y 1, por cada una de las posiciones:

tms9918ascreen

La posición vertical y la posición horizontal no marcaban la posición en pixeles de la pantalla sino la posición del sprite/patrón por lo que era posible generar una escena a nivel de CPU compuesta por 256×256 celdas de 8×8 pixeles permitiendo para ello escenas con scroll donde para avanzar solo hacía falta desplazar la pantalla, el problema es que el scroll del TMS9918A no es nivel de pixel sino de celda haciendo que el desplazamiento de pantalla sea realice no pixel por pixel sino cada 8 pixeles y que los juegos del MSX con escenas compuestas por varias pantallas tuviesen un scroll cuanto menos brusco al desplazarse una celda entera que son 8 pixeles.

Uno de los mayores cambios del TMS9918A es el hecho de pode trabajar con multiples planos distintos, el plano de más al fondo estaba compuesto por un solo color y luego habían dos planos distintos que son fondo y carácteres, la particularidad es que el TMS9918A tenía un mecanismo que activaba la detección de colisiones cuando dos patrones/sprites del primer plano chocaban entre si pero gran ventaja es que el fondo de pantalla ya estaba dibujado y los cambios ocurrían solo en primer plano acelerando el proceso de dibujado de la pantalla.

tms9918a

Pero el TMS9918A no utilizaba un búfer de imagen y su forma de renderizar la escena era siguiendo el haz de electrones de la pantalla y esto lo hacía a una velocidad de 3.58 Mhz en los modelos para pantallas NTSC lo que le permitía cambiar el color cada 8 pixeles en total pudiendo escoger de un total de 15 colores distintos (siendo el último color el transparente que se tendría que ver el color base) los sprites del fondo también son de 15 colores más uno de fondo que sería el del Backdrop Plane que utiliza un solo color, esta limitación de 1 color cada 8 pixeles se ven los juegos del MSX que aparecieron antes que el MSX2 y que por tanto están pensados para el primer modelo.

Pero la particularidad del TMS9918A es que no renderizaba como en el resto de ordenadores haciendo uso de un búfer de imagen (como hemos visto en el caso del Spectrum) ya que hemos de tener en cuenta que cada bit en pantalla tiene 16 colores (2^4 valores) con una resolución de 256×192 pixeles por lo que para tener un búfer de imagen sería necesario:

256×192*4 bits= 24KB

En realidad si que hay un modo bitmap llamado multicolor mode, pero la resolución es pauperrima por el hecho que es de 68×48 pixeles, podéis ver su mala calidad en el siguiente video donde se muestran las diferentes resoluciones del TMS9918A.

Pero no disponemos de esa memoria en el TMS9918A, así que la escena se crea a medida que el haz de electrones va recorriendo la pantalla de fosforo al igual que ocurría con las consolas. ¿Entonces que es lo que se almacena en la VRAM? Pues la paleta de colores, La Name Table con referencia a cada SAT…

32*24*4= 3KB.

Luego tenemos que la VRAM puede almacenar hasta 256 carácteres (recordemos que aquí no se almacena el color)

256*(8×8 pixeles)*1 bit por pixel (1 color y 0 fondo)= 8KB

Necesitamos mucha menos memoria con este método cuyo mecanismo de renderizado se resume de la siguiente manera:

  1. La CPU genera la Name Table del fotograma siguiente mientras el TMS9918A esta enviando el actual al televisor.
  2. Una vez el TMS9918A esta en periodo de overscan y esperando a que el haz de electrones vuelva a su posición original para generar la siguiente imagen la CPU envía a través de un puerto especial del TMS9918A la Name Table que se almacenará en la VRAM y el TMS9918A utilizará como referencia para el siguiente fotograma.
  3. El  procesador gráfico lee de la Name Table para cuales son los patrones/sprites corresponden a la siguiente imagen una vez ha recibido los datos durante el periodo de VSync, a partir de la información de la Name Table genera la Sprite Attribute Table y lo almacena en una memoria que puede ser interna o externa dependiendo del sistema.
  4. Cuando llega el momento de generar la linea lo que hace por cada patrón/sprite es leer el tercer byte (name) de la SAT para saber cual de los 256 carácteres almacenados en memoria tiene que dibujar, los carácteres como hemos visto antes se encuentran almacenados en formato de dos colores en la VRAM.
  5. Lee el Color Code de la SAT para tener el código de color.
  6. Escribe la linea del patrón/sprite en la VRAM según la información obtenida del patrón y el color.

Ahora bien, dado lo exótico del funcionamiento del TMS9918A en comparación con otros ordenadores y el hecho que el MSX utilizaba un Z80A como el Spectrum algún que otro desarrollador porto juegos desde el Spectrum al MSX sin aprovechar las mejoras visuales de este último y por tanto prescindiendo del TMS9918A para generar los gráficos.

Estos juegos que acabáis de ver prescinden por completo del TMS9918A para generar la escena dado a que son ports directos del Spectrum.

El V9938

El cambio principal del MSX al MSX2 fue el cambio del TMS9918A por una versión muy mejorada y avanzada llamada V9938. Con una serie de cambios importantes en lo que a rendimiento se refiere siendo el más vistoso el hecho de aumentar la cantidad de colores disponibles en pantalla a través del hecho de haber aumentado la velocidad de reloj de los 3.58Mhz a los 21Mhz, mejora que además permitió aumentar la resolución estándar a los 256×212 con 256 colores.

El funcionamiento del V9938 es exactamente el mismo que el del TMS9918A pero la mayor velocidad del procesador permite  que los patrones/sprites puedan soportar un colorido mayir, el cual esta por encima de las consolas de 8 bits de la epoca (Famicom/NES y Master System) que utilizan también variaciones del TMS9918A pero lo mejor es ver comparados juegos pensados para ambas generaciones del MSX cara a cara para ver los cambios.

La gran particularidad es la capacidad de tener 64KB, 128KB o 192KB asignados al V9938 en vez de los 16KB del TMS9918 aunque la configuración estandar eran los 128KB, lo cual para una máquina lanzada en 1985 es impresionante.  ¿Verdad que antes he comentado como el TMS9918A no tenía la suficiente memoria para utilizar un bufer de imagen convencional a la resolución de 256×192? Pues el V9938 si que puede hacerlo y es por eso que añade una serie de modos bitmap aparte de los nuevos modos derivados del TMS9918A con mayor colorido.

Modo Patrones Resolución (patrones) Color Paleta VRAM Búfer
Texto 1 6×8 40×24 (240×192) 2 512 4KB Simple
Texto 2 6×8 80×24 (256×192) 2 512 8KB Simple
Multicolor 1×1 64×48 16 512 4KB Simple
Gráfico 1 8×8 32×24 16 512 4KB Simple
Gráfico 2 y 3 8×8 32×24 16 512 48KB Simple
Gráfico 4 1×1 256×212/256×192 16 512 32KB Simple
Gráfico 5 1×1 512×212/512×192 4 512 32KB Simple
Gráfico 6 1×1 512×212/512×192 16 512 128KB Doble
Gráfico 7 1×1 256×212/256×192 256 512 32KB Doble

En los modos basados en sprites el problema del scroll continuo pero en los juegos bajo modo bitmap se puede ver un scroll la mar de suave. Por cierto, comparad estos juegos a nivel de colorido y visual con los puestos anteriormente basados en un mayor colorido de los modos derivados del MSX1.

Si os habéis fijado estos no prescinden del scroll para mostrar una nueva pantalla.. ¿A que es debido esto? Pues que el V9938 añadió un registro adicional para realizar scroll vertical con un precisión de un pixel, de ahí a que estos 3 juegos en modo bitmap tengan una transición tan suave, por el hecho que el desplazamiento no es de 8 pixeles pero solo de uno.

Pero la gran mejora que tuvo el V9938 de cara a los modos bitmap fue el hecho de tener aceleración por hardware de ciertas funciones de manipulación de memoria sin que la CPU tenga que intervenir. Estas operaciones son por ejemplo copiar una parte especifica de la memoria en un area especificada del búfer de imagen, rellanar cajas con un color o dibujar lineas. No muchos juegos utilizaron estas funciones pero tienen un potencial enorme ya que esto permite generar el sprite una sola vez y copiarlo varias veces en el búfer de imagen del modo bitmap si es necesario.

El MSX Turbo R y el MSX 2+

El MSX Turbo R fue la versión más avanzada de la familia MSX, al contrario del MSX2 donde se mantenía el Z80 y su esquema de memoria aquí la CPU fue cambiada por el R800, que era una versión del Z800 a que su vez era la versión de 16 bits del Z80 con la capacidad de direccionar hasta 16MB de memoria aunque el MSX Turbo R solo disponía de 128KB en total y tampoco gozo de mucho éxito.

El MSX2+ en cambio si que mantiene el Z80 y el esquema de memoria del MSX2 pero utilizando el mismo esquema de memoria. El elemento en común entre el MSX2+ y el Turbo R fue su procesador gráfico.

V9958

El Chip del MSX2+ y del MSX Turbo R fue una mejora menor del V9938 aunque para mi es una pena que ninguan consola tomase este chip, el cual para mi es una auténtica pasada a nivel de especificaciones para la época, pero lo mejor es ver algunos juegos pensados para este chip gráfico.

El nivel de colorido es increible gracias al hecho que podía mostrar hasta 19268 colores a una resolución de 256×192 en vez de los 256 del modo gráfico 7 del V9938 pero un modo con más colores no es la única mejora sino que el scroll es suave tanto en horizontal como en vertical como se puede ver en esta versión para el MSX2+ y el Turbo R del Gradius 2:

Pero el gran añadido para mi es el hecho que los comandos de manipulación de memoria no solo están disponibles para el modo bitmap sino para el resto de modos por lo que la velocidad de renderizado aumenta enormemente al descargar a la CPU de dicha tarea que no es otra que la de transmitir los datos desde la memoria principal a la VRAM que en el caso del V9958 lo puede realizar sin problemas el propio procesador gráfico y esto es importante porque descarga a la CPU del trabajo de tener que realizar todas esas operaciones de copia de la Name Table y los patrones/sprites a utilizar en el siguiente fotograma.

Con esto termino, como siempre si hay algo que falte o este mal decidmelo.