Files
pintos_22/specs/freevga/vga/vgadac.htm
2024-10-01 23:37:39 +01:00

191 lines
9.2 KiB
HTML

<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Joshua Neal">
<META NAME="Description" CONTENT="Pure VGA/SVGA hardware programming (registers, identification, and otherlow-level stuff.)">
<META NAME="KeyWords" CONTENT="VGA SVGA hardware video programming">
<TITLE>VGA/SVGA Video Programming--DAC Operation</TITLE>
</HEAD>
<BODY>
<CENTER><A HREF="../home.htm">Home</A> <A HREF="#intro">Intro</A> <A HREF="#DAC">DAC</A>
<A HREF="#programming">Programming</A> <A HREF="#precautions">Precautions</A>
<A HREF="#flicker">Flicker</A> <A HREF="#state">State</A> <A HREF="vga.htm#general">Back</A>&nbsp;
<HR WIDTH="100%"><B>Hardware Level VGA and SVGA Video Programming Information
Page</B></CENTER>
<CENTER>DAC Operation&nbsp;
<HR WIDTH="100%"></CENTER>
<UL>
<LI>
<A HREF="#intro">Introduction</A> -- details the standard VGA DAC capabilities.</LI>
<LI>
<A HREF="#DAC">DAC Subsystem</A> -- gives a description of the DAC hardware.</LI>
<LI>
<A HREF="#programming">Programming the DAC</A> -- details reading and writing
to DAC memory.</LI>
<LI>
<A HREF="#precautions">Programming Precautions</A> -- details potential
problems that can be encountered with DAC hardware.</LI>
<LI>
<A HREF="#flicker">Eliminating Flicker</A> -- details on how to manipulate
DAC memory without causing visible side-effects.</LI>
<LI>
<A HREF="#state">The DAC State</A> -- details one possible use for an otherwise
useless field</LI>
</UL>
<A NAME="intro"></A><B>Introduction</B>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; One of the improvements
the VGA has over the EGA hardware is in the amount of possible colors that
can be generated, in addition to an increase in the amount of colors that
can be displayed at once. The VGA hardware has provisions for up to 256
colors to be displayed at once, selected from a range of 262,144 (256K)
possible colors. This capability is provided by the DAC subsystem, which
accepts attribute information for each pixel and converts it into an analog
signal usable by VGA displays.
<P><A NAME="DAC"></A><B>DAC Subsystem</B>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The VGA's DAC subsystem
accepts an 8 bit input from the attribute subsystem and outputs an analog
signal that is presented to the display circuitry. Internally it contains
256 18-bit memory locations that store 6 bits each of red, blue, and green
signal levels which have values ranging from 0 (minimum intensity) to 63
(maximum intensity.) The DAC hardware takes the 8-bit value from the attribute
subsystem and uses it as an index into the 256 memory locations and obtains
a red, green, and blue triad and produces the necessary output.
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Note -- the DAC subsystem
can be implemented in a number of ways, including discrete components,
in a DAC chip which may or may not contain internal ram, or even integrated
into the main chipset ASIC itself. Many modern DAC chipsets include additional
functionality such as hardware cursor support, extended color mapping,
video overlay, gamma correction, and other functions. Partly because of
this it is difficult to generalize the DAC subsystem's exact behavior.
This document focuses on the common functionality of all VGA DACs; functionality
specific to a particular chipset are described elsewhere.
<P><A NAME="programming"></A><B>Programming the DAC</B>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The DAC's primary host interface
(there may be a secondary non-VGA compatible access method) is through
a set of four external registers containing the <A HREF="colorreg.htm#3C8">DAC
Write Address</A>, the <A HREF="colorreg.htm#3C7W">DAC Read Address</A>,
the <A HREF="colorreg.htm#3C9">DAC Data</A>, and the <A HREF="colorreg.htm#3C7R">DAC
State</A> fields. The DAC memory is accessed by writing an index value
to the <A HREF="colorreg.htm#3C8">DAC Write Address</A> field for write
operations, and to the <A HREF="colorreg.htm#3C7W">DAC Read Address</A>
field for read operations. Then reading or writing the <A HREF="colorreg.htm#3C9">DAC
Data</A> field, depending on the selected operation, three times in succession
returns 3 bytes, each containing 6 bits of red, green, and blue intensity
values, with red being the first value and blue being the last value read/written.
The read or write index then automatically increments such that the next
entry can be read without having to reprogramming the address. In this
way, the entire DAC memory can be read or written in 768 consecutive I/O
cycles to/from the <A HREF="colorreg.htm#3C9">DAC Data</A> field. The <A HREF="colorreg.htm#3C7R">DAC
State</A> field reports whether the DAC is setup to accept reads or writes
next.
<P><A NAME="precautions"></A><B>Programming Precautions</B>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Due to the variances in
the different implementations, programming the DAC takes extra care to
ensure proper operation across the range of possible implementations. There
are a number of things can cause undesired effects, but the simplest way
to avoid problems is to ensure that you program the <A HREF="colorreg.htm#3C7W">DAC
Read Address</A> field or the <A HREF="colorreg.htm#3C8">DAC Write Address</A>
field before each read operation (note that a read operation may include
reads/writes to multiple DAC memory entries.) And always perform writes
and reads in groups of 3 color values. The DAC memory may not be updated
properly otherwise. Reading the value of the <A HREF="colorreg.htm#3C8">DAC
Write Address</A> field may not produce the expected result, as some implementations
may return the current index and some may return the next index. This operation
may even be dependent on whether a read or write operation is being performed.
While it may seem that the DAC implements 2 separate indexes for read and
write, this is often not the case, and interleaving read and write operations
may not work properly without reprogramming the appropriate index.
<UL>
<LI>
<B>Read Operation</B></LI>
<UL>
<LI>
Disable interrupts (this will ensure that a interrupt service routine will
not change the DAC's state)</LI>
<LI>
Output beginning DAC memory index to the <A HREF="colorreg.htm#3C7W">DAC
Read Address</A> register.</LI>
<LI>
Input red, blue, and green values from the <A HREF="colorreg.htm#3C9">DAC
Data</A> register, repeating for the desired number of entries to be read.</LI>
<LI>
Enable interrupts</LI>
</UL>
<LI>
<B>Write Operation</B></LI>
<UL>
<LI>
Disable interrupts (this will ensure that a interrupt service routine will
not change the DAC's state)</LI>
<LI>
Output beginning DAC memory index to the <A HREF="colorreg.htm#3C8">DAC
Write Address</A> register.</LI>
<LI>
Output red, blue, and green values to the <A HREF="colorreg.htm#3C9">DAC
Data</A> register, repeating for the desired number of entries to be read.</LI>
<LI>
Enable interrupts</LI>
</UL>
</UL>
<A NAME="flicker"></A><B>Eliminating Flicker</B>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; An important consideration
when programming the DAC memory is the possible effects on the display
generation. If the DAC memory is accessed by the host CPU at the same time
the DAC memory is being used by the DAC hardware, the resulting display
output may experience side effects such as flicker or "snow". Note that
both reading and writing to the DAC memory has the possibility of causing
these effects. The exact effects, if any, are dependent on the specific
DAC implementation. Unfortunately, it is not possible to detect when side-effects
will occur in all circumstances. The best measure is to only access the
DAC memory during periods of horizontal or vertical blanking. However,
this puts a needless burden on programs run on chipsets that are not affected.
If performance is an issue, then allowing the user to select between flicker-prone
and flicker-free access methods could possibly improve performance.
<P><A NAME="state"></A><B>The DAC State</B>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The <A HREF="colorreg.htm#3C7R">DAC
State</A> field seems to be totally useless, as the DAC state is usually
known by the programmer and it does not give enough information (about
whether a red, green, or blue value is expected next) for a interrupt routine
or such to determine the DAC state. However, I can think of one possible
use for it. You can use the DAC state to allow an interrupt driven routine
to access the palette (like for palette rotation effects or such) while
still allowing the main thread to write to the DAC memory. When the interrupt
routine executes it should check the DAC state. If the DAC state is in
a write state, it should not access the DAC memory. If it is in a read
state, the routine should perform the necessary DAC accesses then return
the DAC to a read state. This means that the main thread use the DAC state
to control the execution of the ISR. Also it means that it can perform
writes to the DAC without having to disable interrupts or otherwise inhibit
the ISR.
<BR>&nbsp;
<P>Notice: All trademarks used or referred to on this page are the property
of their respective owners.
<BR>All pages are Copyright &copy; 1997, 1998, J. D. Neal, except where
noted. Permission for utilization and distribution is subject to the terms
of the <A HREF="license.htm">FreeVGA Project Copyright License</A>.
<BR>&nbsp;
</BODY>
</HTML>