Por petición por e-mail voy a empezar una serie de entradas donde voy a hablar de ordenadores y consolas del pasado en el sentido de como funcionan sus gráficos y por tanto como se generan en pantalla. No deja de ser un remaster mucho más completo y conciso de la antigua serie en el antiguo blog «Gráficos en Consolas Antiguas» pero tomando como base esta vez los diferentes ordenadores que salieron en vez de las consolas.

No voy a realizar la serie de manera cronológica sino de manera que hablare de manero evolutiva de los sistemas en orden de complejidad de tal manera que el lector pueda entender como funciona el hardware de cada uno de los ordenadores y sus diferentes componentes. Hay que tener en cuenta que ciertos componentes se repiten de un sistema  otro por lo que para no repetir el texto vais a ver referencias al sistema original que llevaba dicho procesador como referencia y a continuación los posibles cambios en el nuevo sistema respecto al anterior pero lo que tiene que quedar claro es que los sistemas se construyen a partir de lo ya creado en anteriores.

Antes de entrar en materia en concreto con el ZX Spectrum os recomiendo el siguiente enlace que se puede encontrar en el blog Retroscanlines donde hablan de manera didáctica y completa de como funcionan los monitores analógicos y como estos generan la pantalla. Como es algo que yo no explicaría mejor que su autor os recomiendo que lo leáis para saber como se genera la imagen en el televisor/monitor. Pero hay que tener en cuenta que en el caso de un ordenador necesitamos que este de antemano genera la imagen y es de lo que van a ir estas entradas.

Una vez dicho esta introducción lo mejor es empezar a definir lo que es el ZX Spectrum

#2 Arquitectura General del ZX Spectrum

arquitecturazx

 

#2 Z80 a 3.58 Mhz.

#3 RAM en el ZX Spectrum y búfer de imagen.

El mapa de memoria del Spectrum es el siguiente:

table_spectrum_memory_map

El Z80A puede direccionar como mucho 2^16 bytes de memoria por lo que la suma total del sistema entre RAM y ROM es de unos 64KB (aunque hubo configuraciones superiores, que luego comentare). Los 16KB primeros estaban dedicados a la ROM que venía con el sistema por lo que la RAM que quedaban eran 48KB donde la memoria de pantalla ocupa unos 6KB y y los datos de color unos 768 byes, dicha memoria se encontraba dentro del espacio de 16KB accesibles también por el ULA mientras que los otros 32KB eran accesibles solo por el Z80A. El hecho que los primeros 16KB de RAM (de los 16KB a los 32KB del direccionamiento) fuesen accesibles tanto por la CPU como por el ULA hacía que esa parte de la memoria fuese la que peor rendimiento tenía respecto al resto y es por ello que una vez el modelo de 48KB se estandarizo la mayoría de desarrolladores evitaron tocar esa parte de la memoria en concreto.

El ULA es un chip especializado encargado de realizar una serie de tareas concretas en el sistema:

  • Recibir los datos desde el teclado.
  • Leer la parte de la memoria donde esta el búfer de imagen y convertir los datos en señal de video.
  • Enviar y recibir datos desde y hacía la unidad de casette.

EL ULA tiene preferencia de acceso a los primeros 16KB, para parar al Z80A no hace servir la instrucción WAIT del proceador sino que lo hacía era enlentecer a la CPU durante ese tiempo. Esta forma de hacerlo tiene sentido en el modelo de solo 16KB donde ambos procesadores comparten la memoria pero no tiene sentido en los modelos de 48KB donde la CPU tiene acceso exclusivo a los 32KB de la parte superior de la consola pero el modelo base fue el de 16KB y la parte que nos interesa es la memoria de video que es donde se generan las imagenes.

spectrum-screen-layout

El espacio de memoria son 6KB para almacenar los patrones que forman la pantalla y 768 bytes para almacenar los atributos de color.

La resolución estándar del Spectrum es de 256×192 pixeles con una paleta de 8 colores básicos que se puede convertir en una de 15 colores a base de colocar una versión con más brillo de los diferentes colores siendo el negro el único color que no tiene una versión alterna.

zxspectrum-palette

El búfer de imagen es una matriz de 32×24 bloques donde en cada bloque solo pueden haber dos colores como mucho, esto es lo que hace que muchos juegos de Spectrum tengan su aspecto visual tan particular que ayuda a identificar los juegos del ordenador.

la_abadia_del_crimen-4148-zoom

lunarjetman

Los gráficos son almacenados en los primeros 6KB en monocromo y sin atributo de color, donde en cada uno de los 32×24 bloques hay un patrón de 8×8 pixeles con de 1 bit, por lo que:

256*192= 49152 bits = 6144 bytes = 6KB.

En cuanto al color hay que tener en cuenta que cada patrón de 8×8 tiene como mucho dos colores de una paleta de 15 colores en formato RGB4, donde los 3 primeros bits marcan el color y el último bit si el color es en modo brillante o no, por lo que cada patrón almacenara unos 8 bits de memoria (4 bits por color).

32*24*8 bits= 6144 bits= 768 bytes

Es decir, en teoría el ZX Spectrum tiene suficiente memoria como para almacenar el búfer de imagen  en modo estándar y no tener que renderizar la escena a medida que el haz de electrones pasaba por la pantalla de fosforo y digo en teoría porque el hecho que la CPU y el ULA pudieran acceder a ese espacio de la RAM al mismo tiempo sin ningún mecanismo de contención resultaba en un problema.

Hay que tener en cuenta que el Spectrum fue un ordenador diseñado en el Reino Unido donde el televisor es PAL y no NTSC. La diferencia con el modo NTSC es que pese a que el tiempo por linea es el mismo, el haz de electrones genera unas 625 lineas en modo progresivo a 25hz y 312 lineas en modo entrelazado a 50hz por lo que la tasa de refresco es menor pero el tiempo por linea es el mismo en ambos casos, unos 64 microsegundos.

pal_tv_diagram_interlacepal_tv_diagram_non_interlace

¿Por qué es importante esto? Pues por el hecho que la contención sobre la memoria ocurría cuando el ULA estaba enviando los datos a la señal de video mientras se dibujaba la escena y dicha contención no ocurría en los periodos en que el haz de electrones hacía un salto de linea o volvía al inicio para dibujar el siguiene fotograma por lo que el Spectrum que carecía de chip gráfico propiamente dicho tenía que generar en los 6KB mientras el ULA no miraba la RAM o en su defecto se renderizaba la escena en el espacio superior de 32KB (solo para el modelo de 48KB) y luego se copiaba a través de la instrucción MEMCPY a las direcciones referentes al búfer de imagen.

Algunas versiones mejoradas del Spectrum incluyeron una version del ULA con el modo 8×1, en dicha version los patrones/sprites pasaban de ser 8×8 pixeles a 8×1 pixeles, no es un formato que sea muy útil para videojuegos teniendo en cuenta que se solían trabajar con patrones/sprites cuadrados pero dicho modo era ideal para imagenes estáticas ya que permitía aumentar el número de colores en la escena, dicho modo llamado Hi-Color 8×1 requería unos 12KB de memoria, la idea era que cada patrón en vez de ser 8×8 pixeles en pantalla era de 8×1 pixeles aunque sin aumentar la resolución por la tabla de atributos pasaba a ser de 32×192.

256*192= 49152 bits = 6144 bytes = 6KB.

32*192*8 bits= 6KB

 

La resolución final no cambiaba y habían otros modos gráficos que eran el 8×2 y el 4×1 pero el modo estándar utilizado en los juegos era de 8×8 y en el caso de las imagenes estáticas el 8×1.

El Spectrum tuvo una versión con 128KB de memoria RAM llamado ZX Spectrum 128 que curiosamente se creo y diseño en España y  que tenía algunos cambios respecto a los modelos originales con tal de aumentar el rendimiento.

spectrum128k-sp2

El primero fue el aumento de la RAM de los 48KB a los 128KB, algo que en teoría es imposible en un Z80A pero se utilizaba la selección de bancos para escoger el banco de memoria RAM y/o ROM a utilizar en ese momento por los procesadores, esto se hacía utilizando la dirección 7ffd donde los 3 primeros bits escogian el banco de memoria que se utilizaría, de los 8 bancos los bancos 5 y 7 servían como búfer de imagen y se seleccionaba el banco 5 o el 7 según el dato del cuarto bit, luego el acceso a la ROM se seleccionaba con el resto de bits de dicha dirección de memoria y el último bit le marcaba al sistema si tenía que funcionar como un Spectrum de 48K o como el nuevo modelo de 128K.

A nivel de gráficos el Spectrum 128K no tenía mejores procesadores, pero el hecho de tener dos espacios de memoria reservados eliminaba la contención de memoria y permitía que no hubiesen recortes de rendimiento en el momento en que el haz de electrones dibujaba la pantalla para generar la escena por el hecho que mientras la CPU generaba la escena en uno de los chips de memoria, el ULA leía de otro creando un formato de doble búfer.

A nivel comercial el ULA no fue mejorado en sus capacidades porque  Amstrad comprase Sinclair Research y se cenro el desarrollo de ordenadores más potentes bajo su marca en vez de continuar con la arquitectura del Spectrum, pero el Amstrad CPC tendrá su entrada correspondiente cuando llegue el momento, esto no ha impedido que el mundo homebrew entusiasta del Spectrum haya creado versiones mejoradas del ULA como es el ULAplus.

 

El ULAplus sustituye al ULA original en el hardware del Spectrum pero realiza una serie de mejoras sobre el sistema original aunque mantiene las limitaciones como acceder solo a 16KB de memoria y mostrar unos 2 colores por atributo/patrón, no obstante tiene la mejora de poder utilizar hasta «64» colores distintos, esto lo hace utilizando variaciones de contraste de los ya disponibles y recordemos que ya hay 2 variaciones de los 8 colores básicos por lo que gracias a esto la cantidad de colores disponibles aumenta a 64 colores y la tabla de atributos en modo 8×8 pasa de los 768 bytes a 1KB en el modo estándar y en el modo 8×1 los atributos de color ocupan 7.5KB en este modo.

Pero el ULAplus puede mostrar hasta 256 colores simultaneos en pantalla, este modo es llamado HAM256 ya que permite cambiar la paleta de colores durante el HBlank pero dadas las limitaciones en velocidad de la CPU solo puede cambiar la paleta de colores cada 16 lineas, en realidad el hecho de que el Spectrum solo muestre dos colores por atributo es una limitación de la CPU al igual que la paleta escogida.

ulapus_bbb

El modo de 256 colores se consigue utilizando 8 bits por atributo en vez de 4, los dos primeros bits son para escoger rojo, verde, azul o escala de grises. Los otros 6 bits restantes son para los 6 niveles diferentes de color por lo que por cada color básico tenemos 2^6 combinaciones de color que son 64 colores que sumados a la escala de grises da 256 colores.

En el modo estándar el modo HAM256 ocupa unos 6KB para los patrones/atributos y 1.5KB para el color mientras que en el modo 8×1 añade unos 768 bytes a los 12KB ya ocupados.

Otra versión mejorada del ULA es el SPECTRA.

El SPECTRA trabaja con 32KB de RAM sustituyendo a los 16KB de memoria pero solo utiliza uno de los bancos a la hora de generar la imagen dando al Spectrum estándar la capacidad de doble búfer, es decir, cuando el SPECTRA esta leyendo para enviar a pantalla lee de los 16KB que no están activos en ese momento y a los que tiene acceso el procesador, pero el hecho de tener un doble búfer no es su única mejora respecto al hardware original.

¿Que es lo que hace el SPECTRA entonces? Dicha interfaz le da al SPECTRUM soporte para modos de pantalla con atributos que tengan una altura de 1,2,4 y 8 pixeles y una anchura de 4 y 8 pixeles. Los modos de altura se refieren a linea única, doble y y cuadruple por lo que la resolución en el número de filas es de 192, 96, 48 y 24 respecticamente. Mientras que los modos de anchura son completo y mitad con 64 o 32 atributos respectivamente por lo que con esta mayor cantidad de modos respecto al Spectrum original se gana cierta versatilidad.

Es decir, no es que se consiga aumentar la cantidad de colores por atributo/patrón sino que se consigue trabajar con atributos/patrones más pequeños pero lo ideal en el SPECTRUM original hubiese sido que en cada pixel se pudiesen definir los colores pero esto hubiese requerido unos 18KB de memoria, lo que es más que los 16KB que se incluyen en el SPECTRUM y hubiese necesitado que la CPU pudiese direccionar al menos 128KB de memoria y el Z80A real no puede hacerlo por lo que se necesitaría una CPU de la misma familia con una capacidad de direccionamiento más alta y aunque hay ordenadores de hobby creados por usuarios utilizando el eZ80 esto no forma parte del concepto del Spectrum original, se que el ULAplus y el SPECTRA tampoco pero no van en contra de las limitaciones y el diseño del SPECTRUM original.

Los emuladores del SPECTRUM tienen un modo llamado SPEC256 que se basa esta vez si en poder hacer que cada pixel individual tenga su atributo de color.

Pero el cambio aquí no es emular una variación más potente del ULA sino emular un Z80 con una serie de cambios que son los siguientes:

¿Para qué vamos a reescribir el código del juego si ya tenemos el juego hecho y simplemente hay que emularlo pero con mejores gráficos y sonido? ¿Pero cómo hacer que el simulador de Spectrum visualice gráficos de 256 colores en lugar de los que ya tiene?

Pues la idea es la siguiente: Por un lado, tenemos un emulador de Spectrum con su zona de memoria y por otro lado y de forma paralela emulamos un Z80 que trabaje con registros de 64 bits en lugar de 8 bits y con un mapa de memoria en el que cada posición es de 64 bits y no de 8 bits.

Cada vez que se emula una instrucción del Z80, se simula la misma instrucción que opera con datos que siempre supone que son gráficos. Este procesador paralelo (yo lo he denominado Z80_GFX) modifica su zona de memoria de acuerdo on las instrucciones y para nada interviene en la zona de memoria del Z80. ¿Qué hemos conseguido? Pues una simulación fidedigna por una lado (la del Z80) y una zona de memoria de la que podemos obtener los gráficos en 256 colores.

Una cosa debe de quedar clara, ¡los gráficos no salen en 256 colores por arte de birliybirloque! Es decir, hay que trabajárselos. Disponemos de una herramientas, que permiten modificar a partir de un fichero SNA (mediante capturas de los gráficos en pantallas) los gráficos del juego con una paleta de 256c determinada y generar un fichero GFX que contiene la definición en 8 planos (256 colores) que luego el procesador Z80_GFX utilizará.

El hecho que el Spectrum genere los gráficos a través del Z80A es lo que le permite que en teoría versiones más avanzadas del procesador (tanto reales como emuladas) permitan mostrar mejores gráficos.

ADDENDUM: ZX81

zx81

El ZX81 fue el predecesor del ZX Spectrum, era un ordenador capaz de realizar gráficos tan «impresionantes» como estos:

Esto era debido a que su hardware era muy pero que muy simple:

zx81_leiterkarte

Tenía solo 1KB de memoria RAM y disponía del mismo ULA que el ZX Spectrum pero este no accedía a unos 16KB de RAM sino que construía la pantalla utilizando patrones ya almacenados en una ROM para construir una pantalla de 64×48 pixeles en blanco y negro.

El sistema tenía un modo texto que permitia escribir texto en una matriz de 32×24 carácteres, en el ZX Spectrum ese modo texto evoluciono a poder utilizar patrones definidos por el usuario pero el ZX81 es curioso porque es una versión preliminar del SPECTRUM y nos muestra como el ULA tiene un modo bitmap que no se utilizo en el SPECTRUM capaz de generar una pantalla de 64×48 pixeles (384 bytes de memoria) en modo mapa de bits, lo cual no deja de ser una curiosidad pero que demuestra que el ULA es un procesador que para la época y pese a formar parte de ordenadores de muy bajo coste es una pieza de hardware interesante.

Si queréis saber más del SPECTRUM de manera didáctica y en especial del ULA os recomiendo el siguiente libro:

ulabook

Con esto termino esta primera entrada, la siguiente con tal de seguir una linea evolutiva  a partir del Z80 va a ser la familia MSX.