Let’s face it. BGIs [Borland Graphics Interface] are next to worthless for demo coding. It is difficult to find something that is slower than the BGI units for doing graphics. Another thing is, they weren’t really meant for 256 color screens anyhow. You have to obtain a specific external 256VGA BGI to get into it in Pascal, and it just doesn’t make the grade. So the question remains, how do we get into MCGA 320x200x256 mode in Pascal without a BGI?

DENTHOR, coder for ...
_____   _____   ____   __   __  ___  ___ ___  ___  __   _____
/  _  \ /  ___> |  _ \ |  |_|  | \  \/  / \  \/  / |  | /  _  \
|  _  | \___  \ |  __/ |   _   |  \    /   >    <  |  | |  _  |
\_/ \_/ <_____/ |__|   |__| |__|   |__|   /__/\__\ |__| \_/ \_/
smith9@batis.bis.und.ac.za
The great South African Demo Team! Contact us for info/code exchange!  

Grant Smith, alias Denthor of Asphyxia, wrote up several articles on the creation of demo effects in the 90s. I reproduce them here, as they offer so much insight into the demo scene of the time.

These articles apply some formatting to Denthor's original ASCII files, plus a few typo fixes.

The answer is simple: Assembly language. Obviously assembly language has loads of functions to handle the VGA card, and this is just one of them. If you look in Norton Guides to Assembly Language, it says this …

INT 10h,  00h (0)        Set Video Mode

    Sets the video mode.

       On entry:      AH         00h
                      AL         Video mode

       Returns:       None

       Registers destroyed:      AX, SP, BP, SI, DI

This is all well and good, but what does it mean? It means that if you plug in the video mode into AL and call interrupt 10h, SHAZAM! you are in the mode of your choice. Now, the MCGA video mode is mode 13h, and here is how we do it in Pascal.

Procedure SetMCGA;
BEGIN
  asm
        mov     ax,0013h
        int     10h
  end;
END;

There you have it! One call to that procedure, and BANG you are in 320x200x256 mode. We can’t actually do anything in it yet, so to go back to text mode, you make the video mode equal to 03h, as seen below:

Procedure SetText;
BEGIN
  asm
        mov     ax,0003h
        int     10h
  end;
END;

BANG! We are back in text mode! Now, cry all your enquiring minds, what use is this? We can get into the mode, but how do we actually SHOW something on the screen? For that, you must move onto the next section…

Clearing the screen to a specific color

Now that we are in MCGA mode, how do we clear the screen. The answer is simple: you must just remember that the base address of the screen is $a000. From $a000, the next 64000 bytes are what is actually displayed on the screen (Note : 320 * 200 = 64000). So to clear the screen, you just use the fillchar command (a basic Pascal command) like so:

      FillChar (Mem [$a000:0],64000,Col);

What the mem command passes the segment base and the offset of a part of memory: in this case the screen base is the segment, and we are starting at the top of the screen, offset 0. The 64000 is the size of the screen (see above), and Col is a value between 0 and 255, which represents the color you want to clear the screen to.

Putting a pixel on the screen (two different methods)

If you look in Norton Guides about putting a pixel onto the screen, you will see this:

    Writes a pixel dot of a specified color at a specified screen
    coordinate.

    On entry:      AH         0Ch
                   AL         Pixel color
                   CX         Horizontal position of pixel
                   DX         Vertical position of pixel
                   BH         Display page number (graphics modes with more
                              than 1 page)

    Returns:       None

    Registers destroyed:      AX, SP, BP, SI, DI

As seen from our SetMCGA example, you would write this by doing the following:

Procedure INTPutpixel (X,Y : Integer; Col : Byte);
BEGIN
  asm
     mov        ah,0Ch
     mov        al,[col]
     mov        cx,[x]
     mov        dx,[y]
     mov        bx,[1]
     int        10h
  end;
END;

The X would be the X-Coordinate, the Y would be the Y-Coordinate, and the Col would be the color of the pixel to place. Note that MCGA has 256 colors, numbered 0 to 255. The startoff palette is pretty grotty, and I will show you how to alter it in my next lesson, but for now you will have to hunt for colors that fit in for what you want to do. Luckily, a byte is 0 to 255, so that is what we pass to the col variable. Have a look at the following.

    CGA = 4 colours.
    4x4 = 16
    EGA = 16 colors.
    16x16 = 256
    VGA = 256 colors.
    Therefore an EGA is a CGA squared, and a VGA is an EGA squared ;-)

Anyway, back to reality. Even though the above procedure is written in assembly language, it is slooow. “Why?” I hear your enquiring minds cry. The reason is simple: it uses interrupts (It calls INT 10h). Interrupts are sloooow … which is okay for getting into MCGA mode, but not for trying to put down a pixel lickety-split. So, why not try the following …

Procedure MEMPutpixel (X,Y : Integer; Col : Byte);
BEGIN
  Mem [VGA:X+(Y*320)]:=Col;
END;

The Mem command, as we have seen above, allows you to point at a certain point in memory… the starting point is $a000, the base of the VGA’s memory, and then we specify how far into this base memory we start. Think of the monitor this way. It starts in the top left hand corner at 0. As you increase the number, you start to move across the screen to your right, until you reach 320. At 320, you have gone all the way across the screen and come back out the left side, one pixel down. This carries on until you reach 63999, at the bottom right hand side of the screen. This is how we get the equation X+(Y*320). For every increased Y, we must increment the number by 320. Once we are at the beginning of the Y line we want, we add our X by how far out we want to be. This gives us the exact point in memory that we want to be at, and then we set it equal to the pixel value we want.

The Mem method of putpixel is much faster, and it is shown in the sample program at the end of this lesson. The ASPHYXIA team uses neither putpixel; we use a DMA-Straight-To-Screen-Kill-Yer-Momma-With-An-Axe type putipixel which is FAST.

Well, after this is the sample program; have fun with it, UNDERSTAND it, and next week I will start on fun with the palette.