Gráficos en consolas antiguas (I): Atari VCS 2600

La Atari VCS 2600 fue el primer sistema de videojuegos con un microprocesador (CPU).

Atari260_sss

Los sistemas anteriores que había en el mercado doméstico, las de la generación PONG, eran máquinas de estado finito. Es decir, ejecutaban un programa en forma automática sobre una entrada de datos para producir una salida, dicho programa se encontraba cableado en el hardware y por tanto no podían ejecutar programas almacenados en una memoria, pero no estaban pensadas para ello. La ventaja de utilizar un microprocesador era que el sistema podía ejecutar diferentes tipos de programa y eso implicaba un modelo de negocio basado en vender la consola a bajo coste y los juegos a un alto coste, el modelo de negocio llamado Razor&Blades dado que era el mismo que el de las máquinillas de afeitar y las cuchillas donde la maquinilla tiene un precio accesible y las cuchillas multiplicaban varias veces su coste dando enormes beneficios.

Pero lo que nos interesa es… ¿Como lo hacía la VCS 2600 para producir sus gráficos?

A2600_Pitfallsuper_breakout

Para entenderlo necesitamos mirar en sus entrañas:

l6IGIygVLUPYeOwJ

 

El recuadro naranja justo debido del slot de cartuchos es un MOS 6532 conocido como PIA y/o RIOT, se trata de un circuito integrado (y por tanto no estamos hablando de un microprocesador) que integra en su interior los siguientes elementos:

  • 128 bytes de SRAM (la única memoria que hay en el sistema).
  • Dos puertos de E/S bidireccionales, en el VCS 2600 se utilizaba un puerto para acceder a la SRAM y el otro puerto para acceder al slot de cartuchos.
  • Un contador.

Justo por debajo y en el recuadro amarillo tenemos el microprocesador, un MOS 6507, el cual es una versión recortada del MOS 6507 con la capacidad de direccionar solamente 8KB de memoria, esto en el VCS 2600 no era problema desde el momento en que el sistema solo disponía de 128 bytes de RAM y los cartuchos se pensaron inicialmente para ser solo de 4KB de tamaño. No obstante fijaos que el único que esta conectado al MOS 6532 es el 6507, el chip que esta por debajo, con el recuadro azul turquesa, el llamado adaptador Television Interface Adapter (TIA) carecía de una memoria propia asignada y tampoco tenía acceso a la RAM del sistema, eso si, sus registros se encontraban dentro del mapa de memoria del sistema.

foto 1 foto 2

Erroneamente llaman al TIA con el nombre de Stella aqui, pero el TIA era en realidad una máquina de estado finito que había sido desarrollada por Jay Miner y Al Alcorn, las tareas a realizar eran las siguientes:

  • Dibujar la escena en pantalla, que no es lo mismo que generarla.
  • Generar el sonido del juego.
  • Capturar la información de entrada de los joysticks y pasarla al procesador.

Lo que nos interesa es el primer punto, y he dicho anteriormente que la consola carecía de búfer de imagen… ¿Entonces como generaba la imagen? Pues utilizando una técnica llamada “Racing the beam”  que se podría traducir como “correr contra el haz de electrones del televisor” y es que el VCS 2600 generaba la escena a medida que el haz de electrones recorría la pantalla. ¿Como lo hacía? El TIA lo que hacía era leer los datos de su espacio reservado a la RAM para la generación del escaneo de linea, una vez leidos estos datos aplicaba el programa que tenía códificado via hardware, ya que era una máquina de estado finito, y enviaba la información el modulador RF que se encuentra en la parte inferior derecha. Esto significaba que la CPU tiene que escribir en los registros internos del TIA los datos correspondientes al siguiente escaneo de linea, mientras que el TIA estará procesando los datos del que se esta dibujando actualmente y que el modulador RF esta mostrando en pantalla.

Dado que el TIA no es un microprocesador y se trata de una máquina de estado lo único que necesita para dibujar la escena es que el procesador escriba una serie de datos en las direcciones de memoria asignadas a los registros del TIA para que este lo pueda leer, no voy a entrar en la forma en la que se programa el VCS 2600, sino a explicaros como generaba la consola la imagen en el televisor.

cycles2_2

La generación de la escena empieza desde arriba a la izquierda, en ese momento el contador del PIA se pone en marcha y será el que avise al procesador de los tiempos. Dado que existe un tiempo en que el haz de electrones se ha de colocar en la posición de inició este es aprovechado para procesar la lógica del juego y escribir los registros correspondientes en el TIA para la generación de la imagen, pero para evitar que este envie basura a la pantalla antes de hora lo que se hace es utilizar un registro llamado WSync que para por completo el envió de datos a la entrada de video del televisor.

El proceso funciona de la siguiente manera y desgraciadamente para los desarrolladores de la época el proceso era manual por lo que tenía que ser codificado en el código del programa.

  1. VSync colocado a 1 (se le avisa al TIA que va a generarse una nueva imagen), WSync a 1 durante 3 ciclos, (se le pide al TIA que no transmita nada durante ese tiempo, el haz de electrones que es controlado a través de la entrada de video y por tanto por el TIA no se mueve).
  2. Se activa al VBlank, durara unas 37 lineas de escaneo para que la CPU pueda calcular parte de la lógica del juego y escribir sobre los registros correspondientes del TIA. Durante este periodo el TIA tampoco escribe nada al tener el registro WSync activado.
  3. Se dibuja la escena, esto dura unas 192 lineas de escaneo, a continuación hay un periodo de overscan/vblank para calcular la lógica del juego que dura el tiempo equivalente a 30 lineas de escaneo.

El MOS 6507 funcionaba a 1/3 de la velocidad de reloj del TIA  (1.19 Mhz uno y 3.58 Mhz el otro) por lo que estos se encontraban sincronizados. El TIA esta diseñado para seguir los pasos del haz de electrones y la falta de un búfer de imagen no permitía el envió de la imagen anteriormente generada y en memoria de nuevo a pantalla sino que necesitaba que continuamente el procesador generase la imagen. El problema es que el 6507 no podía procesar la lógica del juego y los gráficos del mismo por lo que tenia que repartir el tiempo entre ambos.

Antes hemos dicho que la consola no tiene memoria de video para un búfer completo y lo que hace es generar la escena por linea de escaneo… ¿pero hay suficiente memoria para hacerlo? La paleta de colores del VCS era de 128 colores, unos 7 bytes por pixel. Utilizando un búfer de linea esto hubiesen sido unos 160 pixels*7 bytes y esto es más que los 128 bytes incluidos para todo el sistema. Por otro lado la CPU se pasaba unos 53 ciclos de reloj dedicados a generar el siguiente escaneo de linea y necesitaba 3 ciclos de reloj para escribir en memoria (ya fuese a la SRAM como a los registros del TIA), por lo que teniendo en cuenta los 76 ciclos como mucho podía escribir unos 25 bytes…. ¿Entonces como lo hacia a la hora de dibujar la escena?

El dispositivo podía dibujar 5 tipos de elementos distintos, llamados jugador 0, jugador 1, campo de juego, fondo, pelota y misil. Todos los elementos excepto fondo y campo de juego se dibujaban colocandose en el escenario y podían ser duplicados varias veces, fondo y campo de juego ocupaban el fotograma entero y por tanto no podían ser duplicados. Jugador 0 y misil 0 tenian un color asignado, color 1 y misil 1 otro color asignado, campo de juego y pelota otro color y fondo un quinto.

PFAtari

Los registros PF0, PF1, y PF2 eran los que se encargaban de dibujar la escena, cada uno de los pixeles arriba mostrados corresponde a 4 pixeles reales, por lo que son 16+32+32= 80 pixeles. Si os fijáis esto es la mitad de la pantalla, en realidad solo procesaba la mitad de la misma y luego a través de una serie de registros marcaba si la otra mitad era igual, no había nada o estaba invertida (modo espejo). En los registros PF un 0 marcaba que se tenia que dibujar el color de fondo y un 1 que se tenia que dibujar el color de campo de juego… ¿Pero que ocurría con los otros elementos? En cada “pixel” del TIA este comprobaba a través de su programa interno que objetos se encontraban ese pixel y dibujaba el color correspondiente teniendo en cuenta una jerarquia de prioridad concreta. En cuanto al posicionamiento de los objetos móviles en pantalla se hacía utilizando tres tipos de registro por elemento, el primero colocaba los 0bjetos en su posición inicial (dada en el programa del cartucho), el segundo tipo marcaba si el objeto en cuestión se encontraba en esa linea de escaneo o no y el tercero marcaba la posición en la que se encontraba respecto a la posición anterior.

Así pues la CPU generaba la escena colocando una serie de datos en unos registros correspondientes y escribiendo sobre unos registros de control para controlar el dibujado de la escena. ¿Pero que ocurría con los juegos que necesitaban un cálculo de la lógica mucho más complejo.

video_chess

La escena no se generaba hasta que que el registro WSYNC del TIA estaba a 0, por lo que realmente no todos los juegos iban a 60 fotogramas por segundo. En sistemas con un búfer de imagen lo que hacía el adaptador de televisión era leer el búfer de imagen cada x tiempo y convertir la imagen, en el caso del VCS 2600 al no haber búfer de imagen habían dos opciones, generar la imagen o no generarla y esto hacía que en juegos con una lógica muy compleja la tasa real de refresco fuese mucho más baja.

Pero con esto creo que queda mucho más clara la explicación. Sí tenéis alguna duda a los comentarios y gracias por el feedback en la primera versión de esta entrada.

Anuncios