From: smayo@wang.com (Scott Mayo)
Subject: Help, VGA weirdness
Organization: Wang Labs, Lowell MA, USA
Date: Wed, 08 Apr 92 18:16:25 GMT

I am trying to make my VGA display emulate an EGA, so an application I am
writing will look more or less identical on both. It should be easy. It isn't.

For the most part, writing to the registers on an EGA and VGA
causes identical behaviour - they were designed that way. But when
it comes to setting colors, they differ, and it is causing me
to tear out my hair. If you understand VGA register programming, please
help!

Here is the problem. An EGA gives you 64 possible colors, 16 at a time.
As it turns out, that's all I need. I am trying to make the VGA give
me those same 64 colors; I still need just 16 at a time (though the
VGA could give me more than that.) I don't want to use the BIOS to set this
up; it does it right, but it is so slow I can't use it (there are a few
places where I want to twiddle the colors, as a group, several times a
second. The BIOS can't keep up.)

The first problem, figuring out which 18 bit values to load to the DAC to
get each of the 64 colors on the EGA, is solved. I think.

The current problem is that some of the colors get set properly, and the
rest don't. And I don't know why. It doesn't seem to be a timing problem -
I've tried large donothing loops between each port write to be sure.

Here is what I try: I wait for vert. retrace, and then
outbyte(0x03c8, 0);	/* select index 0 (color 0) for writing */

outbyte(0x03c9, red_for_color_0);
outbyte(0x03c9, green_for_color_0);
outbyte(0x03c9, blue_for_color_0);

outbyte(0x03c9, red_for_color_1);
outbyte(0x03c9, green_for_color_1);
outbyte(0x03c9, blue_for_color_1);
...up to color 15.

The documentation I have swears that each group of 3 writes will cause
port 0x03c8 to increment to the next color, and it seems to work. But
a number of colors come out completely wrong. It isn't just a case of
not quite getting the RGB values right, either: I set color 13 to 
black (Red=0 green=0 blue=0) and when I draw color 13 it comes out
light purple. The first few colors I set seem to be fine, though.
I can apparently set colors 0-5, and 7. I can't set 6 (it stays an
ugly brown), or 8 and higher (various ugly colors stay set).

I am doing this during vertical retrace.

My first thought was that I had a strangely cooked VGA card, but I tried
it on another card and monitor, and saw the same behaviour. It also doesn't
seem to be my software: it is too stupid and simple to be failing in such an
interesting way. I've also tried just

loop until vert. retrace...;
outbyte(0x03c8, 6);	/* set color 6 */
outbyte(0x03c9, 0);	/* .. to black: no red, no green, no blue */
outbyte(0x03c9, 0);
outbyte(0x03c9, 0);

and color 6 still stays brown. It's like it is glued down. Setting colors
5 and 7 works just fine.

Does anyone know of VGA problems in this area, certain maunfacturers
or makes that might have this problem? (I don't want to mention my
manufacturer's name until I'm sure I haven't made some stupid mistake.)
Is there some weird mode I'm in that could cause this? I am using BIOS to
set mode 0x10, then doing subsequent work with register
writes and direct memory writes. I'm using write mode 2 (graphics) if
that matters. It all works perfectly on the EGA.

The BIOS has already set the controller mode (port 0x03c0 index 0x10) to
1, and port 0x03c0 index 0x14 to 0, so the problem doesn't seem to be
the 4 bit magic substutition that goes on by default. Although, as a
side note, I did try setting 0x03c0,0x10 to 0, to defeat the override
of palatte select bits 4 & 5, and the screen went blank and stayed that
way. That's a separate problem, though. I think. I'm not using those
bits anyway, and they should be filled in with 0's from 0x03c0,0x14.

I will mail the C code to anyone who wants to look at it and laugh.

Help!
--
These are only my opinions.  You should hear my convictions.
smayo@wang.com
Newsgroups: rec.games.programmer