Atari Assembler – Video avanzado

Hasta ahora las rutinas que hemos escrito han sido… bastante fomes, porque sólo hemos escrito programas que también podrían haberse escrito en BASIC.  El foco ha sido simplemente soltar la mano. La proxima rutina recién le sacará el partido a Assembler.

La rutina que cambia colores a partir del contador de frames modifica la dirección 710 en donde se almacena el color de fondo.  Cada vez que el Atari genera un nuevo frame, toma el color almacenado en esta dirección y lo escribe en la dirección 53272, que está conectada directamente con el chip de video.  El sistema operativo del Atari tiene esta dirección auxiliar 710 para que el color de la pantalla siempre se cambie sincronizado con su pintado.  Esto se hace así porque la imagen se está generando constantemente, y si cambiaramos el color directamente en 53272, veríamos que el color se cambia en la mitad de la pantalla, ya que el color cambiaría desde el punto en donde se estaba dibujando la pantalla en ese momento.

El siguiente programa en BASIC cambia el color a la máxima velocidad.  Podremos ver que el color no cambia de forma uniforme, sino que la pantalla queda con varios colores a la vez, pero en forma totalmente desordenada:

100 FOR I = 0 TO 255: POKE 53272, I: NEXT I
110 GOTO 100

Captura de pantalla 2013-04-13 a la(s) 22.03.09Aunque estamos cambiando el color a la máxima velocidad de BASIC, accediendo directamene al chip, qué pasaría si hicieramos lo mismo en Assembler en donde el código se ejecuta a la máxima velocidad del procesador?

Probemos con esta rutina

1536 104           PLA
1537 162   0       LDX #0
1539 143  24 208   STX 53272
1542 232           INX
1543  76   3   6   JMP 1539
1546  96           RTS

En este código tenemos varias cosas nuevas.  Primero podemos ver que en vez de usar el acumulador A, ahora estamos usando un nuevo registro, el X.  El 6502 posee tres registros principales: A, X e Y.  Los registros X e Y son los únicos que tienen una instrucción simple para incrementar o decrementar su valor, en este caso estamos incrementando el valor de X con INX (INcrement X).  Así también encontraremos las instrucciones DEX (DEcrement X), INY y DEY.

Esta rutina parte con el valor 0 en el registro X y lo almacena en la dirección que está conectada directamente al chip para controlar el color de fondo.  Luego incrementa el valor de X y vuelve a escribir infinitamente. La instrucción RTS nunca se ejecutará.

10 TRAP 20: FOR I=0 TO 255: READ D: POKE 1536+I, D: NEXT I
20 PRINT USR(1536)
30 DATA 104, 162, 0, 142, 24, 208, 232, 76, 3, 6, 96

El cambio de colores ahora es muchísimo más rápido.  Es tan rápido que incluso podemos ver varios colores en una sola linea.

Captura de pantalla 2013-04-13 a la(s) 22.18.16En esta rutina, es impredecible la velocidad con que el 6502 ejecuta nuestro código respecto a la velocidad en que el ANTIC está generando el video y es por eso que no se puede obtener una imagen estable.

Por suerte, los diseñadores del Atari incorporaron mecanismos para que el código del 6502 se pudiera sincronizar con la generación del video, y con ese mecanismo podemos obtener una imagen estable.

Vamos a hacer una pequeña modificación al código anterior para estabilizar la imagen:

1536 104           PLA
1537 162   0       LDX #0
1539 141  10 212   STA 54282
1542 143  24 208   STX 53272
1545 232           INX
1546  76   3   6   JMP 1539
1549  96           RTS

El único cambio que hicimos fue agregar el STA 54282.  Esta escritura es una escritura «mágica».  Si el 6502 escribe en esa posición de memoria, el ANTIC lo deja congelado hasta que se va a generar la siguiente linea scan.  Por lo tanto el STX sólo se ejecutará al principio del dibujado de la linea y jamás en la mitad.

Código en BASIC

10 TRAP 20: FOR I=0 TO 255: READ D: POKE 1536+I, D: NEXT I
20 PRINT USR(1536)
30 DATA 104, 162, 0, 141, 10, 212, 142, 24, 208, 232, 76, 3, 6, 96

El resultado te parecerá familiar, ya que es un «efecto» bastante utilizado.
Captura de pantalla 2013-04-13 a la(s) 22.26.12
En la captura no se nota, pero al verlo en vivo se ve como si las barritas se fueran moviendo.  Eso no es nada más que un accidente y tiene que ver con que la cantidad de lineas que se dibujan son diferentes a 256, por lo tanto se van corriendo.

Si quisieramos sincronizar las barritas para que siempre estuvieran en la misma posición tendríamos que saber en todo momento en qué linea nos encontramos.

Nuevamente somos afortunados, porque el ANTIC provee esta información.  Si leemos lo que está conectado a la dirección 54283, obtendremos el número de linea que se está dibujando y podremos sincronizar.

La versión sincronizada de este programa sería:

1536 104           PLA
1537 162   0       LDX #0
1539 173  11 212   LDA 54283
1542 201   0       CMP #0
1544 240 247       BEQ 1537
1546 141  10 212   STA 54282
1549 143  26 208   STX 53274
1552 232           INX
1553  76   3   6   JMP 1539
1556  96           RTS

El objetivo de esta nueva versión es que el registro X tenga un valor fijo cuando el contador de lineas scan se encuentra en un valor conocido.  Esto hará que cada vez que se pinta una linea, ésta siempre tenga el mismo color.

La implementación lee el registro 54283 en donde encontramos el número de linea, y si éste es cero, entonces deja el valor de X también en cero.  A partir de ese momento el X se irá incrementando sólo hasta que nuevamente el contador de lineas sea cero.

Otro cambio que tiene la rutina es que ahora cambia el color del borde (53274 en vez de 53272) para apreciar mejor cómo en la parte superior está sincronizado partiendo desde 0 (negro/gris/blanco)

Programa BASIC

10 TRAP 20: FOR I=0 TO 255: READ D: POKE 1536+I, D: NEXT I
20 PRINT USR(1536)
30 DATA 104, 162, 0, 173, 11, 212, 201, 0, 240, 247, 141, 10, 212, 142, 26,
208, 232, 76, 3, 6, 96

Captura de pantalla 2013-04-13 a la(s) 22.47.30

One Reply to “Atari Assembler – Video avanzado”

  1. nos faltaria ahora franco entrar a los input para ver como ingresamos datos desde estos mismos, exelente tutorial espero por más capitulos, por lo menos voy en viento en popa

Comments are closed.