Windowing
The VGA hardware has the
ability treat the display as a window which can pan and/or scroll across
an image larger than the screen, which is used by some windowing systems
to provide a virtual scrolling desktop, and by some games and assembly
demos to provide scrolling. Some image viewers use this to allow viewing
of images larger than the screen. This capability is not limited to graphics
mode; some terminal programs use this capability to provide a scroll-back
buffer, and some editors use this to provide an editing screen wider than
80 columns.
This feature can be implemented
by brute force by simply copying the portion of the image to be displayed
to the screen. Doing this, however takes significant processor horsepower.
For example, scrolling a 256 color 320x200 display at 30 frames per second
by brute force requires a data transfer rate of 1.92 megabytes/second.
However, using the hardware capability of the VGA the same operation would
require a data transfer rate of only 120 bytes/second. Obviously there
is an advantage to using the VGA hardware. However, there are some limitations--one
being that the entire screen must scroll (or the top portion of the screen
if split-screen mode is used.) and the other being that the maximum size
of the virtual image is limited to the amount of video memory accessible,
although it is possible to redraw portions of the display memory to display
larger virtual images.
In text mode, windowing
allows panning at the character resolution. In graphics mode, windowing
allows panning at 8-bit resolution and scrolling at scan-line resolution.
For more precise control, see Smooth Panning and Scrolling
below. Because the VGA BIOS and most programming environment's graphics
libraries do not support windowing, you must modify or write your own routines
to write to the display for functions such as writing text or graphics.
This section assumes that you have the ability to work with the custom
resolutions possible when windowing is used.
In order to understand virtual
resolutions it is necessary to understand how the VGA's Start
Address High Register, Start Address Low Register,
and Offset field work. Because display memory
in the VGA is accessed by a 32-bit bus, a 16-bit address is sufficient
to uniquely identify any location in the VGA's 256K address space. The
Start Address High Register and Start
Address Low Register provide such an address. This address is used
to specify either the location of the first character in text mode or the
position of the first byte of pixels in graphics mode. At the end of the
vertical retrace, the current line start address is loaded with this value.
This causes one scan line of pixels or characters to be output starting
at this address. At the beginning of the next scan-line (or character row
in text mode) the value of the Offset Register
multiplied by the current memory address size * 2 is added to the current
line start address. The Double-Word Addressing
field and the Word/Byte field specify the
current memory address size. If the value of the Double-Word
Addressing field is 1, then the current memory address size is four
(double-word). Otherwise, the Word/Byte field
specifies the current memory address size. If the value of the Word/Byte
field is 0 then the current memory address size is 2 (word) otherwise,
the current memory address size is 1 (byte).
Normally in graphics modes,
the offset register is programmed to represent (after multiplication) the
number of bytes in a scan line. This means that (unless a CGA/MDA emulation
mode is in effect) scan lines will be arranged sequentially in memory with
no space in between, allowing for the most compact representation in display
memory. However, this does not have to be the case--in fact, by increasing
the value of the offset register we can leave "extra space" between lines.
This is what provides for virtual widths. By programming the offset register
to the value of the equation:
Offset = VirtualWidth / ( PixelsPerAddress * MemoryAddressSize * 2 )
VirtualWidth is the width of the virtual resolution in pixels, and PixelsPerAddress is the number of pixels per display memory address (1, 2, 4 or 8) depending on the current video mode. For virtual text modes, the offset register is programmed with the value of the equation:
Offset = VirtualWidth / ( MemoryAddressSize * 2 )
In text mode, there is always one character per display memory address.
In standard CGA compatible text modes, MemoryAddressSize is 2 (word).
After you have programmed
the new offset, the screen will now display only a portion of a virtual
display. The screen will display the number of scan-lines as specified
by the current mode. If the screen reaches the last byte of memory, the
next byte of memory will wrap around to the first byte of memory. Remember
that the Start Address specifies the display memory address of the upper-left
hand character or pixel. Thus the maximum height of a virtual screen depends
on the width of the virtual screen. By increasing this by the number of
bytes in a scan-line (or character row), the display will scroll one scan-line
or character row vertically downwards. By increasing the Start Address
by less than the number of bytes in a scan line, you can move the virtual
window horizontally to the right. If the virtual width is the same as the
actual width, one can create a vertical scrolling mode. This is used sometimes
as an "elevator" mode or to provide rapid scrollback capability in text
mode. If the virtual height is the same as the actual height, then only
horizontal panning is possible, sometimes called "panoramic" mode. In any
case, the equation for calculating the Start Address is:
Start Address = StartingOffset + Y * BytesPerVirtualRow + X
Y is the vertical position, from 0 to the value of the VitrualHeight
- ActualHeight. X is the horizontal position, from 0 to the value of BytesPerVirtualRow
- BytesPerActualRow . These ranges prevent wrapping around to the left
side of the screen, although you may find it useful to use the wrap-around
for whatever your purpose. Note that the wrap-around simply starts displaying
the next row/scan-line rather than the current one, so is not that useful
(except when using programming techniques that take this factor into account.)
Normally StartingOffset is 0, but if paging or split-screen mode is being
used, or even if you simply want to relocate the screen, you must change
the starting offset to the address of the upper-left hand pixel of the
virtual screen.
For example, a 512x300 virtual
screen in a 320x200 16-color 1 bit/pixel planar display would require 512
pixels / 8 pixels/byte = 64 bytes per row and 64 bytes/row * 300 lines
= 19200 bytes per screen. Assuming the VGA is in byte addressing mode,
this means that we need to program the offset register Offset
field with 512 pixels / (8 pixels/byte * 1 * 2) = 32 (20h). Adding one
to the start address will move the display screen to the right eight pixels.
More precise control is provided by the smooth scrolling mechanism. Adding
64 to the start address will move the virtual screen down one scan line.
See the following chart which shows the virtual screen when the start address
is calculated with an X and Y of 0:
Paging
The video display memory
may be able to hold more than one screen of data (or virtual screen if
virtual resolutions are used.) These multiple screens, called pages, allows
rapid switching between them. As long as they both have the same actual
(and virtual if applicable) resolution, simply changing the Start Address
as given by the Start Address High Register
and Start Address Low Register pair to point
to the memory address of the first byte of the page (or set the StartingOffset
term in the equation for virtual resolutions to the first memory address
of the page.) If they have different virtual widths, then the Offset
field must be reprogrammed. It is possible to store both graphics and text
pages simultaneously in memory, in addition to different graphics mode
pages. In this case, the video mode must be changed when changing pages.
In addition, in text mode the Cursor Location must be reprogrammed for
each page if it is to be displayed. Also paging allows for double buffering
of the display -- the CPU can write to one page while the VGA hardware
is displaying another. By switching between pages during the vertical retrace
period, flicker free screen updates can be implemented.
An example of paging is
that used by the VGA BIOS in the 80x25 text mode. Each page of text takes
up 2000 memory address locations, and the VGA uses a 32K memory aperture,
with the Odd/Even addressing enabled. Because Odd/Even addressing is enabled,
each page of text takes up 4000 bytes in host memory, thus 32768 / 4000
= 8 (rounded down) pages can be provided and can be accessed at one time
by the CPU. Each page starts at a multiple of 4096 (1000h). Because the
display controller circuitry works independent of the host memory access
mode, this means that each page starts at a display address that is a multiple
of 2048 (800h), thus the Starting Address is programmed to the value obtained
by multiplying the page to be displayed by 2048 (800h). See the following
chart which shows the arrangement of these pages in display memory:
Smooth Panning and Scrolling
Because the Start Address
field only provides for scrolling and panning at the memory address level,
more precise panning and scrolling capability is needed to scroll at the
pixel level as multiple pixels may reside at the same memory address especially
in text mode where the Start Address field only allows panning and scrolling
at the character level.
Pixel level panning is controlled
by the Pixel Shift Count and Byte
Panning fields. The Pixel Shift Count
field specifies the number of pixels to shift left. In all graphics modes
and text modes except 9 dot text modes and 256 color graphics modes, the
Pixel Shift Count is defined for values 0-7.
This provides the pixel level control not provided by the Start
Address Register or the Byte Panning fields.
In 9 dot text modes the Pixel Shift Count
is field defined for values 8, and 0-7, with 8 being the minimum shift
amount and 7 being the maximum. In 256 color graphics modes, due to the
way the hardware makes a 256 color value by combining 2 16-bit values,
the Pixel Shift Count field is only defined
for values 0, 2, 4, and 6. Values 1, 3, 5, and 7 cause the screen to be
distorted due to the hardware combining 4 bits from each of 2 adjacent
pixels. The Byte Panning field is added to
the Start Address Register when determining
the address of the top-left hand corner of the screen, and has the value
from 0-3. Combined, both panning fields allow a shift of 15, 31, or 35
pixels, dependent upon the video mode. Note that programming the Pixel
Shift Count field to an undefined value may cause undesired effects
and these effects are not guaranteed to be identical on all chipsets, so
it is best to be avoided.
Pixel level scrolling is
controlled by the Preset Row Scan field. This
field may take any value from 0 up to the value of the Maximum
Scan Line field; anything greater causes interesting artifacts (there
is no guarantee that the result will be the same for all VGA chipsets.)
Incrementing this value will shift the screen upwards by one scan line,
allowing for smooth scrolling in modes where the Offset field does not
provide precise control.
Split-screen Operation
The VGA hardware provides
the ability to specify a horizontal division which divides the screen into
two windows which can start at separate display memory addresses. In addition,
it provides the facility for panning the top window independent of the
bottom window. The hardware does not provide for split-screen modes where
multiple video modes are possible in one display screen as provided by
some non-VGA graphics controllers. In addition, there are some limitations,
the first being that the bottom window's starting display memory address
is fixed at 0. This means that (unless you are using split screen mode
to duplicate memory on purpose) the bottom screen must be located first
in memory and followed by the top. The second limitation is that either
both windows are panned by the same amount, or only the top window pans,
in which case, the bottom window's panning values are fixed at 0. Another
limitation is that the Preset Row Scan field
only applies to the top window -- the bottom window has an effective Preset
Row Scan value of 0.
The Line Compare field in
the VGA, of which bit 9 is in the Maximum Scan
Line Register, bit 8 is in the Overflow Register,
and bits 7-0 are in the Line Compare Register,
specifies the scan line address of the horizontal division. When the line
counter reaches the value in the Line Compare Register, the current scan
line start address is reset to 0. If the Pixel
Panning Mode field is set to 1 then the Pixel
Shift Count and Byte Panning fields are
reset to 0 for the remainder of the display cycle allowing the top window
to pan while the bottom window remains fixed. Otherwise, both windows pan
by the same amount.
Notice: All trademarks used or referred to on this page are the property
of their respective owners.
All pages are Copyright © 1997, 1998, J. D. Neal, except where
noted. Permission for utilization and distribution is subject to the terms
of the FreeVGA Project Copyright License.