                           VESA Video Basics

                            Matthew Probert

                           Servile  Software


This Servile Info Journal sets out to describe the basics of the VESA 
video driver. 

VESA adds a number of exciting display modes to the standard BIOS 
including;

        Code    Resolution      Colours

        6A      800 x 600       16
        100     640 x 400       256
        101     640 x 480       256
        102     800 x 600       16
        103     800 x 600       256
        104     1024 x 768      16
        105     1024 x 768      256
        106     1280 x 1024     16
        107     1280 x 1024     256
        10A     132 x 43 (text) 16

There are other modes, it depends upon the fitted video card.

Selecting a VESA video mode is done by calling the video BIOS 
interrupt 10h, with register AX set to 4F02h (VESA select mode 
function). The mode number is then passed to the VESA driver through 
the BX register pair:


/*
    Example program to allow selection of a VESA video mode from the 
    command prompt.
    Note: The supplied mode must be in decimal, not hex!
          eg 266 not 10A
*/

#include <dos.h>

void setvideo(int mode)
{
    /* Selects a VESA video display mode and clears the screen */

    union REGS inreg,outreg;

    inreg.h.ah = 0x4f;
    inreg.h.al = 0x02;
    inreg.x.bx = mode;
    int86(0x10, &inreg, &outreg);
}

main(int argc, char *argv[])
{
    setvideo(atoi(argv[1]));
}

All other standard video BIOS functions (setting pixels, displaying 
text etc.) may then be accessed with the usual function calls.


As most screen design packages are tailored for 80 column displays, it 
is perhaps worth mentioning how the output of these packages can be 
used in VESA display modes.

A problem occurs if you wish to display an 80x25 image (such as a 
screen dump produced by a drawing package such as "The Draw") in a 
132 column text mode. The following example program includes a 
function, CIM(), which offsets an 80x25 image into the middle of a 132 
column by 43 row VESA mode screen. You can easily adapt the function 
to display the image anywhere else.


---------------------------Cut Here---------------------------
#include <dos.h>
#include <mem.h>

unsigned char IMAGEDATA [] = {
   " \x07\x08\x08\x08 \x07 \x07 \x07 \x07 \x07 \x07\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06 \x06 \x06 \x06"
   "\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07\x08\x08\x08 \x07 \x07 \x07 \x07 \x07 \x07\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06 \x06 \x06\x06\x06\x06\x06 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07\x08\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06 \x06\x06\x06\x06\x06 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07\x08\x08 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08\x08\x08 \x07 \x07"
   " \x07 \x07 \x07 \x07\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\\\x60\x06\x06\x06\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x08"
   "\x06\x06\x06 \x06 \x06 \x06\x06\x06\x06\x06\x06\x06\\\x60"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07\x06\x06\x06\x06\x06 \x06 \x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\\\x60\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06 \x06\x27\x08 \x08\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07\x06\x06\x06 \x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   "\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07\x06\x06\x06 \x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07\x08\x08 \x08 \x08 \x08\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07\x08\x08 \x08 \x08 \x08\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\\\x06 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08\x08 \x08 \x08"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06-\x60-\x60\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   "\x08 \x08\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x05\x05\x05\x05\x05"
   "\x05\x05\x05\x05\\\x06\x06\x06\x06\x06\x06\x06\x06 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x05\x05\x05\x05"
   "\x05\x05\x05\x05\x05\x05\x05/\x06\x06\x06\x06\x06\x06"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x08"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07\x09\x09\x06\x06\x06\x06"
   "\x06 \x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06/\x06 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   "\x08\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x09\x09\x09 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07\x06\x06\x06\x06\x06\x06"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06/\x06 \x06\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07\x08 \x08\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x09\x09\x09"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06"
   "\x06/\x06 \x06 \x06\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07\x08 \x08\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07\x09\x09"
   "\x09 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07\x06\x06\x06\x06\x06\x06"
   "\x06\x06 \x06 \x06 \x06\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07\x08 \x08\x08 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"
   " \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07 \x07"};

unsigned char VIMAGE[132*43*2];

void CIM(void);

void setvideo(int mode)
{
    /* Sets the video display mode    and clears the screen */

    union REGS inreg,outreg;

    inreg.h.ah = 0x4f;
    inreg.h.al = 0x02;
    inreg.x.bx = mode;
    int86(0x10, &inreg, &outreg);
}


void CIM()
{
    /*
        Convert 80 * 25 image to 132 * 43
    */
    int row;
    int col;
    char *p;
    p = VIMAGE;

    /*
        Move image down 9 rows
    */
    p += 9 * 264;

    /*
        Now copy image to centre of display area
    */
    for(row = 0; row < 25; row++)
    {
        p += 52;

        for(col = 0; col < 80; col++)
        {
            *p++ = IMAGEDATA[row * 160 + col * 2];
            *p++ = IMAGEDATA[row * 160 + col * 2 + 1];
        }
        p += 52;
    }
}

main(int argc, char *argv[])
{
    unsigned char far *video;
    unsigned far *video_port;

    /*
        Select 132x43 VESA text mode
    */
    setvideo(0x010A);

    /* Determine type of video card, mono or colour */
    video_port = MK_FP(0x40,0x63);
    if (*video_port == 0x3B4)
    {
        video = MK_FP(0xB000,0);
    }
    else
    {
        video = MK_FP(0xB800,0);
    }

    /*
        Convert the 80x25 image into a 132x43 image
    */
    CIM();
    
    /*
        Copy the converted image to the VESA display
    */
    _fmemcpy(video,VIMAGE,132*43*2);
}
---------------------------Cut Here---------------------------

