Citation:    PC Tech Journal, Nov 1988 v6 n11 p62(8)

---------------------------------------------------------------------------

Title:       Pixel panning and split screens. (overlooked virtues of the
             VGA) (technical)

Authors:     Wilton, Richard

---------------------------------------------------------------------------

Subjects:    Split-Screen Displays;  Graphics Boards/Cards

Products:    IBM Video Graphics Array (Graphics board)_Design and
               construction

Reference #: A7075873

===========================================================================

Abstract: Support for pixel panning and split screens is contained within
          IBM's Video Graphics Array (VGA) hardware. Pixel panning smoothly
          slides a screen image without the user having to wait for the
          software to redraw the image. A split screen can display two
          separate parts of the video buffer simultaneously. Practical
          applications that exploit these features are rare because of the
          lack of support for VGA hardware in commonly used programming
          languages and libraries. A new wave of increasingly functional
          and productive microcomputer applications and programming tools
          will result from the increasing use of these features. VGA is not
          designed for sophisticated animation-quality graphics, however.
          Incorporating routines for the features in C and other language
          libraries is the next logical step. Vendors of VGA equipment will
          aid developers by supporting the features at the VGA BIOS level.

===========================================================================

Full Text COPYRIGHT Ziff-Davis Publishing Co. 1988

Pixel Panning and Split Screens Two overlooked virtues of the VGA allow
easy access to parts of the picture outside the confines of the screen.
RICHARD WILTON The Video Graphics Array (VGA) is more than just a huge,
high-tech box of crayons with 256,000 brilliant hues and subtle shadings. 
Nor does its value to software and applications development end with the
deep intensity with which its 640-by-480-pixel resolution can display
colors on the screen. Contained within the VGA is hardware support for two
features: pixel panning and split screens.

Pixel panning at the hardware level smoothly slides a screen image up,
down, left, and right on the screen without the user having to wait for the
software to redraw the image.  Traditionally, most programmers have made
graphics or text slide across the screen by copying blocks of characters or
pixels from one location in the video buffer to another.  VGA hardware,
however, can do this cleaner and faster by moving part or all of the
displayed image without the need for software to reshuffle pixels
constantly.

Panning can save time in developing and using applications in which the
video output normally extends beyond the confines of the screen and is
especially important for applications that require users to access or
monitor large amounts of data.  For example, medical and scientific
monitoring applications often require that the screen scroll constantly to
the left to display recent input.

A split screen can display two separate parts of the video buffer
simultaneously--one image on top, the other on the bottom. When using a
split screen, commands and data entered in one part can update information
automatically in the other.  Thus, in a spreadsheet application, the user
can input changes in one part of the screen and see them reflected in a
chart on the other part of the same screen.  This feature also could be
used to develop a debugger that allows simultaneous viewing of outputs from
the debugger and program being tested.

This hardware support for split-screen displays and pixel-by-pixel panning
can be used for impressive demonstration programs as well as special
effects.  Practical applications that exploit these features are rare,
however, because of the lack of support for VGA hardware in commonly used
programming languages and libraries.  As developers learn more about
programming the VGA, this is likely to change.

The VGA's ROM BIOS does not directly support either panning or split-screen
programming but instead supports repositioning the screen window in the
video buffer.  For example, INT 10H function 5 changes the value in the CRT
controller (CRTC) start-address registers in increments of one full screen
of text or graphics. IBM's ROM BIOS documentation refers to each screenful
of data as a display page.  This paged organization is no help for panning,
but lets developers display data stored in otherwise unused portions of the
video buffer.

Even though ROM BIOS support is lacking, you can develop applications that
use hardware-level pixel panning and screen splitting without an enormous
amount of programming.  Routines presented in this article demonstrate how
to redimension the video buffer to contain an unusually wide or long table,
spreadsheet, or graph and then pan the screen window across all data in the
video buffer.  They also show how to add a split screen to maintain a
caption in the lower part of the screen while panning the upper. YELLOW FOR
CAUTION Although the panning and split-screen programming techniques for
the VGA are comparatively straightforward, they illustrate some
difficulties in video-hardware programming.  Any program that relies on the
VGA's hardware panning or the split-screen feature is not portable to video
hardware that does not support it.

Many software developers have steered away from both of these features in
the past because of lack of support from IBM's earliest PC-graphics
standard, the Color Graphics Adapter (CGA).  This is less an obstacle,
however, now that the VGA is standard on new computer systems and the CGA
is fading into the canvas.

Perhaps more annoying is the fact that some panning techniques for the VGA
do not quite work on the Enhanced Graphics Adapter (EGA), which IBM
introduced after the CGA and before the VGA.  Both the EGA's CRTC and its
attribute controller lack some of the functionality provided in the VGA.
Therefore, the use of these features on the EGA requires more  coding.

Another potential problem is that some non-IBM VGAs for PC/AT-compatible
systems fail to offer the same panning or split-screen functionality as a
true-blue VGA.  All VGA features described in this article are documented
by IBM, and all examples given should work on compatible VGA boards
available from third parties.  As an added safety measure, buyers may want
to test these features on compatible boards before purchasing them.

Exploiting the VGA's support for panning and split-screen images is not an
insurmountable problem.  Learning how to make the most of these
capabilities in both alphanumeric and graphics video modes is the key to
developing applications that demand smoothly animated text and graphics.
SOFTWARE STOPGAP In terms of programming effort, the easiest approach to
panning is to redraw the image quickly and repeatedly in a sequence of
different positions using software.  The following BASIC program slides the
text string "Hello, there" across the screen from right to left by
redrawing it once in each character column on the screen: 10.SCREEN 0 : KEY
OFF : CLS 20.FOR X=60 TO 1 STEP -1 30.LOCATE 1,X,0 40.PRINT "Hello, there
"; 50.NEXT 60.END When this alphanumeric-mode program runs, the string
seems to zip across the screen until it comes to rest in the upper-left
corner.

The panning effect that this simple program produces is not particularly
useful, however.  The movement of the text string may appear smooth when
the program runs at full speed, but slowing the rate at which the string
slides across the screen--as is the case in most real-world
applications--makes its movement appear increasingly jerky. (To demonstrate
this problem, insert a delay loop between lines 30 and 40 of this program.)

The problem results because the distance between successive appearances of
the string on the screen is the width of one character--about one-tenth of
an inch on a typical VGA display.  The human eye perceives this movement as
a jerky motion rather than as smooth panning.

A reasonable solution is to move the string in increments of one pixel
instead of one character.  This is accomplished in software using one of
the VGA's graphics modes.  In alphanumeric mode, the string is positioned
to the nearest character row or column; in graphics mode, the developer has
more detailed pixel-by-pixel control over the string's location on the
screen.

The following BASIC program illustrates how pixel-by-pixel panning in a
graphics mode can appear much smoother than character-by-character panning
in an alphanumeric mode:  10.DEFINT A-Z : DIM BITBLOCK(58)  20.REM 640 by
200 2-color graphics  30.SCREEN 2 : KEY OFF : CLS  40.LOCATE 1,61,0 : PRINT
"Hello, there ";  50.REM Copy the bit block  60.GET
(480,0)-(584,7),BITBLOCK  70.REM Transfer the bit block  80.FOR X=480 TO 0
STEP -1  90.PUT (X,0),BITBLOCK,PSET 100.NEXT 110.END

One drawback with the graphics-mode version is that it runs more slowly
because graphics-mode software panning must move many more bytes of data in
order to translate an image.  In the alphanumeric-mode program, only 26
bytes of data represent the "Hello, there" string in the video buffer. 
This includes one attribute byte for each character in the string and
accounts for the trailing blank at the end of the string.  In
640-by-200-pixel two-color graphics mode (which is invoked using SCREEN 2
in BASIC), the same string is represented in 104 bytes of data (13
characters times 8 bytes per character). Displaying the same string in the
VGA's 640-by-480-pixel 16-color mode would require 832 bytes of data (13
characters times 16 bytes per character times 4 bit planes).

The large amount of data movement in graphics-mode software panning limits
its usefulness.  The speed at which an image can appear to move across the
VGA screen is limited by the speed of the computer's microprocessor.  The
larger the image, the more slowly it moves.

Furthermore, a CPU that is busy shuffling pixels in the video buffer is not
doing any other work.  In multitasking operating environments such as OS/2,
using this method can mean slowing the execution of other tasks as well as
making on-screen performance rather sluggish.

A related drawback is that a large image in graphics-mode software panning
can take a long time to redraw, resulting in a perceptible lag between the
time the top of the panned image moves across the screen and the time the
bottom moves.  This time lag can cause the image to smear or ripple; it is
most evident with large images and relates directly to the speed of the
microprocessor. THE TRUE GRIT Where software support results in slow and
jerky panning, hardware support is quick and smooth.  By manipulating a few
VGA parameters, the developer can move displayed images directly and
smoothly across the screen.  The VGA hardware also allows splitting the
displayed image horizontally into two independent images, one of which can
be panned smoothly while the other remains stationary.

In order to understand how the VGA hardware supports both smooth panning
and split-screen displays, visualize the relationship between the image
that appears on the screen and all the data that are actually stored in the
VGA's video buffer.  The buffer, which contains all the data displayed on
the screen, is large enough to contain much more than one screenful of
data.  This means that what appears on the screen may not be the entire
image that is contained in the video buffer.

Imagine the screen to be a window on the contents of the video buffer (see
figure 1).  This window is not to be confused with the notion of a window
in an environment such as Microsoft Windows, where a window represents a
logical region in which a program generates its output.  Instead, the
screen window delineates the visible portion of the data contained in the
video buffer.

Although the video buffer is addressed with a linear sequence of addresses,
imagine the video buffer as two-dimensional, with a logical width that
corresponds to the number of characters or pixels that can be displayed in
each row on the screen.  The key to understanding how screen splitting and
panning work on the VGA is to realize that the screen window can be
positioned to display any portion of the video buffer, or (in the case of 
screen splitting) to display two separate portions of the data in the
buffer.

Nevertheless, virtually all VGA programs ignore the extra memory in the
video buffer.  They assume that the origin of the screen window coincides
with the start of the video buffer, and that the logical width of the video
buffer is the same as the logical width of the screen.  In effect, the
VGA's video buffer is longer than the displayed screen image.  In order to
use the extra RAM in the video buffer, developers must know how to program
the VGA's control circuitry to change the origin of the screen window and
the logical width of the video buffer.  Most programmers accomplish this by
writing short assembly-language subroutines that directly access the VGA
hardware, but some of the work can be done through calls to the VGA's ROM
BIOS.  Both of these techniques are used in listings 1 through 8, provided
below. NEW BEGINNINGS The screen window is repositioned by changing its
origin in the video buffer. To accomplish this, you need to know how to
program the VGA's CRTC, which is the portion of the VGA circuitry that
synchronizes the display circuitry's accesses to the video buffer with the
timing signals that control the sweep of the electron beam across the video
display.

In effect, the CRTC locates the screen window by determining the address in
the video buffer that corresponds to the origin (that is, the upper-left
corner) of the screen.  The CRTC also determines the logical width of the
video buffer.  The combination of these parameters determines what portion
of the video buffer is displayed in the screen window.

The VGA's CRTC uses a set of 25 internal 8-bit registers to store a wide
range of values that control the timing signals necessary to drive the
video display.  Among these registers are three--start-address high,
start-address low, and offset--that specify the start address of the screen
window and the logical width of the video buffer.  The developer can change
these values by updating the contents of the appropriate CRTC registers.

All of the VGA's CRTC registers are accessed using the 8-bit I/O port at
3D5H.  To access the port, first write a register number (0 through 18H) to
port 3D4H and then read or write port 3D5H to access the corresponding CRTC
register. (In video modes 7 and 0FH, which emulate the EGA modes supported
on IBM's 5151 monochrome display, the relevant port addresses are 3B4H and
3B5H.)

The subroutine shown in listing 1 reads the value in a VGA CRTC register.
The corresponding routine in listing 2 writes a value to a VGA CRTC
register. These routines are written in assembly language, but, in general,
developers can accomplish the same task in high-level languages that
support port I/O. For example, both the Microsoft C functions outp and inp
and the BASIC functions INP and OUT can access CRTC registers. Vertical
positioning. Several CRTC registers control the position of the origin of
the screen window. The easiest ones to use are the two start-address
registers, numbered 0CH and 0DH.  These two registers contain the 16-bit
offset of the first displayed byte of data in the video buffer, with the
high-order byte of the offset in register 0CH and the low-order byte in
register 0DH.  When you call the VGA ROM BIOS to set up a video mode, the
offset in the start-address registers is set to zero, positioning the
screen window by default at the start of the VGA's video buffer.

Changing the CRTC start-address value repositions the screen window in the
video buffer.  Consider what happens in the C program shown in listing 3,
where the start-address value is incremented by 80 in successive iterations
of a program loop each time a key is pressed.  In 80-column alphanumeric
video modes, each iteration causes the screen window's position to move
down a row of characters.

In a graphics mode, the results are similar.  The difference is that each
row of data in the video buffer is one pixel high instead of one character
high.  The resulting vertical movement of the screen window is smoother
than in alphanumeric modes.

What about pixel-by-pixel vertical scrolling in alphanumeric modes?  To
accomplish this, you need to locate the screen window not only at a
particular row of characters, but also at a particular scan line within the
topmost character row.  The VGA's CRTC provides a way to do this through
its preset-row-scan register (8).  The value in the five low-order bits of
this register is set to zero whenever the ROM BIOS is called to establish a
video mode; changing this value changes the scan line at which the first
row of characters is displayed.  Thus, the combination of the start-address
and preset-row-scan values locates the screen origin at a particular pixel
y-coordinate.

For example, in the VGA's default 80-by-25-pixel 16-color alphanumeric
mode, each character row contains 16 scan lines (that is, 16 pixels).  To
scroll smoothly, increment the preset-row-scan value from 0 through 15.  To
get to the next row of characters, increment the start-address registers
and set the preset-row-scan value to zero. Horizontal positioning. When
experimenting with the CRTC's start-address registers, you will notice that
gradually incrementing the value in these registers moves the screen origin
to the right, character by character.  As in vertical positioning, you must
program an additional register in order to achieve pixel-by-pixel
horizontal positioning of the screen window.

The register that controls pixel-by-pixel horizontal positioning is in the
VGA's attribute controller.  Like the CRTC, the attribute controller uses a
set of 8-bit registers mapped to a single pair of I/O ports to control the
display of data.  The attribute controller, however, is more difficult to
program than the CRTC because the VGA hardware uses the I/O port at 3C0H
both to select a register number and to write data to the register. (This
I/O port's function is controlled by a switch whose state is reset when a
program reads a value from the VGA's input-status register at 3BAH or
3DAH.) To avoid these complications, rely on ROM BIOS INT 10H function 10H,
which provides two subfunctions (7 and 0) that read and write any
designated attribute-controller register.

You must program both the CRTC and the attribute controller in order to
position the screen origin at a particular pixel in the horizontal
direction. The attribute controller's horizontal-pel-panning register (13H)
designates the starting pixel in the video-buffer byte specified by the
CRTC start-address registers.  The assembly-language routine shown in
listing 4 uses these start-address registers to position the screen window
at a specified pixel location in the video buffer.

Determining the value for the horizontal-pel-panning register is slightly
involved because the VGA can display either eight or nine pixels for each
byte in the video buffer, depending on the video mode in use.  You can
determine the number of displayed pixels per byte by examining the
low-order bit of the clocking-mode register (1) in the VGA's sequencer
(which provides basic timing for video memory).  This register is examined
by writing its register number (1) to I/O port 3C4H and then reading port
3C5H to retrieve the contents of the register.  Whether the VGA is
displaying eight or nine pixels per byte, you can use the information in
table 1 to determine the horizontal-pel-panning value required to produce
the desired image shift.

Listing 4 brings all these hardware programming techniques together in a
single, C-callable subroutine that positions the screen window's origin at
a specified pixel location.  Developers can achieve smooth panning and
scrolling effects simply by calling the routine within an iterative loop. 
For example, the C program in listing 5 uses the subroutine in listing 4 to
scroll the screen window smoothly down and up by 100 pixels.

Rewriting this program to scroll the screen window horizontally instead of
vertically reveals a problem.  The logical width of the video buffer is the
same as that of the screen window, so horizontal panning simply wraps the
screen image around the screen.  Increasing the logical width of the video
buffer will allow the developer to scan any material that extends beyond
the width of the screen. RESHAPING THE BUFFER The key to redimensioning the
video buffer is the CRTC-offset register (13H). This register specifies the
logical width of the video buffer, measured in 16-bit words (not bytes). 
In 80-column alphanumeric video modes, the logical line width is 80 bytes
and the value in the offset register is 28H (40 decimal).  In graphics
modes, each byte has 8 displayed pixels.  Thus, in modes having a
horizontal resolution of 640 pixels, the offset register again contains
28H.

To change the VGA video buffer's logical width, simply update the
CRTC-offset register.  For example, you can double the logical width in
80-column alphanumeric modes by storing 50H (80 decimal) in the offset
register.  Modifying listing 5 to do this before panning allows horizontal
panning to proceed across 160-character columns without wrapping.

When redimensioning the video buffer, be careful not to exceed its 64KB
logical size.  For example, in 640-by-480 graphics modes, the logical width
of the video buffer should be no larger than 65,536 bytes per 480 lines,
which equals about 136 bytes (68 words) per line.  Larger values cause the
displayed image to wrap from the top to the bottom of the screen.

To use the display screen as a window on a video buffer that contains more
than one screenful of data, you can fill the entire VGA video buffer with
displayable text or graphics data.  Although only a portion of the contents
of the video buffer can be displayed at one time, you can arrange it so
that keyboard commands or a pointing device will pan the screen to any
desired location in the video buffer.

The ROM BIOS routines are comparatively tolerant about storing text or
graphics data in nondisplayed portions of the video buffer. If you use the
VGA ROM BIOS routines for this purpose, be sure to update the relevant
status variables in the ROM BIOS data segment (see table 2).  This helps
ensure that the ROM BIOS INT 10H functions for character output (functions
9, 0AH, and 0EH) and pixel output (function 0CH) work properly. SEPARATE
BUT EQUAL The VGA's split-screen display is essentially a display of two
different portions of the video buffer at the same time.  As shown in
figure 2, the upper part of the video display contains the data from the
portion of the video buffer designated by the CRTC start-address registers,
and the lower part of the video display contains the data from the
beginning of the video buffer (starting at offset 0 in the buffer).

When using the VGA split-screen feature, keep in mind that most commercial
software packages use the beginning of the video buffer for output. This is
the portion that appears in the bottom part of the split screen.  For
example, when using the DOS command processor, COMMAND.COM, the
command-line prompt will appear in the bottom part of the screen.  For data
to appear in the top part of a split screen, you must store the data in the
portion of the video buffer that begins at the address contained in the
CRTC start-address registers.

You can change the size of the two parts of the split-screen display by
specifying the scan line at which the split in the screen occurs in the
CRTC line-compare register (18H).  Like the other CRTC registers, line
compare is an 8-bit register that contains a value no larger than FFH (255
decimal).  Because the VGA can display more than 256 scan lines, the
designers of the CRTC hardware had to find a way to let developers specify
line-compare values larger than 255.  They accomplished this by using a
10-bit line-compare value; bits 0-7 are stored in the line-compare
register, bit 8 is stored as bit 4 in the CRTC overflow register (7), and
bit 9 is stored as bit 6 in the CRTC maximum-scan-line register (9).  Thus,
in order to create a VGA split screen, you must update three different CRTC
registers to store the 10-bit line-compare value (see listing 6).

To slide the split up and down (enlarging one or the other window), change
the line-compare value within an iterative loop. Increasing the value
enlarges the top part of the displayed image; decreasing the value expands
the bottom part.  To disable the split screen, use the maximum possible
line-compare value (3FFH).  This is the value used by default in all ROM
BIOS video modes. TWO-TONE PROGRAMS Many developers combine panning and
split-screen techniques in the same program only after they have developed
routines for each feature separately and feel comfortable with them.  When
the two techniques are used together in one program, the result is that the
bottom portion of a displayed image remains stationary while the top
portion is moving.

The C program shown in listing 7 provides a simple example of how to
accomplish this capability.  The program produces the illusion of
continuous output by plotting data points at the right side of the screen,
panning from right to left, and then erasing all previously plotted points
as they reach the left side of the screen.  The assembly-language routine
in listing 8 is used to set pixels on the screen.

A potential problem with split-screen panning can occur because changing
the value in the horizontal-pel-panning register shifts both halves of the
screen when developers most likely want to pan only one part.  Developers
can avoid this double panning by setting bit 5 of the attribute controller
mode-control register (register 10H) to 1, which instructs the attribute
controller to use a horizontal-pel-panning register value of zero for the
bottom part of the split-screen image, regardless of the actual value.  In
listing 6, an INT 10H function is used to set bit 5 in the mode-control
register so that all subsequent horizontal-panning operations will proceed
smoothly.

This hardware solution, however, introduces a new problem--bad wrapping. In
the default ROM BIOS alphanumeric modes, the VGA displays nine horizontal
pixels per character.  In this case, setting the horizontal-pel-panning
register to zero shifts the displayed image left by one pixel as described
in table 1. If the top part of the split screen is panned when the VGA
alphanumeric mode is being used, the first-pixel column in the bottom
portion of the split screen wraps from the left to the right side of the
screen. Making the first character blank in each line of the bottom part of
the screen ensures that information does not wrap around. THE PERFECT
PICTURE Few existing programs and software take full advantage of pixel
panning and split screens because of the unreliability and slowness of
these features in the past.  But the VGA's excellent hardware-level support
for these practical functions is the first step in increasing awareness and
use of them.  The proliferation of pixel panning and split screens in the
software community can mean a new wave of increasingly functional and
productive PC applications and programming tools.

Even with the best software, however, PC developers are ultimately limited
in what they can achieve with VGA hardware.  The VGA provides better PC
graphics capabilities than have been previously available, but still these
features clearly are not designed for sophisticated animation-quality
graphics.

For developer ease, the next logical step is to incorporate routines for
the VGA's split screen and panning in C and other language libraries so
that developers do not have to re-create them.  IBM and vendors of VGA
compatibles would aid developers by supporting pixel panning and split
screens at the VGA's BIOS level. This support would reduce the amount of
assembly-language code developers must write to access these features.
Richard Wilton is a fellow in UCLA's Medical Informatics Program.  He is
author of the Programmer's Guide to PC and PS/2 Video Systems (1987) and
coauthor of The New Peter Norton Programmer's Guide to the PC and PS/2
(1988), both from Microsoft Press.

===========================================================================
