133 lines
7.3 KiB
Markdown
133 lines
7.3 KiB
Markdown
---
|
|
title: Michael Abrash's Graphics Programming Black Book, Special Edition
|
|
author: Michael Abrash
|
|
date: '1997-07-01'
|
|
isbn: '1576101746'
|
|
publisher: The Coriolis Group
|
|
category: 'Web and Software Development: Game Development,Web and Software Development:
|
|
Graphics and Multimedia Development'
|
|
chapter: '23'
|
|
pages: 445-448
|
|
---
|
|
|
|
One possible solution to this problem is to pick a second page start
|
|
address that has a 0 value for the lower byte, so only the Start Address
|
|
High register ever needs to be set, but in the sample program in Listing
|
|
23.1 I've gone for generality and always set both bytes. To avoid
|
|
mismatched start address bytes, the sample program waits for pixel data
|
|
to be displayed, as indicated by the Display Enable status; this tells
|
|
us we're somewhere in the displayed portion of the frame, far enough
|
|
away from vertical sync so we can be sure the new start address will get
|
|
used at the next vertical sync. Once the Display Enable status is
|
|
observed, the program sets the new start address, waits for vertical
|
|
sync to happen, sets the new pel panning state, and then continues
|
|
drawing. Don't worry about the details right now; page flipping will
|
|
come up again, at considerably greater length, in later chapters.
|
|
|
|
> 
|
|
> As an interesting side note, be aware that if you run DOS software under
|
|
> a multitasking environment such as Windows NT, timeslicing delays can
|
|
> make mismatched start address bytes or mismatched start address and pel
|
|
> panning settings much more likely, for the graphics code can be
|
|
> interrupted at any time. This is also possible, although much less
|
|
> likely, under non-multitasking environments such as DOS, because
|
|
> strategically placed interrupts can cause the same sorts of problems
|
|
> there. For maximum safety, you should disable interrupts around the key
|
|
> portions of your page-flipping code, although here we run into the
|
|
> problem that if interrupts are disabled from the time we start looking
|
|
> for Display Enable until we set the Pel Panning register, they will be
|
|
> off for far too long, and keyboard, mouse, and network events will
|
|
> potentially be lost. Also, disabling interrupts won't help in true
|
|
> multitasking environments, which never let a program hog the entire CPU.
|
|
> This is one reason that pel panning, although indubitably flashy, isn't
|
|
> widely used and should be reserved for only those cases where it's
|
|
> absolutely necessary.
|
|
|
|
Waiting for the sync pulse has the side effect of causing program
|
|
execution to synchronize to the VGA's frame rate of 60 or 70 frames per
|
|
second, depending on the display mode. This synchronization has the
|
|
useful consequence of causing the program to execute at the same speed
|
|
on any CPU that can draw fast enough to complete the drawing in a single
|
|
frame; the program just idles for the rest of each frame that it
|
|
finishes before the VGA is finished displaying the previous frame.
|
|
|
|
An important point illustrated by the sample program is that while the
|
|
VGA's display memory is far larger and more versatile than is the case
|
|
with earlier adapters, it is nonetheless a limited resource and must be
|
|
used judiciously. The sample program uses VGA memory to store two
|
|
672x384 virtual pages, leaving only 1024 bytes free to store images. In
|
|
this case, the only images needed are a colored ball and a blank block
|
|
with which to erase it, so there is no problem, but many applications
|
|
require dozens or hundreds of images. The tradeoffs between virtual page
|
|
size, page flipping, and image storage must always be kept in mind when
|
|
designing programs for the VGA.
|
|
|
|
To see the program run in 640x200 16-color mode, comment out the `EQU`
|
|
line for `MEDRES_VIDEO_MODE`.
|
|
|
|
### The Hazards of VGA Clones {#Heading10}
|
|
|
|
Earlier, I said that any VGA that doesn't support the features and
|
|
functionality covered in this book can't properly be called VGA
|
|
compatible. I also noted that there are some exceptions, however, and
|
|
we've just come to the most prominent one. You see, all VGAs really
|
|
*are* compatible with the IBM VGA's functionality when it comes to
|
|
drawing pixels into display memory; all the write modes and read modes
|
|
and set/reset capabilities and everything else involved with
|
|
manipulating display memory really does work in the same way on all VGAs
|
|
and VGA clones. That compatibility isn't as airtight when it comes to
|
|
scanning pixels out of display memory and onto the screen in certain
|
|
infrequently-used ways, however.
|
|
|
|
The areas of incompatibility of which I'm aware are illustrated by the
|
|
sample program, and may in fact have caused you to see some glitches
|
|
when you ran Listing 23.1. The problem, which arises only on certain
|
|
VGAs, is that some settings of the Row Offset register cause some pixels
|
|
to be dropped or displaced to the wrong place on the screen; often, this
|
|
happens only in conjunction with certain start address settings. (In my
|
|
experience, only VRAM (Video RAM)-based VGAs exhibit this problem, no
|
|
doubt due to the way that pixel data is fetched from VRAM in large
|
|
blocks.) Panning and large virtual bitmaps can be made to work reliably,
|
|
by careful selection of virtual bitmap sizes and start addresses, but
|
|
it's difficult; that's one of the reasons that most commercial software
|
|
does not use these features, although a number of games do. The upshot
|
|
is that if you're going to use oversized virtual bitmaps and pan around
|
|
them, you should take great care to test your software on a wide variety
|
|
of VRAM- and DRAM-based VGAs.
|
|
|
|
### Just the Beginning {#Heading11}
|
|
|
|
That pretty well covers the important points of the sample VGA program
|
|
in Listing 23.1. There are many VGA features we didn't even touch on,
|
|
but the object was to give you a feel for the variety of features
|
|
available on the VGA, to convey the flexibility and complexity of the
|
|
VGA's resources, and in general to give you an initial sense of what VGA
|
|
programming is like. Starting with the next chapter, we'll begin to
|
|
explore the VGA systematically, on a more detailed basis.
|
|
|
|
### The Macro Assembler {#Heading12}
|
|
|
|
The code in this book is written in both C and assembly. I think C is a
|
|
good development environment, but I believe that often the best code
|
|
(although not necessarily the easiest to write or the most reliable) is
|
|
written in assembly. This is especially true of graphics code for the
|
|
x86 family, given segments, the string instructions, and the asymmetric
|
|
and limited register set, and for real-time programming of a complex
|
|
board like the VGA, there's really no other choice for the lowest-level
|
|
code.
|
|
|
|
Before I'm deluged with protests from C devotees, let me add that the
|
|
majority of my productive work is done in C; no programmer is immune to
|
|
the laws of time, and C is simply a more time-efficient environment in
|
|
which to develop, particularly when working in a programming team. In
|
|
this book, however, we're after the *sine qua non* of PC
|
|
graphics—performance—and we can't get there from here without a fair
|
|
amount of assembly language.
|
|
|
|
Now that we know what the VGA looks like in broad strokes and have a
|
|
sense of what VGA programming is like, we can start looking at specific
|
|
areas in depth. In the next chapter, we'll take a look at the hardware
|
|
assistance the VGA provides the CPU during display memory access. There
|
|
are four latches and four ALUs in those chips, along with some useful
|
|
masks and comparators, and it's that hardware that's the difference
|
|
between sluggish performance and making the VGA get up and dance.
|