73 lines
3.5 KiB
Markdown
73 lines
3.5 KiB
Markdown
That's a shame, because mode 13H has the simplest bitmap organization of
|
||
any mode—one long, linear bitmap, with each byte controlling one pixel.
|
||
We can't have that organization, though, so we'll have to find an
|
||
acceptable substitute if we want to use a higher 256-color resolution.
|
||
|
||
We're talking about the VGA, so of course there are actually *several*
|
||
bitmap organizations that let us use higher 256-color resolutions than
|
||
mode 13H. The one I like best is shown in Figure 31.1. Each byte
|
||
controls one 256-color pixel. Pixel 0 is at address 0 in plane 0, pixel
|
||
1 is at address 0 in plane 1, pixel 2 is at address 0 in plane 2, pixel
|
||
3 is at address 0 in plane 3, pixel 4 is at address 1 in plane 0, and so
|
||
on.
|
||
|
||
Let's look at this another way. Ideally, we'd like one long bitmap, with
|
||
each pixel at the address that's just after the address of the pixel to
|
||
the left. Well, that's true in this case too, *if* you consider the
|
||
number of the plane that the pixel is in to be part of the pixel's
|
||
address. View the pixel numbers on the screen as increasing from left to
|
||
right and from the end of one scan line to the start of the next. Then
|
||
the pixel number, n, of the pixel at display memory address *address* in
|
||
plane *plane* is:
|
||
|
||
\
|
||
**Figure 31.1** *Bitmap organization in 320x400 256-color mode in
|
||
320x400 256-color mode.*
|
||
|
||
*n* = (*address* \* 4) + *plane*
|
||
|
||
To turn that around, the display memory address of pixel number n is
|
||
given by
|
||
|
||
address = *n* / 4
|
||
|
||
and the plane of pixel *n* is given by:
|
||
|
||
plane = *n* modulo 4
|
||
|
||
Basically, the full address of the pixel, its pixel number, is broken
|
||
into two components: the display memory address and the plane.
|
||
|
||
By the way, because 320x400 mode has a significantly different memory
|
||
organization from mode 13H, the BIOS text routines won't work in 320x400
|
||
mode. If you want to draw text in 320x400 mode, you'll have to look up a
|
||
font in the BIOS ROM and draw the text yourself. Likewise, the BIOS read
|
||
pixel and write pixel routines won't work in 320x400 mode, but that's no
|
||
problem because I'll provide equivalent routines in the next section.
|
||
|
||
Our next task is to convert standard mode 13H into 320x400 mode. That's
|
||
accomplished by undoing some of the mode bits that are set up especially
|
||
for mode 13H, so that from a programming perspective the VGA reverts to
|
||
a straightforward planar model of memory. That means taking the VGA out
|
||
of chain 4 mode and doubleword mode, turning off the double display of
|
||
each scan line, making sure chain mode, odd/even mode, and word mode are
|
||
turned off, and selecting byte mode for video data display. All that's
|
||
done in the **Set320x400Mode** subroutine in Listing 31.1, which we'll
|
||
discuss next.
|
||
|
||
#### Reading and Writing Pixels {#Heading6}
|
||
|
||
The basic graphics functions in any mode are functions to read and write
|
||
single pixels. Any more complex function can be built on these
|
||
primitives, although that's rarely the speediest solution. What's more,
|
||
once you understand the operation of the read and write pixel functions,
|
||
you've got all the knowledge you need to create functions that perform
|
||
more complex graphics functions. Consequently, we'll start our
|
||
exploration of 320x400 mode with pixel-at-a-time line drawing.
|
||
|
||
Listing 31.1 draws 8 multicolored octagons in turn, drawing a new one on
|
||
top of the old one each time a key is pressed. The main-loop code of
|
||
Listing 31.1 should be easily understood; a series of diagonal,
|
||
horizontal, and vertical lines are drawn one pixel at a time based on a
|
||
list of line descriptors, with the draw colors incremented for each
|
||
successive time through the line list.
|