Dec 122017
 
Direct access to video RAM for Turbo Pascal.
File MAPSCR.ZIP from The Programmer’s Corner in
Category Pascal Source Code
Direct access to video RAM for Turbo Pascal.
File Name File Size Zip Size Zip Type
BOX.INC 3462 946 deflated
BOXDEMO.PAS 1149 640 deflated
FS.INC 3648 1168 deflated
FSDEMO.PAS 1838 908 deflated
MAPSCR.DOC 11745 4608 deflated
SAVESCRN.INC 1425 504 deflated

Download File MAPSCR.ZIP Here

Contents of the MAPSCR.DOC file


Memory Mapped Screen I/O

Copyright 1987 by:

Bill Mayne
9707 Lawndale Dr.
Silver Spring, MD 20901
(301) 588-2308

These routines and accompanying documentation may be copied and
distributed without charge. Anyone making significant use of these
routines, or who makes or wants to suggest improvements, is asked to
contact the author.

Introduction

It is well known to most programmers that the video display of the IBM
PC and compatible PCs is "memory mapped", i.e. for each character
position on the screen there is a corresponding pair of bytes in RAM
which specify the character displayed at that position and the
attributes used for the display. Two of the principle uses for this
fact are (1) Determining the content of the screen from inside a
program, including saving copies of all or part of the screen for
later restoring; and (2) Performing output to the screen by storing
character and attribute data directly into the video RAM.

Some of the problems associated with this are:

(1) The location of video RAM depends upon whether a monochrome or
color monitor is in use.

(2) If a Color Graphics Adaptor (CGA) is in use, special steps must be
taken to avoid "snow" when video RAM is accessed. This is not
necessary when an Extended Graphics Adaptor (EGA) is installed.
Therefore it is better to determine not only whether a system has a
color or monochrome monitor, but, if color, whether it has an EGA.

Turbo Pascal provides for access to the low level operations necessary
to determine the type of monitor and adaptor and access video RAM in 3
ways: (1) 'External' functions and procedures, normally written in
assembly language; (2) 'inline' machine code, also usually written in
assembly language but entered in the source program as machine code;
and (3) direct access to absolute memory addresses, DOS functions,
interrupts, and i/o ports. Many routines are available which use the
first two methods. The routines presented here, though partly based
on assembly language routines, do not use any external procedures or
inline machine code. This is is done partly for aesthetic reasons and
also because the resulting code, though not as compact, is easier for
most Turbo Pascal programmers to understand, and, if necessary, to
modify.

Though the code is written with the idea of demonstrating the use of
the techniques, it is up to the user to read through the code itself
for what can be learned from it. The presentation is not a tutorial.
Comments in the code itself have been kept to a minimum, in the
interest of saving space and time when actually programming. General
documentation is given below.

Functions Supported

Turbo Pascal source code (in the form of include files) is given to:

(1) Save and restore the content of the video RAM, using 4000 byte
buffers provided by the calling program. These buffers can be either
regular stack variables or dynamically allocated from the heap.

(2) Manipulate the contents of screen buffers, specifically, to place
strings properly interleaved with attribute bytes into buffers,
subscripted by corresponding row and column addresses, and to extract
string values from screen buffers.

(3) The ability to "restore" the video RAM from a modified (or
entirely new) buffer provides the ability to make screen updating
appear intaneously.

(4) Routines are also supplied for drawing boxes either in the actual
video RAM or in screen buffers elsewhere. For direct video RAM
update, exploding windows with and without sound effects are
supported.

SAVESCRN.INC

Global references: None. Global defintions:

WaitForRetrace: a global boolean variable which determines whether or
not special steps are taken to prevent "snow" on a color monitor
with CGA. It is initialized FALSE, which makes the other routines
safe for a monochrome monotor. You may want to keep it false even
for a color monitor with CGA. Some "snow" will result at times,
but screen operations will be faster. It is also okay to set it
TRUE if a color monitor is in use, even if an EGA may be present,
though the extra processing will slow down video RAM update.

SaveScreen: procedure to save a copy of video RAM into a user supplied
buffer. The buffer is passed as an untyped variable and must be
4000 bytes long. The routine checks for color or monochrome
monitor. For color monitors it tests the value of WaitForRetrace.

RestoreScreen: procedure to move a user supplied buffer to video RAM.
This is of course the complement of SaveScreen, but can
additionally be used to display an entirely new screen which has
been contructed in a buffer. The screen update will then appear
virtually instaneously.

EGA_Installed: Boolean function returns TRUE if an EGA, is installed
which can in some cases makes video RAM updates faster. Normally,
programs using the routines given here should include in
initialization: WaitForRetrace:=not EGA_Installed;

FS.INC

Read the name as either "Full Screen" or "Fast Screen" updates. This
include file contains the routines which manipulate 4000 byte screen
buffers to support using RestoreScreen for screen i/o and windows.
One routine, ScreenPutX, updates video RAM directly. Global
references: WaitForRetrace (only if ScreenPutX is used.) Global
defintions:

ScreenBuf and ScreenStr: types. (Unfortunately, Turbo Pascal type
defintions do not obey the normal rules for scope of variables.)
ScreenBuf defines an array of 1..25 rows by 1..80 columns. When
addressing the array directly, remember that the row (or Y
co-ordinate) is given first, though subroutines and functions
generally place the X co-ordinate first. It is better to use the
{$V-} compiler directive to relax string type checking and declare
strings to be placed in screen buffers to their actual lengths,
rather than using the ScreenStr type.

ScreenPut: procedure to put the bytes of a string, interleaved with
copies of a specified attribute, into a screen buffer. Lines wrap
from the end of one line to the beginning of the next. The
programmer is responsible for screen address validation.

ScreenPutX: Like ScreenPut, except that the string is moved directly
to video RAM, rather than to a buffer. WaitForRetrace is checked
only if a color monitor is in use, and video disabling is
performed it TRUE.

ScreenGet: function returns a string consisting of the character bytes
from an area of a screen buffer as a string. The caller specifies
the screen co-ordinates and length. The programmer is responsible
for screen address validation.

BufBox: procedure which stores a box into a screen buffer. The box is
specified by the co-ordinates of the top left and bottom right
corners (like the Turbo Pascal "Window" procedure), the attributes
of the sides, and the character (0 thru 255) to be used to frame
the box. Any of the 256 display characters can be used. By
specifying values outside the range 0 to 255, you can cause a case
selection in the procedure to specify sperately the characters to
use for the four corners, vertical, and horizontal lines.
Currently, the only case supported is 256, which gives a single
solid line around the center of the spaces at the border. The
caller is responsible for validating all parameters.

ClrWindowBuf: procedure to fill a window within a buffer with a
specified character and attribute. (Similar to doing Window,
followed by TextColor, TextBackGround, and ClrScr, except that the
display does not change immediately and the character which fills
the window may be any character, not just a blank.)

ClrScreenBuf: procedure to fill the entire screen buffer with a
specified character and attribute. Equivalent to using
ClrWindowBuf and specifying the entire screen.)

BOX.INC

These routines draw boxes by updating the current video RAM, rather
than a user supplied buffer. Global references: WaitForRetrace.
Global defintions:

Box: procedure to draw a box around a specified window, using any
framing character and attribute, or selecting a predefined set of
framing characters. (Similar to BufBox.)

MakeExpandingBox: procedure to draw a box by first filling the area
from the center outward with a specified character and attribute.
Obtional sound effects consist of a tone of increasing frequency
as the box expands. This works best on monochrome screens.

WaitForRetrace is temporarily set to FALSE, so snow results on a
CGA, though it normally clears up. WaitForRetrace is restored to
its original value before the frame is drawn. (I originally had
it enabled all the time, but found the results unsatisfactory. If
anyone can enlighten me on what is happening here, please do.)

ExpandBox: procedure calls MakeExpandingBox without sound effects.

ExplodeBox: procedure calls MakeExpandingBox with sound effects.

Demonstration Programs

A quick and crude demonstration of some of the capabilities of the
routines described above can be seen by compiling and running the
following programs:

BOXDEMO.PAS: Demonstrates BOX.INC.

FSDEMO.PAS: Demonstrates some of FS.INC, using the same display as
that created by BOXDEMO, but without exploding windows.

Compare the source code to get a better understanding of the use of
the routines for delayed versus immediate video RAM updates.

Specifying Attributes

Note that unlike plain vanilla Turbo Pascal, these routines expect the
caller to specify both the text background and foreground colors in
one byte, as the PC hardware requires. For regular (as opposed to
reverse) video, just use the predefined constants provided by Turbo
Pascal. To specify the background as anything but black, shift the
attribute left 4 bits, then add the foreground attribute. Specifying
a "light" background color or adding 128 to the final value will give
blinking displays. For example, the attribute "(red shl 4)+blue+128"
or the equivalent "(LightRed shl 4)+blue" gives blinking red on blue,
which is very hard to read. Experimentation may be needed to find a
pleasing combination.

On monochrome screens, some of the combinations have a different
effect than you might expect. They are not just a "black and green
(or amber etc.)". Monochrome screens are capable of underlining, and
some meaningless color combinations are used for that. In some other
cases what yields a reverse video color field on a color monitor
results in regular, not reverse video on monochrome. The most
reliable thing is to check the monitor type and use the following for
monochrome: $07=white on black (normal); $70=black on white (reverse);
$87=normal blinking; and $F0=reverse blinking. Note that the
predefined constant 'blink' will not work with these routines.


 December 12, 2017  Add comments

Leave a Reply