<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>The Bank-Switching Functions </TITLE>
</HEAD>
<BODY BGCOLOR="#efefef" TEXT="black" LINK="blue" VLINK="#551A8B" ALINK="red">

<A HREF="VGADriver.html"><EM> How to add an (S)VGA driver to XFree86</EM></A>
 <b>:</b> <EM>The Bank-Switching Functions </EM><BR>
<b>Previous:</b> <A HREF="VGADriver4.html"><EM>Setting Up The Build Information </EM></A><BR>
<b>Next:</b> <A HREF="VGADriver6.html"><EM>The Driver Itself </EM></A>


<HR NOSHADE>
  <H2><A NAME="5"></A>5. The Bank-Switching Functions </H2>
<p>The normal VGA memory map is 64k starting at address 0xA0000.  To access
more than 64k of memory, SuperVGA chipsets implement ``bank switching'' - 
the high-order address bits are used to select the bank of memory in which
operations will take place.  The size and number of these banks varies,
and will be spelled out in the chipset documentation.  A chipset will
have zero, one or two bank registers.  Likely the ONLY case of zero bank
registers is a generic VGA, and hence is not a concern.</p>
<p>Note that some of the newer chipsets (e.g. Trident 8900CL, Cirrus) allow
for a linear mapping of the video memory.  While using such a scheme would
improve the performance of the server, it is not currently supported.  Hence
there is no way to use such features for a new chipset.</p>
<p>Most SVGA chipsets have two bank registers.  This is the most desirable 
structure (if any banking structure can be called ``desirable''), because 
data can be moved from one area of the screen to another with a simple 
`mov' instruction.  There are two forms of dual-banking - one where the 
two bank operations define a read-only bank and a write-only bank, and
one with two read/write windows.  With the first form, the entire SVGA
memory window is used for both read a write operations, and the two
bank registers determine which bank is actually used (e.g. ET3000, ET4000).
With the second form, the SVGA memory window is split into two read/write
banks, with each bank pointer being used to control one window.  In
this case, one window is used for read operations and the other for write
operations (e.g. PVGA1/Western Digital, Cirrus).</p>
<p>A chipset that has a single bank register uses that one bank for both
read and write access.  This is problematic, because copying information
from one part of the screen to another requires that the data be read in,
stored, and then written out.  Fortunately, the server is able to handle
both one-bank and two-bank chipsets; the determination of behavior is
defined by an entry in the driver data structure described below.</p>
<p>A driver requires that three assembly-language functions be written, in
the file `<code>sdc_bank.s</code>'.
These functions set the read bank - <b>SDCSetRead()</b>,
the write bank - <b>SDCSetWrite()</b>, and set both banks -
<b>SDCSetReadWrite()</b>.
For a chipset with only one bank, all three will be declared as entry points
to the same function (see the ``tvga8900'' driver for an example).</p>
<p>The functions are fairly simple - the bank number is passed to the function
in register %al.  The function will shift, bitmask, etc - whatever is 
required to put the bank number into the correct form - and then write
it to the correct I/O port.  For chipsets where the two banks are read-only
HERE
and write-only, the <b>SetReadWrite()</b> function will have to do this twice - once 
for each bank.  For chipsets with two independent read/write windows, the
<b>SetReadWrite()</b> function should use the same bank as the <b>SetWrite()</b> function.</p>
<p>A special note - these functions MUST be written in the macroized assembler
format defined in the header file ``assyntax.h''.  This will ensure that
the correct assembler code will be generated, regardless of OS.  This
macroized format currently supports USL, GNU, and Intel assembler formats.</p>
<p>That's all there is to the banking functions.  Usually the chipset reference
will give examples of this code; if not, it is not difficult to figure out,
especially using the other drivers as examples.</p>

 <HR NOSHADE>
<A HREF="VGADriver.html"><EM> How to add an (S)VGA driver to XFree86</EM></A>
 <b>:</b> <EM>The Bank-Switching Functions </EM><BR>
<b>Previous:</b> <A HREF="VGADriver4.html"><EM>Setting Up The Build Information </EM></A><BR>
<b>Next:</b> <A HREF="VGADriver6.html"><EM>The Driver Itself </EM></A>



</BODY>
</HTML>
