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

73 lines
3.5 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.

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:
![](images/31-01.jpg)\
**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.