abrash-black-book/33-02.md
2013-12-30 20:26:41 +11:00

101 lines
5.9 KiB
Markdown

#### Color Paging with the Color Select Register {#Heading6}
"Wait a minute," you say bemusedly. "Aren't you missing some bits
between the palette RAM and the DAC?" Indeed I am. The palette RAM puts
out 6 bits at a time, and the DAC takes in 8 bits at a time. The two
missing bits—bits 6 and 7 going into the DAC—are supplied by bits 2 and
3 of the Color Select register (Attribute Controller register 14H). This
has intriguing implications. In 16-color modes, pixel data can select
only one of 16 attributes, which the EGA palette RAM translates into one
of 64 attributes. Normally, those 64 attributes look up colors from
registers 0 through 63 in the DAC, because bits 2 and 3 of the Color
Select register are both zero. By changing the Color Select register,
however, one of three other 64 color sets can be selected instantly.
I'll refer to the process of flipping through color sets in this manner
as *color paging*.
That's interesting, but frankly it seems somewhat half-baked; why bother
expanding 16 attributes to 64 attributes before looking up the colors in
the DAC? What we'd *really* like is to map the 16 attributes straight
through the palette RAM without changing them and supply the upper *4*
bits going to the DAC from a register, giving us 16 color pages. As it
happens, all we have to do to make that happen is set bit 7 of the
Attribute Controller Mode register (register 10H) to 1. Once that's
done, bits 0 through 3 of the Color Select register go straight to bits
4 through 7 of the DAC, and only bits 3 through 0 coming out of the
palette RAM are used; bits 4 and 5 from the palette RAM are ignored. In
this mode, the palette RAM effectively contains 4-bit, rather than
6-bit, registers, but that's no problem because the palette RAM will be
programmed to pass pixel values through unchanged by having register 0
set to 0, register 1 set to 1, and so on, a configuration in which the
upper two bits of all the palette RAM registers are the same (zero) and
therefore irrelevant. As a matter of fact, you'll generally want to set
the palette RAM to this pass-through state when working with VGA color,
whether you're using color paging or not.
Why is it a good idea to set the palette RAM to a pass-through state?
It's a good idea because the palette RAM is programmed by the BIOS to
EGA-compatible settings and the first 64 DAC registers are programmed to
emulate the 64 colors that an EGA can display during mode sets for
16-color modes. This is done for compatibility with EGA programs, and
it's useless if you're going to tinker with the VGA's colors. As a VGA
programmer, you want to take a 4-bit pixel value and turn it into an
18-bit RGB value; you can do that without any help from the palette RAM,
and setting the palette RAM to pass-through values effectively takes it
out of the circuit and simplifies life something wonderful. The palette
RAM exists solely for EGA compatibility, and serves no useful purpose
that I know of for VGA-only color programming.
#### 256-Color Mode {#Heading7}
So far I've spoken only of 16-color modes; what of 256-color modes?
The rule in 256-color modes is: *Don't tinker with the VGA palette*.
Period. You can select any colors you want by reprogramming the DAC, and
there's no guarantee as to what will happen if you mess around with the
palette RAM. There's no benefit that I know of to changing the palette
RAM in 256-color mode, and the effect may vary from VGA to VGA. So don't
do it unless you know something I don't.
On the other hand, feel free to alter the DAC settings to your heart's
content in 256-color mode, all the more so because this is the only mode
in which all 256 DAC settings can be displayed simultaneously. By the
way, the Color Select register and bit 7 of the Attribute Controller
Mode register are ignored in 256-color mode; all 8 bits sent from the
VGA chip to the DAC come from display memory. Therefore, there is no
color paging in 256-color mode. Of course, that makes sense given that
all 256 DAC registers are simultaneously in use in 256-color mode.
#### Setting the Palette RAM {#Heading8}
The palette RAM can be programmed either directly or through BIOS
interrupt 10H, function 10H. I strongly recommend using the BIOS
interrupt; a clone BIOS may mask incompatibilities with genuine IBM
silicon. Such incompatibilities could include anything from flicker to
trashing the palette RAM; or they may not exist at all, but why find out
the hard way? My policy is to use the BIOS unless there's a clear reason
not to do so, and there's no such reason that I know of in this case.
When programming specifically for the VGA, the palette RAM needs to be
loaded only once, to store the pass-through values 0 through 15 in
palette RAM registers 0 through 15. Setting the entire palette RAM is
accomplished easily enough with subfunction 2 (AL=2) of function 10H
(AH=10H) of interrupt 10H. A single call to this subfunction sets all 16
palette RAM registers (and the Overscan register) from a block of 17
bytes pointed to by ES:DX, with ES:DX pointing to the value for register
0, ES:DX+1 pointing to the value for register 1, and so on up to
ES:DX+16, which points to the overscan value. The palette RAM registers
store 6 bits each, so only the lower 6 bits of each of the first 16
bytes in the 17-byte block are significant. (The Overscan register,
which specifies what's displayed between the area of the screen that's
controlled by the values in display memory and the blanked region at the
edges of the screen, is an 8-bit register, however.)
Alternatively, any one palette RAM register can be set via subfunction 0
(AL=0) of function 10H (AH=10H) of interrupt 10H. For this subfunction,
BL contains the number of the palette RAM register to set and the lower
6 bits of BH contain the value to which to set that register.
Having said that, let's leave the palette RAM behind (presumably in a
pass-through state) and move on to the DAC, which is the right place to
do color translation on the VGA.