112 lines
6.2 KiB
Markdown
112 lines
6.2 KiB
Markdown
### When to Use Write Mode 2 and When to Use Set/Reset {#Heading7}
|
||
|
||
As indicated earlier, write mode 2 and set/reset are functionally
|
||
interchangeable. Write mode 2 lends itself to more efficient
|
||
implementations when the drawing color changes frequently, as in Listing
|
||
27.2.
|
||
|
||
Set/reset tends to be superior when many pixels in succession are drawn
|
||
in the same color, since with set/reset enabled for all planes the
|
||
Set/Reset register provides the color data and as a result the CPU is
|
||
free to draw whatever byte value it wishes. For example, the CPU can
|
||
execute an **OR** instruction to display memory when set/reset is
|
||
enabled for all planes, thus both loading the latches and writing the
|
||
color value with a single instruction, secure in the knowledge that the
|
||
value it writes is ignored in favor of the set/reset color.
|
||
|
||
Set/reset is also the mode of choice whenever it is necessary to force
|
||
the value written to some planes to a fixed value while allowing the CPU
|
||
byte to modify other planes. This is the mode of operation when
|
||
set/reset is enabled for some but not all planes.
|
||
|
||
### Mode 13H—320x200 with 256 Colors {#Heading8}
|
||
|
||
I'm going to take a minute—and I do mean a minute—to discuss the
|
||
programming model for mode 13H, the VGA's 320x200 256-color mode.
|
||
Frankly, there's just not much to it, especially compared to the
|
||
convoluted 16-color model that we've explored over the last five
|
||
chapters. Mode 13H offers the simplest programming model in the history
|
||
of PC graphics: A linear bitmap starting at A000:0000, consisting of
|
||
64,000 bytes, each controlling one pixel. The byte at offset 0 controls
|
||
the upper left pixel on the screen, the byte at offset 319 controls the
|
||
upper right pixel on the screen, the byte at offset 320 controls the
|
||
second pixel down at the left of the screen, and the byte at offset
|
||
63,999 controls the lower right pixel on the screen. That's all there is
|
||
to it; it's so simple that I'm not going to spend any time on a demo
|
||
program, especially given that some of the listings later in this book,
|
||
such as the antialiasing code in Chapter F on the companion CD-ROM, use
|
||
mode 13H.
|
||
|
||
### Flipping Pages from Text to Graphics and Back {#Heading9}
|
||
|
||
A while back, I got an interesting letter from Phil Coleman, of La
|
||
Jolla, who wrote:
|
||
|
||
"Suppose I have the EGA in mode 10H (640x350 16-color graphics). I would
|
||
like to preserve some or all of the image while I temporarily switch to
|
||
text mode 3 to give my user a ‘Help' screen. Naturally memory is scarce
|
||
so I'd rather not make a copy of the video buffer at A000H to ‘remember'
|
||
the image while I digress to the Help text. The EGA BIOS says that the
|
||
screen memory will not be cleared on a mode set if bit 7 of AL is set.
|
||
Yet if I try that, it is clear that writing text into the B800H buffer
|
||
trashes much more than the 4K bytes of a text page; when I switch back
|
||
to mode 10H, "ghosts" appear in the form of bands of colored dots. (When
|
||
in text mode, I do make a copy of the 4K buffer at B800H before showing
|
||
the help; and I restore the 4K before switching back to mode 10H.) Is
|
||
there a way to preserve the graphics image while I switch to text
|
||
mode?''
|
||
|
||
"A corollary to this question is: Where does the 64/128/256K of EGA
|
||
memory ‘hide' when the EGA is in text mode? Some I guess is used to
|
||
store character sets, but what happens to the rest? Or rather, how can I
|
||
protect it?"
|
||
|
||
Those are good questions. Alas, answering them in full would require
|
||
extensive explanation that would have little general application, so I'm
|
||
not going to do that. However, the issue of how to go to text mode and
|
||
back without losing the graphics image certainly rates a short
|
||
discussion, complete with some working code. That's especially true
|
||
given that both the discussion and the code apply just as well to the
|
||
VGA as to the EGA (with a few differences in mode 12H, the VGA's
|
||
highmode, as noted below).
|
||
|
||
Phil is indeed correct in his observation that setting bit 7 of AL
|
||
instructs the BIOS not to clear display memory on mode sets, and he is
|
||
also correct in surmising that a font is loaded when going to text mode.
|
||
The normal mode 10H bitmap occupies the first 28,000 bytes of each of
|
||
the VGA's four planes. (The mode 12H bitmap takes up the first 38,400
|
||
bytes of each plane.) The normal mode 3 character/attribute memory map
|
||
resides in the first 4000 bytes of planes 0 and 1 (the blue and green
|
||
planes in mode 10H). The standard font in mode 3 is stored in the first
|
||
8K of plane 2 (the red plane in mode 10H). Neither mode 3 nor any other
|
||
text mode makes use of plane 3 (the intensity plane in mode 10H); if
|
||
necessary, plane 3 could be used as scratch memory in text mode.
|
||
|
||
Consequently, you can get away with saving a total of just under 16K
|
||
bytes—the first 4000 bytes of planes 0 and 1 and the first 8K bytes of
|
||
plane 2—when going from mode 10H or mode 12H to mode 3, to be restored
|
||
on returning to graphics mode.
|
||
|
||
That's hardly all there is to the matter of going from text to graphics
|
||
and back without bitmap corruption, though. One interesting point is
|
||
that the mode 10H bitmap can be relocated to A000:8000 simply by doing a
|
||
mode set to mode 10H and setting the start address (programmed at CRT
|
||
Controller registers 0CH and 0DH) to 8000H. You can then access display
|
||
memory starting at A800:8000 instead of the normal A000:0000, with the
|
||
resultant display exactly like that of normal mode 10H. There are BIOS
|
||
issues, since the BIOS doesn't automatically access display memory at
|
||
the new start address, but if your program does all its drawing directly
|
||
without the help of the BIOS, that's no problem.
|
||
|
||
The mode 12H bitmap can't start at A000:8000, because it's so long that
|
||
it would run off the end of display memory. However, the mode 12H bitmap
|
||
can be relocated to, say, A000:6000, where it would fit without
|
||
conflicting with the default font or the normal text mode memory map,
|
||
although it would overlap two of the upper pages available for use (but
|
||
rarely used) by text-mode programs.
|
||
|
||
At any rate, once the graphics mode bitmap is relocated, flipping to
|
||
text mode and back becomes painless. The memory used by mode 3 doesn't
|
||
overlap the relocated mode 10H bitmap at all (unless additional portions
|
||
of font memory are loaded), so all you need do is set bit 7 of AL on
|
||
mode sets in order to flip back and forth between the two modes.
|