CURSO DE PROGRAMACIÓN GRÁFICA

Artículo 9: REGISTROS DE LAS TARJETAS GRÁFICAS

Autor: (c) Santiago Romero.
Revista: Programación Actual (Prensa Técnica) nº 9, Diciembre-1997


Los registros de las tarjetas son el dispositivo E/S de más bajo nivel de nuestros adaptadores graficos, y en este número vamos a aprender a controlarlos para aprovechar nuestra tarjeta al 100% en nuestros programas.

Los registros de las tarjetas gráficas representan acceder al nivel más bajo (más bajo significa más directo a hardware) en cuanto a programación gráfica se refiere. El objetivo es proporcionar unos conocimientos generales en lo que son los registros de las tarjetas gráficas, su uso y más tarde particularizar en algunos de ellos para conseguir una solución hardware a un problema en un programa gráfico.

Como vimos el mes pasado, cada tarjeta SVGA tiene su set de registros y por cuestiones de compatibilidad no convenía programar estas tarjetas a nivel de circuitería, de manera que solucionaremos esto usando el set de registros de las tarjetas VGA, set estándar para todos los adaptadores de este tipo y con el que las SVGA son totalmente compatibles, funcionando los programas que desarrollemos en cualquier tarjeta gráfica VGA o superior (por compatibilidad descendente).


LOS REGISTROS

Un registro, en general, constituye una variable interna implementada en circuitería, es decir, una variable del hardware. De esta manera, las CPU's tienen sus registros (EAX/EBX/ECX/D0/R0, registros intermedios, etc) con los que operan y donde almacenan datos necesarios para el proceso y ejecución de instrucciones. Las tarjetas gráficas también poseen un set de registros donde almacenan datos y parámetros importantes para el correcto funcionamiento del sistema completo que engloba la tarjeta, con el objetivo de que en el monitor aparezcan correctamente los gráficos construidos en la VideoRAM.

Los registros de las tarjetas gráficas contienen pues toda la información que define cómo debe el ordenador representar en el monitor los datos que hay en la VRAM, es decir, un registro almacena la resolución horizontal de pantalla, otro la vertical, otro la velocidad de refresco del monitor, los pixels por scanline, y así con todos los parámetros necesarios para esta representación.


REGISTROS VGA

Las tarjetas VGA poseen un set restringido y estándar de registros, el significado de algunos de los cuales puede resultar muy útil al programador. Lo importante entonces es la determinación de cuántos registros estándar VGA hay, que hace cada uno de ellos y cómo se modifica o lee el valor de estos registros.

Como veremos en el presente artículo, los registros pueden ser accedidos mediante los puertos E/S a los que están conectados, que van desde el 3b0h al 3dfh, permitiéndonos su modificación y lectura.


LOS CONTROLADORES ASOCIADOS A LA VGA

Una tarjeta gráfica consiste en varios controladores hardware (integrados en la misma placa de la tarjeta) cuya asociación produce el resultado esperado en pantalla. Podemos ver en la figura 1 una simple representación de estos controladores dentro de una tarjeta gráfica. Estos 5 controladores son los siguientes:

Controladores de la VGA

-Attribute Controller (puerto 3c0h): es el controlador de atributos, relacionado con todos los temas de colores, atributos, etc, accediéndose por el puerto 3c0h.

-VGA Sequencer (puerto 3c4h): es el secuenciador de la VGA y gestiona sus funciones más críticas e importantes (reseteo de la tarjeta, generador de carácteres, etc).

-Graphics Controller (puerto 3c3h): es el controlador gráfico de la VGA, dando acceso a la lectura de planos, reseteo de registros, etc.

- Cathode Ray Tube Controller (puerto 3d4h): maneja todos los datos referentes al tubo de rayos catódicos que refresca o redibuja la pantalla, en un sistema asociado al monitor.

-El SVGA Controller (puerto ???h) podemos considerar que estará presente en las tarjetas SuperVGA, conteniendo los registros extendidos para este tipo de tarjetas. Su puerto de acceso varía según el fabricante de la tarjeta, de ahí los problemas de compatibilidad en la programación de estas tarjetas.


PROGRAMACIÓN DE LOS REGISTROS VGA

Programar correctamente los registros de las tarjetas gráficas es un tema muy extenso, pero vamos a tratar de proporcionar unas reglas generales.

En principio sabemos que tenemos 4 controladores en la tarjeta gráfica (ATTRC, VGASEQ, GRAPHC y CRTC, descritos arriba) cada uno de ellos con una dirección E/S (un puerto) asignado para su acceso. Estos 4 controladores tienen cada uno una serie de registros y el objetivo es saber cómo se accede a un registro determinado y un controlador determinado.

Supongamos que queremos cambiar el color del borde de la pantalla (normalmente negro) a azul. Miramos en cualquier manual de referencia que contenga los registros de la VGA y vemos que existe un registro llamado <<Border Color Register>> al que se accede mediante el Attribute Controller. En el manual pondrá algo así como:

  Attribute Controller (3c0h):
  Border Color Register, index 11h, r/w.
  Bits (0-5): VGA screen border color.

El significado de esto es que el Border Color Register es el registro número 11h (index 11h) del ATTRC, que es de lectura y escritura (r/w), es decir, que podemos leer su valor y modificarlo, y que si los bits del 0 al 5 de este byte indican el color del borde (0=negro, 1=azul, etc).

Simplificando conceptos: los registros VGA pueden ser de escritura, de lectura, o de escritura y lectura (w, r, r/w), y cada registro de un controlador tiene un número asociado (index port o índice de puerto) que indica dentro del total de registros de un controlador a cuál nos referimos. Ahora tan sólo habría que acceder al registro nº 11h del ATTRC (puerto 3c0h), escribiendo allí el color que queremos que tome el borde, en nuestro caso azul (1).

La función que tiene el index port al acceder a un registro se puede comparar con el que tiene el registro AH (subfunción) al llamar a una interrupción, porque al igual que la interrupción 10h tiene diversas funciones, un controlador VGA puede controlar más de un registro, y necesitamos indicarle cuál de ellos queremos leer o modificar. Así pues, el índice de puerto le indica al puerto al que se escribe cuál es el registro que queremos modificar de todos los que ese puerto controla. Únicamente hemos de enviar los parámetros tal y como los requiere cada controlador, y ese es el principal problema de la programación a bajo nivel de la VGA.

Lo único complicado en este momento es que a cada controlador se accede de una manera, por lo que el procedimiento para leer (o escribir) un registro del Attribute Controller (usaremos abreviaturas a partir de ahora) no se siguen los mismos pasos para leer uno del CRTC, por ejemplo. Lo que vamos a hacer ahora es proporcionar la manera de programar cada uno de estos controladores y ver qué registros posee cada uno, de manera que ya tendremos acceso a la totalidad de ellos. Para simplificar la lectura vamos a definir las siguientes direcciones E/S:


 #define ATTRC   3c0h
 #define VGASEQ  3c4h
 #define GRAPHC  3ceh
 #define CRTC    3d4h

Aunque cada controlador se acceda de diferente forma, al final del artículo desarrollaremos un procedimiento general que contemple todos los casos y permita leer/modificar cualquier registro llamando a dicha función, simplificando así el trabajo con los registros.


GRAPHICS CONTROLLER (3ceh)

Vamos a ver primero el caso del Graphics Controller porque es el más sencillo de acceder de los 4. El GRAPHC posee 8 registros internos importantes a los que se accede desde el puerto 3ceh. Según queramos modificar o leer un registro habremos de:

->Escritura: Se envía al controlador el Index Port (registro a modificar) y se escribe el valor que se le desea asignar en el puerto asociado, PUERTO+1.


void GRAPHCwrite( index, valor )
{
 outportb( GRAPHC, index );
 outportb( GRAPHC+1, valor );
}

Estas dos llamadas a outportb también se pueden concretar en un solo outport() (o <out dx, ax>) de 1 word, que envía el byte bajo al puerto especificado y el byte alto a puerto+1. Para los amantes de la optimización visual, las 2 sentencias anteriores se reducen a un solo outport( GRAPHC, index|valor<<8 );

->Lectura: La lectura es igual de sencilla y consiste en envíar el índice de puerto al controlador y leer del puerto contiguo, tal y como hace el siguiente código:


char GRAPHCread( index )
{
 char valor;
 
 outportb( GRAPHC, index );
 valor = inportb( GRAPHC+1 );
 return(valor);
}


CATHODE RAY TUBE CONTROLLER (3d4h)

El controlador de tubo de rayos catódicos (CRTC) se programa de igual manera que el Graphics Controller, pero teniendo en cuenta que el CRTC dispone de una protección contra escritura de registros que debe ser eliminada antes de intentar modificar cualquier registro que sea accedido mediante el puerto 3d4h.

->Escritura: Si vamos a modificar algún registro habremos de desproteger los registros de CRTC, como se indica unas líneas más abajo. Después basta con realizar la modificación:


void CRTCwrite( index, valor )
{
 outportb( CRTC, index );
 outportb( CRTC+1, valor );
}
 
->Lectura: Para realizar una operación de lectura no es necesario quitar la protección del CRTC, ya que no modificamos sus registros. Basta pues con leer los valores mediante:


char CRTCread( index )
{
 char valor;

 outportb( CRTC, index );
 valor = inportb( CRTC+1 );
 return(valor);
}

->Desprotección: La desprotección se realiza poniendo a 0 el bit 7 del index o registro 11h, realizándose primero la lectura por el método ya descrito y después la desprotección. Este bit (bit 7) cuando está a uno impide la modificación de los registros y debe ser limpiado (bit 7=0) para realizar nuestras operaciones de escritura:


void UnProtectCRTC( void )
{
 int valor;
 outportb( CRTC, 0x11 );
 valor = inportb( CRTC+1 );
 valor = valor & 0x7F;
 outportb( CRTC, 0x11 );
 outportb( CRTC+1, valor);
}

Basta además con realizar una sóla vez la desprotección y restaurarla antes de salir de nuestro programa (activando el bit 7 con un procedimiento similar).


VGA SEQUENCER (3c4h)

La programación del secuenciador de la VGA es igual que la del GRAPHC y CRTC con la excepción de la escritura cuando el puerto de índice es 1. La función 1 significa la modificación del registro de polaridad del reloj de la VGA, y es un caso especial porque antes de modificar este registro se debe resetear el secuenciador. Esto se controlaría de la siguiente manera:

->Escritura: Tan sólo hay que considerar la excepción del registro 1:


void VGASEQwrite( index, valor )
{
 if ( index == 1 )
 {
  outport( VGASEQ, 0x0100 );
  outport( VGASEQ, valor<<8|1 );
  outport( VGASEQ, 0x0300 );
 }
 
 else
 {
  outportb( VGASEQ, index );
  outportb( VGASEQ+1, valor );
 }
}

->Lectura: El sistema de lectura es igual que el de los anteriores sea cual sea el registro al que se desea acceder.


char VGASEQread( index )
{
 char valor;

 outportb( VGASEQ, index );
 valor = inportb( VGASEQ+1 );
 return(valor);
}


ATTRIBUTE CONTROLLER (3c0h)

El Attribute Controller (puerto 3c0h) posee aprox. unos 20 registros. Este es el controlador más complicado de acceder:

->Escritura: Antes de poder acceder al ATTRC debemos limpiar un "flip-flop" interno de la VGA que controla la lectura y escritura. Esto se hace leyendo del Status Register (al que llamaremos STATUS_P), situado en el puerto 3dah. Para resetear el flipflop (un componente hardware que no nos interesa) basta con leer del puerto, ignorando el valor leido.

Después de leer de este puerto de estado, se le envía al Attribute Controller el número de índice de puerto (el registro que se quiere modificar) y posteriormente el valor que se desea asignar al registro.


#define STATUS_P 3dah

void ATTRCwrite( index, valor )
{
 inportb (STATUS_P);
 outportb( ATTRC, index );
 outportb( ATTRC, valor );

 outportb( ATTRC, 0x20 );
}

Después de cada acceso al Attribute Controller se desactiva el refresco de la pantalla y, como se puede ver en el listado anterior, al finalizar las operaciones de escritura activamos de nuevo este refresco mediante:


 outportb( ATTRC, 0x20 );

También puede reactivarse este refresco activando el bit 5 del index al escribirlo en el ATTRC.

->Lectura: Al igual que en la escritura, debe leerse primero del puerto de estado (3dah) y después enviar el índice de puerto al ATTRC. El valor del registro que queremos leer lo obtendremos del puerto ATTRC+1:


char ATTRCread( index )
{
char valor;

 inportb ( STATUS_P );
 outportb( ATTRC, index );
 valor = inportb( ATTRC+1 );
 outportb( ATTRC, 0x20 );
}


OTROS REGISTROS

Hay también registros de la VGA que aunque están asociados a un controlador tienen una dirección E/S propia, como por ejemplo el Status Port (3dah), que es parte del CRTC. En el caso de estos registros con dirección propia, para leer o escribir en ellos basta con leer o escribir en el puerto correspondiente (en este caso 3dah). No es necesario especificar el nº de registro porque ese puerto tan sólo contiene 1.

->Escritura: outportb(puerto, valor);
->Lectura: valor = inportb(puerto);


IMPLEMENTACION DE LAS FUNCIONES

Hemos visto métodos más o menos complejos de acceder a los controladores y alguno de los que siguen la serie de artículos de programación gráfica puede haberse perdido durante la explicación técnica. Para aclararlo vamos a implementar 2 funciones (ReadVGAREG() y WriteVGAREG(), listados 1 y 2) para leer y modificar registros de cualquier controlador mediante una única función. Servirá también como resumen de lo visto hasta ahora sobre registros y como adición a las librerías de este mes.

  LISTADO 1: Lectura de registros VGA.

char ReadVGAREG( int port, char index )
{
char valor;

 switch ( port )
 {
  case ATTRC:
    inportb(STATUS_P); 
    outportb(ATTRC, index);
    valor = inportb(ATTRC+1); 
    outportb( ATTRC, 0x20 );
    break;

   case VGASEQ: 
   case GRAPHC:
   case CRTC:
     outportb(port, index);    
     valor = inportb(port+1);
     break;

   default:
      valor = inportb(port);
      break;
 } 

return(valor);
}


 LISTADO 2: Escritura de registros VGA.

void WriteVGAREG( int port, char index, char valor )
{
 switch (port)
 {
  case ATTRC:
    inportb(STATUS_P);
    outportb(ATTRC, index);
    outportb(ATTRC, valor );
    outportb( ATTRC, 0x20 );
     break;

  case VGASEQ:
    if (index == 1)
    {
     outport(VGASEQ, 0x0100);.
     outport(VGASEQ, valor<<8|1);
     outport(VGASEQ, 0x0300);
     break;
    };
  case GRAPHC:
  case CRTC:
    outport( port, index|valor<<8);
    break;

   default:
     outportb(port, valor);
     break;
  } 
}

Con las nuevas funciones desarrolladas, retomemos el ejemplo que planteábamos al principio sobre cambiar el color del borde. Sabemos que el Border Color Register está situado en el Attribute Controller, index 11h. El cambio del color del borde a azul (1) se reduce a:


 WriteVGAREG( ATTRC, 0x11, 1 );


SET DE REGISTROS VGA

Con todo lo visto hasta ahora se han proporcionado los métodos de acceso a los distintos controladores para modificar/leer el valor sus registros. Ahora lo importante radica en conocer qué significa el valor de cada registro, y las consecuencias que tendría su modificación (que al fin y al cabo es lo que nos interesa). En las tablas 1, 2, 3, 4 y 5 podemos ver los registros más interesantes en un aspecto básico (no están todos comentados), pudiendo encontrar la lista completa en el CD que acompaña a la revista.

     TABLAS 1, 2, 3, 4 y 5: Algunos registros VGA

----------------------------------------------------------------------
Port-Index: 02h              Port: 03c4h
Registro: Color plane write enable register
Descrip.: Controla la escritura en los diferentes planos de la VRAM.
            Bit 7, 6  Reservados
            Bit 3     Permitir escritura en plano 3.
            Bit 2     Permitir escritura en plano 2.
            Bit 1     Permitir escritura en plano 1.
            Bit 0     Permitir escritura en plano 0.
----------------------------------------------------------------------
Port-Index: 04h              Port: 03c4h
Registro: Memory mode register
Descrip.: 
            Bit 4-7  Reservados
            Bit 3    Bit Chain 4. (b3=1 -> modos de 256 colores).
            Bit 2    Direccionamiento Odd/even.
            Bit 1    Activado si hay más de 64 de VRAM.
            Bit 0    b0=1: modo alfanumérico. b0=0: modo gráfico.

----------------------------------------------------------------------
Port-Index: 01h              Port: 3d4h
Registro: Horizontal display enable register
Descrip.: Nº total de carácteres visualizados (horiz.) menos 1.
----------------------------------------------------------------------
Port-Index: 02h           Port: 3d4h
Registro: Start Horizontal blanking register
Descrip.: Carácter en el que empieza el blanqueo.
----------------------------------------------------------------------
Port-Index: 04h               Port: 3d4h, 3b4h
Registro: Start Horizontal retraze register
Descrip.: Carácter en que empieza el retrazo horizontal.
-----------------------------------------------------------------------
Port-Index: 0ah              Port: 3d4h
Registro: Cursor Start Register
Descrip.: Indica línea inicial (0-16) donde empieza el cursor hardware.
            Bit 7, 6 : reservados.
            Bit 5  : Cursor off
            Bit 4-0  : Cursor Start
-----------------------------------------------------------------------
Port-Index: 0bh              Port: 3d4h
Registro: Cursor End Register
Descrip.: Indica línea final (0-16) donde empieza el cursor hardware.
            Bit 7 : reservado.
            Bit 6, 5  : Cursor skew.
            Bit 4-0  : Cursor end.
-----------------------------------------------------------------------
Port-Index: 13h              Port: 3d4h, 3b4h
Registro: Offset/Logical Screen Width register
Descrip.: Anchura lógica entre 2 scanlines sucesivos.
Port-Index:               Port: 3dah
Registro: CTRC Status register
Descrip.: Indica el estado del retrazo vert. Y horiz.
        Bit 3: Retrazo vertical:
                 0 = refrescando.
                 1 = volviendo.
        Bit 0: Retrazo horizontal:
                 0 = refrescando.
                 1 = volviendo.
----------------------------------------------------------------------
Port-Index: 05h              Port: 03ceh
Registro: Mode register
Descrip.: Especifica el modo de lectura y escritura de los datos.
            Bit 7     Reservado (0).
            Bit 6     (b6=1) modo de 256 colores.
            Bit 5     Modo de rotación de registros.
            Bit 4     Modo odd/even de direccionamiento.
            Bit 3     Lectura de datos (b3=0 leer, b3=1 comparar).
            Bit 2     Reservado (0).
            Bit 1, 0  Modo de escritura de datos.
                      0 = escritura directa,
                      1 = transferencia VRAM a VRAM,
                      2 = Uso de color o patrón.
----------------------------------------------------------------------
Port-Index: 06h              Port: 03ceh
Registro: Miscellaneous register
Descrip.: Define datos de distintos tipos (mapeado, modo, etc).
            Bit 7-4  Reservados
            Bit 3-2  Segmento de memoria (g_window) y su tamaño.
                  00 = A000h -> 128k
                  01 = A000h -> 64k
                  10 = B000h -> 32k
                  11 = B800h -> 32k
            Bit 1    Odd/even enable (used in text modes)
            Bit 0    Graphics mode enable
----------------------------------------------------------------------
Port-Index: 10h              Port: 03c0h
Registro: Mode control register
Descrip.: Datos referentes a los modos de vídeo.
            Bit 6  (VGA) Si b6=1, la anchura del pixel = 8 (256 colores).
            Bit 5  (VGA) Si 0, se ignora la comparación de línea.
            Bit 4  Reservado
            Bit 3  Si b3=1, el bit 7 del byte de atributo significa
                   parpadeo. Si es 0, ese bit significa intensidad.
            Bit 2  Si b2=1: caracteres de 9 bits.
            Bit 1  Modo monocromo si es 1. Color si es 0.
            Bit 0  b0=1->modo gráfico. B0=0->modo de texto.
----------------------------------------------------------------------
Port-Index: 11h              Port: 03c0h
Registro: Screen border color register
Descrip.: Indica el color del overscan (borde).
----------------------------------------------------------------------
Port-Index: -              Port: 03c7h
Registro: Lookup table read index register.
Descrip.: Indica el color a leer en el registro 03c9h (cambia el puntero
           dentro de la paleta interna de la tarjeta de vídeo).
----------------------------------------------------------------------
Port-Index: -              Port: 03c8h
Registro: Lookup table write index register.
Descrip.: Indica el color a escribir en el registro 03c9h (cambia el puntero
           dentro de la paleta interna de la tarjeta de vídeo).
----------------------------------------------------------------------
Port-Index: -              Port: 03c9h
Registro: Lookup table data register.
Descrip.: Apunta a la paleta interna (actual), dentro del color especificado
           con los registros 03c8h o 03c7h, y en este puerto podemos modificar
           esta tabla (cambio/lectura de la paleta).
           dentro de la paleta interna de la tarjeta de vídeo).
----------------------------------------------------------------------


UN REGISTRO DE EJEMPLO

Para comprender la importancia de estos registros vamos a comentar el Registro de estado del CRTC (STATUS_P, 3dah), cuya descripción puede verse en la tabla 2. El significado de sus bits es sencillo de interpretar y proporciona información sobre los retrazos verticales y horizontales.

Como ya sabemos, en el monitor hay un haz de electrones (tubo de rayos catódicos) que bombardea el fósforo del monitor componiendo pixel a pixel la imagen final entre 60 y 70 veces por segundo, tomando de la VRAM los bytes que representan cada color. Al final de cada línea horizontal se produce un retorno a la siguiente línea (Retrazo Horizontal), y al finalizar el retrazado completo el haz vuelve a (0,0) (incluido el borde) desde el final de la pantalla (como vimos en el nº 2). A este tiempo de retorno se le llama, pues, Retrazo Vertical. En este período de tiempo el haz está volviendo y no redibujando, de manera que podemos aprovechar este tiempo muerto para escribir en VRAM sabiendo que hasta el próximo refresco no aparecerán los cambios que estamos realizando (deben ser cambios muy rápidos). De esta manera nos aseguramos que no habrá parpadeo ni nieve debido a estas escrituras. Como se puede ver en la descripción, el bit 3 de este registro indica:

  Bit 3 = 0 -> Haz redibujando la pantalla.
  Bit 3 = 1 -> Haz volviendo a (0,0).
La manera de esperar este tiempo muerto para redibujado de pantallas consiste en esperar a que el haz se encuentre redibujando (=refrescando) la pantalla (bit3=0), y luego esperar a que acabe de hacerlo (bit3=1), volviendo. Si sólo se comprobara esta última condición podríamos encontrarnos con el haz a punto de llegar a (0,0) con el consiguiente parpadeo en las operaciones gráficas. Veamos como sería el código de espera al retrazo vertical (WaitVRetrace()):


 mov dx, 3dah
 vert1:
       in al,dx
       test al,8
       jnz vert1
 vert2:
        in al,dx
        test al,8
        jz vert2

El código está implementado en assembler porque tras su ejecución tenemos un tiempo mínimo (el que tarde el haz en volver a (0,0)) para realizar cambios en VRAM, de manera que la sincronización ha de ser lo más rápida posible. Con funciones C/PASCAL (outportb(),port[]) habría saltos, accesos a pila, retornos, etc, malgastando un tiempo demasiado importante.

Con este mismo registro también podemos sincronizarnos con el retrazo horizontal mediante el bit 1 (como se hace en las barras de copper, por ejemplo). Otra posible aplicación es generar (para cualquier tipo de juego, animación o efecto) los fotogramas en una pantalla virtual, esperar el fin de retrazado y volcar esta pantalla virtual sobre la VRAM, repitiendo continuamente el proceso.


NOTA BAJO WINDOWS 3.x/95

Si tratamos de reprogramar los registros bajo una ventana DOS de texto, nuestro programa deberá ejecutarse a pantalla completa (ALT+ENTER), ya que en otro caso no apreciaremos cambio alguno debido a que las ventanas una emulación de lo que hay en la VRAM de texto. El timing además será incorrecto, es decir, los retrazos no serán exactos, y cuestiones similares. Para la ejecución de los ejemplos se recomienda pués arrancar en modo MS-DOS o ejecutar los programas como <Programas DOS>, al igual que hacen la mayoría de programas comerciales (principalmente juegos) que utilizan los registros de la tarjeta de vídeo para conseguir más calidad y velocidad.


UTILIDAD DE LOS REGISTROS

Mirando detenidamente las tablas los registros, estos parecen simples variables internas de información sin utilidad alguna, cuando en realidad, como veremos en el siguiente número, sirven para multitud de tareas, tales como crear resoluciones no estándar, hacer scrolles por hardware con/sin Split Screen, sincronizar tareas con el retrazado, etc. Mediante la lista completa de registros (incluida en el CD), información (como la del próximo mes) y algo de imaginación pueden desarrollarse efectos sorprendentes y acelerar la velocidad de nuestras rutinas gráficas.

Por ejemplo, observando la tabla 5 vemos que los 3 registros descritos tienen una gran utilidad, ya que a través de ellos puede accederse a la paleta actual (leerla o modificarla) directamente mediante la tarjeta gráfica, tal y como se hizo en el nº 4 de este curso (aunque ahora el lector ya puede comprender la metodología de aquellas rutinas).


EN LA PRÓXIMA ENTREGA

En la próxima entrega veremos una aplicación de programación de los registros VGA para utilizar los famosos modos unchained, o modos x indocumentados de la VGA, con mejores resoluciones no estándar (320x240, 256x256, 300x400, 400x300, etc.) a 256 colores, dotando de mayor resolución a nuestros programas sin pasar por los modos SVGA.

Santiago Romero .

Pulse aquí para bajarse los ejemplos y listados del artículo (6 Kb).

Figura 1: "Controladores de una tarjeta de vídeo."

Santiago Romero


Volver a la tabla de contenidos.