VGA programming

The ever - forgotten 16 color modes

 Most people knew the old VGA from it's Mode 13h, the 320x200 256 color mode. Fewer people used the undocumented so - called Mode X variants where it was possible to get resolutions up to 360x480 (at least on a plain old standard VGA) with 256 color. And hardly anyone ever used any of the high resolution 16 color modes. But there are (or were) advantages of that if such low number of colors was enough. These were basically the followings:

 If you are interested in programming this old hardware (And why wouldn't you if you are looking at this article), you should as well google for "FreeVGA". That site (some mirrors still exist, in case they would all vanish, i will mirror it as well) contains good information on the VGA registers although it is inaccurate at some points which i will outline below. So to get a complete idea of how this old hardware works, i suggest you to use both that site and this article

Resolutions and refresh rates

CRT layout

 The default 640x480 mode may be more than enough for most people due to that it has nice square pixels and is a quite good resolution, but it is only 60Hz at refresh rate, and there is not enought VGA memory for two pages of it. A 640x400 graphic mode would be neat for two pages, but sadly the BIOS does not offer such mode, not to talk about other exotic modes. In this case hand - tweaking the VGA registers may come handy.

 First of all, there are a few important things to consider. The most important of these is that the original screens driven by the VGA were very strict on their timing. The absolute low - end VGA display supports only 31.5KHz horizontal refresh rate, and either 60Hz or 70Hz vertical rate. Better displays first supported deviations in the vertical rate, the horizontal was opened later. Note that the VGA card itself can output any rate what you can program in it, your (ancient) display is what will blow up on improper programming. So if you want to tweak stuff, try with a modern CRT or LCD, and don't afraid of what your VGA card will do or not do. It won't hurt.

Setting up a new screen mode

 The most important factors determining the characteristics of the display are the horizontal and vertical total registers at the 0x03D4 - 0x03D5 ports, and the 0x03C2 register. Bits 2 and 3 of the 0x03C2 register select the pixel clock: 0 selects 25MHz, and 1 selects 28MHz. Normally these are used to matain the 31.5KHz horizontal rate at both 640 and 720 pixel wide modes. If you set up 28MHz for a 640 pixels mode, it will increase it's refresh rate with at about 12%, but also means that you will force a 35KHz horizontal rate what old VGA monitors won't handle. If you want to matain the highest compatibility, only use the following values for the horizontal total & vertical total registers (Among the appopriate pixel clock):

 An another interesting register here is bits 6 and 7 of 0x03C2. These selects the sync. polarities which old displays use to determine the vertical size of the picture. 11 selects 480 pixels which results in square pixels even if you only output 400 pixels (You will end up with a "letterboxed" display, but it will show up on the top leaving the bottom 80 pixels empty on an ancient monitor using this method to determine the vertical size); 01 selects 400, and 10 selects 350 pixels (Using these when actually outputting more pixels will most likely result in having most of your picture off the old screen).

The border

 A neat little trick you could use to increase your display size is getting rid of the border. All graphic modes have such, if you set a border color, you will see it. These extend by 8 pixels in all directions. Removing them means reprogramming the CRT controller that way that it no longer displays any border (This may be a little tricky, but possible. The problematic part is sliding away the retraces by 8 pixels). This tweak works fine on any display (except old 640x480 LCDs of course) as it does not involve any change in the actual timing (Only the video card knows if it is now displaying border or actual image). The best result is achieving a 736x496 mode tweaking from 720x480.

To be continued...