Aula Macedonia


Curso de Programación Multimedia Bajo DOS


Artículo realizado por
José Antonio Suárez.





Capítulo 8.
Programación de tarjetas de vídeo (VI).

2.2.- VGA 4 Planos. 320x200x4x256c


Hasta ahora, nos hemos aprovechado de la tarjeta de vídeo usando su modo 13h, pero por su diseño y circuitería este modo sólo permite el acceso a 64kbytes de su espacio de memoria. Pero hay un hecho importante, todas las tarjetas VGA tienen como mínimo 256kbytes de RAM, por lo tanto: ¿dónde está esa memoria que no puedo utilizar desde el modo estándar?

Para afrontar la entrada al modo 4 Planos o 4 Canales (CHAIN-4), es necesario explicar un poco la organización de la memoria de vídeo en su relación con las limitaciones impuestas por la BIOS del sistema.
 

2.2.1.- La Circuitería de Vídeo en Profundidad
 
La memoria está separada en 4 planos de bits. La razón estriba en la EGA, tarjeta de vídeo anterior a la VGA, y sus modos de 16 colores. Al utilizar los planos de bits, los desarrolladores permiten que cada píxel sea direccionable por un sólo byte del segmento de vídeo. Si asuminos que la paleta de colores no ha sido variada de la que está por defecto al arrancar el sistema, cada plano representará uno de los colores primarios de la EGA, es decir, R, G y B, así como la intensidad. Cuando se varía el bit que representa el píxel, el registro de Activar Plano de Escritura (Write Plane Enable) se sitúa con el color adecuado. La lectura de píxel es más complicada y lenta, ya que sólo se puede leer de uno de los planos a la vez, activando el Registro de Selección de Planos para Lectura (Read Plane Select Register).

Como cada dirección del segmento de vídeo puede acceder a 4 píxels, y hay 64 kb de direcciones posibles, 8x65536 = 524288 píxels de 16 colores pueden accederse.

En un modo de 320x200 y 16 colores se pueden tener 8 páginas (524288/(320x200)) y casi 2 de ellas si el modo es de 640x480 (524288/(640x480)).

La cosa cambia cuando la paleta es de 256 colores en vez de sólo 16. Los fabricantes de la VGA decidieron fijar el número en 4 planos, ya que la lógica de 8 planos y 256 colores no hubiese funcionado. En su lugar, una de las metas que se marcaron fue la de hacer un modo de 256 colores que resultase lo más fácil de acceder posible, y la verdad es que después de comparar el método de 8 píxels/dirección en los modos de 16 colores con la correspondencia 1 a 1 del modo 13h, se puede decir que tuvieron éxito, eso sí, no sin un cierto costo, esto es, un verdadero desperdicio de la memoria.

El espacio de direccionamiento del modo 13h está dividido por igual entre los cuatro planos de bits. Cuando un color de 8 bits es escrito en una dirección de memoria de 16 bits en el segmento de la VGA (0A000h), un plano de bit es automáticamente seleccionado por los 2 bits menos significativos de la dirección en el plano de bit seleccionado. La lectura funciona de igual manera.

Ya que los planos de bit están tan ligados a la dirección de memoria, sólo cada cuatro bytes se puede acceder a un byte en la memoria de vídeo, con lo que se desperdician 192 de los 256 kb de la memoria mínima de la VGA.

Desde luego que la eliminación de la molestia de trabajar con los planos de bit es conveniente y beneficiosa, pero para la mayoría de la gente, perder ¾ de la memoria de la VGA resulta imperdonable. (Al menos para el autor de este Proyecto).

Para acomodar este nuevo método de acceder a la memoria de vídeo, los diseñadores de la tarjeta VGA introdujeron una nueva configuración denominada CHAIN-4 que reside en el bit 3 del índice 4 del secuenciador.

En los modos de 16 colores, el estado por defecto de este bit es 0 y en la VGA funciona como se ha explicado antes, o sea se sitúa con valor 1 en los modos de 256 colores, modo 13h, con lo cual se activa este ingenioso, pero costoso, sistema de direccionamiento. En este estado, los planos de bit se dice que están encadenados, por lo que al modo 13 se le llama con frecuencia Modo Encadenado (Chained). Debe notarse que el CHAIN-4 no es suficiente por sí sólo para cambiar a un modo de 256 colores, hay otros registros que también tratan con el proceso de cambio entre los modos de 16 colores y este último.

Con este planteamiento, se puede dilucidar que si se pone a 0 el bit llamado CHAIN-4 del secuenciador, una vez que el modo 13h está activo, podremos tener acceso a los 256Kb de la VGA, ya que los 2 bits menos significativos (lógica de Intel) de la dirección de memoria de vídeo no se desperdiciarán al seleccionar el plano de bit. Pero por otro lado, habrá que olvidarse del esquema simple de direccionamiento del modo 13h.

En el momento que el bit CHAIN-4 es puesto a 0, cada cuarto píxel pertenecerá al mismo plano. Antes de escribir a un desplazamiento dentro de el segmento de vídeo, deberemos asegurarnos de que la máscara de 4 bits del registro Write Plane Enable está correctamente situada, de acuerdo con los cuatro píxels direccionables que se quieren cambiar. En esencia, funciona como un modo de 16 colores con unas pequeñas variaciones.

2.2.2.- El Modo Desencadenado (Unchained)

Los motivos por los que este engorroso-difícil modo de vídeo ha sido implementado e incluido aquí ha sido por su plasmosa suavidad en los desplazamientos de pantalla. Aquí se incluirá una rutina para hacer un desplazamiento vertical a través de dos pantallas gráficas distintas dando la impresión de que están unidas, ideal para los desplazamientos de títulos al estilo del cine. Además, otro procedimiento utilizará este modo de configurar la tarjeta para hacer un espectacular desplazamiento "rectangular" (el mismo que se ve en la "Intro" del Editor) a través de cuatro pantallas adyacentes dando la impresión de que conforman un todo.

Para comprender un poco mejor qué es este modo, pensemos en 4 pantallas distintas con resolución de 320x200 cada una. Imaginemos que las unimos conformando un cuadrado, es decir, dos arriba y dos abajo. El modo de vídeo real es de 320x200, con lo que en el monitor tan sólo 64000 píxels serán visualizados a la vez (una sola pantalla). Pero en memoria almacenaremos las cuatro y tendremos que ver al monitor como una especie de "ventana" que sólo nos permite ver una parte de esas cuatro pantallas juntas.

 

Primeramente veremos el procedimiento que programa este modo.

void ModoGraficoMcga4P(void)
{
    asm {
            mov ax,0x13
            int 0x10
            // Modo 13h seleccionado
            mov dx,0x3c4
            mov ax,0x404
            out dx,ax
            // Apagado el bit CHAIN-4
            mov dx,0x3d4
            mov ax,0x014
            out dx,ax
            // Apaga el modo de dobles palabras. Pone a 1 el Underline Location
            mov ax,0xc317
            out dx,ax
            // Pone a 1 el Mode Control Register del CRT Controller
            mov ah,80
            mov al,0x13
            out dx,ax
        }
        // Para evitar el feo efecto hardware al cambiar el modo
        PaletaNegra();
        // Borra la memoria de vídeo
        BorrarBuffer4P();
}

Como antes se indicó, el monitor será una ventana al contenido de la memoria. El siguiente procedimiento posiciona esa ventana en un espacio virtual de 640x400.

void PosicionVentana4P(int,int);

Debido al uso de los planos de bit, las rutinas gráficas tienden a hacerse más complicadas que las del modo 13h. Un ejemplo de esto es el procedimiento que pone un píxel en cualquier posición del espacio virtual de 640x400, donde se pueden apreciar las operaciones extras que hay que realizar como el cálculo del desplazamiento y la selección del plano.

void PonerPíxelMcga4P(int x,int y,char color)
{
    BYTE desp;
 
    desp=0x1<<(x&3);
    asm{
            mov al,0x2
            mov dx,0x3c4
            out dx,al
            inc dx
            mov al,desp
            out dx,al
            mov ax,SEG_VGA
            mov es,ax
            mov bx,x
            shr bx,2
            mov di,bx
            mov dx,y
            mov bx,dx
            shl bx,7
            shl dx,5
            add dx,bx
            add di,dx
            mov al,color
            stosb
        }
}

Cabe mencionar que en este modo el Write Plane Register no está limitado a la selección de sólo un plano de bit, como el registro Read Plane Enable. Se puede activar cualquier combinación de los cuatro planos que van a ser escritos.

Esta posibilidad de acceder a los cuatro píxels con sólo una instrucción ayuda a cuadruplicar la velocidad en ciertas ocasiones, especialmente cuando queremos dibujar líneas horizontales o rellenamos un polígono con un color sólido. También, la gran mayoría de los algoritmos de dibujo de bloques se pueden optimizar de forma que sólo necesiten un número constante de operaciones OUT en el registro Write Plane Enable, que normalmente son cuatro. Además, esta instrucción es relativamente lenta, luego cuantas menos utilicemos mejor.

Con lo visto de la teoría de la VGA, estos conocimientos nos permiten acceder a los 256kb de la memoria VGA que permitirá cambiar páginas visibles y otras opciones como scroll suave en grandes superficies y animación rápida y sin parpadeo, haciendo estas posibilidades oscurecer la complejidad de su programación.

Además de los procedimientos ya vistos, hay otros que se encargan de la gestión de este modo, y sus cabeceras son:

// Limpia la memoria de vídeo

void BorrarBuffer4P(void);

// Lee un píxel de la memoria de vídeo. Rango = 640x400

unsigned char LeerPixelMcga4P(int,int);

// Copia 64000 bytes en una de las 4 posiciones esquina; zona: 0=izq,arr;

//1=der,arr; 2=izq,abj; 3=der,abj

void VolcarPantalla4P(char,BYTE *);

// Copia 64000 bytes en cualquier posición dentro de los 640x400

void VolcarPantalla4PA(int,int,int,int,int,BYTE *);

El último procedimiento que veremos es el que pone un bloque en la pantalla (igual que BloqueMcga, pero para este modo de vídeo).

void Bloque4P(int xi,int yi,int xf,int yf,int ancho,int alto,BYTE *pantalla)
{
    BYTE *puntero,color,desp;
    register int x,y;
    int xfi,yfi,desplaza;
 
    xfi=xf+ancho;
    yfi=yf+alto;
    desplaza=320-ancho;
    puntero=pantalla;
    puntero+=320*yi+xi;
    for (y=yf;y<yfi;y++)
    {
        for (x=xf;x<xfi;x++)
        {
            color=*puntero;
            desp=0x1<<(x&3);
            asm{
                    mov al,0x2
                    mov dx,0x3c4
                    out dx,al
                    inc dx
                    mov al,desp
                    out dx,al
                    mov ax,SEG_VGA
                    mov es,ax
                    mov bx,x
                    shr bx,2
                    mov di,bx
                    mov dx,y
                    mov bx,dx
                    shl bx,7
                    shl dx,5
                    add dx,bx
                    add di,dx
                    mov al,color
                    stosb
            }
            puntero++;
        }
        puntero+=desplaza;
    }
}

 




AULA MACEDONIA
a
MACEDONIA Magazine