Breve Introducción a la Programación
                                         de
                          Super VGA con VESA (1.2 y 2.0)
                                         en
                                  Modo Real & DPMI

                      by Konstantin Zahar (koza@mindless.com)
 

UN POCO DE HISTORIA

 Al principio todo era frío, sin vida, eran tiempos del CGA, del EGA con
 sus flamantes 16 colores, del Hercules (HGC, muy famoso, snif), y otras
 muchas otras tarjetas no estandares que todavía se pueden ver en las viejas
 BYTE, pero eran pensadas para aplicaciones profesionales como AutoCAD.

 $IBM$ tenía que dar el paso, tr s el desatre comercial de la PS/2
 sobrevivió algo bueno, el VGA, que con sus primeros 64k pod¡a ofrecer
 320x200x256c y 640x480x16c. Se popularizo, se difundió, la nueva regla surg¡a
 quien hizo una importante contribución fue Michael Abrash, que nos regaló los
 Modos X, principalmente permitían usar todos los 256k, hacer scroll por
 hardware, y alcanzar nuevas resoluciones.

 El modo X tiene una propiedad caracteristica, que dependiendo el tipo de
 programa que uno haga puede buena o mala, el acceso a la memoria dividido por
 planos. Pero bueno... los fabricantes empezaron a escabiar y surgieron las
 primeras tarjetas SuperVGA, descendientes de aquellas viejas no estandares,
 solo que ahora soportaban el VGA, pero adem s le añadian caracteristicas
 extras, como m s resolucion & colores. El problema con ellas es que no estan
 diseñadas bajo un estandar, cada una de ellas se programa de diferentes
 formas, si uno quiere usar una resolución SuperVGA, tiene que hacer varias
 versiones de sus rutinas para cada uno de los chipsets mas famosos, as¡ que
 una agrupación llamada Video Electronics Standars Association (VESA) creó un
 estandar para todas las plaquetas SVGA llamado VESA BIOS Extension (VBE).

 Esta pequeña introducción es solo eso, una pequeña introducción, no voy a
 hablar de las funciones VESA del DAC, ni del Scroll, ni de modos de video de
 m s de 256 colores ni del Paginado. Asumo que sab‚s ASM, y la parte de DPMI
 esta escrita como si usaras DOS4G/W, no es dificil transladarlo a otro DOS
 extender, pero ten‚ en cuenta que aca la memoria baja esta mapeada en la
 propia pagina de mem de nuestro programa (O sea, segmento A000h==
 offset A0000h), la parte "dificil" de DPMI es alojar los bufferes en la
 memoria baja. Si se te cuelga, prob  agrandando un poco el stack.
 Yo programo habitualmente en C++, así que mi escritura esta sumamente
 influenciada por él acostumbrensé.
 

CONOCIENDO VESA VBE.

 Las principales versiones de VBE son la 1.2 y la 2.0, lo mejor es que
 nuestro programa soporte ambos, por eso recomiendo que cuando uno vaya a
 ponerse a programar lo haga con los dos estandares impresos y a mano.

 El VBE es una extensi¢n de la int 10h, el codigo puede estar en la ROM de la
 placa (O shadow RAM si es que esta activa), o en la RAM, esta £ltima manera
 se logra cargando un TSR como el UniVBE. Cuando quer‚s acceder a VBE, (Desde
 ahora lo nombrar‚ como VESA, que aunque es incorrecto, me gusta más su sonido)
 tenés que poner AH=4Fh (Para distinguir del viejo Video BIOS) y en AL el
 numero de función que querés, luego haces un int 10h y listo (o no tan listo).

El retorno en AX tiene siempre el mismo significado para todas las func's.:

 AL == 4Fh   La funci¢n esta soportada.
 AL != 4Fh   La funci¢n no esta soportada.
 AH == 00h   La funci¢n se realiz¢ con exito.
 AH == 01h   La funci¢n fall¢.
 AH == 02h   El software soporta esta funci¢n, pero el hardware no.
 AH == 03h   La llamada a la funci¢n es invalida en el videomode actual.

 Est  de m s decir que hay que controlar estos valores, principalmente en las
 llamadas a las funciones 00h==Return SVGA Info, 01h==Return SVGA Mode Info
 y 02h==Set SVGA Mode.
 Bueno, lo primero que hay que hacer es detectar si VESA esta presente,
 pidiendole que nos de la info acerca de la SVGA instalada.
 Esto es fácil si se trabaja en modo Real, pero se complica si es con DPMI:

 0h-Return Super VGA Information.

    Modo Real
 * Alojo un buffer de 256 bytes.
 * Pongo en AX 4F00h, (Elijo Funci¢n).
 * Pongo ES:DI apuntando al Buffer que hab¡a alojado.
 * INT 10h
 * Si AX != 4Fh entonces VESA no est  presente (Ouch!).
 * --UTILIZO LA INFORMACION DEL BUFFER, VER MAS ABAJO (@)--
 * Libero el buffer.

   DPMI
 * AX=100h       (Funcion de DPMI "Allocate Buffer in Real Mem")
 * BX=16         (16*16==256 bytes que le pido)
 * INT 31h       (DPMI int)
 * Si la flag C esta seteada, entonces "Error:no hay suficiente mem baja."
 * En AX me devolvio el segmento real para pasarle a la func VESA
 * En DX me devolvio el selector, para acceder desde mi prog.
 * Ahora tengo que usar la siguiente estructura RMI (Real Mode Interrupt)
   (primero ponerla toda a 0), y pasarsela luego al DPMI, el DPMI llenar
   los registros con el contenido de esta struct y con esos valores
   llamar  a la int 10h:
     DWORD EDI
     DWORD ESI
     DWORD EBP
     DWORD Reservado
     DWORD EBX
     DWORD EDX
     DWORD ECX
     DWORD EAX = 4f00h       (Funci¢n VESA 00h)
     WORD  flags;
     WORD  ES  = El Segmento Retornado Anteriormente por el DPMI host
     WORD  DS,FS,GS,IP,CS,SP,SS
 * AX=300h       (func DPMI "Simulate Real Mode Interrupt")
 * BX=10h        (le digo al DPMI que int quiero que llame)
 * CX=0
 * Pongo ES:EDI apuntando a RMI (ES=DS por supu)
 * INT 31h       (DPMI int)
 * Lo que devuelve la int 10h se encuentra en RMI, o sea:
   si RMI.EAX!= 4Fh entonces VESA no est  presente (Arghh!).
 * --UTILIZO LA INFORMACION DEL BUFFER, VER MAS ABAJO (@)--
 * AX=101h       (func DPMI "Deallocate Real Mem Buffer").
 * Pongo DX igual al Selector que me hab¡a retornado antes.
 * INT 31h       (DPMI int)
 * Si la flag C esta seteada entonces no pudo desalojar el buffer de mem baja.

Utilizando la Info que nos dio VESA

Bueno, ya lo hicimos, ahora...Que hay en el buffer que me llenó VESA??

Rta. Esto:

VBEInfoBock:

    BYTE  VESAsignature[4]         ;Debe contener 'VESA'
    WORD  VESAversion              ;Version de VESA
    DWORD OEM_ptr                  ;Puntero a una string de OEM
    BYTE  Capacidad[4]             ;Capacidades de el video actual (pa' DAC)
    DWORD Vmode_ptr                ;Puntero a los modos SVGA soportados
    BYTE  MemTotal                 ;Numero de bloques (64k) de mem en el video
/* Lo de abajo solo en VESA 2.0 para adelante */
    WORD  OEM_Software_Rev_ptr     ;Revision de la implementaci¢n por soft
    DWORD OEM_Vendor_Name_ptr      ;Nombre del Vendedor
    DWORD OEM_Product_Name_ptr     ;Nombre del Producto
    DWORD OEM_Product_Rev_ptr      ;Revision del Producto
    BYTE Reservado[222]            ;Reservado

(todos los _ptr son punteros a una stringz en la memoria real (-Vmode_ptr))

  ATENCION: En VESA 2.0 el tamaño de esta estructura es de 512 bytes, o sea que
 si la queremos usar como tal (2.0), debemos en los pasos anteriores alojar
 un buffer de 512 bytes en vez de 256, y poner en VESAsignature, antes de
 llamar a la func 00h, 'VBE2', con esto le indicamos que es un buffer de 512,
 pero igualmente no le veo mucho sentido el hacerlo.

 De esta estructura yo solo le encontre utilidad a los siguientes miembros:

 * VESAversion: Aca nos fijamos con que versión estamos laburando, ya sabés,
 si es menor a la 2.0 olvidate de usar Linear Frame Buffer y Window's con
 llamadas en modo p. (Si no sab‚s lo que es esto, m s abajo lo explico).
 El byte alto de esta word es el numero mayor de la version (1 en V1.2, 2 en
 V2.0), en el bajo esta el numero menor (2 en V1.2, 0 en V2.0), NO hagan como
 los retardados de Micro$$$oft que en el MSD se equivocaron, interpretaron
 0102h como si fuera VESA 1.02, cuando en realidad es 1.2.

 * Vmode_ptr: Este puntero apunta a los modos de video soportados por esta
 placa, los modos estan descriptos por una WORD (M s adelante explicar‚ que
 modos hay) y la lista termina con un -1 (0FFFFh).

 * MemTotal: Cuando nuestro programa esta preparado para un modo de video
 especifico, ya sabemos de antemano cuanta memoria tiene que tener como minimo
 la placa para que nuestro prog funke, con esto podemos largar el mensaje
 "Error: No hay suficiente memoria en la placa de video para modo....", aca
 esta el numero de bloques de 64k que tiene la placa.

 Bueno, ahora el siguiente paso depende del dise¤o de nuestro prog, si lo
 hicimos para que acepte varias resoluciones y/o colores, entonces nos tenemos
 que fijar en la lista de modos disponibles, y elegir el que m s nos guste o
 darle al usuario a que elija (El maldito lamo es quien manda!), pero tambi‚n
 pudimos hacerlo para una sola resoluci¢n, entonces ya sabemos que numero
 corresponde a nuestro modo de video...
 

PEDIR INFO DE EL MODO DE VIDEO QUERIDO

 Voy a suponer que nuestro prog siempre usa una resoluci¢n de 640x480x256c,
 que es el estandar que ahora se esta imponiendo. Cada modo de video en VESA
 tiene un numero correspondiente (Word) asociado, el numero se forma as¡:

 Bit 0 a 8  = Numero de modo, si Bit 8 == 0, no es un modo VESA
                             si Bit 8 == 1, si es un modo VESA
 Bit 9 a 13 = Reservado

/*** Lo de abajo a partir de VESA 2.0 ***/

 Bit 14     = Linear Frame Buffer (LFB) 0 == Usar VGA Frame (64k)
                                       1 == Usar LFB
 Bit 15     = Preservar la Memoria de video en el cambio de Modo 0 == No
                                                                1 == Si

Algunos modos de video de ejemplo

 100h    640x400x256c
 101h    640x480x256c
 102h    800x600x16c
 103h    800x600x256c
 104h    1024x768x16c
 103h    1024x768x256c

 RECORDAR: No necesariamente que sea definido por VESA significa que la
 tarjeta de video soporta ese modo, especialmente el modo 100h puede no estar
 en muchas placas, adem s depende de la memoria.

 Bueno, o sea que 101h es el alias de 640x480x256c, entonces tenemos que
 pedirle m s informaci¢n a VESA, esta vez, la info especifica de el modo que
 queremos setear. Voy a poner como se pide esta informacion, que es algo
 similar a lo que se hab¡a hecho con la funci¢n 00h, pero ahora voy a obviar
 la parte de alojar el buffer en la memoria real, en realidad, como tambi‚n es
 de 256 bytes, yo me manejo con el mismo buffer que hab¡a alojado al principio,
 o sea que lo que puse antes de dealojar el buffer pueden retirarlo.

01h-Return VBE mode Information.

  Modo Real
 * Alojo un buffer de 256 bytes (YA HECHO en la func 00h).
 * Pongo en AX 4F01h            (Elijo Funci¢n).
 * Pongo en CX 101h             (Numero de Modo de Video).
 * Pongo ES:DI apuntando al Buffer que hab¡a alojado.
 * INT 10h
 * Si AL != 4Fh entonces algo fall¢ (caracoles!).
 * Si AH != 00h entonces esta placa no soporta este modo de video (ay!).
 * --UTILIZO LA INFORMACION DEL BUFFER, VER MAS ABAJO (#)--
 * Libero el buffer (AHORA SI).

   DPMI
 * Ya aloje el buffer en la llamada a la anterior funci¢n.
 * En la struct RMI (primero la pongo a 0), pongo los siguientes valores:
     DWORD EDI
     DWORD ESI
     DWORD EBP
     DWORD Reservado
     DWORD EBX
     DWORD EDX
     DWORD ECX = 101h        (Modo de Video)
     DWORD EAX = 4f01h       (Funci¢n VESA 01h)
     WORD  flags;
     WORD  ES  = El Segmento Retornado Anteriormente por el DPMI host
     WORD  DS,FS,GS,IP,CS,SP,SS
 * AX=300h      (func DPMI "Simulate Real Mode Interrupt")
 * BX=10h       (le digo al DPMI que int quiero que llame)
 * CX=0
 * Pongo ES:EDI apuntando a RMI (ES=DS por supu)
 * INT 31h      (DPMI int)
 * Lo que devuelve la int 10h se encuentra en RMI, o sea:
   si RMI.EAX & 0x000000FF != 4Fh entonces algo fall¢ (Rayos y Centellas!).
   si RMI.EAX & 0x0000FF00 != 00h entonces esta placa no soporta este modo
                                 de video (Rechanfle!).
 * --UTILIZO LA INFORMACION DEL BUFFER, VER MAS ABAJO (#)--
 * Dealojo el Buffer tal como explique en la función 00h

 Utilizando la Info de el Modo de Video

Aca esta la struct:

VesaModeInfoBlock:

/* Obligatorios en toda VESA */
    WORD  ModeAttributes           ;Atributos del Modo
    BYTE  WinAAttributes             ;Atributos de la Win A
    BYTE  WinBAttributes             ;Atributos de la Win B
    WORD  WinGranularity            ;Granularidad de la Win
    WORD  WinSize                       ;Tamaño de la Win
    WORD  WinASegment              ;Segmento de la Win A (Casi siempre A000)
    WORD  WinBSegment              ;Segmento de la Win B (Casi siempre A000)
    DWORD WinFuncPtr               ;Puntero a la funcion de cambio de Win
    WORD  BytesPerScanLine;        ;Bytes por Scanline
/* Obligatorios desde VESA 1.2 */
    WORD  XResolution              ;Resolucion horizontal en pixeles o chars
    WORD  YResolution              ;Resolucion vertical en pixeles o chars
    BYTE  XCharSize                ;Ancho de la cell de caracter en pixeles
    BYTE  YCharSize                ;Alto de la cell de caracter en pixeles
    BYTE  NumberOfPlanes           ;Numero de planos
    BYTE  BitsPerPixel             ;Bits por pixel
    BYTE  NumberOfBanks            ;Numero de bankos
    BYTE  MemoryModel              ;Tipo de memoria
    BYTE  BankSize                 ;Tama¤o del banko en Kb
    BYTE  NumberOfImagePages       ;Numero de paginas
    BYTE  ReservedP                ;Reservado
/* Campos de Direct Color */
    BYTE  RedMaskSize              ;Me cans‚ de traducir cosas que no usas
    BYTE  RedFieldPosition         ;Me cans‚ de traducir cosas que no usas
    BYTE  GreenMaskSize            ;Me cans‚ de traducir cosas que no usas
    BYTE  GreenFieldPosition       ;Me cans‚ de traducir cosas que no usas
    BYTE  BlueMaskSize             ;Me cans‚ de traducir cosas que no usas
    BYTE  BlueFieldPosition        ;Me cans‚ de traducir cosas que no usas
    BYTE  RsvdMaskSize             ;Me cans‚ de traducir cosas que no usas
    BYTE  RsvdFieldPosition        ;Me cans‚ de traducir cosas que no usas
    BYTE  DirectColorModeInfo      ;Me cans‚ de traducir cosas que no usas
/* Obligatorios desde VESA 2.0 */
    DWORD PhysBasePtr              ;Direccion Fisica del LFB
    DWORD OffScreenMemOffset       ;Puntero a la 2da pagina del LFB
    WORD  OffScreenMemSize         ;Tama¤o de lo que queda de Mem
    BYTE  Reserved[206]            ;Reservado

Vamos a ver algunos campos de estos:

* ModeAttributes: Atributos del Modo de video, los más importantes bits:

 Bit 0 = Modo soportado por el hard        (0==NO, 1==SI)
 Bit 6 = Modo de Window's o Bank soportado (0==SI, 1==NO)
 Bit 7 = Linear Frame Buffer disponible    (0==NO, 1==SI)

* WinAAtributes & WinBAtributes: Atributos de las Windows A y B (Explicaci¢n
 de lo que es una window m s abajo).

 Bit 0 = Soportada  (0==Una sola Window 1==Varias Windows)
 Bit 1 = Leible     (0==NO, 1==SI)
 Bit 2 = Escribible (0==NO, 1==SI)

* WinGranularity: La Granularidad de la Win, o sea, cual es el salto minimo
 que puede pegar (Brutal description).

* WinASegment & WinBSegment: Segmento de cada una de las windows, casi siempre
 es en A000, pero igualmente puede ser otro segmento (como C000).

* WinFuncPtr: Puntero a la memoria real para usar la función de cambio de
 Windows. Este puntero provee una interfase m s directa con la funci¢n VESA
 05h, porque como es llamada intensivamente en algunos programas, para reducir
 el overhead que provoca hacer la int 10h, igualmente esto es solo en caso de
 que haya soporte para Window's y que estemos trabajando en modo Real, porque
 desde DPMI no creo que sea posible hacerlo, y si lo es, ser¡a muy inestable y
 lento.

* PhysBasePtr: Direccion Fisica del LFB, este es el numerito mas preciado
 cuando vamos a usar LFB, esto es lo que necesitamos para setearlo, es la
 direccion FISICA de memoria, luego tendremos que mapearla en nuestro espacio
 de mem para usarla.

 Seguramente están perdidos con dos cosas, Que significan Window's y que es el
 LFB, bueno, son los 2 metodos que implementa VESA para poder acceder a toda
 la memoria de video. Porque por ejemplo, el modo que estamos usando
 (640x480x256c==101h) ocupa 300k, cuando en la VGA queriamos usar todos los
 256k teniamos que acudir al Modo X y mediante cambio de planos y cambio del
 Start Adress pod¡amos hacerlo. Esto es por supuesto, por la antigua limitaci¢n
 de la familia x86 de segmentos de 64kb, bueno, cuando trabajamos en modo real
 seguimos teniendo esa limitación, así que hay que acudir a las window's, pero
 si estamos en modo protegido (Bajo un host DPMI en este caso) podemos usar el
 LFB, que es algo asi como con el viejo modo 13h, pero en vez de los 64kb que
 ten¡a de tamaño (en realidad 62.5kb), va a tener el tamaño que necesite, tal
 como 300k para 640x480x256c. OjO: Nuestro programa aunque este hecho con DPMI,
 tiene que seguir soportando las Window's, porque hay placas de video que no
 soportan el LFB (como una Trident 8900 vieja que tengo). Por supuesto, como ya
 dije antes, para usar LFB tiene que estar el VESA 2.0, y siempre que este,
 preferirlo usar antes que las lentas Window's.
 

SETEAR Y USAR MODO DE VIDEO CON BANKED MODE (WINDOWS)

02h-Set Super VGA video mode

 Modo Real & DPMI Seteo de Video
 * AX = 4F02h         (Funci¢n 02h de VESA)
 * BX = 101h          (Modo de Video)
 * INT 10h
 * Revisar lo que retorna en AX para ver si funco bien.

Bueno, ahora ya estamos en el modo de video 101h con Window's.

QUE ES UNA WINDOW O BANK??: Es el metodo para acceder m s all  de los 64kb
 normales que tiene el segmento en modo real y poder escribir en toda la
 memoria de la placa de video. Leemos y Escribimos en el segmento de la win,
 (El que usualmente es 0A000, a menos que en el campo WinASegment o
 WinBSegment (dependiendo la win), tenga otro valor). Antes de hacer nada
 con una window, nos tenemos que fijar si esta soportada y si es escribible,
 leible o ambas cosas. Puede haber 1 o 2 Win's, la A y la B, puede ser que
 una sea escribible pero no leible, y la otra sea leible pero no escribible,
 entonces cuando se vaya realizar una operaci¢n en la memoria de video, habr
 que elegir la win que corresponda, en el caso de las placas que yo uso, hay
 una sola window escribible y leible en A000. Ahora bien, la posici¢n de la
 win es lo que debemos variar para ir "mirando por la ventana de 64k"
 diferentes partes de los 300k que estamos usando, ejemplo:

     (0,0)
     .------------------------------------------------------------.-- Pos 0 de la Win
     |                                                                                          |
     |_____________________________________________|__ Pos 1 de la Win
     |                                                                                          |
     |_____________________________________________|__ Pos 2 de la Win
     |                                                                                          |
     |_____________________________________________|__ Pos 3 de la Win
     |                                                                                          |
     |_____________________________________________|__ Pos 4 de la Win
     |                                                                                          |
     |                                                                                          |
     '------------------------------------------------------------' (640,480)

 Vamos a suponer que nuestra win tiene una granularidad de 64k, la
 granularidad significa por que numero tengo que multiplicar la posici¢n para
 que me de la dirección en bytes en la pantalla real. Por ejemplo, los
 segmentos de la ram en modo real tienen una granularidad de 16 bytes, porque
 el segmento 0 representa 0 bytes desde el comienzo, y el segmento 1
 representa 16 bytes desde el comienzo. Aca es lo mismo, nada m s que en vez
 de 16 bytes son 64k, pero puede variar, en algunas placas son 4k, tenemos
 que tener muy en cuenta el campo WinGranularity del VesaModeInfo.

 Si queremos acceder a un pixel, supongamos el (300,200), tenemos que calcular
 ((200*640)+300), y tenemos el offset, ahora hay que cambiar la posición de la
 Win para que "veamos" esa parte, la posición de la win se calcula dividiendo
 el resultado anterior por WinGranularity(64k), ponemos la win en esa posici¢n
 y usamos el byte que esta a partir de A000 m s el resto que nos haya dado la
 anterior división. Siempre teniendo en cuenta que si vamos a escribir, usar
 una win escribible y si vamos a leer, una leible. Como habr n adivinado, hay
 que diseñar el prog para que haga la cantidad menor de cambios de posición,
 ya que es un cuello de botella.

Para cambiar la posición de la Win:

05h-Display Window Control

 Modo Real & DPMI Window Control
 * AX = 4F05h            (Función 02h de VESA)
 * BH = 00h              (SubFunción Set Memory Window)
 * BL = Win              (00h para WinA y 01h para WinB)
 * DX = Posici¢n         (En Unidades de granularidad(ej. 0,1,2,3 o 4))
 * INT 10h

 Consideraciones especiales en Modo Real
 Lo más conveniente y absolutamente recomendable cuando se trabaja en Modo
 Real es usar el puntero a la función 05h que vino en el ModeInfo (WinFuncPtr)
 para cambiar la posición de la Win, o sea:
 * AX = 4F05h            (Función 02h de VESA)
 * BH = 00h              (SubFunción Set Memory Window)
 * BL = Win              (00h para WinA y 01h para WinB)
 * DX = Posición         (En Unidades de granularidad)
 * Far Call a WinFuncPtr (En vez de int 10h)

Consideraciones especiales en DPMI
 En DPMI no se puede usar el puntero directo a la función 05h, y el llamar a
 las interrupciones es aún más lento que en el modo Real. Por eso si usamos
 DPMI siempre tenemos que fijarnos si hay posibilidad de hacer el LFB que es
 m s rapido. Igualmente existe una manera de llamar directamente a la funci¢n
 de cambio de Win, mediante otra funci¢n de VESA 2.0(0Ah), que nos devuelve el
 codigo y nosotros lo copiamos en nuestra zona de memoria, y le hacemos un
 call ahí. Este metodo no lo voy a explicar porque en este momento hice la
 prueba (Bajo Watcom C++ DOS4GW) y salta un error de page fault, as¡ que tengo
 que volver a revisar el codigo a ver que es lo que anda mal. Igualmente si
 alguien tiene codigo de como hacerlo, agradecería que me lo pasase, tambi‚n el
 codigo de LFB, porque aunque me anda perfecto, es algo que no lo v¡ en ning£n
 lado y me las rebusqué, por eso quiero saber si esta bien hecho.
 

SETEAR Y USAR MODO DE VIDEO CON LINEAR FRAME BUFFER (LFB) (Only DPMI & VESA 2)

 Usar y entender el LFB es mucho m s fac¡l y rapido que con las Windows, lo
 £nico que hay que hacer es mappear el LFB en nuestra memoria, mediante una
 llamada a DPMI y luego setear el modo de video con VESA especificandole el
 modo con LFB. Cuando salimos del programa, o no usamos mas el LFB, lo tenemos
 que desmappear de nuestra memoria con otra llamada a DPMI.

 Mapear el LFB en nuestra Memoria
 * AX = 0x800;        (Subfunc DPMI "Physical Address Mapping")
 * BX:CX = PhysBasePtr;
 * SI:DI = Tama¤o del LFB (640*480)
 * INT 31h
 * Si FlagC esta seteada entonces Error
 * Nos retorno en BX:CX el offset en nuestra memoria del LFB!

.02h-Set Super VGA video mode.

 DPMI Seteo de Video
 * AX = 4F02h         (Funci¢n 02h de VESA)
 * BX = 4101h         (Modo de Video (Notar que bit 14 esta activo==LFB))
 * INT 10h

 Listo!, ahora tenemos toda la mem que necesitamos de la placa de video en el
 LFB, para calcular el offset se hace ((y*640)+x) y lo sumamos al offset del
 LFB y ya podemos cambiar o leer ese byte. Es exactamente igual que tener un
 modo 13h pero con 300k, y por supuesto no hay que andar haciendo ES=0A000h,
 porque ya esta en el segmento de nuestra pagina de memoria, o sea que solo
 es un offset m s (Las ventajas de la arquitectura 386). Esta de m s decir
 que LFB rulz!!.

 Cuando no usamos m s el LFB hay que hacer (OjO: solo DPMI 1.0+):

 Desmapear el LFB en nuestra Memoria
 * AX = 0x801         (Subfunc DPMI "Free Physical Adress Mapping")
 * BX:CX = Offset del LFB en nuestra Mem
 * INT 31h            (DPMI int)
 

MAS ALLA DE VESA:

 VESA AUDIO
 No tengo mucha información sobre esto, aunque creo que ya sali¢ la primera
 versión del estandar. Es como el VBE pero para audio, o sea que vamos a poder
 controlar todas las tarjetas de sonido de la misma forma, una muy buena idea,
 pero no tengo m s info, solo algo que le¡ por ah¡.

VESA ACELLERATOR INTERFASE
 Las placas como la S3 tienen funciones especiales como BitBlt, dibujo de
 poligonos y otras. Con este nuevo proyecto de VESA las podremos aprovechar,
 aumentando la rapidez de nuestros programas al usar func's por Hardware, sin
 importar que placa sea la instalada.

 LAST WORDS
 As¡ como dijo Cascarudo Pimentón (Capussotto) una vez,
 "No te dejes caer en la tentación de la burgues¡a", no te dejes seducir por
 la facilidad de DirectX, si podes usar la alta resolución en DOS, y
V ESA AUDIO, y con VESA ACELLERATOR, Cartón lleno y a sembrar la anarqu¡a!!!!.
 

btw: este articulito lo escribi hace bocha de tiempo.. el error que tenia ya
        lo solucione.. pero ahora vieja.. (/MODE stone on), la onda es usar todo
        Linux y GGi (www.ggi-project.org) ya fue dos.. ya fue windoze.. linux a
        phuel (iiiiiiii!).
 
 

                                       by KoZa/jSD - koza@mindless.com
                                         Jinetes de Sizthole & Diazthole
                                         for SuDAMERiKaR7 zine #1
                                         KeeP THe MiND oPeN!