Introduction This page documents the
configuration of the VGA's CRTC registers which control the framing and
timing of video signals sent to the display device, usually a monitor.

Dot Clocks The standard VGA has two
"standard" dot clock frequencies available to it, as well as a possible
"external" clock source, which is implementation dependent. The two
standard clock frequencies are nominally 25 Mhz and 28 MHz. Some
chipsets use 25.000 MHz and 28.000 MHz, while others use slightly greater
clock frequencies. The IBM VGA chipset I have uses 25.1750 MHz
Mhz and 28.3220 crystals. Some newer cards use the closest generated
frequency produced by their clock chip. In most circumstances the
IBM VGA timings can be assumed as the monitor should allow an amount of
variance; however, if you know the actual frequencies used you should use
them in your timing calculations.
The dot clock source in
the VGA hardware is selected using the Clock
Select field. For the VGA, two of the values are undefined; some
SVGA chipsets use the undefined values for clock frequencies used for 132
column mode and such. The 25 MHz clock is designed for 320 and 640
pixel modes and the 28 MHz is designed for 360 and 720 pixel modes. The
Dot Clock Rate field specifies whether to use
the dot clock source directly or to divide it in half before using it as
the actual dot clock rate.

Horizontal Timing The VGA measures horizontal
timing periods in terms of character clocks, which can either be 8 or 9
dot clocks, as specified by the 9/8 Dot Mode
field. The 9 dot clock mode was included for monochrome emulation
and 9-dot wide character modes, and can be used to provide 360 and 720
pixel wide modes that work on all standard VGA monitors, when combined
with a 28 Mhz dot clock. The VGA uses a horizontal character counter which
is incremented at each character, which the horizontal timing circuitry
compares against the values of the horizontal timing fields to control
the horizontal state. The horizontal periods that are controlled are the
active display, overscan, blanking, and refresh periods.
The start of the active
display period coincides with the resetting of the horizontal character
counter, thus is fixed at zero. The value at which the horizontal
character is reset is controlled by the Horizontal
Total field. Note, however, that the value programmed into the Horizontal
Total field is actually 5 less than the actual value due to timing
concerns.
The end of the active display
period is controlled by the End Horizontal Display
field. When the horizontal character counter is equal to the value
of this field, the sequencer begins outputting the color specified by the
Overscan Palette Index field. This continues
until the active display begins at the beginning of the next scan line
when the active display begins again. Note that the horizontal blanking
takes precedence over the sequencer and attribute controller.
The horizontal blanking
period begins when the character clock equals the value of the Start
Horizontal Blanking field. During the horizontal blanking period,
the output voltages of the DAC signal the monitor to turn off the guns.
Under normal conditions, this prevents the overscan color from being displayed
during the horizontal retrace period. This period extends until the
lower 6 bits of the End Horizontal Blanking
field match the lower 6 bits of the horizontal character counter.
This allows for a blanking period from 1 to 64 character clocks, although
some implementations may treat 64 as 0 character clocks in length.
The blanking period may occur anywhere in the scan line, active display
or otherwise even though its meant to appear outside the active display
period. It takes precedence over all other VGA output. There
is also no requirement that blanking occur at all. If the Start
Horizontal Blanking field falls outside the maximum value of the character
clock determined by the Horizontal Total field,
then no blanking will occur at all. Note that due to the setting
of the Horizontal Total field, the first match
for the End Horizontal Blanking field may
be on the following scan line.
Similar to the horizontal
blanking period, the horizontal retrace period is specified by the Start
Horizontal Retrace and End Horizontal Retrace
fields. The horizontal retrace period begins when the character clock equals
the value stored in the Start Horizontal Retrace
field. The horizontal retrace ends when the lower 5 bits of the character
clock match the bit pattern stored in the End
Horizontal Retrace field, allowing a retrace period from 1 to 32 clocks;
however, a particular implementation may treat 32 clocks as zero clocks
in length. The operation of this is identical to that of the horizontal
blanking mechanism with the exception of being a 5 bit comparison instead
of 6, and affecting the horizontal retrace signal instead of the horizontal
blanking.
There are two horizontal
timing fields that are described as being related to internal timings of
the VGA, the Display Enable Skew and Horizontal
Retrace Skew fields. In the VGA they do seem to affect the timing,
but also do not seem to be necessary for the operation of the VGA and are
pretty much unused. These registers were required by the IBM VGA
implementations, so I'm assuming this was added in the early stages of
the VGA design for EGA compatibility, but the internal timings were changed
to more friendly ones making the use of these fields unnecessary.
It seems to be totally safe to set these fields to 0 and ignore them.
See the register descriptions for more details, if you have to deal with
software that programs them.

Vertical Timing The VGA maintains a scanline
counter which is used to measure vertical timing periods. This counter
begins at zero which coincides with the first scan line of the active display.
This counter is set to zero before the beginning of the first scanline
of the active display. Depending on the setting of the Divide
Scan Line Clock by 2 field, this counter is incremented either every
scanline, or every second scanline. The vertical scanline counter
is incremented before the beginning of each horizontal scan line, as all
of the VGA's vertical timing values are measured at the beginning of the
scan line, after the counter has ben set/incremented. The maximum
value of the scanline counter is specified by the Vertical
Total field. Note that, like the rest of the vertical timing
values that "overflow" an 8-bit register, the most significant bits are
located in the Overflow Register. The
Vertical Total field is programmed with the
value of the scanline counter at the beginning of the last scanline.
The vertical active display
period begins when the scanline counter is at zero, and extends up to the
value specified by the Vertical Display End
field. This field is set with the value of the scanline counter at
the beginning of the first inactive scanline, telling the video hardware
when to stop outputting scanlines of sequenced pixel data and outputs the
attribute specified by the Overscan Palette Index
field in the horizontal active display period of those scanlines.
This continues until the start of the next frame when the active display
begins again.
The Start
Vertical Blanking and End Vertical Blanking
fields control the vertical blanking interval. The Start
Vertical Blanking field is programmed with the value of the scanline
counter at the beginning of the scanline to begin blanking at. The
value of the End Vertical Blanking field is
set to the lower eight bits of the scanline counter at the beginning of
the scanline after the last scanline of vertical blanking.
The Vertical
Retrace Start and Vertical Retrace End
fields determine the length of the vertical retrace interval. The
Vertical Retrace Start field contains the
value of the scanline counter at the beginning of the first scanline where
the vertical retrace signal is asserted. The Vertical
Retrace End field is programmed with the value of the lower four bits
of the scanline counter at the beginning of the scanline after the last
scanline where the vertical retrace signal is asserted.

Monitoring Timing There are certain operations
that should be performed during certain periods of the display cycle to
minimize visual artifacts, such as attribute and DAC writes. There
are two bit fields that return the current state of the VGA, the Display
Disabled and Vertical Retrace fields.
The Display Disabled field is set to 1 when
the display enable signal is not asserted, providing the programmer with
a means to determine if the video hardware is currently refreshing the
active display or it is currently outputting blanking.
The Vertical
Retrace field signals whether or not the VGA is in a vertical retrace
period. This is useful for determining the end of a display period,
which can be used by applications that need to update the display every
period such as when doing animation. Under normal conditions, when
the blanking signal is asserted during the entire vertical retrace, this
can also be used to detect this period of blanking, such that a large amount
of register accesses can be performed, such as reloading the complete set
of DAC entries.

Miscellaneous There are a few registers
that affect display generation, but don't fit neatly into the horizontal
or vertical timing categories. The first is the Sync
Enable field which controls whether the horizontal and vertical sync
signals are sent to the display or masked off. The sync signals should
be disabled while setting up a new mode to ensure that an improper signal
that could damage the display is not being output. Keeping the sync
disabled for a period of one or more frames helps the display determine
that a mode change has occurred as well.
The Memory Refresh Bandwidth
field is used by the original IBM VGA hardware and some compatible VGA/SVGA
chipsets to control how often the display memory is refreshed. This
field controls whether the VGA hardware provides 3 or 5 memory refresh
cycles per scanline. At or above VGA horizontal refresh rates, this
field should be programmed for 3 memory refresh cycles per scanline.
Below this rate, for compatibility's sake the 5 memory refresh cycles per
scanline setting might be safer, see the Memory
Refresh Bandwidth field for (slightly) more information.