Gráficos en consola antiguas (VI): Memoria y dibujado en pantalla

Antes de continuar adelante con nuestro viaje histórico me gustaría hacer un inciso acerca de como funciona la memoria en los sistemas basados en el TMS9918A y derivados, lo digo porque es algo que tendría que haber escrito en la entrada de la Colecovision pero no lo hice en su momento y la entrada ha tenido ya suficientes revisiones en pocos días y esto no solo afecta a la Colecovision sino también a otras consolas de las que vamos a hablar a partir de ahora, por lo que haremos una pequeña retrospectiva por el momento, tomad esto no como una sexta parte sino como una parte cuatro punto cinco.En la cuarta entrega hable de la Colecovision, la cual estaba compuesta por los siguientes elementos:

TMS9918ADiagram

  • CPU Z80A a 3.58Mhz (CPU)
  • 8KB de memoria RAM. (CPU RAM)
  • TMS9918A para gráficos. (VDP)
  • 16KB VRAM
  • Cartuchos de hasta 32KB de memoria. (CPU ROM)

Dado que los videojuegos son un medio interactivo no se sabe como será el siguiente fotograma por lo que la CPU continuamente tiene que ir cambiando la situación de la escena en cada fotograma. Por ejemplo si el personaje es dañado entonces tendrá que cambiar el Patrón/Sprite del personaje por el del personaje dañado, desplazarlo hacía atrás y luego volver a colocar el del personaje en su posición normal o hacer aparecer la pantalla de Game Over.

Dado que el TMS9918A solo se encarga de dibujar la escena cualquier modificación sobre la misma tiene que ser realizada por la CPU manipulando la memoria de video cuando el TMS9918A no este dibujando la escena, por lo que solo podemos acceder  a la memoria de vídeo en el periodo en que el TMS9918A no esta accediendo a los datos para dibujar, en ese momento la CPU generará la Name Table . En el caso de la Atari 5200 teníamos el ANTIC y os comente que lo que hacía la CPU era crear una lista de comandos que utilizaba el ANTIC para realizar la escena, pues bien la Name Tables serían algo parecido.  Pero….¿Como funciona? Es la tabla/mapa que dice cual será la configuración de pantalla. Su composición de 32 (8 pixeles por sprite en horizontal, 256 pixeles en total por linea)x 24 (8 pixeles por sprite en vertical, 192 lineas), dando un total de 768 bytes en cuanto a tamaño, pero lo que almacenan no es la información en forma de pixeles sino a que posición corresponde cada patrón/sprite en pantalla, los cuales se encuentran almacenados en una lista llamada Sprite Generator Table, la cual tiene un tamaño de 128 bytes (4 bytes por sprite).

El Z80A tiene una instrucción que permite mover grandes bloques de información por lo que la respuesta más obvía es utilizar esa instrucción para mover la RAM a la VRAM… ¿Sencillo no? Pues resulta que el TMS9918A no permitía hacer eso.

FailLogo_711691a

Para acceder a la VRAM la CPU tenía que hacer tres envios, los dos primeros para decir la operación que se quería realizar: Leer de la VRAM, escribir en la VRAM, Escribir en la Color RAM/Paleta o escribir en uno de los ocho registros del TMS9918A que sirven para su configuración, esto ocupaba dos bits en total. Los otros 14 bits eran para decir la dirección de la memoria de video que se quiere manipular, de ahi a que el 9918A como mucho tenga unos 16KB de memoria VRAM asignada y no más. El tercer envió es para escribir el dato que queremos escribir.

El Z80A necesita por lo tanto unos 16 ciclos de reloj para escribir un byte en dicha memoria y dado que solo puede hacerlo durante los escaneos de linea en los cuales el 9918A no dibuja nada entonces tenemos que:

3,58 Mhz*10^6=3.580.000 ciclos/segundo.

3.580.000 / 60 fotogramas por segundo = 59666.67 ciclos/fotograma.

59666.67/ 262 lineas por fotograma= 228 ciclos/linea.

Sabemos que la resolución de la Colecovision era de 256×192 esto nos deja unas 70 lineas libres, y teniendo en cuenta que el Z80 puede escribir cada 16 ciclos entonces:

228 ciclos por linea/16 ciclos para escribir en la VRAM por parte de la CPU= 14 escrituras por linea.

14*70 lineas libres= 980 bytes. (Tamaño de la Name Table= 768 Bytes, tamaño de Sprite Generator Table= 128 bytes).

En el caso de la Famicom/NES la modificación en el sistema de memoria fue bastante profunda. Tal y como explique en la entrada anterior la VRAM esta dividida en varias memorias distintas, estando la Sprite Generator Table dentro de la memoria interna de la PPU y la Name Table en los 2KB de memoria de video.

Una de las modificaciones exclusivas de la PPU es la función DMA_OAM, siendo OAM la memoria interna de 256 bytes en la cual se almacenan los 64 sprites distintos que se utilizaran en la escena y por tanto estamos hablando de lo mismo que la Sprite Generator Table. Pues bien, el registro DMA_OAM hace una transferencia de 256 bytes en bloque para llenar la OAM lo más rapidamente posible con solo que la CPU escriba la dirección donde se encuentran los datos que quiere transmitir. Dicha transferencia se realiza a través de un dispositivo DMA.

El acceso directo a memoria (DMA, del inglés direct memory access) permite a cierto tipo de componentes de una computadora acceder a la memoria del sistema para leer o escribir independientemente de la unidad central de procesamiento (CPU) principal.

Esto permite no gastar ciclos de reloj de la CPU de Famicom/NES en la transferencia de la Sprie Attribute Table. Ahora bien, con la Famicom/NES la cosa es más compleja ya que la imagen esta compuesta por unos 256×224 pixeles (32×28 bloques) por lo que necesitamos unos 896 bytes para la generación de la pantalla actual y solo tenemos 38 escaneos de linea libres, esto en teoría haría que fuese imposible crear la Name Table en tan poco tiempo.

Picture_2_c

La CIRAM de 2KB (ver entrada anterior) es donde se almacenan la Name Table pero… ¿como lo hace para poder la name table en tan poco tiempo? Para empezar el acceso a la CIRAM/VRAM es el mismo que el descrito en la Colecovision más arriba… ¿entonces? Bueno, el secreto esta en que utiliza un 6502 que a la hora de transmitir byte por byte es mucho más rápido que el Z80A por lo que solo necesita 4 ciclos de reloj para transmitir datos en vez de 16 ciclos, y esto hace que la CPU de NES pese a ir a la mitad de la velocidad sea capas de transmitir el doble de datos por escaneo de linea. Esto hacen unos 28 bytes por escaneo de linea para 38 lineas libres y por tanto unos 1064 bytes de transferencia.

Perdón por esta entrada tan larga, pero he pensado que era necesario hacerla para hacer más amenas y menos confusas futuras entradas de la serie.

Anuncios