xserver/hw/xorg/drivers/nv Makefile.am, NONE, 1.1 nv.4.html, NONE, 1.1 nv._man, NONE, 1.1 nv.man, NONE, 1.1 nv_const.h, NONE, 1.1 nv_cursor.c, NONE, 1.1 nv_dac.c, NONE, 1.1 nv_dga.c, NONE, 1.1 nv_dma.h, NONE, 1.1 nv_driver.c, NONE, 1.1 nv_hw.c, NONE, 1.1 nv_include.h, NONE, 1.1 nv_local.h, NONE, 1.1 nv_proto.h, NONE, 1.1 nv_setup.c, NONE, 1.1 nv_shadow.c, NONE, 1.1 nv_type.h, NONE, 1.1 nv_video.c, NONE, 1.1 nv_xaa.c, NONE, 1.1 riva_const.h, NONE, 1.1 riva_cursor.c, NONE, 1.1 riva_dac.c, NONE, 1.1 riva_dga.c, NONE, 1.1 riva_driver.c, NONE, 1.1 riva_hw.c, NONE, 1.1 riva_hw.h, NONE, 1.1 riva_include.h, NONE, 1.1 riva_local.h, NONE, 1.1 riva_proto.h, NONE, 1.1 riva_setup.c, NONE, 1.1 riva_shadow.c, NONE, 1.1 riva_tbl.h, NONE, 1.1 riva_type.h, NONE, 1.1 riva_xaa.c, NONE, 1.1

Chris Lee xserver-commit at pdx.freedesktop.org
Sat Jun 5 19:57:31 PDT 2004


Committed by: clee

Update of /cvs/xserver/xserver/hw/xorg/drivers/nv
In directory pdx:/tmp/cvs-serv427

Added Files:
	Makefile.am nv.4.html nv._man nv.man nv_const.h nv_cursor.c 
	nv_dac.c nv_dga.c nv_dma.h nv_driver.c nv_hw.c nv_include.h 
	nv_local.h nv_proto.h nv_setup.c nv_shadow.c nv_type.h 
	nv_video.c nv_xaa.c riva_const.h riva_cursor.c riva_dac.c 
	riva_dga.c riva_driver.c riva_hw.c riva_hw.h riva_include.h 
	riva_local.h riva_proto.h riva_setup.c riva_shadow.c 
	riva_tbl.h riva_type.h riva_xaa.c 
Log Message:
This is an autotooled version of the 'nv' driver from the Xorg monolithic tree. The driver builds and loads perfectly here with no known issues, if the patch from http://c133.org/files/Xorg-buildsystem.diff is applied from the xserver base directory.


--- NEW FILE: Makefile.am ---
AM_CFLAGS = $(XORG_CFLAGS)

INCLUDES = $(XORG_INCS) \
	   -I$(top_srcdir)/mi \
	   -I$(top_srcdir)/fb \
	   -I$(top_srcdir)/hw/xorg/fbdevhw \
	   -I$(top_srcdir)/hw/xorg/loader \
	   -I$(top_srcdir)/hw/xorg/ddc \
	   -I$(top_srcdir)/hw/xorg/rac \
	   -I$(top_srcdir)/hw/xorg/vbe \
	   -I$(top_srcdir)/hw/xorg/int10 \
	   -I$(top_srcdir)/hw/xorg/i2c \
	   -I$(top_srcdir)/hw/xorg/parser \
	   -I$(top_srcdir)/hw/xorg/shadowfb \
	   -I$(top_srcdir)/hw/xorg/vgahw \
	   -I$(top_srcdir)/hw/xorg/Xi \
	   -I$(top_srcdir)/hw/xorg/xaa \
	   -I$(top_srcdir)/hw/xorg/ramdac \
	   -I$(top_srcdir)/os \
	   -I$(top_srcdir)/hw/xorg/xf1bpp \
	   -I$(top_srcdir)/hw/xorg/xf4bpp \
	   -I$(top_srcdir)/mfb

lib_LIBRARIES = libnv.a

libnv_drv_a_SOURCES = \
                      nv_driver.c \
		      nv_dac.c \
		      nv_setup.c \
		      nv_cursor.c \
		      nv_xaa.c \
		      nv_dga.c \
		      nv_shadow.c \
		      nv_hw.c \
		      nv_video.c

libriva128_a_SOURCES = \
		       riva_driver.c \
		       riva_dac.c \
		       riva_setup.c \
		       riva_cursor.c \
		       riva_xaa.c \
		       riva_dga.c \
		       riva_shadow.c \
		       riva_hw.c

libnv_a_SOURCES = $(libnv_drv_a_SOURCES) $(libriva128_a_SOURCES)

--- NEW FILE: nv.4.html ---

<!--
  $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv.man,v 1.22 2003/10/18 01:14:26 mvojkovi Exp $ 
   shorthand for double quote that works everywhere.
 
-->
<!-- manual page source format generated by PolyglotMan v3.0.8+XFree86, -->
<!-- available at http://polyglotman.sourceforge.net/ -->

<html>
<head>
<title>NV(4) manual page</title>
</head>
<body bgcolor='#efefef' text='black' link='blue' vlink='#551A8B' alink='red'>
<a href='#toc'>Table of Contents</a><p>

<h2><a name='sect0' href='#toc0'>Name</a></h2>
nv - NVIDIA video driver 
<h2><a name='sect1' href='#toc1'>Synopsis</a></h2>
<br>
<pre><b>Section "Device"</b>
<b>  Identifier "</b><i>devname</i><b>"</b>
<b>  Driver "nv"</b>
&nbsp;&nbsp;...
<b>EndSection</b>
</pre>
<h2><a name='sect2' href='#toc2'>Description</a></h2>
<b>nv </b> is an XFree86 driver for NVIDIA video cards.  The driver
supports 2D  acceleration and provides support for the following framebuffer
depths: 8, 15, 16 (except Riva128) and 24.  All visual types are supported
for depth 8, TrueColor and DirectColor visuals are supported for the other
depths with the exception of the Riva128 which only supports TrueColor
in the higher depths.  
<p> 
<h2><a name='sect3' href='#toc3'>Supported Hardware</a></h2>
The <b>nv</b> driver supports PCI and
AGP video cards based on the following NVIDIA chips: 
<dl>

<dt><b>RIVA 128</b> </dt>
<dd>NV3 </dd>

<dt><b>RIVA
TNT</b> </dt>
<dd>NV4 </dd>

<dt><b>RIVA TNT2</b> </dt>
<dd>NV5 </dd>

<dt><b>GeForce 256, QUADRO </b> </dt>
<dd>NV10 </dd>

<dt><b>GeForce2, QUADRO2</b> </dt>
<dd>NV11
&amp; NV15   </dd>

<dt><b>GeForce3, QUADRO DCC</b> </dt>
<dd>NV20 </dd>

<dt><b>nForce, nForce2</b> </dt>
<dd>NV1A, NV1F </dd>

<dt><b>GeForce4,
QUADRO4</b> </dt>
<dd>NV17, NV18, NV25, NV28 </dd>

<dt><b>GeForce FX, QUADRO FX</b> </dt>
<dd>NV30, NV31, NV34,
NV35, NV36, NV38 </dd>
</dl>

<h2><a name='sect4' href='#toc4'>Configuration Details</a></h2>
Please refer to <a href='XF86Config.5.html'>XF86Config(5x)</a>
 for
general configuration details.  This section only covers configuration details
specific to this driver. <p>
The driver auto-detects the chipset type and the
amount of video memory present for all chips. <p>
The following driver <b>Options</b>
are supported: 
<dl>

<dt><b>Option "HWCursor" "</b><i>boolean</i><b>"</b> </dt>
<dd>Enable or disable the HW cursor.
 Default: on. </dd>

<dt><b>Option "NoAccel" "</b><i>boolean</i><b>"</b> </dt>
<dd>Disable or enable acceleration.
 Default: acceleration is enabled. </dd>

<dt><b>Option "UseFBDev" "</b><i>boolean</i><b>"</b> </dt>
<dd>Enable or
disable use of on OS-specific fb interface (and is not supported on all
OSs).  See <a href='fbdevhw.4.html'>fbdevhw(4)</a>
 for further information. Default: off. </dd>

<dt><b>Option "CrtcNumber"
"</b><i>integer</i><b>"</b> </dt>
<dd>GeForce2 MX, nForce2, Quadro4, GeForce4, Quadro FX and GeForce
FX  may have two video outputs.   The driver attempts to autodetect which
one the monitor is connected to.  In the case that autodetection picks the
wrong one, this option may be used to force usage of a particular output.
 The options are "0" or "1". Default: autodetected. </dd>

<dt><b>Option "FlatPanel" "</b><i>boolean</i><b>"</b>
</dt>
<dd>The driver usually can autodetect the presence of a digital flat panel.
 In the case that this fails, this option can be used to force the driver
to  treat the attached device as a digital flat panel.  With this  driver,
a digital flat panel will only work if it was POSTed by the BIOS,  that
is, the machine must have booted to the panel.  If you have a dual head
card you may also need to set the option CrtcNumber described above. Default:
off. </dd>

<dt><b>Option "FPDither" "</b><i>boolean</i><b>"</b> </dt>
<dd>Many digital flat panels (particularly
ones on laptops) have only 6 bits  per component color resolution. This
option tells the driver to dither from 8 bits per component to 6 before
the flat panel truncates it. This is only supported in depth 24 on GeForce2
MX,  nForce2, GeForce4, Quadro4, Geforce FX and Quadro FX. Default: off.
</dd>

<dt><b>Option "Rotate" "CW"</b> </dt>
<dd></dd>

<dt><b>Option "Rotate" "CCW"</b> </dt>
<dd>Rotate the display clockwise
or counterclockwise.  This mode is unaccelerated. Default: no rotation. 
<p> Note:
The Resize and Rotate extension will be disabled if the Rotate option is
used. </dd>

<dt><b>Option "ShadowFB" "</b><i>boolean</i><b>"</b> </dt>
<dd>Enable or disable use of the shadow framebuffer
layer.  Default: off. </dd>
</dl>

<h2><a name='sect5' href='#toc5'>See Also</a></h2>
<a href='XFree86.1.html'>XFree86(1)</a>
, <a href='XF86Config.5.html'>XF86Config(5x)</a>
, <a href='xf86config.1.html'>xf86config(1)</a>
,
<a href='Xserver.1.html'>Xserver(1)</a>
, <a href='X.7.html'>X(7)</a>
 
<h2><a name='sect6' href='#toc6'>Authors</a></h2>
Authors include: David McKay, Jarno Paananen, Chas
Inman, Dave Schmenk,  Mark Vojkovich <p>

<hr><p>
<a name='toc'><b>Table of Contents</b></a><p>
<ul>
<li><a name='toc0' href='#sect0'>Name</a></li>
<li><a name='toc1' href='#sect1'>Synopsis</a></li>
<li><a name='toc2' href='#sect2'>Description</a></li>
<li><a name='toc3' href='#sect3'>Supported Hardware</a></li>
<li><a name='toc4' href='#sect4'>Configuration Details</a></li>
<li><a name='toc5' href='#sect5'>See Also</a></li>
<li><a name='toc6' href='#sect6'>Authors</a></li>
</ul>
</body>
</html>

--- NEW FILE: nv._man ---
.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv.man,v 1.22 2003/10/18 01:14:26 mvojkovi Exp $ 
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH NV 4 Version\ 4.3.99.902 XFree86
.SH NAME
nv \- NVIDIA video driver
.SH SYNOPSIS
.nf
.B "Section \*qDevice\*q"
.BI "  Identifier \*q"  devname \*q
.B  "  Driver \*qnv\*q"
\ \ ...
.B EndSection
.fi
.SH DESCRIPTION
.B nv 
is an XFree86 driver for NVIDIA video cards.  The driver supports 2D 
acceleration and provides support for the following framebuffer depths:
8, 15, 16 (except Riva128) and 24.  All
visual types are supported for depth 8, TrueColor and DirectColor
visuals are supported for the other depths with the exception of
the Riva128 which only supports TrueColor in the higher depths. 

.SH SUPPORTED HARDWARE
The
.B nv
driver supports PCI and AGP video cards based on the following NVIDIA chips:
.TP 22
.B RIVA 128
NV3
.TP 22
.B RIVA TNT
NV4
.TP 22
.B RIVA TNT2
NV5
.TP 22
.B GeForce 256, QUADRO 
NV10
.TP 22
.B GeForce2, QUADRO2
NV11 & NV15  
.TP 22
.B GeForce3, QUADRO DCC
NV20
.TP 22
.B nForce, nForce2
NV1A, NV1F
.TP 22
.B GeForce4, QUADRO4
NV17, NV18, NV25, NV28
.TP 22
.B GeForce FX, QUADRO FX
NV30, NV31, NV34, NV35, NV36, NV38
.SH CONFIGURATION DETAILS
Please refer to XF86Config(5x) for general configuration
details.  This section only covers configuration details specific to this
driver.
.PP
The driver auto-detects the chipset type and the amount of video memory
present for all chips.
.PP
The following driver
.B Options
are supported:
.TP
.BI "Option \*qHWCursor\*q \*q" boolean \*q
Enable or disable the HW cursor.  Default: on.
.TP
.BI "Option \*qNoAccel\*q \*q" boolean \*q
Disable or enable acceleration.  Default: acceleration is enabled.
.TP
.BI "Option \*qUseFBDev\*q \*q" boolean \*q
Enable or disable use of on OS-specific fb interface (and is not supported
on all OSs).  See fbdevhw(4) for further information.
Default: off.
.TP
.BI "Option \*qCrtcNumber\*q \*q" integer \*q
GeForce2 MX, nForce2, Quadro4, GeForce4, Quadro FX and GeForce FX 
may have two video outputs.  
The driver attempts to autodetect
which one the monitor is connected to.  In the case that autodetection picks
the wrong one, this option may be used to force usage of a particular output. 
The options are "0" or "1".
Default: autodetected.
.TP
.BI "Option \*qFlatPanel\*q \*q" boolean \*q
The driver usually can autodetect the presence of a digital flat panel.  In
the case that this fails, this option can be used to force the driver to 
treat the attached device as a digital flat panel.  With this 
driver, a digital flat panel will only work if it was POSTed by the BIOS, 
that is, the
machine must have booted to the panel.  If you have a dual head card
you may also need to set the option CrtcNumber described above.
Default: off.
.TP
.BI "Option \*qFPDither\*q \*q" boolean \*q
Many digital flat panels (particularly ones on laptops) have only 6 bits 
per component color resolution.
This option tells the driver to dither from 8 bits per component to 6 before
the flat panel truncates it. This is only supported in depth 24 on GeForce2 MX, 
nForce2, GeForce4, Quadro4, Geforce FX and Quadro FX.
Default: off.
.TP
.BI "Option \*qRotate\*q \*qCW\*q"
.TP
.BI "Option \*qRotate\*q \*qCCW\*q"
Rotate the display clockwise or counterclockwise.  This mode is unaccelerated.
Default: no rotation.

Note: The Resize and Rotate extension will be disabled if the Rotate option
is used.
.TP
.BI "Option \*qShadowFB\*q \*q" boolean \*q
Enable or disable use of the shadow framebuffer layer.  Default: off.
.SH "SEE ALSO"
XFree86(1), XF86Config(5x), xf86config(1), Xserver(1), X(7)
.SH AUTHORS
Authors include: David McKay, Jarno Paananen, Chas Inman, Dave Schmenk, 
Mark Vojkovich

--- NEW FILE: nv.man ---
.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv.man,v 1.22 2003/10/18 01:14:26 mvojkovi Exp $ 
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH NV __drivermansuffix__ __vendorversion__
.SH NAME
nv \- NVIDIA video driver
.SH SYNOPSIS
.nf
.B "Section \*qDevice\*q"
.BI "  Identifier \*q"  devname \*q
.B  "  Driver \*qnv\*q"
\ \ ...
.B EndSection
.fi
.SH DESCRIPTION
.B nv 
is an XFree86 driver for NVIDIA video cards.  The driver supports 2D 
acceleration and provides support for the following framebuffer depths:
8, 15, 16 (except Riva128) and 24.  All
visual types are supported for depth 8, TrueColor and DirectColor
visuals are supported for the other depths with the exception of
the Riva128 which only supports TrueColor in the higher depths. 

.SH SUPPORTED HARDWARE
The
.B nv
driver supports PCI and AGP video cards based on the following NVIDIA chips:
.TP 22
.B RIVA 128
NV3
.TP 22
.B RIVA TNT
NV4
.TP 22
.B RIVA TNT2
NV5
.TP 22
.B GeForce 256, QUADRO 
NV10
.TP 22
.B GeForce2, QUADRO2
NV11 & NV15  
.TP 22
.B GeForce3, QUADRO DCC
NV20
.TP 22
.B nForce, nForce2
NV1A, NV1F
.TP 22
.B GeForce4, QUADRO4
NV17, NV18, NV25, NV28
.TP 22
.B GeForce FX, QUADRO FX
NV30, NV31, NV34, NV35, NV36, NV38
.SH CONFIGURATION DETAILS
Please refer to XF86Config(__filemansuffix__) for general configuration
details.  This section only covers configuration details specific to this
driver.
.PP
The driver auto-detects the chipset type and the amount of video memory
present for all chips.
.PP
The following driver
.B Options
are supported:
.TP
.BI "Option \*qHWCursor\*q \*q" boolean \*q
Enable or disable the HW cursor.  Default: on.
.TP
.BI "Option \*qNoAccel\*q \*q" boolean \*q
Disable or enable acceleration.  Default: acceleration is enabled.
.TP
.BI "Option \*qUseFBDev\*q \*q" boolean \*q
Enable or disable use of on OS-specific fb interface (and is not supported
on all OSs).  See fbdevhw(__drivermansuffix__) for further information.
Default: off.
.TP
.BI "Option \*qCrtcNumber\*q \*q" integer \*q
GeForce2 MX, nForce2, Quadro4, GeForce4, Quadro FX and GeForce FX 
may have two video outputs.  
The driver attempts to autodetect
which one the monitor is connected to.  In the case that autodetection picks
the wrong one, this option may be used to force usage of a particular output. 
The options are "0" or "1".
Default: autodetected.
.TP
.BI "Option \*qFlatPanel\*q \*q" boolean \*q
The driver usually can autodetect the presence of a digital flat panel.  In
the case that this fails, this option can be used to force the driver to 
treat the attached device as a digital flat panel.  With this 
driver, a digital flat panel will only work if it was POSTed by the BIOS, 
that is, the
machine must have booted to the panel.  If you have a dual head card
you may also need to set the option CrtcNumber described above.
Default: off.
.TP
.BI "Option \*qFPDither\*q \*q" boolean \*q
Many digital flat panels (particularly ones on laptops) have only 6 bits 
per component color resolution.
This option tells the driver to dither from 8 bits per component to 6 before
the flat panel truncates it. This is only supported in depth 24 on GeForce2 MX, 
nForce2, GeForce4, Quadro4, Geforce FX and Quadro FX.
Default: off.
.TP
.BI "Option \*qRotate\*q \*qCW\*q"
.TP
.BI "Option \*qRotate\*q \*qCCW\*q"
Rotate the display clockwise or counterclockwise.  This mode is unaccelerated.
Default: no rotation.

Note: The Resize and Rotate extension will be disabled if the Rotate option
is used.
.TP
.BI "Option \*qShadowFB\*q \*q" boolean \*q
Enable or disable use of the shadow framebuffer layer.  Default: off.
.SH "SEE ALSO"
XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
.SH AUTHORS
Authors include: David McKay, Jarno Paananen, Chas Inman, Dave Schmenk, 
Mark Vojkovich

--- NEW FILE: nv_const.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_const.h,v 1.6 2001/12/07 00:09:55 mvojkovi Exp $ */

#ifndef __NV_CONST_H__
#define __NV_CONST_H__

#define NV_VERSION 4000
#define NV_NAME "NV"
#define NV_DRIVER_NAME "nv"
#define NV_MAJOR_VERSION 1
#define NV_MINOR_VERSION 0
#define NV_PATCHLEVEL 1

#endif /* __NV_CONST_H__ */
          

--- NEW FILE: nv_cursor.c ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.11 2002/11/26 23:41:58 mvojkovi Exp $ */

#include "nv_include.h"

#include "cursorstr.h"

/****************************************************************************\
*                                                                            *
*                          HW Cursor Entrypoints                             *
*                                                                            *
\****************************************************************************/

#define TRANSPARENT_PIXEL   0

#define ConvertToRGB555(c) \
(((c & 0xf80000) >> 9 ) | ((c & 0xf800) >> 6 ) | ((c & 0xf8) >> 3 ) | 0x8000)

#define ConvertToRGB888(c) (c | 0xff000000)

#define BYTE_SWAP_32(c)  ((c & 0xff000000) >> 24) |  \
                         ((c & 0xff0000) >> 8) |     \
                         ((c & 0xff00) << 8) |       \
                         ((c & 0xff) << 24)


static void 
ConvertCursor1555(NVPtr pNv, CARD32 *src, CARD16 *dst)
{
    CARD32 b, m;
    int i, j;
    
    for ( i = 0; i < 32; i++ ) {
        b = *src++;
        m = *src++;
        for ( j = 0; j < 32; j++ ) {
#if X_BYTE_ORDER == X_BIG_ENDIAN
            if ( m & 0x80000000)
                *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
            else
                *dst = TRANSPARENT_PIXEL;
            b <<= 1;
            m <<= 1;
#else
            if ( m & 1 )
                *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
            else
                *dst = TRANSPARENT_PIXEL;
            b >>= 1;
            m >>= 1;
#endif
            dst++;
        }
    }
}


static void
ConvertCursor8888(NVPtr pNv, CARD32 *src, CARD32 *dst)
{
    CARD32 b, m;
    int i, j;
   
    for ( i = 0; i < 128; i++ ) {
        b = *src++;
        m = *src++;
        for ( j = 0; j < 32; j++ ) {
#if X_BYTE_ORDER == X_BIG_ENDIAN
            if ( m & 0x80000000)
                *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
            else
                *dst = TRANSPARENT_PIXEL;
            b <<= 1;
            m <<= 1;
#else
            if ( m & 1 )
                *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
            else
                *dst = TRANSPARENT_PIXEL;
            b >>= 1;
            m >>= 1;
#endif
            dst++;
        }
    }
}


static void
TransformCursor (NVPtr pNv)
{
    CARD32 *tmp;
    int i, dwords;

    /* convert to color cursor */
    if(pNv->alphaCursor) {
       dwords = 64 * 64;
       if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
       ConvertCursor8888(pNv, pNv->curImage, tmp);
    } else {
       dwords = (32 * 32) >> 1;
       if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
       ConvertCursor1555(pNv, pNv->curImage, (CARD16*)tmp);
    }

    for(i = 0; i < dwords; i++)
        pNv->CURSOR[i] = tmp[i];

    DEALLOCATE_LOCAL(tmp);
}

static void
NVLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
{
    NVPtr pNv = NVPTR(pScrn);

    /* save copy of image for color changes */
    memcpy(pNv->curImage, src, (pNv->alphaCursor) ? 1024 : 256);

    TransformCursor(pNv);
}

static void
NVSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
    NVPtr pNv = NVPTR(pScrn);

    pNv->PRAMDAC[0x0000300/4] = (x & 0xFFFF) | (y << 16);
}

static void
NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
    NVPtr pNv = NVPTR(pScrn);
    CARD32 fore, back;

    if(pNv->alphaCursor) {
        fore = ConvertToRGB888(fg);
        back = ConvertToRGB888(bg);
#if X_BYTE_ORDER == X_BIG_ENDIAN
        if((pNv->Chipset & 0x0ff0) == 0x0110) {
           fore = BYTE_SWAP_32(fore);
           back = BYTE_SWAP_32(back);
        }
#endif
    } else {
        fore = ConvertToRGB555(fg);
        back = ConvertToRGB555(bg);
#if X_BYTE_ORDER == X_BIG_ENDIAN
        if((pNv->Chipset & 0x0ff0) == 0x0110) {
           fore = ((fore & 0xff) << 8) | (fore >> 8);
           back = ((back & 0xff) << 8) | (back >> 8);
        }
#endif
   }

    if ((pNv->curFg != fore) || (pNv->curBg != back)) {
        pNv->curFg = fore;
        pNv->curBg = back;
            
        TransformCursor(pNv);
    }
}


static void 
NVShowCursor(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);
    /* Enable cursor - X-Windows mode */
    NVShowHideCursor(pNv, 1);
}

static void
NVHideCursor(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);
    /* Disable cursor */
    NVShowHideCursor(pNv, 0);
}

static Bool 
NVUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
    return TRUE;
}

#ifdef ARGB_CURSOR
static Bool 
NVUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
{
    if((pCurs->bits->width <= 64) && (pCurs->bits->height <= 64))
        return TRUE;

    return FALSE;
}

static void
NVLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
{
    NVPtr pNv = NVPTR(pScrn);
    CARD32 *image = pCurs->bits->argb;
    CARD32 *dst = (CARD32*)pNv->CURSOR;
    int x, y, w, h;

    w = pCurs->bits->width;
    h = pCurs->bits->height;

#if X_BYTE_ORDER == X_BIG_ENDIAN
    if((pNv->Chipset & 0x0ff0) == 0x0110) {
       CARD32 tmp;

       for(y = 0; y < h; y++) {
          for(x = 0; x < w; x++) {
              tmp = *image++;
              *dst++ = BYTE_SWAP_32(tmp);
          }
          for(; x < 64; x++)
              *dst++ = 0;
       }
    } else 
#endif
    {
       for(y = 0; y < h; y++) {
          for(x = 0; x < w; x++) 
              *dst++ = *image++;
          for(; x < 64; x++)
              *dst++ = 0;
       }
    }

    if(y < 64)
      memset(dst, 0, 64 * (64 - y) * 4);
}
#endif

Bool 
NVCursorInit(ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    NVPtr pNv = NVPTR(pScrn);
    xf86CursorInfoPtr infoPtr;

    infoPtr = xf86CreateCursorInfoRec();
    if(!infoPtr) return FALSE;
    
    pNv->CursorInfoRec = infoPtr;

    if(pNv->alphaCursor)
       infoPtr->MaxWidth = infoPtr->MaxHeight = 64;
    else
       infoPtr->MaxWidth = infoPtr->MaxHeight = 32;

    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
                     HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32; 
    infoPtr->SetCursorColors = NVSetCursorColors;
    infoPtr->SetCursorPosition = NVSetCursorPosition;
    infoPtr->LoadCursorImage = NVLoadCursorImage;
    infoPtr->HideCursor = NVHideCursor;
    infoPtr->ShowCursor = NVShowCursor;
    infoPtr->UseHWCursor = NVUseHWCursor;

#ifdef ARGB_CURSOR
    if(pNv->alphaCursor &&
       (((pNv->Chipset & 0x0ff0) != 0x0110) || !pNv->FPDither))
    {
       infoPtr->UseHWCursorARGB = NVUseHWCursorARGB;
       infoPtr->LoadCursorARGB = NVLoadCursorARGB;
    }
#endif

    return(xf86InitCursor(pScreen, infoPtr));
}

--- NEW FILE: nv_dac.c ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.37 2003/09/08 20:00:27 mvojkovi Exp $ */

#include "nv_include.h"

Bool
NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
    int i;
    int horizDisplay    = (mode->CrtcHDisplay/8)   - 1;
    int horizStart      = (mode->CrtcHSyncStart/8) - 1;
    int horizEnd        = (mode->CrtcHSyncEnd/8)   - 1;
    int horizTotal      = (mode->CrtcHTotal/8)     - 5;
    int horizBlankStart = (mode->CrtcHDisplay/8)   - 1;
    int horizBlankEnd   = (mode->CrtcHTotal/8)     - 1;
    int vertDisplay     =  mode->CrtcVDisplay      - 1;
    int vertStart       =  mode->CrtcVSyncStart    - 1;
    int vertEnd         =  mode->CrtcVSyncEnd      - 1;
    int vertTotal       =  mode->CrtcVTotal        - 2;
    int vertBlankStart  =  mode->CrtcVDisplay      - 1;
    int vertBlankEnd    =  mode->CrtcVTotal        - 1;
   

    NVPtr pNv = NVPTR(pScrn);
    NVRegPtr nvReg = &pNv->ModeReg;
    NVFBLayout *pLayout = &pNv->CurrentLayout;
    vgaRegPtr   pVga;

    /*
     * This will initialize all of the generic VGA registers.
     */
    if (!vgaHWInit(pScrn, mode))
        return(FALSE);

    pVga = &VGAHWPTR(pScrn)->ModeReg;

    /*
     * Set all CRTC values.
     */

    if(mode->Flags & V_INTERLACE) 
        vertTotal |= 1;

    if(pNv->FlatPanel == 1) {
       vertStart = vertTotal - 3;  
       vertEnd = vertTotal - 2;
       vertBlankStart = vertStart;
       horizStart = horizTotal - 5;
       horizEnd = horizTotal - 2;   
       horizBlankEnd = horizTotal + 4;    
    }

    pVga->CRTC[0x0]  = Set8Bits(horizTotal);
    pVga->CRTC[0x1]  = Set8Bits(horizDisplay);
    pVga->CRTC[0x2]  = Set8Bits(horizBlankStart);
    pVga->CRTC[0x3]  = SetBitField(horizBlankEnd,4:0,4:0) 
                       | SetBit(7);
    pVga->CRTC[0x4]  = Set8Bits(horizStart);
    pVga->CRTC[0x5]  = SetBitField(horizBlankEnd,5:5,7:7)
                       | SetBitField(horizEnd,4:0,4:0);
    pVga->CRTC[0x6]  = SetBitField(vertTotal,7:0,7:0);
    pVga->CRTC[0x7]  = SetBitField(vertTotal,8:8,0:0)
                       | SetBitField(vertDisplay,8:8,1:1)
                       | SetBitField(vertStart,8:8,2:2)
                       | SetBitField(vertBlankStart,8:8,3:3)
                       | SetBit(4)
                       | SetBitField(vertTotal,9:9,5:5)
                       | SetBitField(vertDisplay,9:9,6:6)
                       | SetBitField(vertStart,9:9,7:7);
    pVga->CRTC[0x9]  = SetBitField(vertBlankStart,9:9,5:5)
                       | SetBit(6)
                       | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
    pVga->CRTC[0x10] = Set8Bits(vertStart);
    pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
    pVga->CRTC[0x12] = Set8Bits(vertDisplay);
    pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
    pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
    pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);

    pVga->Attribute[0x10] = 0x01;

    if(pNv->Television)
       pVga->Attribute[0x11] = 0x00;

    nvReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
                  | SetBitField(vertBlankStart,10:10,3:3)
                  | SetBitField(vertStart,10:10,2:2)
                  | SetBitField(vertDisplay,10:10,1:1)
                  | SetBitField(vertTotal,10:10,0:0);

    nvReg->horiz  = SetBitField(horizTotal,8:8,0:0) 
                  | SetBitField(horizDisplay,8:8,1:1)
                  | SetBitField(horizBlankStart,8:8,2:2)
                  | SetBitField(horizStart,8:8,3:3);

    nvReg->extra  = SetBitField(vertTotal,11:11,0:0)
                    | SetBitField(vertDisplay,11:11,2:2)
                    | SetBitField(vertStart,11:11,4:4)
                    | SetBitField(vertBlankStart,11:11,6:6);

    if(mode->Flags & V_INTERLACE) {
       horizTotal = (horizTotal >> 1) & ~1;
       nvReg->interlace = Set8Bits(horizTotal);
       nvReg->horiz |= SetBitField(horizTotal,8:8,4:4);
    } else {
       nvReg->interlace = 0xff;  /* interlace off */
    }


    /*
     * Initialize DAC palette.
     */
    if(pLayout->bitsPerPixel != 8 )
    {
        for (i = 0; i < 256; i++)
        {
            pVga->DAC[i*3]     = i;
            pVga->DAC[(i*3)+1] = i;
            pVga->DAC[(i*3)+2] = i;
        }
    }
    
    /*
     * Calculate the extended registers.
     */

    if(pLayout->depth < 24) 
	i = pLayout->depth;
    else i = 32;

    if(pNv->Architecture >= NV_ARCH_10)
	pNv->CURSOR = (U032 *)(pNv->FbStart + pNv->CursorStart);

    NVCalcStateExt(pNv, 
                    nvReg,
                    i,
                    pLayout->displayWidth,
                    mode->CrtcHDisplay,
                    pScrn->virtualY,
                    mode->Clock,
                    mode->Flags);

    nvReg->scale = pNv->PRAMDAC[0x00000848/4] & 0xfff000ff;
    if(pNv->FlatPanel == 1) {
       nvReg->pixel |= (1 << 7);
       if(!pNv->fpScaler || (pNv->fpWidth <= mode->HDisplay)
                         || (pNv->fpHeight <= mode->VDisplay))
       {
           nvReg->scale |= (1 << 8) ;
       }
    }

    nvReg->vpll = nvReg->pll;
    nvReg->vpll2 = nvReg->pll;
    nvReg->vpllB = nvReg->pllB;
    nvReg->vpll2B = nvReg->pllB;

    if(pNv->CRTCnumber) {
       nvReg->head  = pNv->PCRTC0[0x00000860/4] & ~0x00001000;
       nvReg->head2 = pNv->PCRTC0[0x00002860/4] | 0x00001000;
       nvReg->crtcOwner = 3;
       nvReg->pllsel |= 0x20000800;
       nvReg->vpll = pNv->PRAMDAC0[0x0508/4];
       if(pNv->twoStagePLL) 
          nvReg->vpllB = pNv->PRAMDAC0[0x0578/4];
    } else 
    if(pNv->twoHeads) {
       nvReg->head  =  pNv->PCRTC0[0x00000860/4] | 0x00001000;
       nvReg->head2 =  pNv->PCRTC0[0x00002860/4] & ~0x00001000;
       nvReg->crtcOwner = 0;
       nvReg->vpll2 = pNv->PRAMDAC0[0x0520/4];
       if(pNv->twoStagePLL) 
          nvReg->vpll2B = pNv->PRAMDAC0[0x057C/4];
    }

    nvReg->cursorConfig = 0x00000100;
    if(mode->Flags & V_DBLSCAN)
       nvReg->cursorConfig |= (1 << 4);
    if(pNv->alphaCursor) {
        nvReg->cursorConfig |= 0x04011000;
        nvReg->general |= (1 << 29);

        if((pNv->Chipset & 0x0ff0) == 0x0110) {
            nvReg->dither = pNv->PRAMDAC[0x0528/4] & ~0x00010000;
            if(pNv->FPDither)
               nvReg->dither |= 0x00010000;
            else
               nvReg->cursorConfig |= (1 << 28);
        } else 
        if((pNv->Chipset & 0x0ff0) >= 0x0170) {
           nvReg->dither = pNv->PRAMDAC[0x083C/4] & ~1;
           nvReg->cursorConfig |= (1 << 28);
           if(pNv->FPDither)
              nvReg->dither |= 1;
        } else {
           nvReg->cursorConfig |= (1 << 28);
        }
    } else
       nvReg->cursorConfig |= 0x02000000;

    nvReg->timingH = 0;
    nvReg->timingV = 0;

    return (TRUE);
}

void 
NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
             Bool primary)
{
    NVPtr pNv = NVPTR(pScrn);
    int restore = VGA_SR_MODE;

    if(primary) restore |= VGA_SR_CMAP | VGA_SR_FONTS;
    else if((pNv->Chipset & 0xffff) == 0x0018) 
	restore |= VGA_SR_CMAP;
    NVLoadStateExt(pNv, nvReg);
#if defined(__powerpc__)
    restore &= ~VGA_SR_FONTS;
#endif
    vgaHWRestore(pScrn, vgaReg, restore);
}

/*
 * NVDACSave
 *
 * This function saves the video state.
 */
void
NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
          Bool saveFonts)
{
    NVPtr pNv = NVPTR(pScrn);

#if defined(__powerpc__)
    saveFonts = FALSE;
#endif

    NVLockUnlock(pNv, 0);

    vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE | 
                             (saveFonts? VGA_SR_FONTS : 0));
    NVUnloadStateExt(pNv, nvReg);

    /* can't read this reliably on NV11 */
    if((pNv->Chipset & 0x0ff0) == 0x0110) 
       nvReg->crtcOwner = ((pNv->Chipset & 0x0fff) == 0x0112) ? 3 : 0;
}

#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)

void
NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
                 VisualPtr pVisual )
{
    int i, index;
    NVPtr pNv = NVPTR(pScrn);
    vgaRegPtr   pVga;

    pVga = &VGAHWPTR(pScrn)->ModeReg;

    switch(pNv->CurrentLayout.depth) {
    case 15:
        for(i = 0; i < numColors; i++) {
            index = indices[i];
            pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
            pVga->DAC[MAKE_INDEX(index, 5) + 1] = colors[index].green;
            pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
        }
        break;
    case 16:
        for(i = 0; i < numColors; i++) {
            index = indices[i];
            pVga->DAC[MAKE_INDEX(index, 6) + 1] = colors[index].green;
	    if(index < 32) {
            	pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
            	pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
	    }
        }
        break;
    default:
	for(i = 0; i < numColors; i++) {
            index = indices[i];
            pVga->DAC[index*3]     = colors[index].red;
            pVga->DAC[(index*3)+1] = colors[index].green;
            pVga->DAC[(index*3)+2] = colors[index].blue;
	}
	break;
    }
    vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
}

/*
 * DDC1 support only requires DDC_SDA_MASK,
 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
 */
#define DDC_SDA_READ_MASK  (1 << 3)
#define DDC_SCL_READ_MASK  (1 << 2)
#define DDC_SDA_WRITE_MASK (1 << 4)
#define DDC_SCL_WRITE_MASK (1 << 5)

static void
NV_I2CGetBits(I2CBusPtr b, int *clock, int *data)
{
    NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
    unsigned char val;

    /* Get the result. */
    VGA_WR08(pNv->PCIO, 0x3d4, pNv->DDCBase);
    val = VGA_RD08(pNv->PCIO, 0x3d5);

    *clock = (val & DDC_SCL_READ_MASK) != 0;
    *data  = (val & DDC_SDA_READ_MASK) != 0;
}

static void
NV_I2CPutBits(I2CBusPtr b, int clock, int data)
{
    NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
    unsigned char val;

    VGA_WR08(pNv->PCIO, 0x3d4, pNv->DDCBase + 1);
    val = VGA_RD08(pNv->PCIO, 0x3d5) & 0xf0;
    if (clock)
        val |= DDC_SCL_WRITE_MASK;
    else
        val &= ~DDC_SCL_WRITE_MASK;

    if (data)
        val |= DDC_SDA_WRITE_MASK;
    else
        val &= ~DDC_SDA_WRITE_MASK;

    VGA_WR08(pNv->PCIO, 0x3d4, pNv->DDCBase + 1);
    VGA_WR08(pNv->PCIO, 0x3d5, val | 0x1);
}

Bool
NVDACi2cInit(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);
    I2CBusPtr I2CPtr;

    I2CPtr = xf86CreateI2CBusRec();
    if(!I2CPtr) return FALSE;

    pNv->I2C = I2CPtr;

    I2CPtr->BusName    = "DDC";
    I2CPtr->scrnIndex  = pScrn->scrnIndex;
    I2CPtr->I2CPutBits = NV_I2CPutBits;
    I2CPtr->I2CGetBits = NV_I2CGetBits;
    I2CPtr->AcknTimeout = 5;

    if (!xf86I2CBusInit(I2CPtr)) {
        return FALSE;
    }
    return TRUE;
}


--- NEW FILE: nv_dga.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c,v 1.11 2002/01/25 21:56:06 tsi Exp $ */

#include "nv_local.h"
#include "nv_include.h"
#include "nv_type.h"
#include "nv_proto.h"
#include "xaalocal.h"
#include "dgaproc.h"


static Bool NV_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 
					int *, int *, int *);
static Bool NV_SetMode(ScrnInfoPtr, DGAModePtr);
static int  NV_GetViewport(ScrnInfoPtr);
static void NV_SetViewport(ScrnInfoPtr, int, int, int);
static void NV_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
static void NV_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
static void NV_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 
					unsigned long);

static
DGAFunctionRec NV_DGAFuncs = {
   NV_OpenFramebuffer,
   NULL,
   NV_SetMode,
   NV_SetViewport,
   NV_GetViewport,
   NVSync,
   NV_FillRect,
   NV_BlitRect,
   NV_BlitTransRect
};



static DGAModePtr
NVSetupDGAMode(
   ScrnInfoPtr pScrn,
   DGAModePtr modes,
   int *num,
   int bitsPerPixel,
   int depth,
   Bool pixmap,
   int secondPitch,
   unsigned long red,
   unsigned long green,
   unsigned long blue,
   short visualClass
){
   DisplayModePtr firstMode, pMode;
   NVPtr pNv = NVPTR(pScrn);
   DGAModePtr mode, newmodes;
   int size, pitch, Bpp = bitsPerPixel >> 3;

SECOND_PASS:

   pMode = firstMode = pScrn->modes;

   while(1) {

	pitch = (pMode->HDisplay + 31) & ~31;
	size = pitch * Bpp * pMode->VDisplay;

	if((!secondPitch || (pitch != secondPitch)) &&
		(size <= pNv->ScratchBufferStart)) {

	    if(secondPitch)
		pitch = secondPitch; 

	    if(!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
		break;

	    modes = newmodes;
	    mode = modes + *num;

	    mode->mode = pMode;
	    mode->flags = DGA_CONCURRENT_ACCESS;

	    if(pixmap)
		mode->flags |= DGA_PIXMAP_AVAILABLE;
	    if(!pNv->NoAccel)
		mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
	    if(pMode->Flags & V_DBLSCAN)
		mode->flags |= DGA_DOUBLESCAN;
	    if(pMode->Flags & V_INTERLACE)
		mode->flags |= DGA_INTERLACED;
	    mode->byteOrder = pScrn->imageByteOrder;
	    mode->depth = depth;
	    mode->bitsPerPixel = bitsPerPixel;
	    mode->red_mask = red;
	    mode->green_mask = green;
	    mode->blue_mask = blue;
	    mode->visualClass = visualClass;
	    mode->viewportWidth = pMode->HDisplay;
	    mode->viewportHeight = pMode->VDisplay;
	    mode->xViewportStep = 4 / Bpp;
	    mode->yViewportStep = 1;
	    mode->viewportFlags = DGA_FLIP_RETRACE;
	    mode->offset = 0;
	    mode->address = pNv->FbStart;
	    mode->bytesPerScanline = pitch * Bpp;
	    mode->imageWidth = pitch;
	    mode->imageHeight =  pNv->ScratchBufferStart / 
                                 mode->bytesPerScanline; 
	    mode->pixmapWidth = mode->imageWidth;
	    mode->pixmapHeight = mode->imageHeight;
	    mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
	    mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
	    (*num)++;
	}

	pMode = pMode->next;
	if(pMode == firstMode)
	   break;
    }

    if(secondPitch) {
	secondPitch = 0;
	goto SECOND_PASS;
    }

    return modes;
}


Bool
NVDGAInit(ScreenPtr pScreen)
{   
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
   NVPtr pNv = NVPTR(pScrn);
   DGAModePtr modes = NULL;
   int num = 0;

   /* 8 */
   modes = NVSetupDGAMode (pScrn, modes, &num, 8, 8, 
		(pScrn->bitsPerPixel == 8),
		(pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
		0, 0, 0, PseudoColor);

   /* 15 */
   modes = NVSetupDGAMode (pScrn, modes, &num, 16, 15, 
		(pScrn->bitsPerPixel == 16),
		(pScrn->depth != 15) ? 0 : pScrn->displayWidth,
		0x7c00, 0x03e0, 0x001f, TrueColor);

   /* 16 */
   modes = NVSetupDGAMode (pScrn, modes, &num, 16, 16, 
		(pScrn->bitsPerPixel == 16),
		(pScrn->depth != 16) ? 0 : pScrn->displayWidth,
		0xf800, 0x07e0, 0x001f, TrueColor);

   /* 32 */
   modes = NVSetupDGAMode (pScrn, modes, &num, 32, 24, 
		(pScrn->bitsPerPixel == 32),
		(pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
		0xff0000, 0x00ff00, 0x0000ff, TrueColor);

   pNv->numDGAModes = num;
   pNv->DGAModes = modes;

   return DGAInit(pScreen, &NV_DGAFuncs, modes, num);  
}


static int 
BitsSet(unsigned long data)
{
   unsigned long mask;
   int set = 0;

   for(mask = 1; mask; mask <<= 1)
        if(mask & data) set++;   

   return set;
}

static Bool
NV_SetMode(
   ScrnInfoPtr pScrn,
   DGAModePtr pMode
){
   static NVFBLayout SavedLayouts[MAXSCREENS];
   int index = pScrn->pScreen->myNum;

   NVPtr pNv = NVPTR(pScrn);

   if(!pMode) { /* restore the original mode */
      if(pNv->DGAactive)
        memcpy(&pNv->CurrentLayout, &SavedLayouts[index], sizeof(NVFBLayout));
                
      pScrn->currentMode = pNv->CurrentLayout.mode;
      NVSwitchMode(index, pScrn->currentMode, 0);
      NVAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
      pNv->DGAactive = FALSE;
   } else {
      if(!pNv->DGAactive) {  /* save the old parameters */
	memcpy(&SavedLayouts[index], &pNv->CurrentLayout, sizeof(NVFBLayout));
	pNv->DGAactive = TRUE;
      }

      /* update CurrentLayout */
      pNv->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
      pNv->CurrentLayout.depth = pMode->depth;
      pNv->CurrentLayout.displayWidth = pMode->bytesPerScanline / 
                              (pMode->bitsPerPixel >> 3);
      pNv->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
      pNv->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
      pNv->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
      /* NVModeInit() will set the mode field */
      NVSwitchMode(index, pMode->mode, 0);
   }
   
   return TRUE;
}



static int  
NV_GetViewport(
  ScrnInfoPtr pScrn
){
    NVPtr pNv = NVPTR(pScrn);

    return pNv->DGAViewportStatus;
}

static void 
NV_SetViewport(
   ScrnInfoPtr pScrn, 
   int x, int y, 
   int flags
){
   NVPtr pNv = NVPTR(pScrn);

   NVAdjustFrame(pScrn->pScreen->myNum, x, y, flags);

   while(VGA_RD08(pNv->PCIO, 0x3da) & 0x08);
   while(!(VGA_RD08(pNv->PCIO, 0x3da) & 0x08));

   pNv->DGAViewportStatus = 0;  
}

static void 
NV_FillRect (
   ScrnInfoPtr pScrn, 
   int x, int y, int w, int h, 
   unsigned long color
){
    NVPtr pNv = NVPTR(pScrn);

    if(!pNv->AccelInfoRec) return;

    (*pNv->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
    (*pNv->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);

    SET_SYNC_FLAG(pNv->AccelInfoRec);
}

static void 
NV_BlitRect(
   ScrnInfoPtr pScrn, 
   int srcx, int srcy, 
   int w, int h, 
   int dstx, int dsty
){
    NVPtr pNv = NVPTR(pScrn);
    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
    int ydir = (srcy < dsty) ? -1 : 1;

    if(!pNv->AccelInfoRec) return;

    (*pNv->AccelInfoRec->SetupForScreenToScreenCopy)(
		pScrn, xdir, ydir, GXcopy, ~0, -1);

    (*pNv->AccelInfoRec->SubsequentScreenToScreenCopy)(
		pScrn, srcx, srcy, dstx, dsty, w, h);

    SET_SYNC_FLAG(pNv->AccelInfoRec);
}


static void 
NV_BlitTransRect(
   ScrnInfoPtr pScrn, 
   int srcx, int srcy, 
   int w, int h, 
   int dstx, int dsty,
   unsigned long color
){
   /* not implemented */
}


static Bool 
NV_OpenFramebuffer(
   ScrnInfoPtr pScrn, 
   char **name,
   unsigned char **mem,
   int *size,
   int *offset,
   int *flags
){
    NVPtr pNv = NVPTR(pScrn);

    *name = NULL; 		/* no special device */
    *mem = (unsigned char*)pNv->FbAddress;
    *size = pNv->FbMapSize;
    *offset = 0;
    *flags = DGA_NEED_ROOT;

    return TRUE;
}

--- NEW FILE: nv_dma.h ---

 /***************************************************************************\
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dma.h,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */

#define SURFACE_FORMAT                                              0x00000300
#define SURFACE_FORMAT_DEPTH8                                       0x00000001
#define SURFACE_FORMAT_DEPTH15                                      0x00000002
#define SURFACE_FORMAT_DEPTH16                                      0x00000004
#define SURFACE_FORMAT_DEPTH24                                      0x00000006
#define SURFACE_PITCH                                               0x00000304
#define SURFACE_PITCH_SRC                                           15:0
#define SURFACE_PITCH_DST                                           31:16
#define SURFACE_OFFSET_SRC                                          0x00000308
#define SURFACE_OFFSET_DST                                          0x0000030C

#define ROP_SET                                                     0x00002300

#define PATTERN_FORMAT                                              0x00004300
#define PATTERN_FORMAT_DEPTH8                                       0x00000003
#define PATTERN_FORMAT_DEPTH16                                      0x00000001
#define PATTERN_FORMAT_DEPTH24                                      0x00000003
#define PATTERN_COLOR_0                                             0x00004310
#define PATTERN_COLOR_1                                             0x00004314
#define PATTERN_PATTERN_0                                           0x00004318
#define PATTERN_PATTERN_1                                           0x0000431C

#define CLIP_POINT                                                  0x00006300
#define CLIP_POINT_X                                                15:0
#define CLIP_POINT_Y                                                31:16
#define CLIP_SIZE                                                   0x00006304
#define CLIP_SIZE_WIDTH                                             15:0
#define CLIP_SIZE_HEIGHT                                            31:16

#define LINE_FORMAT                                                 0x00008300
#define LINE_FORMAT_DEPTH8                                          0x00000003
#define LINE_FORMAT_DEPTH16                                         0x00000001
#define LINE_FORMAT_DEPTH24                                         0x00000003
#define LINE_COLOR                                                  0x00008304
#define LINE_MAX_LINES                                              16
#define LINE_LINES(i)                                               0x00008400\
                                                                    +(i)*8
#define LINE_LINES_POINT0_X                                         15:0
#define LINE_LINES_POINT0_Y                                         31:16 
#define LINE_LINES_POINT1_X                                         47:32
#define LINE_LINES_POINT1_Y                                         63:48

#define BLIT_POINT_SRC                                              0x0000A300
#define BLIT_POINT_SRC_X                                            15:0
#define BLIT_POINT_SRC_Y                                            31:16
#define BLIT_POINT_DST                                              0x0000A304
#define BLIT_POINT_DST_X                                            15:0
#define BLIT_POINT_DST_Y                                            31:16
#define BLIT_SIZE                                                   0x0000A308
#define BLIT_SIZE_WIDTH                                             15:0
#define BLIT_SIZE_HEIGHT                                            31:16

#define RECT_FORMAT                                                 0x0000C300
#define RECT_FORMAT_DEPTH8                                          0x00000003
#define RECT_FORMAT_DEPTH16                                         0x00000001
#define RECT_FORMAT_DEPTH24                                         0x00000003
#define RECT_SOLID_COLOR                                            0x0000C3FC
#define RECT_SOLID_RECTS_MAX_RECTS                                  32
#define RECT_SOLID_RECTS(i)                                         0x0000C400\
                                                                    +(i)*8
#define RECT_SOLID_RECTS_Y                                          15:0
#define RECT_SOLID_RECTS_X                                          31:16
#define RECT_SOLID_RECTS_HEIGHT                                     47:32
#define RECT_SOLID_RECTS_WIDTH                                      63:48

#define RECT_EXPAND_ONE_COLOR_CLIP                                  0x0000C7EC
#define RECT_EXPAND_ONE_COLOR_CLIP_POINT0_X                         15:0
#define RECT_EXPAND_ONE_COLOR_CLIP_POINT0_Y                         31:16
#define RECT_EXPAND_ONE_COLOR_CLIP_POINT1_X                         47:32
#define RECT_EXPAND_ONE_COLOR_CLIP_POINT1_Y                         63:48
#define RECT_EXPAND_ONE_COLOR_COLOR                                 0x0000C7F4
#define RECT_EXPAND_ONE_COLOR_SIZE                                  0x0000C7F8
#define RECT_EXPAND_ONE_COLOR_SIZE_WIDTH                            15:0
#define RECT_EXPAND_ONE_COLOR_SIZE_HEIGHT                           31:16
#define RECT_EXPAND_ONE_COLOR_POINT                                 0x0000C7FC
#define RECT_EXPAND_ONE_COLOR_POINT_X                               15:0
#define RECT_EXPAND_ONE_COLOR_POINT_Y                               31:16
#define RECT_EXPAND_ONE_COLOR_DATA_MAX_DWORDS                       128
#define RECT_EXPAND_ONE_COLOR_DATA(i)                               0x0000C800\
                                                                    +(i)*4

#define RECT_EXPAND_TWO_COLOR_CLIP                                  0x0000CBE4
#define RECT_EXPAND_TWO_COLOR_CLIP_POINT0_X                         15:0
#define RECT_EXPAND_TWO_COLOR_CLIP_POINT0_Y                         31:16
#define RECT_EXPAND_TWO_COLOR_CLIP_POINT1_X                         47:32
#define RECT_EXPAND_TWO_COLOR_CLIP_POINT1_Y                         63:48
#define RECT_EXPAND_TWO_COLOR_COLOR_0                               0x0000CBEC
#define RECT_EXPAND_TWO_COLOR_COLOR_1                               0x0000CBF0
#define RECT_EXPAND_TWO_COLOR_SIZE_IN                               0x0000CBF4
#define RECT_EXPAND_TWO_COLOR_SIZE_IN_WIDTH                         15:0
#define RECT_EXPAND_TWO_COLOR_SIZE_IN_HEIGHT                        31:16
#define RECT_EXPAND_TWO_COLOR_SIZE_OUT                              0x0000CBF8
#define RECT_EXPAND_TWO_COLOR_SIZE_OUT_WIDTH                        15:0
#define RECT_EXPAND_TWO_COLOR_SIZE_OUT_HEIGHT                       31:16
#define RECT_EXPAND_TWO_COLOR_POINT                                 0x0000CBFC
#define RECT_EXPAND_TWO_COLOR_POINT_X                               15:0
#define RECT_EXPAND_TWO_COLOR_POINT_Y                               31:16
#define RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS                       128
#define RECT_EXPAND_TWO_COLOR_DATA(i)                               0x0000CC00\
                                                                    +(i)*4

#define STRETCH_BLIT_FORMAT                                         0x0000E300
#define STRETCH_BLIT_FORMAT_DEPTH8                                  0x00000004
#define STRETCH_BLIT_FORMAT_DEPTH16                                 0x00000007
#define STRETCH_BLIT_FORMAT_DEPTH24                                 0x00000004
#define STRETCH_BLIT_FORMAT_X8R8G8B8                                0x00000004
#define STRETCH_BLIT_FORMAT_YUYV                                    0x00000005
#define STRETCH_BLIT_FORMAT_UYVY                                    0x00000006
#define STRETCH_BLIT_CLIP_POINT                                     0x0000E308
#define STRETCH_BLIT_CLIP_POINT_X                                   15:0 
#define STRETCH_BLIT_CLIP_POINT_Y                                   31:16
#define STRETCH_BLIT_CLIP_POINT                                     0x0000E308
#define STRETCH_BLIT_CLIP_SIZE                                      0x0000E30C
#define STRETCH_BLIT_CLIP_SIZE_WIDTH                                15:0
#define STRETCH_BLIT_CLIP_SIZE_HEIGHT                               31:16
#define STRETCH_BLIT_DST_POINT                                      0x0000E310
#define STRETCH_BLIT_DST_POINT_X                                    15:0
#define STRETCH_BLIT_DST_POINT_Y                                    31:16
#define STRETCH_BLIT_DST_SIZE                                       0x0000E314
#define STRETCH_BLIT_DST_SIZE_WIDTH                                 15:0
#define STRETCH_BLIT_DST_SIZE_HEIGHT                                31:16
#define STRETCH_BLIT_DU_DX                                          0x0000E318
#define STRETCH_BLIT_DV_DY                                          0x0000E31C
#define STRETCH_BLIT_SRC_SIZE                                       0x0000E400
#define STRETCH_BLIT_SRC_SIZE_WIDTH                                 15:0
#define STRETCH_BLIT_SRC_SIZE_HEIGHT                                31:16
#define STRETCH_BLIT_SRC_FORMAT                                     0x0000E404
#define STRETCH_BLIT_SRC_FORMAT_PITCH                               15:0
#define STRETCH_BLIT_SRC_FORMAT_ORIGIN                              23:16
#define STRETCH_BLIT_SRC_FORMAT_ORIGIN_CENTER                       0x00000001
#define STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER                       0x00000002
#define STRETCH_BLIT_SRC_FORMAT_FILTER                              31:24
#define STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE                 0x00000000
#define STRETCH_BLIT_SRC_FORMAT_FILTER_BILINEAR                     0x00000001
#define STRETCH_BLIT_SRC_OFFSET                                     0x0000E408
#define STRETCH_BLIT_SRC_POINT                                      0x0000E40C
#define STRETCH_BLIT_SRC_POINT_U                                    15:0
#define STRETCH_BLIT_SRC_POINT_V                                    31:16

--- NEW FILE: nv_driver.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.1.4.4 2004/03/05 13:40:29 eich Exp $ */
/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
/*
 * Copyright 1996-1997  David J. McKay
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
[...1796 lines suppressed...]
    return TRUE;
}

static Bool
NVSaveScreen(ScreenPtr pScreen, int mode)
{
    return vgaHWSaveScreen(pScreen, mode);
}

static void
NVSave(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);
    NVRegPtr nvReg = &pNv->SavedReg;
    vgaHWPtr pVga = VGAHWPTR(pScrn);
    vgaRegPtr vgaReg = &pVga->SavedReg;

    NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);
}


--- NEW FILE: nv_hw.c ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
[...1225 lines suppressed...]
        }

        if(pNv->FlatPanel) {
           VGA_WR08(pNv->PCIO, 0x03D4, 0x53);
           state->timingH = VGA_RD08(pNv->PCIO, 0x03D5);
           VGA_WR08(pNv->PCIO, 0x03D4, 0x54);
           state->timingV = VGA_RD08(pNv->PCIO, 0x03D5);
        }
    }
}

void NVSetStartAddress (
    NVPtr   pNv,
    CARD32 start
)
{
    pNv->PCRTC[0x800/4] = start;
}



--- NEW FILE: nv_include.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h,v 1.9 2000/10/06 12:31:03 eich Exp $ */

#ifndef __NV_INCLUDE_H__
#define __NV_INCLUDE_H__

/* All drivers should typically include these */
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "xf86_ansic.h"
#include "compiler.h"

/* Drivers for PCI hardware need this */
#include "xf86PciInfo.h"

/* Drivers that need to access the PCI config space directly need this */
#include "xf86Pci.h"

/* All drivers initialising the SW cursor need this */
#include "mipointer.h"

/* All drivers implementing backing store need this */
#include "mibstore.h"

#include "micmap.h"

#include "xf86DDC.h"

#include "vbe.h"

#include "xf86RAC.h"

#include "nv_const.h"

#include "dixstruct.h"
#include "scrnintstr.h"

#include "fb.h"

#include "xaa.h"
#include "xf86cmap.h"
#include "shadowfb.h"
#include "fbdevhw.h"

#include "xf86xv.h"
#include "X11/extensions/Xv.h"

#include "vgaHW.h"

#include "xf86Cursor.h"
#include "xf86DDC.h"

#include "region.h"

#include "nv_local.h"
#include "nv_type.h"
#include "nv_proto.h"

#endif /* __NV_INCLUDE_H__ */

--- NEW FILE: nv_local.h ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h,v 1.8tsi Exp $ */

#ifndef __NV_LOCAL_H__
#define __NV_LOCAL_H__

/*
 * This file includes any environment or machine specific values to access the
 * HW.  Put all affected includes, typdefs, etc. here so the riva_hw.* files
 * can stay generic in nature.
 */ 
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86_OSproc.h"

/*
 * Typedefs to force certain sized values.
 */
typedef unsigned char  U008;
typedef unsigned short U016;
typedef unsigned int   U032;

/*
 * HW access macros.  These assume memory-mapped I/O, and not normal I/O space.
 */
#define NV_WR08(p,i,d)  MMIO_OUT8((pointer)(p), (i), (d))
#define NV_RD08(p,i)    MMIO_IN8((pointer)(p), (i))
#define NV_WR16(p,i,d)  MMIO_OUT16((pointer)(p), (i), (d))
#define NV_RD16(p,i)    MMIO_IN16((pointer)(p), (i))
#define NV_WR32(p,i,d)  MMIO_OUT32((pointer)(p), (i), (d))
#define NV_RD32(p,i)    MMIO_IN32((pointer)(p), (i))

/* VGA I/O is now always done through MMIO */
#define VGA_WR08(p,i,d) NV_WR08(p,i,d)
#define VGA_RD08(p,i)   NV_RD08(p,i)

#define NVDmaNext(pNv, data) \
     (pNv)->dmaBase[(pNv)->dmaCurrent++] = (data)

#define NVDmaStart(pNv, tag, size) {          \
     if((pNv)->dmaFree <= (size))             \
        NVDmaWait(pNv, size);                 \
     NVDmaNext(pNv, ((size) << 18) | (tag));  \
     (pNv)->dmaFree -= ((size) + 1);          \
}

#if defined(__i386__)
#define _NV_FENCE() outb(0x3D0, 0);
#else
#define _NV_FENCE() mem_barrier();
#endif

#define WRITE_PUT(pNv, data) {       \
  volatile CARD8 scratch;            \
  _NV_FENCE()                        \
  scratch = (pNv)->FbStart[0];       \
  (pNv)->FIFO[0x0010] = (data) << 2; \
  mem_barrier();                     \
}

#define READ_GET(pNv) ((pNv)->FIFO[0x0011] >> 2)


#endif /* __NV_LOCAL_H__ */

--- NEW FILE: nv_proto.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h,v 1.9 2003/05/04 01:20:52 mvojkovi Exp $ */

#ifndef __NV_PROTO_H__
#define __NV_PROTO_H__

/* in nv_driver.c */
Bool   NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
void   NVAdjustFrame(int scrnIndex, int x, int y, int flags);
Bool   NVI2CInit(ScrnInfoPtr pScrn);


/* in nv_dac.c */
Bool   NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
void   NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
                 NVRegPtr nvReg, Bool saveFonts);
void   NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
                    NVRegPtr nvReg, Bool restoreFonts);
void   NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
                        LOCO *colors, VisualPtr pVisual );
Bool   NVDACi2cInit(ScrnInfoPtr pScrn);


/* in nv_video.c */
void NVInitVideo(ScreenPtr);
void NVResetVideo (ScrnInfoPtr pScrnInfo);

/* in nv_setup.c */
void   RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter);
void   NVCommonSetup(ScrnInfoPtr pScrn);

/* in nv_cursor.c */
Bool   NVCursorInit(ScreenPtr pScreen);

/* in nv_xaa.c */
Bool   NVAccelInit(ScreenPtr pScreen);
void   NVSync(ScrnInfoPtr pScrn);
void   NVResetGraphics(ScrnInfoPtr pScrn);
void   NVDmaKickoff(NVPtr pNv);
void   NVDmaWait(NVPtr pNv, int size);

/* in nv_dga.c */
Bool   NVDGAInit(ScreenPtr pScreen);

/* in riva_hw.c */
void NVCalcStateExt(NVPtr,struct _riva_hw_state *,int,int,int,int,int,int);
void NVLoadStateExt(NVPtr,struct _riva_hw_state *);
void NVUnloadStateExt(NVPtr,struct _riva_hw_state *);
void NVSetStartAddress(NVPtr,CARD32);
int  NVShowHideCursor(NVPtr,int);
void NVLockUnlock(NVPtr,int);

/* in nv_shadow.c */
void NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void NVRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void NVRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void NVRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void NVPointerMoved(int index, int x, int y);

#endif /* __NV_PROTO_H__ */


--- NEW FILE: nv_setup.c ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.39 2003/11/07 23:56:28 mvojkovi Exp $ */

#include "nv_include.h"

/*
 * Override VGA I/O routines.
 */
static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
    VGA_WR08(pNv->PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET,  value);
}
static CARD8 NVReadCrtc(vgaHWPtr pVga, CARD8 index)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
    return (VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
}
static void NVWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index);
    VGA_WR08(pNv->PVIO, VGA_GRAPH_DATA,  value);
}
static CARD8 NVReadGr(vgaHWPtr pVga, CARD8 index)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index);
    return (VGA_RD08(pNv->PVIO, VGA_GRAPH_DATA));
}
static void NVWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
    VGA_WR08(pNv->PVIO, VGA_SEQ_DATA,  value);
}
static CARD8 NVReadSeq(vgaHWPtr pVga, CARD8 index)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
    return (VGA_RD08(pNv->PVIO, VGA_SEQ_DATA));
}
static void NVWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    if (pVga->paletteEnabled)
        index &= ~0x20;
    else
        index |= 0x20;
    VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX,  index);
    VGA_WR08(pNv->PCIO, VGA_ATTR_DATA_W, value);
}
static CARD8 NVReadAttr(vgaHWPtr pVga, CARD8 index)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    if (pVga->paletteEnabled)
        index &= ~0x20;
    else
        index |= 0x20;
    VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX, index);
    return (VGA_RD08(pNv->PCIO, VGA_ATTR_DATA_R));
}
static void NVWriteMiscOut(vgaHWPtr pVga, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PVIO, VGA_MISC_OUT_W, value);
}
static CARD8 NVReadMiscOut(vgaHWPtr pVga)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    return (VGA_RD08(pNv->PVIO, VGA_MISC_OUT_R));
}
static void NVEnablePalette(vgaHWPtr pVga)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX, 0x00);
    pVga->paletteEnabled = TRUE;
}
static void NVDisablePalette(vgaHWPtr pVga)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX, 0x20);
    pVga->paletteEnabled = FALSE;
}
static void NVWriteDacMask(vgaHWPtr pVga, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PDIO, VGA_DAC_MASK, value);
}
static CARD8 NVReadDacMask(vgaHWPtr pVga)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    return (VGA_RD08(pNv->PDIO, VGA_DAC_MASK));
}
static void NVWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PDIO, VGA_DAC_READ_ADDR, value);
}
static void NVWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PDIO, VGA_DAC_WRITE_ADDR, value);
}
static void NVWriteDacData(vgaHWPtr pVga, CARD8 value)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    VGA_WR08(pNv->PDIO, VGA_DAC_DATA, value);
}
static CARD8 NVReadDacData(vgaHWPtr pVga)
{
    NVPtr pNv = (NVPtr)pVga->MMIOBase;
    return (VGA_RD08(pNv->PDIO, VGA_DAC_DATA));
}

static Bool 
NVIsConnected (ScrnInfoPtr pScrn, int output)
{
    NVPtr pNv = NVPTR(pScrn);
    volatile U032 *PRAMDAC = pNv->PRAMDAC0;
    CARD32 reg52C, reg608;
    Bool present;

    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
               "Probing for analog device on output %s...\n", 
                output ? "B" : "A");

    if(output) PRAMDAC += 0x800;

    reg52C = PRAMDAC[0x052C/4];
    reg608 = PRAMDAC[0x0608/4];

    PRAMDAC[0x0608/4] = reg608 & ~0x00010000;

    PRAMDAC[0x052C/4] = reg52C & 0x0000FEEE;
    usleep(1000);
    PRAMDAC[0x052C/4] |= 1;

    pNv->PRAMDAC0[0x0610/4] = 0x94050140;
    pNv->PRAMDAC0[0x0608/4] |= 0x00001000;

    usleep(1000);

    present = (PRAMDAC[0x0608/4] & (1 << 28)) ? TRUE : FALSE;

    if(present)
       xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ...found one\n");
    else
       xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ...can't find one\n");

    pNv->PRAMDAC0[0x0608/4] &= 0x0000EFFF;

    PRAMDAC[0x052C/4] = reg52C;
    PRAMDAC[0x0608/4] = reg608;

    return present;
}

static void
NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head)
{
    NVPtr pNv = NVPTR(pScrn);

    if(head) {
       pNv->PCIO = pNv->PCIO0 + 0x2000;
       pNv->PCRTC = pNv->PCRTC0 + 0x800;
       pNv->PRAMDAC = pNv->PRAMDAC0 + 0x800;
       pNv->PDIO = pNv->PDIO0 + 0x2000;
    } else {
       pNv->PCIO = pNv->PCIO0;
       pNv->PCRTC = pNv->PCRTC0;
       pNv->PRAMDAC = pNv->PRAMDAC0;
       pNv->PDIO = pNv->PDIO0;
    }
}

static xf86MonPtr 
NVProbeDDC (ScrnInfoPtr pScrn, int bus)
{
    NVPtr pNv = NVPTR(pScrn);
    xf86MonPtr MonInfo = NULL;

    if(!pNv->I2C) return NULL;

    pNv->DDCBase = bus ? 0x36 : 0x3e;

    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
               "Probing for EDID on I2C bus %s...\n", bus ? "B" : "A");

    if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pNv->I2C))) {
       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                  "DDC detected a %s:\n", MonInfo->features.input_type ?
                  "DFP" : "CRT");
       xf86PrintEDID( MonInfo );
    } else {
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
                  "  ... none found\n");
    }

    return MonInfo;
}

static void nv4GetConfig (NVPtr pNv)
{
    if (pNv->PFB[0x0000/4] & 0x00000100) {
        pNv->RamAmountKBytes = ((pNv->PFB[0x0000/4] >> 12) & 0x0F) * 1024 * 2
                              + 1024 * 2;
    } else {
        switch (pNv->PFB[0x0000/4] & 0x00000003) {
        case 0:
            pNv->RamAmountKBytes = 1024 * 32;
            break;
        case 1:
            pNv->RamAmountKBytes = 1024 * 4;
            break;
        case 2:
            pNv->RamAmountKBytes = 1024 * 8;
            break;
        case 3:
        default:
            pNv->RamAmountKBytes = 1024 * 16;
            break;
        }
    }
    pNv->CrystalFreqKHz = (pNv->PEXTDEV[0x0000/4] & 0x00000040) ? 14318 : 13500;
    pNv->CURSOR         = &(pNv->PRAMIN[0x1E00]);
    pNv->MinVClockFreqKHz = 12000;
    pNv->MaxVClockFreqKHz = 350000;
}

static void nv10GetConfig (NVPtr pNv)
{
    CARD32 implementation = pNv->Chipset & 0x0ff0;

#if X_BYTE_ORDER == X_BIG_ENDIAN
    /* turn on big endian register access */
    if(!(pNv->PMC[0x0004/4] & 0x01000001)) {
       pNv->PMC[0x0004/4] = 0x01000001;
       mem_barrier();
    }
#endif

    if((pNv->Chipset & 0xffff) == 0x01a0) {
        int amt = pciReadLong(pciTag(0, 0, 1), 0x7C);
        pNv->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
    } else if((pNv->Chipset & 0xffff) == 0x01f0) {
        int amt = pciReadLong(pciTag(0, 0, 1), 0x84);
        pNv->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
    } else {
        pNv->RamAmountKBytes = (pNv->PFB[0x020C/4] & 0xFFF00000) >> 10;
    }

    pNv->CrystalFreqKHz = (pNv->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 : 13500;
    
    if((implementation == 0x0170) ||
       (implementation == 0x0180) ||
       (implementation == 0x01F0) ||
       (implementation >= 0x0250))
    {
       if(pNv->PEXTDEV[0x0000/4] & (1 << 22))
           pNv->CrystalFreqKHz = 27000;
    }

    pNv->CursorStart      = (pNv->RamAmountKBytes - 96) * 1024;
    pNv->CURSOR           = NULL;  /* can't set this here */
    pNv->MinVClockFreqKHz = 12000;
    pNv->MaxVClockFreqKHz = pNv->twoStagePLL ? 400000 : 350000;
}


void
NVCommonSetup(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);
    vgaHWPtr pVga = VGAHWPTR(pScrn);
    CARD16 implementation = pNv->Chipset & 0x0ff0;
    xf86MonPtr monitorA, monitorB;
    Bool mobile = FALSE;
    Bool tvA = FALSE;
    Bool tvB = FALSE;
    int FlatPanel = -1;   /* really means the CRTC is slaved */
    Bool Television = FALSE;
    
    /*
     * Override VGA I/O routines.
     */
    pVga->writeCrtc         = NVWriteCrtc;
    pVga->readCrtc          = NVReadCrtc;
    pVga->writeGr           = NVWriteGr;
    pVga->readGr            = NVReadGr;
    pVga->writeAttr         = NVWriteAttr;
    pVga->readAttr          = NVReadAttr;
    pVga->writeSeq          = NVWriteSeq;
    pVga->readSeq           = NVReadSeq;
    pVga->writeMiscOut      = NVWriteMiscOut;
    pVga->readMiscOut       = NVReadMiscOut;
    pVga->enablePalette     = NVEnablePalette;
    pVga->disablePalette    = NVDisablePalette;
    pVga->writeDacMask      = NVWriteDacMask;
    pVga->readDacMask       = NVReadDacMask;
    pVga->writeDacWriteAddr = NVWriteDacWriteAddr;
    pVga->writeDacReadAddr  = NVWriteDacReadAddr;
    pVga->writeDacData      = NVWriteDacData;
    pVga->readDacData       = NVReadDacData;
    /*
     * Note: There are different pointers to the CRTC/AR and GR/SEQ registers.
     * Bastardize the intended uses of these to make it work.
     */
    pVga->MMIOBase   = (CARD8 *)pNv;
    pVga->MMIOOffset = 0;
    
    pNv->REGS = xf86MapPciMem(pScrn->scrnIndex, 
                              VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, 
                              pNv->PciTag, pNv->IOAddress, 0x01000000);

    pNv->PRAMIN   = pNv->REGS + (0x00710000/4);
    pNv->PCRTC0   = pNv->REGS + (0x00600000/4);
    pNv->PRAMDAC0 = pNv->REGS + (0x00680000/4);
    pNv->PFB      = pNv->REGS + (0x00100000/4);
    pNv->PFIFO    = pNv->REGS + (0x00002000/4);
    pNv->PGRAPH   = pNv->REGS + (0x00400000/4);
    pNv->PEXTDEV  = pNv->REGS + (0x00101000/4);
    pNv->PTIMER   = pNv->REGS + (0x00009000/4);
    pNv->PMC      = pNv->REGS + (0x00000000/4);
    pNv->FIFO     = pNv->REGS + (0x00800000/4);

    /* 8 bit registers */
    pNv->PCIO0    = (U008*)pNv->REGS + 0x00601000;
    pNv->PDIO0    = (U008*)pNv->REGS + 0x00681000;
    pNv->PVIO     = (U008*)pNv->REGS + 0x000C0000;

    pNv->twoHeads =  (implementation >= 0x0110) &&
                     (implementation != 0x0150) &&
                     (implementation != 0x01A0) &&
                     (implementation != 0x0200);

    pNv->fpScaler = (pNv->twoHeads && (implementation != 0x0110));

    pNv->twoStagePLL = (implementation == 0x0310) ||
                       (implementation == 0x0340);

    /* look for known laptop chips */
    switch(pNv->Chipset & 0xffff) {
    case 0x0112:
    case 0x0174:
    case 0x0175:
    case 0x0176:
    case 0x0177:
    case 0x0179:
    case 0x017C:
    case 0x017D:
    case 0x0186:
    case 0x0187:
    case 0x0189:
    case 0x0286:
    case 0x028C:
    case 0x0316:
    case 0x0317:
    case 0x031A:
    case 0x031B:
    case 0x031C:
    case 0x031D:
    case 0x031E:
    case 0x031F:
    case 0x0324:
    case 0x0325:
    case 0x0328:
    case 0x0329:
    case 0x032C:
    case 0x032D:
    case 0x0347:
    case 0x0348:
    case 0x0349:
    case 0x034B:
    case 0x034C:
        mobile = TRUE;
        break;
    default:
        break;
    }

    if(pNv->Architecture == NV_ARCH_04)
        nv4GetConfig(pNv);
    else
        nv10GetConfig(pNv);

    NVSelectHeadRegisters(pScrn, 0);

    NVLockUnlock(pNv, 0);

    NVI2CInit(pScrn);

    pNv->Television = FALSE;

    if(!pNv->twoHeads) {
       pNv->CRTCnumber = 0;
       if((monitorA = NVProbeDDC(pScrn, 0))) {
           FlatPanel = monitorA->features.input_type ? 1 : 0;

           /* NV4 doesn't support FlatPanels */
           if((pNv->Chipset & 0x0fff) <= 0x0020)
              FlatPanel = 0;
       } else {
           VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
           if(VGA_RD08(pNv->PCIO, 0x03D5) & 0x80) {
              VGA_WR08(pNv->PCIO, 0x03D4, 0x33);
              if(!(VGA_RD08(pNv->PCIO, 0x03D5) & 0x01)) 
                 Television = TRUE;
              FlatPanel = 1;
           } else {
              FlatPanel = 0;
           }
           xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                         "HW is currently programmed for %s\n",
                          FlatPanel ? (Television ? "TV" : "DFP") : "CRT");
       } 

       if(pNv->FlatPanel == -1) {
           pNv->FlatPanel = FlatPanel;
           pNv->Television = Television;
       } else {
           xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
                      "Forcing display type to %s as specified\n", 
                       pNv->FlatPanel ? "DFP" : "CRT");
       }
    } else {
       CARD8 outputAfromCRTC, outputBfromCRTC;
       int CRTCnumber = -1;
       CARD8 slaved_on_A, slaved_on_B;
       Bool analog_on_A, analog_on_B;
       CARD32 oldhead;
       CARD8 cr44;
      
       if(implementation != 0x0110) {
           if(pNv->PRAMDAC0[0x0000052C/4] & 0x100)
               outputAfromCRTC = 1;
           else            
               outputAfromCRTC = 0;
           if(pNv->PRAMDAC0[0x0000252C/4] & 0x100)
               outputBfromCRTC = 1;
           else
               outputBfromCRTC = 0;
          analog_on_A = NVIsConnected(pScrn, 0);
          analog_on_B = NVIsConnected(pScrn, 1);
       } else {
          outputAfromCRTC = 0;
          outputBfromCRTC = 1;
          analog_on_A = FALSE;
          analog_on_B = FALSE;
       }

       VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
       cr44 = VGA_RD08(pNv->PCIO, 0x03D5);

       VGA_WR08(pNv->PCIO, 0x03D5, 3);
       NVSelectHeadRegisters(pScrn, 1);
       NVLockUnlock(pNv, 0);

       VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
       slaved_on_B = VGA_RD08(pNv->PCIO, 0x03D5) & 0x80;
       if(slaved_on_B) {
           VGA_WR08(pNv->PCIO, 0x03D4, 0x33);
           tvB = !(VGA_RD08(pNv->PCIO, 0x03D5) & 0x01);
       }

       VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
       VGA_WR08(pNv->PCIO, 0x03D5, 0);
       NVSelectHeadRegisters(pScrn, 0);
       NVLockUnlock(pNv, 0);

       VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
       slaved_on_A = VGA_RD08(pNv->PCIO, 0x03D5) & 0x80; 
       if(slaved_on_A) {
           VGA_WR08(pNv->PCIO, 0x03D4, 0x33);
           tvA = !(VGA_RD08(pNv->PCIO, 0x03D5) & 0x01);
       }

       oldhead = pNv->PCRTC0[0x00000860/4];
       pNv->PCRTC0[0x00000860/4] = oldhead | 0x00000010;

       monitorA = NVProbeDDC(pScrn, 0);
       monitorB = NVProbeDDC(pScrn, 1);

       if(slaved_on_A && !tvA) {
          CRTCnumber = 0;
          FlatPanel = 1;
          xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                    "CRTC 0 is currently programmed for DFP\n");
       } else 
       if(slaved_on_B && !tvB) {
          CRTCnumber = 1;
          FlatPanel = 1;
          xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                    "CRTC 1 is currently programmed for DFP\n");
       } else
       if(analog_on_A) {
          CRTCnumber = outputAfromCRTC;
          FlatPanel = 0;
          xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                    "CRTC %i appears to have a CRT attached\n", CRTCnumber);
       } else
       if(analog_on_B) {
           CRTCnumber = outputBfromCRTC;
           FlatPanel = 0;
           xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                    "CRTC %i appears to have a CRT attached\n", CRTCnumber);
       } else
       if(slaved_on_A) {
          CRTCnumber = 0;
          FlatPanel = 1;
          Television = 1;
          xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                    "CRTC 0 is currently programmed for TV\n");
       } else
       if(slaved_on_B) {
          CRTCnumber = 1;
          FlatPanel = 1;
          Television = 1;
          xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                    "CRTC 1 is currently programmed for TV\n");
       } else
       if(monitorA) {
           FlatPanel = monitorA->features.input_type ? 1 : 0;
       } else 
       if(monitorB) {
           FlatPanel = monitorB->features.input_type ? 1 : 0;
       }

       if(pNv->FlatPanel == -1) {
          if(FlatPanel != -1) {
             pNv->FlatPanel = FlatPanel;
             pNv->Television = Television;
          } else {
             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                        "Unable to detect display type...\n");
             if(mobile) {
                 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
                            "...On a laptop, assuming DFP\n");
                 pNv->FlatPanel = 1;
             } else {
                 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
                            "...Using default of CRT\n");
                 pNv->FlatPanel = 0;
             }
          }
       } else {
           xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
                      "Forcing display type to %s as specified\n", 
                       pNv->FlatPanel ? "DFP" : "CRT");
       }

       if(pNv->CRTCnumber == -1) {
          if(CRTCnumber != -1) pNv->CRTCnumber = CRTCnumber;
          else {
             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                        "Unable to detect which CRTCNumber...\n");
             if(pNv->FlatPanel) pNv->CRTCnumber = 1;
             else pNv->CRTCnumber = 0;
             xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
                        "...Defaulting to CRTCNumber %i\n", pNv->CRTCnumber);
          }
       } else {
           xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
                      "Forcing CRTCNumber %i as specified\n", pNv->CRTCnumber);
       }
     
       if(monitorA) {
           if((monitorA->features.input_type && pNv->FlatPanel) ||
              (!monitorA->features.input_type && !pNv->FlatPanel))
           {
               if(monitorB) { 
                  xfree(monitorB);
                  monitorB = NULL;
               }
           } else {
              xfree(monitorA);
              monitorA = NULL;
           }
       }

       if(monitorB) {
           if((monitorB->features.input_type && !pNv->FlatPanel) ||
              (!monitorB->features.input_type && pNv->FlatPanel)) 
           {
              xfree(monitorB);
           } else {
              monitorA = monitorB;
           }
           monitorB = NULL;
       }

       if(implementation == 0x0110)
           cr44 = pNv->CRTCnumber * 0x3;

       pNv->PCRTC0[0x00000860/4] = oldhead;

       VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
       VGA_WR08(pNv->PCIO, 0x03D5, cr44);
       NVSelectHeadRegisters(pScrn, pNv->CRTCnumber);
    }

    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
              "Using %s on CRTC %i\n",
              pNv->FlatPanel ? (pNv->Television ? "TV" : "DFP") : "CRT", 
              pNv->CRTCnumber);

    if(pNv->FlatPanel && !pNv->Television) {
       pNv->fpWidth = pNv->PRAMDAC[0x0820/4] + 1;
       pNv->fpHeight = pNv->PRAMDAC[0x0800/4] + 1;
       xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
                  pNv->fpWidth, pNv->fpHeight);
    }

    if(monitorA)
      xf86SetDDCproperties(pScrn, monitorA);

    if(!pNv->FlatPanel || (pScrn->depth != 24))
        pNv->FPDither = FALSE;
}


--- NEW FILE: nv_shadow.c ---
/*
   Copyright (c) 1999,  The XFree86 Project Inc. 
   Written by Mark Vojkovich <markv at valinux.com>
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_shadow.c,v 1.5 2000/03/13 18:49:29 mvojkovi Exp $ */

#include "nv_local.h"
#include "nv_include.h"
#include "nv_type.h"
#include "shadowfb.h"
#include "servermd.h"


void
NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    NVPtr pNv = NVPTR(pScrn);
    int width, height, Bpp, FBPitch;
    unsigned char *src, *dst;
   
    Bpp = pScrn->bitsPerPixel >> 3;
    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);

    while(num--) {
	width = (pbox->x2 - pbox->x1) * Bpp;
	height = pbox->y2 - pbox->y1;
	src = pNv->ShadowPtr + (pbox->y1 * pNv->ShadowPitch) + 
						(pbox->x1 * Bpp);
	dst = pNv->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);

	while(height--) {
	    memcpy(dst, src, width);
	    dst += FBPitch;
	    src += pNv->ShadowPitch;
	}
	
	pbox++;
    }
} 

void
NVPointerMoved(int index, int x, int y)
{
    ScrnInfoPtr pScrn = xf86Screens[index];
    NVPtr pNv = NVPTR(pScrn);
    int newX, newY;

    if(pNv->Rotate == 1) {
	newX = pScrn->pScreen->height - y - 1;
	newY = x;
    } else {
	newX = y;
	newY = pScrn->pScreen->width - x - 1;
    }

    (*pNv->PointerMoved)(index, newX, newY);
}

void
NVRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    NVPtr pNv = NVPTR(pScrn);
    int count, width, height, y1, y2, dstPitch, srcPitch;
    CARD8 *dstPtr, *srcPtr, *src;
    CARD32 *dst;

    dstPitch = pScrn->displayWidth;
    srcPitch = -pNv->Rotate * pNv->ShadowPitch;

    while(num--) {
	width = pbox->x2 - pbox->x1;
	y1 = pbox->y1 & ~3;
	y2 = (pbox->y2 + 3) & ~3;
	height = (y2 - y1) >> 2;  /* in dwords */

	if(pNv->Rotate == 1) {
	    dstPtr = pNv->FbStart + 
			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
	    srcPtr = pNv->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
	} else {
	    dstPtr = pNv->FbStart + 
			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
	    srcPtr = pNv->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
	}

	while(width--) {
	    src = srcPtr;
	    dst = (CARD32*)dstPtr;
	    count = height;
	    while(count--) {
		*(dst++) = src[0] | (src[srcPitch] << 8) | 
					(src[srcPitch * 2] << 16) | 
					(src[srcPitch * 3] << 24);
		src += srcPitch * 4;
	    }
	    srcPtr += pNv->Rotate;
	    dstPtr += dstPitch;
	}

	pbox++;
    }
} 


void
NVRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    NVPtr pNv = NVPTR(pScrn);
    int count, width, height, y1, y2, dstPitch, srcPitch;
    CARD16 *dstPtr, *srcPtr, *src;
    CARD32 *dst;

    dstPitch = pScrn->displayWidth;
    srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 1;

    while(num--) {
	width = pbox->x2 - pbox->x1;
	y1 = pbox->y1 & ~1;
	y2 = (pbox->y2 + 1) & ~1;
	height = (y2 - y1) >> 1;  /* in dwords */

	if(pNv->Rotate == 1) {
	    dstPtr = (CARD16*)pNv->FbStart + 
			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
	    srcPtr = (CARD16*)pNv->ShadowPtr + 
			((1 - y2) * srcPitch) + pbox->x1;
	} else {
	    dstPtr = (CARD16*)pNv->FbStart + 
			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
	    srcPtr = (CARD16*)pNv->ShadowPtr + 
			(y1 * srcPitch) + pbox->x2 - 1;
	}

	while(width--) {
	    src = srcPtr;
	    dst = (CARD32*)dstPtr;
	    count = height;
	    while(count--) {
		*(dst++) = src[0] | (src[srcPitch] << 16);
		src += srcPitch * 2;
	    }
	    srcPtr += pNv->Rotate;
	    dstPtr += dstPitch;
	}

	pbox++;
    }
}


void
NVRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    NVPtr pNv = NVPTR(pScrn);
    int count, width, height, dstPitch, srcPitch;
    CARD32 *dstPtr, *srcPtr, *src, *dst;

    dstPitch = pScrn->displayWidth;
    srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 2;

    while(num--) {
	width = pbox->x2 - pbox->x1;
	height = pbox->y2 - pbox->y1;

	if(pNv->Rotate == 1) {
	    dstPtr = (CARD32*)pNv->FbStart + 
			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
	    srcPtr = (CARD32*)pNv->ShadowPtr + 
			((1 - pbox->y2) * srcPitch) + pbox->x1;
	} else {
	    dstPtr = (CARD32*)pNv->FbStart + 
			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
	    srcPtr = (CARD32*)pNv->ShadowPtr + 
			(pbox->y1 * srcPitch) + pbox->x2 - 1;
	}

	while(width--) {
	    src = srcPtr;
	    dst = dstPtr;
	    count = height;
	    while(count--) {
		*(dst++) = *src;
		src += srcPitch;
	    }
	    srcPtr += pNv->Rotate;
	    dstPtr += dstPitch;
	}

	pbox++;
    }
}




--- NEW FILE: nv_type.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.44 2003/09/08 20:00:27 mvojkovi Exp $ */

#ifndef __NV_STRUCT_H__
#define __NV_STRUCT_H__

#include "colormapst.h"
#include "vgaHW.h"
#include "xaa.h"
#include "xf86Cursor.h"
#include "xf86int10.h"

#define NV_ARCH_04  0x04
#define NV_ARCH_10  0x10
#define NV_ARCH_20  0x20
#define NV_ARCH_30  0x30


#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1)  << (b))
#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
#define SetBF(mask,value) ((value) << (0?mask))
#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
#define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
#define SetBit(n) (1<<(n))
#define Set8Bits(value) ((value)&0xff)

typedef struct {
    int bitsPerPixel;
    int depth;
    int displayWidth;
    rgb weight;
    DisplayModePtr mode;
} NVFBLayout;

typedef struct _riva_hw_state
{
    U032 bpp;
    U032 width;
    U032 height;
    U032 interlace;
    U032 repaint0;
    U032 repaint1;
    U032 screen;
    U032 scale;
    U032 dither;
    U032 extra;
    U032 pixel;
    U032 horiz;
    U032 arbitration0;
    U032 arbitration1;
    U032 pll;
    U032 pllB;
    U032 vpll;
    U032 vpll2;
    U032 vpllB;
    U032 vpll2B;
    U032 pllsel;
    U032 general;
    U032 crtcOwner;
    U032 head;
    U032 head2;
    U032 config;
    U032 cursorConfig;
    U032 cursor0;
    U032 cursor1;
    U032 cursor2;
    U032 timingH;
    U032 timingV;
} RIVA_HW_STATE, *NVRegPtr;


typedef struct {
    RIVA_HW_STATE       SavedReg;
    RIVA_HW_STATE       ModeReg;
    RIVA_HW_STATE       *CurrentState;
    CARD32              Architecture;
    CARD32              CursorStart;
    EntityInfoPtr       pEnt;
    pciVideoPtr         PciInfo;
    PCITAG              PciTag;
    int                 Chipset;
    int                 ChipRev;
    Bool                Primary;
    CARD32              IOAddress;
    unsigned long       FbAddress;
    unsigned char *     FbBase;
    unsigned char *     FbStart;
    CARD32              FbMapSize;
    CARD32              FbUsableSize;
    CARD32              ScratchBufferSize;
    CARD32              ScratchBufferStart;
    Bool                NoAccel;
    Bool                HWCursor;
    Bool                ShadowFB;
    unsigned char *     ShadowPtr;
    int                 ShadowPitch;
    CARD32              MinVClockFreqKHz;
    CARD32              MaxVClockFreqKHz;
    CARD32              CrystalFreqKHz;
    CARD32              RamAmountKBytes;

    volatile U032 *REGS;
    volatile U032 *PCRTC0;
    volatile U032 *PCRTC;
    volatile U032 *PRAMDAC0;
    volatile U032 *PFB;
    volatile U032 *PFIFO;
    volatile U032 *PGRAPH;
    volatile U032 *PEXTDEV;
    volatile U032 *PTIMER;
    volatile U032 *PMC;
    volatile U032 *PRAMIN;
    volatile U032 *FIFO;
    volatile U032 *CURSOR;
    volatile U008 *PCIO0;
    volatile U008 *PCIO;
    volatile U008 *PVIO;
    volatile U008 *PDIO0;
    volatile U008 *PDIO;
    volatile U032 *PRAMDAC;

    XAAInfoRecPtr       AccelInfoRec;
    xf86CursorInfoPtr   CursorInfoRec;
    DGAModePtr          DGAModes;
    int                 numDGAModes;
    Bool                DGAactive;
    int                 DGAViewportStatus;
    void		(*PointerMoved)(int index, int x, int y);
    ScreenBlockHandlerProcPtr BlockHandler;
    CloseScreenProcPtr  CloseScreen;
    Bool                FBDev;
    int			Rotate;
    NVFBLayout		CurrentLayout;
    /* Cursor */
    CARD32              curFg, curBg;
    CARD32              curImage[256];
    /* I2C / DDC */
    I2CBusPtr           I2C;
    xf86Int10InfoPtr    pInt;
    void		(*VideoTimerCallback)(ScrnInfoPtr, Time);
    void		(*DMAKickoffCallback)(ScrnInfoPtr);
    XF86VideoAdaptorPtr	overlayAdaptor;
    XF86VideoAdaptorPtr	blitAdaptor;
    int			videoKey;
    int			FlatPanel;
    Bool                FPDither;
    Bool                Television;
    int			CRTCnumber;
    OptionInfoPtr	Options;
    Bool                alphaCursor;
    unsigned char       DDCBase;
    Bool                twoHeads;
    Bool                twoStagePLL;
    Bool                fpScaler;
    int                 fpWidth;
    int                 fpHeight;

    CARD32              dmaPut;
    CARD32              dmaCurrent;
    CARD32              dmaFree;
    CARD32              dmaMax;
    CARD32              *dmaBase;

    CARD32              currentRop;
} NVRec, *NVPtr;

#define NVPTR(p) ((NVPtr)((p)->driverPrivate))

#endif /* __NV_STRUCT_H__ */

--- NEW FILE: nv_video.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_video.c,v 1.20tsi Exp $ */

#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "xf86fbman.h"
#include "regionstr.h"

#include "xf86xv.h"
#include "X11/extensions/Xv.h"
#include "xaa.h"
#include "xaalocal.h"
#include "dixstruct.h"
#include "fourcc.h"

[...1420 lines suppressed...]
 {
   &NVImages[2],
   VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
   NVAllocSurface,
   NVFreeSurface,
   NVDisplaySurface,
   NVStopSurface,
   NVGetSurfaceAttribute,
   NVSetSurfaceAttribute,
   2046, 2046,
   NUM_ATTRIBUTES - 1,
   &NVAttributes[1]
  },
};

static void
NVInitOffscreenImages (ScreenPtr pScreen)
{
    xf86XVRegisterOffscreenImages(pScreen, NVOffscreenImages, 2);
}

--- NEW FILE: nv_xaa.c ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.33 2003/09/21 00:17:34 mvojkovi Exp $ */

#include "nv_include.h"
#include "xaalocal.h"
#include "miline.h"
#include "nv_dma.h"

static const int NVCopyROP[16] =
{
   0x00,            /* GXclear */
   0x88,            /* GXand */
   0x44,            /* GXandReverse */
   0xCC,            /* GXcopy */
   0x22,            /* GXandInverted */
   0xAA,            /* GXnoop */
   0x66,            /* GXxor */
   0xEE,            /* GXor */
   0x11,            /* GXnor */
   0x99,            /* GXequiv */
   0x55,            /* GXinvert*/
   0xDD,            /* GXorReverse */
   0x33,            /* GXcopyInverted */
   0xBB,            /* GXorInverted */
   0x77,            /* GXnand */
   0xFF             /* GXset */
};

static const int NVCopyROP_PM[16] =
{
   0x0A,            /* GXclear */
   0x8A,            /* GXand */
   0x4A,            /* GXandReverse */
   0xCA,            /* GXcopy */
   0x2A,            /* GXandInverted */
   0xAA,            /* GXnoop */
   0x6A,            /* GXxor */
   0xEA,            /* GXor */
   0x1A,            /* GXnor */
   0x9A,            /* GXequiv */
   0x5A,            /* GXinvert*/
   0xDA,            /* GXorReverse */
   0x3A,            /* GXcopyInverted */
   0xBA,            /* GXorInverted */
   0x7A,            /* GXnand */
   0xFA             /* GXset */
};

static const int NVPatternROP[16] =
{
   0x00,
   0xA0,
   0x50,
   0xF0,
   0x0A,
   0xAA,
   0x5A,
   0xFA,
   0x05,
   0xA5,
   0x55,
   0xF5,
   0x0F,
   0xAF,
   0x5F,
   0xFF
};

void
NVDmaKickoff(NVPtr pNv)
{
    if(pNv->dmaCurrent != pNv->dmaPut) {
        pNv->dmaPut = pNv->dmaCurrent;
        WRITE_PUT(pNv,  pNv->dmaPut);
    }
}


/* There is a HW race condition with videoram command buffers.
   You can't jump to the location of your put offset.  We write put
   at the jump offset + SKIPS dwords with noop padding in between
   to solve this problem */
#define SKIPS  8

void 
NVDmaWait (
   NVPtr pNv,
   int size
){
    int dmaGet;

    size++;

    while(pNv->dmaFree < size) {
       dmaGet = READ_GET(pNv);

       if(pNv->dmaPut >= dmaGet) {
           pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
           if(pNv->dmaFree < size) {
               NVDmaNext(pNv, 0x20000000);
               if(dmaGet <= SKIPS) {
                   if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */
                      WRITE_PUT(pNv, SKIPS + 1);
                   do { dmaGet = READ_GET(pNv); }
                   while(dmaGet <= SKIPS);
               }
               WRITE_PUT(pNv, SKIPS);
               pNv->dmaCurrent = pNv->dmaPut = SKIPS;
               pNv->dmaFree = dmaGet - (SKIPS + 1);
           }
       } else 
           pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1;
    }
}

/* 
  currentRop =  0-15  solid fill
               16-31  8x8 pattern fill
               32-47  solid fill with planemask 
*/

static void 
NVSetPattern(
   ScrnInfoPtr pScrn,
   CARD32 clr0,
   CARD32 clr1,
   CARD32 pat0,
   CARD32 pat1
)
{
    NVPtr pNv = NVPTR(pScrn);

    NVDmaStart(pNv, PATTERN_COLOR_0, 4);
    NVDmaNext (pNv, clr0);
    NVDmaNext (pNv, clr1);
    NVDmaNext (pNv, pat0);
    NVDmaNext (pNv, pat1);
}

static void 
NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask)
{
    NVPtr pNv = NVPTR(pScrn);

    if(planemask != ~0) {
        NVSetPattern(pScrn, 0, planemask, ~0, ~0);
        if(pNv->currentRop != (rop + 32)) {
           NVDmaStart(pNv, ROP_SET, 1);
           NVDmaNext (pNv, NVCopyROP_PM[rop]);
           pNv->currentRop = rop + 32;
        }
    } else 
    if (pNv->currentRop != rop) {
        if(pNv->currentRop >= 16)
             NVSetPattern(pScrn, ~0, ~0, ~0, ~0);
        NVDmaStart(pNv, ROP_SET, 1);
        NVDmaNext (pNv, NVCopyROP[rop]);
        pNv->currentRop = rop;
    }
}

void NVResetGraphics(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);
    CARD32 surfaceFormat, patternFormat, rectFormat, lineFormat;
    int pitch, i;

    if(pNv->NoAccel) return;

    pitch = pNv->CurrentLayout.displayWidth * 
            (pNv->CurrentLayout.bitsPerPixel >> 3);

    pNv->dmaBase = (CARD32*)(&pNv->FbStart[pNv->FbUsableSize]);

    for(i = 0; i < SKIPS; i++)
      pNv->dmaBase[i] = 0x00000000;

    pNv->dmaBase[0x0 + SKIPS] = 0x00040000;
    pNv->dmaBase[0x1 + SKIPS] = 0x80000010;
    pNv->dmaBase[0x2 + SKIPS] = 0x00042000;
    pNv->dmaBase[0x3 + SKIPS] = 0x80000011;
    pNv->dmaBase[0x4 + SKIPS] = 0x00044000;
    pNv->dmaBase[0x5 + SKIPS] = 0x80000012;
    pNv->dmaBase[0x6 + SKIPS] = 0x00046000;
    pNv->dmaBase[0x7 + SKIPS] = 0x80000013;
    pNv->dmaBase[0x8 + SKIPS] = 0x00048000;
    pNv->dmaBase[0x9 + SKIPS] = 0x80000014;
    pNv->dmaBase[0xA + SKIPS] = 0x0004A000;
    pNv->dmaBase[0xB + SKIPS] = 0x80000015;
    pNv->dmaBase[0xC + SKIPS] = 0x0004C000;
    pNv->dmaBase[0xD + SKIPS] = 0x80000016;
    pNv->dmaBase[0xE + SKIPS] = 0x0004E000;
    pNv->dmaBase[0xF + SKIPS] = 0x80000017;

    pNv->dmaPut = 0;
    pNv->dmaCurrent = 16 + SKIPS;
    pNv->dmaMax = 8191;
    pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;

    switch(pNv->CurrentLayout.depth) {
    case 24:
       surfaceFormat = SURFACE_FORMAT_DEPTH24;
       patternFormat = PATTERN_FORMAT_DEPTH24;
       rectFormat    = RECT_FORMAT_DEPTH24;
       lineFormat    = LINE_FORMAT_DEPTH24;
       break;
    case 16:
    case 15:
       surfaceFormat = SURFACE_FORMAT_DEPTH16;
       patternFormat = PATTERN_FORMAT_DEPTH16;
       rectFormat    = RECT_FORMAT_DEPTH16;
       lineFormat    = LINE_FORMAT_DEPTH16;
       break;
    default:
       surfaceFormat = SURFACE_FORMAT_DEPTH8;
       patternFormat = PATTERN_FORMAT_DEPTH8;
       rectFormat    = RECT_FORMAT_DEPTH8;
       lineFormat    = LINE_FORMAT_DEPTH8;
       break;
    }

    NVDmaStart(pNv, SURFACE_FORMAT, 4);
    NVDmaNext (pNv, surfaceFormat);
    NVDmaNext (pNv, pitch | (pitch << 16));
    NVDmaNext (pNv, 0);
    NVDmaNext (pNv, 0);

    NVDmaStart(pNv, PATTERN_FORMAT, 1);
    NVDmaNext (pNv, patternFormat);

    NVDmaStart(pNv, RECT_FORMAT, 1);
    NVDmaNext (pNv, rectFormat);

    NVDmaStart(pNv, LINE_FORMAT, 1);
    NVDmaNext (pNv, lineFormat);

    pNv->currentRop = ~0;  /* set to something invalid */
    NVSetRopSolid(pScrn, GXcopy, ~0);

    NVDmaKickoff(pNv);
}

void NVSync(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);

    if(pNv->DMAKickoffCallback)
       (*pNv->DMAKickoffCallback)(pScrn);

    while(READ_GET(pNv) != pNv->dmaPut);

    while(pNv->PGRAPH[0x0700/4]);
}

static void
NVDMAKickoffCallback (ScrnInfoPtr pScrn)
{
   NVPtr pNv = NVPTR(pScrn);

   NVDmaKickoff(pNv);
   pNv->DMAKickoffCallback = NULL;
}


static void
NVSetupForScreenToScreenCopy(
   ScrnInfoPtr pScrn, 
   int xdir, int ydir, 
   int rop,
   unsigned planemask, 
   int transparency_color
)
{
    NVPtr pNv = NVPTR(pScrn);

    planemask |= ~0 << pNv->CurrentLayout.depth;

    NVSetRopSolid(pScrn, rop, planemask);

    pNv->DMAKickoffCallback = NVDMAKickoffCallback;
}

static void
NVSubsequentScreenToScreenCopy(
   ScrnInfoPtr pScrn, 
   int x1, int y1,
   int x2, int y2, 
   int w, int h
)
{
    NVPtr pNv = NVPTR(pScrn);

    NVDmaStart(pNv, BLIT_POINT_SRC, 3);
    NVDmaNext (pNv, (y1 << 16) | x1);
    NVDmaNext (pNv, (y2 << 16) | x2);
    NVDmaNext (pNv, (h  << 16) | w);

    if((w * h) >= 512)
       NVDmaKickoff(pNv); 
}

static void
NVSetupForSolidFill(
   ScrnInfoPtr pScrn, 
   int color, 
   int rop,
   unsigned planemask
)
{
   NVPtr pNv = NVPTR(pScrn);

   planemask |= ~0 << pNv->CurrentLayout.depth;

   NVSetRopSolid(pScrn, rop, planemask);
   NVDmaStart(pNv, RECT_SOLID_COLOR, 1);
   NVDmaNext (pNv, color);

   pNv->DMAKickoffCallback = NVDMAKickoffCallback;
}

static void
NVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
   NVPtr pNv = NVPTR(pScrn);

   NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2);
   NVDmaNext (pNv, (x << 16) | y);
   NVDmaNext (pNv, (w << 16) | h);

   if((w * h) >= 512)
      NVDmaKickoff(pNv);
}

static void
NVSetupForMono8x8PatternFill (
   ScrnInfoPtr pScrn, 
   int patternx, int patterny,
   int fg, int bg, 
   int rop, 
   unsigned planemask
)
{
   NVPtr pNv = NVPTR(pScrn);

   planemask = ~0 << pNv->CurrentLayout.depth;

   fg |= planemask;
   if(bg == -1) bg = 0;
   else bg |= planemask;

   if (pNv->currentRop != (rop + 16)) {
       NVDmaStart(pNv, ROP_SET, 1);
       NVDmaNext (pNv, NVPatternROP[rop]);
       pNv->currentRop = rop + 16;
   }

   NVSetPattern(pScrn, bg, fg, patternx, patterny);
   NVDmaStart(pNv, RECT_SOLID_COLOR, 1);
   NVDmaNext (pNv, fg);

   pNv->DMAKickoffCallback = NVDMAKickoffCallback;
}

static void
NVSubsequentMono8x8PatternFillRect(
   ScrnInfoPtr pScrn,
   int patternx, int patterny,
   int x, int y, 
   int w, int h
)
{
   NVPtr pNv = NVPTR(pScrn);

   NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2);
   NVDmaNext (pNv, (x << 16) | y);
   NVDmaNext (pNv, (w << 16) | h);

   if((w * h) >= 512)
      NVDmaKickoff(pNv);
}

static CARD32 _bg_pixel;
static CARD32 _fg_pixel;
static Bool _transparent;
static CARD32 _color_expand_dwords;
static CARD32 _color_expand_offset;
static int _remaining;
static unsigned char *_storage_buffer[1];

static void
NVSetupForScanlineCPUToScreenColorExpandFill (
   ScrnInfoPtr pScrn,
   int fg, int bg,
   int rop,
   unsigned int planemask
)
{
   NVPtr pNv = NVPTR(pScrn);

   CARD32 mask = ~0 << pNv->CurrentLayout.depth;

   planemask |= mask;
   _fg_pixel = fg | mask;

   if(bg == -1) {
      _transparent = TRUE;
   } else {
      _transparent = FALSE;
      _bg_pixel = bg | mask;
   }

   NVSetRopSolid (pScrn, rop, planemask);
}

static void
NVSubsequentScanlineCPUToScreenColorExpandFill (
    ScrnInfoPtr pScrn, 
    int x, int y,
    int w, int h,
    int skipleft
)
{
   NVPtr pNv = NVPTR(pScrn);
   int bw = (w + 31) & ~31;

   _color_expand_dwords = bw >> 5;
   _remaining = h;

   if(_transparent) {
      NVDmaStart(pNv, RECT_EXPAND_ONE_COLOR_CLIP, 5);
      NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF));
      NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF));
      NVDmaNext (pNv, _fg_pixel);
      NVDmaNext (pNv, (h << 16) | bw);
      NVDmaNext (pNv, (y << 16) | (x & 0xFFFF));
      _color_expand_offset = RECT_EXPAND_ONE_COLOR_DATA(0);
   } else {
      NVDmaStart(pNv, RECT_EXPAND_TWO_COLOR_CLIP, 7);
      NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF));
      NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF));
      NVDmaNext (pNv, _bg_pixel);
      NVDmaNext (pNv, _fg_pixel);
      NVDmaNext (pNv, (h << 16) | bw);
      NVDmaNext (pNv, (h << 16) | bw);
      NVDmaNext (pNv, (y << 16) | (x & 0xFFFF));
      _color_expand_offset = RECT_EXPAND_TWO_COLOR_DATA(0); 
   }

   NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords);
   _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent];
}

static void
NVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
   NVPtr pNv = NVPTR(pScrn);

   pNv->dmaCurrent += _color_expand_dwords;

   if(--_remaining) {
       NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords);
       _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent];
   } else {
       /* hardware bug workaround */
       NVDmaStart(pNv, BLIT_POINT_SRC, 1);
       NVDmaNext (pNv, 0);
       NVDmaKickoff(pNv);
   }
}

static void 
NVSetupForScanlineImageWrite(
   ScrnInfoPtr pScrn, int rop, 
   unsigned int planemask, 
   int trans_color, 
   int bpp, int depth
)
{
   NVPtr pNv = NVPTR(pScrn);

   planemask |= ~0 << pNv->CurrentLayout.depth;

   NVSetRopSolid (pScrn, rop, planemask);
}

static CARD32 _image_size;
static CARD32 _image_srcpoint;
static CARD32 _image_dstpoint;
static CARD32 _image_dstpitch;

static void 
NVSubsequentScanlineImageWriteRect(
   ScrnInfoPtr pScrn, 
   int x, int y, 
   int w, int h, 
   int skipleft
)
{
   NVPtr pNv = NVPTR(pScrn);
   int Bpp = pNv->CurrentLayout.bitsPerPixel >> 3;
   int image_srcpitch;

   _image_size = (1 << 16) | (w - skipleft);
   _image_srcpoint = skipleft;
   _image_dstpoint = (y << 16) | (x + skipleft);
   _remaining = h;
   _image_dstpitch = pNv->CurrentLayout.displayWidth * Bpp;
   image_srcpitch =  ((w * Bpp) + 63) & ~63;
   _storage_buffer[0] = pNv->FbStart + pNv->ScratchBufferStart;

   NVSync(pScrn);

   NVDmaStart(pNv, SURFACE_PITCH, 2);
   NVDmaNext (pNv, (_image_dstpitch << 16) | image_srcpitch);
   NVDmaNext (pNv, pNv->ScratchBufferStart);
}

static void NVSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
{
   NVPtr pNv = NVPTR(pScrn);

   NVDmaStart(pNv, BLIT_POINT_SRC, 3);
   NVDmaNext (pNv, _image_srcpoint);
   NVDmaNext (pNv, _image_dstpoint);
   NVDmaNext (pNv, _image_size);
   NVDmaKickoff(pNv);

   if(--_remaining) {
      _image_dstpoint += (1 << 16);
      NVSync(pScrn);
   } else {
      NVDmaStart(pNv, SURFACE_PITCH, 2);
      NVDmaNext (pNv, _image_dstpitch | (_image_dstpitch << 16));
      NVDmaNext (pNv, 0);
   }
}

static void
NVSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
{
    NVPtr pNv = NVPTR(pScrn);

    planemask |= ~0 << pNv->CurrentLayout.depth;

    NVSetRopSolid(pScrn, rop, planemask);

    _fg_pixel = color;

    pNv->DMAKickoffCallback = NVDMAKickoffCallback;
}

static void 
NVSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
{
    NVPtr pNv = NVPTR(pScrn);

    NVDmaStart(pNv, LINE_COLOR, 1);
    NVDmaNext (pNv, _fg_pixel);
    NVDmaStart(pNv, LINE_LINES(0), 2);
    NVDmaNext (pNv, (y << 16) | ( x & 0xffff));
    if(dir == DEGREES_0) {
       NVDmaNext (pNv, (y << 16) | ((x + len) & 0xffff));
    } else {
       NVDmaNext (pNv, ((y + len) << 16) | (x & 0xffff));
    }
}

static void 
NVSubsequentSolidTwoPointLine(
   ScrnInfoPtr pScrn, 
   int x1, int y1,
   int x2, int y2, 
   int flags
)
{
    NVPtr pNv = NVPTR(pScrn);
    Bool drawLast = !(flags & OMIT_LAST);

    NVDmaStart(pNv, LINE_COLOR, 1);
    NVDmaNext (pNv, _fg_pixel);
    NVDmaStart(pNv, LINE_LINES(0), drawLast ? 4 : 2);
    NVDmaNext (pNv, (y1 << 16) | (x1 & 0xffff));
    NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff));
    if(drawLast) {
        NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff));
        NVDmaNext (pNv, ((y2 + 1) << 16) | (x2 & 0xffff));
    }
}

static void
NVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
{
    NVPtr pNv = NVPTR(pScrn);
    int h = y2 - y1 + 1;
    int w = x2 - x1 + 1;

    NVDmaStart(pNv, CLIP_POINT, 2);
    NVDmaNext (pNv, (y1 << 16) | x1); 
    NVDmaNext (pNv, (h << 16) | w);
}

static void
NVDisableClipping(ScrnInfoPtr pScrn)
{
    NVPtr pNv = NVPTR(pScrn);

    NVDmaStart(pNv, CLIP_POINT, 2);
    NVDmaNext (pNv, 0);              
    NVDmaNext (pNv, 0x7FFF7FFF);
}


/* Initialize XAA acceleration info */
Bool
NVAccelInit(ScreenPtr pScreen) 
{
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
   NVPtr pNv = NVPTR(pScrn);
   XAAInfoRecPtr accel;

   accel = pNv->AccelInfoRec = XAACreateInfoRec();
   if(!accel) return FALSE;

   accel->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
   accel->Sync = NVSync;

   accel->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
   accel->SetupForScreenToScreenCopy = NVSetupForScreenToScreenCopy;
   accel->SubsequentScreenToScreenCopy = NVSubsequentScreenToScreenCopy;

   accel->SolidFillFlags = 0;
   accel->SetupForSolidFill = NVSetupForSolidFill;
   accel->SubsequentSolidFillRect = NVSubsequentSolidFillRect;

   accel->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
                                    HARDWARE_PATTERN_PROGRAMMED_BITS |
                                    NO_PLANEMASK;
   accel->SetupForMono8x8PatternFill = NVSetupForMono8x8PatternFill;
   accel->SubsequentMono8x8PatternFillRect = NVSubsequentMono8x8PatternFillRect;

   accel->ScanlineCPUToScreenColorExpandFillFlags = 
                                    BIT_ORDER_IN_BYTE_LSBFIRST |
                                    CPU_TRANSFER_PAD_DWORD |
                                    LEFT_EDGE_CLIPPING |
                                    LEFT_EDGE_CLIPPING_NEGATIVE_X;
   accel->NumScanlineColorExpandBuffers = 1;
   accel->SetupForScanlineCPUToScreenColorExpandFill = 
            NVSetupForScanlineCPUToScreenColorExpandFill;
   accel->SubsequentScanlineCPUToScreenColorExpandFill = 
            NVSubsequentScanlineCPUToScreenColorExpandFill;
   accel->SubsequentColorExpandScanline = 
            NVSubsequentColorExpandScanline;
   accel->ScanlineColorExpandBuffers = _storage_buffer;

   accel->ScanlineImageWriteFlags = NO_GXCOPY |
                                    NO_TRANSPARENCY |
                                    LEFT_EDGE_CLIPPING |
                                    LEFT_EDGE_CLIPPING_NEGATIVE_X;
   accel->NumScanlineImageWriteBuffers = 1;
   accel->SetupForScanlineImageWrite = NVSetupForScanlineImageWrite;
   accel->SubsequentScanlineImageWriteRect = NVSubsequentScanlineImageWriteRect;
   accel->SubsequentImageWriteScanline = NVSubsequentImageWriteScanline;
   accel->ScanlineImageWriteBuffers = _storage_buffer;

   accel->SolidLineFlags = 0;
   accel->SetupForSolidLine = NVSetupForSolidLine;
   accel->SubsequentSolidHorVertLine = NVSubsequentSolidHorVertLine;
   accel->SubsequentSolidTwoPointLine = NVSubsequentSolidTwoPointLine;
   accel->SetClippingRectangle = NVSetClippingRectangle;
   accel->DisableClipping = NVDisableClipping;
   accel->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
   
   miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);

   return (XAAInit(pScreen, accel));
}


--- NEW FILE: riva_const.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_const.h $ */

#ifndef __RIVA_CONST_H__
#define __RIVA_CONST_H__

#define RIVA_VERSION 4000
#define RIVA_NAME "RIVA128"
#define RIVA_DRIVER_NAME "riva128"
#define RIVA_MAJOR_VERSION 1
#define RIVA_MINOR_VERSION 0
#define RIVA_PATCHLEVEL 1

#endif /* __RIVA_CONST_H__ */
          

--- NEW FILE: riva_cursor.c ---
/*
 * Copyright 1996-1997  David J. McKay
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* Rewritten with reference from mga driver and 3.3.4 NVIDIA driver by
   Jarno Paananen <jpaana at s2.org> */

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_cursor.c $ */

#include "riva_include.h"

#include "cursorstr.h"

/****************************************************************************\
*                                                                            *
*                          HW Cursor Entrypoints                             *
*                                                                            *
\****************************************************************************/

#define TRANSPARENT_PIXEL   0

#define ConvertToRGB555(c) \
(((c & 0xf80000) >> 9 ) | ((c & 0xf800) >> 6 ) | ((c & 0xf8) >> 3 ) | 0x8000)


static void 
RivaConvertCursor1555(RivaPtr pRiva, CARD32 *src, CARD16 *dst)
{
    CARD32 b, m;
    int i, j;
    
    for ( i = 0; i < 32; i++ ) {
        b = *src++;
        m = *src++;
        for ( j = 0; j < 32; j++ ) {
            if ( m & 1 )
                *dst = ( b & 1) ? pRiva->curFg : pRiva->curBg;
            else
                *dst = TRANSPARENT_PIXEL;
            b >>= 1;
            m >>= 1;
            dst++;
        }
    }
}


static void
RivaTransformCursor (RivaPtr pRiva)
{
    CARD32 *tmp;
    int i, dwords;

    dwords = (32 * 32) >> 1;
    if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
    RivaConvertCursor1555(pRiva, pRiva->curImage, (CARD16*)tmp);

    for(i = 0; i < dwords; i++)
        pRiva->riva.CURSOR[i] = tmp[i];

    DEALLOCATE_LOCAL(tmp);
}

static void
RivaLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
{
    RivaPtr pRiva = RivaPTR(pScrn);

    /* save copy of image for color changes */
    memcpy(pRiva->curImage, src, 256);

    RivaTransformCursor(pRiva);
}

static void
RivaSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    pRiva->riva.PRAMDAC[0x0000300/4] = (x & 0xFFFF) | (y << 16);
}

static void
RivaSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    CARD32 fore, back;

    fore = ConvertToRGB555(fg);
    back = ConvertToRGB555(bg);

    if ((pRiva->curFg != fore) || (pRiva->curBg != back)) {
        pRiva->curFg = fore;
        pRiva->curBg = back;
            
        RivaTransformCursor(pRiva);
    }
}


static void 
RivaShowCursor(ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    /* Enable cursor - X-Windows mode */
    pRiva->riva.ShowHideCursor(&pRiva->riva, 1);
}

static void
RivaHideCursor(ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    /* Disable cursor */
    pRiva->riva.ShowHideCursor(&pRiva->riva, 0);
}

static Bool 
RivaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
    return TRUE;
}


Bool 
RivaCursorInit(ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    RivaPtr pRiva = RivaPTR(pScrn);
    xf86CursorInfoPtr infoPtr;

    infoPtr = xf86CreateCursorInfoRec();
    if(!infoPtr) return FALSE;
    
    pRiva->CursorInfoRec = infoPtr;

    infoPtr->MaxWidth = infoPtr->MaxHeight = 32;
    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
                     HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32; 
    infoPtr->SetCursorColors = RivaSetCursorColors;
    infoPtr->SetCursorPosition = RivaSetCursorPosition;
    infoPtr->LoadCursorImage = RivaLoadCursorImage;
    infoPtr->HideCursor = RivaHideCursor;
    infoPtr->ShowCursor = RivaShowCursor;
    infoPtr->UseHWCursor = RivaUseHWCursor;

    return(xf86InitCursor(pScreen, infoPtr));
}

--- NEW FILE: riva_dac.c ---
/*
 * Copyright 1996-1997  David J. McKay
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
   <jpaana at s2.org> */

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_dac.c,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */

#include "riva_include.h"

Bool
RivaDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
    int i;
    int horizDisplay    = (mode->CrtcHDisplay/8)   - 1;
    int horizStart      = (mode->CrtcHSyncStart/8) - 1;
    int horizEnd        = (mode->CrtcHSyncEnd/8)   - 1;
    int horizTotal      = (mode->CrtcHTotal/8)     - 5;
    int horizBlankStart = (mode->CrtcHDisplay/8)   - 1;
    int horizBlankEnd   = (mode->CrtcHTotal/8)     - 1;
    int vertDisplay     =  mode->CrtcVDisplay      - 1;
    int vertStart       =  mode->CrtcVSyncStart    - 1;
    int vertEnd         =  mode->CrtcVSyncEnd      - 1;
    int vertTotal       =  mode->CrtcVTotal        - 2;
    int vertBlankStart  =  mode->CrtcVDisplay      - 1;
    int vertBlankEnd    =  mode->CrtcVTotal        - 1;
   

    RivaPtr pRiva = RivaPTR(pScrn);
    RivaRegPtr rivaReg = &pRiva->ModeReg;
    RivaFBLayout *pLayout = &pRiva->CurrentLayout;
    vgaRegPtr   pVga;

    /*
     * This will initialize all of the generic VGA registers.
     */
    if (!vgaHWInit(pScrn, mode))
        return(FALSE);

    pVga = &VGAHWPTR(pScrn)->ModeReg;

    /*
     * Set all CRTC values.
     */

    if(mode->Flags & V_INTERLACE) 
        vertTotal |= 1;

    pVga->CRTC[0x0]  = Set8Bits(horizTotal);
    pVga->CRTC[0x1]  = Set8Bits(horizDisplay);
    pVga->CRTC[0x2]  = Set8Bits(horizBlankStart);
    pVga->CRTC[0x3]  = SetBitField(horizBlankEnd,4:0,4:0) 
                       | SetBit(7);
    pVga->CRTC[0x4]  = Set8Bits(horizStart);
    pVga->CRTC[0x5]  = SetBitField(horizBlankEnd,5:5,7:7)
                       | SetBitField(horizEnd,4:0,4:0);
    pVga->CRTC[0x6]  = SetBitField(vertTotal,7:0,7:0);
    pVga->CRTC[0x7]  = SetBitField(vertTotal,8:8,0:0)
                       | SetBitField(vertDisplay,8:8,1:1)
                       | SetBitField(vertStart,8:8,2:2)
                       | SetBitField(vertBlankStart,8:8,3:3)
                       | SetBit(4)
                       | SetBitField(vertTotal,9:9,5:5)
                       | SetBitField(vertDisplay,9:9,6:6)
                       | SetBitField(vertStart,9:9,7:7);
    pVga->CRTC[0x9]  = SetBitField(vertBlankStart,9:9,5:5)
                       | SetBit(6)
                       | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
    pVga->CRTC[0x10] = Set8Bits(vertStart);
    pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
    pVga->CRTC[0x12] = Set8Bits(vertDisplay);
    pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
    pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
    pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);

    pVga->Attribute[0x10] = 0x01;

    rivaReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
                  | SetBitField(vertBlankStart,10:10,3:3)
                  | SetBitField(vertStart,10:10,2:2)
                  | SetBitField(vertDisplay,10:10,1:1)
                  | SetBitField(vertTotal,10:10,0:0);

    rivaReg->horiz  = SetBitField(horizTotal,8:8,0:0) 
                  | SetBitField(horizDisplay,8:8,1:1)
                  | SetBitField(horizBlankStart,8:8,2:2)
                  | SetBitField(horizStart,8:8,3:3);

    rivaReg->extra  = SetBitField(vertTotal,11:11,0:0)
                    | SetBitField(vertDisplay,11:11,2:2)
                    | SetBitField(vertStart,11:11,4:4)
                    | SetBitField(vertBlankStart,11:11,6:6);

    if(mode->Flags & V_INTERLACE) {
       horizTotal = (horizTotal >> 1) & ~1;
       rivaReg->interlace = Set8Bits(horizTotal);
       rivaReg->horiz |= SetBitField(horizTotal,8:8,4:4);
    } else {
       rivaReg->interlace = 0xff;  /* interlace off */
    }

    /*
     * Initialize DAC palette.
     */
    if(pLayout->bitsPerPixel != 8 )
    {
        for (i = 0; i < 256; i++)
        {
            pVga->DAC[i*3]     = i;
            pVga->DAC[(i*3)+1] = i;
            pVga->DAC[(i*3)+2] = i;
        }
    }
    
    /*
     * Calculate the extended registers.
     */

    if(pLayout->depth < 24) 
	i = pLayout->depth;
    else i = 32;

    pRiva->riva.CalcStateExt(&pRiva->riva, 
                           rivaReg,
                           i,
                           pLayout->displayWidth,
                           mode->CrtcHDisplay,
                           pScrn->virtualY,
                           mode->Clock,
			   mode->Flags);

    rivaReg->cursorConfig = 0x02000100;
    if(mode->Flags & V_DBLSCAN)
       rivaReg->cursorConfig |= (1 << 4);

    return (TRUE);
}

void 
RivaDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
             Bool primary)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    int restore = VGA_SR_MODE;

    restore |= primary ? (VGA_SR_CMAP | VGA_SR_FONTS) : VGA_SR_CMAP;
    pRiva->riva.LoadStateExt(&pRiva->riva, rivaReg);
    vgaHWRestore(pScrn, vgaReg, restore);
}

/*
 * RivaDACSave
 *
 * This function saves the video state.
 */
void
RivaDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
          Bool saveFonts)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    pRiva->riva.LockUnlock(&pRiva->riva, 0);

    vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE | 
                             (saveFonts? VGA_SR_FONTS : 0));
    pRiva->riva.UnloadStateExt(&pRiva->riva, rivaReg);
}

#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)

void
RivaDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
                 VisualPtr pVisual )
{
    int i, index;
    RivaPtr pRiva = RivaPTR(pScrn);
    vgaRegPtr   pVga;

    pVga = &VGAHWPTR(pScrn)->ModeReg;

    if(pRiva->CurrentLayout.depth != 8)
           return;

    for(i = 0; i < numColors; i++) {
        index = indices[i];
        pVga->DAC[index*3]     = colors[index].red;
        pVga->DAC[(index*3)+1] = colors[index].green;
        pVga->DAC[(index*3)+2] = colors[index].blue;
    }
    vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
}

/*
 * DDC1 support only requires DDC_SDA_MASK,
 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
 */
#define DDC_SDA_READ_MASK  (1 << 3)
#define DDC_SCL_READ_MASK  (1 << 2)
#define DDC_SDA_WRITE_MASK (1 << 4)
#define DDC_SCL_WRITE_MASK (1 << 5)

static void
Riva_I2CGetBits(I2CBusPtr b, int *clock, int *data)
{
    RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
    unsigned char val;

    /* Get the result. */
    VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase);
    val = VGA_RD08(pRiva->riva.PCIO, 0x3d5);

    *clock = (val & DDC_SCL_READ_MASK) != 0;
    *data  = (val & DDC_SDA_READ_MASK) != 0;
}

static void
Riva_I2CPutBits(I2CBusPtr b, int clock, int data)
{
    RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
    unsigned char val;

    VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
    val = VGA_RD08(pRiva->riva.PCIO, 0x3d5) & 0xf0;
    if (clock)
        val |= DDC_SCL_WRITE_MASK;
    else
        val &= ~DDC_SCL_WRITE_MASK;

    if (data)
        val |= DDC_SDA_WRITE_MASK;
    else
        val &= ~DDC_SDA_WRITE_MASK;

    VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
    VGA_WR08(pRiva->riva.PCIO, 0x3d5, val | 0x1);
}

Bool
RivaDACi2cInit(ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    I2CBusPtr I2CPtr;

    I2CPtr = xf86CreateI2CBusRec();
    if(!I2CPtr) return FALSE;

    pRiva->I2C = I2CPtr;

    I2CPtr->BusName    = "DDC";
    I2CPtr->scrnIndex  = pScrn->scrnIndex;
    I2CPtr->I2CPutBits = Riva_I2CPutBits;
    I2CPtr->I2CGetBits = Riva_I2CGetBits;
    I2CPtr->AcknTimeout = 5;

    if (!xf86I2CBusInit(I2CPtr)) {
        return FALSE;
    }
    return TRUE;
}


--- NEW FILE: riva_dga.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/riva/riva_dga.c $ */

#include "riva_local.h"
#include "riva_include.h"
#include "riva_type.h"
#include "riva_proto.h"
#include "xaalocal.h"
#include "dgaproc.h"


static Bool Riva_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 
					int *, int *, int *);
static Bool Riva_SetMode(ScrnInfoPtr, DGAModePtr);
static int  Riva_GetViewport(ScrnInfoPtr);
static void Riva_SetViewport(ScrnInfoPtr, int, int, int);
static void Riva_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
static void Riva_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
static void Riva_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 
					unsigned long);

static
DGAFunctionRec Riva_DGAFuncs = {
   Riva_OpenFramebuffer,
   NULL,
   Riva_SetMode,
   Riva_SetViewport,
   Riva_GetViewport,
   RivaSync,
   Riva_FillRect,
   Riva_BlitRect,
   Riva_BlitTransRect
};



static DGAModePtr
RivaSetupDGAMode(
   ScrnInfoPtr pScrn,
   DGAModePtr modes,
   int *num,
   int bitsPerPixel,
   int depth,
   Bool pixmap,
   int secondPitch,
   unsigned long red,
   unsigned long green,
   unsigned long blue,
   short visualClass
){
   DisplayModePtr firstMode, pMode;
   RivaPtr pRiva = RivaPTR(pScrn);
   DGAModePtr mode, newmodes;
   int size, pitch, Bpp = bitsPerPixel >> 3;

SECOND_PASS:

   pMode = firstMode = pScrn->modes;

   while(1) {

	pitch = (pMode->HDisplay + 31) & ~31;
	size = pitch * Bpp * pMode->VDisplay;

	if((!secondPitch || (pitch != secondPitch)) &&
		(size <= pRiva->FbUsableSize)) {

	    if(secondPitch)
		pitch = secondPitch; 

	    if(!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
		break;

	    modes = newmodes;
	    mode = modes + *num;

	    mode->mode = pMode;
	    mode->flags = DGA_CONCURRENT_ACCESS;

	    if(pixmap)
		mode->flags |= DGA_PIXMAP_AVAILABLE;
	    if(!pRiva->NoAccel)
		mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
	    if(pMode->Flags & V_DBLSCAN)
		mode->flags |= DGA_DOUBLESCAN;
	    if(pMode->Flags & V_INTERLACE)
		mode->flags |= DGA_INTERLACED;
	    mode->byteOrder = pScrn->imageByteOrder;
	    mode->depth = depth;
	    mode->bitsPerPixel = bitsPerPixel;
	    mode->red_mask = red;
	    mode->green_mask = green;
	    mode->blue_mask = blue;
	    mode->visualClass = visualClass;
	    mode->viewportWidth = pMode->HDisplay;
	    mode->viewportHeight = pMode->VDisplay;
	    mode->xViewportStep = 4 / Bpp;
	    mode->yViewportStep = 1;
	    mode->viewportFlags = DGA_FLIP_RETRACE;
	    mode->offset = 0;
	    mode->address = pRiva->FbStart;
	    mode->bytesPerScanline = pitch * Bpp;
	    mode->imageWidth = pitch;
	    mode->imageHeight =  pRiva->FbUsableSize / mode->bytesPerScanline; 
	    mode->pixmapWidth = mode->imageWidth;
	    mode->pixmapHeight = mode->imageHeight;
	    mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
	    mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
	    (*num)++;
	}

	pMode = pMode->next;
	if(pMode == firstMode)
	   break;
    }

    if(secondPitch) {
	secondPitch = 0;
	goto SECOND_PASS;
    }

    return modes;
}


Bool
RivaDGAInit(ScreenPtr pScreen)
{   
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
   RivaPtr pRiva = RivaPTR(pScrn);
   DGAModePtr modes = NULL;
   int num = 0;

   /* 8 */
   modes = RivaSetupDGAMode (pScrn, modes, &num, 8, 8, 
		(pScrn->bitsPerPixel == 8),
		(pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
		0, 0, 0, PseudoColor);

   /* 15 */
   modes = RivaSetupDGAMode (pScrn, modes, &num, 16, 15, 
		(pScrn->bitsPerPixel == 16),
		(pScrn->depth != 15) ? 0 : pScrn->displayWidth,
		0x7c00, 0x03e0, 0x001f, TrueColor);

   /* 32 */
   modes = RivaSetupDGAMode (pScrn, modes, &num, 32, 24, 
		(pScrn->bitsPerPixel == 32),
		(pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
		0xff0000, 0x00ff00, 0x0000ff, TrueColor);

   pRiva->numDGAModes = num;
   pRiva->DGAModes = modes;

   return DGAInit(pScreen, &Riva_DGAFuncs, modes, num);  
}


static int 
BitsSet(unsigned long data)
{
   unsigned long mask;
   int set = 0;

   for(mask = 1; mask; mask <<= 1)
        if(mask & data) set++;   

   return set;
}

static Bool
Riva_SetMode(
   ScrnInfoPtr pScrn,
   DGAModePtr pMode
){
   static RivaFBLayout SavedLayouts[MAXSCREENS];
   int index = pScrn->pScreen->myNum;

   RivaPtr pRiva = RivaPTR(pScrn);

   if(!pMode) { /* restore the original mode */
      if(pRiva->DGAactive)
        memcpy(&pRiva->CurrentLayout, &SavedLayouts[index], sizeof(RivaFBLayout));
                
      pScrn->currentMode = pRiva->CurrentLayout.mode;
      RivaSwitchMode(index, pScrn->currentMode, 0);
      RivaAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
      pRiva->DGAactive = FALSE;
   } else {
      if(!pRiva->DGAactive) {  /* save the old parameters */
	memcpy(&SavedLayouts[index], &pRiva->CurrentLayout, sizeof(RivaFBLayout));
	pRiva->DGAactive = TRUE;
      }

      /* update CurrentLayout */
      pRiva->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
      pRiva->CurrentLayout.depth = pMode->depth;
      pRiva->CurrentLayout.displayWidth = pMode->bytesPerScanline / 
                              (pMode->bitsPerPixel >> 3);
      pRiva->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
      pRiva->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
      pRiva->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
      /* RivaModeInit() will set the mode field */
      RivaSwitchMode(index, pMode->mode, 0);
   }
   
   return TRUE;
}



static int  
Riva_GetViewport(
  ScrnInfoPtr pScrn
){
    RivaPtr pRiva = RivaPTR(pScrn);

    return pRiva->DGAViewportStatus;
}

static void 
Riva_SetViewport(
   ScrnInfoPtr pScrn, 
   int x, int y, 
   int flags
){
   RivaPtr pRiva = RivaPTR(pScrn);

   RivaAdjustFrame(pScrn->pScreen->myNum, x, y, flags);

   while(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08);
   while(!(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08));

   pRiva->DGAViewportStatus = 0;  
}

static void 
Riva_FillRect (
   ScrnInfoPtr pScrn, 
   int x, int y, int w, int h, 
   unsigned long color
){
    RivaPtr pRiva = RivaPTR(pScrn);

    if(!pRiva->AccelInfoRec) return;

    (*pRiva->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
    (*pRiva->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);

    SET_SYNC_FLAG(pRiva->AccelInfoRec);
}

static void 
Riva_BlitRect(
   ScrnInfoPtr pScrn, 
   int srcx, int srcy, 
   int w, int h, 
   int dstx, int dsty
){
    RivaPtr pRiva = RivaPTR(pScrn);
    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
    int ydir = (srcy < dsty) ? -1 : 1;

    if(!pRiva->AccelInfoRec) return;

    (*pRiva->AccelInfoRec->SetupForScreenToScreenCopy)(
		pScrn, xdir, ydir, GXcopy, ~0, -1);

    (*pRiva->AccelInfoRec->SubsequentScreenToScreenCopy)(
		pScrn, srcx, srcy, dstx, dsty, w, h);

    SET_SYNC_FLAG(pRiva->AccelInfoRec);
}


static void 
Riva_BlitTransRect(
   ScrnInfoPtr pScrn, 
   int srcx, int srcy, 
   int w, int h, 
   int dstx, int dsty,
   unsigned long color
){
   /* not implemented... yet */
}


static Bool 
Riva_OpenFramebuffer(
   ScrnInfoPtr pScrn, 
   char **name,
   unsigned char **mem,
   int *size,
   int *offset,
   int *flags
){
    RivaPtr pRiva = RivaPTR(pScrn);

    *name = NULL; 		/* no special device */
    *mem = (unsigned char*)pRiva->FbAddress;
    *size = pRiva->FbMapSize;
    *offset = 0;
    *flags = DGA_NEED_ROOT;

    return TRUE;
}

--- NEW FILE: riva_driver.c ---
/*
 * Copyright 1996-1997  David J. McKay
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
[...1348 lines suppressed...]
/* Do screen blanking */

/* Mandatory */
static Bool
RivaSaveScreen(ScreenPtr pScreen, int mode)
{
    return vgaHWSaveScreen(pScreen, mode);
}

static void
RivaSave(ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    RivaRegPtr rivaReg = &pRiva->SavedReg;
    vgaHWPtr pVga = VGAHWPTR(pScrn);
    vgaRegPtr vgaReg = &pVga->SavedReg;

    (*pRiva->Save)(pScrn, vgaReg, rivaReg, pRiva->Primary);
}


--- NEW FILE: riva_hw.c ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.51tsi Exp $ */

#include "riva_local.h"
#include "compiler.h"
#include "riva_include.h"
#include "riva_hw.h"
#include "riva_tbl.h"

/*
 * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT
 * operate identically (except TNT has more memory and better 3D quality.
 */
static int nv3Busy
(
    RIVA_HW_INST *chip
)
{
    return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x000006B0/4] & 0x01));
}
static void vgaLockUnlock
(
    RIVA_HW_INST *chip,
    Bool           Lock
)
{
    CARD8 cr11;
    VGA_WR08(chip->PCIO, 0x3D4, 0x11);
    cr11 = VGA_RD08(chip->PCIO, 0x3D5);
    if(Lock) cr11 |= 0x80;
    else cr11 &= ~0x80;
    VGA_WR08(chip->PCIO, 0x3D5, cr11);
}

static void nv3LockUnlock
(
    RIVA_HW_INST *chip,
    Bool           Lock
)
{
    VGA_WR08(chip->PVIO, 0x3C4, 0x06);
    VGA_WR08(chip->PVIO, 0x3C5, Lock ? 0x99 : 0x57);
    vgaLockUnlock(chip, Lock);
}
static int ShowHideCursor
(
    RIVA_HW_INST *chip,
    int           ShowHide
)
{
    int current;
    current                     =  chip->CurrentState->cursor1;
    chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) |
	                          (ShowHide & 0x01);
    VGA_WR08(chip->PCIO, 0x3D4, 0x31);
    VGA_WR08(chip->PCIO, 0x3D5, chip->CurrentState->cursor1);
    return (current & 0x01);
}

/****************************************************************************\
*                                                                            *
* The video arbitration routines calculate some "magic" numbers.  Fixes      *
* the snow seen when accessing the framebuffer without it.                   *
* It just works (I hope).                                                    *
*                                                                            *
\****************************************************************************/

#define DEFAULT_GR_LWM 100
#define DEFAULT_VID_LWM 100
#define DEFAULT_GR_BURST_SIZE 256
#define DEFAULT_VID_BURST_SIZE 128
#define VIDEO		0
#define GRAPHICS	1
#define MPORT		2
#define ENGINE		3
#define GFIFO_SIZE	320
#define GFIFO_SIZE_128	256
#define MFIFO_SIZE	120
#define VFIFO_SIZE	256
#define	ABS(a)	(a>0?a:-a)
typedef struct {
  int gdrain_rate;
  int vdrain_rate;
  int mdrain_rate;
  int gburst_size;
  int vburst_size;
  char vid_en;
  char gr_en;
  int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm;
  int by_gfacc;
  char vid_only_once;
  char gr_only_once;
  char first_vacc;
  char first_gacc;
  char first_macc;
  int vocc;
  int gocc;
  int mocc;
  char cur;
  char engine_en;
  char converged;
  int priority;
} nv3_arb_info;
typedef struct {
  int graphics_lwm;
  int video_lwm;
  int graphics_burst_size;
  int video_burst_size;
  int graphics_hi_priority;
  int media_hi_priority;
  int rtl_values;
  int valid;
} nv3_fifo_info;
typedef struct {
  char pix_bpp;
  char enable_video;
  char gr_during_vid;
  char enable_mp;
  int memory_width;
  int video_scale;
  int pclk_khz;
  int mclk_khz;
  int mem_page_miss;
  int mem_latency;
  char mem_aligned;
} nv3_sim_state;
static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
{
    int iter = 0;
    int tmp;
    int vfsize, mfsize, gfsize;
    int mburst_size = 32;
    int mmisses, gmisses, vmisses;
    int misses;
    int vlwm, glwm;
    int last, next, cur;
    int max_gfsize ;
    long ns;

    vlwm = 0;
    glwm = 0;
    vfsize = 0;
    gfsize = 0;
    cur = ainfo->cur;
    mmisses = 2;
    gmisses = 2;
    vmisses = 2;
    if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128;
    else  max_gfsize = GFIFO_SIZE;
    max_gfsize = GFIFO_SIZE;
    while (1)
    {
        if (ainfo->vid_en)
        {
            if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc;
            if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ;
            ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
            vfsize = ns * ainfo->vdrain_rate / 1000000;
            vfsize =  ainfo->wcvlwm - ainfo->vburst_size + vfsize;
        }
        if (state->enable_mp)
        {
            if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc;
        }
        if (ainfo->gr_en)
        {
            if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ;
            if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc;
            ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
            gfsize = (ns * (long) ainfo->gdrain_rate)/1000000;
            gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize;
        }
        mfsize = 0;
        if (!state->gr_during_vid && ainfo->vid_en)
            if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once)
                next = VIDEO;
            else if (ainfo->mocc < 0)
                next = MPORT;
            else if (ainfo->gocc< ainfo->by_gfacc)
                next = GRAPHICS;
            else return (0);
        else switch (ainfo->priority)
            {
                case VIDEO:
                    if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
                        next = VIDEO;
                    else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
                        next = GRAPHICS;
                    else if (ainfo->mocc<0)
                        next = MPORT;
                    else    return (0);
                    break;
                case GRAPHICS:
                    if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
                        next = GRAPHICS;
                    else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
                        next = VIDEO;
                    else if (ainfo->mocc<0)
                        next = MPORT;
                    else    return (0);
                    break;
                default:
                    if (ainfo->mocc<0)
                        next = MPORT;
                    else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
                        next = GRAPHICS;
                    else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
                        next = VIDEO;
                    else    return (0);
                    break;
            }
        last = cur;
        cur = next;
        iter++;
        switch (cur)
        {
            case VIDEO:
                if (last==cur)    misses = 0;
                else if (ainfo->first_vacc)   misses = vmisses;
                else    misses = 1;
                ainfo->first_vacc = 0;
                if (last!=cur)
                {
                    ns =  1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; 
                    vlwm = ns * ainfo->vdrain_rate/ 1000000;
                    vlwm = ainfo->vocc - vlwm;
                }
                ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz;
                ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000;
                ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000;
                ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000;
                break;
            case GRAPHICS:
                if (last==cur)    misses = 0;
                else if (ainfo->first_gacc)   misses = gmisses;
                else    misses = 1;
                ainfo->first_gacc = 0;
                if (last!=cur)
                {
                    ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ;
                    glwm = ns * ainfo->gdrain_rate/1000000;
                    glwm = ainfo->gocc - glwm;
                }
                ns = 1000000*(misses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
                ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
                ainfo->gocc = ainfo->gocc + ainfo->gburst_size - ns*ainfo->gdrain_rate/1000000;
                ainfo->mocc = ainfo->mocc + 0 - ns*ainfo->mdrain_rate/1000000;
                break;
            default:
                if (last==cur)    misses = 0;
                else if (ainfo->first_macc)   misses = mmisses;
                else    misses = 1;
                ainfo->first_macc = 0;
                ns = 1000000*(misses*state->mem_page_miss + mburst_size/(state->memory_width/8))/state->mclk_khz;
                ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
                ainfo->gocc = ainfo->gocc + 0 - ns*ainfo->gdrain_rate/1000000;
                ainfo->mocc = ainfo->mocc + mburst_size - ns*ainfo->mdrain_rate/1000000;
                break;
        }
        if (iter>100)
        {
            ainfo->converged = 0;
            return (1);
        }
        ns = 1000000*ainfo->gburst_size/(state->memory_width/8)/state->mclk_khz;
        tmp = ns * ainfo->gdrain_rate/1000000;
        if (ABS(ainfo->gburst_size) + ((ABS(ainfo->wcglwm) + 16 ) & ~0x7) - tmp > max_gfsize)
        {
            ainfo->converged = 0;
            return (1);
        }
        ns = 1000000*ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
        tmp = ns * ainfo->vdrain_rate/1000000;
        if (ABS(ainfo->vburst_size) + (ABS(ainfo->wcvlwm + 32) & ~0xf)  - tmp> VFIFO_SIZE)
        {
            ainfo->converged = 0;
            return (1);
        }
        if (ABS(ainfo->gocc) > max_gfsize)
        {
            ainfo->converged = 0;
            return (1);
        }
        if (ABS(ainfo->vocc) > VFIFO_SIZE)
        {
            ainfo->converged = 0;
            return (1);
        }
        if (ABS(ainfo->mocc) > MFIFO_SIZE)
        {
            ainfo->converged = 0;
            return (1);
        }
        if (ABS(vfsize) > VFIFO_SIZE)
        {
            ainfo->converged = 0;
            return (1);
        }
        if (ABS(gfsize) > max_gfsize)
        {
            ainfo->converged = 0;
            return (1);
        }
        if (ABS(mfsize) > MFIFO_SIZE)
        {
            ainfo->converged = 0;
            return (1);
        }
    }
}
static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state,  nv3_arb_info *ainfo) 
{
    long ens, vns, mns, gns;
    int mmisses, gmisses, vmisses, eburst_size, mburst_size;
    int refresh_cycle;

    refresh_cycle = 0;
    refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5;
    mmisses = 2;
    if (state->mem_aligned) gmisses = 2;
    else    gmisses = 3;
    vmisses = 2;
    eburst_size = state->memory_width * 1;
    mburst_size = 32;
    gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
    ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000;
    ainfo->wcmocc = 0;
    ainfo->wcgocc = 0;
    ainfo->wcvocc = 0;
    ainfo->wcvlwm = 0;
    ainfo->wcglwm = 0;
    ainfo->engine_en = 1;
    ainfo->converged = 1;
    if (ainfo->engine_en)
    {
        ens =  1000000*(state->mem_page_miss + eburst_size/(state->memory_width/8) +refresh_cycle)/state->mclk_khz;
        ainfo->mocc = state->enable_mp ? 0-ens*ainfo->mdrain_rate/1000000 : 0;
        ainfo->vocc = ainfo->vid_en ? 0-ens*ainfo->vdrain_rate/1000000 : 0;
        ainfo->gocc = ainfo->gr_en ? 0-ens*ainfo->gdrain_rate/1000000 : 0;
        ainfo->cur = ENGINE;
        ainfo->first_vacc = 1;
        ainfo->first_gacc = 1;
        ainfo->first_macc = 1;
        nv3_iterate(res_info, state,ainfo);
    }
    if (state->enable_mp)
    {
        mns = 1000000 * (mmisses*state->mem_page_miss + mburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
        ainfo->mocc = state->enable_mp ? 0 : mburst_size - mns*ainfo->mdrain_rate/1000000;
        ainfo->vocc = ainfo->vid_en ? 0 : 0- mns*ainfo->vdrain_rate/1000000;
        ainfo->gocc = ainfo->gr_en ? 0: 0- mns*ainfo->gdrain_rate/1000000;
        ainfo->cur = MPORT;
        ainfo->first_vacc = 1;
        ainfo->first_gacc = 1;
        ainfo->first_macc = 0;
        nv3_iterate(res_info, state,ainfo);
    }
    if (ainfo->gr_en)
    {
        ainfo->first_vacc = 1;
        ainfo->first_gacc = 0;
        ainfo->first_macc = 1;
        gns = 1000000*(gmisses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
        ainfo->gocc = ainfo->gburst_size - gns*ainfo->gdrain_rate/1000000;
        ainfo->vocc = ainfo->vid_en? 0-gns*ainfo->vdrain_rate/1000000 : 0;
        ainfo->mocc = state->enable_mp ?  0-gns*ainfo->mdrain_rate/1000000: 0;
        ainfo->cur = GRAPHICS;
        nv3_iterate(res_info, state,ainfo);
    }
    if (ainfo->vid_en)
    {
        ainfo->first_vacc = 0;
        ainfo->first_gacc = 1;
        ainfo->first_macc = 1;
        vns = 1000000*(vmisses*state->mem_page_miss + ainfo->vburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
        ainfo->vocc = ainfo->vburst_size - vns*ainfo->vdrain_rate/1000000;
        ainfo->gocc = ainfo->gr_en? (0-vns*ainfo->gdrain_rate/1000000) : 0;
        ainfo->mocc = state->enable_mp? 0-vns*ainfo->mdrain_rate/1000000 :0 ;
        ainfo->cur = VIDEO;
        nv3_iterate(res_info, state, ainfo);
    }
    if (ainfo->converged)
    {
        res_info->graphics_lwm = (int)ABS(ainfo->wcglwm) + 16;
        res_info->video_lwm = (int)ABS(ainfo->wcvlwm) + 32;
        res_info->graphics_burst_size = ainfo->gburst_size;
        res_info->video_burst_size = ainfo->vburst_size;
        res_info->graphics_hi_priority = (ainfo->priority == GRAPHICS);
        res_info->media_hi_priority = (ainfo->priority == MPORT);
        if (res_info->video_lwm > 160)
        {
            res_info->graphics_lwm = 256;
            res_info->video_lwm = 128;
            res_info->graphics_burst_size = 64;
            res_info->video_burst_size = 64;
            res_info->graphics_hi_priority = 0;
            res_info->media_hi_priority = 0;
            ainfo->converged = 0;
            return (0);
        }
        if (res_info->video_lwm > 128)
        {
            res_info->video_lwm = 128;
        }
        return (1);
    }
    else
    {
        res_info->graphics_lwm = 256;
        res_info->video_lwm = 128;
        res_info->graphics_burst_size = 64;
        res_info->video_burst_size = 64;
        res_info->graphics_hi_priority = 0;
        res_info->media_hi_priority = 0;
        return (0);
    }
}
static char nv3_get_param(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
{
    int done, g,v, p;
    
    done = 0;
    for (p=0; p < 2; p++)
    {
        for (g=128 ; g > 32; g= g>> 1)
        {
            for (v=128; v >=32; v = v>> 1)
            {
                ainfo->priority = p;
                ainfo->gburst_size = g;     
                ainfo->vburst_size = v;
                done = nv3_arb(res_info, state,ainfo);
                if (done && (g==128))
                    if ((res_info->graphics_lwm + g) > 256)
                        done = 0;
                if (done)
                    goto Done;
            }
        }
    }

 Done:
    return done;
}
static void nv3CalcArbitration 
(
    nv3_fifo_info * res_info,
    nv3_sim_state * state
)
{
    nv3_fifo_info save_info;
    nv3_arb_info ainfo;
    char   res_gr, res_vid;

    ainfo.gr_en = 1;
    ainfo.vid_en = state->enable_video;
    ainfo.vid_only_once = 0;
    ainfo.gr_only_once = 0;
    ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
    ainfo.vdrain_rate = (int) state->pclk_khz * 2;
    if (state->video_scale != 0)
        ainfo.vdrain_rate = ainfo.vdrain_rate/state->video_scale;
    ainfo.mdrain_rate = 33000;
    res_info->rtl_values = 0;
    if (!state->gr_during_vid && state->enable_video)
    {
        ainfo.gr_only_once = 1;
        ainfo.gr_en = 1;
        ainfo.gdrain_rate = 0;
        res_vid = nv3_get_param(res_info, state,  &ainfo);
        res_vid = ainfo.converged;
        save_info.video_lwm = res_info->video_lwm;
        save_info.video_burst_size = res_info->video_burst_size;
        ainfo.vid_en = 1;
        ainfo.vid_only_once = 1;
        ainfo.gr_en = 1;
        ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
        ainfo.vdrain_rate = 0;
        res_gr = nv3_get_param(res_info, state,  &ainfo);
        res_gr = ainfo.converged;
        res_info->video_lwm = save_info.video_lwm;
        res_info->video_burst_size = save_info.video_burst_size;
        res_info->valid = res_gr & res_vid;
    }
    else
    {
        if (!ainfo.gr_en) ainfo.gdrain_rate = 0;
        if (!ainfo.vid_en) ainfo.vdrain_rate = 0;
        res_gr = nv3_get_param(res_info, state,  &ainfo);
        res_info->valid = ainfo.converged;
    }
}
static void nv3UpdateArbitrationSettings
(
    unsigned      VClk, 
    unsigned      pixelDepth, 
    unsigned     *burst,
    unsigned     *lwm,
    RIVA_HW_INST *chip
)
{
    nv3_fifo_info fifo_data;
    nv3_sim_state sim_data;
    unsigned int M, N, P, pll, MClk;
    
    pll = chip->PRAMDAC[0x00000504/4];
    M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
    MClk = (N * chip->CrystalFreqKHz / M) >> P;
    sim_data.pix_bpp        = (char)pixelDepth;
    sim_data.enable_video   = 0;
    sim_data.enable_mp      = 0;
    sim_data.video_scale    = 1;
    sim_data.memory_width   = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
    sim_data.memory_width   = 128;

    sim_data.mem_latency    = 9;
    sim_data.mem_aligned    = 1;
    sim_data.mem_page_miss  = 11;
    sim_data.gr_during_vid  = 0;
    sim_data.pclk_khz       = VClk;
    sim_data.mclk_khz       = MClk;
    nv3CalcArbitration(&fifo_data, &sim_data);
    if (fifo_data.valid)
    {
        int  b = fifo_data.graphics_burst_size >> 4;
        *burst = 0;
        while (b >>= 1) (*burst)++;
        *lwm   = fifo_data.graphics_lwm >> 3;
    }
    else
    {
        *lwm   = 0x24;
        *burst = 0x2;
    }
}

/****************************************************************************\
*                                                                            *
*                          RIVA Mode State Routines                          *
*                                                                            *
\****************************************************************************/

/*
 * Calculate the Video Clock parameters for the PLL.
 */
static int CalcVClock
(
    int           clockIn,
    int          *clockOut,
    int          *mOut,
    int          *nOut,
    int          *pOut,
    RIVA_HW_INST *chip
)
{
    unsigned lowM, highM, highP;
    unsigned DeltaNew, DeltaOld;
    unsigned VClk, Freq;
    unsigned M, N, P;
    
    DeltaOld = 0xFFFFFFFF;

    VClk     = (unsigned)clockIn;
    
    if (chip->CrystalFreqKHz == 13500)
    {
        lowM  = 7;
        highM = 12;
    }                      
    else
    {
        lowM  = 8;
        highM = 13;
    }

    highP = 3;
    for (P = 0; P <= highP; P ++)
    {
        Freq = VClk << P;
        if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
        {
            for (M = lowM; M <= highM; M++)
            {
                N    = (VClk << P) * M / chip->CrystalFreqKHz;
                if(N <= 255) {
                    Freq = (chip->CrystalFreqKHz * N / M) >> P;
                    if (Freq > VClk)
                        DeltaNew = Freq - VClk;
                    else
                        DeltaNew = VClk - Freq;
                    if (DeltaNew < DeltaOld)
                    {
                        *mOut     = M;
                        *nOut     = N;
                        *pOut     = P;
                        *clockOut = Freq;
                        DeltaOld  = DeltaNew;
                    }
                }
            }
        }
    }
    return (DeltaOld != 0xFFFFFFFF);
}
/*
 * Calculate extended mode parameters (SVGA) and save in a 
 * mode state structure.
 */
static void CalcStateExt
(
    RIVA_HW_INST  *chip,
    RIVA_HW_STATE *state,
    int            bpp,
    int            width,
    int            hDisplaySize,
    int            height,
    int            dotClock,
    int		   flags 
)
{
    int pixelDepth, VClk, m, n, p;
    /*
     * Save mode parameters.
     */
    state->bpp    = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
    state->width  = width;
    state->height = height;
    /*
     * Extended RIVA registers.
     */
    pixelDepth = (bpp + 1)/8;
    CalcVClock(dotClock, &VClk, &m, &n, &p, chip);

    nv3UpdateArbitrationSettings(VClk, 
                                 pixelDepth * 8, 
                                 &(state->arbitration0),
                                 &(state->arbitration1),
                                 chip);
    state->cursor0  = 0x00;
    state->cursor1  = 0x78;
    if (flags & V_DBLSCAN)
       state->cursor1 |= 2;
    state->cursor2  = 0x00000000;
    state->pllsel   = 0x10010100;
    state->config   = ((width + 31)/32)
                      | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
                      | 0x1000;
    state->general  = 0x00100100;
    state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;


    state->vpll     = (p << 16) | (n << 8) | m;
    state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
    state->pixel    = pixelDepth > 2   ? 3    : pixelDepth;
    state->offset   = 0;
    state->pitch    = pixelDepth * width;
}
/*
 * Load fixed function state and pre-calculated/stored state.
 */
#define LOAD_FIXED_STATE(tbl,dev)                                       \
    for (i = 0; i < sizeof(tbl##Table##dev)/8; i++)                 \
        chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
#define LOAD_FIXED_STATE_8BPP(tbl,dev)                                  \
    for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++)            \
        chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
#define LOAD_FIXED_STATE_15BPP(tbl,dev)                                 \
    for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++)           \
        chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
#define LOAD_FIXED_STATE_16BPP(tbl,dev)                                 \
    for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++)           \
        chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
#define LOAD_FIXED_STATE_32BPP(tbl,dev)                                 \
    for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++)           \
        chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
static void UpdateFifoState
(
    RIVA_HW_INST  *chip
)
{
}
static void LoadStateExt
(
    RIVA_HW_INST  *chip,
    RIVA_HW_STATE *state
)
{
    int i;

    /*
     * Load HW fixed function state.
     */
    LOAD_FIXED_STATE(Riva,PMC);
    LOAD_FIXED_STATE(Riva,PTIMER);
     /*
      * Make sure frame buffer config gets set before loading PRAMIN.
      */
    chip->PFB[0x00000200/4] = state->config;
    LOAD_FIXED_STATE(nv3,PFIFO);
    LOAD_FIXED_STATE(nv3,PRAMIN);
    LOAD_FIXED_STATE(nv3,PGRAPH);
    switch (state->bpp)
    {
     case 15:
     case 16:
         LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
         LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
         break;
     case 24:
     case 32:
         LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
         LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
         break;
     case 8:
     default:
         LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
        LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
        break;
    }
    for (i = 0x00000; i < 0x00800; i++)
        chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03;
    chip->PGRAPH[0x00000630/4] = state->offset;
    chip->PGRAPH[0x00000634/4] = state->offset;
    chip->PGRAPH[0x00000638/4] = state->offset;
    chip->PGRAPH[0x0000063C/4] = state->offset;
    chip->PGRAPH[0x00000650/4] = state->pitch;
    chip->PGRAPH[0x00000654/4] = state->pitch;
    chip->PGRAPH[0x00000658/4] = state->pitch;
    chip->PGRAPH[0x0000065C/4] = state->pitch;

    LOAD_FIXED_STATE(Riva,FIFO);
    UpdateFifoState(chip);

    /*
     * Load HW mode state.
     */
    VGA_WR08(chip->PCIO, 0x03D4, 0x19);
    VGA_WR08(chip->PCIO, 0x03D5, state->repaint0);
    VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
    VGA_WR08(chip->PCIO, 0x03D5, state->repaint1);
    VGA_WR08(chip->PCIO, 0x03D4, 0x25);
    VGA_WR08(chip->PCIO, 0x03D5, state->screen);
    VGA_WR08(chip->PCIO, 0x03D4, 0x28);
    VGA_WR08(chip->PCIO, 0x03D5, state->pixel);
    VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
    VGA_WR08(chip->PCIO, 0x03D5, state->horiz);
    VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
    VGA_WR08(chip->PCIO, 0x03D5, state->arbitration0);
    VGA_WR08(chip->PCIO, 0x03D4, 0x20);
    VGA_WR08(chip->PCIO, 0x03D5, state->arbitration1);
    VGA_WR08(chip->PCIO, 0x03D4, 0x30);
    VGA_WR08(chip->PCIO, 0x03D5, state->cursor0);
    VGA_WR08(chip->PCIO, 0x03D4, 0x31);
    VGA_WR08(chip->PCIO, 0x03D5, state->cursor1);
    VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
    VGA_WR08(chip->PCIO, 0x03D5, state->cursor2);
    VGA_WR08(chip->PCIO, 0x03D4, 0x39);
    VGA_WR08(chip->PCIO, 0x03D5, state->interlace);

    chip->PRAMDAC[0x00000508/4] = state->vpll;
    chip->PRAMDAC[0x0000050C/4] = state->pllsel;
    chip->PRAMDAC[0x00000600/4]  = state->general;

    /*
     * Turn off VBlank enable and reset.
     */
    chip->PCRTC[0x00000140/4] = 0;
    chip->PCRTC[0x00000100/4] = chip->VBlankBit;
    /*
     * Set interrupt enable.
     */    
    chip->PMC[0x00000140/4]  = chip->EnableIRQ & 0x01;
    /*
     * Set current state pointer.
     */
    chip->CurrentState = state;
    /*
     * Reset FIFO free and empty counts.
     */
    chip->FifoFreeCount  = 0;
    /* Free count from first subchannel */
    chip->FifoEmptyCount = chip->Rop->FifoFree; 
}

static void UnloadStateExt
(
    RIVA_HW_INST  *chip,
    RIVA_HW_STATE *state
)
{
    /*
     * Save current HW state.
     */
    VGA_WR08(chip->PCIO, 0x03D4, 0x19);
    state->repaint0     = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
    state->repaint1     = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x25);
    state->screen       = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x28);
    state->pixel        = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
    state->horiz        = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
    state->arbitration0 = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x20);
    state->arbitration1 = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x30);
    state->cursor0      = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x31);
    state->cursor1      = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
    state->cursor2      = VGA_RD08(chip->PCIO, 0x03D5);
    VGA_WR08(chip->PCIO, 0x03D4, 0x39);
    state->interlace    = VGA_RD08(chip->PCIO, 0x03D5);
    state->vpll         = chip->PRAMDAC[0x00000508/4];
    state->pllsel       = chip->PRAMDAC[0x0000050C/4];
    state->general      = chip->PRAMDAC[0x00000600/4];
    state->config       = chip->PFB[0x00000200/4];
    state->offset       = chip->PGRAPH[0x00000630/4];
    state->pitch        = chip->PGRAPH[0x00000650/4];
}

static void SetStartAddress
(
    RIVA_HW_INST *chip,
    unsigned      start
)
{
    int offset = start >> 2;
    int pan    = (start & 3) << 1;
    unsigned char tmp;

    /*
     * Unlock extended registers.
     */
    chip->LockUnlock(chip, 0);
    /*
     * Set start address.
     */
    VGA_WR08(chip->PCIO, 0x3D4, 0x0D); VGA_WR08(chip->PCIO, 0x3D5, offset);
    offset >>= 8;
    VGA_WR08(chip->PCIO, 0x3D4, 0x0C); VGA_WR08(chip->PCIO, 0x3D5, offset);
    offset >>= 8;
    VGA_WR08(chip->PCIO, 0x3D4, 0x19); tmp = VGA_RD08(chip->PCIO, 0x3D5);
    VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x01F) | (tmp & ~0x1F));
    VGA_WR08(chip->PCIO, 0x3D4, 0x2D); tmp = VGA_RD08(chip->PCIO, 0x3D5);
    VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x60) | (tmp & ~0x60));
    /*
     * 4 pixel pan register.
     */
    offset = VGA_RD08(chip->PCIO, chip->IO + 0x0A);
    VGA_WR08(chip->PCIO, 0x3C0, 0x13);
    VGA_WR08(chip->PCIO, 0x3C0, pan);
}
/****************************************************************************\
*                                                                            *
*                      Probe RIVA Chip Configuration                         *
*                                                                            *
\****************************************************************************/

static void nv3GetConfig
(
    RIVA_HW_INST *chip
)
{
    /*
     * Fill in chip configuration.
     */
    if (chip->PFB[0x00000000/4] & 0x00000020)
    {
        if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
         && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02))
        {        
            /*
             * SDRAM 128 ZX.
             */
            chip->RamBandwidthKBytesPerSec = 800000;
            switch (chip->PFB[0x00000000/4] & 0x03)
            {
                case 2:
                    chip->RamAmountKBytes = 1024 * 4;
                    break;
                case 1:
                    chip->RamAmountKBytes = 1024 * 2;
                    break;
                default:
                    chip->RamAmountKBytes = 1024 * 8;
                    break;
            }
        }            
        else            
        {
            chip->RamBandwidthKBytesPerSec = 1000000;
            chip->RamAmountKBytes          = 1024 * 8;
        }            
    }
    else
    {
        /*
         * SGRAM 128.
         */
        chip->RamBandwidthKBytesPerSec = 1000000;
        switch (chip->PFB[0x00000000/4] & 0x00000003)
        {
            case 0:
                chip->RamAmountKBytes = 1024 * 8;
                break;
            case 2:
                chip->RamAmountKBytes = 1024 * 4;
                break;
            default:
                chip->RamAmountKBytes = 1024 * 2;
                break;
        }
    }        
    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
    chip->CURSOR           = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]);
    chip->VBlankBit        = 0x00000100;
    chip->MaxVClockFreqKHz = 256000;
    /*
     * Set chip functions.
     */
    chip->Busy            = nv3Busy;
    chip->ShowHideCursor  = ShowHideCursor;
    chip->CalcStateExt    = CalcStateExt;
    chip->LoadStateExt    = LoadStateExt;
    chip->UnloadStateExt  = UnloadStateExt;
    chip->SetStartAddress = SetStartAddress;
    chip->LockUnlock      = nv3LockUnlock;
}
int RivaGetConfig
(
    RivaPtr pRiva
)
{
    RIVA_HW_INST *chip = &pRiva->riva;

    nv3GetConfig(chip);
    /*
     * Fill in FIFO pointers.
     */
    chip->Rop    = (RivaRop                 *)&(chip->FIFO[0x00000000/4]);
    chip->Clip   = (RivaClip                *)&(chip->FIFO[0x00002000/4]);
    chip->Patt   = (RivaPattern             *)&(chip->FIFO[0x00004000/4]);
    chip->Pixmap = (RivaPixmap              *)&(chip->FIFO[0x00006000/4]);
    chip->Blt    = (RivaScreenBlt           *)&(chip->FIFO[0x00008000/4]);
    chip->Bitmap = (RivaBitmap              *)&(chip->FIFO[0x0000A000/4]);
    chip->Line   = (RivaLine                *)&(chip->FIFO[0x0000C000/4]);
    return (0);
}


--- NEW FILE: riva_hw.h ---
/***************************************************************************\
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
\***************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h,v 1.25 2003/05/04 01:20:52 mvojkovi Exp $ */
#ifndef __RIVA_HW_H__
#define __RIVA_HW_H__

/*
 * Define supported architectures.
 */
/***************************************************************************\
*                                                                           *
*                             FIFO registers.                               *
*                                                                           *
\***************************************************************************/

/*
 * Raster OPeration. Windows style ROP3.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop;
    U032 reserved01[0x0BB];
    U032 Rop3;
} RivaRop;
/*
 * 8X8 Monochrome pattern.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop;
    U032 reserved01[0x0BD];
    U032 Shape;
    U032 reserved03[0x001];
    U032 Color0;
    U032 Color1;
    U032 Monochrome[2];
} RivaPattern;
/*
 * Scissor clip rectangle.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop;
    U032 reserved01[0x0BB];
    U032 TopLeft;
    U032 WidthHeight;
} RivaClip;
/*
 * 2D filled rectangle.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop[1];
    U032 reserved01[0x0BC];
    U032 Color;
    U032 reserved03[0x03E];
    U032 TopLeft;
    U032 WidthHeight;
} RivaRectangle;
/*
 * 2D screen-screen BLT.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop;
    U032 reserved01[0x0BB];
    U032 TopLeftSrc;
    U032 TopLeftDst;
    U032 WidthHeight;
} RivaScreenBlt;
/*
 * 2D pixel BLT.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop[1];
    U032 reserved01[0x0BC];
    U032 TopLeft;
    U032 WidthHeight;
    U032 WidthHeightIn;
    U032 reserved02[0x03C];
    U032 Pixels;
} RivaPixmap;
/*
 * Filled rectangle combined with monochrome expand.  Useful for glyphs.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop;
    U032 reserved01[0x0BB];
    U032 reserved03[(0x040)-1];
    U032 Color1A;
    struct
    {
        U032 TopLeft;
        U032 WidthHeight;
    } UnclippedRectangle[64];
    U032 reserved04[(0x080)-3];
    struct
    {
        U032 TopLeft;
        U032 BottomRight;
    } ClipB;
    U032 Color1B;
    struct
    {
        U032 TopLeft;
        U032 BottomRight;
    } ClippedRectangle[64];
    U032 reserved05[(0x080)-5];
    struct
    {
        U032 TopLeft;
        U032 BottomRight;
    } ClipC;
    U032 Color1C;
    U032 WidthHeightC;
    U032 PointC;
    U032 MonochromeData1C;
    U032 reserved06[(0x080)+121];
    struct
    {
        U032 TopLeft;
        U032 BottomRight;
    } ClipD;
    U032 Color1D;
    U032 WidthHeightInD;
    U032 WidthHeightOutD;
    U032 PointD;
    U032 MonochromeData1D;
    U032 reserved07[(0x080)+120];
    struct
    {
        U032 TopLeft;
        U032 BottomRight;
    } ClipE;
    U032 Color0E;
    U032 Color1E;
    U032 WidthHeightInE;
    U032 WidthHeightOutE;
    U032 PointE;
    U032 MonochromeData01E;
} RivaBitmap;
/*
 * 2D line.
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop[1];
    U032 reserved01[0x0BC];
    U032 Color;             /* source color               0304-0307*/
    U032 Reserved02[0x03e];
    struct {                /* start aliased methods in array   0400-    */
        U032 point0;        /* y_x S16_S16 in pixels            0-   3*/
        U032 point1;        /* y_x S16_S16 in pixels            4-   7*/
    } Lin[16];              /* end of aliased methods in array      -047f*/
    struct {                /* start aliased methods in array   0480-    */
        U032 point0X;       /* in pixels, 0 at left                0-   3*/
        U032 point0Y;       /* in pixels, 0 at top                 4-   7*/
        U032 point1X;       /* in pixels, 0 at left                8-   b*/
        U032 point1Y;       /* in pixels, 0 at top                 c-   f*/
    } Lin32[8];             /* end of aliased methods in array      -04ff*/
    U032 PolyLin[32];       /* y_x S16_S16 in pixels         0500-057f*/
    struct {                /* start aliased methods in array   0580-    */
        U032 x;             /* in pixels, 0 at left                0-   3*/
        U032 y;             /* in pixels, 0 at top                 4-   7*/
    } PolyLin32[16];        /* end of aliased methods in array      -05ff*/
    struct {                /* start aliased methods in array   0600-    */
        U032 color;         /* source color                     0-   3*/
        U032 point;         /* y_x S16_S16 in pixels            4-   7*/
    } ColorPolyLin[16];     /* end of aliased methods in array      -067f*/
} RivaLine;
/*
 * 2D/3D surfaces
 */
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop;
    U032 reserved01[0x0BE];
    U032 Offset;
} RivaSurface;
typedef volatile struct
{
    U032 reserved00[4];
    U016 FifoFree;
    U016 Nop;
    U032 reserved01[0x0BD];
    U032 Pitch;
    U032 RenderBufferOffset;
    U032 ZBufferOffset;
} RivaSurface3D;
    
/***************************************************************************\
*                                                                           *
*                        Virtualized RIVA H/W interface.                    *
*                                                                           *
\***************************************************************************/

#define FP_ENABLE  1
#define FP_DITHER  2

struct _riva_hw_inst;
struct _riva_hw_state;
/*
 * Virtialized chip interface. Makes RIVA 128 and TNT look alike.
 */
typedef struct _riva_hw_inst
{
    /*
     * Chip specific settings.
     */
    U032 CrystalFreqKHz;
    U032 RamAmountKBytes;
    U032 MaxVClockFreqKHz;
    U032 RamBandwidthKBytesPerSec;
    U032 EnableIRQ;
    U032 IO;
    U032 VBlankBit;
    U032 FifoFreeCount;
    U032 FifoEmptyCount;
    U032 CursorStart;
    /*
     * Non-FIFO registers.
     */
    volatile U032 *PCRTC;
    volatile U032 *PFB;
    volatile U032 *PFIFO;
    volatile U032 *PGRAPH;
    volatile U032 *PEXTDEV;
    volatile U032 *PTIMER;
    volatile U032 *PMC;
    volatile U032 *PRAMIN;
    volatile U032 *FIFO;
    volatile U032 *CURSOR;
    volatile U008 *PCIO;
    volatile U008 *PVIO;
    volatile U008 *PDIO;
    volatile U032 *PRAMDAC;
    /*
     * Common chip functions.
     */
    int  (*Busy)(struct _riva_hw_inst *);
    void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int,int);
    void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
    void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
    void (*SetStartAddress)(struct _riva_hw_inst *,U032);
    int  (*ShowHideCursor)(struct _riva_hw_inst *,int);
    void (*LockUnlock)(struct _riva_hw_inst *, int);
    /*
     * Current extended mode settings.
     */
    struct _riva_hw_state *CurrentState;
    /*
     * FIFO registers.
     */
    RivaRop                 *Rop;
    RivaPattern             *Patt;
    RivaClip                *Clip;
    RivaPixmap              *Pixmap;
    RivaScreenBlt           *Blt;
    RivaBitmap              *Bitmap;
    RivaLine                *Line;
} RIVA_HW_INST;
/*
 * Extended mode state information.
 */
typedef struct _riva_hw_state
{
    U032 bpp;
    U032 width;
    U032 height;
    U032 interlace;
    U032 repaint0;
    U032 repaint1;
    U032 screen;
    U032 extra;
    U032 pixel;
    U032 horiz;
    U032 arbitration0;
    U032 arbitration1;
    U032 vpll;
    U032 pllsel;
    U032 general;
    U032 config;
    U032 cursorConfig;
    U032 cursor0;
    U032 cursor1;
    U032 cursor2;
    U032 offset;
    U032 pitch;
} RIVA_HW_STATE;

/*
 * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
 */

#define RIVA_FIFO_FREE(hwinst,hwptr,cnt)                           \
{                                                                  \
   while ((hwinst).FifoFreeCount < (cnt)) {                          \
        mem_barrier(); \
        mem_barrier(); \
	(hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2;        \
   } \
   (hwinst).FifoFreeCount -= (cnt);                                \
}
#define RIVA_BUSY(hwinst) \
{ \
   mem_barrier(); \
   while ((hwinst).Busy(&(hwinst))); \
}
#endif /* __RIVA_HW_H__ */


--- NEW FILE: riva_include.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_include.h $ */

#ifndef __RIVA_INCLUDE_H__
#define __RIVA_INCLUDE_H__

/* All drivers should typically include these */
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "xf86_ansic.h"
#include "compiler.h"

/* Drivers for PCI hardware need this */
#include "xf86PciInfo.h"

/* Drivers that need to access the PCI config space directly need this */
#include "xf86Pci.h"

/* All drivers initialising the SW cursor need this */
#include "mipointer.h"

/* All drivers implementing backing store need this */
#include "mibstore.h"

#include "micmap.h"

#include "xf86DDC.h"

#include "vbe.h"

#include "xf86RAC.h"

#include "riva_const.h"

#include "dixstruct.h"
#include "scrnintstr.h"

#include "fb.h"

#include "xaa.h"
#include "xf86cmap.h"
#include "shadowfb.h"
#include "fbdevhw.h"

#include "xf86xv.h"
#include "X11/extensions/Xv.h"

#include "vgaHW.h"

#include "xf86Cursor.h"
#include "xf86DDC.h"

#include "region.h"

#include "riva_local.h"
#include "riva_type.h"
#include "riva_proto.h"

#endif /* __RIVA_INCLUDE_H__ */

--- NEW FILE: riva_local.h ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_local.h,v 1.1tsi Exp $ */

#ifndef __RIVA_LOCAL_H__
#define __RIVA_LOCAL_H__

/*
 * This file includes any environment or machine specific values to access the
 * HW.  Put all affected includes, typdefs, etc. here so the riva_hw.* files
 * can stay generic in nature.
 */ 
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86_OSproc.h"

/*
 * Typedefs to force certain sized values.
 */
typedef unsigned char  U008;
typedef unsigned short U016;
typedef unsigned int   U032;

/*
 * HW access macros.  These assume memory-mapped I/O, and not normal I/O space.
 */
#define RIVA_WR08(p,i,d)  MMIO_OUT8((pointer)(p), (i), (d))
#define RIVA_RD08(p,i)    MMIO_IN8((pointer)(p), (i))
#define RIVA_WR16(p,i,d)  MMIO_OUT16((pointer)(p), (i), (d))
#define RIVA_RD16(p,i)    MMIO_IN16((pointer)(p), (i))
#define RIVA_WR32(p,i,d)  MMIO_OUT32((pointer)(p), (i), (d))
#define RIVA_RD32(p,i)    MMIO_IN32((pointer)(p), (i))

/* VGA I/O is now always done through MMIO */
#define VGA_WR08(p,i,d) RIVA_WR08(p,i,d)
#define VGA_RD08(p,i)   RIVA_RD08(p,i)

#endif /* __RIVA_LOCAL_H__ */

--- NEW FILE: riva_proto.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_proto.h $ */

#ifndef __RIVA_PROTO_H__
#define __RIVA_PROTO_H__

/* in riva_driver.c */
Bool    RivaSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
void    RivaAdjustFrame(int scrnIndex, int x, int y, int flags);
Bool    RivaI2CInit(ScrnInfoPtr pScrn);
const   OptionInfoRec * RivaAvailableOptions(int chipid, int busid);
Bool    RivaGetScrnInfoRec(PciChipsets *chips, int chip);

/* in riva_dac.c */
Bool    RivaDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
void    RivaDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
                  RivaRegPtr rivaReg, Bool saveFonts);
void    RivaDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
                     RivaRegPtr rivaReg, Bool restoreFonts);
void    RivaDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
                         LOCO *colors, VisualPtr pVisual );
Bool    RivaDACi2cInit(ScrnInfoPtr pScrn);


/* in riva_setup.c */
void    RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter);
void    Riva3Setup(ScrnInfoPtr pScrn);

/* in riva_cursor.c */
Bool    RivaCursorInit(ScreenPtr pScreen);

/* in riva_xaa.c */
Bool    RivaAccelInit(ScreenPtr pScreen);
void    RivaSync(ScrnInfoPtr pScrn);
void    RivaResetGraphics(ScrnInfoPtr pScrn);

/* in riva_dga.c */
Bool    RivaDGAInit(ScreenPtr pScreen);


#endif /* __RIVA_PROTO_H__ */


--- NEW FILE: riva_setup.c ---
/*
 * Copyright 1996-1997  David J. McKay
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
   <jpaana at s2.org> */

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_setup.c $ */

#include "riva_include.h"

/*
 * Override VGA I/O routines.
 */
static void RivaWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
    VGA_WR08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET,  value);
}
static CARD8 RivaReadCrtc(vgaHWPtr pVga, CARD8 index)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
    return (VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
}
static void RivaWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PVIO, VGA_GRAPH_INDEX, index);
    VGA_WR08(pRiva->riva.PVIO, VGA_GRAPH_DATA,  value);
}
static CARD8 RivaReadGr(vgaHWPtr pVga, CARD8 index)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PVIO, VGA_GRAPH_INDEX, index);
    return (VGA_RD08(pRiva->riva.PVIO, VGA_GRAPH_DATA));
}
static void RivaWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PVIO, VGA_SEQ_INDEX, index);
    VGA_WR08(pRiva->riva.PVIO, VGA_SEQ_DATA,  value);
}
static CARD8 RivaReadSeq(vgaHWPtr pVga, CARD8 index)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PVIO, VGA_SEQ_INDEX, index);
    return (VGA_RD08(pRiva->riva.PVIO, VGA_SEQ_DATA));
}
static void RivaWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    if (pVga->paletteEnabled)
        index &= ~0x20;
    else
        index |= 0x20;
    VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX,  index);
    VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_DATA_W, value);
}
static CARD8 RivaReadAttr(vgaHWPtr pVga, CARD8 index)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    if (pVga->paletteEnabled)
        index &= ~0x20;
    else
        index |= 0x20;
    VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX, index);
    return (VGA_RD08(pRiva->riva.PCIO, VGA_ATTR_DATA_R));
}
static void RivaWriteMiscOut(vgaHWPtr pVga, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PVIO, VGA_MISC_OUT_W, value);
}
static CARD8 RivaReadMiscOut(vgaHWPtr pVga)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    return (VGA_RD08(pRiva->riva.PVIO, VGA_MISC_OUT_R));
}
static void RivaEnablePalette(vgaHWPtr pVga)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX, 0x00);
    pVga->paletteEnabled = TRUE;
}
static void RivaDisablePalette(vgaHWPtr pVga)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    volatile CARD8 tmp;

    tmp = VGA_RD08(pRiva->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
    VGA_WR08(pRiva->riva.PCIO, VGA_ATTR_INDEX, 0x20);
    pVga->paletteEnabled = FALSE;
}
static void RivaWriteDacMask(vgaHWPtr pVga, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PDIO, VGA_DAC_MASK, value);
}
static CARD8 RivaReadDacMask(vgaHWPtr pVga)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    return (VGA_RD08(pRiva->riva.PDIO, VGA_DAC_MASK));
}
static void RivaWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PDIO, VGA_DAC_READ_ADDR, value);
}
static void RivaWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PDIO, VGA_DAC_WRITE_ADDR, value);
}
static void RivaWriteDacData(vgaHWPtr pVga, CARD8 value)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    VGA_WR08(pRiva->riva.PDIO, VGA_DAC_DATA, value);
}
static CARD8 RivaReadDacData(vgaHWPtr pVga)
{
    RivaPtr pRiva = (RivaPtr)pVga->MMIOBase;
    return (VGA_RD08(pRiva->riva.PDIO, VGA_DAC_DATA));
}



static xf86MonPtr 
RivaProbeDDC (ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    xf86MonPtr MonInfo = NULL;

    if(!pRiva->I2C) return NULL;

    pRiva->DDCBase = 0x3e;

    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probing for EDID...\n");

    if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pRiva->I2C))) {
       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                  "  ... found one\n");
       xf86PrintEDID( MonInfo );
    } else {
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
                  "  ... none found\n");
    }

    return MonInfo;
}

void
Riva3Setup(ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    vgaHWPtr pVga = VGAHWPTR(pScrn);
    CARD32 regBase = pRiva->IOAddress;
    CARD32 frameBase = pRiva->FbAddress;
    xf86MonPtr monitor;
    int mmioFlags;
    
    pRiva->Save = RivaDACSave;
    pRiva->Restore = RivaDACRestore;
    pRiva->ModeInit = RivaDACInit;

    pRiva->Dac.LoadPalette = RivaDACLoadPalette;

    /*
     * Override VGA I/O routines.
     */
    pVga->writeCrtc         = RivaWriteCrtc;
    pVga->readCrtc          = RivaReadCrtc;
    pVga->writeGr           = RivaWriteGr;
    pVga->readGr            = RivaReadGr;
    pVga->writeAttr         = RivaWriteAttr;
    pVga->readAttr          = RivaReadAttr;
    pVga->writeSeq          = RivaWriteSeq;
    pVga->readSeq           = RivaReadSeq;
    pVga->writeMiscOut      = RivaWriteMiscOut;
    pVga->readMiscOut       = RivaReadMiscOut;
    pVga->enablePalette     = RivaEnablePalette;
    pVga->disablePalette    = RivaDisablePalette;
    pVga->writeDacMask      = RivaWriteDacMask;
    pVga->readDacMask       = RivaReadDacMask;
    pVga->writeDacWriteAddr = RivaWriteDacWriteAddr;
    pVga->writeDacReadAddr  = RivaWriteDacReadAddr;
    pVga->writeDacData      = RivaWriteDacData;
    pVga->readDacData       = RivaReadDacData;
    /*
     * Note: There are different pointers to the CRTC/AR and GR/SEQ registers.
     * Bastardize the intended uses of these to make it work.
     */
    pVga->MMIOBase   = (CARD8 *)pRiva;
    pVga->MMIOOffset = 0;
    
    /*
     * No IRQ in use.
     */
    pRiva->riva.EnableIRQ = 0;
    pRiva->riva.IO      = VGA_IOBASE_COLOR;

    mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;

    pRiva->riva.PRAMDAC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00680000, 0x00003000);
    pRiva->riva.PFB     = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00100000, 0x00001000);
    pRiva->riva.PFIFO   = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00002000, 0x00002000);
    pRiva->riva.PGRAPH  = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00400000, 0x00002000);
    pRiva->riva.PEXTDEV = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00101000, 0x00001000);
    pRiva->riva.PTIMER  = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00009000, 0x00001000);
    pRiva->riva.PMC     = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00000000, 0x00009000);
    pRiva->riva.FIFO    = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                      regBase+0x00800000, 0x00010000);
    pRiva->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pRiva->PciTag,
                                     frameBase+0x00C00000, 0x00008000);

    /*
     * These registers are read/write as 8 bit values.  Probably have to map
     * sparse on alpha.
     */
    pRiva->riva.PCIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
                                           pRiva->PciTag, regBase+0x00601000,
                                           0x00003000);
    pRiva->riva.PDIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
                                           pRiva->PciTag, regBase+0x00681000,
                                           0x00003000);
    pRiva->riva.PVIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
                                           pRiva->PciTag, regBase+0x000C0000,
                                           0x00001000);

    pRiva->riva.PCRTC = pRiva->riva.PGRAPH;

    RivaGetConfig(pRiva);

    pRiva->riva.LockUnlock(&pRiva->riva, 0);

    RivaI2CInit(pScrn);

    monitor = RivaProbeDDC(pScrn);

    if(monitor)
      xf86SetDDCproperties(pScrn, monitor);

    pRiva->Dac.maxPixelClock = pRiva->riva.MaxVClockFreqKHz;
}

--- NEW FILE: riva_shadow.c ---
/*
   Copyright (c) 1999,  The XFree86 Project Inc. 
   Written by Mark Vojkovich <markv at valinux.com>
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_shadow.c $ */

#include "riva_local.h"
#include "riva_include.h"
#include "riva_type.h"
#include "shadowfb.h"
#include "servermd.h"


void
RivaRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    int width, height, Bpp, FBPitch;
    unsigned char *src, *dst;
   
    Bpp = pScrn->bitsPerPixel >> 3;
    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);

    while(num--) {
	width = (pbox->x2 - pbox->x1) * Bpp;
	height = pbox->y2 - pbox->y1;
	src = pRiva->ShadowPtr + (pbox->y1 * pRiva->ShadowPitch) + 
						(pbox->x1 * Bpp);
	dst = pRiva->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);

	while(height--) {
	    memcpy(dst, src, width);
	    dst += FBPitch;
	    src += pRiva->ShadowPitch;
	}
	
	pbox++;
    }
} 

void
RivaPointerMoved(int index, int x, int y)
{
    ScrnInfoPtr pScrn = xf86Screens[index];
    RivaPtr pRiva = RivaPTR(pScrn);
    int newX, newY;

    if(pRiva->Rotate == 1) {
	newX = pScrn->pScreen->height - y - 1;
	newY = x;
    } else {
	newX = y;
	newY = pScrn->pScreen->width - x - 1;
    }

    (*pRiva->PointerMoved)(index, newX, newY);
}

void
RivaRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    int count, width, height, y1, y2, dstPitch, srcPitch;
    CARD8 *dstPtr, *srcPtr, *src;
    CARD32 *dst;

    dstPitch = pScrn->displayWidth;
    srcPitch = -pRiva->Rotate * pRiva->ShadowPitch;

    while(num--) {
	width = pbox->x2 - pbox->x1;
	y1 = pbox->y1 & ~3;
	y2 = (pbox->y2 + 3) & ~3;
	height = (y2 - y1) >> 2;  /* in dwords */

	if(pRiva->Rotate == 1) {
	    dstPtr = pRiva->FbStart + 
			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
	    srcPtr = pRiva->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
	} else {
	    dstPtr = pRiva->FbStart + 
			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
	    srcPtr = pRiva->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
	}

	while(width--) {
	    src = srcPtr;
	    dst = (CARD32*)dstPtr;
	    count = height;
	    while(count--) {
		*(dst++) = src[0] | (src[srcPitch] << 8) | 
					(src[srcPitch * 2] << 16) | 
					(src[srcPitch * 3] << 24);
		src += srcPitch * 4;
	    }
	    srcPtr += pRiva->Rotate;
	    dstPtr += dstPitch;
	}

	pbox++;
    }
} 


void
RivaRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    int count, width, height, y1, y2, dstPitch, srcPitch;
    CARD16 *dstPtr, *srcPtr, *src;
    CARD32 *dst;

    dstPitch = pScrn->displayWidth;
    srcPitch = -pRiva->Rotate * pRiva->ShadowPitch >> 1;

    while(num--) {
	width = pbox->x2 - pbox->x1;
	y1 = pbox->y1 & ~1;
	y2 = (pbox->y2 + 1) & ~1;
	height = (y2 - y1) >> 1;  /* in dwords */

	if(pRiva->Rotate == 1) {
	    dstPtr = (CARD16*)pRiva->FbStart + 
			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
	    srcPtr = (CARD16*)pRiva->ShadowPtr + 
			((1 - y2) * srcPitch) + pbox->x1;
	} else {
	    dstPtr = (CARD16*)pRiva->FbStart + 
			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
	    srcPtr = (CARD16*)pRiva->ShadowPtr + 
			(y1 * srcPitch) + pbox->x2 - 1;
	}

	while(width--) {
	    src = srcPtr;
	    dst = (CARD32*)dstPtr;
	    count = height;
	    while(count--) {
		*(dst++) = src[0] | (src[srcPitch] << 16);
		src += srcPitch * 2;
	    }
	    srcPtr += pRiva->Rotate;
	    dstPtr += dstPitch;
	}

	pbox++;
    }
}


void
RivaRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    int count, width, height, dstPitch, srcPitch;
    CARD32 *dstPtr, *srcPtr, *src, *dst;

    dstPitch = pScrn->displayWidth;
    srcPitch = -pRiva->Rotate * pRiva->ShadowPitch >> 2;

    while(num--) {
	width = pbox->x2 - pbox->x1;
	height = pbox->y2 - pbox->y1;

	if(pRiva->Rotate == 1) {
	    dstPtr = (CARD32*)pRiva->FbStart + 
			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
	    srcPtr = (CARD32*)pRiva->ShadowPtr + 
			((1 - pbox->y2) * srcPitch) + pbox->x1;
	} else {
	    dstPtr = (CARD32*)pRiva->FbStart + 
			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
	    srcPtr = (CARD32*)pRiva->ShadowPtr + 
			(pbox->y1 * srcPitch) + pbox->x2 - 1;
	}

	while(width--) {
	    src = srcPtr;
	    dst = dstPtr;
	    count = height;
	    while(count--) {
		*(dst++) = *src;
		src += srcPitch;
	    }
	    srcPtr += pRiva->Rotate;
	    dstPtr += dstPitch;
	}

	pbox++;
    }
}




--- NEW FILE: riva_tbl.h ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h,v 1.9 2002/01/30 01:35:03 mvojkovi Exp $ */


/*
 * RIVA Fixed Functionality Init Tables.
 */
static unsigned RivaTablePMC[][2] =
{
    {0x00000050, 0x00000000},
    {0x00000080, 0xFFFF00FF},
    {0x00000080, 0xFFFFFFFF}
};
static unsigned RivaTablePTIMER[][2] =
{
    {0x00000080, 0x00000008},
    {0x00000084, 0x00000003},
    {0x00000050, 0x00000000},
    {0x00000040, 0xFFFFFFFF}
};
static unsigned RivaTableFIFO[][2] =
{
    {0x00000000, 0x80000000},
    {0x00000800, 0x80000001},
    {0x00001000, 0x80000002},
    {0x00001800, 0x80000010},
    {0x00002000, 0x80000011},
    {0x00002800, 0x80000012},
    {0x00003000, 0x80000016},
    {0x00003800, 0x80000013}
};
static unsigned nv3TablePFIFO[][2] =
{
    {0x00000140, 0x00000000},
    {0x00000480, 0x00000000},
    {0x00000490, 0x00000000},
    {0x00000494, 0x00000000},
    {0x00000481, 0x00000000},
    {0x00000084, 0x00000000},
    {0x00000086, 0x00002000},
    {0x00000085, 0x00002200},
    {0x00000484, 0x00000000},
    {0x0000049C, 0x00000000},
    {0x00000104, 0x00000000},
    {0x00000108, 0x00000000},
    {0x00000100, 0x00000000},
    {0x000004A0, 0x00000000},
    {0x000004A4, 0x00000000},
    {0x000004A8, 0x00000000},
    {0x000004AC, 0x00000000},
    {0x000004B0, 0x00000000},
    {0x000004B4, 0x00000000},
    {0x000004B8, 0x00000000},
    {0x000004BC, 0x00000000},
    {0x00000050, 0x00000000},
    {0x00000040, 0xFFFFFFFF},
    {0x00000480, 0x00000001},
    {0x00000490, 0x00000001},
    {0x00000140, 0x00000001}
};
static unsigned nv3TablePGRAPH[][2] =
{
    {0x00000020, 0x1230001F},
    {0x00000021, 0x10113000},
    {0x00000022, 0x1131F101},
    {0x00000023, 0x0100F531},
    {0x00000060, 0x00000000},
    {0x00000065, 0x00000000},
    {0x00000068, 0x00000000},
    {0x00000069, 0x00000000},
    {0x0000006A, 0x00000000},
    {0x0000006B, 0x00000000},
    {0x0000006C, 0x00000000},
    {0x0000006D, 0x00000000},
    {0x0000006E, 0x00000000},
    {0x0000006F, 0x00000000},
    {0x000001A8, 0x00000000},
    {0x00000440, 0xFFFFFFFF},
    {0x00000480, 0x00000001},
    {0x000001A0, 0x00000000},
    {0x000001A2, 0x00000000},
    {0x0000018A, 0xFFFFFFFF},
    {0x00000190, 0x00000000},
    {0x00000142, 0x00000000},
    {0x00000154, 0x00000000},
    {0x00000155, 0xFFFFFFFF},
    {0x00000156, 0x00000000},
    {0x00000157, 0xFFFFFFFF},
    {0x00000064, 0x10010002},
    {0x00000050, 0x00000000},
    {0x00000051, 0x00000000},
    {0x00000040, 0xFFFFFFFF},
    {0x00000041, 0xFFFFFFFF},
    {0x00000440, 0xFFFFFFFF},
    {0x000001A9, 0x00000001}
};
static unsigned nv3TablePGRAPH_8BPP[][2] =
{
    {0x000001AA, 0x00001111}
};
static unsigned nv3TablePGRAPH_15BPP[][2] =
{
    {0x000001AA, 0x00002222}
};
static unsigned nv3TablePGRAPH_32BPP[][2] =
{
    {0x000001AA, 0x00003333}
};
static unsigned nv3TablePRAMIN[][2] =
{
    {0x00000500, 0x00010000},
    {0x00000501, 0x007FFFFF},
    {0x00000200, 0x80000000},
    {0x00000201, 0x00C20341},
    {0x00000204, 0x80000001},
    {0x00000205, 0x00C50342},
    {0x00000208, 0x80000002},
    {0x00000209, 0x00C60343},
    {0x0000020C, 0x80000003},
    {0x0000020D, 0x00DC0348},
    {0x00000210, 0x80000004},
    {0x00000211, 0x00DC0349},
    {0x00000214, 0x80000005},
    {0x00000215, 0x00DC034A},
    {0x00000218, 0x80000006},
    {0x00000219, 0x00DC034B},
    {0x00000240, 0x80000010},
    {0x00000241, 0x00D10344},
    {0x00000244, 0x80000011},
    {0x00000245, 0x00D00345},
    {0x00000248, 0x80000012},
    {0x00000249, 0x00CC0346},
    {0x0000024C, 0x80000013},
    {0x0000024D, 0x00D70347},
    {0x00000258, 0x80000016},
    {0x00000259, 0x00CA034C},
    {0x00000D05, 0x00000000},
    {0x00000D06, 0x00000000},
    {0x00000D07, 0x00000000},
    {0x00000D09, 0x00000000},
    {0x00000D0A, 0x00000000},
    {0x00000D0B, 0x00000000},
    {0x00000D0D, 0x00000000},
    {0x00000D0E, 0x00000000},
    {0x00000D0F, 0x00000000},
    {0x00000D11, 0x00000000},
    {0x00000D12, 0x00000000},
    {0x00000D13, 0x00000000},
    {0x00000D15, 0x00000000},
    {0x00000D16, 0x00000000},
    {0x00000D17, 0x00000000},
    {0x00000D19, 0x00000000},
    {0x00000D1A, 0x00000000},
    {0x00000D1B, 0x00000000},
    {0x00000D1D, 0x00000140},
    {0x00000D1E, 0x00000000},
    {0x00000D1F, 0x00000000},
    {0x00000D20, 0x10100200},
    {0x00000D21, 0x00000000},
    {0x00000D22, 0x00000000},
    {0x00000D23, 0x00000000},
    {0x00000D24, 0x10210200},
    {0x00000D25, 0x00000000},
    {0x00000D26, 0x00000000},
    {0x00000D27, 0x00000000},
    {0x00000D28, 0x10420200},
    {0x00000D29, 0x00000000},
    {0x00000D2A, 0x00000000},
    {0x00000D2B, 0x00000000},
    {0x00000D2C, 0x10830200},
    {0x00000D2D, 0x00000000},
    {0x00000D2E, 0x00000000},
    {0x00000D2F, 0x00000000},
    {0x00000D31, 0x00000000},
    {0x00000D32, 0x00000000},
    {0x00000D33, 0x00000000}
};
static unsigned nv3TablePRAMIN_8BPP[][2] =
{
    /*           0xXXXXX3XX For  MSB mono format */
    /*           0xXXXXX2XX For  LSB mono format */
    {0x00000D04, 0x10110203},
    {0x00000D08, 0x10110203},
    {0x00000D0C, 0x1011020B},
    {0x00000D10, 0x10118203},
    {0x00000D14, 0x10110203},
    {0x00000D18, 0x10110203},
    {0x00000D1C, 0x10419208},
    {0x00000D30, 0x10118203}
};
static unsigned nv3TablePRAMIN_15BPP[][2] =
{
    /*           0xXXXXX2XX For  MSB mono format */
    /*           0xXXXXX3XX For  LSB mono format */
    {0x00000D04, 0x10110200},
    {0x00000D08, 0x10110200},
    {0x00000D0C, 0x10110208},
    {0x00000D10, 0x10118200},
    {0x00000D14, 0x10110200},
    {0x00000D18, 0x10110200},
    {0x00000D1C, 0x10419208},
    {0x00000D30, 0x10118200}
};
static unsigned nv3TablePRAMIN_32BPP[][2] =
{
    /*           0xXXXXX3XX For  MSB mono format */
    /*           0xXXXXX2XX For  LSB mono format */
    {0x00000D04, 0x10110201},
    {0x00000D08, 0x10110201},
    {0x00000D0C, 0x10110209},
    {0x00000D10, 0x10118201},
    {0x00000D14, 0x10110201},
    {0x00000D18, 0x10110201},
    {0x00000D1C, 0x10419208},
    {0x00000D30, 0x10118201}
};


--- NEW FILE: riva_type.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_type.h $ */

#ifndef __Riva_STRUCT_H__
#define __Riva_STRUCT_H__

#include "riva_hw.h"
#include "colormapst.h"
#include "vgaHW.h"
#include "xaa.h"
#include "xf86Cursor.h"
#include "xf86int10.h"


#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1)  << (b))
#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
#define SetBF(mask,value) ((value) << (0?mask))
#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
#define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
#define SetBit(n) (1<<(n))
#define Set8Bits(value) ((value)&0xff)

typedef RIVA_HW_STATE* RivaRegPtr;

typedef struct {
    Bool        isHwCursor;
    int         CursorMaxWidth;
    int         CursorMaxHeight;
    int         CursorFlags;
    int         CursorOffscreenMemSize;
    Bool        (*UseHWCursor)(ScreenPtr, CursorPtr);
    void        (*LoadCursorImage)(ScrnInfoPtr, unsigned char*);
    void        (*ShowCursor)(ScrnInfoPtr);
    void        (*HideCursor)(ScrnInfoPtr);
    void        (*SetCursorPosition)(ScrnInfoPtr, int, int);
    void        (*SetCursorColors)(ScrnInfoPtr, int, int);
    long        maxPixelClock;
    void        (*LoadPalette)(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
    void        (*Save)(ScrnInfoPtr, vgaRegPtr, RivaRegPtr, Bool);
    void        (*Restore)(ScrnInfoPtr, vgaRegPtr, RivaRegPtr, Bool);
    Bool        (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
} RivaRamdacRec, *RivaRamdacPtr;

typedef struct {
    int bitsPerPixel;
    int depth;
    int displayWidth;
    rgb weight;
    DisplayModePtr mode;
} RivaFBLayout;

typedef struct {
    RIVA_HW_INST        riva;
    RIVA_HW_STATE       SavedReg;
    RIVA_HW_STATE       ModeReg;
    EntityInfoPtr       pEnt;
    pciVideoPtr         PciInfo;
    PCITAG              PciTag;
    xf86AccessRec       Access;
    int                 ChipRev;
    Bool                Primary;
    CARD32              IOAddress;
    unsigned long       FbAddress;
    int                 FbBaseReg;
    unsigned char *     IOBase;
    unsigned char *     FbBase;
    unsigned char *     FbStart;
    long                FbMapSize;
    long                FbUsableSize;
    RivaRamdacRec         Dac;
    Bool                NoAccel;
    Bool                HWCursor;
    Bool                ShowCache;
    Bool                ShadowFB;
    unsigned char *     ShadowPtr;
    int                 ShadowPitch;
    int                 MinClock;
    int                 MaxClock;
    XAAInfoRecPtr       AccelInfoRec;
    xf86CursorInfoPtr   CursorInfoRec;
    DGAModePtr          DGAModes;
    int                 numDGAModes;
    Bool                DGAactive;
    int                 DGAViewportStatus;
    void                (*Save)(ScrnInfoPtr, vgaRegPtr, RivaRegPtr, Bool);
    void                (*Restore)(ScrnInfoPtr, vgaRegPtr, RivaRegPtr, Bool);
    Bool                (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
    void		(*PointerMoved)(int index, int x, int y);
    CloseScreenProcPtr  CloseScreen;
    Bool                FBDev;
    /* Color expansion */
    unsigned char       *expandBuffer;
    unsigned char       *expandFifo;
    int                 expandWidth;
    int                 expandRows;
    CARD32		FgColor;
    CARD32		BgColor;
    int			Rotate;
    RivaFBLayout		CurrentLayout;
    /* Cursor */
    CARD32              curFg, curBg;
    CARD32              curImage[64];
    /* Misc flags */
    unsigned int        opaqueMonochrome;
    int                 currentRop;
    /* I2C / DDC */
    I2CBusPtr           I2C;
    xf86Int10InfoPtr    pInt;
    OptionInfoPtr	Options;
    unsigned char       DDCBase;
} RivaRec, *RivaPtr;

#define RivaPTR(p) ((RivaPtr)((p)->driverPrivate))

void RivaRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void RivaRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void RivaRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void RivaRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void RivaPointerMoved(int index, int x, int y);

int RivaGetConfig(RivaPtr);

#endif /* __Riva_STRUCT_H__ */

--- NEW FILE: riva_xaa.c ---
 /***************************************************************************\
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
|*     international laws.  Users and possessors of this source code are     *|
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
|*     use this code in individual and commercial software.                  *|
|*                                                                           *|
|*     Any use of this source code must include,  in the user documenta-     *|
|*     tion and  internal comments to the code,  notices to the end user     *|
|*     as follows:                                                           *|
|*                                                                           *|
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
|*                                                                           *|
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
|*                                                                           *|
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
|*     computer  software  documentation,"  as such  terms  are  used in     *|
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
|*     all U.S. Government End Users  acquire the source code  with only     *|
|*     those rights set forth herein.                                        *|
|*                                                                           *|
 \***************************************************************************/

/* Hacked together from mga driver and 3.3.4 NVIDIA driver by
   Jarno Paananen <jpaana at s2.org> */

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_xaa.c $ */

#include "riva_include.h"
#include "xaalocal.h"
#include "xaarop.h"

#include "miline.h"

static void
RivaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
{
    int height = y2-y1 + 1;
    int width  = x2-x1 + 1;
    RivaPtr pRiva = RivaPTR(pScrn);

    RIVA_FIFO_FREE(pRiva->riva, Clip, 2);
    pRiva->riva.Clip->TopLeft     = (y1     << 16) | (x1 & 0xffff);
    pRiva->riva.Clip->WidthHeight = (height << 16) | width;
}


static void
RivaDisableClipping(ScrnInfoPtr pScrn)
{
    RivaSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
}

/*
 * Set pattern. Internal routine. The upper bits of the colors
 * are the ALPHA bits.  0 == transparency.
 */
static void
RivaSetPattern(RivaPtr pRiva, int clr0, int clr1, int pat0, int pat1)
{
    RIVA_FIFO_FREE(pRiva->riva, Patt, 4);
    pRiva->riva.Patt->Color0        = clr0;
    pRiva->riva.Patt->Color1        = clr1;
    pRiva->riva.Patt->Monochrome[0] = pat0;
    pRiva->riva.Patt->Monochrome[1] = pat1;
}

/*
 * Set ROP.  Translate X rop into ROP3.  Internal routine.
 */
static void
RivaSetRopSolid(RivaPtr pRiva, int rop)
{    
    if (pRiva->currentRop != rop) {
        if (pRiva->currentRop >= 16)
            RivaSetPattern(pRiva, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
        pRiva->currentRop = rop;
        RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
        pRiva->riva.Rop->Rop3 = XAACopyROP[rop];
    }
}

static void
RivaSetRopPattern(RivaPtr pRiva, int rop)
{
    if (pRiva->currentRop != (rop + 16)) {
        pRiva->currentRop = rop + 16; /* +16 is important */
        RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
        pRiva->riva.Rop->Rop3 = XAAPatternROP[rop];
    }
}

/*
 * Fill solid rectangles.
 */
static
void RivaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
                         unsigned planemask)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    RivaSetRopSolid(pRiva, rop);
    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
    pRiva->riva.Bitmap->Color1A = color;
}

static void
RivaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    
    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
    pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft     = (x << 16) | y; 
    write_mem_barrier();
    pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
    write_mem_barrier();
}

/*
 * Screen to screen BLTs.
 */
static void
RivaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
                             unsigned planemask, int transparency_color)
{
    RivaSetRopSolid(RivaPTR(pScrn), rop);
}

static void
RivaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
                               int x2, int y2, int w, int h)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    RIVA_FIFO_FREE(pRiva->riva, Blt, 3);
    pRiva->riva.Blt->TopLeftSrc  = (y1 << 16) | x1;
    pRiva->riva.Blt->TopLeftDst  = (y2 << 16) | x2;
    write_mem_barrier();
    pRiva->riva.Blt->WidthHeight = (h  << 16) | w;
    write_mem_barrier();
}


/*
 * Fill 8x8 monochrome pattern rectangles.  patternx and patterny are
 * the overloaded pattern bits themselves. The pattern colors don't
 * support 565, only 555. Hack around it.
 */
static void
RivaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
                             int fg, int bg, int rop, unsigned planemask)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    RivaSetRopPattern(pRiva, rop);
    if (pScrn->depth == 16)
    {
        fg = ((fg & 0x0000F800) << 8)
           | ((fg & 0x000007E0) << 5)
           | ((fg & 0x0000001F) << 3)
           |        0xFF000000;
        if (bg != -1)
            bg = ((bg & 0x0000F800) << 8)
               | ((bg & 0x000007E0) << 5)
               | ((bg & 0x0000001F) << 3)
               |        0xFF000000;
        else
            bg = 0;
    }
    else
    {
	fg |= pRiva->opaqueMonochrome;
	bg  = (bg == -1) ? 0 : bg | pRiva->opaqueMonochrome;
    };
    RivaSetPattern(pRiva, bg, fg, patternx, patterny);
    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
    pRiva->riva.Bitmap->Color1A = fg;
}

static void
RivaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
                                   int patternx, int patterny,
                                   int x, int y, int w, int h)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
    pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft     = (x << 16) | y;
    write_mem_barrier();
    pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
    write_mem_barrier();
}


void
RivaResetGraphics(ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    if(pRiva->NoAccel) return;

    RIVA_FIFO_FREE(pRiva->riva, Patt, 1);
    pRiva->riva.Patt->Shape = 0; 
    RivaDisableClipping(pScrn);
    pRiva->currentRop = 16;  /* to force RivaSetRopSolid to reset the pattern */
    RivaSetRopSolid(pRiva, GXcopy);
}



/*
 * Synchronise with graphics engine.  Make sure it is idle before returning.
 * Should attempt to yield CPU if busy for awhile.
 */
void RivaSync(ScrnInfoPtr pScrn)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    RIVA_BUSY(pRiva->riva);
}

/* Color expansion */
static void
RivaSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
                                             int fg, int bg, int rop, 
                                             unsigned int planemask)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    RivaSetRopSolid(pRiva, rop);

    if ( bg == -1 )
    {
        /* Transparent case */
        bg = 0x80000000;
        pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData1C;
    }
    else
    {
        pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
        if (pScrn->depth == 16)
        {
            bg = ((bg & 0x0000F800) << 8)
               | ((bg & 0x000007E0) << 5)
               | ((bg & 0x0000001F) << 3)
               |        0xFF000000;
        }
        else
        {
            bg  |= pRiva->opaqueMonochrome;
        };
    }
    pRiva->FgColor = fg;
    pRiva->BgColor = bg;
}

static void
RivaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    int t = pRiva->expandWidth;
    CARD32 *pbits = (CARD32*)pRiva->expandBuffer;
    CARD32 *d = (CARD32*)pRiva->expandFifo;
    
    while(t >= 16) 
    {
	RIVA_FIFO_FREE(pRiva->riva, Bitmap, 16);
	d[0]  = pbits[0];
	d[1]  = pbits[1];
	d[2]  = pbits[2];
	d[3]  = pbits[3];
	d[4]  = pbits[4];
	d[5]  = pbits[5];
	d[6]  = pbits[6];
	d[7]  = pbits[7];
	d[8]  = pbits[8];
	d[9]  = pbits[9];
	d[10] = pbits[10];
	d[11] = pbits[11];
	d[12] = pbits[12];
	d[13] = pbits[13];
	d[14] = pbits[14];
	d[15] = pbits[15];
	t -= 16; pbits += 16;
    }
    if(t) {
	RIVA_FIFO_FREE(pRiva->riva, Bitmap, t);
	while(t >= 4) 
	{
	    d[0]  = pbits[0];
	    d[1]  = pbits[1];
	    d[2]  = pbits[2];
	    d[3]  = pbits[3];
	    t -= 4; pbits += 4;
	}
	while(t--) 
	    *(d++) = *(pbits++); 
    }

    if (!(--pRiva->expandRows)) { /* hardware bug workaround */
       RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
       write_mem_barrier();
       pRiva->riva.Blt->TopLeftSrc = 0;
    }
    write_mem_barrier();
}

static void
RivaSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    if ( --pRiva->expandRows ) {
       RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
    } else { /* hardware bug workaround */
       RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
       write_mem_barrier();
       pRiva->riva.Blt->TopLeftSrc = 0;
    }
    write_mem_barrier();
}

static void
RivaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
                                               int y, int w, int h,
                                               int skipleft)
{
    int bw;
    RivaPtr pRiva = RivaPTR(pScrn);
    
    bw = (w + 31) & ~31;
    pRiva->expandWidth = bw >> 5;

    if ( pRiva->BgColor == 0x80000000 )
    {
        /* Use faster transparent method */
        RIVA_FIFO_FREE(pRiva->riva, Bitmap, 5);
        pRiva->riva.Bitmap->ClipC.TopLeft     = (y << 16) | ((x+skipleft)
                                                           & 0xFFFF);
        pRiva->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
        pRiva->riva.Bitmap->Color1C           = pRiva->FgColor;
        pRiva->riva.Bitmap->WidthHeightC      = (h << 16) | bw;
        write_mem_barrier();
        pRiva->riva.Bitmap->PointC            = (y << 16) | (x & 0xFFFF);
        write_mem_barrier();
    }
    else
    {
        /* Opaque */
        RIVA_FIFO_FREE(pRiva->riva, Bitmap, 7);
        pRiva->riva.Bitmap->ClipE.TopLeft     = (y << 16) | ((x+skipleft)
                                                           & 0xFFFF);
        pRiva->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
        pRiva->riva.Bitmap->Color0E           = pRiva->BgColor;
        pRiva->riva.Bitmap->Color1E           = pRiva->FgColor;
        pRiva->riva.Bitmap->WidthHeightInE  = (h << 16) | bw;
        pRiva->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
        write_mem_barrier();
        pRiva->riva.Bitmap->PointE          = (y << 16) | (x & 0xFFFF);
        write_mem_barrier();
    }

    pRiva->expandRows = h;

    if(pRiva->expandWidth > (pRiva->riva.FifoEmptyCount >> 2)) {
	pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
	pRiva->AccelInfoRec->SubsequentColorExpandScanline = 
				RivaSubsequentColorExpandScanline;
    } else {
	pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandFifo;
	pRiva->AccelInfoRec->SubsequentColorExpandScanline = 
				RivaSubsequentColorExpandScanlineFifo;
	RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
    }
}

static void
RivaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    RivaSetRopSolid(pRiva, rop);
    pRiva->FgColor = color;
}

static void 
RivaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
{
    RivaPtr pRiva = RivaPTR(pScrn);

    RIVA_FIFO_FREE(pRiva->riva, Line, 3);
    pRiva->riva.Line->Color = pRiva->FgColor;
    pRiva->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff));
    write_mem_barrier();
    if ( dir ==DEGREES_0 )
        pRiva->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff));
    else
        pRiva->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff));
    write_mem_barrier();
}

static void 
RivaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
                              int x2, int y2, int flags)
{
    RivaPtr pRiva = RivaPTR(pScrn);
    Bool  lastPoint = !(flags & OMIT_LAST);

    RIVA_FIFO_FREE(pRiva->riva, Line, lastPoint ? 5 : 3);
    pRiva->riva.Line->Color = pRiva->FgColor;
    pRiva->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff));
    write_mem_barrier();
    pRiva->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff));
    write_mem_barrier();
    if (lastPoint)
    {
        pRiva->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff));
        write_mem_barrier();
        pRiva->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff));
        write_mem_barrier();
    }
}

static void
RivaValidatePolyArc(
   GCPtr        pGC,
   unsigned long changes,
   DrawablePtr pDraw
){
   if(pGC->planemask != ~0) return;

   if(!pGC->lineWidth && 
	((pGC->alu != GXcopy) || (pGC->lineStyle != LineSolid)))
   {
        pGC->ops->PolyArc = miZeroPolyArc;
   }
}

static void
RivaValidatePolyPoint(
   GCPtr        pGC,
   unsigned long changes,
   DrawablePtr pDraw
){
   pGC->ops->PolyPoint = XAAFallbackOps.PolyPoint;

   if(pGC->planemask != ~0) return;

   if(pGC->alu != GXcopy)
        pGC->ops->PolyPoint = miPolyPoint;
}

/* Initialize XAA acceleration info */
Bool
RivaAccelInit(ScreenPtr pScreen) 
{
    XAAInfoRecPtr infoPtr;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    RivaPtr pRiva = RivaPTR(pScrn);

    pRiva->AccelInfoRec = infoPtr = XAACreateInfoRec();
    if(!infoPtr) return FALSE;

    /* fill out infoPtr here */
    infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;

    /* sync */
    infoPtr->Sync = RivaSync;

    /* solid fills */
    infoPtr->SolidFillFlags = NO_PLANEMASK;
    infoPtr->SetupForSolidFill = RivaSetupForSolidFill;
    infoPtr->SubsequentSolidFillRect = RivaSubsequentSolidFillRect;

    /* screen to screen copy */
    infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
    infoPtr->SetupForScreenToScreenCopy = RivaSetupForScreenToScreenCopy;
    infoPtr->SubsequentScreenToScreenCopy = RivaSubsequentScreenToScreenCopy;

    /* 8x8 mono patterns */
    /*
     * Set pattern opaque bits based on pixel format.
     */
    pRiva->opaqueMonochrome = ~((1 << pScrn->depth) - 1);

    infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
				       HARDWARE_PATTERN_PROGRAMMED_BITS |
				       NO_PLANEMASK;
    infoPtr->SetupForMono8x8PatternFill = RivaSetupForMono8x8PatternFill;
    infoPtr->SubsequentMono8x8PatternFillRect =
        RivaSubsequentMono8x8PatternFillRect;

    /* Color expansion */
    infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
				BIT_ORDER_IN_BYTE_LSBFIRST | 
				NO_PLANEMASK | 
				CPU_TRANSFER_PAD_DWORD |
				LEFT_EDGE_CLIPPING | 		
				LEFT_EDGE_CLIPPING_NEGATIVE_X;

    infoPtr->NumScanlineColorExpandBuffers = 1;

    infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
        RivaSetupForScanlineCPUToScreenColorExpandFill;
    infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 
        RivaSubsequentScanlineCPUToScreenColorExpandFill;

    pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
    
    /* Allocate buffer for color expansion and also image writes in the
       future */
    pRiva->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8);


    infoPtr->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
    infoPtr->SubsequentColorExpandScanline = RivaSubsequentColorExpandScanline;

    infoPtr->SolidLineFlags = infoPtr->SolidFillFlags;
    infoPtr->SetupForSolidLine = RivaSetupForSolidLine;
    infoPtr->SubsequentSolidHorVertLine =
		RivaSubsequentSolidHorVertLine;
    infoPtr->SubsequentSolidTwoPointLine = 
		RivaSubsequentSolidTwoPointLine;
    infoPtr->SetClippingRectangle = RivaSetClippingRectangle;
    infoPtr->DisableClipping = RivaDisableClipping;
    infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
    miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);

    infoPtr->ValidatePolyArc = RivaValidatePolyArc;
    infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask;
    infoPtr->ValidatePolyPoint = RivaValidatePolyPoint;
    infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
   
    RivaResetGraphics(pScrn);

    return(XAAInit(pScreen, infoPtr));
}





More information about the xserver-commit mailing list