http://GameProgrammer.Com

Programming

GP Mailing List
     Thread Index
     Date Index

ATXGPSIG List
     Thread Index
     Date Index

Google
>

Home

Wise2Food


Tweaked VGA Modes

Bob Pendleton
Bob@Pendleton.com


Download Demo

Download Source Code

The graphics hardware in your PC draws a picture on your screen by interpreting the contents of video memory according to a set of rules called a "video mode" or just a "mode" for short. If you have VGA or SVGA graphics hardware then your graphics hardware is very flexible. These types of displays can show you the contents of memory as graphics or text, in color or in monochrome, and in resolutions ranging from 320x200 pixels to 720x480 pixels for a standard VGA and up to 1280x1024 or more for SVGA displays.

There is a set of standard video modes that are understood by the BIOSes that come with all VGA displays. You can put your display hardware in a graphics mode by just asking the BIOS to set up one of these standard modes for you. If you have an SVGA then odds are you can set up one of the VESA high resolution modes just as easily.

But what if none of the standard video modes meet the requirements of your application? If you want to do animation you need more than one page of video memory. You want to be able to write to a page that isn't being displayed while displaying another page so that you get smooth animation. If you want to display real looking graphics you want to be able to show as many different colors and as many pixels at once as possible. Multimedia, video games, and virtual reality are types of applications that need multiple pages, lots of colors, and high resolution (lots of pixels.)

If you are programming for a standard VGA (which is the common denominator of the PC graphics world) you can get good resolution from mode 12h. Mode 12 gives you 640x480 pixels to work with. But mode 12 only allows 16 colors and only one page. Mode 13h allows 256 colors at once from a palette of 262,144 colors. But, mode 13 only allows 320x200 pixels and also only supports one page. Not only is mode 13 low resolution but the pixels you get aren't square.

So what can you do? Well, as has been known for a long time, the standard VGA modes aren't magic. Each video mode is a set of values that are stored in the control registers of a VGA display. There are lots of other ways to set up the VGA that work just as well as the standard modes and let you do things you can't do with the standard modes.

These nonstandard unsupported modes are referred to as "tweaked" modes. One such mode, mode-x, has been made so popular by Abrash's articles in "Doctor Dobbs Journal" that it is used in almost every PC video game on the market.

Recently I've been doing a lot of programming in mode-x. This mode gives you 320x240 displayed pixels, 256 colors, 3 display pages, and square pixels. The last is an interesting and important point. Most of the VGA graphic modes do not give you square pixels. To get square pixels the ratio of the width to the height in pixels must be 4/3 or 1.333... Only the 640x480 modes give you square pixels. Square pixels are important if you expect to draw a square in display memory and see a square rather than a rectangle on the screen.

Like I said, I've been doing a lot of work with mode-x. I started wondering what other tweaked modes were lurking in the maze of registers that control the standard VGA. And I started wondering if tweaking the VGA could get me access to some of the abilities of SVGAs through the standard VGA registers. I wanted more pixels. (I knew I wasn't going to get more colors by tweaking.) And I wanted my pixels to be square. So I fired up my compiler and started tweaking the contents of the VGA registers.

I should say right now that in the bad old days of the original PC it was possible to fry a monitor by tweaking the video controller registers the wrong way. I don't know if it is possible to toast a modern SVGA monitor by tweaking the register contents, but if you aren't willing to take the chance you shouldn't play with register tweaking. I do know (I did it last summer and earlier today) that it is still possible to generate video modes that monitors can't synchronize to. This means that you get a weird looking display of random looking lines and sometimes the monitor makes odd noises. But as far as I know I've never damaged a monitor through tweaking. Be prepared to take the risks or don't play the game. You've been warned.

If by chance you do get random hash on your monitor after tweaking a register or while using software that uses tweaked modes punch the reset button on your machine and start over.

Digging into the descriptions of the VGA registers in Ferraro's book I quickly decided that I needed to cross check the register descriptions with the description of the VGA registers in other books. I found, much to my disgust, that I have three books that claim to describe the VGA register set and usually one of the three disagreed with the others. In some cases I found outright errors in the books. So if something I tried didn't work I look up the register description in a couple of other books and work from there. Ferraro's book seems to be the most accurate of the three I have but it is also the hardest to read.

Anyway, I found out how to tweak mode 13 from 320x200 to 320x400 mode. Then I sat back and looked at what you could hope to get out of a VGA and I decided to go out on the Internet looking for references to tweaked modes. Both activities paid off.

First off, if you look at the descriptions of the supported video modes you'll see that the VGA supports video modes that are 320, 640, and 720 pixels wide and 200, 350, 400, and 480 pixels high. You'll also notice that the 256 color mode 13 gives 320 pixels across, but is actually set up like a 640x400 mode. Turns out it is easy to divide the height by a small integer and that 256 color modes give half as many pixels on a line as 16 color graphic or text modes do. This seems to be a restriction caused by the planar nature of the VGA display memory.

The VGA has 4 planes of display memory and it reads a byte (8 bits) from all 4 planes (total of 32 bits) once for every 8 pixels (one character width) that it draws. In a 16 color mode this way of doing things gives you 4 bits per pixel for each of 8 pixels on every read. But, when displaying 256 colors it needs 8 bits per pixel so the VGA can only draw 4 pixels per "character" and must draw half as many pixels per scan line as you would expect from the way a video mode is set up.

I figured this all meant that in 256 color tweaked modes I couldn't get more than 360 pixels (720/2) across or more than 480 scan lines. But, 360x480 in 256 colors would be very nice. I was just hoping I could get 360x270 in 256 colors. It might not be a lot better than 320x240 mode-x. But anything that reduced the size of the pixels would be worth it.

About then my looking around on the net paid of. I found a great file on oak.oakland.edu in /pub/msdos/vga/tweak16b.zip. This gem was left there by Robert Schmidt of Ztiff Zox Softwear. According to the header in tweak.doc (one of the files in the zip file) Mr. Schmidt has placed the contents of the file in the public domain. Mr. Schmidt has provided us with "tweak" a tool for tweaking VGA modes, documentation of some of the key concepts behind tweaked VGA modes, and the register settings for just about all the tweaked modes that I'm interested in.

In particular he provides the information needed to set up square pixel 256 color video modes with resolutions of 320x240, 360x270, and 400x300 pixels. As well as a 256x256 pixel mode, a 320x400 mode, a 360x360 mode, and a 360x480 mode. Most of these modes can be set up on an ordinary VGA card, but you will need a monitor capable of displaying at least 800x600 to use some of these modes.

You may have noticed that tweaked modes display 64k or more pixels and that the video memory range on the PC is exactly 64k. How is it possible to access more pixels than you have addresses for? The answer is the chain 4 bit. The VGA has its memory set up in 4 planes. Each plane contains 64K bytes of display memory for a total of 256k. The chain 4 bit is used in mode 13 to make the memory look like it isn't laid out in planes. This makes it possible to map one mode 13 pixel to one byte address in the video memory address space. But it also makes it so that you can't get at of the display memory. Mode 13 is called a "chained" mode because it uses the chain 4 feature. All the tweaked modes I'm interested in are unchained. That is, the chain 4 bit is turned off in these modes.

When the chain 4 bit is turned off 4 pixels map to a 1 byte address. Writing to the address of the 4 pixels can write all 4 pixels or any of the 4 pixels. This means that writing a 32 bit word (4 bytes) to display memory will affect 16 adjacent pixels. This 4 to 1 mapping lets you write all 256K of VGA video memory through the 64K video memory address space. You use a mask in the Write Plane Enable register to control which of the 4 pixels will be written.

Using an unchained mode slows you down if you are writing a lot of single pixels because you have to set the mask register before writing the pixel and setting the register takes at least as long as writing the pixel does. But, if you are filling spans of adjacent pixels being able to fill 2, 3, or even 4 pixels at a time can buy you back some speed.

I've done some experiments with unchaining the VESA video modes. One of the real problems with using the VESA modes is that you have to use bank switching to access all the display memory used by these modes. I tried unchaining VESA mode 100, a 640x400 256 color mode. It worked. Unchained I could get at all 256,000 pixels through the 64k PC graphics address space. After trying it on my machine I checked with friends on the net and it seems it works on most if not all SVGA displays. I tried out an unchained version of the 640x480 256 color VESA mode 101 and that worked too.

Just as tweaking the chain 4 register gets you access to more video memory tweaking the vertical and horizontal timing registers and the offset register lets you change the vertical and horizontal resolution of the display modes.

The code included with this column includes a tweaked mode library that lets you use one of 7 different unchained, 256 color video modes to draw pixels, lines, filled rectangles, and do page swapping for smooth animation. I picked video modes that appealed to me for various reasons. The supported video modes are:

160x120

This is one I tweaked up using tweak. I started with 320x240 mode. I modified the maximum scan line value in the maximum scan line register to make it display 120 lines instead of 240. Then I modified the offset register and the horizontal display end register to get 160 pixels across the screen instead of 320. Finally I had to tweak the rest of the horizontal timing registers to get the image centered on the screen and to get it to fill most of the screen.

This mode has HUGE pixels. But, it doesn't have very many of them so you get 13 display pages. I really can't think of very many uses for this mode. I did it just to see if I could.

296x220

This is another mode I tweaked up starting with 320x240 mode. It is a very interesting mode to me and one that I think will be of interest in low end virtual reality systems because it is well suited for stereo viewing. Stereo viewing is a standard part of virtual reality systems. And, you need at least 4 display pages to do smooth stereo animation.

The 296x220 mode has an aspect ratio, width to height, of 1.345... which means the pixels are very close to being square. It also gives you 65,120 pixels on the screen at one time, and gives you 4 display pages. With 4 display pages you can't have more than 65,536 pixel per display page on a standard VGA.

This mode comes as close to being the perfect VGA stereo display mode as I could get. A 296x221 display mode would have an aspect ratio of 1.339 and give you one more scan line on the screen. But, try as I might, I couldn't get that mode to work properly. It seems you have to have an even number of scan lines.

Creating the 296x220 mode makes me want to look at tweaking a mode starting with VESA mode 101, a 640x480 256 color mode. It looks like you could tweak up a mode with a resolution of 592x440 or 592x442 that would give you 4 display pages with square pixels on a 1024k SVGA. Such a mode would also let you access each pixel of a display page through the 64k PC graphics address space.

320x200

This is unchained mode 13. The code shows just how easy it is to unchain a mode.

320x240

This is the famous Mode-X. This mode is used in many commercial video games. It has the same resolution as some of the other commercial game platforms, 3 video pages for smooth animation, and square pixels.

320x400

This is unchained mode 13 with the maximum scan line register tweaked to give you twice as many pixels on the screen. This mode gives you 2 display pages of 128,000 pixels each. The aspect ratio of the pixels is 0.8, a long way from a perfect 1.333... This means that the pixels are much wider than they are high. But, this is an easy mode to get into and one that should work on any VGA display.

360x360

I included this mode because it has just about as many pixels on the screen as you can get on a standard VGA and still have two display pages.

400x300

I like this mode. It has square pixels. It gives you 2 display pages on a standard VGA. And it has 120,000 pixels on the screen. I found the original version of this mode in tweak16b.zip but I changed it to use a higher clock frequency to get rid of a problem with vertical over scan. It was drawing above and below the top and bottom edges of my monitor.

If you have any trouble viewing these modes on your machine please send me email telling me the symptoms and the type of machine and display hardware you are using.


The Demo

When you fire up the demo program you'll see a simple menu that lets you select one of 3 demos and a tweaked video mode. Once you select the video mode the demo will start. To end the demo press any key and you'll return to the menu. Selecting "q" from the menu will end the demo. During the demo the current video resolution is shown in the upper left hand corner of the screen.

The "lines" demo animates a red line and a green line. This demo gives you a feel for the size and aspect ratios of the pixels available in each mode.

The "worms" demo animates a bunch of worms crawling around the screen. The worms twist and turn as they crawl along. This demo also shows the effects of the sizes of pixels and their shapes on graphics and the code reads from display memory as well as writing to it. Anyway, it was fun to write and my kids like it.

The "fract" demo recursively subdivides the pixels on the screen and assigns them a color based on a random function and the color of all regions they are members of. This creates an image that looks remarkably like an aerial photograph of cities and hills. Again, the size and aspect ratio of the pixels in the tweaked video mode affect what you see on the screen.


References:

"Programmer's Guide to the EGA and VGA Cards", Richard F. Ferraro, 2nd ed. 1990, Addison-Wesley, ISBN 0-201-57025-4

"EGA/VGA A Programmer's Reference Guide", Bradley Dyck Kliewer, 2nd ed. 1990, McGraw-Hill, ISBN 0-07-035099-X

"PC Intern" Michael Tischer, 1994, Abacus, ISBN 1-55755-145-6

"The Peter Norton PC Programmer's bible", Peter Norton, Peter Aitken, Richard Wilton, 3rd ed. 1993, Microsoft Press.

tweak16b.zip, Robert Schmidt, 1993

xsharp21.zip, Michael Abrash, 1992


Copyright 1993, 1997 Robert C. Pendleton. All rights reserved.