                      QUICK TEXT WRITES ON THE PC

                           Matthew  Probert
                           Servile Software



When a PC is in a text display mode, text can be written quickly to 
the PC screen using direct memory writes, rather than utilising the 
BIOS or DOS and the BIOS. 

Video memory starts at one of two locations dependant upon whether a 
colour or mono display adapter is fitted. The type of video adapter 
can be discovered by reading the value stored at location 0040:0063.
This code fragment shows how the type of display adapter can be 
discovered and used to set a pointer (video) to the start of display 
memory. 

    unsigned char far *video;
    unsigned far *video_port;

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


Before you can write directly to the video memory, you need to be 
aware of how it is arranged. Firstly, video memory is divided into 
pages. Each page is 4K bytes long (4096 bytes). The first page, page 0 
commences at offset 0000h, the second at offset 1000h and so on. 
Within each page are stored pairs of byte values for each text display 
character. The first byte records the ascii code of the character to 
display and the second byte the colour information. 

The function DISPLAY_TEXT() displays a text string at a specified 
screen coordinates using the colour information already on the screen. 
It assumes that a global variable 'video' has already been assigned 
the address of the start of the required video memory page. 

Notice how the temporary pointer, 'ptr', is increased to the correct 
address based upon the required display row * 160 (80 columns * 2) and 
the required column * 2. 

void DISPLAY_TEXT(unsigned char row, unsigned char column,char *s)
{
    unsigned char far *ptr;

    ptr = video + (row * 160) + (column * 2);
    while(*s)
    {
        *ptr = *s;
        ptr += 2;
        s++;
    }
}

This function could easily be adapted to accept colour information as 
well: 

void DISPLAY_COLOUR_TEXT(unsigned char row, unsigned char 
column,unsigned char colour, char *s) { 
    unsigned char far *ptr;

    ptr = video + (row * 160) + (column * 2);
    while(*s)
    {
        *ptr++ = *s++;
        *ptr = colour;
    }
}

Some drawing packages, such as "THE DRAW" enable a programmer to 
create colourful screen pages and save them as C code definitions. 
These can be displayed even quicker: 

void DISPLAY_DRAW_SCREEN(char *IMAGEDATA)
{
        memcpy(video,IMAGEDATA,4000);
}

So you should be able to see how a screen page can be read into 
memory, replaced by another page, and then redisplayed. 

This function will return the first screen page to a character 
pointer: 

unsigned char *SAVE_SCREEN(void)
{
        unsigned char far *ptr;

        memcpy(ptr,video,4000);
}

How about a quick clear screen?

void CLEAR_SCREEN(void)
{
    int n;

    for(n = 0; n < 4000; n += 2)
    {
        video[n] = 32;
        video[n + 1] = 7;
    }
}

There are ways in which these functions could be further optimized, 
but they then lose some readability. For example rather than issuing 
single bytes, words can be written/read at roughly twice the speed 
simply by using a pointer to video memory of type "unsigned int" 
rather than "unsigned char". 
