Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : FXCOL.ZIP
Filename : VGA.DOC
Output of file : VGA.DOC contained in archive : FXCOL.ZIP
Written by Chris Dunford
Edited by Jim Fowler
This document is an attempt to explains how VGA text attributes work,
and how the effects in FXCOLOR are possible. It also provides tips for
creating your own special effects.
What's different with the VGA?
------------------------------
The CGA implemented a direct relationship between a 4-bit attribute and
a color. Each attribute mapped to one color, and the color could not be
changed.
That changed with the EGA (which had palette registers to play with),
and changed again, radically, with the VGA. The attribute number
specifies the displayed color very indirectly; it is combined with bits
and pieces of 5 different internal VGA registers before it appears on
the screen as one of the 262,144 possible colors. There are, therefore,
several ways to change a character's color other than by changing its
attribute. And, of course, if you change the way an attribute is
displayed, all characters with that attribute are affected. Thus, it is
possible to "design" attributes with interesting effects, and to alter
the way entire screen fields are displayed very efficiently.
Mapping attributes to colors
----------------------------
Before we start, let me note that we are working here with 4-bit
attributes. The 8-bit attribute that's associated with a character is,
of course, two 4-bit attributes: one for the foreground, and one for the
background. This document discusses how these 4-bit attributes become
colors; everything here applies equally to foreground and background
attributes (thus it is possible to use blinking backgrounds, etc.)
Screen colors in text modes are controlled by the VGA's attribute
controller. In one of its two modes (the one that the PS/2 BIOS sets
by default), here is how a color is selected by an attribute:
AND
attribute |-------| color plane enable register
|
| selects
|
palette register 0-15 color select register
| |
| |
| bits 0-5 bits 6-7 |
+------------+------------+
|
| AND
+-------+--------video DAC mask register
|
| selects
|
video DAC color register 0-255
This appears complex, but it can be simplified. First, notice the two
logical AND operations. Since both the color plane enable register and
the video DAC mask register normally contain all ones, they tend to drop
out of the picture, resulting in:
attribute 0-15
|
| selects
|
palette register 0-15 color select register
| |
| |
| bits 0-5 bits 6-7 |
+------------+------------+
|
| selects
|
video DAC color register 0-255
The 4-bit attribute (0-15) selects one of the 16 palette registers. The
palette register contains a number. This number is combined with the
contents of the color select register to form another number. For
example, suppose:
attribute = 13
palreg[13] = 1Bh
CSR = 3
Attribute 13 selects palette register 13, which contains 1Bh. The color
select register contains 3. We put the contents of the color select
register in bits 6-7 of the final number, and the contents of palreg[13]
in bits 0-5:
3 1Bh
-- ------
11 011011
The resulting number is 11011011 binary, 219 decimal. This number
selects one of the 256 video DAC color registers.
The color that will be displayed is the color defined by the selected
video DAC color register (DAC stands for Digital-to-Analog Converter).
Each video DAC register is an 18-bit register that contains three 6-bit
values: one for each of the red, green, and blue primary colors. Each
value specifies the intensity of that primary color on the screen. A
zero for a primary means that it's not included in the color; 63 is
maximum intensity.
Suppose, in our example, that video DAC register 219 contains the
numbers 0, 3Fh, and 3Fh (it's convenient to think of the register as
three 6-bit values rather than one 18-bit value). This means that red
will be off, and green and blue will be at maximum intensity. The color
displayed by attribute 13 will be bright cyan.
Notice that you could change the color of a character with FG attribute
N in four different ways:
1. Change the attribute
2. Change the contents of palreg[N]
3. Change the contents of the video DAC register specified by
palreg[N] and the color select register
4. Change the contents of the color select register
These all have different effects on the total screen display. Changing
an attribute affects a single character; changing a palette register
affects all characters with that attribute; changing a video DAC
register affects any character whose attribute, when combined with color
select, selects that register -- this could be several attributes;
changing the color select register could very well affect everything on
the screen.
Another way to visualize color selection
----------------------------------------
There is a simpler way to look at the process. The two bits used from
the color select register always end up in the high two bits of the
video DAC color register number. Thus, the selected DAC color register
will always be one of:
CSR=0: 00xx xxxx (register range 0-63)
CSR=1: 01xx xxxx (64-127)
CSR=2: 10xx xxxx (128-191)
CSR=3: 11xx xxxx (192-255)
The remaining 6 bits come directly from the selected palette register.
If we break the 256 video DAC color registers into four palettes of 64
colors each, as follows:
DAC registers Palette
0-63 0
64-127 1
128-191 2
192-255 3
then the color select register selects one of the four 64-color
palettes, and the palette register (which is selected by the attribute)
selects one of the 64 colors of the CSR-selected palette.
Thus, it's simply stated: the attribute selects one of the 64 colors
available from the palette selected by the color select register.
Mode 1
------
I mentioned that the above represents one of the two modes supported by
the attribute controller; call it "mode 0". The other mode (mode 1) is
very similar; the only difference is in which bits are combined from the
palette register and the color select register. The simplified diagram
is as follows:
attribute 0-15
|
| selects
|
palette register 0-15 color select register
| |
| |
| bits 0-3 bits 4-7 |
+------------+------------+
|
| selects
|
video DAC color register 0-255
The difference is that there are four bits each from the palette
register and the color select register (instead of 6 and 2 under the
mode 0).
The effect of mode 1 is that the 256 video DAC color registers are
broken down into sixteen 16-color palettes instead of four 64-color
palettes:
DAC registers Palette
0-15 0
16-31 1
32-47 2
...
240-255 15
The palette register (still selected by the attribute) selects one of
the 16 colors available in the palette selected by the current color
select register.
The more complex effects (fading, pulsing, etc.) of FXCOLOR are
generated under mode 1. This is because all 256 colors defined by the
video DAC color registers can be accessed by simply changing the
contents of the color select register, which is very efficient (it
takes less than 1/100th of a second).
Under mode 0, only 75% of the available colors can be accessed by just
changing the color select register (this is because there are 64 colors
per palette, but only 16 attributes). To get to the remaining colors,
you have to change the palette registers. But there are 16 palette
registers; if you need to alter more than one displayed color, this is
less efficient than using the color select register.
A mode 1 technique
------------------
As mentioned, there are a number of ways to alter displayed colors. I
will concentrate on one technique: creating a series of palettes and
then switching palettes by systematically changing the contents of the
color select register. This document concentrates on mode 1; some of
the same effects (such as periodic intensification and simulated
blinking) can be obtained in mode 0.
Note that the use of mode 1 largely dictates that you must reinitialize
the palette registers. The VGA BIOS initializes some of these registers
with values greater than 15; these will be masked in mode 1 to the low
4 bits, yielding values in the range 0..15. These values will probably
not result in the colors you intend (two attributes will yield red
foreground, for example). The simplest solution is to just fill the
palette registers sequentially with numbers from 0..15; this largely
causes the palregs to drop out of the picture: attribute N will map
directly to color N within the palette selected by the color select
register.
Assuming that the palette registers are set as described, create a
"base" palette in palette 0. That is, fill palette 0 (video DAC color
registers 0-15) with 16 base color definitions. It makes sense to set
the standard color combinations for the 16 CGA-like colors that people
will expect to see (color intensity values in hex):
DAC regs Attr R G B Color
0-2 0 0 0 0 Black
3-5 1 0 0 2A Blue
6-8 2 0 2A 0 Green
9-11 3 0 2A 2A Cyan
12-14 4 2A 0 0 Red
15-17 5 2A 0 2A Magenta
18-20 6 15 2A 0 Brown
21-23 7 2A 2A 2A White
24-26 8 15 15 15 Grey
27-29 9 0 0 3F Bright Blue
30-32 10 0 3F 0 Bright Green
33-35 11 0 3F 3F Bright Cyan
36-38 12 3F 0 0 Bright Red
39-41 13 3F 0 3F Bright Magenta
42-44 14 3F 3F 0 Yellow
45-47 15 3F 3F 3F Bright White
(In FXCOLOR, 35h is used in place of 3Fh. This leaves some room to
pulse even the bright colors by intensification.)
The second step is to duplicate palette 0 into palettes 1-15, and then
vary the color definitions for attributes of interest in some systematic
way. For example, let's specify that attribute 1 is not going to be
"blue"; it's going to be a green that continuously cycles from normal
intensity to high intensity and back. The effect is similar to blinking
text, but more subtle. To do this, set the colors for attribute 1 in
each of the palettes as follows (RGB values in hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
G 2A 2C 2E 31 33 35 36 37 38 39 3A 3B 3C 3D 3E 3F
B 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Note that the intensity of the green primary slowly increases from
normal (2Ah) in palette 0 to maximum intensity (3Fh) in palette 15.
Also note that attribute 1 no longer has anything to do with blue --
it's green.
If these values are loaded into the video DAC color registers, and you
then sequence through the palettes in a cyclical pattern (0->15->0),
characters with attribute 1 will slowly "pulse" from green to bright
green. The effect is more subtle - and readable - than simply switching
the characters off and on.
The palette change is easily and efficiently accomplished by setting the
color select register -- say, in a timer tick intercept routine. Using a
timer intercept is an ideal way to accomplish this sort of special
effect.
It is both efficient and flexible: the speed of the effect can be
adjusted by altering the values of either the incremental rate of the
palette changes and/or the interval period of timer ticks before a change
is made. Increasing the increment value for palette changes causes the
pulse rate to speed up by skipping palettes; increasing the interval
period between timer ticks before making a change slows the pulsing by
skipping clock ticks.
Effects
-------
Many "special effects" are possible using this technique.
PERIODIC INTENSIFICATION
Pulsing is a gradual change from a low intensity color to a high
intensity color. The effect can be hardened (resulting in blinking) by
using the normal color for half of the palettes and an intensified
version for the other half. For example, the following palettes blink
cyan to bright cyan (RGB values in hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
G 2A 2A 2A 2A 2A 2A 2A 2A 3F 3F 3F 3F 3F 3F 3F 3F
B 2A 2A 2A 2A 2A 2A 2A 2A 3F 3F 3F 3F 3F 3F 3F 3F
[ fx_Blink( "bg", "bg+" ) ]
The effect can be varied by altering the ratio of low intensity palettes
to high intensity palettes ("beacons", below, are simply extreme cases
of periodic intensification).
COLOR CHANGES
Another effect is to blink text from one color to another. This set of
palettes blinks bright green to bright red:
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
G 3F 3F 3F 3F 3F 3F 3F 3F 0 0 0 0 0 0 0 0
B 0 0 0 0 0 0 0 0 3F 3F 3F 3F 3F 3F 3F 3F
[ fx_Blink( "g+", "r+" ) ]
GRADED COLOR CHANGES
An interesting effect is to "grade" (fade) one color into another.
Rather than simply blinking green to red, change it gradually by fading
out the green primary and fading in the red (RGB values in hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 2 4 6 9 0C 0F 12 15 18 1B 1E 21 24 27 2A
G 2A 27 24 21 1E 1B 18 15 12 0F 0C 9 6 4 2 0
B 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[ fx_Fade( "g", "r" ) ]
This attribute will still change from green to red, but the change is
not instantaneous; it slowly fades from one color to the other, passing
through various other unnamed colors (all combinations of red and green)
on the way.
SIMULATED BLINKING
Regular hardware blinking can be simulated via a variant of the above
scheme; simply use the background color for half of the palettes (or the
foreground color, if you want to flash the background) (RGB values in
hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 3F 3F 3F 3F 3F 3F 3F 3F 0 0 0 0 0 0 0 0
G 3F 3F 3F 3F 3F 3F 3F 3F 0 0 0 0 0 0 0 0
B 0 0 0 0 0 0 0 0 2A 2A 2A 2A 2A 2A 2A 2A
[ fx_Blink( "gr+", "b" ) ]
The example flashes yellow text if displayed on a blue background.
SOFTENED BLINKING
By placing the background attribute in half of the palettes (as for
flashing) and fading out the foreground in the other half, a softer
version of blinking is possible (RGB values in hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
G 2A 24 1E 19 14 0F 0A 5 0 0 0 0 0 0 0 0
B 2A 24 1E 19 14 0F 0A 5 0 0 0 0 0 0 0 0
[ fx_Blink( "bg", "n", .T. ) ]
The example shows softened blinking of cyan text on a black background.
If any of the background primaries are also components of the
foreground color, do not fade those (RGB values in hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
G 2A 24 1E 19 14 0F 0A 5 0 0 0 0 0 0 0 0
B 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
[ fx_Blink( "bg", "b", .T. ) ]
The example shows softened blinking of cyan on blue.
FADING
This is an even softer version of blinking text. It fades the
foreground over the full 16 palettes by grading the foregound color
into the background color (RGB values in hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
G 2A 27 24 21 1E 1B 18 15 12 0F 0C 9 6 4 2 0
B 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[ fx_Fade( "g", "n" ) ]
The example fades a green foreground into a black background. If the
background is a color other than black, a graded color change from the
FG color to the BG color is used.
STROBES AND BEACONS
These are two other effects (not in the demo). A strobe is a color
that's invisible most of the time (BG=FG) but flashes briefly to maximum
intensity. The following palettes strobe yellow when used with a blue
background (RGB values in hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3F
G 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3F
B 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 0
A beacon is a low intensity color that briefly flashes to maximum
intensity. The following palettes create a blue beacon (RGB values in
hex):
Palette 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
G 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
B 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3F
IMPORTANT: Note that only palettes that are a multiple of the palette
incremant rate are ever used. E.g., if the palette increment rate is 2,
palette 15 will not be used; put the strobe or beacon color in palette
14 instead.
Advantages/disadvantages
------------------------
Creating special effects in this manner has several advantages over
using hardware effects (such as blinking), and some disdvantages. Among
the advantages are:
- MANY more effects are possible; I have mentioned only a few of the
possibilities.
- Transition rates are under your control; the hardware blink rate
is fixed.
- Effects can be mixed on one screen (one attribute could be a
strobe, another a graded color change).
- Any effect can be applied to background as well as foreground.
Among the disadvantages are:
- A background timer routine has some effect on system efficiency
(but it's small).
- Effects are associated with attribute numbers, not with bit
positions.
The last one bears some explanation. Hardware blinking is associated
with a single bit (bit 7) of the FG/BG attribute byte. Thus, you have
16 FG colors, all of which can be blinked. Software-controlled special
effects, however, are associated with attributes. If you set, say,
attribute 6 to be pulsed green, you no longer have a brown attribute
available. Thus, the number of effective "base" colors is reduced for
each special effect attribute you create.
Mode 0
------
I have covered attribute control mode 1 in some detail, but some of the
same effects can be accomplished in mode 0. The primary difference is
that you have only four palettes to work with. The simpler effects such
as color changes, periodic intensification, and simulated blink can
easily be accomplished in mode 0 by putting the second color in palette
1, and then alternating between palettes 0 and 1.
More complex effects would require periodic alterations to the palette
registers and/or color plane enable register.
Programming
-----------
The programming required to accomplish these special effects is
relatively straightforward. The VGA BIOS provides the necessary
services; but register-level programming is used in FXCOLOR to eliminate
distracting "blips" caused when RGB values or palettes are changed.
The linkable object module
--------------------------
FXCOLOR.OBJ(ASM) provides a linkable object module containing callable
functions for Clipper 5.01 that can be used to generate all of the
special effects described above, and others.
Be sure to call fx_Enable() when you start and fx_Disable() when you
exit.
The demo program (FXDEMO.PRG) demonstrates use of the commands.
Author and reference
--------------------
The original document is by:
Chris Dunford
CompuServe ID# 76703,2002
The original document is copyright (C) 1989 by Chris Dunford. Permission
is granted to distribute freely by electronic or other means, but it may
not be republished without permission. This document is an edited version
of the original and is presented here with permission.
Edited by:
Jim Fowler
CompuServe ID# 73340,3325
Clipper is a registered trademark of Nantucket Corp.
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/