Contents of the BITMAP.DOC file
Author: Bill Mayne
9707 Lawndale Dr.
Silver Spring, MD 20901
Language: Microsoft C, version 4.0. Should be portable to other versions
of C, possibly requiring modifications to the DOS calls in
System: MS/DOS or PC/DOS
Hardware: CGA required
The routines included here perform bit mapped graphics for PCs
equipped with color/graphics adaptors (CGA). Both 320 by 200 and
640 by 200 resolution modes are supported. These don't do anything
unusual, many graphics libraries are around which do more, but
this one is done entirely in C with the object of helping C
programmers understand the bit mapping done for a CGA.
Checking and setting the video mode is done by the functions
get_mode(), set_mode(), and set_colors(), which are found in
SETVIDEO.C. These use DOS function calls with the REGS union and
intdos() functions and are the only parts of the code here which
might not port to other versions of C, though they could be
modified for any implementation which provides for DOS calls.
Actual pixel input and output is done by directly accessing the
CGA video RAM, which starts at segment B800. This is faster than
going through DOS. The code is written for clarity rather than u
4the absolute maximum in speed. Partly for simplicity and partly
for speed no error checking is done. Even for production code
this seems appropriate, since these routines are executed
thousands of times in a typical program, so a lot of time is
saved by making the mode setting and error checking the
responsibility of the caller. Range checking on coordinates and
colors can just as well be done by the caller, preferably using
the ASSERT macro so it could be removed easily once the program
I could have made the routines a lot more flexible by having them
test for mode themselves, rather than having a different set of
functions for medium and high resolution, but again it seemed
better to leave this to the caller, since few programs will use
both modes. Directly accessing the video RAM naturally limits
the portability of the code, but that really doesn't matter much
for such small, low-level routines. They would be easy enough to
rewrite for any other system supporting pixel graphics and it is
the portability of the application calling them, not these
routines themselves, that counts.
Another advantage of this method is that, with slight
modification, you could change the address of the buffer from the
actual video RAM to another area of memory, and build the graphic
screens while displaying something else, then do a block transfer
into video RAM to make the screens pop up all at once.
Programmers who have experience with CGAs may notice the absense
of any "wait for retrace" code, as would be necessary to prevent
"snow" when doing updates in text mode. I originally left that
out to make the routines faster, but found in testing that it
does not seem to be necessary for these routines.
All of these routines should when compiled using any memory
model. The object code in BITMAP.LIB is for the default small
The routines here are part of a larger library under development,
but contain the basic building blocks for anything you might want
to do with a CGA. One additional function which would to useful
would be to fill in a convex area given the coordinates of its
boundary points. (At the lowest level do this for a triangle.)
fill in a convex area given the coordinates of its boundary This
is not done here mainly because it is much more complicated than
it seems at first and these routines are written mainly as
tutorials. Bit mapping and direct output to video RAM offers the
greatest possibilities for optimization when doing areas, since
all 4 or 8 bits in a byte could be set when one write when
filling in solid horizontal lines.
No assembly language is used because it is not necessary and the
code is also intended to help C programmers get an understanding
of the bit mapping scheme. I hope you find these useful, or at
Source File Function Notes
----------- ------------ ------------------------------------
SETVIDEO.C get_mode() These use the REGS union and intdos()
set_mode() function, possibly non-portable.
DOT320.C put_dot() Contains compile option to use bit
DOT640.C put_dot_640() Few differences from DOT320.C, could
get_dot_640() have even been done as a preprocessor
option of DOT320.C.
DRAWLINE.C draw_line() Function name and resolution can be
draw_line_640() changed by preprocessor options.
Also generates a main() function to
allow for simple testing by defining
symbol TEST. (See comments at start
BITMAP.LIB (all above) Library containing .OBJ for all of
TESTDRAW.EXE Executeable test driver for line drawing
(and indirectly for dot output) in
320 by 200 mode. Arguments are:
x1, y1, x2, y3, color. "x" and "y" values
are the coordinates of the end points,
in the range (0, 0) through (319, 199).
Color should be in the range 0 thru 3.