Programación en ensamblador C64: interrupciones y líneas de exploración

En este tutorial, muestro cómo usar interrupciones de línea de exploración para dibujar el marco del Commodore 64 en diferentes colores. Con este truco puedes lograr efectos gráficos que en realidad no deberían funcionar.

Programación en ensamblador C64: interrupciones y líneas de exploración

Espera un minuto, ¿los 16 colores en el marco de la pantalla? ¿Cómo es eso posible cuando solo hay una dirección con el color de fondo en la memoria? La palabra mágica es interrumpir. Con estos disparadores activados por ciertos eventos, puede crear una gran cantidad de efectos gráficos geniales. Una muy sencilla es dibujar el marco en diferentes colores.

ejemplo

Como siempre, el ejemplo se puede encontrar en mi página de GitHub. En un tutorial anterior mostré que puedes pintar el fondo en colores brillantes. En ese momento, sin embargo, estaba desordenado y solo parpadeaba. En este ejemplo, uso interrupciones de las líneas de exploración para cambiar el color cada pocas líneas.

Antes de entrar en los detalles del programa, cada lector interesado debería ejecutarlo él mismo o al menos echar un vistazo de cerca a la captura de pantalla.

funcionalidad

El marco de la salida de pantalla se muestra en 16 colores diferentes. El color básico es el negro. Entonces, si el color de fondo (€D021) se establece en negro (#€0), todo el cuadro se dibuja en negro. Para poder dibujar líneas individuales del marco en un color diferente, debemos dejar de pensar en marcos y áreas de contenido. La imagen dibujada consta de líneas (scanlines) que se dibujan línea por línea con el cañón de electrones de una pantalla CRT. Para el Commodore 64 se ve así:

Se dibujan 312 líneas individuales, cada una de las cuales consta de 504 píxeles. ¡Esas 312 líneas se dibujan 50 veces por segundo! El área de contenido tiene una resolución de 320×200 píxeles a su alrededor está el marco con las dimensiones 403×284. Alrededor de este marco están las áreas HBlank y VBlank en las que no se dibuja nada. Suponiendo una velocidad constante para que el rayo atraviese las líneas, HBlank Range es el tiempo que tarda el rayo en comenzar sobre la siguiente línea y VBank es el tiempo que tarda el rayo en moverse desde la parte inferior derecha a la parte superior izquierda necesaria para la siguiente línea. fotografía.

Vemos dos cosas principales en el gráfico:

  • una imagen se construye línea por línea
  • la computadora tiene que llevar un contador a alguna parte para que sepa qué línea se está dibujando y otro cuando tiene que saltar hacia atrás para la siguiente línea o comenzar una nueva imagen

La teoría es esta: entre cambiar una línea, simplemente cambia el color almacenado en €D021. Pero, ¿cómo saber cuándo comenzar una nueva línea?

interrumpe

Una interrupción es una señal para la CPU. Esto hace que la CPU interrumpa la ejecución del programa en ejecución y ejecute otra pequeña pieza de código antes de que la CPU reanude la ejecución del programa original. El C64 distingue entre:

  • IRQ (Solicitud de interrupción)
    Con este tipo de interrupción, la CPU puede decidir si ignorarla o no. Según lo decida la CPU, se ejecuta SEI o CLI. CLI acepta la interrupción.
  • INM
    estas interrupciones no se pueden ignorar.

Cambiar a una nueva línea es una gran interrupción. Por ejemplo, podemos optar por reaccionar al cambio en la línea 5. Desde el punto de vista de un programador ensamblador, necesitamos escribir una función para ser ejecutada y crear un vector de interrupción en ella. Con el comando CLI aceptamos la interrupción y su procesamiento.

programa

He definido 2 variables (direcciones en memoria) para mi programa. En el primero almaceno el color de fondo actual para el marco (BORDERCOLOR) y en el otro un contador (COUNTER) en el que cuento los colores de un máximo de 16 a 0 y luego finalizo la interrupción.
Mi programa consta de 2 partes:

  • inicialización
  • función de interrupción

Comenzaré con la función de interrupción. Este es el código que se ejecuta cuando se activa la interrupción. En mi programa, el código se llama desde una determinada línea a medida que se crea cada imagen:

La función comienza con la etiqueta «Irq». En las dos primeras líneas, la variable COUNTER se inicializa con el número máximo de colores (16). Después de eso, comienza un ciclo con la etiqueta «Loop». El primer paso es establecer el color del borde en el valor de BORDERCOLOR. No sucede nada durante las próximas 3 líneas con la etiqueta «Pausa». El registro X se inicializa con 90 hexadecimal y luego se cuenta hacia atrás. Mientras no sea 0, la cuenta atrás continúa. Durante este tiempo no sucede nada excepto que la línea de cuadrícula dibuja la imagen y la barra en el color de fondo actual. Luego, el siguiente color se cambia a BORDERCOLOR, el CONTADOR se reduce en uno y este ciclo continúa hasta que el CONTADOR es 0. El color del borde se restablece a negro, la interrupción se confirma con ASL €D019 y se realiza un salto a la rutina de interrupción estándar del núcleo.

Des da las siguientes constantes:

  • dieciséis
    el número de colores diferentes. 16 es el máximo, también puedes reducir este número
  • €90
    el ancho de las barras de color. Puede cambiar este valor como desee.

Para que la interrupción se llame en algún momento, debe «registrarla». Lo siguiente se hace en el área de inicialización del programa de ejemplo. La variable BORDERCOLOR se inicializa con 1 para el color blanco. Para que la salida se vea un poco mejor, establecí el fondo del área de contenido en negro y el color del texto en blanco (pero solo se aplica al texto nuevo -> Listo). Entonces se pone emocionante, se registra la interrupción:

  • SER
    durante la inicialización, la CPU debe ignorar todas las interrupciones (se cancela nuevamente al final de la inicialización con CLI)
  • Ignorar interrupciones CIA-1
    €DC0D es el bit «Control y estado de interrupción». Al escribir, podemos ignorar interrupciones especiales con los bits individuales. Con el código, simplemente ignoramos a todos. Como recordatorio, las interrupciones IRQ pueden ignorarse.
  • Borrar bit de interrupción VIC
  • Reconocer las interrupciones de la CIA
    con un acceso de lectura a las direcciones €DC0C (IRQ, chip CIA-1) y €DD0D (NMI, chip CIA-2) confirmamos solicitudes de interrupción abiertas.
  • establecer la línea en la que debe ocurrir la interrupción
    se establece en el valor constante €35, esta es la línea 53.
  • Establecer dirección de salto a la función Irq
    este código #Irq obtienes el byte de orden superior de la dirección, esto viene después de €0315. No olvide: ¡64kByte solo se puede direccionar con 2 bytes!
  • Habilitar interrupciones VIC
    Establecer el primer bit en €D01A activa las interrupciones de trama del chip de gráficos VIC
  • CLI
    Reactivar el procesamiento de interrupciones para la CPU

Conclusión

Este ejemplo bastante simple muestra cuán poderosas son las interrupciones. Con el C64, se modifica mucho, especialmente en los juegos. Las limitaciones fijas para el número máximo de colores o sprites para un área de imagen pueden anularse y mostrarse efectos que no son posibles únicamente desde el formulario en papel. Este artículo muestra de manera muy impresionante que no solo programa lo que debe mostrarse, sino también cuándo.

(Visita 210 veces, 1 visita hoy)