Sprites, BOBs  y otras criaturas mágicas (III): EL BLITTER (I)

 

Tras el capítulo anterior, en el que comentamos brevemente el funcionamiento del Copper y algunos de sus principales usos en juegos y demos, le toca el turno al otro coprocesador del Amiga: el Blitter. Como vosotros mismos comprobareis, el Blitter no es tan accesible (¿ni divertido?) como el Copper, pero no por ello es menos importante y, bien utilizado, puede marcar la diferencia. Voy a dividir este capítulo en 2 entregas: en la primera introduciré algunos conceptos previos relacionados con la forma en que el Amiga almacena los gráficos y en la segunda ya entraremos de lleno en el funcionamiento del Blitter. Agarraos, que vienen curvas… Pero, antes, os dejo un mensaje para que reflexionéis:

to-blit-or-not-to-blit

Shakespeare era amiguero.

 

El sistema de numeración binario

Este punto queda un poco lejos del objetivo de este artículo, pero considero necesario tener una noción básica sobre cómo funciona el sistema de numeración binario para poder entender ciertos conceptos que aparecerán en los puntos siguientes. Si ya sabes contar en binario, enhorabuena, puedes avanzar hasta el siguiente apartado. En caso contrario, verás que es mucho más sencillo de lo que puede parecer.  En binario, para representar 2^N (2 elevado a la N) valores necesitamos N bits. Vamos a verlo resumido en una imagen de ejemplo:

sistema-binario

Curso acelerado de numeración en binario.

 

            Venga, ya sabéis binario… xD Al lío!

 

El modo planar

Los gráficos en el Amiga se almacenan en modo planar, es decir, la memoria en la que almacenamos una imagen se divide en partes o tramos, llamados bitplanes. En un gráfico que sólo conste de un bitplane, el color de cada píxel vendrá dado por el valor del correspondiente bit en dicho bitplane. Por tanto, sólo dispondremos de 2 posibles colores para cada píxel, representados por los valores 0 y 1. Además, si el gráfico es de 32 píxeles de ancho por 16 de alto, por ejemplo, el bitplane tendrá un total de 32 * 16 = 512 bits = 512 / 8 = 64 bytes. ¿Y si necesitamos más colores? Como ya he dicho antes, para poder representar 2^N valores en binario necesitamos N bits. Así, para poder representar 32 colores, como 32 = 2^5, necesitaremos 5 bitplanes. Aquí se puede ver cómo, a partir del mismo bit en los diferentes bitplanes, se construye el número binario que determina el índice de la paleta cuyo color ha de mostrar ese píxel. En el ejemplo, el número que se obtiene es el 24, por lo que el hardware de vídeo iría al registro 24 (de un total de 32) de la paleta y emplearía el color que ahí se indique para el correspondiente píxel.hrm-planar

 

Cómo se traduce la información de los bitplanes a un color concreto.

 

La figura con la que el Amiga Hardware Reference Manual (la biblia de la programación en ensamblador para Amiga) ilustra este mecanismo no está mal pero… mejor veamos todo esto con un ejemplo al grito de “Let’s go!”:

planar_v5

 

Un Lemming vale más que mil palabras.

 

 

Supongamos que esta imagen está en 16 colores (2^4): necesitamos 4 bitplanes para representarla. Además, simplificando, diremos que, como mide 5×9 = 45 píxeles, necesitaremos 45 píxeles * 4 planos= 180 bits (casi 24 bytes) para almacenar la imagen en memoria. En el ejemplo se muestran los valores de los bits correspondientes a los píxeles de las líneas 1 y 5 (siendo 0 el número de la primera línea) en cada uno de los 4 bitplanes. Por ejemplo, el color azul es el número 13 en la paleta de ejemplo que, representado con 4 bits sería el número 1101. Como podéis ver en el texto gris que aparece entre las 2 líneas  un 1 en el bitplane n equivale al valor 2^(n-1). Es decir, en el caso del color azul tendríamos:

            Bitplane 1 = 1 → 2^0 = 1

            Bitplane 2 = 0

            Bitplane 3 = 1 → 2^2 = 4

            Bitplane 4 = 1 → 2^3 = 8

            Por tanto, 1 + 0 + 4 + 8 = 13, que se corresponde con el índice del color azul en nuestra paleta de 16 colores. Esto mismo se podría aplicar a cualquier píxel de la imagen.

El modo planar tiene 2 variantes:

  •    ACBM (Amiga Contiguous Bitmap): se almacenan todas las líneas del bitplane 1, luego las del 2, luego las del 3, etc.
  •    ILBM (Amiga Interleaved Bitmap): se almacena la línea 1 (bitplane 1, bitplane 2, bitplane 3, etc.), la línea 2 (bitplane 1, bitplane 2, bitplane 3, etc.) y así sucesivamente.

 

 

El Blitter: introducción

            El Blitter es un coprocesador capaz de copiar áreas rectangulares de la memoria chip, además de rellenar superficies y dibujar líneas. Cada una de las operaciones realizadas por el Blitter se denomina ‘blit’.

 

            ¿Qué es lo que aporta el Blitter? Aunque, como digo, el Blitter puede copiar áreas de memoria independientemente de su contenido, su diseño y capacidades lo hacen especialmente adecuado para el manejo de gráficos 2D. En ausencia de sprites hardware, como ocurría en algunas máquinas tanto de 8 como de 16 bits, todo el pintado corría a cargo de la CPU. Incluso las máquinas que disponían de sprites hardware, dadas las limitaciones de éstos, tenían que tirar de la CPU para pintar los fondos y, posiblemente, otros muchos elementos gráficos de los juegos (caso del Commodore 64, por citar un ejemplo). El Blitter funciona en paralelo con la CPU, pudiendo encargarse de las principales tareas de pintado, mientras ésta continúa con la ejecución del programa. Es más, al tratarse de un coprocesador específicamente diseñado para mover grandes cantidades de datos (pudiendo, además, aplicar diversas operaciones sobre ellos), en general, el Blitter es capaz de llevar a cabo estos movimientos de datos a mayor velocidad que la CPU. Si bien es cierto que a partir del 68020, la CPU puede llegar a ser más eficiente que el propio Blitter.

 

            ¿Nadie es perfecto? Efectivamente, tal y como sucedía en el caso del Copper, el Blitter no es una excepción a esta regla y su uso tiene tanto limitaciones como implicaciones en el resto del sistema:

  •    El Blitter es sencillo de entender pero bastante complicado de dominar.
  •    Forma parte de los custom chips (Agnus): sólo puede operar sobre la memoria chip.
  •    Además, las direcciones de memoria sobre las que trabaja tienen que ser siempre pares (alineadas a palabra de 16 bits, por tanto).
  •    El tamaño máximo del área que puede copiar el Blitter es de 1024×1024, por lo que esta limitación, realmente, no lo es tanto.
  •    Aunque el Blitter funciona en paralelo con la CPU, ambos pueden llegar a competir por el acceso a un recurso común: la memoria chip. En este caso, el Blitter tiene prioridad sobre el procesador, pudiendo dejar algunos ciclos de memoria libres para éste o consumiendo todos los que necesite hasta que termine su operación actual (modo Blitter Nasty) y, potencialmente, “ahogando” a la CPU durante ese tiempo.
  •    Para indicar al Blitter la operación que debe realizar necesitaremos configurar una serie de registros, lo cual requiere de un cierto tiempo de procesamiento por parte de la CPU.

 

            Aquí acaba el capítulo más farragoso de la corta historia de esta sección… Pero ya sabéis que “la fama cuesta y aquí es donde vais a empezar a pagar… con sudor!!!” 😀  Espero vuestras dudas, comentarios, rectificaciones, sugerencias, regalos, etc., os recomiendo que leáis (o releáis) la primera entrega de esta serie de artículos y os emplazo para la siguiente entrega de “Sprites, BOBs y otras criaturas mágicas”, donde veremos en detalle cómo funciona el Blitter y, en concreto, describiremos las operaciones necesarias para pintar un BOB en el contexto de un juego.

 

 

fernando cabrera

Un artículo publicado por:

Fernando Cabrera (@fcabrera_77)
Ingeniero informático. Nostálgico del Spectrum, adorador del Amiga y aficionado a los videojuegos y a la retro-informática. Ahora también Colaborador desde mi sección para Commodore Spain. 

 

Logo El rincón de Fer

 

 

4 Comentarios sobre “Sprites, BOBs y otras criaturas mágicas (III): EL BLITTER (I)

  1. pacob

    Leído e intentado entender, me lío un poco con lo de sumar binarios pero me voy haciendo una idea, de verdad una serie de artículos realmente interesante me encanta intentar comprender como funcionan las máquinas y lo haces de una forma muy sencilla.
    Muchas gracias Fer. Imagino que resumir tanto e intentar simplificar para que un zoquete como yo entienda algo tiene que ser una ardua tarea.

    • Fernando Cabrera

      Muchas gracias, Paco! 🙂 No es fácil, sobre todo cuando se tratan según qué temas más complicados y que requieren ciertos conocimientos previos, como es el caso del Blitter. Pero merece la pena! Amplío algo más la explicación sobre el sistema binario, por si te ayuda ;).

      En un número decimal el valor de un dígito depende de su posición y en binario es igual. Por ejemplo, en el número 342 el 4, en realidad, vale 40 porque está en la posición de las decenas. El número se descompondría así:

      342 = (3 * 10^2) + (4 * 10^1) + (2 * 10^0) = (3 * 100) + (4 * 10) + (2 * 1) = 300 + 40 + 2

      En binario es lo mismo salvo que, en lugar de usar 1, 10, 100, 1000, etc. para calcular lo que vale cada dígito se usa 1, 2, 4, 8, etc. Es decir, las sucesivas potencias de 2. Ejemplo:

      10111 = (1 * 2^4) + (0 * 2^3) + (1 * 2^2) + (1 * 2^1) + (1 * 2^0) = 16 + 0 + 4 + 2 + 1 = 23

      Saludos!

  2. Edu Arana

    Excelente artículo Fer, como siempre impecable. Lo primetido, comenzaré con el primero hasta el último.

    Gracias por compartir conocimientos.

    Salu2.

    • Fernando Cabrera

      Muchas gracias, Edu :). Estoy seguro de que te graduarás con matrícula de honor ;). Y si tienes dudas según vayas leyendo los artículos, ya sabes, deja un comentario. Saludos!

Deja un comentario

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

clear formSubmit