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

94 lines
5.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Chapter 25\
VGA Data Machinery {#Heading1}
-------------------
### The Barrel Shifter, Bit Mask, and Set/Reset Mechanisms {#Heading2}
In the last chapter, we examined a simplified model of data flow within
the GC portion of the VGA, featuring the latches and ALUs. Now we're
ready to expand that model to include the barrel shifter, bit mask, and
the set/reset capabilities, leaving only the write modes to be explored
over the next few chapters.
### VGA Data Rotation {#Heading3}
Figure 25.1 shows an expanded model of GC data flow, featuring the
barrel shifter and bit mask circuitry. Let's look at the barrel shifter
first. A barrel shifter is circuitry capable of shifting—or rotating, in
the VGA's case—data an arbitrary number of bits in a single operation,
as opposed to being able to shift only one bit position at a time. The
barrel shifter in the VGA can rotate incoming CPU data up to seven bits
to the right (toward the least significant bit), with bit 0 wrapping
back to bit 7, after which the VGA continues processing the rotated byte
just as it normally processes unrotated CPU data. Thanks to the nature
of barrel shifters, this rotation requires no extra processing time over
unrotated VGA operations. The number of bits by which CPU data is
shifted is controlled by bits 2-0 of GC register 3, the Data Rotate
register, which also contains the ALU function select bits (data
unmodified, AND, OR, and XOR) that we looked at in the last chapter.
![](images/25-01.jpg)\
**Figure 25.1**  *Data flow through the Graphics Controller.*
The barrel shifter is powerful, but (as sometimes happens in this
business) it sounds more useful than it really is. This is because the
GC can only rotate CPU data, a task that the CPU itself is perfectly
capable of performing. Two **OUT**s are needed to select a given
rotation: one to set the GC Index register, and one to set the Data
Rotate register. However, with careful programming it's sometimes
possible to leave the GC Index always pointing to the Data Rotate
register, so only one **OUT** is needed. Even so, it's often easier
and/or faster to simply have the CPU rotate the data of interest CL
times than to set the Data Rotate register. (Bear in mind that a single
**OUT** takes from 11 to 31 cycles on a 486—and longer if the VGA is
sluggish at responding to OUTs, as many VGAs are.) If only the VGA could
rotate *latched* data, then there would be all sorts of useful
applications for rotation, but, sadly, only CPU data can be rotated.
The drawing of bit-mapped text is one use for the barrel shifter, and
I'll demonstrate that application below. In general, though, don't knock
yourself out trying to figure out how to work data rotation into your
programs—it just isn't all that useful in most cases.
### The Bit Mask {#Heading4}
The VGA has bit mask circuitry for each of the four memory planes. The
four bit masks operate in parallel and are all driven by the same mask
data for each operation, so they're generally referred to in the
singular, as "the bit mask." Figure 25.2 illustrates the operation of
one bit of the bit mask for one plane. This circuitry occurs eight times
in the bit mask for a given plane, once for each bit of the byte written
to display memory. Briefly, the bit mask determines on a bit-by-bit
basis whether the source for each byte written to display memory is the
ALU for that plane or the latch for that plane.
![](images/25-02.jpg)\
**Figure 25.2**  *Bit mask operation.*
The bit mask is controlled by GC register 8, the Bit Mask register. If a
given bit of the Bit Mask register is 1, then the corresponding bit of
data from the ALUs is written to display memory for all four planes,
while if that bit is 0, then the corresponding bit of data from the
latches for the four planes is written to display memory unchanged. (In
write mode 3, the actual bit mask that's applied to data written to
display memory is the logical AND of the contents of the Bit Mask
register and the data written by the CPU, as we'll see in Chapter 26.)
The most common use of the bit mask is to allow updating of selected
bits within a display memory byte. This works as follows: The display
memory byte of interest is latched; the bit mask is set to preserve all
but the bit or bits to be changed; the CPU writes to display memory,
with the bit mask preserving the indicated latched bits and allowing ALU
data through to change the other bits. Remember, though, that it is not
possible to alter selected bits in a display memory byte *directly;* the
byte must first be latched by a CPU read, and then the bit mask can keep
selected bits of the latched byte unchanged.
Listing 25.1 shows a program that uses the bit mask data rotation
capabilities of the GC to draw bitmapped text at any screen location.
The BIOS only draws characters on character boundaries; in 640x480
graphics mode the default font is drawn on byte boundaries horizontally
and every 16 scan lines vertically. However, with direct bitmapped text
drawing of the sort used in Listing 25.1, it's possible to draw any font
of any size anywhere on the screen (and a lot faster than via DOS or the
BIOS, as well).