112 lines
6.3 KiB
Markdown
112 lines
6.3 KiB
Markdown
Chapter 34\
|
|
Changing Colors without Writing Pixels {#Heading1}
|
|
---------------------------------------
|
|
|
|
### Special Effects through Realtime Manipulation of DAC Colors {#Heading2}
|
|
|
|
Sometimes, strange as it may seem, the harder you try, the less you
|
|
accomplish. Brute force is fine when it suffices, but it does not always
|
|
suffice, and when it does not, finesse and alternative approaches are
|
|
called for. Such is the case with rapidly cycling through colors by
|
|
repeatedly loading the VGA's Digital to Analog Converter (DAC). No
|
|
matter how much you optimize your code, you just can't reliably load the
|
|
whole DAC cleanly in a single frame, so you had best find other ways to
|
|
use the DAC to cycle colors. What's more, BIOS support for DAC loading
|
|
is so inconsistent that it's unusable for color cycling; direct loading
|
|
through the I/O ports is the only way to go. We'll see why next, as we
|
|
explore color cycling, and then finish up this chapter and this section
|
|
by cleaning up some odds and ends about VGA color.
|
|
|
|
There's a lot to be said about loading the DAC, so let's dive right in
|
|
and see where the complications lie.
|
|
|
|
### Color Cycling {#Heading3}
|
|
|
|
As we've learned in past chapters, the VGA's DAC contains 256 storage
|
|
locations, each holding one 18-bit value representing an RGB color
|
|
triplet organized as 6 bits per primary color. Each and every pixel
|
|
generated by the VGA is fed into the DAC as an 8-bit value (refer to
|
|
Chapter 33 and to Chapter A on the companion CD-ROM to see how pixels
|
|
become 8-bit values in non-256 color modes) and each 8-bit value is used
|
|
to look up one of the 256 values stored in the DAC. The looked-up value
|
|
is then converted to analog red, green, and blue signals and sent to the
|
|
monitor to form one pixel.
|
|
|
|
That's straightforward enough, and we've produced some pretty impressive
|
|
color effects by loading the DAC once and then playing with the 8-bit
|
|
path into the DAC. Now, however, we want to generate color effects by
|
|
dynamically changing the values stored in the DAC in real time, a
|
|
technique that I'll call *color cycling*. The potential of color cycling
|
|
should be obvious: Smooth motion can easily be simulated by altering the
|
|
colors in an appropriate pattern, and all sorts of changing color
|
|
effects can be produced without altering a single bit of display memory.
|
|
|
|
For example, a sunset can be made to color and darken by altering the
|
|
DAC locations containing the colors used to draw the sunset, or a river
|
|
can be made to appear to flow by cycling through the colors used to draw
|
|
the river. Another use for color cycling is in providing more realistic
|
|
displays for applications like realtime 3-D games, where the VGA's 256
|
|
simultaneous colors can be made to seem like many more by changing the
|
|
DAC settings from frame to frame to match the changing color demands of
|
|
the rendered scene. Which leaves only one question: How do we load the
|
|
DAC smoothly in realtime?
|
|
|
|
Actually, so far as I know, you can't. At least you can't load the
|
|
*entire* DAC—all 256 locations—frame after frame without producing
|
|
distressing on-screen effects on at least some computers. In non-256
|
|
color modes, it is indeed possible to load the DAC quickly enough to
|
|
cycle all displayed colors (of which there are 16 or fewer), so color
|
|
cycling could be used successfully to cycle all colors in such modes. On
|
|
the other hand, color paging (which flips among a number of color sets
|
|
stored within the DAC in all modes other than 256 color mode, as
|
|
discussed in Chapter A on the companion CD-ROM) can be used in non-256
|
|
color modes to produce many of the same effects as color cycling and is
|
|
considerably simpler and more reliable then color cycling, so color
|
|
paging is generally superior to color cycling whenever it's available.
|
|
In short, color cycling is really the method of choice for dynamic color
|
|
effects only in 256-color mode—but, regrettably, color cycling is at its
|
|
least reliable and capable in that mode, as we'll see next.
|
|
|
|
### The Heart of the Problem {#Heading4}
|
|
|
|
Here's the problem with loading the entire DAC repeatedly: The DAC
|
|
contains 256 color storage locations, each loaded via either 3 or 4
|
|
**OUT** instructions (more on that next), so at least 768 **OUT**s are
|
|
needed to load the entire DAC. That many **OUT**s take a considerable
|
|
amount of time, all the more so because **OUT**s are painfully slow on
|
|
486s and Pentiums, and because the DAC is frequently on the ISA bus
|
|
(although VLB and PCI are increasingly common), where wait states are
|
|
inserted in fast computers. In an 8 MHz AT, 768 **OUT**s alone would
|
|
take 288 microseconds, and the data loading and looping that are also
|
|
required would take in the ballpark of 1,800 microseconds more, for a
|
|
minimum of 2 milliseconds total.
|
|
|
|
As it happens, the DAC should only be loaded during vertical blanking;
|
|
that is, the time between the end of displaying the bottom border and
|
|
the start of displaying the top border, when no video information at all
|
|
is being sent to the screen by the DAC. Otherwise, small dots of snow
|
|
appear on the screen, and while an occasional dot of this sort wouldn't
|
|
be a problem, the constant DAC loading required by color cycling would
|
|
produce a veritable snowstorm on the screen. By the way, I do mean
|
|
"border," not "frame buffer"; the overscan pixels pass through the DAC
|
|
just like the pixels controlled by the frame buffer, so you can't even
|
|
load the DAC while the border color is being displayed without getting
|
|
snow.
|
|
|
|
The start of vertical blanking itself is not easy to find, but the
|
|
leading edge of the vertical sync pulse is easy to detect via bit 3 of
|
|
the Input Status 1 register at 3DAH; when bit 3 is 1, the vertical sync
|
|
pulse is active. Conveniently, the vertical sync pulse starts partway
|
|
through but not too far into vertical blanking, so it serves as a handy
|
|
way to tell when it's safe to load the DAC without producing snow on the
|
|
screen.
|
|
|
|
So we wait for the start of the vertical sync pulse, then begin to load
|
|
the DAC. There's a catch, though. On many computers—Pentiums, 486s, and
|
|
386s sometimes, 286s most of the time, and 8088s all the time—there just
|
|
isn't enough time between the start of the vertical sync pulse and the
|
|
end of vertical blanking to load all 256 DAC locations. That's the crux
|
|
of the problem with the DAC, and shortly we'll get to a tool that will
|
|
let you explore for yourself the extent of the problem on computers in
|
|
which you're interested. First, though, we must address *another* DAC
|
|
loading problem: the BIOS.
|