The video mode 13h
What is 13h?

Many computer games have used it such as DOOM and DOOM2, the original C&C the DOS version of C&C-RedAlert. It's also Quake's standard resolution, and QuakeII's non 3d excelerated standard resolution. So as you can see, it's a very widley used video mode... at least it WAS, until Microsoft came over and made direct-x, which by the way is about twice as slow as just programming the graphics support your self, it's just that you probabley can't tell the differance because of how fast computers are now-a-days anyway. I think I'll stick to programming my own graphics :)

One of the more interesting questions that comes up about 13h is "What is it?". There is a very simple answer to that question: 320x200x256. The only problem with that answer is the fact that not every body knows what it means.

The answer to that question is not quite so simple to answer, although once known is so simple that you will never forget what it means.

The first number in the list (which in our case is 320) tells us the horisontal resolution. Just incase you don't know what a horisontal resolution(RES) is, I'll tell you: it is the number of pixels per row on the screen

horisontal RES = 15

*____________*
---------------
---------------
---------------
---------------
---------------
---------------

The second number (in our case 200) tells us the vertical resolution(RES). The vertical RES is the number of pixels per column on the screen:

*
|---------------
|---------------
Vertical |---------------
RES = 6 |---------------
|---------------
|---------------
*

The last number (in our case 256) is the amount of possible colors to be displayed on the screen at once. it is commonly reffered to as the "color palette". There are actually 262144 possible total colors, you just can't display all of them on the screen at once (you can only display 256 of them at once).

So how do I change the video mode to 13h?

Well, this one is somthing that there is only one efficient way to do, so I'll just give you the code right here:

int init_vga_mode(void)
{
union REGS regs;
__djgpp_nearptr_enable();
vgamemory=(char *)(0xA0000 + __djgpp_conventional_base);
if((vgabuffer=(char *)malloc(320*200))==NULL)
{
return(1);
}
regs.h.ah=0x00; //Procedure 0x00: Set Video Mode
regs.h.al=0x13; //The mode to set (0x# = #h)
int86(0x10, regs, regs); //Call BIOS intr 0x10
return(0);
}

The code above will work with DJGPP if you include the following:

dos.h
bios.h
dpmi.h
stdio.h
conio.h
math.h
stdlib.h
go32.h
pc.h
sys/nearptr.h

And then you also have to declare the following global pointers:

char *vgamemory;
char *vgabuffer;

Of course one main question does come to mind... what does all that code do? Well, it changes the video mode to 13h... DUHHHHH!!! But what does each individual line do?! Well, I'll show you:

The first line is obvious:

int init_vga_mode(void)

It sets up the function, and if you don't know what "setting up a function" means then you shouldn't be reading this until you do.

The second line (after the "{" ) which is:

union REGS regs;

sets up a union of the type REGS with the name regs. That union will be later used to store the address of the hardware function that we want to execute.

The third line:

__djgpp_nearptr_enable();

enables the "real memory access by way of pointers" mode (and yes, I did make that phrase up). Since DJGPP compiles protected mode programs, we can't directly access the computer hardware and memory, so we must use this function to allow use to access them indirectly by using pointers. Again, if you don't know what a pointer is, you shouldn't be reading this until you do.

Now the third line:

vgamemory=(char *)(0xA0000 + __djgpp_conventional_base);

tells your program that "vgamemory" points to the video memory (which starts at 0xA0000) plus the djgpp conventional base. The DJGPP conventional base is one of the things that the __djgpp_nearptr_enable() function initializes, we use the DJGPP conventional base to point to certain sections of memory by adding it to the real-mode address. So basicly this line makes vgamemory point to a pointer that is pointing to the video memory (wow, that was a breath full).

The 4th line:

if((vgabuffer=(char *)malloc(320*200))==0)

sets up the video buffer which is actually not needed, but if your going to program real time graphics then it is (especially with game programming). All it does is it ask if it can allocate 320*200 bytes of memory for the video buffer, and if it can, then it does. Well, actually it does somthing a little different, but it ends out the same way.

The 5th line:

return(1);

is within the above if statement, and this will let you know that it couldn't allocate any memory for the video buffer because it returns 1 and exits the function if it can't.

The 6th line:

regs.h.ah=0x00;

puts the byte 0x00 into the h.ah section of regs (whcih, if you remember, is a union). 0x00 is the hardware operation that tells the computer that you are about to change the video mode. Right now this won't do anything, but we need it there for the int86 functio (which is comming).

Now the 7th line:

regs.h.al=0x13;

basically does the same thing as the 6th line except it puts a different byte into a different section of "regs". The byte 0x13 represents the 13h video mode, this is what will be past into the 0x00 function so that it knows which video mode to change to.

The 8th line:

int86(0x10, regs, regs);

calls the bios interupt 0x10, and passes regs.h.ah to 0x10 as the hardware function to run, and then it passes regs.h.al to 0x10 (which is basicly "run hardware procedure/function") so that 0x10 will pass it to what ever is in regs.h.ah (in our case 0x00). So this is the part of our function that actually CHANGES the video mode... all the stuff before this was just preparing to change it.

The 9th (and last) line:

return(0);

just returns 0, which means that our function has succesfully changed the video mode :)

Now how do I change the video mode back?

Well, all you really have to do is call the "video mode changing" hardware function (0x00) with the text mode byte in regs.h.al, un-allocate the video buffer, and then turn off the "real memory access by way of pointers" mode. So how do I do that?! Well, heres the code for you:

void done_vga_mode(void)
{
union REGS regs;
regs.h.ah=0x00; //Procedure 0x00: Set Video Mode
regs.h.al=0x03; //The mode to set (0x# = #h)
int86(0x10, regs, regs); //Call BIOS intr 0x10
free(vgabuffer);
__djgpp_nearptr_disable();
}

So what does each line in that do? It does what I just said above: it calls the video mode changing hardware function with the text mode byte in regs.h.al, un-allocates the video buffer, and then turns off the "real memory access by way of pointers" mode.

How does this help me when I don't even know how to plot a pixel?

It doesn't, but if you don't know how to change the color palette then pixel ploting doesn't help you either :) So now you may go on to read the DOCS on Palette Changing. Good luck!

---Nathan Vegdahl

"Adults are afraid of children thinking differently then them, THAT is why schools exist." --a Quote from Nathan Vegdahl's own mouth


Discuss this article in the forums


Date this article was posted to GameDev.net: 7/16/1999
(Note that this date does not necessarily correspond to the date the article was written)

See Also:
Graphics

© 1999-2011 Gamedev.net. All rights reserved. Terms of Use Privacy Policy
Comments? Questions? Feedback? Click here!