diff -urN xf86-video-nsc-2.8.1-orig/man/nsc.man xf86-video-nsc-2.8.1/man/nsc.man
--- xf86-video-nsc-2.8.1-orig/man/nsc.man	2006-02-27 19:16:13.000000000 +0100
+++ xf86-video-nsc-2.8.1/man/nsc.man	2006-07-11 17:00:28.000000000 +0200
@@ -14,15 +14,18 @@
 .fi
 .SH DESCRIPTION
 .B nsc
-is an __xservername__ driver for National Semiconductors GEODE processor family.
-It uses the DURANGO kit provided by National Semiconductor.
+is an __xservername__ driver for the AMD Geode (formerly National Semiconductors
+Geode) processor family.
+It uses the DURANGO kit provided by National Semiconductor up to the GX
+series and the CIMARRON kit provided by AMD for the LX series.
 The driver is accelerated, and provides support for the following 
-framebuffer depths: 8, 16 and 24.
+framebuffer depths: 8, 16 and 24 including XVideo acceleration. On the
+LX series hardware RGBA cursors are supported.
 .SH SUPPORTED HARDWARE
 The
 .B nsc
-driver supports GXLV (5530 companion chip), SC1200, SC1400 and
-GX2 (5535 companion chip).
+driver supports the GXLV (5530 companion chip), SC1200, SC1400,
+GX2 (5535 companion chip) and AMD LX.
 .SH CONFIGURATION DETAILS
 Please refer to __xconfigfile__(__filemansuffix__) for general configuration
 details.  This section only covers configuration details specific to this
@@ -131,4 +134,4 @@
 .SH "SEE ALSO"
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
 .SH AUTHOR
-Author: Sarma V. Kolluru
+Author: Sarma V. Kolluru and Rene Rebe
diff -urN xf86-video-nsc-2.8.1-orig/src/Makefile.am xf86-video-nsc-2.8.1/src/Makefile.am
--- xf86-video-nsc-2.8.1-orig/src/Makefile.am	2005-10-05 00:59:15.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/Makefile.am	2006-07-11 17:00:28.000000000 +0200
@@ -23,7 +23,7 @@
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _ladir passes a dummy rpath to libtool so the thing will actually link
 # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel
+AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel -I$(top_srcdir)/src/cim
 AM_CCASFLAGS = @XORG_CFLAGS@
 nsc_drv_la_LTLIBRARIES = nsc_drv.la
 nsc_drv_la_LDFLAGS = -module -avoid-version
@@ -31,6 +31,7 @@
 
 nsc_drv_la_SOURCES = \
          durango.c \
+         cimarron.c \
          nsc_driver.c \
          nsc_fourcc.h \
          nsc_galstub.c \
@@ -46,6 +47,12 @@
          nsc_gx2_driver.c \
          nsc_gx2_shadow.c \
          nsc_gx2_video.c \
+         amd_lx_accel.c \
+         amd_lx_cursor.c \
+         amd_lx_dga.c \
+         amd_lx_driver.c \
+         amd_lx_shadow.c \
+         amd_lx_video.c \
          nsc.h \
          panel.c
 
@@ -117,6 +124,18 @@
 	gfx/tv_fs451.c		\
 	gfx/tv_geode.c		\
 	gfx/vid_1400.c		\
-	gfx/vip_1400.c
+	gfx/vip_1400.c		\
+				\
+	cim/cim_df.c		\
+	cim/cim_gp.c		\
+	cim/cim_modes.c		\
+	cim/cim_vg.ci		\
+	cim/cim_vop.c		\
+	cim/cim_filter.c	\
+	cim/cim_init.c		\
+	cim/cim_msr.c		\
+	cim/cim_vip.c		\
+	cim/cimarron.c
+
 
 
diff -urN xf86-video-nsc-2.8.1-orig/src/Makefile.in xf86-video-nsc-2.8.1/src/Makefile.in
--- xf86-video-nsc-2.8.1-orig/src/Makefile.in	2006-04-08 03:37:03.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/Makefile.in	2006-07-11 17:55:20.000000000 +0200
@@ -78,19 +78,22 @@
 nsc_drv_laLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(nsc_drv_la_LTLIBRARIES)
 nsc_drv_la_LIBADD =
-am__nsc_drv_la_SOURCES_DIST = durango.c nsc_driver.c nsc_fourcc.h \
-	nsc_galstub.c nsc_gx1_accel.c nsc_gx1_cursor.c nsc_gx1_dga.c \
-	nsc_gx1_driver.c nsc_gx1_shadow.c nsc_gx1_video.c \
-	nsc_gx2_accel.c nsc_gx2_cursor.c nsc_gx2_dga.c \
-	nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c nsc.h \
-	panel.c nsc_msr_asm.S
+am__nsc_drv_la_SOURCES_DIST = durango.c cimarron.c nsc_driver.c \
+	nsc_fourcc.h nsc_galstub.c nsc_gx1_accel.c nsc_gx1_cursor.c \
+	nsc_gx1_dga.c nsc_gx1_driver.c nsc_gx1_shadow.c \
+	nsc_gx1_video.c nsc_gx2_accel.c nsc_gx2_cursor.c nsc_gx2_dga.c \
+	nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c \
+	amd_lx_accel.c amd_lx_cursor.c amd_lx_dga.c amd_lx_driver.c \
+	amd_lx_shadow.c amd_lx_video.c nsc.h panel.c nsc_msr_asm.S
 @I386ARCH_TRUE@am__objects_1 = nsc_msr_asm.lo
-am_nsc_drv_la_OBJECTS = durango.lo nsc_driver.lo nsc_galstub.lo \
-	nsc_gx1_accel.lo nsc_gx1_cursor.lo nsc_gx1_dga.lo \
-	nsc_gx1_driver.lo nsc_gx1_shadow.lo nsc_gx1_video.lo \
-	nsc_gx2_accel.lo nsc_gx2_cursor.lo nsc_gx2_dga.lo \
-	nsc_gx2_driver.lo nsc_gx2_shadow.lo nsc_gx2_video.lo panel.lo \
-	$(am__objects_1)
+am_nsc_drv_la_OBJECTS = durango.lo cimarron.lo nsc_driver.lo \
+	nsc_galstub.lo nsc_gx1_accel.lo nsc_gx1_cursor.lo \
+	nsc_gx1_dga.lo nsc_gx1_driver.lo nsc_gx1_shadow.lo \
+	nsc_gx1_video.lo nsc_gx2_accel.lo nsc_gx2_cursor.lo \
+	nsc_gx2_dga.lo nsc_gx2_driver.lo nsc_gx2_shadow.lo \
+	nsc_gx2_video.lo amd_lx_accel.lo amd_lx_cursor.lo \
+	amd_lx_dga.lo amd_lx_driver.lo amd_lx_shadow.lo \
+	amd_lx_video.lo panel.lo $(am__objects_1)
 nsc_drv_la_OBJECTS = $(am_nsc_drv_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -238,17 +241,18 @@
 # -avoid-version prevents gratuitous .0.0.0 version numbers on the end
 # _ladir passes a dummy rpath to libtool so the thing will actually link
 # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel
+AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel -I$(top_srcdir)/src/cim
 AM_CCASFLAGS = @XORG_CFLAGS@
 nsc_drv_la_LTLIBRARIES = nsc_drv.la
 nsc_drv_la_LDFLAGS = -module -avoid-version
 nsc_drv_ladir = @moduledir@/drivers
-nsc_drv_la_SOURCES = durango.c nsc_driver.c nsc_fourcc.h nsc_galstub.c \
-	nsc_gx1_accel.c nsc_gx1_cursor.c nsc_gx1_dga.c \
+nsc_drv_la_SOURCES = durango.c cimarron.c nsc_driver.c nsc_fourcc.h \
+	nsc_galstub.c nsc_gx1_accel.c nsc_gx1_cursor.c nsc_gx1_dga.c \
 	nsc_gx1_driver.c nsc_gx1_shadow.c nsc_gx1_video.c \
 	nsc_gx2_accel.c nsc_gx2_cursor.c nsc_gx2_dga.c \
-	nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c nsc.h \
-	panel.c $(am__append_1)
+	nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c \
+	amd_lx_accel.c amd_lx_cursor.c amd_lx_dga.c amd_lx_driver.c \
+	amd_lx_shadow.c amd_lx_video.c nsc.h panel.c $(am__append_1)
 EXTRA_DIST = \
         nsc_galfns.c		\
         nsc_gx2_vga.c		\
@@ -312,7 +316,18 @@
 	gfx/tv_fs451.c		\
 	gfx/tv_geode.c		\
 	gfx/vid_1400.c		\
-	gfx/vip_1400.c
+	gfx/vip_1400.c		\
+				\
+	cim/cim_df.c		\
+	cim/cim_gp.c		\
+	cim/cim_modes.c		\
+	cim/cim_vg.ci		\
+	cim/cim_vop.c		\
+	cim/cim_filter.c	\
+	cim/cim_init.c		\
+	cim/cim_msr.c		\
+	cim/cim_vip.c		\
+	cim/cimarron.c
 
 all: all-am
 
@@ -383,6 +398,13 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_accel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_cursor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_dga.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_driver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_shadow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_video.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cimarron.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/durango.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nsc_driver.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nsc_galstub.Plo@am__quote@
@@ -489,7 +511,7 @@
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 distdir: $(DISTFILES)
-	$(mkdir_p) $(distdir)/gfx $(distdir)/panel
+	$(mkdir_p) $(distdir)/cim $(distdir)/gfx $(distdir)/panel
 	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
 	list='$(DISTFILES)'; for file in $$list; do \
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_accel.c xf86-video-nsc-2.8.1/src/amd_lx_accel.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_accel.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_accel.c	2006-07-11 18:08:36.000000000 +0200
@@ -0,0 +1,1476 @@
+/*
+ * $Workfile: amd_lx_accel.c $
+ * $Revision: #4 $
+ * $Author: billm $
+ *
+ * File Contents: This file is consists of main Xfree
+ *                acceleration supported routines like solid fill used
+ *                here.
+ * Project:       Geode Xfree Frame buffer device driver.
+ *
+ *     
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Xfree86 header files */
+
+#include "vgaHW.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xaalocal.h"
+#include "xf86fbman.h"
+#include "miline.h"
+#include "xf86_libc.h"
+#include "xaarop.h"
+#include "nsc.h"
+
+#define LX_FILL_RECT_SUPPORT 1
+#define LX_BRES_LINE_SUPPORT 1
+#define LX_DASH_LINE_SUPPORT 1
+#define LX_MONO_8X8_PAT_SUPPORT 1
+#define LX_CLREXP_8X8_PAT_SUPPORT 1
+#define LX_SCR2SCREXP_SUPPORT 1
+#define LX_SCR2SCRCPY_SUPPORT 1
+#define LX_CPU2SCREXP_SUPPORT 1
+#define LX_SCANLINE_SUPPORT 1
+#define LX_USE_OFFSCRN_MEM 1
+#define LX_WRITE_PIXMAP_SUPPORT 1
+
+#undef ulong
+typedef unsigned long ulong;
+#undef uint
+typedef unsigned int uint;
+#undef ushort
+typedef unsigned short ushort;
+#undef uchar
+typedef unsigned char uchar;
+
+#if DEBUGLVL>0
+extern FILE *zdfp;
+#if DEBUGTIM>0
+#ifndef USE_RDTSC
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long secs,usecs; \
+  getsecs(&secs,&usecs); fprintf(zdfp,"%d,%d ",secs,usecs); \
+  fprintf(zdfp,s); } } while(0)
+#else
+#define tsc(n) __asm__ __volatile__ ( \
+   " rdtsc" \
+ : "=a" (((int*)(&(n)))[0]), "=d" (((int*)(&(n)))[1]) \
+ : )
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long long t; \
+  tsc(t); fprintf(zdfp,"%lld ",t); \
+  fprintf(zdfp,s); } } while(0)
+#endif
+#else
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0)
+#endif
+#else
+#define DBLOG(n,s...) do {} while(0)
+#endif
+
+#define CALC_FBOFFSET(x, y) \
+   (((ulong)(y) << gu3_yshift) | \
+    ((ulong)(x) << gu3_xshift))
+
+#define OS_UDELAY 0
+#if OS_UDELAY > 0
+#define OS_USLEEP(usec) usleep(usec);
+#else
+#define OS_USLEEP(usec)
+#endif
+
+#define HOOK(fn) localRecPtr->fn = LX##fn
+
+static int lx0 = -1, ly0 = -1;
+static int lx1 = -1, ly1 = -1;
+static int ROP;
+
+/* #define ENABLE_PREFETCH CIMGP_ENABLE_PREFETCH */
+#define ENABLE_PREFETCH 0
+#define BLTFLAGS_HAZARD CIMGP_BLTFLAGS_HAZARD
+
+/* specify dst bounding box, upper left/lower right */
+static int
+lx_flags0(int x0,int y0, int x1,int y1)
+{
+   int n = ((ROP^(ROP>>1))&0x55) == 0 || /* no dst */
+           x0 >= lx1 || y0 >= ly1 ||     /* rght/below */
+           x1 <= lx0 || y1 <= ly0 ?      /* left/above */
+              ENABLE_PREFETCH : BLTFLAGS_HAZARD ;
+   lx0 = x0;  ly0 = y0;  lx1 = x1;  ly1 = y1;
+   return n;
+}
+
+/* specify dst bounding box, upper left/WxH */
+static int
+lx_flags1(int x0,int y0, int w,int h)
+{
+   return lx_flags0(x0,y0, x0+w,y0+h);
+}
+
+/* specify dst bounding box, two points */
+static int
+lx_flags2(int x0,int y0, int x1,int y1)
+{
+   int n;
+   if( x0 >= x1 ) { n = x0;  x0 = x1-1;  x1 = n+1; }
+   if( y0 >= y1 ) { n = y0;  y0 = y1-1;  y1 = n+1; }
+   return lx_flags0(x0,y0, x1,y1);
+}
+
+/* specify src/dst bounding box, upper left/WxH */
+static int
+lx_flags3(int x0,int y0, int x1,int y1, int w,int h)
+{
+   int x2 = x1+w, y2 = y1+h;
+   /* dst not hazzard and src not hazzard */
+   int n = ( ((ROP^(ROP>>1))&0x55) == 0 ||
+              x1 >= lx1 || y1 >= ly1 ||
+              x2 <= lx0 || y2 <= ly0 ) &&
+           ( ((ROP^(ROP>>2))&0x33) == 0 ||
+              x0 >= lx1 || y0 >= ly1 ||
+              x0+w <= lx0 || y0+h <= ly0 ) ?
+       ENABLE_PREFETCH : BLTFLAGS_HAZARD;
+   lx0 = x1;  ly0 = y1;  lx1 = x2;  ly1 = y2;
+   return n;
+}
+
+static void
+lx_endpt(int x,int y,int len, int mag,int min,int err,int oct, int *px, int *py)
+{
+   int u = len-1;
+   int v = (u*min-err)/mag;
+
+   switch( oct ) {
+   default:
+   case 0:  x += u;  y += v;  break;
+   case 1:  x += v;  y += u;  break;
+   case 2:  x += u;  y -= v;  break;
+   case 3:  x += v;  y -= u;  break;
+   case 4:  x -= u;  y += v;  break;
+   case 5:  x -= v;  y += u;  break;
+   case 6:  x -= u;  y -= v;  break;
+   case 7:  x -= v;  y -= u;  break;
+   }
+   *px = x;  *py = y;
+}
+
+/* static storage declarations */
+
+typedef struct sGBltBox {
+   ulong x, y;
+   ulong w, h;
+   ulong color;
+   int bpp, transparent;
+} GBltBox;
+
+static GBltBox giwr;
+static GBltBox gc2s;
+
+typedef struct sGDashLine {
+   ulong pat;
+   int len;
+   int fg;
+   int bg;
+} GDashLine;
+
+static GDashLine gdln;
+
+static uint gu3_xshift = 1;
+static uint gu3_yshift = 1;
+static uint gu3_img_fmt = 0;
+#if !LX_USE_OFFSCRN_MEM
+static uint ImgBufOffset;
+#else
+static uchar *ImgLnsBuffers;
+#endif
+static uchar *ClrLnsBuffers;
+static XAAInfoRecPtr localRecPtr;
+
+static int lx_src_fmt[4] = {
+   CIMGP_SOURCE_FMT_8BPP_INDEXED,
+   CIMGP_SOURCE_FMT_0_5_6_5,
+   CIMGP_SOURCE_FMT_24BPP,
+   CIMGP_SOURCE_FMT_8_8_8_8
+};
+
+
+/* pat  0xF0 */
+/* src  0xCC */
+/* dst  0xAA */
+
+/* (src FUNC dst) */
+
+static const int SDfn[16] = { 
+   0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
+   0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
+};
+
+/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */
+
+static const int SDfn_PM[16] = {
+   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA
+};
+
+/* (pat FUNC dst) */
+
+static int PDfn[16] = {
+   0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
+   0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF
+};
+
+/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */
+
+static int PDfn_SM[16] = {
+   0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA,
+   0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE
+};
+
+
+
+/*----------------------------------------------------------------------------
+ * LXAccelSync.
+ *
+ * Description  :This function is called to synchronize with the graphics
+ *               engine and it waits the graphic engine is idle.  This is
+ *               required before allowing direct access to the framebuffer.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *
+ * Returns              :none
+ *---------------------------------------------------------------------------*/
+void
+LXAccelSync(ScrnInfoPtr pScrni)
+{
+   DBLOG(3,"LXAccelSync()\n");
+   while( gp_test_blt_busy() != 0 ) { OS_USLEEP(OS_UDELAY) }
+}
+
+#if LX_FILL_RECT_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForSolidFill.
+ *
+ * Description  :The SetupFor and Subsequent SolidFill(Rect) provide
+ *               filling rectangular areas of the screen with a
+ *               foreground color.
+ *
+ * Parameters.
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *   color        int     foreground fill color
+ *    rop         int     unmapped raster op
+ * planemask     uint     -1 (fill) or pattern data
+ *
+ * Returns              :none
+ *--------------------------------------------------------------------------*/
+static void
+LXSetupForSolidFill(ScrnInfoPtr pScrni, int color, int rop, uint planemask)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForSolidFill(%#x,%#x,%#x)\n",color,rop,planemask);
+   rop &= 0x0F;
+   gp_declare_blt(0);
+   if( planemask == ~0U ) { /* fill with color */
+      gp_set_raster_operation(ROP=SDfn[rop]);
+   }
+   else { /* select rop that uses source data for planemask */
+      gp_set_raster_operation(ROP=SDfn_PM[rop]);
+      gp_set_solid_pattern(planemask);
+   }
+   gp_set_solid_source(color);
+   gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+   gp_write_parameters();
+}
+
+ /*----------------------------------------------------------------------------
+ * LXSubsequentSolidFillRect.
+ *
+ * Description  :see LXSetupForSolidFill.
+ *
+ * Parameters.
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x          int     destination x offset
+ *     y          int     destination y offset
+ *     w          int     fill area width (pixels)
+ *     h          int     fill area height (pixels)
+ *
+ * Returns      :none
+ *
+ * Sample application uses:
+ *   - Window backgrounds. 
+ *   - pull down highlighting.
+ *   - x11perf: rectangle tests (-rect500).
+ *   - x11perf: fill trapezoid tests (-trap100).
+ *   - x11perf: horizontal line segments (-hseg500).
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h)
+{
+   int flags;
+   DBLOG(2,"LXSubsequentSolidFillRect() at %d,%d %dx%d\n",x,y,w,h);
+   flags = lx_flags1(x,y,w,h);
+   gp_declare_blt(flags);
+   gp_pattern_fill(CALC_FBOFFSET(x,y), w, h);
+}
+
+/* LX_FILL_RECT_SUPPORT */
+#endif
+
+#if LX_CLREXP_8X8_PAT_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForColor8x8PatternFill
+ *
+ * Description  :8x8 color pattern data is 64 pixels of full color data
+ *               stored linearly in offscreen video memory.  These patterns
+ *               are useful as a substitute for 8x8 mono patterns when tiling,
+ *               doing opaque stipples, or regular stipples. 
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *    patx        int     x offset to pattern data
+ *    paty        int     y offset to pattern data
+ *    rop         int     unmapped raster operation
+ * planemask     uint     -1 (copy) or pattern data
+ * trans_color    int     -1 (copy) or transparent color (not enabled)
+ *                         trans color only supported on source channel
+ *                         or in monochrome pattern channel
+ * 
+ * Returns      :none.
+ *
+ *---------------------------------------------------------------------------*/
+
+static void
+LXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop,
+                               uint planemask, int trans_color)
+{
+   unsigned long *pat_8x8;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n"
+           ,patx,paty,rop,planemask,trans_color);
+   pat_8x8 = (unsigned long *)(pGeode->FBBase+CALC_FBOFFSET(patx,paty));
+   /* since the cache may be loaded by blt, we must wait here */
+   LXAccelSync(pScrni);
+   gp_set_color_pattern(pat_8x8,gu3_img_fmt,0,0);
+   rop &= 0x0F;
+   gp_declare_blt(0);
+   if( planemask == ~0U ) { /* fill with pattern */
+      gp_set_raster_operation(ROP=PDfn[rop]);
+   }
+   else { /* select rop that uses source data for planemask */
+      gp_set_raster_operation(ROP=PDfn_SM[rop]);
+      gp_set_solid_source((ulong)planemask);
+   }
+   gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+   gp_write_parameters();
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentColor8x8PatternFillRect
+ *
+ * Description  :see LXSetupForColor8x8PatternFill.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *   patx         int     pattern phase x offset
+ *   paty         int     pattern phase y offset
+ *      x         int     destination x offset
+ *      y         int     destination y offset
+ *      w         int     fill area width (pixels)
+ *      h         int     fill area height (pixels)
+ *              
+ * Returns      :none
+ *
+ * Sample application uses:
+ *   - Patterned desktops
+ *   - x11perf: stippled rectangle tests (-srect500).
+ *   - x11perf: opaque stippled rectangle tests (-osrect500).
+ *--------------------------------------------------------------------------*/
+static void
+LXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
+                                     int x, int y, int w, int h)
+{
+   int flags;
+   DBLOG(2,"LXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n",
+           patx,paty,x,y,w,h);
+   flags = lx_flags1(x,y,w,h);
+   gp_declare_blt(flags);
+   gp_set_pattern_origin(patx,paty);
+   gp_pattern_fill(CALC_FBOFFSET(x,y), w, h);
+}
+
+/* LX_CLREXP_8X8_PAT_SUPPORT */
+#endif
+
+#if LX_MONO_8X8_PAT_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForMono8x8PatternFill
+ *
+ * Description  :8x8 mono pattern data is 64 bits of color expansion data
+ *               with ones indicating the foreground color and zeros
+ *               indicating the background color.  These patterns are
+ *               useful when tiling, doing opaque stipples, or regular
+ *               stipples. 
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *    patx        int     x offset to pattern data
+ *    paty        int     y offset to pattern data
+ *     fg         int     foreground color
+ *     bg         int     -1 (transparent) or background color
+ *    rop         int     unmapped raster operation
+ * planemask     uint     -1 (copy) or pattern data
+ * 
+ * Returns      :none.
+ *
+ * Comments     :none.
+ *
+ *--------------------------------------------------------------------------*/
+static void
+LXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty,
+                                int fg, int bg, int rop, uint planemask)
+{
+   int trans;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n",
+            patx,paty,fg,bg,rop,planemask);
+   rop &= 0x0F;
+   gp_declare_blt(0);
+   if( planemask == ~0U ) { /* fill with pattern */
+      gp_set_raster_operation(ROP=PDfn[rop]);
+   }
+   else { /* select rop that uses source data for planemask */
+      gp_set_raster_operation(ROP=PDfn_SM[rop]);
+      gp_set_solid_source((ulong)planemask);
+   }
+   trans =  bg==-1 ? 1 : 0;
+   gp_set_mono_pattern(bg,fg, patx,paty, trans, 0, 0);
+   gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+   gp_write_parameters();
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentMono8x8PatternFillRect
+ *
+ * Description  :see LXSetupForMono8x8PatternFill
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *   patx         int     pattern phase x offset
+ *   paty         int     pattern phase y offset
+ *      x         int     destination x offset
+ *      y         int     destination y offset
+ *      w         int     fill area width (pixels)
+ *      h         int     fill area height (pixels)
+
+ * Returns      :none
+ *
+ * Sample application uses:
+ *   - Patterned desktops
+ *   - x11perf: stippled rectangle tests (-srect500).
+ *   - x11perf: opaque stippled rectangle tests (-osrect500).
+ *--------------------------------------------------------------------------*/
+static void
+LXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
+	     		          int x, int y, int w, int h)
+{
+   int flags;
+   DBLOG(2,"LXSubsequentMono8x8PatternFillRect() pat %#x,%#x at %d,%d %dx%d\n",patx,paty,x,y,w,h);
+   flags = lx_flags1(x,y,w,h);
+   gp_declare_blt(flags);
+   gp_set_pattern_origin(patx,paty);
+   gp_pattern_fill(CALC_FBOFFSET(x,y), w,h);
+}
+
+/* LX_MONO_8X8_PAT_SUPPORT */
+#endif
+
+#if LX_SCR2SCRCPY_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForScreenToScreenCopy
+ *
+ * Description  :SetupFor and Subsequent ScreenToScreenCopy functions
+ *               provide an interface for copying rectangular areas from
+ *               video memory to video memory.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *   xdir         int     x copy direction (up/dn)
+ *   ydir         int     y copy direction (up/dn)
+ *    rop         int     unmapped raster operation
+ * planemask     uint     -1 (copy) or pattern data
+ * trans_color    int     -1 (copy) or transparent color
+ *
+ * Returns      :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop,
+                              uint planemask, int trans_color)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForScreenToScreenCopy() xd%d yd%d rop %#x %#x %#x\n",
+           xdir,ydir,rop,planemask,trans_color);
+   rop &= 0x0F;
+   gp_declare_blt(0);
+   if( planemask == ~0U ) {
+      gp_set_raster_operation(ROP=SDfn[rop]);
+   }
+   else {
+      gp_set_raster_operation(ROP=SDfn_PM[rop]);
+      gp_set_solid_pattern((ulong)planemask);
+   }
+   gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+   gp_write_parameters();
+   gc2s.transparent = (trans_color == -1) ? 0 : 1;
+   gc2s.color = trans_color;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsquentScreenToScreenCopy
+ *
+ * Description  :see LXSetupForScreenToScreenCopy.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x1         int     source x offset
+ *     y1         int     source y offset
+ *     x2         int     destination x offset
+ *     y2         int     destination y offset
+ *      w         int     copy area width (pixels)
+ *      h         int     copy area height (pixels)
+ * 
+ * Returns      :none
+ *
+ * Sample application uses (non-transparent):
+ *   - Moving windows.
+ *   - x11perf: scroll tests (-scroll500).
+ *   - x11perf: copy from window to window (-copywinwin500).
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni,
+                                int x1, int y1, int x2, int y2, int w, int h)
+{
+   int flags;
+   DBLOG(2,"LXSubsequentScreenToScreenCopy() from %d,%d to %d,%d %dx%d\n",x1,y1,x2,y2,w,h);
+   flags = lx_flags3(x1,y1,x2,y2,w,h);
+   gp_declare_blt(flags);
+   if( gc2s.transparent ) {
+      gp_set_source_transparency(gc2s.color,~0);
+   }
+   flags = 0;
+   if( x2 > x1 ) flags |= 1;
+   if( y2 > y1 ) flags |= 2;
+   gp_screen_to_screen_blt(CALC_FBOFFSET(x2,y2), CALC_FBOFFSET(x1,y1), w,h, flags);
+}
+
+/* LX_SCR2SCRCPY_SUPPORT */
+#endif
+
+#if LX_SCANLINE_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForScanlineImageWrite
+ *
+ * Description  :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline
+ *               transfer full color pixel data from system memory to video
+ *               memory.  This is useful for dealing with alignment issues and
+ *               performing raster ops on the data.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *    rop         int     unmapped raster operation
+ * planemask     uint     -1 (copy) or pattern data
+ *    bpp         int     bits per pixel (unused)
+ *  depth         int     color depth (unused)
+ *
+ * Returns      :none
+ *
+ *  x11perf -putimage10  
+ *  x11perf -putimage100 
+ *  x11perf -putimage500 
+*----------------------------------------------------------------------------
+*/
+static void
+LXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask,
+                              int trans_color, int bpp, int depth)
+{
+   int Bpp = (bpp+7) >> 3;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForScanlineImageWrite() rop %#x %#x %#x %d %d\n",
+           rop,planemask,trans_color,bpp,depth);
+   rop &= 0x0F;
+   gp_set_source_format(lx_src_fmt[Bpp-1]);
+   gp_declare_blt(0);
+   if( planemask == ~0U ) {
+      gp_set_raster_operation(ROP=SDfn[rop]);
+   }
+   else {
+      gp_set_raster_operation(ROP=SDfn_PM[rop]);
+      gp_set_solid_pattern(planemask);
+   }
+   gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+   gp_write_parameters();
+   giwr.transparent = (trans_color == -1) ? 0 : 1;
+   giwr.color = trans_color;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentScanlineImageWriteRect
+ *
+ * Description  : see LXSetupForScanlineImageWrite.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *      x         int     destination x offset
+ *      y         int     destination y offset
+ *      w         int     copy area width (pixels)
+ *      h         int     copy area height (pixels)
+ * skipleft       int     x margin (pixels) to skip (not enabled)
+ *      
+ * Returns      :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni,
+                                    int x, int y, int w, int h, int skipleft)
+{
+   DBLOG(2,"LXSubsequentScanlineImageWriteRect() rop %d,%d %dx%d %d\n",x,y,w,h,skipleft);
+   giwr.x = x;  giwr.y = y;
+   giwr.w = w;  giwr.h = h;
+   /* since the image buffer must be not busy (it may be busy from
+    * a previous ScanlineWriteImage), we must add a Sync here */
+#if !LX_USE_OFFSCRN_MEM
+   LXAccelSync(pScrni);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsquentImageWriteScanline
+ *
+ * Description  : see LXSetupForScanlineImageWrite.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *  bufno         int     scanline number in write group
+ *
+ * Returns      :none
+ *
+ * Sample application uses (non-transparent):
+ *   - Moving windows.
+ *   - x11perf: scroll tests (-scroll500).
+ *   - x11perf: copy from window to window (-copywinwin500).
+ *
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno)
+{
+   GeodePtr pGeode;
+   int blt_height = 0;
+   DBLOG(3,"LXSubsequentImageWriteScanline() %d\n",bufno);
+   pGeode = GEODEPTR(pScrni);
+
+   if( (blt_height=pGeode->NoOfImgBuffers) > giwr.h )
+      blt_height = giwr.h;
+   if( ++bufno < blt_height ) return;
+
+   gp_declare_blt(ENABLE_PREFETCH);
+   if( giwr.transparent ) {
+      gp_set_source_transparency(giwr.color,~0);
+   }
+#if !LX_USE_OFFSCRN_MEM
+   gp_screen_to_screen_blt(CALC_FBOFFSET(giwr.x,giwr.y), ImgBufOffset,
+                           giwr.w, blt_height, 0);
+   LXAccelSync(pScrni);
+#else
+   gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(giwr.x,giwr.y), 0,
+                           giwr.w, blt_height, ImgLnsBuffers, pGeode->AccelPitch);
+#endif
+   giwr.h -= blt_height;
+   giwr.y += blt_height;
+}
+
+/* LX_SCANLINE_SUPPORT */
+#endif
+
+#if LX_CPU2SCREXP_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForScanlineCPUToScreenColorExpandFill
+ *
+ * Description  :SetupFor/Subsequent CPUToScreenColorExpandFill and
+ *               ColorExpandScanline routines provide an interface for
+ *               doing expansion blits from source patterns stored in
+ *               system memory.
+ *                              
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     fg         int     foreground color
+ *     bg         int     -1 (transparent) or background color
+ *    rop         int     unmapped raster operation
+ * planemask     uint     -1 (copy) or pattern data
+ *
+ * Returns      :none.
+ *---------------------------------------------------------------------------*/
+
+static void
+LXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
+                                      int fg, int bg, int rop,
+                                      uint planemask)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForScanlineCPUToScreenColorExpandFill() fg %#x bg %#x rop %#x %#x\n",
+            fg,bg,rop,planemask);
+   rop &= 0x0F;
+   gp_declare_blt(0);
+   if( planemask == ~0U ) {
+      gp_set_raster_operation(ROP=SDfn[rop]);
+   }
+   else {
+      gp_set_raster_operation(ROP=SDfn_PM[rop]);
+      gp_set_solid_pattern(planemask);
+   }
+   gp_set_mono_source(bg, fg, (bg == -1));
+   gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+   gp_write_parameters();
+   gc2s.bpp = 1;
+   gc2s.transparent = 0;
+   gc2s.color = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentScanlineCPUToScreenColorExpandFill
+ *
+ * Description  :see LXSetupForScanlineCPUToScreenColorExpandFill
+ *
+ * Parameters:
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x          int     destination x offset
+ *     y          int     destination y offset
+ *     w          int     fill area width (pixels)
+ *     h          int     fill area height (pixels)
+ *      
+ * Returns      :none
+ *
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
+                                    int x, int y, int w, int h, int skipleft)
+{
+   DBLOG(2,"LXSubsequentScanlineCPUToScreenColorExpandFill() %d,%d %dx%d %d\n",
+            x,y,w,h,skipleft);
+   gc2s.x = x;  gc2s.y = y;  
+   gc2s.w = w;  gc2s.h = h;  
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentColorExpandScanline
+ *
+ * Description  :see LXSetupForScanlineCPUToScreenColorExpandFill
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *  bufno         int     scanline number in write group
+ *
+ * Returns      :none
+*----------------------------------------------------------------------------
+*/
+static void
+LXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno)
+{
+   GeodePtr pGeode;
+   ulong srcpitch;
+   int blt_height = 0;
+   DBLOG(3,"LXSubsequentColorExpandScanline() %d\n",bufno);
+   pGeode = GEODEPTR(pScrni);
+
+   if( (blt_height=pGeode->NoOfImgBuffers) > gc2s.h )
+      blt_height = gc2s.h;
+   if( ++bufno < blt_height ) return;
+
+   gp_declare_blt(ENABLE_PREFETCH);
+   /* convert from bits to dwords */
+   srcpitch = ((pGeode->AccelPitch+31) >> 5) << 2;
+   gp_mono_bitmap_to_screen_blt(CALC_FBOFFSET(gc2s.x,gc2s.y), 0, gc2s.w,blt_height,
+                                ClrLnsBuffers,srcpitch);
+   gc2s.h -= blt_height;
+   gc2s.y += blt_height;
+}
+
+/* LX_CPU2SCREXP_SUPPORT */
+#endif
+
+#if LX_SCR2SCREXP_SUPPORT
+
+/*----------------------------------------------------------------------------
+ * LXSetupForScreenToScreenColorExpandFill
+ *
+ * Description  :SetupFor/Subsequent ScreenToScreenColorExpandFill and
+ *               ColorExpandScanline routines provide an interface for
+ *               doing expansion blits from source patterns stored in
+ *               video memory.
+ *                              
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     fg         int     foreground color
+ *     bg         int     -1 (transparent) or background color
+ *    rop         int     unmapped raster operation
+ * planemask     uint     -1 (copy) or pattern data
+ *
+ * Returns      :none.
+ *---------------------------------------------------------------------------*/
+
+static void
+LXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg,
+                                         int rop, uint planemask)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForScreenToScreenColorExpandFill() fg %#x bg %#x rop %#x %#x\n",
+	   fg,bg,rop,planemask);
+   rop &= 0x0F;
+   gp_declare_blt(0);
+   if( planemask == ~0U ) {
+      gp_set_raster_operation(ROP=SDfn[rop]);
+   }
+   else {
+      gp_set_raster_operation(ROP=SDfn_PM[rop]);
+      gp_set_solid_pattern(planemask);
+   }
+   gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+   gp_set_mono_source(bg, fg, (bg == -1));
+   gp_write_parameters();
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentScreenToScreenColorExpandFill
+ *
+ * Description  :see LXSetupForScreenToScreenColorExpandFill
+ *
+ * Parameters:
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x          int     destination x offset
+ *     y          int     destination y offset
+ *     w          int     fill area width (pixels)
+ *     h          int     fill area height (pixels)
+ * offset         int     initial x offset
+ *      
+ * Returns      :none
+ *
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni,
+                                           int x, int y, int w, int h,
+                                           int srcx, int srcy, int offset)
+{
+   int flags;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSubsequentScreenToScreenColorExpandFill() %d,%d %dx%d %d,%d %d\n",
+	   x,y,w,h,srcx,srcy,offset);
+   flags = lx_flags3(srcx,srcy,x,y,w,h);
+   gp_declare_blt(flags);
+   gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+   gp_mono_expand_blt(CALC_FBOFFSET(x,y), CALC_FBOFFSET(srcx,srcy), offset, w,h, 0);
+}
+
+/* LX_SCR2SCREXP_SUPPORT */
+#endif
+
+#define VM_X_MAJOR 0
+#define VM_Y_MAJOR 1
+#define VM_MAJOR_INC 2
+#define VM_MAJOR_DEC 0
+#define VM_MINOR_INC 4
+#define VM_MINOR_DEC 0
+
+static ushort vmode[] = {
+   VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,  /* !XDECREASING !YDECREASING !YMAJOR */
+   VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC,  /* !XDECREASING !YDECREASING  YMAJOR */
+   VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,  /* !XDECREASING  YDECREASING !YMAJOR */
+   VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,  /* !XDECREASING  YDECREASING  YMAJOR */
+   VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC,  /*  XDECREASING !YDECREASING !YMAJOR */
+   VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC,  /*  XDECREASING !YDECREASING  YMAJOR */
+   VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,  /*  XDECREASING  YDECREASING !YMAJOR */
+   VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC,  /*  XDECREASING  YDECREASING  YMAJOR */
+};
+
+#define ABS(_val1, _val2) (((_val1) > (_val2)) ? ((_val1)-(_val2)) : ((_val2) - (_val1)))
+
+#if LX_BRES_LINE_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForSolidLine
+ *
+ * Description  :SetupForSolidLine and Subsequent HorVertLine TwoPointLine
+ *               BresenhamLine provides an interface for drawing thin
+ *               solid lines.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *   color        int     foreground fill color
+ *    rop         int     unmapped raster op
+ * planemask     uint     -1 (fill) or pattern data (not enabled)
+ * 
+ * Returns              :none
+*---------------------------------------------------------------------------*/
+static void
+LXSetupForSolidLine(ScrnInfoPtr pScrni,
+                     int color, int rop, uint planemask)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForSolidLine() %#x %#x %#x\n",color,rop,planemask);
+   rop &= 0x0F;
+   gp_declare_vector(CIMGP_BLTFLAGS_HAZARD);
+   if( planemask == ~0U ) {
+      gp_set_raster_operation(ROP=PDfn[rop]);
+   }
+   else {
+      gp_set_raster_operation(ROP=PDfn_SM[rop]);
+      gp_set_solid_source(planemask);
+   }
+   gp_set_solid_pattern((ulong)color);
+   gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+   gp_write_parameters();
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentSolidBresenhamLine
+ *
+ * Description  :see LXSetupForSolidLine
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x1         int     destination x offset
+ *     y1         int     destination y offset
+ * absmaj         int     Bresenman absolute major
+ * absmin         int     Bresenman absolute minor
+ *    err         int     Bresenman initial error term
+ *    len         int     length of the vector (pixels)
+ * octant         int     specifies sign and magnitude relationships
+ *                         used to determine axis of magor rendering
+ *                         and direction of vector progress.
+ *
+ * Returns      :none
+ *
+ *   - Window outlines on window move.
+ *   - x11perf: line segments (-line500).
+ *   - x11perf: line segments (-seg500).
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
+                           int absmaj, int absmin, int err,
+                           int len, int octant)
+{
+   int x2, y2, flags;
+   long axial, diagn;
+   DBLOG(2,"LXSubsequentSolidBresenhamLine() %d,%d %d %d, %d %d, %d\n",
+           x1,y1,absmaj,absmin,err,len,octant);
+   if( len <= 0 ) return;
+   lx_endpt(x1,y1,len,absmaj,absmin,err,octant,&x2,&y2);
+   flags = lx_flags2(x1,y1,x2+1,y2+1);
+   gp_declare_vector(flags);
+   axial = absmin;
+   err += axial;
+   diagn = absmin-absmaj;
+   gp_bresenham_line(CALC_FBOFFSET(x1,y1), len, err, axial, diagn, vmode[octant]);
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentSolidTwoPointLine
+ *
+ * Description  :see LXSetupForSolidLine
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x0         int     destination x start offset
+ *     y0         int     destination y start offset
+ *     x1         int     destination x end offset
+ *     y1         int     destination y end offset
+ *  flags         int     OMIT_LAST, dont draw last pixel (not used)
+ *
+ * Returns      :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
+                               int x1, int y1, int flags)
+{
+   long dx, dy, dmaj, dmin, octant, bias;
+   long axial, diagn, err, len;
+   DBLOG(2,"LXSubsequentSolidTwoPointLine() %d,%d %d,%d, %#x\n",
+           x0,y0,x1,y1,flags);
+
+   if( (dx=x1-x0) < 0 ) dx = -dx;
+   if( (dy=y1-y0) < 0 ) dy = -dy;
+   if( dy >= dx ) {
+      dmaj = dy;  dmin = dx;
+      octant = YMAJOR;
+   }
+   else {
+      dmaj = dx;  dmin = dy;
+      octant = 0;
+   }
+   len = dmaj;
+   if( (flags&OMIT_LAST) == 0 ) ++len;
+   if( len <= 0 ) return;
+   if (x1 < x0) octant |= XDECREASING;
+   if (y1 < y0) octant |= YDECREASING;
+
+   flags = lx_flags2(x0,y0,x1+1,y1+1);
+   gp_declare_vector(flags);
+   axial = dmin << 1;
+   bias = miGetZeroLineBias(pScrni->pScreen);
+   err = axial - dmaj - ((bias>>octant) & 1);
+   diagn = (dmin-dmaj) << 1;
+   gp_bresenham_line(CALC_FBOFFSET(x0,y0), len, err, axial, diagn, vmode[octant]);
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentSolidHorVertLine
+ *
+ * Description  :see LXSetupForSolidLine
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x          int     destination x offset
+ *     y          int     destination y offset
+ *    len         int     length of the vector (pixels)
+ *    dir         int     DEGREES_270 or DEGREES_0 line direction
+ *
+ * Sample application uses:
+ *   - Window outlines on window move.
+ *   - x11perf: line segments (-hseg500).
+ *   - x11perf: line segments (-vseg500).
+ *---------------------------------------------------------------------------
+ */
+static void
+LXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni,
+                         int x, int y, int len, int dir)
+{
+   int flags, w, h;
+   DBLOG(2,"LXSubsequentHorVertLine() %d,%d %d %d\n",x,y,len,dir);
+   gp_declare_blt(0);
+   if( dir == DEGREES_0 ) {
+      w = len;  h = 1;
+   }
+   else {
+      w = 1;  h = len;
+   }
+   flags = lx_flags1(x,y,w,h);
+   gp_declare_blt(flags);
+   gp_pattern_fill(CALC_FBOFFSET(x,y),
+                   ((dir == DEGREES_0) ? len : 1),
+                   ((dir == DEGREES_0) ? 1 : len));
+}
+
+/* LX_BRES_LINE_SUPPORT */
+#endif
+
+#if LX_DASH_LINE_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForDashedLine
+ *
+ * Description  :SetupForDashedLine and Subsequent TwoPointLine
+ *               BresenhamLine provides an interface for drawing thin
+ *               dashed lines.
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     fg         int     foreground fill color
+ *     bg         int     -1 (transp) or background fill color
+ *    rop         int     unmapped raster op
+ * planemask     uint     -1 (fill) or pattern data (not enabled)
+ *  length        int     pattern length (bits)
+ * pattern     uchar*     dash pattern mask
+ * 
+ * Returns              :none
+*---------------------------------------------------------------------------*/
+static void
+LXSetupForDashedLine(ScrnInfoPtr pScrni,
+                      int fg, int bg, int rop, uint planemask,
+                      int length, uchar *pattern)
+{
+   int n;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(2,"LXSetupForDashedLine() fg %#x bg %#x rop %#x pm %#x len %d, pat %#x\n",
+	   fg,bg,rop,planemask,length,*(ulong*)pattern);
+   gdln.fg = fg;
+   gdln.bg = bg;
+   gdln.len = length;
+   n = (length+7)/8;
+   if( n > sizeof(gdln.pat) )
+      n = sizeof(gdln.pat);
+   memcpy(&gdln.pat,pattern,n);
+   rop &= 0x0F;
+   gp_declare_vector(CIMGP_BLTFLAGS_HAZARD);
+   if( planemask == ~0U ) {
+      gp_set_raster_operation(ROP=PDfn[rop]);
+   }
+   else {
+      gp_set_raster_operation(ROP=PDfn_SM[rop]);
+      gp_set_solid_source(planemask);
+   }
+   gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+   gp_write_parameters();
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentDashedBresenhamLine
+ *
+ * Description  :see LXSetupForDashedLine
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x1         int     destination x offset
+ *     y1         int     destination y offset
+ * absmaj         int     Bresenman absolute major
+ * absmin         int     Bresenman absolute minor
+ *    err         int     Bresenman initial error term
+ *    len         int     length of the vector (pixels)
+ * octant         int     specifies sign and magnitude relationships
+ *                         used to determine axis of magor rendering
+ *                         and direction of vector progress.
+ *  phase         int     initial pattern offset at x1,y1
+ *
+ * Returns      :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
+                           int absmaj, int absmin, int err,
+                           int len, int octant, int phase)
+{
+   int x2, y2, flags;
+   long axial, diagn;
+   ulong pattern;
+   DBLOG(2,"LXSubsequentDashedBresenhamLine() %d,%d %d %d, %d %d, %d %d\n",
+           x1,y1,absmaj,absmin,err,len,octant,phase);
+   if( len <= 0 ) return;
+   pattern = gdln.pat;
+   if( phase > 0 ) {
+      int n = gdln.len-phase;
+      pattern = ((pattern>>phase)&((1UL<<n)-1)) | (pattern<<n);
+   }
+   gp_set_vector_pattern(pattern,gdln.fg,gdln.len);
+   lx_endpt(x1,y1,len,absmaj,absmin,err,octant,&x2,&y2);
+   flags = lx_flags2(x1,y1,x2+1,y2+1);
+   gp_declare_vector(flags);
+   axial = absmin;
+   err += axial;
+   diagn = absmin-absmaj;
+   gp_bresenham_line(CALC_FBOFFSET(x1,y1), len, err, axial, diagn, vmode[octant]);
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentDashedTwoPointLine
+ *
+ * Description  :see LXSetupForDashedLine
+ *
+ *    Arg        Type     Comment
+ *  pScrni   ScrnInfoPtr  pointer to Screeen info
+ *     x0         int     destination x start offset
+ *     y0         int     destination y start offset
+ *     x1         int     destination x end offset
+ *     y1         int     destination y end offset
+ *  flags         int     OMIT_LAST, dont draw last pixel (not used)
+ *  phase         int     initial pattern offset at x1,y1
+ *
+ * Returns      :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
+                               int x1, int y1, int flags, int phase)
+{
+   ulong pattern;
+   long dx, dy, dmaj, dmin, octant, bias;
+   long axial, diagn, err, len;
+   DBLOG(2,"LXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n",
+           x0,y0,x1,y1,flags,phase);
+
+   if( (dx=x1-x0) < 0 ) dx = -dx;
+   if( (dy=y1-y0) < 0 ) dy = -dy;
+   if( dy >= dx ) {
+      dmaj = dy;  dmin = dx;
+      octant = YMAJOR;
+   }
+   else {
+      dmaj = dx;  dmin = dy;
+      octant = 0;
+   }
+   len = dmaj;
+   if( (flags&OMIT_LAST) == 0 ) ++len;
+   if( len <= 0 ) return;
+   if (x1 < x0) octant |= XDECREASING;
+   if (y1 < y0) octant |= YDECREASING;
+
+   pattern = gdln.pat;
+   if( phase > 0 ) {
+      int n = gdln.len-phase;
+      pattern = ((pattern>>phase)&((1UL<<n)-1)) | (pattern<<n);
+   }
+   gp_set_vector_pattern(pattern,gdln.fg,gdln.len);
+   flags = lx_flags2(x0,y0,x1+1,y1+1);
+   gp_declare_vector(flags);
+
+   axial = dmin << 1;
+   bias = miGetZeroLineBias(pScrni->pScreen);
+   err = axial-dmaj - ((bias>>octant) & 1);
+   diagn = (dmin-dmaj) << 1;
+   gp_bresenham_line(CALC_FBOFFSET(x0,y0), len, err, axial, diagn, vmode[octant]);
+}
+
+/* LX_DASH_LINE_SUPPORT */
+#endif
+
+#if LX_WRITE_PIXMAP_SUPPORT
+void
+LXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, unsigned char *src, int srcwidth,
+               int rop, unsigned int planemask, int trans, int bpp, int depth)
+{
+   int flags, dx, dy;
+   int Bpp = (bpp+7) >> 3;
+   unsigned long offset;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   DBLOG(2,"LXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n",
+           x,y, w,h, src, srcwidth, rop, planemask, trans,bpp,depth);
+
+   rop &= 0x0F;
+   gp_set_source_format(lx_src_fmt[Bpp-1]);
+   /* must assign before lx_flags */
+   ROP = planemask == ~0U ? SDfn[rop] : SDfn_PM[rop];
+
+   if( src >= pGeode->FBBase && src < pGeode->FBBase+pGeode->FBSize ) {
+      offset = src-pGeode->FBBase;
+      dx = (offset & ((1<<gu3_yshift)-1)) >> Bpp;
+      dy = offset >> gu3_yshift;
+      flags = lx_flags3(x,y,dx,dy,w,h);
+   }
+   else
+      flags = ENABLE_PREFETCH;
+
+   gp_declare_blt(flags);
+   gp_set_raster_operation(ROP);
+   if( planemask != ~0U )
+      gp_set_solid_pattern(planemask);
+   gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+   if( trans != -1 ) {
+      gp_set_source_transparency(trans,~0);
+   }
+
+   gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(x,y), 0, w,h, src, srcwidth);
+   SET_SYNC_FLAG(pGeode->AccelInfoRec);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXAccelInit.
+ *
+ * Description  :Create and initialize XAAInfoRec structure.
+ *               The XAAInfoRec structure contains many fields, most of
+ *               which are primitive function pointers and flags.  Each
+ *               primitive will have two or more functions and a set of
+ *               associated associated flags.  These functions can be
+ *               classified into two principle classes, the "SetupFor"
+ *               and "Subsequent" functions.  The "SetupFor" function tells
+ *               the driver that the hardware should be initialized for
+ *               a particular type of graphics operation.  After the
+ *               "SetupFor" function, one or more calls to the "Subsequent"
+ *               function will be made to indicate that an instance of the
+ *               particular primitive should be rendered by the hardware.
+ *
+ *    Arg        Type     Comment
+ *  pScrn      ScreenPtr  pointer to active Screen data
+ *
+ * Returns              :TRUE on success and FALSE on Failure
+ *
+ * Comments             :This function is called in LXScreenInit in
+ *                       amd_lx_driver.c to initialize acceleration.
+ *---------------------------------------------------------------------------*/
+Bool
+LXAccelInit(ScreenPtr pScrn)
+{
+   GeodePtr pGeode;
+   ScrnInfoPtr pScrni;
+#if DEBUGLVL>0
+   if( zdfp == NULL ) { zdfp = fopen("/tmp/xwin.log","w"); setbuf(zdfp,NULL); }
+#endif
+   DBLOG(2,"LXAccelInit()\n");
+
+   pScrni = xf86Screens[pScrn->myNum];
+   pGeode = GEODEPTR(pScrni);
+
+   switch (pScrni->bitsPerPixel) {
+   case 8:
+      gu3_img_fmt = CIMGP_SOURCE_FMT_3_3_2;
+      break;
+   case 16:
+      gu3_img_fmt = CIMGP_SOURCE_FMT_0_5_6_5;
+      break;
+   case 32:
+      gu3_img_fmt = CIMGP_SOURCE_FMT_8_8_8_8;
+      break;
+   }
+
+   gu3_xshift = pScrni->bitsPerPixel >> 4;
+
+   switch (pGeode->AccelPitch) {
+   case 1024:
+      gu3_yshift = 10;
+      break;
+   case 2048:
+      gu3_yshift = 11;
+      break;
+   case 4096:
+      gu3_yshift = 12;
+      break;
+   case 8192:
+      gu3_yshift = 13;
+      break;
+   }
+
+   /* Getting the pointer for acceleration Inforecord */
+   pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec();
+
+   /* SET ACCELERATION FLAGS */
+   localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
+
+   /* HOOK SYNCRONIZARION ROUTINE */
+   localRecPtr->Sync = LXAccelSync;
+
+#if LX_FILL_RECT_SUPPORT
+   /* HOOK FILLED RECTANGLES */
+   HOOK(SetupForSolidFill);
+   HOOK(SubsequentSolidFillRect);
+   localRecPtr->SolidFillFlags = 0;
+#endif
+
+#if LX_MONO_8X8_PAT_SUPPORT
+   /* HOOK 8x8 Mono EXPAND PATTERNS */
+   HOOK(SetupForMono8x8PatternFill);
+   HOOK(SubsequentMono8x8PatternFillRect);
+   localRecPtr->Mono8x8PatternFillFlags = 
+         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD |
+         HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
+#endif
+
+#if LX_CLREXP_8X8_PAT_SUPPORT
+   /* Color expansion */
+   HOOK(SetupForColor8x8PatternFill);
+   HOOK(SubsequentColor8x8PatternFillRect);
+   localRecPtr->Color8x8PatternFillFlags =
+         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY |
+         HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
+#endif
+
+#if LX_SCR2SCRCPY_SUPPORT
+   /* HOOK SCREEN TO SCREEN COPIES
+    * Set flag to only allow copy if transparency is enabled.
+    */
+   HOOK(SetupForScreenToScreenCopy);
+   HOOK(SubsequentScreenToScreenCopy);
+   localRecPtr->ScreenToScreenCopyFlags =
+         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+
+#if LX_BRES_LINE_SUPPORT
+   /* HOOK BRESENHAM SOLID LINES */
+   localRecPtr->SolidLineFlags = NO_PLANEMASK;
+   HOOK(SetupForSolidLine);
+   HOOK(SubsequentSolidBresenhamLine);
+   HOOK(SubsequentSolidHorVertLine);
+   HOOK(SubsequentSolidTwoPointLine);
+   localRecPtr->SolidBresenhamLineErrorTermBits = 15;
+#endif
+
+#if LX_DASH_LINE_SUPPORT
+   /* HOOK BRESENHAM DASHED LINES */
+   localRecPtr->DashedLineFlags = NO_PLANEMASK | TRANSPARENCY_ONLY |
+	 LINE_PATTERN_LSBFIRST_LSBJUSTIFIED | SCANLINE_PAD_DWORD;
+   HOOK(SetupForDashedLine);
+   HOOK(SubsequentDashedBresenhamLine);
+   HOOK(SubsequentDashedTwoPointLine);
+   localRecPtr->DashedBresenhamLineErrorTermBits = 15;
+   localRecPtr->DashPatternMaxLength = 32;
+#endif
+
+#if LX_SCR2SCREXP_SUPPORT
+   /* Color expansion */
+   HOOK(SetupForScreenToScreenColorExpandFill);
+   HOOK(SubsequentScreenToScreenColorExpandFill);
+   localRecPtr->ScreenToScreenColorExpandFillFlags =
+         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+
+   if (pGeode->AccelImageWriteBuffers) {
+#if LX_SCANLINE_SUPPORT
+      localRecPtr->ScanlineImageWriteBuffers = pGeode->AccelImageWriteBuffers;
+      localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers;
+      HOOK(SetupForScanlineImageWrite);
+      HOOK(SubsequentScanlineImageWriteRect);
+      HOOK(SubsequentImageWriteScanline);
+      localRecPtr->ScanlineImageWriteFlags = 
+         BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+#if !LX_USE_OFFSCRN_MEM
+      ImgBufOffset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase;
+#else
+      ImgLnsBuffers = (uchar *)pGeode->AccelImageWriteBuffers[0];
+#endif
+
+   } else {
+      localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
+   }
+
+   if (pGeode->AccelColorExpandBuffers) {
+#if LX_CPU2SCREXP_SUPPORT
+      /* Color expansion */
+      localRecPtr->ScanlineColorExpandBuffers = pGeode->AccelColorExpandBuffers;
+      localRecPtr->NumScanlineColorExpandBuffers = pGeode->NoOfColorExpandLines;
+      HOOK(SetupForScanlineCPUToScreenColorExpandFill);
+      HOOK(SubsequentScanlineCPUToScreenColorExpandFill);
+      HOOK(SubsequentColorExpandScanline);
+      localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = 
+            BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+      ClrLnsBuffers = (uchar *)pGeode->AccelColorExpandBuffers[0];
+   }
+
+#if LX_WRITE_PIXMAP_SUPPORT
+   HOOK(WritePixmap);
+#endif
+
+
+   return (XAAInit(pScrn, localRecPtr));
+}
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_cursor.c xf86-video-nsc-2.8.1/src/amd_lx_cursor.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_cursor.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_cursor.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,392 @@
+/*
+ * $Workfile: amd_lx_cursor.c $
+ * $Revision: #4 $
+ * $Author: raymondd $
+ *
+ * File Contents: Xfree cursor implementation routines
+ *                for geode HWcursor init.setting cursor color,image etc
+ *                are done here.
+ * Project:       Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "nsc.h"
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+/* Forward declarations of the functions */
+Bool LXHWCursorInit(ScreenPtr pScrn);
+static void LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg);
+static void LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y);
+void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src);
+void LXHideCursor(ScrnInfoPtr pScrni);
+void LXShowCursor(ScrnInfoPtr pScrni);
+static Bool LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
+extern void LXSetVideoPosition(int x, int y, int width, int height,
+				short src_w, short src_h, short drw_w,
+				short drw_h, int id, int offset,
+				ScrnInfoPtr pScrni);
+#ifdef ARGB_CURSOR
+static Bool LXUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
+static void LXLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXHWCursorInit.
+ *
+ * Description	:This function sets the cursor information by probing the
+ * hardware.
+ *
+ * Parameters.
+ *     pScrn	:Screeen pointer structure.
+ *
+ * Returns		:TRUE on success and FALSE on Failure
+ *
+ * Comments		:Geode supports the hardware_cursor,no need to enable SW
+ *                    cursor.
+*----------------------------------------------------------------------------
+*/
+Bool
+LXHWCursorInit(ScreenPtr pScrn)
+{
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   xf86CursorInfoPtr infoPtr;
+
+   infoPtr = xf86CreateCursorInfoRec();
+   if (!infoPtr)
+      return FALSE;
+   /* the geode structure is intiallized with the cursor infoRec */
+   pGeode->CursorInfo = infoPtr;
+   infoPtr->MaxWidth = 32;
+   infoPtr->MaxHeight = 32;
+   /* seeting up the cursor flags */
+   infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+	 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+	 HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+   /* cursor info ptr is intiallized with the values obtained from
+    * * durnago calls
+    */
+   infoPtr->SetCursorColors = LXSetCursorColors;
+   infoPtr->SetCursorPosition = LXSetCursorPosition;
+   infoPtr->LoadCursorImage = LXLoadCursorImage;
+   infoPtr->HideCursor = LXHideCursor;
+   infoPtr->ShowCursor = LXShowCursor;
+   infoPtr->UseHWCursor = LXUseHWCursor;
+#ifdef ARGB_CURSOR
+   infoPtr->UseHWCursorARGB = LXUseHWCursorARGB;
+   infoPtr->LoadCursorARGB = LXLoadCursorARGB;
+#endif
+
+   return (xf86InitCursor(pScrn, infoPtr));
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetCursorColors.
+ *
+ * Description	:This function sets the cursor foreground and background
+ *                    colors
+ * Parameters:
+ *    pScrni:	Screeen information pointer structure.
+ *    	   bg:	Specifies the color value of cursor background color.
+ *    	   fg:	Specifies the color value of cursor foreground color.
+ *    Returns:	none.
+ *
+ *   Comments:	The integer color value passed by this function is
+ *              converted into  * RGB  value by the gfx_set_color routines.
+ *----------------------------------------------------------------------------
+ */
+static void
+LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg)
+{
+    GeodePtr pGeode = GEODEPTR(pScrni);
+
+#ifdef ARGB_CURSOR
+    /* Don't recolour cursors set with SetCursorARGB. */
+    if (pGeode->cursor_argb)
+       return;
+#endif
+
+   vg_set_mono_cursor_colors(bg, fg);
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetCursorPosition.
+ *
+ * Description	:This function sets the cursor co -ordinates and enable the
+ *               cursor.
+ *
+ * Parameters:
+ *    pScrni: Screeen information pointer structure.
+ *    	    x: Specifies the x-cordinates of the cursor.
+ *    	    y: Specifies the y co-ordinate of the cursor.
+ *    Returns: none.
+ *
+ *----------------------------------------------------------------------------
+ */
+static void
+LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y)
+{
+   static unsigned long panOffset = 0;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   int newX, newY;
+
+   (*pGeode->Rotation)(x,y,pGeode->HDisplay,pGeode->VDisplay,&newX,&newY);
+   (*pGeode->RBltXlat)(newX,newY,32,32,&newX,&newY);
+   if (newX < -31) newX = -31;
+   if (newY < -31) newY = -31;
+
+   {  VG_PANNING_COORDINATES panning;
+      vg_set_cursor_position(newX+31, newY+31, &panning); }
+   vg_set_cursor_enable(1);
+
+#ifndef AMD_V4L2_VIDEO
+   if ((pGeode->OverlayON) && (pGeode->EnabledOutput & LX_OT_FP)) {
+      pGeode->PrevDisplayOffset = vg_get_display_offset();
+      if (pGeode->PrevDisplayOffset != panOffset) {
+	 LXSetVideoPosition(pGeode->video_x, pGeode->video_y,
+			     pGeode->video_w, pGeode->video_h,
+			     pGeode->video_srcw, pGeode->video_srch,
+			     pGeode->video_dstw, pGeode->video_dsth,
+			     pGeode->video_id, pGeode->video_offset,
+			     pGeode->video_scrnptr);
+	 panOffset = pGeode->PrevDisplayOffset;
+      }
+   }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * LXLoadCursorImage
+ *
+ * Description	:This function loads the 32x32 cursor pattern.The shape
+ *               and color is set by AND and XOR masking of arrays of 32
+ *               DWORD.
+ * Parameters:
+ *    pScrni: Screeen information pointer structure.
+ *    src    : Specifies cursor data.
+ * Returns   : none
+ *
+ *----------------------------------------------------------------------------
+*/
+void
+LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src)
+{
+   int i, n, x, y, newX, newY;
+   unsigned long andMask[32], xorMask[32];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   unsigned long mskb, rowb;
+   unsigned char *rowp = &src[0];
+   unsigned char *mskp = &src[128];
+
+   if( src != NULL ) {
+      mskb = rowb = 0;
+      for( y=32; --y>=0; ) 
+         andMask[y] = xorMask[y] = 0;
+      for( y=0; y<32; ++y ) {
+         for( x=0; x<32; ++x ) {
+            if( (i=x&7) == 0 ) {
+               rowb = (*rowp & *mskp);
+               mskb = ~(*mskp);
+               ++rowp;  ++mskp;
+            }
+            (*pGeode->Rotation)(x,y,32,32,&newX,&newY);
+            i = 7-i;  n = 31-newX;
+            andMask[newY] |= (((mskb>>i)&1)<<n);
+            xorMask[newY] |= (((rowb>>i)&1)<<n);
+         }
+      }
+   }
+   else {
+      for( y=32; --y>=0; ) {
+         andMask[y] = ~0;
+         xorMask[y] = 0;
+      }
+   }
+
+#ifdef ARGB_CURSOR
+    pGeode->cursor_argb = FALSE;
+#endif
+
+
+#if 0
+   andMask[31] = 0;
+   xorMask[31] = 0;
+   for( y=31; --y>0; ) {
+      andMask[y] &= ~0x80000001;
+      xorMask[y] &= ~0x80000001;
+   }
+   andMask[0] = 0;
+   xorMask[0] = 0;
+#endif
+
+   vg_set_mono_cursor_shape32(pGeode->CursorStartOffset,&andMask[0],&xorMask[0],31,31);
+}
+
+/*----------------------------------------------------------------------------
+ * LXHideCursor
+ *
+ * Description	:This function will disable the cursor.
+ *
+ * Parameters:
+ *    pScrni: Handles to the Screeen information pointer structure.
+ *
+ *    Returns: none.
+ *
+ *   Comments:	gfx_set_cursor enable function is hardcoded to disable
+ *		the cursor.
+ *----------------------------------------------------------------------------
+ */
+void
+LXHideCursor(ScrnInfoPtr pScrni)
+{
+   vg_set_cursor_enable(0);
+}
+
+/*----------------------------------------------------------------------------
+ * LXShowCursor
+ *
+ * Description	:This function will enable  the cursor.
+ *
+ * Parameters:
+ *	pScrni		:Handles to the Screeen information pointer structure.
+ *
+ * Returns      :none
+ *
+ * Comments		:gfx_set_cursor enable function is hardcoded to enable the
+ * 											cursor
+ *----------------------------------------------------------------------------
+*/
+void
+LXShowCursor(ScrnInfoPtr pScrni)
+{
+   vg_set_cursor_enable(1);
+}
+
+/*----------------------------------------------------------------------------
+ * LXUseHwCursor.
+ *
+ * Description	:This function will sets the hardware cursor flag in
+ *                 pscreen  structure.
+ *
+ * Parameters.
+ *	pScreen		:Handles to the Screeen pointer structure.
+ *
+ * Returns		:none
+ *
+ * Comments		:none
+ *
+ *----------------------------------------------------------------------------
+*/
+static Bool
+LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
+{
+   ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn);
+ 
+   if (pScrni->currentMode->Flags & V_DBLSCAN)
+      return FALSE;
+   return TRUE;
+}
+
+#ifdef ARGB_CURSOR
+#include "cursorstr.h"
+
+/* Determine if hardware cursor is in use. */
+static Bool LXUseHWCursorARGB (ScreenPtr pScrn, CursorPtr pCurs)
+{
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   if (LXUseHWCursor(pScrn, pCurs) &&
+      pCurs->bits->height <= HW_ARGB_CURSOR_H &&
+      pCurs->bits->width <= HW_ARGB_CURSOR_W)
+      return TRUE;
+   return FALSE;
+}
+
+static void LXLoadCursorARGB (ScrnInfoPtr pScrni, CursorPtr pCurs)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   int           x, y, w, h, newX,newY, newW, newH;
+   CARD32        *image = pCurs->bits->argb;
+   CARD32        rotated_image[HW_ARGB_CURSOR_W * HW_ARGB_CURSOR_H];
+
+   if (!image)
+      return; /* XXX can't happen */
+
+   w = pCurs->bits->width;
+   h = pCurs->bits->height;
+
+   switch( pGeode->Rotate ) 
+   {
+   case 1:
+   case 3:
+      newW=h;
+      newH=w;
+      break;
+   case 2:
+   default:
+      newW=w;
+      newH=h;
+   }
+
+   if (newW > HW_ARGB_CURSOR_W)
+       newW = HW_ARGB_CURSOR_W;
+   if (newH > HW_ARGB_CURSOR_H)
+       newH = HW_ARGB_CURSOR_H;
+
+   for (y=0;y<h;y++)
+     for (x=0;x<w;x++) {
+        (*pGeode->Rotation)(x,y,w,h,&newX,&newY);
+        rotated_image [newY*newW+newX] = image[y*w+x];
+     }
+
+   vg_set_color_cursor_shape (pGeode->CursorStartOffset,
+                              (unsigned char*)rotated_image,
+                              newW, newH, newW * 4 /*pitch*/, 31/*x_hot*/, 31/*y_hotspot*/);
+
+   pGeode->cursor_argb = TRUE;
+}
+
+#endif
+
+/* End of File */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_dga.c xf86-video-nsc-2.8.1/src/amd_lx_dga.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_dga.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_dga.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,416 @@
+/*
+ * $Workfile: amd_lx_dga.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ * 
+ * File contents: DGA(Direct Acess Graphics mode) is feature of
+ *                XFree86 that allows the program to access directly to video
+ *                memory on the graphics card.DGA supports the double
+ *                flickering.This file has the functions to support the DGA
+ *                modes.
+ *
+ * Project:       Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "nsc.h"
+#include "dgaproc.h"
+
+/* forward declarations */
+Bool LXDGAInit(ScreenPtr pScrn);
+static Bool LX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+				int *, int *, int *);
+static void LX_CloseFramebuffer(ScrnInfoPtr pScrni);
+static Bool LX_SetMode(ScrnInfoPtr, DGAModePtr);
+static int LX_GetViewport(ScrnInfoPtr);
+static void LX_SetViewport(ScrnInfoPtr, int, int, int);
+static void LX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void LX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+
+extern void LXAdjustFrame(int, int, int, int);
+extern Bool LXSwitchMode(int, DisplayModePtr, int);
+extern void LXAccelSync(ScrnInfoPtr pScrni);
+
+static DGAFunctionRec LXDGAFuncs = {
+   LX_OpenFramebuffer,
+   LX_CloseFramebuffer,
+   LX_SetMode,
+   LX_SetViewport,
+   LX_GetViewport,
+   LXAccelSync,
+   LX_FillRect,
+   LX_BlitRect,
+   NULL
+};
+
+/*----------------------------------------------------------------------------
+ * LXDGAInit.
+ *
+ * Description	:This function is used to intiallize the DGA modes and sets the
+			 	 viewport based on the screen mode.
+ * Parameters.
+ *	pScreeen	:Pointer to screen info structure.
+ *
+ * Returns		:TRUE on success and FALSE on failure.
+ *
+ * Comments		:This function prepares the DGA mode settings for
+ *				 other func reference.
+ *
+*----------------------------------------------------------------------------
+*/
+Bool
+LXDGAInit(ScreenPtr pScrn)
+{
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+   DisplayModePtr pMode, firstMode;
+   int Bpp = pScrni->bitsPerPixel >> 3;
+   int num = 0;
+   Bool oneMore;
+
+   pMode = firstMode = pScrni->modes;
+   DEBUGMSG(0, (0, X_NONE, "LXDGAInit %d\n", Bpp));
+   while (pMode) {
+
+      /* redundant but it can be used in future:if(0). */
+      if (0) {				/*pScrni->displayWidth != pMode->HDisplay */
+	 /* memory is allocated for dga to
+	  *setup the viewport and mode parameters
+	  */
+	 newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+	 oneMore = TRUE;
+      } else {
+	 /* one record is allocated here */
+	 newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+	 oneMore = FALSE;
+      }
+      if (!newmodes) {
+	 xfree(modes);
+	 return FALSE;
+      }
+      modes = newmodes;
+
+    SECOND_PASS:			/* DGA mode flgas and viewport parametrs are set here. */
+
+      currentMode = modes + num;
+      num++;
+      currentMode->mode = pMode;
+      currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+      currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+      if (pMode->Flags & V_DBLSCAN)
+	 currentMode->flags |= DGA_DOUBLESCAN;
+      if (pMode->Flags & V_INTERLACE)
+	 currentMode->flags |= DGA_INTERLACED;
+      currentMode->byteOrder = pScrni->imageByteOrder;
+      currentMode->depth = pScrni->depth;
+      currentMode->bitsPerPixel = pScrni->bitsPerPixel;
+      currentMode->red_mask = pScrni->mask.red;
+      currentMode->green_mask = pScrni->mask.green;
+      currentMode->blue_mask = pScrni->mask.blue;
+      currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
+      currentMode->viewportWidth = pMode->HDisplay;
+      currentMode->viewportHeight = pMode->VDisplay;
+      currentMode->xViewportStep = 1;
+      currentMode->yViewportStep = 1;
+      currentMode->viewportFlags = DGA_FLIP_RETRACE;
+      currentMode->offset = 0;
+      currentMode->address = pGeode->FBBase;
+      if (oneMore) {			/* first one is narrow width */
+	 currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+	 currentMode->imageWidth = pMode->HDisplay;
+	 currentMode->imageHeight = pMode->VDisplay;
+	 currentMode->pixmapWidth = currentMode->imageWidth;
+	 currentMode->pixmapHeight = currentMode->imageHeight;
+	 currentMode->maxViewportX = currentMode->imageWidth -
+	       currentMode->viewportWidth;
+	 /* this might need to get clamped to some maximum */
+	 currentMode->maxViewportY = currentMode->imageHeight -
+	       currentMode->viewportHeight;
+	 oneMore = FALSE;
+	 goto SECOND_PASS;
+      } else {
+	 currentMode->bytesPerScanline =
+	       ((pScrni->displayWidth * Bpp) + 3) & ~3L;
+	 currentMode->imageWidth = pScrni->displayWidth;
+	 currentMode->imageHeight = pMode->VDisplay;
+	 currentMode->pixmapWidth = currentMode->imageWidth;
+	 currentMode->pixmapHeight = currentMode->imageHeight;
+	 currentMode->maxViewportX = currentMode->imageWidth -
+	       currentMode->viewportWidth;
+	 /* this might need to get clamped to some maximum */
+	 currentMode->maxViewportY = currentMode->imageHeight -
+	       currentMode->viewportHeight;
+      }
+      pMode = pMode->next;
+      if (pMode == firstMode)
+	 break;
+   }
+   pGeode->numDGAModes = num;
+   pGeode->DGAModes = modes;
+   return DGAInit(pScrn, &LXDGAFuncs, modes, num);
+}
+
+/*----------------------------------------------------------------------------
+ * LX_SetMode.
+ *
+ * Description	:This function is sets into the DGA mode.
+ *.
+ * Parameters.
+ *	pScreeen	:Pointer to screen info structure.
+ *	pMode		:Points to the DGAmode ptr data
+ * Returns		:TRUE on success and FALSE on failure.
+ *
+ * Comments		:none.
+ *			
+ *
+*----------------------------------------------------------------------------
+*/
+static Bool
+LX_SetMode(ScrnInfoPtr pScrni, DGAModePtr pMode)
+{
+   static int OldDisplayWidth[MAXSCREENS];
+   int index = pScrni->pScreen->myNum;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   DEBUGMSG(0, (0, X_NONE, "LX_SetMode\n"));
+
+   if (!pMode) {
+      /* restore the original mode
+       * * put the ScreenParameters back
+       */
+      pScrni->displayWidth = OldDisplayWidth[index];
+      DEBUGMSG(0,
+	       (0, X_NONE, "LX_SetMode !pMode %d\n", pScrni->displayWidth));
+      LXSwitchMode(index, pScrni->currentMode, 0);
+      pGeode->DGAactive = FALSE;
+   } else {
+      if (!pGeode->DGAactive) {		/* save the old parameters */
+	 OldDisplayWidth[index] = pScrni->displayWidth;
+	 pGeode->DGAactive = TRUE;
+	 DEBUGMSG(0,
+		  (0, X_NONE, "LX_SetMode pMode+ NA %d\n",
+		   pScrni->displayWidth));
+      }
+      pGeode->PrevDisplayOffset = vg_get_display_offset();
+
+      pScrni->displayWidth = pMode->bytesPerScanline /
+	    (pMode->bitsPerPixel >> 3);
+      DEBUGMSG(0,
+	       (0, X_NONE, "LX_SetMode pMode+  %d\n", pScrni->displayWidth));
+      LXSwitchMode(index, pMode->mode, 0);
+   }
+   /* enable/disable Compression */
+   if (pGeode->Compression) {
+      vg_set_compression_enable(!pGeode->DGAactive);
+   }
+
+   /* enable/disable cursor */
+   if (pGeode->HWCursor) {
+      vg_set_cursor_enable(!pGeode->DGAactive);
+   }
+
+   return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LX_GetViewPort.
+ *
+ * Description	:This function is Gets the viewport window memory.
+ *.
+ * Parameters.
+ *	pScrni		:Pointer to screen info structure.
+ *	
+ * Returns		:returns the viewport status.
+ *
+ * Comments		:none.
+ *			
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LX_GetViewport(ScrnInfoPtr pScrni)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   return pGeode->DGAViewportStatus;
+}
+
+/*----------------------------------------------------------------------------
+ * LX_SetViewPort.
+ *
+ * Description	:This function is Gets the viewport window memory.
+ *
+ * Parameters.
+ *	pScrni		:Pointer to screen info structure.
+		x		:x-cordinate of viewport window
+ *		y		:y-codinate of the viewport window.
+ *	flags		:indicates the viewport to be flipped or not.
+ * Returns		:returns the viewport status  as zero.
+ *
+ * Comments		:none.
+ *			
+*----------------------------------------------------------------------------
+*/
+static void
+LX_SetViewport(ScrnInfoPtr pScrni, int x, int y, int flags)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   LXAdjustFrame(pScrni->pScreen->myNum, x, y, flags);
+   pGeode->DGAViewportStatus = 0;	/*LXAdjustFrame loops until finished */
+}
+
+/*----------------------------------------------------------------------------
+ * LX_FillRect.
+ *
+ * Description	:This function is Gets the viewport window memory.
+ *.
+ * Parameters.
+ *	pScrni		:Pointer to screen info structure.
+ *		x		:x-cordinate of viewport window
+ *		y		:y-codinate of the viewport window.
+ *		w		:width of the rectangle
+ *      h		:height of the rectangle.
+ *	color		:color to be filled in rectangle.
+ *
+ * Returns		:returns the viewport status  as zero.
+ *
+ * Comments		:This function is implemented by solidfill routines..
+ *			
+*----------------------------------------------------------------------------
+*/
+static void
+LX_FillRect(ScrnInfoPtr pScrni, int x, int y,
+	     int w, int h, unsigned long color)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   if (pGeode->AccelInfoRec) {
+      (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrni, color, GXcopy, ~0);
+      (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrni, x, y, w, h);
+      SET_SYNC_FLAG(pGeode->AccelInfoRec);
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LX_BlitRect.
+ *
+ * Description	:This function implementing Blit and it moves a
+ *			 	 Rectangular block of data from one location to other
+ *			 	 Location.
+ *
+ * Parameters.
+ *	pScrni		:Pointer to screen info structure.
+ *	srcx		:x-cordinate of the src rectangle
+ *	srcy		:y-codinate of src rectangle.
+ *	  w			:width of the rectangle
+ *    h			:height of the rectangle.
+ *	dstx		:x-cordinate of the dst rectangle.
+ *	dsty		:y -coordinates of the dst rectangle.
+ * Returns		:none.
+ *
+ * Comments		:none
+ *			
+*----------------------------------------------------------------------------
+*/
+static void
+LX_BlitRect(ScrnInfoPtr pScrni,
+	     int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   if (pGeode->AccelInfoRec) {
+      int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+      int ydir = (srcy < dsty) ? -1 : 1;
+
+      (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy)
+	    (pScrni, xdir, ydir, GXcopy, ~0, -1);
+      (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrni, srcx,
+							     srcy, dstx, dsty,
+							     w, h);
+      SET_SYNC_FLAG(pGeode->AccelInfoRec);
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LX_OpenFramebuffer.
+ *
+ * Description	:This function open the framebuffer driver for DGA.
+ *			
+ * Parameters.
+ *	pScrni		:Pointer to screen info structure.
+ *	srcx		:x-cordinate of the src rectangle
+ *	srcy		:y-codinate of src rectangle.
+ *		w		:width of the rectangle
+ *    	h		:height of the rectangle.
+ *	dstx		:x-cordinate of the dst rectangle.
+ *	dsty		:y -coordinates of the dst rectangle.
+ * Returns		:none.
+ *
+ * Comments		:none
+ *			
+*----------------------------------------------------------------------------
+*/
+static Bool
+LX_OpenFramebuffer(ScrnInfoPtr pScrni,
+		    char **name, unsigned char **mem,
+		    int *size, int *offset, int *flags)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   *name = NULL;			/* no special device */
+   *mem = (unsigned char *)pGeode->FBLinearAddr;
+   *size = pGeode->FBAvail;
+   *offset = 0;
+   *flags = DGA_NEED_ROOT;
+   return TRUE;
+}
+
+static void
+LX_CloseFramebuffer(ScrnInfoPtr pScrni)
+{
+}
+
+/* end of file */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_driver.c xf86-video-nsc-2.8.1/src/amd_lx_driver.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_driver.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_driver.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,2836 @@
+/*
+ * $Workfile: amd_lx_driver.c $
+ * $Revision: #6 $
+ * $Author: raymondd $
+ *
+ * File Contents: This is the main module configures the interfacing 
+ *                with the X server. The individual modules will be 
+ *                loaded based upon the options selected from the 
+ *                XF86Config. This file also has modules for finding 
+ *                supported modes, turning on the modes based on options.
+ *
+ * Project:       Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Includes that are used by all drivers */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86_libc.h"
+#include "xf86Resources.h"
+
+/* We may want inb() and outb() */
+#include "compiler.h"
+
+/* We may want to access the PCI config space */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+/* Colormap handling stuff */
+#include "xf86cmap.h"
+
+#define RC_MAX_DEPTH 24
+
+#include "nsc.h"
+#include "cim_defs.h"
+#include "cim_regs.h"
+#include "cim_dev.h"
+
+/* Frame buffer stuff */
+#include "fb.h"
+
+#include "shadowfb.h"
+
+/* Machine independent stuff */
+#include "mipointer.h"
+#include "mibank.h"
+#include "micmap.h"
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+#include "vgaHW.h"
+#include "vbe.h"
+
+/* Check for some extensions */
+#ifdef XFreeXDGA
+#define _XF86_DGA_SERVER_
+#include <X11/extensions/xf86dgastr.h>
+#endif /* XFreeXDGA */
+
+#ifdef DPMSExtension
+#include "globals.h"
+#include "opaque.h"
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+#endif /* DPMSExtension */
+
+#include "amd_lx_vga.c"
+
+extern SymTabRec GeodeChipsets[];
+extern OptionInfoRec GeodeOptions[];
+
+/* Forward definitions */
+static Bool LXPreInit(ScrnInfoPtr, int);
+static Bool LXScreenInit(int, ScreenPtr, int, char **);
+static Bool LXEnterVT(int, int);
+static void LXLeaveVT(int, int);
+static void LXFreeScreen(int, int);
+void LXAdjustFrame(int, int, int, int);
+Bool LXSwitchMode(int, DisplayModePtr, int);
+static int LXValidMode(int, DisplayModePtr, Bool, int);
+static void LXLoadPalette(ScrnInfoPtr pScrni,
+			   int numColors, int *indizes,
+			   LOCO * colors, VisualPtr pVisual);
+static Bool LXMapMem(ScrnInfoPtr);
+static Bool LXUnmapMem(ScrnInfoPtr);
+
+extern Bool LXAccelInit(ScreenPtr pScrn);
+extern Bool LXHWCursorInit(ScreenPtr pScrn);
+extern void LXHideCursor(ScrnInfoPtr pScrni);
+extern void LXShowCursor(ScrnInfoPtr pScrni);
+extern void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src);
+extern void LXPointerMoved(int index, int x, int y);
+extern void LXRotationInit(ScrnInfoPtr pScrni);
+extern void LXShadowFBInit(ScreenPtr pScrn,GeodePtr pGeode,int bytpp);
+extern void LXInitVideo(ScreenPtr pScrn);
+extern Bool LXDGAInit(ScreenPtr pScrn);
+
+unsigned char *XpressROMPtr;
+unsigned long fb;
+
+/* List of symbols from other modules that this module references.The purpose
+* is that to avoid unresolved symbol warnings
+*/
+extern const char *nscVgahwSymbols[];
+extern const char *nscVbeSymbols[];
+extern const char *nscInt10Symbols[];
+
+extern const char *nscFbSymbols[];
+extern const char *nscXaaSymbols[];
+extern const char *nscRamdacSymbols[];
+extern const char *nscShadowSymbols[];
+
+void LXSetupChipsetFPtr(ScrnInfoPtr pScrni);
+GeodePtr LXGetRec(ScrnInfoPtr pScrni);
+void lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp);
+void lx_clear_fb(ScrnInfoPtr pScrni);
+void lx_disable_dac_power(ScrnInfoPtr pScrni,int option);
+void lx_enable_dac_power(ScrnInfoPtr pScrni,int option);
+
+#if DEBUGLVL>0
+FILE *zdfp = NULL;
+#endif
+
+/* Reference: Video Graphics Suite Specification:
+ * VG Config Register (0x00) page 16
+ * VG FP Register (0x02) page 18 */
+
+#define LX_READ_VG(reg) ( outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E) )
+
+/* panel resolutiosn decode of FP config reg */
+
+static struct sLXFpResolution {
+  int xres, yres;
+} lx_fp_resolution[] = {
+  {  320,  240 }, {  640,  480 }, {  800,  600 }, { 1024,  768 },
+   { 1152, 864 }, { 1280, 1024 }, { 1600, 1200 }, {    0,    0 }
+};
+
+/* Get the information from the BIOS regarding the panel */
+
+static int
+lx_get_panel_info(int *xres, int *yres)
+{
+  unsigned short reg = LX_READ_VG(0x02);
+  *xres = lx_fp_resolution[(reg>>3) & 0x07].xres;
+  *yres = lx_fp_resolution[(reg>>3) & 0x07].yres;
+  return 0;
+}
+
+static int
+lx_panel_configured(void)
+{
+  unsigned short reg = LX_READ_VG(0x00); 
+  unsigned char ret = (reg >> 8) & 0x7;
+  return (ret == 1) || (ret == 5) ? 1 : 0;
+}
+
+void
+LXSetupChipsetFPtr(ScrnInfoPtr pScrni)
+{
+#if DEBUGLVL>0
+   if( zdfp == NULL ) { zdfp = fopen("/tmp/xwin.log","w"); setbuf(zdfp,NULL); }
+#endif
+   DEBUGMSG(1,(0, X_INFO, "LXSetupChipsetFPtr!\n"));
+   pScrni->PreInit = LXPreInit;
+   pScrni->ScreenInit = LXScreenInit;
+   pScrni->SwitchMode = LXSwitchMode;
+   pScrni->AdjustFrame = LXAdjustFrame;
+   pScrni->EnterVT = LXEnterVT;
+   pScrni->LeaveVT = LXLeaveVT;
+   pScrni->FreeScreen = LXFreeScreen;
+   pScrni->ValidMode = LXValidMode;
+}
+
+#ifdef AMD_V4L2_VIDEO
+void
+LXInitVideo(ScreenPtr pScrn)
+{
+   GeodePtr pGeode;
+   int num_adaptors;
+   XF86VideoAdaptorPtr *adaptors;
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   pGeode = GEODEPTR(pScrni);
+   if (!pGeode->NoAccel) {
+      num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors);
+      if( num_adaptors > 0 )
+         xf86XVScreenInit(pScrn,adaptors,num_adaptors);
+   }
+}
+#else
+extern void LXInitVideo(ScreenPtr pScrn);
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXGetRec.
+ *
+ * Description	:This function allocate an GeodeRec and hooked into
+ * pScrni 	 str driverPrivate member of ScreeenInfo
+ * 				 structure.
+ * Parameters.
+ * pScrni 	:Pointer handle to the screenonfo structure.
+ *
+ * Returns		:allocated driver structure.
+ *
+ * Comments     :none
+ *
+*----------------------------------------------------------------------------
+*/
+GeodePtr
+LXGetRec(ScrnInfoPtr pScrni)
+{
+   if (!pScrni->driverPrivate) {
+      GeodePtr pGeode;
+
+      pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1);
+#if INT10_SUPPORT
+      pGeode->vesa = xcalloc(sizeof(VESARec), 1);
+#endif
+   }
+   return GEODEPTR(pScrni);
+}
+
+/*----------------------------------------------------------------------------
+ * LXFreeRec.
+ *
+ * Description	:This function deallocate an GeodeRec and freed from
+ *               pScrni str driverPrivate member of ScreeenInfo
+ *               structure.
+ * Parameters.
+ * pScrni	:Pointer handle to the screenonfo structure.
+ *
+ * Returns		:none
+ *
+ * Comments     :none
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXFreeRec(ScrnInfoPtr pScrni)
+{
+   if (pScrni->driverPrivate == NULL) {
+      return;
+   }
+   xfree(pScrni->driverPrivate);
+   pScrni->driverPrivate = NULL;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSaveScreen.
+ *
+ * Description	:This is todo the screen blanking
+ *
+ * Parameters.
+ *     pScrn	:Handle to ScreenPtr structure.
+ *     mode		:mode is used by vgaHWSaveScren to check blnak os on.
+ * 												
+ * Returns		:TRUE on success and FALSE on failure.
+ *
+ * Comments     :none
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXSaveScreen(ScreenPtr pScrn, int mode)
+{
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   DEBUGMSG(0,(0, X_INFO, "LXSaveScreen!\n"));
+
+   if (!pScrni->vtSema)
+      return vgaHWSaveScreen(pScrn, mode);
+
+   return TRUE;
+}
+
+static xf86MonPtr
+LXProbeDDC(ScrnInfoPtr pScrni, int index)
+{
+   vbeInfoPtr pVbe;
+   xf86MonPtr ddc = NULL;
+
+   if (xf86LoadSubModule(pScrni, "vbe")) {
+      pVbe = VBEInit(NULL, index);
+      ddc = vbeDoEDID(pVbe, NULL);
+      vbeFree(pVbe);
+   }
+   return ddc;
+}
+
+static void
+LXDecodeDDC(ScrnInfoPtr pScrni,xf86MonPtr ddc)
+{
+   int i;
+   DEBUGMSG(1,(0, X_INFO,
+     "Detected monitor DDC (%4s) id %d serno %d week %d year %d nsects %d\n",
+     &ddc->vendor.name[0],ddc->vendor.prod_id,ddc->vendor.serial,
+     ddc->vendor.week,ddc->vendor.year,ddc->no_sections));
+   for( i=0; i<DET_TIMINGS; ++i ) {
+      struct detailed_monitor_section *dp = &ddc->det_mon[i];
+      switch( dp->type ) {
+      case DT: {
+         struct detailed_timings *r = &dp->section.d_timings;
+         DEBUGMSG(1,(0, X_INFO, "  mon det timing %0.3f  %dx%d\n",
+           r->clock/1000000.0, r->h_active, r->v_active));
+         DEBUGMSG(1,(0, X_INFO, "  mon border %d,%d laced %d stereo %d sync %d, misc %d\n",
+           r->h_border, r->v_border, r->interlaced, r->stereo, r->sync, r->misc));
+         } break;
+      case DS_SERIAL: {
+         char *serial_no = (char*)&dp->section.serial[0];
+         DEBUGMSG(1,(0, X_INFO, "  mon serial %13s\n",serial_no));
+         } break;
+      case DS_ASCII_STR: {
+         char *ascii = (char*)&dp->section.ascii_data[0];
+         DEBUGMSG(1,(0, X_INFO, "  mon ascii_str %13s\n",ascii));
+         } break;
+      case DS_NAME: {
+         char *name = (char*)&dp->section.name[0];
+         DEBUGMSG(1,(0, X_INFO, "  mon name %13s\n",name));
+         } break;
+      case DS_RANGES: {
+         struct monitor_ranges *r = &dp->section.ranges;
+         DEBUGMSG(1,(0, X_INFO, "  mon ranges v %d-%d h %d-%d clk %d\n",
+           r->min_v, r->max_v, r->min_h, r->max_h, r->max_clock));
+         } break;
+      case DS_WHITE_P: {
+         struct whitePoints *wp = &dp->section.wp[0];
+         DEBUGMSG(1,(0, X_INFO, "  mon whitept %f,%f %f,%f idx %d,%d gamma %f,%f\n",
+           wp[1].white_x, wp[1].white_y, wp[2].white_x, wp[2].white_y,
+           wp[1].index, wp[2].index, wp[1].white_gamma, wp[2].white_gamma));
+         } break;
+      case DS_STD_TIMINGS: {
+         struct std_timings *t = &dp->section.std_t[0];
+         DEBUGMSG(1,(0, X_INFO, "  mon std_timing no   size   @rate, id\n"));
+         for( i=0; i<5; ++i )
+            DEBUGMSG(1,(0, X_INFO, "                 %d %5dx%-5d @%-4d %d\n",
+              i, t[i].hsize, t[i].vsize, t[i].refresh, t[i].id));
+         } break;
+      }
+   }
+}
+
+static void
+LXFBAlloc(int fd,unsigned int offset, unsigned int size)
+{
+   cim_mem_req_t req;
+   memset(&req,0,sizeof(req));
+   strcpy(&req.owner[0],"XFree86");
+   sprintf(&req.name[0],"%08lx",offset);
+   req.flags = CIM_F_PUBLIC;
+   req.size  = size;
+   ioctl(fd,CIM_RESERVE_MEM,&req);
+}
+
+/* check for "tv-" or "pnl-" in mode name, decode suffix */
+/*  return -1 if mode name is not a known tv/pnl mode */
+static int
+lx_tv_mode(DisplayModePtr pMode)
+{
+   int tv_mode = -1;
+   char *bp, *cp;
+   cp = pMode->name;
+   if( (*(bp=cp) == 't' && *++bp == 'v') ||
+       (*(bp=cp) == 'p' && *++bp == 'n' && *++bp == 'l') ) {
+      if( *++bp == '-' ) {
+         if( xf86NameCmp("ntsc",++bp) == 0 )         tv_mode = VG_TVMODE_NTSC;
+         else if( xf86NameCmp("pal",bp) == 0 )       tv_mode = VG_TVMODE_PAL;
+         else if( xf86NameCmp("6x4_ntsc",bp) == 0 )  tv_mode = VG_TVMODE_6X4_NTSC;
+         else if( xf86NameCmp("8x6_ntsc",bp) == 0 )  tv_mode = VG_TVMODE_8X6_NTSC;
+         else if( xf86NameCmp("10x7_ntsc",bp) == 0 ) tv_mode = VG_TVMODE_10X7_NTSC;
+         else if( xf86NameCmp("6x4_pal",bp) == 0 )   tv_mode = VG_TVMODE_6X4_PAL;
+         else if( xf86NameCmp("8x6_pal",bp) == 0 )   tv_mode = VG_TVMODE_8X6_PAL;
+         else if( xf86NameCmp("10x7_pal",bp) == 0 )  tv_mode = VG_TVMODE_10X7_PAL;
+         else if( xf86NameCmp("480p",bp) == 0 )      tv_mode = VG_TVMODE_480P;
+         else if( xf86NameCmp("720p",bp) == 0 )      tv_mode = VG_TVMODE_720P;
+         else if( xf86NameCmp("1080i",bp) == 0 )     tv_mode = VG_TVMODE_1080I;
+      }
+   }
+   return tv_mode;
+}
+
+static int
+lx_tv_mode_interlaced(int tv_mode)
+{
+   switch( tv_mode ) {
+   case VG_TVMODE_NTSC:
+   case VG_TVMODE_PAL:
+   case VG_TVMODE_1080I:
+      return 1;
+   }
+   return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * LXPreInit.
+ *
+ * Description	:This function is called only once ate teh server startup
+ *
+ * Parameters.
+ *  pScrni :Handle to ScreenPtr structure.
+ *  options       :may be used to check the probeed one with config.
+ * 												
+ * Returns		:TRUE on success and FALSE on failure.
+ *
+ * Comments     :none.
+ *----------------------------------------------------------------------------
+ */
+static Bool
+LXPreInit(ScrnInfoPtr pScrni, int options)
+{
+   ClockRangePtr GeodeClockRange;
+   MessageType from;
+   int i = 0;
+   GeodePtr pGeode;
+   char *mod = NULL;
+   xf86MonPtr ddc = NULL;
+   Q_WORD msrValue;
+   unsigned long offset, length, fb_top;
+   char dev_name[64], dev_owner[64];
+   FILE *fp;  int fd;
+#if INT10_SUPPORT
+   VESAPtr pVesa;
+#endif
+   unsigned int PitchInc, minPitch, maxPitch;
+   unsigned int minHeight, maxHeight;
+   unsigned int flags, fmt, high, low;
+   int tv_encoder, tv_bus_fmt, tv_601_fmt;
+   int tv_conversion, tvox, tvoy, tv_flags;
+   int tv_601_flags, tv_vsync_shift, tv_vsync_select;
+   int tv_vsync_shift_count;
+   const char *s;
+   char **modes;
+
+   /*
+   * Setup the ClockRanges, which describe what clock ranges are
+   * available, and what sort of modes they can be used for.
+   */
+   GeodeClockRange = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1);
+   GeodeClockRange->next = NULL;
+   GeodeClockRange->minClock =  25175;
+   GeodeClockRange->maxClock = 341350;
+   GeodeClockRange->clockIndex = -1; /* programmable */
+   GeodeClockRange->interlaceAllowed = TRUE;
+   GeodeClockRange->doubleScanAllowed = FALSE; /* XXX check this */
+
+   /* Select valid modes from those available */
+   minPitch = 1024;   maxPitch = 8192;	/* Can support upto 1920x1440 32Bpp */
+   minHeight = 400;   maxHeight = 2048;	/* Can support upto 1920x1440 32Bpp */
+					/* need height >= maxWidth for rotate */
+
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit!\n"));
+   /* Allocate driver private structure */
+   if (!(pGeode = LXGetRec(pScrni)))
+      return FALSE;
+
+   DEBUGMSG(1, (0, X_NONE, "pGeode = %p\n", (void*)pGeode));
+
+   /* This is the general case */
+   for (i = 0; i < pScrni->numEntities; i++) {
+      pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[i]);
+      if (pGeode->pEnt->resources)
+	 return FALSE;
+      pGeode->Chipset = pGeode->pEnt->chipset;
+      pScrni->chipset = (char *)xf86TokenToString(GeodeChipsets,
+						       pGeode->pEnt->chipset);
+   }
+
+   if( (options & PROBE_DETECT) != 0 ) {
+      ConfiguredMonitor = LXProbeDDC(pScrni, pGeode->pEnt->index);
+      return TRUE;
+   }
+
+#if INT10_SUPPORT
+   if (!xf86LoadSubModule(pScrni, "int10"))
+      return FALSE;
+   xf86LoaderReqSymLists(nscInt10Symbols, NULL);
+#endif
+
+   /* If the vgahw module would be needed it would be loaded here */
+   if (!xf86LoadSubModule(pScrni, "vgahw")) {
+      return FALSE;
+   }
+   xf86LoaderReqSymLists(nscVgahwSymbols, NULL);
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(1)!\n"));
+   /* Do the cimarron hardware detection */
+   init_detect_cpu(&pGeode->cpu_version,&pGeode->cpu_revision);
+
+   /* find the base chipset core. Currently there can be only one 
+    * chip active at any time.
+    */
+   if ((pGeode->cpu_version & 0xFF) != CIM_CPU_GEODELX) {
+      ErrorF("Chipset not GEODELX !!!\n");
+      return FALSE;
+   }
+   pGeode->DetectedChipSet = LX;
+   DEBUGMSG(1,(0, X_INFO, "Detected BaseChip (%d)\n", pGeode->DetectedChipSet));
+
+   /* LX : Can have CRT or PANEL/TVO only */
+   msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msrValue);
+   fmt = (msrValue.low>>3) & 0x07;
+   switch( fmt ) {
+   case 4:
+   case 2:
+   case 0:
+      flags = LX_OT_CRT;
+      break;
+   case 1:
+   case 3:
+   case 5:
+      flags = LX_OT_FP;
+      if( (msrValue.low & 0x8000) != 0 ) flags |= LX_OT_CRT;
+      break;
+   case 6:
+      flags = LX_OT_VOP;
+      break;
+   case 7:
+      flags = LX_OT_DRGB;
+      break;
+   }
+
+   /* currently supported formats */
+   flags &= (LX_OT_FP | LX_OT_CRT | LX_OT_VOP);
+   /*  can switch from crt/pnl vop, but not the other way */
+   flags |= LX_OT_VOP;
+   pGeode->EnabledOutput = flags;
+
+   xf86DrvMsg(0, X_INFO, "AMD LX Output Formats -%sCRT,%sVOP,%sFP,%sDRGB\n",
+      ((flags & LX_OT_CRT) ? " " : " No "), ((flags & LX_OT_VOP) ? " " : " No "),
+      ((flags & LX_OT_FP)  ? " " : " No "), ((flags & LX_OT_DRGB)? " " : " No "));
+
+   pGeode->vid_version = CIM_CPU_GEODELX;
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(1.2)!\n"));
+   init_read_base_addresses (&(pGeode->InitBaseAddress));
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(1.4)!\n"));
+
+   pGeode->FBLinearAddr = pGeode->InitBaseAddress.framebuffer_base;
+   fb_top = pGeode->InitBaseAddress.framebuffer_size;
+
+   if (pGeode->pEnt->device->videoRam == 0) {
+      from = X_PROBED;
+      pScrni->videoRam = fb_top / 1024;
+   } else {
+      pScrni->videoRam = pGeode->pEnt->device->videoRam;
+      from = X_CONFIG;
+      fb_top = pScrni->videoRam << 10;
+   }
+
+   DEBUGMSG(1, (pScrni->scrnIndex, from, "VideoRam: %lu kByte\n",
+		(unsigned long)pScrni->videoRam));
+
+   pGeode->CmdBfrOffset = 0;
+   pGeode->CmdBfrSize = 0;
+
+   /* try to cause modules to load now, to reserve fb mem for other drivers */
+   pGeode->cimFd = open("/dev/cimarron",O_RDONLY);
+   if( pGeode->cimFd < 0 )
+      pGeode->cimFd = open("/dev/cim",O_RDONLY);
+   DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "/dev/cimarron: fd=%d\n",pGeode->cimFd));
+   if( (fd=open("/dev/video",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video0",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video1",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video2",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video3",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video/video0",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video/video1",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video/video2",O_RDONLY)) >= 0 ) close(fd);
+   if( (fd=open("/dev/video/video3",O_RDONLY)) >= 0 ) close(fd);
+
+   DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "open cim map\n"));
+   if( (fp=fopen("/proc/driver/cimarron/map","r")) != NULL ) {
+      low = 0;
+      high = fb_top;
+
+      DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "scan cim map\n"));
+      while( fscanf(fp,"%63s %63s %x %lx %lx\n",
+                       &dev_owner[0],&dev_name[0],&flags,&offset,&length) == 5 ) {
+         if( offset < pGeode->FBLinearAddr ) continue;
+         offset -= pGeode->FBLinearAddr;
+         if( (flags & CIM_F_CMDBUF) != 0 ) {
+            pGeode->CmdBfrOffset = offset;
+            pGeode->CmdBfrSize = length;
+         }
+         if( offset >= fb_top ) continue;
+         if( (flags & CIM_F_PRIVATE) != 0 )
+           if( offset < high ) high = offset;
+         if( offset+length >= fb_top )
+            length = fb_top - offset;
+         if( (flags & CIM_F_PUBLIC) != 0 || (flags & CIM_F_FREE) != 0 )
+            if( offset+length > low ) low = offset+length;
+      }
+      fclose(fp);
+      fb_top = high < low ? high : low;
+   }
+
+   DEBUGMSG(1,(0, X_INFO, "fb_top = %08lx\n", fb_top));
+   DEBUGMSG(1, (pScrni->scrnIndex, X_INFO,
+             "cmd bfr (map) %08lx/%08lx\n",pGeode->CmdBfrOffset,pGeode->CmdBfrSize));
+
+   /* if cimarron module not reporting, use default buffer parameters */
+   if( pGeode->CmdBfrSize == 0 ) {
+      if( fb_top < CIM_CMD_BFR_SZ ) {
+         ErrorF("No memory for CMD_BFR !!!\n");
+         return FALSE;
+      }
+      pGeode->CmdBfrSize = CIM_CMD_BFR_SZ;
+      fb_top -= pGeode->CmdBfrSize;
+      pGeode->CmdBfrOffset = fb_top;
+   }
+
+   if( pGeode->CmdBfrSize < CIM_CMD_BFR_MIN ) {
+      ErrorF("Not enough memory for CMD_BFR !!!\n");
+      return FALSE;
+   }
+   DEBUGMSG(1, (pScrni->scrnIndex, X_INFO,
+             "cmd bfr (actual) %08lx/%08lx\n",pGeode->CmdBfrOffset,pGeode->CmdBfrSize));
+
+   /* now soak up all of the usable framebuffer memory */
+   if( pGeode->cimFd >= 0 ) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "alloc cim map\n"));
+      for(;;) {
+         if( (fp=fopen("/proc/driver/cimarron/map","r")) == NULL ) break;
+         low = fb_top;
+         high = 0;
+         while( fscanf(fp,"%63s %63s %x %lx %lx\n",
+                          &dev_owner[0],&dev_name[0],&flags,&offset,&length) == 5 ) {
+            if( offset < pGeode->FBLinearAddr ) continue;
+            offset -= pGeode->FBLinearAddr;
+            if( offset >= fb_top ) continue;
+            if( (flags & CIM_F_FREE) == 0 ) continue;
+            if( low < offset ) continue;
+            low = offset;
+            if( offset+length > fb_top )
+               length = fb_top - offset;
+            high = length;
+         }
+         fclose(fp);
+         if( high == 0 ) break;
+         LXFBAlloc(pGeode->cimFd,low,high);
+      }
+      DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "check cim map\n"));
+      /* only shared memory allowed below fb_top */
+      if( (fp=fopen("/proc/driver/cimarron/map","r")) != NULL ) {
+         low = 0;
+         while( fscanf(fp,"%63s %63s %x %lx %lx\n",
+                          &dev_owner[0],&dev_name[0],&flags,&offset,&length) == 5 ) {
+            if( offset < pGeode->FBLinearAddr ) continue;
+            offset -= pGeode->FBLinearAddr;
+            if( offset >= fb_top ) continue;
+            if( (flags&CIM_F_PUBLIC) == 0 ) {
+               low = 1;  break;
+            }
+         }
+         fclose(fp);
+         if( low != 0 ) {
+            ErrorF("Not able to claim free FB memory !!!\n");
+            return FALSE;
+         }
+      }
+   }
+
+   pGeode->FBTop = fb_top;
+   if( fb_top < GP3_SCRATCH_BUFFER_SIZE ) {
+      ErrorF("No available FB memory !!!\n");
+      return FALSE;
+   }
+
+   /* must remove cimarron scratch buffer from FB */
+   pGeode->FBAvail = fb_top - GP3_SCRATCH_BUFFER_SIZE;
+
+   DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "FBAvail = %08lx\n",pGeode->FBAvail));
+   if (pGeode->DetectedChipSet & LX) {
+      pGeode->cpu_reg_size = 0x4000;
+      pGeode->gp_reg_size = 0x4000;
+      pGeode->vg_reg_size = 0x4000;
+      pGeode->vid_reg_size = 0x4000;
+      pGeode->vip_reg_size = 0x4000;
+   } else {
+      pGeode->cpu_reg_size = 0x9000;
+      pGeode->vid_reg_size = 0x1000;
+   }
+
+   if (!LXMapMem(pScrni))
+      return FALSE;
+
+   /* KFB will Knock of VGA */
+   /* check if VGA is active */
+   pGeode->FBVGAActive = gu3_get_vga_active();
+
+   DEBUGMSG(1, (0, X_PROBED, "VGA = %d\n", pGeode->FBVGAActive));
+
+   /* Fill in the monitor field */
+   pScrni->monitor = pScrni->confScreen->monitor;
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(2)!\n"));
+   /* Determine depth, bpp, etc. */
+   if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb|Support32bppFb))
+      return FALSE;
+
+   if( !((pScrni->depth == 8) || (pScrni->depth == 16) ||
+         (pScrni->depth == 24) || (pScrni->depth == 32))) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+        "Given depth (%d bpp) is not supported by this driver\n",
+        pScrni->depth));
+      return FALSE;
+   }
+
+   /*This must happen after pScrni->display has been set
+    * * because xf86SetWeight references it.
+    */
+   if (pScrni->depth > 8) {
+      /* The defaults are OK for us */
+      rgb BitsPerComponent = { 0, 0, 0 };
+      rgb BitMask = { 0, 0, 0 };
+
+      if (pScrni->depth > 16) {
+	 /* we are operating in 24 bpp, Redcloud */
+	 BitsPerComponent.red = 8;
+	 BitsPerComponent.green = 8;
+	 BitsPerComponent.blue = 8;
+
+	 BitMask.red   = 0xFF0000;
+	 BitMask.green = 0x00FF00;
+	 BitMask.blue  = 0x0000FF;
+      }
+      if( xf86SetWeight(pScrni, BitsPerComponent, BitMask) == 0 )
+         return FALSE;
+   }
+   
+
+   xf86PrintDepthBpp(pScrni);
+
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(3)!\n"));
+
+   if (!xf86SetDefaultVisual(pScrni, -1))
+      return FALSE;
+
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(4)!\n"));
+
+   /* The new cmap layer needs this to be initialized */
+   if (pScrni->depth > 1) {
+      Gamma zeros = { 0.0, 0.0, 0.0 };
+
+      if (!xf86SetGamma(pScrni, zeros)) {
+	 return FALSE;
+      }
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(5)!\n"));
+
+   /* We use a programmable clock */
+   pScrni->progClock = TRUE;
+
+   /*Collect all of the relevant option flags
+    * *(fill in pScrni->options)
+    */
+   xf86CollectOptions(pScrni, NULL);
+
+   /*Process the options */
+   xf86ProcessOptions(pScrni->scrnIndex, pScrni->options,
+		      GeodeOptions);
+
+#if INT10_SUPPORT
+   pVesa = pGeode->vesa;
+   /* Initialize Vesa record */
+
+   if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) {
+      xf86DrvMsg(0, X_ERROR, "Int10 initialization failed.\n");
+      return (FALSE);
+   }
+#endif
+
+   /*Set the bits per RGB for 8bpp mode */
+   if (pScrni->depth == 8) {
+      /* Default to 8 */
+      pScrni->rgbBits = 8;
+   }
+   from = X_DEFAULT;
+
+   pGeode->FPGeomDstSet = 0;
+   if( (s=xf86GetOptValString(GeodeOptions, OPTION_FP_DEST_GEOM)) != NULL ) {
+      char *sp;
+      int xres = strtoul(s,&sp,0);
+      if( sp != NULL && *sp == 'x' ) {
+         int yres = strtoul(sp+1,&sp,0);
+         if( sp != NULL && *sp == 0 ) {
+            if( xres > 0 && xres <= maxPitch &&
+                yres >= minHeight && yres <= maxHeight ) {
+               pGeode->FPGeomDstSet = 1;
+               pGeode->FPGeomDstX = xres;
+               pGeode->FPGeomDstY = yres;
+            }
+            else
+               DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+                        "FP_DEST_GEOM \"%dx%d\" out of range\n",xres,yres));
+         }
+      }
+      if( pGeode->FPGeomDstSet == 0 ) {
+         DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+                  "FP_DEST_GEOM \"%s\" not recognized\n",s));
+         return FALSE;
+      }
+      pGeode->EnabledOutput |= LX_OT_FP;
+   }
+
+   pGeode->FPGeomActSet = 0;
+   if( (s=xf86GetOptValString(GeodeOptions, OPTION_FP_ACTIVE_GEOM)) != NULL ) {
+      char *sp;
+      int xres = strtoul(s,&sp,0);
+      if( sp != NULL && *sp == 'x' ) {
+         int yres = strtoul(sp+1,&sp,0);
+         if( sp != NULL && *sp == 0 ) {
+            if( xres > 0 && xres <= maxPitch &&
+                yres >= minHeight && yres <= maxHeight ) {
+               pGeode->FPGeomActSet = 1;
+               pGeode->FPGeomActX = xres;
+               pGeode->FPGeomActY = yres;
+            }
+            else
+               DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+                        "FP_ACTIVE_GEOM \"%s\" out of range\n",s));
+         }
+      }
+      if( pGeode->FPGeomActSet == 0 ) {
+         DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+                  "FP_ACTIVE_GEOM \"%s\" not recognized\n",s));
+         return FALSE;
+      }
+      pGeode->EnabledOutput |= LX_OT_FP;
+   }
+
+   if( (pGeode->EnabledOutput & LX_OT_FP) !=0 ) {
+      if( pGeode->FPGeomDstSet == 0 ) {
+         if( lx_panel_configured() == 0 ) {
+            ErrorF("Panel configured and enabled but not configured in BIOS !!!\n");
+            return FALSE;
+         }
+         lx_get_panel_info(&pGeode->FPBiosResX, &pGeode->FPBiosResY);
+         DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FP Bios panel configuation used\n"));
+         pGeode->FPGeomDstX = pGeode->FPBiosResX;
+         pGeode->FPGeomDstY = pGeode->FPBiosResY;
+      }
+      if( pGeode->FPGeomActSet == 0 ) {
+         pGeode->FPGeomActX = pGeode->FPGeomDstX;
+         pGeode->FPGeomActY = pGeode->FPGeomDstY;
+      }
+      if( pGeode->FPGeomActX > pGeode->FPGeomDstX ||
+          pGeode->FPGeomActY > pGeode->FPGeomDstY ) {
+         ErrorF("FP Geom params Active %dx%d bigger than Dest %dx%d\n",
+                pGeode->FPGeomActX,pGeode->FPGeomActY,pGeode->FPGeomDstX, pGeode->FPGeomDstY);
+         return FALSE;
+      }
+      DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FP Geom params Dest %dx%d, Active %dx%d\n",
+	       pGeode->FPGeomDstX, pGeode->FPGeomDstY,pGeode->FPGeomActX,pGeode->FPGeomActY));
+   }
+
+   if (xf86IsOptionSet(GeodeOptions,OPTION_FLATPANEL)) {
+      if (xf86ReturnOptValBool(GeodeOptions, OPTION_FLATPANEL, TRUE)) {
+         if( (pGeode->EnabledOutput & LX_OT_FP) != 0 ) {
+            DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FlatPanel Selected\n"));
+         }
+         else
+            DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, 
+                      "FlatPanel Selected, but not available - ignored\n"));
+      }
+      else {
+         if( (pGeode->EnabledOutput & LX_OT_FP) != 0 ) {
+            DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FlatPanel configured, but not enabled\n"));
+            pGeode->EnabledOutput &= ~LX_OT_FP;
+         }
+      }
+   }
+
+   /*
+    * *The preferred method is to use the "hw cursor" option as a tri-state
+    * *option, with the default set above.
+    */
+   pGeode->HWCursor = TRUE;
+   if (xf86GetOptValBool(GeodeOptions, OPTION_HW_CURSOR, &pGeode->HWCursor)) {
+      from = X_CONFIG;
+   }
+   /* For compatibility, accept this too (as an override) */
+   if (xf86ReturnOptValBool(GeodeOptions, OPTION_SW_CURSOR, FALSE)) {
+      from = X_CONFIG;
+      pGeode->HWCursor = FALSE;
+   }
+   DEBUGMSG(1, (pScrni->scrnIndex, from, "Using %s cursor\n",
+		pGeode->HWCursor ? "HW" : "SW"));
+
+   pGeode->Compression = TRUE;
+   if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOCOMPRESSION, FALSE)) {
+      pGeode->Compression = FALSE;
+      DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "NoCompression\n"));
+   }
+
+   pGeode->NoAccel = FALSE;
+   if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOACCEL, FALSE)) {
+      pGeode->NoAccel = TRUE;
+      DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Acceleration disabled\n"));
+   }
+
+   if (!xf86GetOptValInteger(GeodeOptions, OPTION_OSM_IMG_BUFS,
+			     &(pGeode->NoOfImgBuffers)))
+      pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS;
+   DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+		"NoOfImgBuffers = %d\n", pGeode->NoOfImgBuffers));
+   if (!xf86GetOptValInteger(GeodeOptions, OPTION_OSM_CLR_BUFS,
+			     &(pGeode->NoOfColorExpandLines)))
+      pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS;
+   if( pGeode->NoOfColorExpandLines <= 0 )
+      pGeode->NoOfColorExpandLines = 0;
+   DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+		"NoOfColorExpandLines = %d\n", pGeode->NoOfColorExpandLines));
+
+   pGeode->CustomMode = FALSE;
+   if (xf86ReturnOptValBool(GeodeOptions, OPTION_CUSTOM_MODE, FALSE)) {
+      pGeode->CustomMode = TRUE;
+      DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Custom mode enabled\n"));
+   }
+
+   if (xf86IsOptionSet(GeodeOptions,OPTION_CRTENABLE)) {
+      if (xf86ReturnOptValBool(GeodeOptions, OPTION_CRTENABLE, TRUE)) {
+         if( (pGeode->EnabledOutput & LX_OT_FP) != 0 ) {
+            DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "CRT Output Selected\n"));
+         }
+         else
+            DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, 
+                      "CRT Output Selected, but not available - ignored\n"));
+      }
+      else {
+         if( (pGeode->EnabledOutput & LX_OT_CRT) != 0 ) {
+            DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "CRT output configured, but not enabled\n"));
+            pGeode->EnabledOutput &= ~LX_OT_CRT;
+         }
+      }
+   }
+
+   pGeode->TVSupport = FALSE;
+   if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_ENCODER)) != NULL ) {
+      tv_encoder = -1;
+      if( xf86NameCmp(s,"ADV7171") == 0 )
+         tv_encoder = VG_ENCODER_ADV7171;
+      else if( xf86NameCmp(s,"SAA7127") == 0 )
+         tv_encoder = VG_ENCODER_SAA7127;
+      else if( xf86NameCmp(s,"FS454") == 0 )
+         tv_encoder = VG_ENCODER_FS454;
+      else if( xf86NameCmp(s,"ADV7300") == 0 )
+         tv_encoder = VG_ENCODER_ADV7300;
+      if( tv_encoder < 0 ) {
+         DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+           "VOP output configured, but no encoder specified, VOP diabled\n"));
+         pGeode->EnabledOutput &= ~LX_OT_VOP;
+      }
+      else
+         pGeode->TVSupport = TRUE;
+      pGeode->tv_encoder = tv_encoder;
+   }
+
+   /* If TV Supported then check for TVO support */
+   if( pGeode->TVSupport != FALSE ) {
+      tv_bus_fmt = -1;
+      tv_601_fmt = -1;
+      if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_BUS_FMT)) != NULL ) {
+         if( xf86NameCmp(s,"disabled") == 0 )
+            tv_bus_fmt = VOP_MODE_DISABLED;
+         else if( xf86NameCmp(s,"vip11") == 0 )
+            tv_bus_fmt = VOP_MODE_VIP11;
+         else if( xf86NameCmp(s,"ccir656") == 0 )
+            tv_bus_fmt = VOP_MODE_CCIR656;
+         else if( xf86NameCmp(s,"vip20_8bit") == 0 )
+            tv_bus_fmt = VOP_MODE_VIP20_8BIT;
+         else if( xf86NameCmp(s,"vip20_16bit") == 0 )
+            tv_bus_fmt = VOP_MODE_VIP20_16BIT;
+         else if( xf86NameCmp(s,"601_yuv_8bit") == 0 ) {
+            tv_601_fmt = VOP_601_YUV_8BIT;
+            tv_bus_fmt = VOP_MODE_601;
+         } else if( xf86NameCmp(s,"601_yuv_16bit") == 0 ) {
+            tv_601_fmt = VOP_601_YUV_16BIT;
+            tv_bus_fmt = VOP_MODE_601;
+         } else if( xf86NameCmp(s,"601_rgb_8_8_8") == 0 ) {
+            tv_601_fmt = VOP_601_RGB_8_8_8;
+            tv_bus_fmt = VOP_MODE_601;
+         } else if( xf86NameCmp(s,"601_yuv_4_4_4") == 0 ) {
+            tv_601_fmt = VOP_601_YUV_4_4_4;
+            tv_bus_fmt = VOP_MODE_601;
+         }
+      }
+      if( tv_bus_fmt < 0 ) {
+         DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+           "VOP output configured, but no bus format specified,\n"
+           "VOP bus format will depend on SD/HD mode\n"));
+      }
+      pGeode->tv_bus_fmt = tv_bus_fmt;
+      pGeode->tv_601_fmt = tv_601_fmt;
+      tv_flags = 0;
+      if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_FLAGS)) != NULL ) {
+         char *opt, *sp = strdup(s);
+         if( sp != NULL ) {
+            for( opt=strtok(sp,":"); opt!=NULL; opt=strtok(NULL,":") ) {
+               if( xf86NameCmp(opt,"singlechipcompat") == 0 )
+                  tv_flags |= VOP_FLAG_SINGLECHIPCOMPAT;
+               else if( xf86NameCmp(opt,"extendedsav") == 0 )
+                  tv_flags |= VOP_FLAG_EXTENDEDSAV;
+               else if( xf86NameCmp(opt,"vbi") == 0 )
+                  tv_flags |= VOP_FLAG_VBI;
+               else if( xf86NameCmp(opt,"task") == 0 )
+                  tv_flags |= VOP_FLAG_TASK;
+               else if( xf86NameCmp(opt,"swap_uv") == 0 )
+                  tv_flags |= VOP_FLAG_SWAP_UV;
+               else if( xf86NameCmp(opt,"swap_vbi") == 0 )
+                  tv_flags |= VOP_FLAG_SWAP_VBI;
+               else
+                  DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+                    "VOP flag \"%s\" not recognized\n",opt));
+            }
+            free(sp);
+         }
+      }
+      tv_vsync_shift_count = 0;
+      tv_601_flags = 0;
+      tv_vsync_shift = VOP_VSYNC_NOSHIFT;
+      if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_601_FLAGS)) != NULL ) {
+         char *opt, *sp = strdup(s);
+         if( sp != NULL ) {
+            for( opt=strtok(sp,":"); opt!=NULL; opt=strtok(NULL,":") ) {
+               if( xf86NameCmp(opt,"inv_de_pol") == 0 )
+                  tv_601_flags |= VOP_601_INVERT_DISPE;
+               else if( xf86NameCmp(opt,"inv_hs_pol") == 0 )
+                  tv_601_flags |= VOP_601_INVERT_HSYNC;
+               else if( xf86NameCmp(opt,"inv_vs_pol") == 0 )
+                  tv_601_flags |= VOP_601_INVERT_VSYNC;
+               else if( xf86NameCmp(opt,"vsync-4") == 0 )
+                  tv_vsync_shift = VOP_VSYNC_EARLIER_BY4;
+               else if( xf86NameCmp(opt,"vsync-2") == 0 )
+                  tv_vsync_shift = VOP_VSYNC_EARLIER_BY2;
+               else if( xf86NameCmp(opt,"vsync+0") == 0 )
+                  tv_vsync_shift = VOP_VSYNC_NOSHIFT;
+               else if( xf86NameCmp(opt,"vsync+2") == 0 ) {
+                  tv_vsync_shift = VOP_VSYNC_LATER_BY_X;
+                  tv_vsync_shift_count = 2;
+               }
+               else if( xf86NameCmp(opt,"vsync+4") == 0 ) {
+                  tv_vsync_shift = VOP_VSYNC_LATER_BY_X;
+                  tv_vsync_shift_count = 4;
+               }
+               else
+                  DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+                    "VOP 601_flag \"%s\" not recognized\n",opt));
+            }
+            free(sp);
+         }
+      }
+      tv_vsync_select = VOP_MB_SYNCSEL_DISABLED;
+      if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_VSYNC_SELECT)) != NULL ) {
+         char *opt, *sp = strdup(s);
+         if( sp != NULL ) {
+            for( opt=strtok(sp,":"); opt!=NULL; opt=strtok(NULL,":") ) {
+               if( xf86NameCmp(opt,"disabled") == 0 )
+                  tv_vsync_select = VOP_MB_SYNCSEL_DISABLED;
+               else if( xf86NameCmp(opt,"vg") == 0 )
+                  tv_vsync_select = VOP_MB_SYNCSEL_VG;
+               else if( xf86NameCmp(opt,"vg_inv") == 0 )
+                  tv_vsync_select = VOP_MB_SYNCSEL_VG_INV;
+               else if( xf86NameCmp(opt,"statreg17") == 0 )
+                  tv_vsync_select = VOP_MB_SYNCSEL_STATREG17;
+               else if( xf86NameCmp(opt,"statreg17_inv") == 0 )
+                  tv_vsync_select = VOP_MB_SYNCSEL_STATREG17_INV;
+               else
+                  DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+                    "VOP vsync_select \"%s\" not recognized\n",opt));
+            }
+            free(sp);
+         }
+      }
+      pGeode->tv_flags = tv_flags;
+      pGeode->tv_601_flags = tv_601_flags;
+      pGeode->tv_vsync_shift = tv_vsync_shift;
+      pGeode->tv_vsync_shift_count = tv_vsync_shift_count;
+      pGeode->tv_vsync_select = tv_vsync_select;
+      tv_conversion = -1;
+      if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_CONVERSION)) != NULL ) {
+         if( xf86NameCmp(s,"cosited") == 0 )
+            tv_conversion = VOP_422MODE_COSITED;
+         else if( xf86NameCmp(s,"interspersed") == 0 )
+            tv_conversion = VOP_422MODE_INTERSPERSED;
+         else if( xf86NameCmp(s,"alternating") == 0 )
+            tv_conversion = VOP_422MODE_ALTERNATING;
+         else {
+            DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+              "VOP conversion \"%s\" not recognized\n",s));
+         }
+      }
+      if( tv_conversion < 0 ) {
+         DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+           "VOP output configured, but no conversion specified,\n"
+           "VOP conversion will defaults to \"cosited\"\n"));
+         tv_conversion = VOP_422MODE_COSITED;
+      }
+      pGeode->tv_conversion = tv_conversion;
+      tvox = tvoy = 0;
+      if( (s=xf86GetOptValString(GeodeOptions,OPTION_TV_OVERSCAN)) != NULL ) {
+         char *opt, *sp = strdup(s);
+         if( sp != NULL ) {
+            if( (opt=strtok(sp,":")) != NULL )   tvox = strtol(opt,NULL,0);
+            if( (opt=strtok(NULL, ":")) != NULL) tvoy = strtol(opt,NULL,0);
+            free(sp);
+         }
+         DEBUGMSG(1, (0, X_CONFIG, "TVO %d %d\n", tvox,tvoy));
+      }
+      pGeode->tvox = tvox;  pGeode->tvoy = tvoy;
+   }
+   else if( (pGeode->EnabledOutput & LX_OT_VOP) != 0 ) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+        "VOP output enabled, but not configured, VOP diabled\n"));
+      pGeode->EnabledOutput &= ~LX_OT_VOP;
+   }
+
+   if( (pGeode->EnabledOutput & LX_OT_CRT) != 0 ) {
+      ddc = LXProbeDDC(pScrni, pGeode->pEnt->index);
+   }
+
+   flags = pGeode->EnabledOutput;
+   xf86DrvMsg(0, X_INFO, "AMD LX Active Formats -%sCRT,%sVOP,%sFP,%sDRGB\n",
+      ((flags & LX_OT_CRT) ? " " : " No "), ((flags & LX_OT_VOP) ? " " : " No "),
+      ((flags & LX_OT_FP)  ? " " : " No "), ((flags & LX_OT_DRGB)? " " : " No "));
+
+   if( (pGeode->EnabledOutput & (LX_OT_CRT|LX_OT_FP|LX_OT_VOP)) == 0 ) {
+      ErrorF("No output enabled !!!\n");
+      return FALSE;
+   }
+
+   pGeode->ShadowFB = FALSE;
+   if (xf86ReturnOptValBool(GeodeOptions, OPTION_SHADOW_FB, FALSE)) {
+      pGeode->ShadowFB = TRUE;
+      DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+		   "Using \"Shadow Framebuffer\"\n"));
+   }
+
+   pGeode->Rotate = 0;
+   if ((s = xf86GetOptValString(GeodeOptions, OPTION_ROTATE))) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Rotating - %s\n", s));
+      if (!xf86NameCmp(s, "CW")) {
+	 pGeode->Rotate = 1;
+	 DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+		      "Rotating screen clockwise\n"));
+      }
+      else if (!xf86NameCmp(s, "INVERT")) {
+	 pGeode->Rotate = 2;
+	 DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+		      "Rotating screen inverted\n"));
+      }
+      else if (!xf86NameCmp(s, "CCW")) {
+	 pGeode->Rotate = 3;
+	 DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+			 "Rotating screen counter clockwise\n"));
+      }
+      if( pGeode->Rotate != 0 ) {
+	 pGeode->ShadowFB = TRUE;
+      }
+      else {
+	    DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+		 "\"%s\" is not a valid value for Option \"Rotate\"\n", s));
+	    DEBUGMSG(1, (pScrni->scrnIndex, X_INFO,
+		 "Valid options are \"CW\", \"INVERT\", or \"CCW\"\n"));
+      }
+   }
+
+   /* XXX Init further private data here */
+
+   /*
+    * * This shouldn't happen because such problems should be caught in
+    * * GeodeProbe(), but check it just in case.
+    */
+   if (pScrni->chipset == NULL) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+		   "ChipID 0x%04X is not recognised\n", pGeode->Chipset));
+      return FALSE;
+   }
+   if (pGeode->Chipset < 0) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+		   "Chipset \"%s\" is not recognised\n",
+		   pScrni->chipset));
+      return FALSE;
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(6)!\n"));
+
+   /*
+    * * Init the screen with some values
+    */
+   DEBUGMSG(1, (pScrni->scrnIndex, from,
+		"Video I/O registers at 0x%08lX\n",
+		(unsigned long)VGAHW_GET_IOBASE()));
+
+   if (pScrni->memPhysBase == 0) {
+      from = X_PROBED;
+      pScrni->memPhysBase = pGeode->FBLinearAddr;
+   }
+   pScrni->fbOffset = 0;
+
+   DEBUGMSG(1, (pScrni->scrnIndex, from,
+		"Linear framebuffer at 0x%08lX\n",
+		(unsigned long)pScrni->memPhysBase));
+
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(7)!\n"));
+
+   /*
+    * * xf86ValidateModes will check that the mode HTotal and VTotal values
+    * * don't exceed the chipset's limit if pScrni->maxHValue adn
+    * * pScrni->maxVValue are set. Since our LXValidMode()
+    * * already takes care of this, we don't worry about setting them here.
+    */
+   if (pScrni->depth > 16) {
+      PitchInc = 4096;
+   } else if (pScrni->depth == 16) {
+      PitchInc = 2048;
+   } else {
+      PitchInc = 1024;
+   }
+   PitchInc <<= 3;			/* in bits */
+
+   /* by default use what user sets in the XF86Config file */
+   modes = pScrni->display->modes;
+
+   if( ddc != NULL && pScrni->monitor != NULL && pScrni->monitor->DDC == NULL ) {
+      pScrni->monitor->DDC = ddc;
+      LXDecodeDDC(pScrni,ddc);
+   }
+
+   i = xf86ValidateModes(pScrni, pScrni->monitor->Modes, modes, GeodeClockRange,
+      NULL, minPitch, maxPitch, PitchInc, minHeight, maxHeight,
+      pScrni->display->virtualX, pScrni->display->virtualY,
+      pGeode->FBAvail, LOOKUP_BEST_REFRESH);
+
+   DEBUGMSG(1, (pScrni->scrnIndex, from, "xf86ValidateModes:%d %d %d %d\n",
+		i, pScrni->virtualX, pScrni->virtualY, pScrni->displayWidth));
+   if( i == -1 ) {
+      LXFreeRec(pScrni);
+      return FALSE;
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(8)!\n"));
+
+   /* Prune the modes marked as invalid */
+   xf86PruneDriverModes(pScrni);
+
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(9)!\n"));
+   if( i == 0 || pScrni->modes == NULL ) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "No valid modes found\n"));
+      LXFreeRec(pScrni);
+      return FALSE;
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(10)!\n"));
+
+   xf86SetCrtcForModes(pScrni, 0);
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(11)!\n"));
+
+   /* Set the current mode to the first in the list */
+   pScrni->currentMode = pScrni->modes;
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(12)!\n"));
+
+   /* Print the list of modes being used */
+   xf86PrintModes(pScrni);
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(13)!\n"));
+
+   /* Set the display resolution */
+   xf86SetDpi(pScrni, 0, 0);
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(14)!\n"));
+
+   /* Load bpp-specific modules */
+   mod = NULL;
+
+   if (xf86LoadSubModule(pScrni, "fb") == NULL) {
+      LXFreeRec(pScrni);
+      return FALSE;
+   }
+   xf86LoaderReqSymLists(nscFbSymbols, NULL);
+
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(15)!\n"));
+   if (pGeode->NoAccel == FALSE) {
+      if (!xf86LoadSubModule(pScrni, "xaa")) {
+	 LXFreeRec(pScrni);
+	 return FALSE;
+      }
+      xf86LoaderReqSymLists(nscXaaSymbols, NULL);
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(16)!\n"));
+   if (pGeode->HWCursor == TRUE) {
+      if (!xf86LoadSubModule(pScrni, "ramdac")) {
+	 LXFreeRec(pScrni);
+	 return FALSE;
+      }
+      xf86LoaderReqSymLists(nscRamdacSymbols, NULL);
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(17)!\n"));
+   /* Load shadowfb if needed */
+   if (pGeode->ShadowFB) {
+      if (!xf86LoadSubModule(pScrni, "shadowfb")) {
+	 LXFreeRec(pScrni);
+	 return FALSE;
+      }
+      xf86LoaderReqSymLists(nscShadowSymbols, NULL);
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit(18)!\n"));
+   if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) {
+      DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+		   "xf86RegisterResources() found resource conflicts\n"));
+      LXFreeRec(pScrni);
+      return FALSE;
+   }
+   LXUnmapMem(pScrni);
+   DEBUGMSG(1,(0, X_INFO, "LXPreInit ... done successfully!\n"));
+   return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LXRestore.
+ *
+ * Description	:This function restores the mode that was saved on server
+                 entry
+ * Parameters.
+ * pScrni 	:Handle to ScreenPtr structure.
+ *  Pmode       :poits to screen mode
+ * 												
+ * Returns		:none.
+ *
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXRestore(ScrnInfoPtr pScrni)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   DEBUGMSG(0,(0, X_INFO, "LXRestore!\n"));
+   if (pGeode->FBVGAActive) {
+      vgaHWPtr pvgaHW = VGAHWPTR(pScrni);
+
+      vgaHWProtect(pScrni, TRUE);
+      vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL);
+      vgaHWProtect(pScrni, FALSE);
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LXCalculatePitchBytes.
+ *
+ * Description	:This function restores the mode that was saved on server
+ *
+ * Parameters.
+ * pScrni 	:Handle to ScreenPtr structure.
+ *    Pmode     :Points to screenmode
+ * 									
+ * Returns		:none.
+ *
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+static int
+LXCalculatePitchBytes(unsigned int width, unsigned int bpp)
+{
+   int lineDelta = width * (bpp >> 3);
+
+   if (width < 640) {
+      /* low resolutions have both pixel and line doubling */
+      DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n",
+		   width, lineDelta));
+      lineDelta <<= 1;
+   }
+   /* needed in Rotate mode when in accel is turned off */
+   if (1) {				/*!pGeode->NoAccel */
+      if (lineDelta > 4096)
+	 lineDelta = 8192;
+      else if (lineDelta > 2048)
+	 lineDelta = 4096;
+      else if (lineDelta > 1024)
+	 lineDelta = 2048;
+      else
+	 lineDelta = 1024;
+   }
+
+   DEBUGMSG(0, (0, X_INFO, "pitch %d %d\n", width, lineDelta));
+
+   return lineDelta;
+}
+
+/*----------------------------------------------------------------------------
+ * LXGetRefreshRate.
+ *
+ * Description	:This function restores the mode that saved on server
+ *
+ * Parameters.
+ *     Pmode    :Pointer to the screen modes
+ * 												
+ * Returns		:It returns the selected refresh rate.
+ *
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+static int
+LXGetRefreshRate(DisplayModePtr pMode)
+{
+#define THRESHOLD 2
+   unsigned int i;
+   static int validRates[] = { 56, 60, 70, 72, 75, 85, 90, 100 };	/* Hz */
+   unsigned long dotClock;
+   int refreshRate;
+   int selectedRate;
+
+   dotClock = pMode->SynthClock * 1000;
+   refreshRate = dotClock / (pMode->CrtcHTotal * pMode->CrtcVTotal);
+
+   if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480))
+      refreshRate >>= 2;		/* double pixel and double scan */
+
+   DEBUGMSG(0, (0, X_INFO, "dotclock %lu %d\n", dotClock, refreshRate));
+
+   selectedRate = validRates[0];
+
+   for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) {
+      if (validRates[i] < (refreshRate + THRESHOLD)) {
+	 selectedRate = validRates[i];
+      }
+   }
+   return selectedRate;
+}
+
+void
+lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp)
+{
+   /* no accels, mode is not yet set */
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   unsigned long offset = vg_get_display_offset();
+   unsigned long pitch = vg_get_display_pitch();
+   unsigned long n = width * ((bpp+7)>>3);
+   DEBUGMSG(0, (0, X_INFO, "clear screen %lx %d %d %d %lu %lu\n", offset,width,height,bpp,pitch,n));
+   while( height > 0 ) {
+      memset(pGeode->FBBase+offset,0,n);
+      offset += pitch;
+      --height;
+   }
+}
+
+void
+lx_clear_fb(ScrnInfoPtr pScrni)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   unsigned char *fb = pGeode->FBBase+pGeode->FBOffset;
+   memset(fb,0,pGeode->FBSize);
+   if( pGeode->ShadowPtr != NULL && pGeode->ShadowPtr != fb )
+      memset(pGeode->ShadowPtr,0,pGeode->ShadowSize);
+}
+
+static int
+lx_set_tv_mode(ScrnInfoPtr pScrni,int tv_mode)
+{
+   int ret, bpp, flags;
+   int tv_conversion, tv_bus_fmt, tv_flags;
+   int tv_601_fmt, tv_601_flags;
+   int tv_vsync_shift, tv_vsync_shift_count, tv_vsync_select;
+   unsigned long src_width, src_height;
+   char *bp, *cp, *dp;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   VOPCONFIGURATIONBUFFER vopc;
+   bpp = pScrni->bitsPerPixel;
+   if( bpp == 32 ) bpp = 24;
+   flags = lx_tv_mode_interlaced(tv_mode) != 0 ? VG_MODEFLAG_INTERLACED : 0; 
+   src_width = src_height = 0;
+   ret = vg_set_tv_mode(&src_width,&src_height,
+      pGeode->tv_encoder,tv_mode,bpp,flags,0,0);
+   DEBUGMSG(1, (0, X_INFO,
+      "Setting TV mode %lux%lu encoder=%d,bpp=%d,flags=%d,overscan %d,%d\n",
+      src_width,src_height,pGeode->tv_encoder,bpp,flags,
+      pGeode->tvox,pGeode->tvoy));
+   ret = vg_set_tv_mode(&src_width,&src_height,
+      pGeode->tv_encoder,tv_mode,bpp,flags,pGeode->tvox,pGeode->tvoy);
+       
+   DEBUGMSG(1, (0, X_INFO, "Set TV mode ret=%d\n", ret));
+   if( ret == 0 ) {
+      memset(&vopc,0,sizeof(vopc));
+      tv_flags = pGeode->tv_flags;
+      tv_bus_fmt = pGeode->tv_bus_fmt;
+      tv_601_fmt = pGeode->tv_601_fmt;
+      tv_601_flags = pGeode->tv_601_flags;
+      tv_vsync_shift = pGeode->tv_vsync_shift;
+      tv_vsync_shift_count = pGeode->tv_vsync_shift_count;
+      tv_vsync_select = pGeode->tv_vsync_select;
+      tv_conversion = pGeode->tv_conversion;
+      if( tv_bus_fmt < 0 ) {
+         dp = "defaults";
+         switch( tv_mode ) {
+         case VG_TVMODE_NTSC:     case VG_TVMODE_6X4_NTSC:
+         case VG_TVMODE_8X6_NTSC: case VG_TVMODE_10X7_NTSC:
+         case VG_TVMODE_PAL:      case VG_TVMODE_6X4_PAL:
+         case VG_TVMODE_8X6_PAL:  case VG_TVMODE_10X7_PAL:
+            tv_bus_fmt = VOP_MODE_VIP11;
+            break;
+         default:
+            tv_bus_fmt = VOP_MODE_VIP20_16BIT;
+            break;
+         }
+      }
+      else
+         dp = "set";
+      switch( tv_bus_fmt ) {
+      case VOP_MODE_VIP11:       bp = "vop11";         break;
+      case VOP_MODE_CCIR656:     bp = "ccir656";       break;
+      case VOP_MODE_VIP20_8BIT:  bp = "vip20_8bit";    break;
+      case VOP_MODE_VIP20_16BIT: bp = "vip20_16bit";   break;
+      case VOP_MODE_601:
+         switch( tv_601_fmt ) {
+         default: tv_601_fmt = VOP_601_YUV_8BIT;
+         case VOP_601_YUV_8BIT:  bp = "601_yuv_8bit";  break;
+         case VOP_601_YUV_16BIT: bp = "601_yuv_16bit"; break;
+         case VOP_601_RGB_8_8_8: bp = "601_rgb_8_8_8"; break;
+         case VOP_601_YUV_4_4_4: bp = "601_yuv_4_4_4"; break;
+         }
+         break;
+      default: tv_bus_fmt = VOP_MODE_DISABLED;
+      case VOP_MODE_DISABLED:    bp = "disabled";      break;
+      }
+      switch( tv_conversion ) {
+      default: tv_conversion = VOP_422MODE_COSITED;
+      case VOP_422MODE_COSITED:      cp = "cosited";       break;
+      case VOP_422MODE_INTERSPERSED: cp = "interspersed";  break;
+      case VOP_422MODE_ALTERNATING:  cp = "alternating";   break;
+      }
+      vopc.flags = tv_flags;
+      vopc.mode = tv_bus_fmt;
+      vopc.conversion_mode = tv_conversion;
+      vopc.vsync_out = tv_vsync_select;
+      vopc.vop601.flags = tv_601_flags;
+      vopc.vop601.vsync_shift = tv_vsync_shift;
+      vopc.vop601.vsync_shift_count = tv_vsync_shift_count;
+      vopc.vop601.output_mode = tv_601_fmt;
+      DEBUGMSG(1, (0, X_INFO,
+         "Set TV mode %s to %s, conv %s, flags %x\n",
+         dp,bp,cp,tv_flags));
+      DEBUGMSG(1, (0, X_INFO,
+        "Set TV 601 mode %x flags %x vsync shift %x/%x\n",
+         tv_601_fmt,tv_601_flags,tv_vsync_shift,tv_vsync_shift_count));
+      vop_set_configuration(&vopc);
+   }
+   return ret;
+}
+
+static int
+lx_set_custom_mode(unsigned long bpp, unsigned long flags,
+   unsigned long hactive, unsigned long hblankstart,
+   unsigned long hsyncstart, unsigned long hsyncend,
+   unsigned long hblankend, unsigned long htotal,
+   unsigned long vactive, unsigned long vblankstart,
+   unsigned long vsyncstart, unsigned long vsyncend,
+   unsigned long vblankend, unsigned long vtotal,
+   unsigned long frequency)
+
+{
+   VG_DISPLAY_MODE mode;
+   memset(&mode,0,sizeof(mode));
+   mode.flags = flags;
+   mode.src_width = hactive;
+   mode.src_height = vactive;
+   mode.mode_width = hactive;
+   mode.mode_height = vactive;
+   mode.hactive = hactive;
+   mode.hblankstart = hblankstart;
+   mode.hsyncstart = hsyncstart;
+   mode.hsyncend = hsyncend;
+   mode.hblankend = hblankend;
+   mode.htotal = htotal;
+   mode.vactive = vactive;
+   mode.vblankstart = vblankstart;
+   mode.vsyncstart = vsyncstart;
+   mode.vsyncend = vsyncend;
+   mode.vblankend = vblankend;
+   mode.vtotal = vtotal;
+   mode.vactive_even = vactive;
+   mode.vblankstart_even = vblankstart;
+   mode.vsyncstart_even = vsyncstart;
+   mode.vsyncend_even = vsyncend;
+   mode.vblankend_even = vblankend;
+   mode.vtotal_even = vtotal;
+   mode.frequency = frequency;
+   return vg_set_custom_mode(&mode,bpp);
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetMode.
+ *
+ * Description	:This function sets parametrs for screen mode
+ *
+ * Parameters.
+ * pScrni 	:Pointer to the screenInfo structure.
+ *	 Pmode      :Pointer to the screen modes
+ * 												
+ * Returns		:TRUE on success and FALSE on Failure.
+ *
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+
+static Bool
+LXSetMode(ScrnInfoPtr pScrni, DisplayModePtr pMode)
+{
+   int bpp, bppx, rate, video_enable, tv_mode, opath;
+   unsigned long flags, srcw,srch, actw,acth, dstw,dsth, video_flags;
+
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DF_VIDEO_SOURCE_PARAMS vs_odd, vs_even;
+   gp_wait_until_idle();
+   /* disable video */
+   df_get_video_enable(&video_enable,&video_flags);
+   if( video_enable != 0 ) df_set_video_enable(0,0);
+   df_get_video_source_configuration(&vs_odd, &vs_even);
+   lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+
+   DEBUGMSG(1, (0, X_NONE, "LXSetMode! %p %p %p\n",
+		cim_gp_ptr, cim_vid_ptr, cim_fb_ptr));
+
+   /* Set the VT semaphore */
+   pScrni->vtSema = TRUE;
+
+   srcw = pMode->CrtcHDisplay;
+   srch = pMode->CrtcVDisplay;
+   bpp = pScrni->bitsPerPixel;
+   rate = LXGetRefreshRate(pMode);
+   /* otherwise color/chroma keying doesnt work */
+   bppx = bpp == 32 ? 24 : bpp;
+
+   /* The timing will be adjusted later */
+   DEBUGMSG(1, (0, X_PROBED,
+     "Setting mode %dx%d %0.3f  %d %d %d %d  %d %d %d %d\n",
+     pMode->CrtcHDisplay, pMode->CrtcVDisplay,  pMode->SynthClock/1000.0,
+     pMode->CrtcHDisplay, pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, pMode->CrtcHTotal,
+     pMode->CrtcVDisplay, pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, pMode->CrtcVTotal));
+   DEBUGMSG(1,(0, X_INFO, "Set display mode: %lux%lu-%d (%dHz) Pitch %d/%d\n",
+	       srcw,srch, bpp, rate, pGeode->Pitch,pGeode->AccelPitch));
+
+   opath = DF_DISPLAY_CRT;
+   if( (pGeode->EnabledOutput&LX_OT_FP) != 0 ) {
+      if( (pGeode->EnabledOutput&LX_OT_CRT) != 0 )
+         opath = DF_DISPLAY_CRT_FP;
+      else
+         opath = DF_DISPLAY_FP;
+   }
+
+   if( pGeode->TVSupport && (tv_mode=lx_tv_mode(pMode)) >= 0 ) {
+      DEBUGMSG(1, (0, X_INFO, "Set TV mode %d\n",tv_mode));
+      lx_set_tv_mode(pScrni,tv_mode);
+      opath = DF_DISPLAY_VOP;
+   }
+   else if( pGeode->CustomMode != 0 ) {
+      DEBUGMSG(1, (0, X_PROBED, "Setting Custom mode\n"));
+      flags = 0;
+      if( (pMode->Flags & V_NHSYNC) != 0 ) flags |= VG_MODEFLAG_NEG_HSYNC;
+      if( (pMode->Flags & V_NVSYNC) != 0 ) flags |= VG_MODEFLAG_NEG_VSYNC;
+      lx_set_custom_mode(bppx, flags,
+        pMode->CrtcHDisplay, pMode->CrtcHBlankStart, pMode->CrtcHSyncStart,
+        pMode->CrtcHSyncEnd, pMode->CrtcHBlankEnd, pMode->CrtcHTotal,
+        pMode->CrtcVDisplay, pMode->CrtcVBlankStart, pMode->CrtcVSyncStart,
+        pMode->CrtcVSyncEnd, pMode->CrtcVBlankEnd, pMode->CrtcVTotal,
+        (int)((pMode->SynthClock/1000.0)*0x10000));
+   }
+   else if( (pGeode->EnabledOutput&LX_OT_FP) != 0 ) {
+      /* display is fp */
+      actw = pGeode->FPGeomActX;  dstw = pGeode->FPGeomDstX;
+      acth = pGeode->FPGeomActY;  dsth = pGeode->FPGeomDstY;
+      flags = (pGeode->EnabledOutput&LX_OT_CRT) != 0 ? VG_MODEFLAG_CRT_AND_FP : 0;
+      /* cant do scaling if width > 1024 (hw bfr size limitation) */
+      if( srcw > 1024 ) {
+         if( srcw != actw )
+            DEBUGMSG(1, (0, X_PROBED, "FPGeomSrcX > 1024, scaling disabled\n"));
+         actw = srcw;  acth = srch;
+         vg_set_border_color(0);
+      }
+      DEBUGMSG(1, (0, X_PROBED, "Setting Display for TFT %lux%lu %lux%lu %lux%lu %d\n",
+                   srcw,srch, actw,acth, dstw,dsth, pScrni->bitsPerPixel));
+      vg_set_panel_mode(srcw,srch, actw,acth, dstw,dsth, bppx, flags);
+   }
+   else {
+      /* display is crt */
+      DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT %lux%lu-%d@%d\n",
+                   srcw, srch, bppx, LXGetRefreshRate(pMode)));
+      vg_set_display_mode(srcw,srch, srcw,srch, bppx, LXGetRefreshRate(pMode),0);
+   }
+
+   df_set_output_path(opath);
+   vg_set_display_pitch(pGeode->Pitch);
+   gp_set_bpp(pScrni->bitsPerPixel);
+
+   vg_set_display_offset(0L);
+   vg_wait_vertical_blank();
+
+   DEBUGMSG(1, (0, X_PROBED, "Display mode set\n"));
+   /* enable compression if option selected */
+   if( pGeode->Compression != 0 ) {
+      DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n", pGeode->Compression));
+      /* set the compression parameters,and it will be turned on later. */
+      vg_configure_compression(&(pGeode->CBData));
+
+      /* set the compression buffer, all parameters already set */
+      vg_set_compression_enable(1);
+   }
+
+   if( pGeode->HWCursor != 0 ) {
+      VG_PANNING_COORDINATES panning;
+      /* Load blank cursor */
+      LXLoadCursorImage(pScrni, NULL);
+      vg_set_cursor_position(0, 0, &panning);
+      LXShowCursor(pScrni);
+   }
+
+   DEBUGMSG(1,(0, X_INFO, "setting mode done.\n"));
+
+   vg_set_display_offset(pGeode->PrevDisplayOffset);
+
+   /* Restore the contents in the screen info */
+   DEBUGMSG(1,(0, X_INFO, "After setting the mode\n"));
+   switch( pGeode->Rotate ) {
+   case 1:
+   case 3:
+      pGeode->HDisplay = pMode->VDisplay;
+      pGeode->VDisplay = pMode->HDisplay;
+      break;
+   default:
+      pGeode->HDisplay = pMode->HDisplay;
+      pGeode->VDisplay = pMode->VDisplay;
+      break;
+   }
+
+   df_configure_video_source(&vs_odd,&vs_even);
+   if( video_enable != 0 )
+      df_set_video_enable(video_enable,video_flags);
+   lx_enable_dac_power(pScrni,1);
+   return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LXEnterGraphics.
+ *
+ * Description	:This function will intiallize the displaytiming
+				 structure for nextmode and switch to VGA mode.
+ *
+ * Parameters.
+ *    pScrn   :Screen information will be stored in this structure.
+ * 	pScrni :Pointer to the screenInfo structure.
+ *													
+ * Returns		:TRUE on success and FALSE on Failure.
+ *
+ * Comments     :gfx_vga_mode_switch() will start and end the
+ *				switching based on the arguments 0 or 1.soft_vga
+ *				is disabled in this function.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni)
+{
+   int bpp;
+   unsigned long cmd_bfr_phys;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   vgaHWPtr pvgaHW = VGAHWPTR(pScrni);
+
+   DEBUGMSG(1,(0, X_INFO, "LXEnterGraphics.\n"));
+
+   gp_wait_until_idle();
+   cmd_bfr_phys = pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset;
+   cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset;
+   gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base,pGeode->FBTop);
+   gp_set_command_buffer_base(cmd_bfr_phys,0,pGeode->CmdBfrSize);
+
+   lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+   /* Save CRT State */
+   vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, &bpp);
+   pGeode->FBcimdisplaytiming.wBpp = bpp;
+
+   pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch();
+
+   /* Save Display offset */
+   pGeode->FBDisplayOffset = vg_get_display_offset();
+   pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040);
+   DEBUGMSG(1,(0, X_INFO, "FBBIOSMode %d\n", pGeode->FBBIOSMode));
+
+   /* Save the current Compression state */
+   pGeode->FBCompressionEnable = vg_get_compression_enable();
+
+   vg_get_compression_info (&(pGeode->FBCBData));
+
+   /* Save Cursor offset */
+   vg_get_cursor_info(&pGeode->FBCursor);
+
+   /* only if comming from VGA */
+   if (pGeode->FBVGAActive) {
+      unsigned short sequencer;
+      vgaHWPtr pvgaHW = VGAHWPTR(pScrni);
+
+      /* Map VGA aperture */
+      if (!vgaHWMapMem(pScrni))
+	 return FALSE;
+
+      /* Unlock VGA registers */
+      vgaHWUnlock(pvgaHW);
+
+      /* Save the current state and setup the current mode */
+      vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL);
+
+      /* DISABLE VGA SEQUENCER */
+      /* This allows the VGA state machine to terminate. We must delay */
+      /* such that there are no pending MBUS requests.  */
+
+      cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE);
+      sequencer = cim_inb(DC3_SEQUENCER_DATA);
+      sequencer |= DC3_CLK_MODE_SCREEN_OFF;
+      cim_outb(DC3_SEQUENCER_DATA, sequencer);
+
+      vg_delay_milliseconds(1);
+
+      /* BLANK THE VGA DISPLAY */
+      cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET);
+      sequencer = cim_inb(DC3_SEQUENCER_DATA);
+      sequencer &= ~DC3_RESET_VGA_DISP_ENABLE;
+      cim_outb(DC3_SEQUENCER_DATA, sequencer);
+
+      vg_delay_milliseconds(1);
+   }
+
+   lx_clear_fb(pScrni);
+
+   if (!LXSetMode(pScrni, pScrni->currentMode)) {
+      return FALSE;
+   }
+
+   lx_enable_dac_power(pScrni,1);
+   return TRUE;
+}
+
+void
+lx_disable_dac_power(ScrnInfoPtr pScrni,int option)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   if( (pGeode->EnabledOutput&LX_OT_FP) != 0 )
+      df_set_panel_enable(0);
+   if( (pGeode->EnabledOutput&LX_OT_CRT) != 0 ) {
+      if( (pGeode->EnabledOutput&LX_OT_FP) != 0 )
+         /* wait for the panel to be fully powered off */
+         while( (READ_VID32(DF_POWER_MANAGEMENT) & 2) == 0 );
+      df_set_crt_enable(option);
+   }
+}
+
+void
+lx_enable_dac_power(ScrnInfoPtr pScrni, int option)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   df_set_crt_enable(DF_CRT_ENABLE);
+   if( option != 0 && (pGeode->EnabledOutput&LX_OT_CRT) == 0 ) {
+      unsigned int misc = READ_VID32(DF_VID_MISC);
+      misc |= DF_DAC_POWER_DOWN;
+      WRITE_VID32(DF_VID_MISC, misc);
+   }
+   if( (pGeode->EnabledOutput&LX_OT_FP) != 0 )
+      df_set_panel_enable(1);
+}
+
+/*----------------------------------------------------------------------------
+ * LXLeaveGraphics:
+ *
+ * Description	:This function will restore the displaymode parameters
+ * 				 and switches the VGA mode
+ *
+ * Parameters.
+ *    pScrni   :Pointer to the screenInfo structure.
+ * 												
+ * Returns		:none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXLeaveGraphics(ScrnInfoPtr pScrni)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   gp_wait_until_idle();
+
+   /* Restore VG registers */
+   lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+   vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), 
+       pGeode->FBcimdisplaytiming.wBpp);
+
+   vg_set_compression_enable(0);
+
+   /* Restore the previous Compression state */
+   if (pGeode->FBCompressionEnable) {
+      vg_configure_compression(&(pGeode->FBCBData));
+      vg_set_compression_enable(1);
+   }
+
+   vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch);
+
+   vg_set_display_offset(pGeode->FBDisplayOffset);
+
+   /* Restore Cursor */
+   {  VG_PANNING_COORDINATES panning;
+      vg_set_cursor_position(pGeode->FBCursor.cursor_x,pGeode->FBCursor.cursor_y,&panning); }
+
+   /* For the moment, always do an int 10 */
+
+#if INT10_SUPPORT
+   pGeode->vesa->pInt->num = 0x10;
+   pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode;
+   pGeode->vesa->pInt->bx = 0;
+   xf86ExecX86int10(pGeode->vesa->pInt);
+#endif
+   vg_delay_milliseconds(3);
+   LXRestore(pScrni);
+
+   lx_enable_dac_power(pScrni,0);
+}
+
+/*----------------------------------------------------------------------------
+ * LXCloseScreen.
+ *
+ * Description	:This function will restore the original mode
+ *				 and also it unmap video memory
+ *
+ * Parameters.
+ *    ScrnIndex	:Screen index value of the screen will be closed.
+ * 	pScrn    	:Pointer to the screen structure.
+ *	
+ * 												
+ * Returns		:TRUE on success and FALSE on Failure.
+ *
+ * Comments		:none.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXCloseScreen(int scrnIndex, ScreenPtr pScrn)
+{
+   ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   if( pGeode->ShadowPtr && !pGeode->ShadowInFBMem )
+      xfree(pGeode->ShadowPtr);
+
+   DEBUGMSG(1, (scrnIndex, X_PROBED, "LXCloseScreen %d\n",
+		pScrni->vtSema));
+   if (pScrni->vtSema)
+      LXLeaveGraphics(pScrni);
+
+   if (pGeode->AccelInfoRec)
+      XAADestroyInfoRec(pGeode->AccelInfoRec);
+
+   if (pGeode->AccelImageWriteBuffers) {
+#if LX_USE_OFFSCRN_MEM
+      xfree(pGeode->AccelImageWriteBuffers[0]);
+#endif
+      xfree(pGeode->AccelImageWriteBuffers);
+      pGeode->AccelImageWriteBuffers = NULL;
+   }
+   if (pGeode->AccelColorExpandBuffers) {
+      xfree(pGeode->AccelColorExpandBuffers[0]);
+      xfree(pGeode->AccelColorExpandBuffers);
+      pGeode->AccelColorExpandBuffers = NULL;
+   }
+   pScrni->vtSema = FALSE;
+
+   LXUnmapMem(pScrni);
+
+   if (pGeode && (pScrn->CloseScreen = pGeode->CloseScreen)) {
+      pGeode->CloseScreen = NULL;
+      return ((*pScrn->CloseScreen)(scrnIndex,pScrn));
+   }
+   return TRUE;
+}
+
+#ifdef DPMSExtension
+/*----------------------------------------------------------------------------
+ * LXDPMSSet.
+ *
+ * Description	:This function sets geode into Power Management
+ *               Signalling mode.				
+ *
+ * Parameters.
+ * 	pScrni	 :Pointer to screen info strucrure.
+ * 	mode         :Specifies the power management mode.
+ *	 												
+ * Returns		 :none.
+ *
+ * Comments      :none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags)
+{
+   GeodePtr pGeode;
+
+   pGeode = GEODEPTR(pScrni);
+
+   DEBUGMSG(1,(0, X_INFO, "LXDPMSSet!\n"));
+
+   /* Check if we are actively controlling the display */
+   if (!pScrni->vtSema) {
+      ErrorF("LXDPMSSet called when we not controlling the VT!\n");
+      return;
+   }
+   switch (mode) {
+   case DPMSModeOn:         /* Screen: On; HSync: On; VSync: On */
+      lx_enable_dac_power(pScrni,1);
+      break;
+
+   case DPMSModeStandby:    /* Screen: Off; HSync: Off; VSync: On */
+      lx_disable_dac_power(pScrni,DF_CRT_STANDBY);
+      break;
+
+   case DPMSModeSuspend:    /* Screen: Off; HSync: On; VSync: Off */
+      lx_disable_dac_power(pScrni,DF_CRT_SUSPEND);
+      break;
+   case DPMSModeOff:        /* Screen: Off; HSync: Off; VSync: Off */
+      lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+      break;
+   }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXScreenInit.
+ *
+ * Description	:This function will be called at the each ofserver
+ *   			 generation.				
+ *
+ * Parameters.
+ *   scrnIndex   :Specfies the screenindex value during generation.
+ *    pScrn	 :Pointer to screen strucrure.
+ * 	argc         :parameters for command line arguments count
+ *	argv         :command line arguments if any it is not used.  												
+ *
+ * Returns		 :none.
+ *
+ * Comments      :none.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv)
+{
+   int i, bytpp, size, fbsize, fboffset, fbavail;
+   int pitch, displayWidth, virtualX, virtualY;
+   int HDisplay, VDisplay, maxHDisplay, maxVDisplay, maxX, maxY;
+   unsigned char *FBStart, **ap, *bp;
+   DisplayModePtr p;
+   GeodePtr pGeode;
+   VisualPtr visual;
+   BoxRec AvailBox;
+   RegionRec OffscreenRegion;
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   Bool Inited = FALSE;
+
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit!\n"));
+   /* Get driver private */
+   pGeode = LXGetRec(pScrni);
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(0)!\n"));
+   /*
+    * * Allocate a vgaHWRec
+    */
+
+   if (!vgaHWGetHWRec(pScrni))
+      return FALSE;
+   if (!vgaHWMapMem(pScrni))
+      return FALSE;
+
+   vgaHWGetIOBase(VGAHWPTR(pScrni));
+
+   if (!LXMapMem(pScrni))
+      return FALSE;
+
+   pGeode->Pitch = LXCalculatePitchBytes(pScrni->virtualX,
+					  pScrni->bitsPerPixel);
+   pGeode->AccelPitch =  pGeode->Pitch;
+   bytpp = (pScrni->bitsPerPixel+7)/8;
+
+   /* start of framebuffer for accels */
+   fboffset = 0;
+   fbavail = pGeode->FBAvail;
+
+   /* allocate display frame buffer at zero offset */
+   fbsize = pScrni->virtualY * pGeode->Pitch;
+   pGeode->FBSize = fbsize;
+
+   pGeode->CursorSize = (HW_CURSOR_W*HW_CURSOR_H)/8*2; /* can be RGBA */
+   pGeode->CursorStartOffset = 0;
+
+   DEBUGMSG(1, (scrnIndex, X_PROBED,"%d %d %d\n",
+            pScrni->virtualX, pScrni->bitsPerPixel, pGeode->Pitch));
+
+   HDisplay = pScrni->currentMode->HDisplay;
+   VDisplay = pScrni->currentMode->VDisplay;
+   pGeode->orig_virtX = pScrni->virtualX;
+   pGeode->orig_virtY = pScrni->virtualY;
+
+   p = pScrni->modes;
+   maxHDisplay = p->HDisplay;
+   maxVDisplay = p->VDisplay;
+   while( (p=p->next)!=pScrni->modes ) {
+      if( maxHDisplay < p->HDisplay ) maxHDisplay = p->HDisplay;
+      if( maxVDisplay < p->VDisplay ) maxVDisplay = p->VDisplay;
+   }
+   DEBUGMSG(1, (scrnIndex, X_PROBED,"maxHDisplay %d maxVDisplay %d\n",maxHDisplay,maxVDisplay));
+
+   switch( pGeode->Rotate ) {
+   case 1:
+   case 3:
+      pGeode->HDisplay = VDisplay;
+      pGeode->VDisplay = HDisplay;
+      virtualX = pScrni->virtualY;
+      virtualY = pScrni->virtualX;
+      maxX = maxVDisplay;
+      maxY = maxHDisplay;
+      break;
+   default:
+      pGeode->HDisplay = HDisplay;
+      pGeode->VDisplay = VDisplay;
+      virtualX = pScrni->virtualX;
+      virtualY = pScrni->virtualY;
+      maxX = maxHDisplay;
+      maxY = maxVDisplay;
+      break;
+   }
+
+   /* shadow may be first in FB, since accels render there */
+
+   pGeode->ShadowPtr = NULL;
+   if( pGeode->ShadowFB ) {
+      if( !pGeode->PointerMoved ) {
+         pGeode->PointerMoved = pScrni->PointerMoved;
+         pScrni->PointerMoved = LXPointerMoved;
+      }
+      if( !pGeode->NoAccel ) {
+         pGeode->ShadowPitch = LXCalculatePitchBytes(virtualX,pScrni->bitsPerPixel);
+         size = pGeode->ShadowPitch * virtualY;
+         if( size <= fbavail-fbsize ) {
+            pGeode->ShadowPtr = (unsigned char *)pGeode->FBBase + fboffset;
+            pGeode->AccelPitch =  pGeode->ShadowPitch;
+            pGeode->ShadowSize = size;
+            pGeode->ShadowInFBMem = TRUE;
+            fboffset += size;
+            fbavail -= size;
+         }
+         else {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB, No FB Memory, trying offscreen\n");
+         }
+      }
+      if( pGeode->ShadowPtr == NULL ) {
+         pGeode->ShadowPitch = BitmapBytePad(pScrni->bitsPerPixel*virtualX);
+         size = pGeode->ShadowPitch * virtualY;
+         pGeode->ShadowPtr = xalloc(size);
+         if( pGeode->ShadowPtr != NULL ) {
+            pGeode->ShadowSize = size;
+            pGeode->ShadowInFBMem = FALSE;
+            if( !pGeode->NoAccel ) {
+               pGeode->NoAccel = TRUE;
+               pGeode->HWCursor = FALSE;
+	       xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB offscreen, All Accels disabled\n");
+            }
+         }
+         else {
+            xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB, No offscreen Memory, disabled\n");
+            pGeode->ShadowFB = FALSE;
+            pGeode->Rotate = 0;
+            pGeode->HDisplay = HDisplay;
+            pGeode->VDisplay = VDisplay;
+            virtualX = pScrni->virtualX;
+            virtualY = pScrni->virtualY;
+         }
+      }
+   }
+
+   if( pGeode->ShadowPtr != NULL ) {
+      displayWidth = pGeode->ShadowPitch / bytpp;
+      FBStart = pGeode->ShadowPtr;
+      DEBUGMSG(1, (0, X_PROBED, "Shadow %p \n", FBStart));
+   }
+   else {
+      displayWidth = pGeode->Pitch / bytpp;
+      FBStart = pGeode->FBBase;
+      DEBUGMSG(1, (0, X_PROBED, "FBStart %p \n", FBStart));
+   }
+
+   DEBUGMSG(1, (0, X_PROBED, "FB display %X size %X \n",fboffset,fbsize));
+   pGeode->FBOffset = fboffset;     /* offset of display framebuffer */
+   pScrni->fbOffset = fboffset;
+   fboffset += fbsize;
+   fbavail -= fbsize;
+
+   if( pGeode->Compression ) {      /* Compression enabled */
+      pGeode->CBData.size = 512+32;
+      pGeode->CBData.pitch = 512+32;
+      size = maxY*pGeode->CBData.pitch;
+      DEBUGMSG(1, (0, X_PROBED, "CB %#x size %#x (%d*%lu)\n",fboffset,size,maxY,pGeode->CBData.pitch));
+      if( size <= fbavail ) {
+         pGeode->CBData.compression_offset = fboffset;
+         fboffset += size;
+         fbavail -= size;
+      }
+      else {
+	 xf86DrvMsg(scrnIndex, X_ERROR, "Compression, No FB Memory, disabled\n");
+         pGeode->Compression = FALSE;
+      }
+   }
+
+   if( pGeode->HWCursor ) {         /* HWCursor enabled */
+      size = pGeode->CursorSize;
+      if( size <= fbavail ) {
+         pGeode->CursorStartOffset = fboffset;
+         fboffset += size;
+         fbavail -= size;
+      }
+      else {
+	 xf86DrvMsg(scrnIndex, X_ERROR, "HWCursor, No FB Memory, disabled\n");
+         pGeode->HWCursor = FALSE;
+      }
+   }
+
+   if( !pGeode->NoAccel ) {            /* Acceleration enabled */
+      if( pGeode->NoOfImgBuffers > 0 ) {
+         pGeode->AccelImageWriteBuffers = NULL;
+	 pitch = pGeode->AccelPitch;
+         size = pitch * pGeode->NoOfImgBuffers;
+#if !LX_USE_OFFSCRN_MEM
+         if( size <= fbavail ) {
+	    bp = (unsigned char *)pGeode->FBBase + fboffset;
+            ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * pGeode->NoOfImgBuffers);
+	    if( ap != NULL ) {
+	       for( i=0; i<pGeode->NoOfImgBuffers; ++i ) {
+	          ap[i] = bp;
+	          bp += pitch;
+	       }
+               pGeode->AccelImageWriteBuffers = ap;
+               fboffset += size;
+               fbavail -= size;
+	    }
+            else {
+	       xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No Memory\n");
+	    }
+	 }
+         else {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No FB Memory\n");
+         }
+#else
+         if( (bp=(unsigned char *)xalloc(size)) != NULL ) {
+            ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * pGeode->NoOfImgBuffers);
+	    if( ap != NULL ) {
+	       for( i=0; i<pGeode->NoOfImgBuffers; ++i ) {
+	          ap[i] = bp;
+	          bp += pitch;
+	       }
+               pGeode->AccelImageWriteBuffers = ap;
+	    }
+            else {
+	       xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No Memory\n");
+	    }
+	 }
+         else {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No offscreen Memory\n");
+         }
+#endif
+	 if( pGeode->AccelImageWriteBuffers == NULL ) {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Accel Image Write disabled\n");
+            pGeode->NoOfImgBuffers = 0;
+	 }
+      }
+
+      if (pGeode->NoOfColorExpandLines > 0) {
+	 pGeode->AccelColorExpandBuffers = NULL;
+	 pitch = ((pGeode->AccelPitch+31) >> 5) << 2;
+         size = pitch * pGeode->NoOfColorExpandLines;
+         if( (bp=(unsigned char *)xalloc(size)) != NULL ) {
+            ap = xalloc(sizeof(pGeode->AccelColorExpandBuffers[0]) * pGeode->NoOfColorExpandLines);
+	    if( ap != NULL ) {
+	       for( i=0; i<pGeode->NoOfColorExpandLines; ++i ) {
+	          ap[i] = bp;
+	          bp += pitch;
+	       }
+               pGeode->AccelColorExpandBuffers = ap;
+	    }
+            else {
+	       xf86DrvMsg(scrnIndex, X_ERROR, "Color Expansion, No Memory\n");
+	    }
+	 }
+         else {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Color Expansion, No offscreen Memory\n");
+	 }
+	 if( pGeode->AccelColorExpandBuffers == NULL ) {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Accel Color Expansion disabled\n");
+            pGeode->NoOfColorExpandLines = 0;
+	 }
+      }
+   }
+   else {
+      pGeode->NoOfImgBuffers = 0;
+      pGeode->AccelImageWriteBuffers = NULL;
+      pGeode->NoOfColorExpandLines = 0;
+      pGeode->AccelColorExpandBuffers = NULL;
+   }
+
+   /* Initialise graphics mode */
+   if (!LXEnterGraphics(pScrn, pScrni))
+      return FALSE;
+
+   pScrni->virtualX = virtualX;
+   pScrni->virtualY = virtualY;
+
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(1)!\n"));
+
+   /* Reset visual list */
+   miClearVisualTypes();
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(2)!\n"));
+
+   /* Setup the visual we support */
+   if (pScrni->bitsPerPixel > 8) {
+      DEBUGMSG(1, (scrnIndex, X_PROBED,
+		   "miSetVisualTypes %d %X %X %X\n",
+		   pScrni->depth,
+		   TrueColorMask,
+		   pScrni->rgbBits, pScrni->defaultVisual));
+
+      if (!miSetVisualTypes(pScrni->depth,
+			    TrueColorMask,
+			    pScrni->rgbBits,
+			    pScrni->defaultVisual)) {
+	 return FALSE;
+      }
+   } else {
+      if (!miSetVisualTypes(pScrni->depth,
+			    miGetDefaultVisualMask(pScrni->depth),
+			    pScrni->rgbBits,
+			    pScrni->defaultVisual)) {
+	 return FALSE;
+      }
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(3)!\n"));
+
+   /* Set for RENDER extensions */
+   miSetPixmapDepths();
+
+   /* Call the framebuffer layer's ScreenInit function, and fill in other
+    * * pScrn fields.
+    */
+   switch (pScrni->bitsPerPixel) {
+   case 8:
+   case 16:
+   case 24:
+   case 32:
+      Inited = fbScreenInit(pScrn, FBStart, virtualX, virtualY,
+			    pScrni->xDpi, pScrni->yDpi,
+			    displayWidth, pScrni->bitsPerPixel);
+      break;
+   default:
+      xf86DrvMsg(scrnIndex, X_ERROR,
+		 "Internal error: invalid bpp (%d) in ScreenInit\n",
+		 pScrni->bitsPerPixel);
+      Inited = FALSE;
+      break;
+   }
+   if (!Inited)
+      return FALSE;
+
+   LXRotationInit(pScrni);
+   LXAdjustFrame(scrnIndex, pScrni->frameX0, pScrni->frameY0, 0);
+
+   /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */
+   AvailBox.x1 = 0;
+   AvailBox.y1 = (fboffset + pGeode->AccelPitch-1) / pGeode->AccelPitch;
+   AvailBox.x2 = displayWidth;
+   AvailBox.y2 = (pGeode->FBAvail - pGeode->AccelPitch+1) / pGeode->AccelPitch;
+
+   if( AvailBox.y1 < AvailBox.y2 ) {
+      xf86DrvMsg(scrnIndex, X_INFO,
+	         "Initializing Memory manager to (%d,%d) (%d,%d)\n",
+	         AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2);
+      REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2);
+      if( !xf86InitFBManagerRegion(pScrn, &OffscreenRegion) ) {
+         xf86DrvMsg(scrnIndex, X_ERROR,
+                    "Memory manager initialization failed, Cache Diabled\n");
+      }
+      REGION_UNINIT(pScrn, &OffscreenRegion);
+   }
+   else {
+      xf86DrvMsg(scrnIndex, X_INFO,
+	         "No Off Screen Memory, Cache Disabled (%d,%d) (%d,%d)\n",
+		 AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2);
+   }
+
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(4)!\n"));
+   xf86SetBlackWhitePixels(pScrn);
+
+   if( !pGeode->ShadowFB ) {
+      LXDGAInit(pScrn);
+   }
+
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(5)!\n"));
+   if (pScrni->bitsPerPixel > 8) {
+      /* Fixup RGB ordering */
+      visual = pScrn->visuals + pScrn->numVisuals;
+      while (--visual >= pScrn->visuals) {
+	 if ((visual->class | DynamicClass) == DirectColor) {
+	    visual->offsetRed = pScrni->offset.red;
+	    visual->offsetGreen = pScrni->offset.green;
+	    visual->offsetBlue = pScrni->offset.blue;
+	    visual->redMask = pScrni->mask.red;
+	    visual->greenMask = pScrni->mask.green;
+	    visual->blueMask = pScrni->mask.blue;
+	 }
+      }
+   }
+   /* must be after RGB ordering fixed */
+   fbPictureInit(pScrn, 0, 0);
+
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(6)!\n"));
+   if (!pGeode->NoAccel) {
+      LXAccelInit(pScrn);
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(7)!\n"));
+   miInitializeBackingStore(pScrn);
+   xf86SetBackingStore(pScrn);
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(8)!\n"));
+   /* Initialise software cursor */
+   miDCInitialize(pScrn, xf86GetPointerScreenFuncs());
+   /* Initialize HW cursor layer.
+    * * Must follow software cursor initialization
+    */
+   if (pGeode->HWCursor) {
+      if (!LXHWCursorInit(pScrn))
+	 xf86DrvMsg(pScrni->scrnIndex, X_ERROR,
+		    "Hardware cursor initialization failed\n");
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(9)!\n"));
+   /* Setup default colourmap */
+   if (!miCreateDefColormap(pScrn)) {
+      return FALSE;
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(10)!\n"));
+   if( pScrni->bitsPerPixel == 8 ) {
+      /* Initialize colormap layer.
+       * * Must follow initialization of the default colormap
+       */
+      if (!xf86HandleColormaps(pScrn, 256, 8,
+			       LXLoadPalette, NULL,
+			       CMAP_PALETTED_TRUECOLOR |
+			       CMAP_RELOAD_ON_MODE_SWITCH)) {
+         return FALSE;
+      }
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(11)!\n"));
+
+   if (pGeode->ShadowFB) {
+      DEBUGMSG(1,(0, X_INFO, "Shadowed, Rotate=%d, NoAccel=%d\n",pGeode->Rotate,pGeode->NoAccel));
+      LXShadowFBInit(pScrn,pGeode,bytpp);
+   }
+#ifdef DPMSExtension
+   xf86DPMSInit(pScrn, LXDPMSSet, 0);
+#endif
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(12)!\n"));
+
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(13)!\n"));
+   LXInitVideo(pScrn);		/* needed for video */
+   /* Wrap the screen's CloseScreen vector and set its
+    * SaveScreen vector 
+    */
+   pGeode->CloseScreen = pScrn->CloseScreen;
+   pScrn->CloseScreen = LXCloseScreen;
+
+   pScrn->SaveScreen = LXSaveScreen;
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(14)!\n"));
+
+   /* Report any unused options */
+   if (serverGeneration == 1) {
+      xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options);
+   }
+   DEBUGMSG(1,(0, X_INFO, "LXScreenInit(15)!\n"));
+   return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSwitchMode.
+ *
+ * Description	:This function will switches the screen mode
+ *   			    				
+ * Parameters:
+ *    scrnIndex	:Specfies the screen index value.
+ *    pMode		:pointer to the mode structure.
+ * 	  flags     :may be used for status check?.
+ *	  												
+ * Returns		:Returns TRUE on success and FALSE on failure.
+ *
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+Bool
+LXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
+{
+   DEBUGMSG(1,(0, X_INFO, "LXSwitchMode!\n"));
+   return LXSetMode(xf86Screens[scrnIndex], pMode);
+}
+
+/*----------------------------------------------------------------------------
+ * LXAdjustFrame.
+ *
+ * Description	:This function is used to intiallize the start
+ *				 address of the memory.
+ * Parameters.
+ *    scrnIndex	:Specfies the screen index value.
+ *     x     	:x co-ordinate value interms of pixels.
+ * 	   y        :y co-ordinate value interms of pixels.
+ *	  												
+ * Returns		:none.
+ *
+ * Comments    	:none.
+*----------------------------------------------------------------------------
+*/
+void
+LXAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+   ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   int newX, newY;
+   unsigned long offset;
+   if( x+pGeode->HDisplay >= pScrni->virtualX )
+      x = pScrni->virtualX-pGeode->HDisplay;
+   if( x < 0 ) x = 0;
+   if( y+pGeode->VDisplay >= pScrni->virtualY )
+      y = pScrni->virtualY-pGeode->VDisplay;
+   if( y < 0 ) y = 0;
+   pScrni->frameX0 = x;
+   pScrni->frameY0 = y;
+   pScrni->frameX1 = x + pGeode->HDisplay-1;
+   pScrni->frameY1 = y + pGeode->VDisplay-1;
+   (*pGeode->Rotation)(x,y,pScrni->virtualX,pScrni->virtualY,&newX,&newY);
+   (*pGeode->RBltXlat)(newX,newY,pGeode->HDisplay,pGeode->VDisplay,&newX,&newY);
+   offset = pGeode->FBOffset + newY*pGeode->Pitch + newX*(pScrni->bitsPerPixel>>3);
+   vg_set_display_offset(offset);
+}
+
+/*----------------------------------------------------------------------------
+ * LXEnterVT.
+ *
+ * Description	:This is called when VT switching back to the X server
+ *			
+ * Parameters.
+ *    scrnIndex	:Specfies the screen index value.
+ *     flags   	:Not used inside the function.
+ * 	 						
+ * Returns		:none.
+ *
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXEnterVT(int scrnIndex, int flags)
+{
+   DEBUGMSG(1,(0, X_INFO, "LXEnterVT!\n"));
+   return LXEnterGraphics(NULL, xf86Screens[scrnIndex]);
+}
+
+/*----------------------------------------------------------------------------
+ * LXLeaveVT.
+ *
+ * Description	:This is called when VT switching  X server text mode.
+ *			
+ * Parameters.
+ *    scrnIndex	:Specfies the screen index value.
+ *     flags    :Not used inside the function.
+ * 	 						
+ * Returns		:none.
+ *
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXLeaveVT(int scrnIndex, int flags)
+{
+   ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   pGeode->PrevDisplayOffset = vg_get_display_offset();
+   DEBUGMSG(1,(0, X_INFO, "LXLeaveVT!\n"));
+   LXLeaveGraphics(xf86Screens[scrnIndex]);
+}
+
+/*----------------------------------------------------------------------------
+ * LXFreeScreen.
+ *
+ * Description	:This is called to free any persistent data structures.
+ *			
+ * Parameters.
+ *    scrnIndex :Specfies the screen index value.
+ *     flags   	:Not used inside the function.
+ * 	 						
+ * Returns		:none.
+ *
+ * Comments     :This will be called only when screen being deleted..
+*----------------------------------------------------------------------------
+*/
+static void
+LXFreeScreen(int scrnIndex, int flags)
+{
+   DEBUGMSG(1,(0, X_INFO, "LXFreeScreen!\n"));
+   if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+      vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+   LXFreeRec(xf86Screens[scrnIndex]);
+}
+
+/*----------------------------------------------------------------------------
+ * LXValidMode.
+ *
+ * Description	:This function checks if a mode is suitable for selected
+ *                   		chipset.
+ * Parameters.
+ *    scrnIndex :Specfies the screen index value.
+ *     pMode	:Pointer to the screen mode structure..
+ * 	 verbose    :not used for implementation.						
+ *     flags    :not used for implementation
+ *
+ * Returns		:MODE_OK if the specified mode is supported or
+ *                    		MODE_NO_INTERLACE.
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+static int
+LXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags)
+{
+   unsigned int total_memory_required;
+   ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+   int ret = -1;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+
+   DEBUGMSG(0, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n",
+		pMode->CrtcHDisplay, pMode->CrtcVDisplay,
+		pScrni->bitsPerPixel, LXGetRefreshRate(pMode)));
+   if( pGeode->CustomMode == 0 ) {
+      int tv_mode;
+      VG_QUERY_MODE vgQueryMode;
+      unsigned long flags;
+
+      if (pMode->Flags & V_INTERLACE)
+	 return MODE_NO_INTERLACE;
+
+      flags = VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP | 
+              VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT;
+
+      if( (pGeode->EnabledOutput&LX_OT_FP) != 0 ) {
+         /* scaling required, but too big to scale */
+         if( pGeode->FPGeomDstX != pMode->CrtcHDisplay && pMode->CrtcHDisplay > 1024 )
+            return MODE_NOMODE;
+         flags = VG_QUERYFLAG_PANELWIDTH | VG_QUERYFLAG_PANELHEIGHT |
+                 VG_QUERYFLAG_PANEL;
+         vgQueryMode.panel_width = pGeode->FPGeomDstX;
+         vgQueryMode.panel_height = pGeode->FPGeomDstY;
+      }
+
+      vgQueryMode.active_width = pMode->CrtcHDisplay;
+      vgQueryMode.active_height = pMode->CrtcVDisplay;
+      vgQueryMode.bpp = pScrni->bitsPerPixel;
+      vgQueryMode.hz = LXGetRefreshRate(pMode);
+      vgQueryMode.query_flags = VG_QUERYFLAG_REFRESH     | VG_QUERYFLAG_BPP | 
+                                VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT;
+      if( (tv_mode=lx_tv_mode(pMode)) >= 0 ) {
+         vgQueryMode.encoder = pGeode->tv_encoder;
+         vgQueryMode.tvmode = tv_mode;
+         vgQueryMode.query_flags |= VG_QUERYFLAG_TVMODE | VG_QUERYFLAG_ENCODER;
+         vgQueryMode.query_flags &= ~VG_QUERYFLAG_REFRESH;
+         if( lx_tv_mode_interlaced(tv_mode) != 0 ) {
+            vgQueryMode.query_flags |= VG_QUERYFLAG_INTERLACED;
+            vgQueryMode.active_height /= 2;
+         }
+      }
+      ret = vg_get_display_mode_index(&vgQueryMode);
+      if (ret < 0)
+         return MODE_NOMODE;
+   }
+
+   total_memory_required = LXCalculatePitchBytes(pMode->CrtcHDisplay,
+                           pScrni->bitsPerPixel) * pMode->CrtcVDisplay;
+
+   DEBUGMSG(0, (0, X_NONE, "Total Mem %x %lx\n",
+		total_memory_required, pGeode->FBAvail));
+
+   if (total_memory_required > pGeode->FBAvail)
+      return MODE_MEM;
+
+   return MODE_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * LXLoadPalette.
+ *
+ * Description	:This function sets the  palette entry used for graphics data
+ *
+ * Parameters.
+ *   pScrni:Points the screeninfo structure.
+ *     numColors:Specifies the no of colors it supported.
+ * 	 indizes    :This is used get index value .						
+ *     LOCO     :to be added.
+ *     pVisual  :to be added.
+ *
+ * Returns		:MODE_OK if the specified mode is supported or
+ *          	 MODE_NO_INTERLACE.
+ * Comments     :none.
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXLoadPalette(ScrnInfoPtr pScrni,
+	       int numColors, int *indizes, LOCO * colors, VisualPtr pVisual)
+{
+   int i, index, color;
+
+   for (i = 0; i < numColors; i++) {
+      index = indizes[i] & 0xFF;
+      color = (((unsigned long)(colors[index].red & 0xFF)) << 16) |
+              (((unsigned long)(colors[index].green & 0xFF)) << 8) |
+              ((unsigned long)(colors[index].blue & 0xFF));
+      vg_set_display_palette_entry(index, color);
+   }
+}
+
+static Bool
+LXMapMem(ScrnInfoPtr pScrni)
+{
+   unsigned long cmd_bfr_phys;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+      DEBUGMSG(1, (0, X_NONE, "LXMapMem\n"));
+
+   cim_gp_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+			      VIDMEM_MMIO,
+			      pGeode->InitBaseAddress.gp_register_base,
+			      pGeode->gp_reg_size);
+   cim_vg_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+			      VIDMEM_MMIO,
+			      pGeode->InitBaseAddress.vg_register_base,
+			      pGeode->vg_reg_size);
+   cim_vid_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+			      VIDMEM_MMIO,
+			      pGeode->InitBaseAddress.df_register_base,
+			      pGeode->vid_reg_size);
+
+   cim_vip_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+			      VIDMEM_MMIO,
+			      pGeode->InitBaseAddress.vip_register_base,
+			      pGeode->vip_reg_size);
+
+   cim_fb_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+                              VIDMEM_FRAMEBUFFER,
+                              pGeode->InitBaseAddress.framebuffer_base,
+                              pGeode->InitBaseAddress.framebuffer_size);
+   pGeode->FBBase = cim_fb_ptr;
+
+   DEBUGMSG(1, (0, X_NONE, "cim ptrs %p %p %p %p %p\n",
+		cim_gp_ptr, cim_vg_ptr, cim_vid_ptr,
+		cim_vip_ptr, cim_fb_ptr));
+
+   /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */
+   if ((!cim_gp_ptr) || (!cim_vid_ptr) || (!cim_fb_ptr)) {
+      DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n"));
+      return (FALSE);
+   }
+
+   cmd_bfr_phys = pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset;
+   cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset;
+
+   /* map the top of the frame buffer as the scratch buffer (GP3_SCRATCH_BUFFER_SIZE) */
+   gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base,pGeode->FBTop);
+   gp_set_command_buffer_base(cmd_bfr_phys,0,pGeode->CmdBfrSize);
+   DEBUGMSG(1, (0, X_NONE, "cim cmd  %p %lx %lx %lx\n",
+		cim_cmd_base_ptr, pGeode->CmdBfrSize, cmd_bfr_phys, pGeode->FBTop));
+
+   /* Map the XpressROM ptr to read what platform are we on */
+   XpressROMPtr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+						 VIDMEM_FRAMEBUFFER, 0xF0000,
+						 0x10000);
+
+   DEBUGMSG(1, (0, X_NONE, "adapter info %lx %lx %lx %lx %p, %p\n",
+		pGeode->cpu_version,
+		pGeode->vid_version, pGeode->FBLinearAddr,
+		pGeode->FBAvail, pGeode->FBBase, XpressROMPtr));
+
+   return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+LXUnmapMem(ScrnInfoPtr pScrni)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+      DEBUGMSG(1, (0, X_NONE, "LXUnMapMem\n"));
+
+   /* unmap all the memory map's */
+   xf86UnMapVidMem(pScrni->scrnIndex,
+                   cim_gp_ptr, pGeode->gp_reg_size);
+   xf86UnMapVidMem(pScrni->scrnIndex,
+                   cim_vg_ptr, pGeode->vg_reg_size);
+   xf86UnMapVidMem(pScrni->scrnIndex,
+		   cim_vid_ptr, pGeode->vid_reg_size);
+   xf86UnMapVidMem(pScrni->scrnIndex,
+		   cim_vip_ptr, pGeode->vip_reg_size);
+   xf86UnMapVidMem(pScrni->scrnIndex,
+                   cim_fb_ptr, pGeode->InitBaseAddress.framebuffer_size);
+   xf86UnMapVidMem(pScrni->scrnIndex, XpressROMPtr, 0x10000);
+   return TRUE;
+}
+
+/* End of file */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_regacc.c xf86-video-nsc-2.8.1/src/amd_lx_regacc.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_regacc.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_regacc.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,70 @@
+/*
+ * $Workfile: amd_regacc.c $
+ * $Revision: #2 $
+ * $Author: raymondd $
+ *
+ * This is the main file used to add Cimarron graphics support to a software 
+ * project.  The main reason to have a single file include the other files
+ * is that it centralizes the location of the compiler options.  This file
+ * should be tuned for a specific implementation, and then modified as needed
+ * for new Cimarron releases.  The releases.txt file indicates any updates to
+ * this main file, such as a new definition for a new hardware platform. 
+ *
+ * In other words, this file should be copied from the Cimarron source files
+ * once when a software project starts, and then maintained as necessary.  
+ * It should not be recopied with new versions of Cimarron unless the 
+ * developer is willing to tune the file again for the specific project.
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#include "cim_defs.h"
+
+extern unsigned char *cim_vid_ptr;
+
+void cim_write_vid32(unsigned long offset, unsigned long value);
+unsigned long cim_read_vid32(unsigned long offset);
+
+	void
+cim_write_vid32(unsigned long offset, unsigned long value)
+{
+   WRITE_VID32(offset, value);
+}
+unsigned long
+cim_read_vid32(unsigned long offset)
+{
+   unsigned long value;
+
+   value = READ_VID32(offset);
+   return value;
+}
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_shadow.c xf86-video-nsc-2.8.1/src/amd_lx_shadow.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_shadow.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_shadow.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,436 @@
+/*
+ * $Workfile: amd_lx_shadow.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ *
+ * File Contents: Direct graphics display routines are implemented and 
+ *                graphics rendering are all done in memory.
+ *
+ * Project:       Geode Xfree Frame buffer device driver.
+ *
+ *     
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "nsc.h"
+#include "shadowfb.h"
+#include "servermd.h"
+
+#define CLIP(sip,bp,u1,v1,u2,v2) \
+   u1 = bp->x1;  v1 = bp->y1; \
+   u2 = bp->x2;  v2 = bp->y2; \
+   if( u1 < 0 ) u1 = 0; \
+   if( v1 < 0 ) v1 = 0; \
+   if( u1 > sip->virtualX ) u1 = sip->virtualX; \
+   if( v1 > sip->virtualY ) v1 = sip->virtualY; \
+   if( u2 < 0 ) u2 = 0; \
+   if( v2 < 0 ) v2 = 0; \
+   if( u2 > sip->virtualX ) u2 = sip->virtualX; \
+   if( v2 > sip->virtualY ) v2 = sip->virtualY;
+
+void LXAccelSync(ScrnInfoPtr pScrni);
+
+void
+LXRotation0(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newX = x;
+   *newY = y;
+}
+
+void
+LXRotation1(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newX = (h-1) - y;
+   *newY = x;
+}
+
+void
+LXRotation2(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newX = (w-1) - x;
+   *newY = (h-1) - y;
+}
+
+void
+LXRotation3(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newY = (w-1) - x;
+   *newX = y;
+}
+
+void
+LXRBltXlat0(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newX = x;
+   *newY = y;
+}
+
+void
+LXRBltXlat1(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newX = x - (h-1);
+   *newY = y;
+}
+
+void
+LXRBltXlat2(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newX = x - (w-1);
+   *newY = y - (h-1);
+}
+
+void
+LXRBltXlat3(int x,int y,int w,int h,int *newX,int *newY)
+{
+   *newX = x;
+   *newY = y - (w-1);
+}
+
+/*----------------------------------------------------------------------------
+ * LXPointerMoved.
+ *
+ * Description	:This function moves one screen memory from one area to other.
+ *
+ * Parameters.
+ *    index		:Pointer to screen index.
+ *     x		:Specifies the new x co-ordinates of new area.
+ *     y		:Specifies the new y co-ordinates of new area.
+ * Returns		:none
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+void
+LXPointerMoved(int index, int x, int y)
+{
+   ScrnInfoPtr pScrni = xf86Screens[index];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   Bool frameChanged = FALSE;
+
+   if( x < 0 )
+      x = 0;
+   else if( x >= pScrni->virtualX )
+      x = pScrni->virtualX-1;
+   if( y < 0 )
+      y = 0;
+   else if( y >= pScrni->virtualY )
+      y = pScrni->virtualY-1;
+
+   if( pScrni->frameX0 > x ) {
+      pScrni->frameX0 = x;
+      pScrni->frameX1 = x + pGeode->HDisplay - 1;
+      frameChanged = TRUE ;
+    }
+
+    if( pScrni->frameX1 < x ) {
+       pScrni->frameX1 = x + 1;
+       pScrni->frameX0 = x - pGeode->HDisplay + 1;
+       frameChanged = TRUE ;
+    }
+
+    if( pScrni->frameY0 > y ) {
+       pScrni->frameY0 = y;
+       pScrni->frameY1 = y + pGeode->VDisplay - 1;
+       frameChanged = TRUE;
+    }
+
+    if( pScrni->frameY1 < y ) {
+       pScrni->frameY1 = y;
+       pScrni->frameY0 = y - pGeode->VDisplay + 1;
+       frameChanged = TRUE;
+    }
+
+    if(frameChanged && pScrni->AdjustFrame != NULL)
+       pScrni->AdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0);
+}
+
+void
+LXRefreshArea_Cpy(ScrnInfoPtr pScrni, int num, BoxPtr pbox)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   int x1, y1, x2, y2, width, height;
+   unsigned long src, dst;
+   int Bpp = pScrni->bitsPerPixel >> 3;
+   gp_declare_blt(0);
+   gp_set_raster_operation(0xcc); /* copy dst=src */
+   gp_write_parameters();
+   for( ; --num>=0; ++pbox ) {
+      CLIP(pScrni,pbox,x1,y1,x2,y2);
+      if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;
+      src = y1*pGeode->ShadowPitch + x1*Bpp;
+      dst = pGeode->FBOffset + y1*pGeode->Pitch + x1*Bpp;
+      gp_declare_blt(0);
+      gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch);
+      gp_screen_to_screen_blt(dst,src, width,height, 0);
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LXRefreshArea8.
+ *
+ * Description	:This function  copies the memory to be displayed from the
+ *                 shadow pointer by 8bpp.
+ * Parameters.
+ *    pScrni		:Pointer to ScrnInfo structure.
+ *    num		:Specifies the num of squarebox area to be displayed.
+ *    pbox		:Points to square of memory to be displayed.
+ * Returns		:none
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+
+static int lx_shdw_fmt[4] = {
+   CIMGP_SOURCE_FMT_3_3_2,
+   CIMGP_SOURCE_FMT_0_5_6_5,
+   CIMGP_SOURCE_FMT_24BPP,
+   CIMGP_SOURCE_FMT_8_8_8_8
+};
+
+
+void
+LXRefreshArea_Blt(ScrnInfoPtr pScrni, int num, BoxPtr pbox)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   int width, height, x1, y1, x2, y2, newX, newY;
+   unsigned long src, dst;
+   int Bpp = pScrni->bitsPerPixel >> 3;
+   gp_set_source_format(lx_shdw_fmt[Bpp-1]);
+   gp_declare_blt(0);
+   gp_set_raster_operation(0xcc); /* copy dst=src */
+   gp_write_parameters();
+   for( ; --num>=0; ++pbox ) {
+      CLIP(pScrni,pbox,x1,y1,x2,y2);
+      if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;
+      (*pGeode->Rotation)(x1,y1,pScrni->virtualX,pScrni->virtualY,&newX,&newY);
+      (*pGeode->RBltXlat)(newX,newY,width,height,&newX,&newY);
+      src = y1*pGeode->ShadowPitch + x1*Bpp;
+      dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*Bpp;
+      gp_declare_blt(0);
+      gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch);
+      gp_rotate_blt(dst,src, width,height, pGeode->Rotate*90);
+   }
+}
+
+void
+LXRefreshArea0_Cpu(ScrnInfoPtr pScrni, int num, BoxPtr pbox)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   int width, height, x1, y1, x2, y2;
+   unsigned char *src, *dst;
+   int Bpp = pScrni->bitsPerPixel >> 3;
+   LXAccelSync(pScrni);
+   for( ; --num>=0; ++pbox ) {
+      CLIP(pScrni,pbox,x1,y1,x2,y2);
+      if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;
+      src = pGeode->ShadowPtr + y1*pGeode->ShadowPitch + x1*Bpp;
+      dst = pGeode->FBBase+pGeode->FBOffset + y1*pGeode->Pitch + x1*Bpp;
+      width *= Bpp;
+      while( --height >= 0 ) {
+	 memcpy(dst,src,width);
+	 dst += pGeode->Pitch;
+	 src += pGeode->ShadowPitch;
+      }
+   }
+}
+
+#define RefreshArea1_Cpu(nm,typ) \
+void LXRefreshArea1_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox)\
+{                                                                     \
+   GeodePtr pGeode = GEODEPTR(pScrni);                                \
+   int l, width, height, x1, y1, x2, y2, newX, newY;                  \
+   unsigned long src, dst, dp;                                        \
+   typ *sp;                                                           \
+   LXAccelSync(pScrni);                                              \
+   for( ; --num>=0; ++pbox ) {                                        \
+      CLIP(pScrni,pbox,x1,y1,x2,y2);                                  \
+      if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;        \
+      src = y1*pGeode->ShadowPitch + x1*sizeof(typ);                  \
+      newX = pScrni->virtualY-1 - y1;                                 \
+      newY = x1;                                                      \
+      dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \
+      while( --height >= 0 ) {                                        \
+         sp = (typ *)(pGeode->ShadowPtr + src);                       \
+         dp = (unsigned long)(pGeode->FBBase + dst);                  \
+         for( l=width; --l>=0; ) {                                    \
+            *(typ *)dp = *sp++;                                       \
+	    dp += pGeode->Pitch;                                      \
+         }                                                            \
+	 dst -= sizeof(typ);                                          \
+	 src += pGeode->ShadowPitch;                                  \
+      }                                                               \
+   }                                                                  \
+}
+
+RefreshArea1_Cpu( 8,unsigned char)
+RefreshArea1_Cpu(16,unsigned short)
+RefreshArea1_Cpu(32,unsigned int)
+
+#define RefreshArea2_Cpu(nm,typ) \
+void LXRefreshArea2_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox)\
+{                                                                     \
+   GeodePtr pGeode = GEODEPTR(pScrni);                                \
+   int l, width, height, x1, y1, x2, y2, newX, newY;                  \
+   unsigned long src, dst, dp;                                        \
+   typ *sp;                                                           \
+   LXAccelSync(pScrni);                                              \
+   for( ; --num>=0; ++pbox ) {                                        \
+      CLIP(pScrni,pbox,x1,y1,x2,y2);                                  \
+      if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;        \
+      src = y1*pGeode->ShadowPitch + x1*sizeof(typ);                  \
+      newX = pScrni->virtualX-1 - x1;                                 \
+      newY = pScrni->virtualY-1 - y1;                                 \
+      dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \
+      while( --height >= 0 ) {                                        \
+         sp = (typ *)(pGeode->ShadowPtr + src);                       \
+         dp = (unsigned long)(pGeode->FBBase + dst);                  \
+         for( l=width; --l>=0; ) {                                    \
+            *(typ *)dp = *sp++;                                       \
+            dp -= sizeof(typ);                                        \
+         }                                                            \
+	 src += pGeode->ShadowPitch;                                  \
+	 dst -= pGeode->Pitch;                                        \
+      }                                                               \
+   }                                                                  \
+}
+
+RefreshArea2_Cpu( 8,unsigned char)
+RefreshArea2_Cpu(16,unsigned short)
+RefreshArea2_Cpu(32,unsigned int)
+
+#define RefreshArea3_Cpu(nm,typ) \
+void LXRefreshArea3_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox)\
+{                                                                     \
+   GeodePtr pGeode = GEODEPTR(pScrni);                                \
+   int l, width, height, x1, y1, x2, y2, newX, newY;                  \
+   unsigned long src, dst, dp;                                        \
+   typ *sp;                                                           \
+   LXAccelSync(pScrni);                                              \
+   for( ; --num>=0; ++pbox ) {                                        \
+      CLIP(pScrni,pbox,x1,y1,x2,y2);                                  \
+      if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;        \
+      src = y1*pGeode->ShadowPitch + x1*sizeof(typ);                  \
+      newX = y1;                                                      \
+      newY = pScrni->virtualX-1 - x1;                                 \
+      dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \
+      while( --height >= 0 ) {                                        \
+         sp = (typ *)(pGeode->ShadowPtr + src);                       \
+         dp = (unsigned long)(pGeode->FBBase + dst);                  \
+         for( l=width; --l>=0; ) {                                    \
+            *(typ *)dp = *sp++;                                       \
+	    dp -= pGeode->Pitch;                                      \
+         }                                                            \
+	 dst += sizeof(typ);                                          \
+	 src += pGeode->ShadowPitch;                                  \
+      }                                                               \
+   }                                                                  \
+}
+
+RefreshArea3_Cpu( 8,unsigned char)
+RefreshArea3_Cpu(16,unsigned short)
+RefreshArea3_Cpu(32,unsigned int)
+
+void
+LXRotationInit(ScrnInfoPtr pScrni)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   switch( pGeode->Rotate ) {
+   case 1:
+      pGeode->Rotation = LXRotation1;
+      pGeode->RBltXlat = LXRBltXlat1;
+      break;
+   case 2:
+      pGeode->Rotation = LXRotation2;
+      pGeode->RBltXlat = LXRBltXlat2;
+      break;
+   case 3:
+      pGeode->Rotation = LXRotation3;
+      pGeode->RBltXlat = LXRBltXlat3;
+      break;
+   default: 
+      pGeode->Rotation = LXRotation0;
+      pGeode->RBltXlat = LXRBltXlat0;
+      break;
+   }
+}
+
+void
+LXShadowFBInit(ScreenPtr pScrn,GeodePtr pGeode,int bytpp)
+{
+   RefreshAreaFuncPtr refreshArea;
+   if( pGeode->NoAccel || !pGeode->ShadowInFBMem || 0 ) {
+      switch( bytpp ) {
+      case 2:
+         switch( pGeode->Rotate ) {
+            case 1:  refreshArea = LXRefreshArea1_Cpu16;   break;
+            case 2:  refreshArea = LXRefreshArea2_Cpu16;   break;
+            case 3:  refreshArea = LXRefreshArea3_Cpu16;   break;
+            default: refreshArea = LXRefreshArea0_Cpu;     break;
+         }
+         break;
+      case 4:
+         switch( pGeode->Rotate ) {
+            case 1:  refreshArea = LXRefreshArea1_Cpu32;   break;
+            case 2:  refreshArea = LXRefreshArea2_Cpu32;   break;
+            case 3:  refreshArea = LXRefreshArea3_Cpu32;   break;
+            default: refreshArea = LXRefreshArea0_Cpu;     break;
+         }
+         break;
+      default:
+         switch( pGeode->Rotate ) {
+            case 1:  refreshArea = LXRefreshArea1_Cpu8;    break;
+            case 2:  refreshArea = LXRefreshArea2_Cpu8;    break;
+            case 3:  refreshArea = LXRefreshArea3_Cpu8;    break;
+            default: refreshArea = LXRefreshArea0_Cpu;     break;
+         }
+         break;
+      }
+   }
+   else {
+      refreshArea = pGeode->Rotate? LXRefreshArea_Blt : LXRefreshArea_Cpy;
+   }
+   ShadowFBInit(pScrn, refreshArea);
+}
+
+/* End of file */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_vga.c xf86-video-nsc-2.8.1/src/amd_lx_vga.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_vga.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_vga.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,56 @@
+/*
+ * $Workfile: amd_lx_vga.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ *
+ * This file contains routines to set modes using the VGA registers.  
+ * Since this file is for the first generation graphics unit, it interfaces
+ * to SoftVGA registers.  It works for both VSA1 and VSA2.
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+
+/* VGA STRUCTURE */
+
+int gu3_get_vga_active(void);
+
+int
+gu3_get_vga_active(void)
+{
+   int data = READ_REG32(DC3_GENERAL_CFG);
+
+   if (data & DC3_GCFG_VGAE)
+      return 1;
+   return 0;
+}
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_video.c xf86-video-nsc-2.8.1/src/amd_lx_video.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_video.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_video.c	2007-04-17 12:10:19.000000000 +0200
@@ -0,0 +1,1436 @@
+/*
+ * $Workfile: amd_lx_video.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ *
+ * File Contents: This file consists of main Xfree video supported routines.
+ *
+ * Project:       Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* 
+ * Fixes & Extensions to support Y800 greyscale modes 
+ * Alan Hourihane <alanh@fairlite.demon.co.uk>
+ */
+#ifndef AMD_V4L2_VIDEO
+#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 "nsc.h"
+#include <X11/extensions/Xv.h>
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+#include "nsc_fourcc.h"
+
+#if DEBUGLVL>0
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0)
+#include "xf86_ansic.h"
+extern FILE *zdfp;
+#else
+#define DBLOG(n,s...) do {} while(0)
+#endif
+
+#define OFF_DELAY 	200		/* milliseconds */
+#define FREE_DELAY 	60000
+
+#define OFF_TIMER 	0x01
+#define FREE_TIMER	0x02
+#define CLIENT_VIDEO_ON	0x04
+
+#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
+#define XV_PROFILE 0
+#define REINIT  1
+
+#define DBUF 1
+void LXInitVideo(ScreenPtr pScrn);
+void LXResetVideo(ScrnInfoPtr pScrni);
+static XF86VideoAdaptorPtr LXSetupImageVideo(ScreenPtr);
+static void LXInitOffscreenImages(ScreenPtr);
+static void LXStopVideo(ScrnInfoPtr, pointer, Bool);
+static int LXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int LXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);
+static void LXQueryBestSize(ScrnInfoPtr, Bool,
+			     short, short, short, short, unsigned int *,
+			     unsigned int *, pointer);
+static int LXPutImage(ScrnInfoPtr, short, short, short, short, short, short,
+		       short, short, int, unsigned char *, short, short, Bool,
+		       RegionPtr, pointer);
+static int LXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
+				   unsigned short *, int *, int *);
+
+static void LXBlockHandler(int, pointer, pointer, pointer);
+void LXSetVideoPosition(int x, int y, int width, int height,
+			 short src_w, short src_h, short drw_w,
+			 short drw_h, int id, int offset, ScrnInfoPtr pScrni);
+
+extern void LXAccelSync(ScrnInfoPtr pScrni);
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvColorKey, xvColorKeyMode, xvFilter
+#if DBUF
+  , xvDoubleBuffer
+#endif
+  ;
+
+/*----------------------------------------------------------------------------
+ * LXInitVideo
+ *
+ * Description	:This is the initialization routine.It creates a new video adapter
+ *				 and calls LXSetupImageVideo to initialize the adaptor by filling
+ *				 XF86VideoAdaptorREc.Then it lists the existing adaptors and adds the 
+ *				 new one to it. Finally the list of XF86VideoAdaptorPtr pointers are
+ *				 passed to the xf86XVScreenInit().
+ *
+ * Parameters.
+ * ScreenPtr
+ *		pScrn	:Screen handler pointer having screen information.
+ *
+ * Returns		:none
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+void
+LXInitVideo(ScreenPtr pScrn)
+{
+   GeodePtr pGeode;
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   DBLOG(1,"LXInitVideo()\n");
+
+   pGeode = GEODEPTR(pScrni);
+
+   if (!pGeode->NoAccel) {
+      XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+      XF86VideoAdaptorPtr newAdaptor = NULL;
+
+      int num_adaptors;
+
+      newAdaptor = LXSetupImageVideo(pScrn);
+      LXInitOffscreenImages(pScrn);
+
+      num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors);
+
+      if (newAdaptor) {
+	 if (!num_adaptors) {
+	    num_adaptors = 1;
+	    adaptors = &newAdaptor;
+	 } else {
+	    newAdaptors =		/* need to free this someplace */
+		  xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
+	    if (newAdaptors) {
+	       memcpy(newAdaptors, adaptors, num_adaptors *
+		      sizeof(XF86VideoAdaptorPtr));
+	       newAdaptors[num_adaptors] = newAdaptor;
+	       adaptors = newAdaptors;
+	       num_adaptors++;
+	    }
+	 }
+      }
+
+      if (num_adaptors)
+	 xf86XVScreenInit(pScrn, adaptors, num_adaptors);
+
+      if (newAdaptors)
+	 xfree(newAdaptors);
+   }
+}
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding[1] = {
+   {
+    0,
+    "XV_IMAGE",
+    1024, 1024,
+    {1, 1}
+    }
+};
+
+#define NUM_FORMATS 4
+
+static XF86VideoFormatRec Formats[NUM_FORMATS] = {
+   {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+#if DBUF
+#define NUM_ATTRIBUTES 4
+#else
+#define NUM_ATTRIBUTES 3
+#endif
+
+static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
+#if DBUF
+   {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
+#endif
+   {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+   {XvSettable | XvGettable, 0, 1, "XV_FILTER"},
+   {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"}
+};
+
+static XF86ImageRec Images[] = {
+   XVIMAGE_UYVY,
+   XVIMAGE_YUY2,
+   XVIMAGE_Y2YU,
+   XVIMAGE_YVYU,
+   XVIMAGE_Y800,
+   XVIMAGE_I420,
+   XVIMAGE_YV12
+};
+
+#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0]));
+
+typedef struct
+{
+   FBAreaPtr area;
+   FBLinearPtr linear;
+   RegionRec clip;
+   CARD32 filter;
+   CARD32 colorKey;
+   CARD32 colorKeyMode;
+   CARD32 videoStatus;
+   Time offTime;
+   Time freeTime;
+#if DBUF
+   Bool doubleBuffer;
+   int currentBuffer;
+#endif
+}
+GeodePortPrivRec, *GeodePortPrivPtr;
+
+#define GET_PORT_PRIVATE(pScrni) \
+   (GeodePortPrivPtr)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr)
+
+/*----------------------------------------------------------------------------
+ * LXSetColorKey
+ *
+ * Description	:This function reads the color key for the pallete and
+ *				  sets the video color key register.
+ *
+ * Parameters.
+ * ScreenInfoPtr
+ *		pScrni	:Screen  pointer having screen information.
+ *		pPriv	:Video port private data
+ *
+ * Returns		:none
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+static INT32
+LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivPtr pPriv)
+{
+   int red, green, blue;
+   unsigned long key;
+
+   switch (pScrni->depth) {
+   case 8:
+      vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key);
+      red = ((key >> 16) & 0xFF);
+      green = ((key >> 8) & 0xFF);
+      blue = (key & 0xFF);
+      break;
+   case 16:
+      red = (pPriv->colorKey & pScrni->mask.red) >>
+	    pScrni->offset.red << (8 - pScrni->weight.red);
+      green = (pPriv->colorKey & pScrni->mask.green) >>
+	    pScrni->offset.green << (8 - pScrni->weight.green);
+      blue = (pPriv->colorKey & pScrni->mask.blue) >>
+	    pScrni->offset.blue << (8 - pScrni->weight.blue);
+      break;
+   default:
+      /* for > 16 bpp we send in the mask in xf86SetWeight. This
+       * function is providing the offset by 1 more. So we take 
+       * this as a special case and subtract 1 for > 16
+       */
+      red = (pPriv->colorKey & pScrni->mask.red) >>
+	    (pScrni->offset.red - 1) << (8 - pScrni->weight.red);
+      green = (pPriv->colorKey & pScrni->mask.green) >>
+	    (pScrni->offset.green - 1) << (8 - pScrni->weight.green);
+      blue = (pPriv->colorKey & pScrni->mask.blue) >>
+	    (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue);
+      break;
+   }
+
+   DBLOG(1,"LXSetColorkey() %08x %d\n",blue|(green<<8)|(red<<16),pPriv->colorKeyMode);
+   if( pPriv->colorKeyMode != 0 )
+      df_set_video_color_key((blue | (green << 8) | (red << 16)), 0xFFFFFF, 1);
+   else
+      df_set_video_color_key(0,0,1);
+   REGION_EMPTY(pScrni->pScreen, &pPriv->clip);
+   return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * LXResetVideo
+ *
+ * Description	: This function resets the video
+ *
+ * Parameters.
+ * ScreenInfoPtr
+ *		pScrni	:Screen  pointer having screen information.
+ *
+ * Returns		:None
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+
+void
+LXResetVideo(ScrnInfoPtr pScrni)
+{
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(1,"LXResetVideo()\n");
+
+   if (!pGeode->NoAccel) {
+      GeodePortPrivPtr pPriv = pGeode->adaptor->pPortPrivates[0].ptr;
+
+      LXAccelSync(pScrni);
+      df_set_video_palette(NULL);
+      LXSetColorkey(pScrni, pPriv);
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetupImageVideo
+ *
+ * Description	: This function allocates space for a Videoadaptor and initializes
+ *				  the XF86VideoAdaptorPtr record.
+ *
+ * Parameters.
+ * ScreenPtr
+ *		pScrn	:Screen handler pointer having screen information.
+ *
+ * Returns		:XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record.
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+
+static XF86VideoAdaptorPtr
+LXSetupImageVideo(ScreenPtr pScrn)
+{
+   ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   XF86VideoAdaptorPtr adapt;
+   GeodePortPrivPtr pPriv;
+   DBLOG(1,"LXSetupImageVideo()\n");
+
+   if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+			 sizeof(GeodePortPrivRec) + sizeof(DevUnion))))
+      return NULL;
+
+   adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+   adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+   adapt->name = "Advanced Micro Devices";
+   adapt->nEncodings = 1;
+   adapt->pEncodings = DummyEncoding;
+   adapt->nFormats = NUM_FORMATS;
+   adapt->pFormats = Formats;
+   adapt->nPorts = 1;
+   adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
+   pPriv = (GeodePortPrivPtr) (&adapt->pPortPrivates[1]);
+   adapt->pPortPrivates[0].ptr = (pointer) (pPriv);
+   adapt->pAttributes = Attributes;
+   adapt->nImages = NUM_IMAGES;
+   adapt->nAttributes = NUM_ATTRIBUTES;
+   adapt->pImages = Images;
+   adapt->PutVideo = NULL;
+   adapt->PutStill = NULL;
+   adapt->GetVideo = NULL;
+   adapt->GetStill = NULL;
+   adapt->StopVideo = LXStopVideo;
+   adapt->SetPortAttribute = LXSetPortAttribute;
+   adapt->GetPortAttribute = LXGetPortAttribute;
+   adapt->QueryBestSize = LXQueryBestSize;
+   adapt->PutImage = LXPutImage;
+   adapt->QueryImageAttributes = LXQueryImageAttributes;
+
+   pPriv->filter = 0;
+   pPriv->colorKey = pGeode->videoKey;
+   pPriv->colorKeyMode = 0;
+   pPriv->videoStatus = 0;
+#if DBUF
+   pPriv->doubleBuffer = TRUE;
+   pPriv->currentBuffer = 0; /* init to first buffer */
+#endif
+
+   /* gotta uninit this someplace */
+#if defined(REGION_NULL)
+   REGION_NULL(pScrn, &pPriv->clip);
+#else
+   REGION_INIT(pScrn, &pPriv->clip, NullBox, 0);
+#endif
+
+   pGeode->adaptor = adapt;
+
+   pGeode->BlockHandler = pScrn->BlockHandler;
+   pScrn->BlockHandler = LXBlockHandler;
+
+   xvColorKey = MAKE_ATOM("XV_COLORKEY");
+   xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE");
+   xvFilter = MAKE_ATOM("XV_FILTER");
+#if DBUF
+   xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
+#endif
+
+   LXResetVideo(pScrni);
+
+   return adapt;
+}
+
+/*----------------------------------------------------------------------------
+ * LXStopVideo
+ *
+ * Description	:This function is used to stop input and output video
+ *
+ * Parameters.
+ *		pScrni		:Screen handler pointer having screen information.
+ *		data		:Pointer to the video port's private data
+ *		exit		:Flag indicating whether the offscreen areas used for video
+ *					 to be deallocated or not.
+ * Returns		:none
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit)
+{
+   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   DBLOG(1,"LXStopVideo()\n");
+
+   REGION_EMPTY(pScrni->pScreen, &pPriv->clip);
+
+   LXAccelSync(pScrni);
+   if (exit) {
+      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
+	 df_set_video_enable(0,0);
+      }
+      if (pPriv->area) {
+	 xf86FreeOffscreenArea(pPriv->area);
+	 pPriv->area = NULL;
+      }
+      pPriv->videoStatus = 0;
+      pGeode->OverlayON = FALSE;
+   } else {
+      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
+	 pPriv->videoStatus |= OFF_TIMER;
+	 pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+      }
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetPortAttribute
+ *
+ * Description	:This function is used to set the attributes of a port like colorkeymode,
+ *				  double buffer support and filter.
+ *
+ * Parameters.
+ *		pScrni		:Screen handler pointer having screen information.
+ *		data		:Pointer to the video port's private data
+ *		attribute	:The port attribute to be set
+ *		value		:Value of the attribute to be set.  
+ *					 
+ * Returns		:Sucess if the attribute is supported, else BadMatch
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LXSetPortAttribute(ScrnInfoPtr pScrni,
+		    Atom attribute, INT32 value, pointer data)
+{
+   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+   DBLOG(1,"LXSetPortAttribute(%d,%#x)\n",attribute,value);
+
+   LXAccelSync(pScrni);
+   if (attribute == xvColorKey) {
+      pPriv->colorKey = value;
+      LXSetColorkey(pScrni, pPriv);
+   }
+#if DBUF
+   else if (attribute == xvDoubleBuffer) {
+      if ((value < 0) || (value > 1))
+	 return BadValue;
+      pPriv->doubleBuffer = value;
+   }
+#endif
+   else if (attribute == xvColorKeyMode) {
+      pPriv->colorKeyMode = value;
+      LXSetColorkey(pScrni, pPriv);
+   }
+   else if (attribute == xvFilter) {
+      if ((value < 0) || (value > 1))
+	 return BadValue;
+      pPriv->filter = value;
+   }
+   else
+      return BadMatch;
+
+   return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXGetPortAttribute
+ *
+ * Description	:This function is used to get the attributes of a port like hue,
+ *				 saturation,brightness or contrast.
+ *
+ * Parameters.
+ *		pScrni		:Screen handler pointer having screen information.
+ *		data		:Pointer to the video port's private data
+ *		attribute	:The port attribute to be read
+ *		value		:Pointer to the value of the attribute to be read.  
+ *					 
+ * Returns		:Sucess if the attribute is supported, else BadMatch
+ *
+ * Comments		:none
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LXGetPortAttribute(ScrnInfoPtr pScrni,
+		    Atom attribute, INT32 * value, pointer data)
+{
+   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+   DBLOG(1,"LXGetPortAttribute(%d)\n",attribute);
+
+   if (attribute == xvColorKey) {
+      *value = pPriv->colorKey;
+   }
+#if DBUF
+   else if (attribute == xvDoubleBuffer) {
+      *value = (pPriv->doubleBuffer) ? 1 : 0;
+   }
+#endif
+   else if (attribute == xvColorKeyMode) {
+      *value = pPriv->colorKeyMode;
+   }
+   else if (attribute == xvFilter) {
+      *value = pPriv->filter;
+   } else
+      return BadMatch;
+
+   return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXQueryBestSize
+ *
+ * Description	:This function provides a way to query what the destination dimensions
+ *				 would end up being if they were to request that an area vid_w by vid_h
+ *               from the video stream be scaled to rectangle of drw_w by drw_h on 
+ *				 the screen.
+ *
+ * Parameters.
+ * ScreenInfoPtr
+ *		pScrni		:Screen handler pointer having screen information.
+ *		data		:Pointer to the video port's private data
+ *      vid_w,vid_h	:Width and height of the video data.
+ *		drw_w,drw_h :Width and height of the scaled rectangle.
+ *		p_w,p_h		:Width and height of the destination rectangle. 
+ *					 
+ * Returns		:None
+ *
+ * Comments		:None
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXQueryBestSize(ScrnInfoPtr pScrni,
+		 Bool motion,
+		 short vid_w, short vid_h,
+		 short drw_w, short drw_h,
+		 unsigned int *p_w, unsigned int *p_h, pointer data)
+{
+   *p_w = drw_w;
+   *p_h = drw_h;
+
+   if (*p_w > 16384)
+      *p_w = 16384;
+   DBLOG(1,"LXQueryBestSize(%d, src %dx%d scl %dx%d dst %dx%d)\n",motion,vid_w,vid_h,drw_w,drw_h,*p_w,*p_h);
+}
+
+static void
+LXCopyGreyscale(unsigned char *src, unsigned char *dst, int srcp, int dstp, int h, int w)
+{
+   int i;
+   unsigned char *src2 = src;
+   unsigned char *dst2 = dst;
+   unsigned char *dst3;
+   unsigned char *src3;
+
+   dstp <<= 1;
+
+   while (h--) {
+      dst3 = dst2;
+      src3 = src2;
+      for (i = 0; i < w; i++) {
+	 *dst3++ = *src3++;		/* Copy Y data */
+	 *dst3++ = 0x80;		/* Fill UV with 0x80 - greyscale */
+      }
+      src3 = src2;
+      for (i = 0; i < w; i++) {
+	 *dst3++ = *src3++;		/* Copy Y data */
+	 *dst3++ = 0x80;		/* Fill UV with 0x80 - greyscale */
+      }
+      dst2 += dstp;
+      src2 += srcp;
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LXCopyData420
+ *
+ * Description	: Copies data from src to destination
+ *
+ * Parameters.
+ *		src	: pointer to the source data
+ *		dst	: pointer to destination data
+ *		srcp	: pitch of the srcdata
+ *		dstp	: pitch of the destination data 
+ *		h & w	: height and width of source data
+ *					 
+ * Returns		:None
+ *
+ * Comments		:None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXCopyData420(unsigned char *src, unsigned char *dst, int srcp, int dstp, int h, int w)
+{
+   while (h--) {
+      memcpy(dst, src, w);
+      src += srcp; dst += dstp;
+   }
+}
+
+/*----------------------------------------------------------------------------
+ * LXCopyData422
+ *
+ * Description	: Copies data from src to destination
+ *
+ * Parameters.
+ *		src			: pointer to the source data
+ *		dst			: pointer to destination data
+ *		srcp	: pitch of the srcdata
+ *		dstp	: pitch of the destination data 
+ *		h & w		: height and width of source data
+ *					 
+ * Returns		:None
+ *
+ * Comments		:None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXCopyData422(unsigned char *src, unsigned char *dst,
+	       int srcp, int dstp, int h, int w)
+{
+   w <<= 1;
+   while (h--) {
+      memcpy(dst, src, w);
+      src += srcp; dst += dstp;
+   }
+}
+
+static FBAreaPtr
+LXAllocateMemory(ScrnInfoPtr pScrni, FBAreaPtr area, int numlines)
+{
+   ScreenPtr pScrn = screenInfo.screens[pScrni->scrnIndex];
+   FBAreaPtr new_area;
+
+   if (area) {
+      if ((area->box.y2 - area->box.y1) >= numlines)
+	 return area;
+
+      if (xf86ResizeOffscreenArea(area, pScrni->displayWidth, numlines))
+	 return area;
+
+      xf86FreeOffscreenArea(area);
+   }
+
+   new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth,
+					numlines, 0, NULL, NULL, NULL);
+
+   if (!new_area) {
+      int max_w, max_h;
+
+      xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0,
+				    FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME);
+
+      if ((max_w < pScrni->displayWidth) || (max_h < numlines))
+	 return NULL;
+
+      xf86PurgeUnlockedOffscreenAreas(pScrn);
+      new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth,
+					   numlines, 0, NULL, NULL, NULL);
+   }
+
+   return new_area;
+}
+
+static BoxRec dstBox;
+static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0;
+static INT32 Bx1, Bx2, By1, By2;
+static int top, left, npixels, nlines;
+static int offset, s1offset = 0, s2offset = 0, s3offset = 0;
+static unsigned char *dst_start;
+static int d2offset = 0, d3offset = 0;
+
+static DF_VIDEO_SOURCE_PARAMS vSrcParams;
+
+void
+LXSetVideoPosition(int x, int y, int width, int height,
+		    short src_w, short src_h, short drw_w, short drw_h,
+		    int id, int offset, ScrnInfoPtr pScrni)
+{
+   long ystart, xend, yend;
+   unsigned long lines = 0;
+   unsigned long y_extra, uv_extra = 0;
+   DF_VIDEO_POSITION vidPos;
+
+   DBLOG(1,"LXSetVideoPosition(%d,%d %dx%d, src %dx%d, dst %dx%d, id %d, ofs %d)\n",
+           x,y,width,height,src_w,src_h,drw_w,drw_h,id,offset);
+
+   xend = x + drw_w;
+   yend = y + drw_h;
+
+   /*  TOP CLIPPING */
+
+   if (y < 0) {
+      if (src_h < drw_h)
+	 lines = (-y) * src_h / drw_h;
+      else
+	 lines = (-y);
+      ystart = 0;
+      drw_h += y;
+      y_extra = lines * dstPitch;
+      uv_extra = (lines >> 1) * (dstPitch2);
+   } else {
+      ystart = y;
+      lines = 0;
+      y_extra = 0;
+   }
+
+   memset(&vidPos,0,sizeof(vidPos));
+   vidPos.x= x;
+   vidPos.y = ystart;
+   vidPos.width = xend - x;
+   vidPos.height = yend - ystart;
+
+   DBLOG(1,"video_pos %d,%d %dx%d\n",vidPos.x,vidPos.y,vidPos.width,vidPos.height);
+   df_set_video_position(&vidPos);
+
+   vSrcParams.y_offset = offset + y_extra;
+   if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) {
+      vSrcParams.u_offset = offset + d3offset + uv_extra;
+      vSrcParams.v_offset = offset + d2offset + uv_extra;
+   }
+   else {
+      vSrcParams.u_offset = vSrcParams.v_offset = 0;
+   }
+   vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING;
+
+   DBLOG(1,"video_format %#x yofs %#x uofs %#x vofs %#x yp %d uvp %d wh %dx%d flg %#x\n",
+        vSrcParams.video_format, vSrcParams.y_offset, vSrcParams.u_offset,
+        vSrcParams.v_offset, vSrcParams.y_pitch, vSrcParams.uv_pitch,
+        vSrcParams.width, vSrcParams.height, vSrcParams.flags);
+ 
+   df_configure_video_source(&vSrcParams, &vSrcParams); 
+}
+
+/*----------------------------------------------------------------------------
+ * LXDisplayVideo
+ *
+ * Description	: This function sets up the video registers for playing video
+ *		  It sets up the video format,width, height & position of the 
+ *		  video window ,video offsets( y,u,v) and video pitches(y,u,v)	
+ * Parameters.
+ *					 
+ * Returns	:None
+ *
+ * Comments	:None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXDisplayVideo(ScrnInfoPtr pScrni,
+		int id,
+		int offset,
+		short width, short height,
+		int pitch,
+		int x1, int y1, int x2, int y2,
+		BoxPtr dstBox,
+		short src_w, short src_h, short drw_w, short drw_h)
+{
+   DBLOG(1,"LXDisplayVideo(id %d, ofs %d, %dx%d, p %d, %d,%d, %d,%d, src %dx%d dst %dx%d)\n",
+         id,offset,width,height,pitch,x1,y1,x2,y2,src_w,src_h,drw_w,drw_h);
+
+   LXAccelSync(pScrni);
+
+   switch (id) {
+   case FOURCC_UYVY: vSrcParams.video_format = DF_VIDFMT_UYVY; break;
+   case FOURCC_Y800:
+   case FOURCC_YV12:
+   case FOURCC_I420: vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; break;
+   case FOURCC_YUY2: vSrcParams.video_format = DF_VIDFMT_YUYV; break;
+   case FOURCC_Y2YU: vSrcParams.video_format = DF_VIDFMT_Y2YU; break;
+   case FOURCC_YVYU: vSrcParams.video_format = DF_VIDFMT_YVYU; break;
+   }
+
+   vSrcParams.width = width;
+   vSrcParams.height = height;
+   vSrcParams.y_pitch = dstPitch;
+   vSrcParams.uv_pitch = dstPitch2;
+
+   df_set_video_filter_coefficients(NULL,1);
+   if ((drw_w >= src_w) && (drw_h >= src_h))
+      df_set_video_scale(width, height, drw_w, drw_h, 
+         DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY);
+   else if (drw_w < src_w)
+      df_set_video_scale(drw_w, height, drw_w, drw_h,
+         DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY);
+   else if (drw_h < src_h)
+      df_set_video_scale(width, drw_h, drw_w, drw_h,
+         DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY);
+
+   LXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w,
+		       src_h, drw_w, drw_h, id, offset, pScrni);
+
+   df_set_video_enable(1,0);
+}
+
+#if REINIT
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+   int *dataA, *dataB;
+   int num;
+
+   num = REGION_NUM_RECTS(A);
+   if (num != REGION_NUM_RECTS(B)) {
+      return FALSE;
+   }
+
+   if ((A->extents.x1 != B->extents.x1) ||
+       (A->extents.x2 != B->extents.x2) ||
+       (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2))
+      return FALSE;
+
+   dataA = (int *)REGION_RECTS(A);
+   dataB = (int *)REGION_RECTS(B);
+
+   while (num--) {
+      if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+	 return FALSE;
+      dataA += 2;
+      dataB += 2;
+   }
+
+   return TRUE;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXPutImage	: This function writes a single frame of video into a drawable.
+ *		The position and size of the source rectangle is specified by src_x,src_y,
+ *		src_w and src_h. This data is stored in a system memory buffer at buf.  
+ *		The position and size of the destination rectangle is specified by drw_x,
+ *      drw_y,drw_w,drw_h.The data is in the format indicated by the image descriptor 
+ *		and represents a source of size width by height.  If sync is TRUE the driver 
+ *		should not return from this function until it is through reading the data from 
+ *		buf.  Returning when sync is TRUE indicates that it is safe for the data at buf
+ *		to be replaced,freed, or modified.
+ *
+ *
+ * Description		: 
+ * Parameters.
+ *					 
+ * Returns		:None
+ *
+ * Comments		:None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static int
+LXPutImage(ScrnInfoPtr pScrni,
+	    short src_x, short src_y,
+	    short drw_x, short drw_y,
+	    short src_w, short src_h,
+	    short drw_w, short drw_h,
+	    int id, unsigned char *buf,
+	    short width, short height,
+	    Bool sync, RegionPtr clipBoxes, pointer data)
+{
+   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   int new_h;
+
+#if REINIT
+   BOOL ReInitVideo = FALSE;
+   static BOOL DoReinitAgain = 0;
+#endif
+
+#if XV_PROFILE
+   long oldtime, newtime;
+
+   UpdateCurrentTime();
+   oldtime = currentTime.milliseconds;
+#endif
+   DBLOG(1,"LXPutImage(src %d,%d %dx%d dst %d,%d %dx%d, id %d %dx%d sync %d)\n",
+     src_x,src_y,src_w,src_h,drw_x,drw_y,drw_w,drw_h,id,width,height,sync);
+
+#if REINIT
+/* update cliplist */
+   if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
+      ReInitVideo = TRUE;
+   }
+   if (DoReinitAgain)
+      ReInitVideo = TRUE;
+
+   if (ReInitVideo) {
+      DBLOG(1, "Regional Not Equal - Init\n");
+#endif
+      DoReinitAgain = ~DoReinitAgain;
+      if (drw_w > 16384)
+	 drw_w = 16384;
+
+      /* Clip */
+      Bx1 = src_x;
+      Bx2 = src_x + src_w;
+      By1 = src_y;
+      By2 = src_y + src_h;
+
+      if ((Bx1 >= Bx2) || (By1 >= By2))
+	 return Success;
+
+      dstBox.x1 = drw_x;
+      dstBox.x2 = drw_x + drw_w;
+      dstBox.y1 = drw_y;
+      dstBox.y2 = drw_y + drw_h;
+
+      dstBox.x1 -= pScrni->frameX0;
+      dstBox.x2 -= pScrni->frameX0;
+      dstBox.y1 -= pScrni->frameY0;
+      dstBox.y2 -= pScrni->frameY0;
+
+      switch (id) {
+      case FOURCC_YV12:
+      case FOURCC_I420:
+
+      srcPitch = (width + 3) & ~3; /* of luma */
+      dstPitch = (width + 31) & ~31;
+
+      s2offset = srcPitch * height;
+      d2offset = dstPitch * height;
+
+      srcPitch2 = ((width >> 1) + 3) & ~3;
+      dstPitch2 = ((width >> 1) + 15) & ~15;
+
+      s3offset = (srcPitch2 * (height >> 1)) + s2offset;
+      d3offset = (dstPitch2 * (height >> 1)) + d2offset;
+
+      new_h = dstPitch * height;	/* Y */
+      new_h += (dstPitch2 * height);	/* U+V */
+      new_h += pGeode->Pitch - 1;
+      new_h /= pGeode->Pitch;
+      break;
+
+      case FOURCC_UYVY:
+      case FOURCC_YUY2:
+      case FOURCC_Y800:
+      default:
+      dstPitch = ((width << 1) + 3) & ~3;
+      srcPitch = (width << 1);
+      new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch;
+      break;
+      }
+
+#if DBUF
+      if (pPriv->doubleBuffer)
+         new_h <<= 1;
+#endif
+
+      if (!(pPriv->area = LXAllocateMemory(pScrni, pPriv->area, new_h)))
+         return BadAlloc;
+
+      /* copy data */
+      top = By1;
+      left = Bx1 & ~1;
+      npixels = ((Bx2 + 1) & ~1) - left;
+
+      switch (id) {
+      case FOURCC_YV12:
+      case FOURCC_I420:
+	 {
+	    int tmp;
+
+	    top &= ~1;
+	    offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch);
+
+#if DBUF
+	    if (pPriv->doubleBuffer && pPriv->currentBuffer)
+	       offset += (new_h >> 1) * pGeode->Pitch;
+#endif
+
+	    dst_start = pGeode->FBBase + offset + left;
+	    tmp = ((top >> 1) * srcPitch2) + (left >> 1);
+	    s2offset += tmp;
+	    s3offset += tmp;
+	    if (id == FOURCC_I420) {
+	       tmp = s2offset;
+	       s2offset = s3offset;
+	       s3offset = tmp;
+	    }
+	    nlines = ((By2 + 1) & ~1) - top;
+	 }
+	 break;
+      case FOURCC_UYVY:
+      case FOURCC_YUY2:
+      case FOURCC_Y800:
+      default:
+	 left <<= 1;
+	 buf += (top * srcPitch) + left;
+	 nlines = By2 - top;
+	 offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch);
+#if DBUF
+	 if (pPriv->doubleBuffer && pPriv->currentBuffer)
+	    offset += (new_h >> 1) * pGeode->Pitch;
+#endif
+
+	 dst_start = pGeode->FBBase + offset + left;
+	 break;
+      }
+      s1offset = (top * srcPitch) + left;
+
+#if REINIT
+      /* update cliplist */
+      REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes);
+      if (pPriv->colorKeyMode == 0) {
+	 /* draw these */
+	 xf86XVFillKeyHelper(pScrni->pScreen, pPriv->colorKey, clipBoxes);
+      }
+      LXDisplayVideo(pScrni, id, offset, width, height, dstPitch,
+		      Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w,
+		      drw_h);
+   }
+#endif
+
+   switch (id) {
+
+   case FOURCC_Y800:
+      LXCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+      break;
+   case FOURCC_YV12:
+   case FOURCC_I420:
+      LXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines,
+		     npixels);
+      LXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2,
+		     dstPitch2, nlines >> 1, npixels >> 1);
+      LXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2,
+		     dstPitch2, nlines >> 1, npixels >> 1);
+      break;
+   case FOURCC_UYVY:
+   case FOURCC_YUY2:
+   default:
+      LXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+      break;
+   }
+#if !REINIT
+   /* update cliplist */
+   REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes);
+   if (pPriv->colorKeyMode == 0) {
+      /* draw these */
+      XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0,
+			REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes));
+   }
+   LXDisplayVideo(pScrni, id, offset, width, height, dstPitch,
+		   Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h);
+#endif
+
+#if XV_PROFILE
+   UpdateCurrentTime();
+   newtime = currentTime.milliseconds;
+   DBLOG(1, "PI %d\n", newtime - oldtime);
+#endif
+
+#if DBUF
+   pPriv->currentBuffer ^= 1;
+#endif
+
+   pPriv->videoStatus = CLIENT_VIDEO_ON;
+   pGeode->OverlayON = TRUE;
+   return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXQueryImageAttributes
+ *
+ * Description	:This function is called to let the driver specify how data
+ *				 for a particular image of size width by height should be 
+ *				 stored. 		
+ *
+ * Parameters.
+ *		pScrni		:Screen handler pointer having screen information.
+ *		id		:Id for the video format
+ *		width		:width  of the image (can be modified by the driver)  
+ *		height		:height of the image (can be modified by the driver)  
+ * Returns		: Size of the memory required for storing this image
+ *
+ * Comments		:None
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LXQueryImageAttributes(ScrnInfoPtr pScrni,
+			int id,
+			unsigned short *w, unsigned short *h,
+			int *pitches, int *offsets)
+{
+   int size;
+   int tmp;
+
+   if (*w > 1024)
+      *w = 1024;
+   if (*h > 1024)
+      *h = 1024;
+
+   *w = (*w + 1) & ~1;
+   if (offsets)
+      offsets[0] = 0;
+
+   switch (id) {
+   case FOURCC_YV12:
+   case FOURCC_I420:
+      *h = (*h + 1) & ~1;
+      size = (*w + 3) & ~3;
+      if (pitches)
+	 pitches[0] = size;
+      size *= *h;
+      if (offsets)
+	 offsets[1] = size;
+      tmp = ((*w >> 1) + 3) & ~3;
+      if (pitches)
+	 pitches[1] = pitches[2] = tmp;
+      tmp *= (*h >> 1);
+      size += tmp;
+      if (offsets)
+	 offsets[2] = size;
+      size += tmp;
+      break;
+   case FOURCC_UYVY:
+   case FOURCC_YUY2:
+   case FOURCC_Y800:
+   default:
+      size = *w << 1;
+      if (pitches)
+	 pitches[0] = size;
+      size *= *h;
+      break;
+   }
+   DBLOG(1,"LXQueryImageAttributes(%d)= %d, %dx%d %d/%d/%d %d/%d/%d\n",
+      id,size,*w,*h,pitches[0],pitches[1],pitches[2],offsets[0],offsets[1],offsets[2]);
+   return size;
+}
+
+static void
+LXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+   ScreenPtr pScrn = screenInfo.screens[i];
+   ScrnInfoPtr pScrni = xf86Screens[i];
+   GeodePtr pGeode = GEODEPTR(pScrni);
+   GeodePortPrivPtr pPriv = GET_PORT_PRIVATE(pScrni);
+
+   pScrn->BlockHandler = pGeode->BlockHandler;
+   (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask);
+   pScrn->BlockHandler = LXBlockHandler;
+
+   if (pPriv->videoStatus & TIMER_MASK) {
+      DBLOG(1,"LXBlockHandler(%d)\n",i);
+      LXAccelSync(pScrni);
+      UpdateCurrentTime();
+      if (pPriv->videoStatus & OFF_TIMER) {
+	 if (pPriv->offTime < currentTime.milliseconds) {
+	    df_set_video_enable(0,0);
+	    pPriv->videoStatus = FREE_TIMER;
+	    pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+	 }
+      } else {				/* FREE_TIMER */
+	 if (pPriv->freeTime < currentTime.milliseconds) {
+	    if (pPriv->area) {
+	       xf86FreeOffscreenArea(pPriv->area);
+	       pPriv->area = NULL;
+	    }
+	    pPriv->videoStatus = 0;
+	 }
+      }
+   }
+}
+
+/****************** Offscreen stuff ***************/
+
+typedef struct
+{
+   FBAreaPtr area;
+   FBLinearPtr linear;
+   Bool isOn;
+}
+OffscreenPrivRec, *OffscreenPrivPtr;
+
+/*----------------------------------------------------------------------------
+ * LXAllocateSurface
+ *
+ * Description	:This function allocates an area of w by h in the offscreen
+ * Parameters.
+ *		pScrni	:Screen handler pointer having screen information.
+ * 
+ * Returns		:None
+ *
+ * Comments		:None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static int
+LXAllocateSurface(ScrnInfoPtr pScrni,
+		   int id,
+		   unsigned short w, unsigned short h, XF86SurfacePtr surface)
+{
+   FBAreaPtr area;
+   int pitch, fbpitch, numlines;
+   OffscreenPrivPtr pPriv;
+   DBLOG(1,"LXAllocateSurface(id %d, %dx%d)\n",id,w,h);
+
+   if ((w > 1024) || (h > 1024))
+      return BadAlloc;
+
+   w = (w + 1) & ~1;
+   pitch = ((w << 1) + 15) & ~15;
+   fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3;
+   numlines = ((pitch * h) + fbpitch - 1) / fbpitch;
+
+   if (!(area = LXAllocateMemory(pScrni, NULL, numlines)))
+      return BadAlloc;
+
+   surface->width = w;
+   surface->height = h;
+
+   if (!(surface->pitches = xalloc(sizeof(int))))
+      return BadAlloc;
+   if (!(surface->offsets = xalloc(sizeof(int)))) {
+      xfree(surface->pitches);
+      return BadAlloc;
+   }
+   if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
+      xfree(surface->pitches);
+      xfree(surface->offsets);
+      return BadAlloc;
+   }
+
+   pPriv->area = area;
+   pPriv->isOn = FALSE;
+
+   surface->pScrn = pScrni;
+   surface->id = id;
+   surface->pitches[0] = pitch;
+   surface->offsets[0] = area->box.y1 * fbpitch;
+   surface->devPrivate.ptr = (pointer) pPriv;
+
+   return Success;
+}
+
+static int
+LXStopSurface(XF86SurfacePtr surface)
+{
+   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+   DBLOG(1,"LXStopSurface()\n");
+
+   if (pPriv->isOn) {
+      pPriv->isOn = FALSE;
+   }
+
+   return Success;
+}
+
+static int
+LXFreeSurface(XF86SurfacePtr surface)
+{
+   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+   DBLOG(1,"LXFreeSurface()\n");
+
+   if (pPriv->isOn)
+      LXStopSurface(surface);
+   xf86FreeOffscreenArea(pPriv->area);
+   xfree(surface->pitches);
+   xfree(surface->offsets);
+   xfree(surface->devPrivate.ptr);
+
+   return Success;
+}
+
+static int
+LXGetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 * value)
+{
+   return LXGetPortAttribute(pScrni, attribute, value,
+			      (pointer) (GET_PORT_PRIVATE(pScrni)));
+}
+
+static int
+LXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value)
+{
+   return LXSetPortAttribute(pScrni, attribute, value,
+			      (pointer) (GET_PORT_PRIVATE(pScrni)));
+}
+
+static int
+LXDisplaySurface(XF86SurfacePtr surface,
+		  short src_x, short src_y,
+		  short drw_x, short drw_y,
+		  short src_w, short src_h,
+		  short drw_w, short drw_h, RegionPtr clipBoxes)
+{
+   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+   ScrnInfoPtr pScrni = surface->pScrn;
+   GeodePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrni);
+   INT32 x1, y1, x2, y2;
+   BoxRec dstBox;
+   DBLOG(1,"LXDisplaySurface(src %d,%d %dx%d, dst %d,%d %dx%d)\n",
+         src_x,src_y,src_w,src_h,drw_x,drw_y,drw_w,drw_h);
+
+   DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n"));
+   x1 = src_x;
+   x2 = src_x + src_w;
+   y1 = src_y;
+   y2 = src_y + src_h;
+
+   dstBox.x1 = drw_x;
+   dstBox.x2 = drw_x + drw_w;
+   dstBox.y1 = drw_y;
+   dstBox.y2 = drw_y + drw_h;
+
+   if ((x1 >= x2) || (y1 >= y2))
+      return Success;
+
+   dstBox.x1 -= pScrni->frameX0;
+   dstBox.x2 -= pScrni->frameX0;
+   dstBox.y1 -= pScrni->frameY0;
+   dstBox.y2 -= pScrni->frameY0;
+
+   xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes);
+
+   LXDisplayVideo(pScrni, surface->id, surface->offsets[0],
+		   surface->width, surface->height, surface->pitches[0],
+		   x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+
+   pPriv->isOn = TRUE;
+   if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
+      REGION_EMPTY(pScrni->pScreen, &portPriv->clip);
+      UpdateCurrentTime();
+      portPriv->videoStatus = FREE_TIMER;
+      portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+   }
+
+   return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXInitOffscreenImages
+ *
+ * Description	:This function sets up the offscreen memory management.It fills 
+ *				 in the XF86OffscreenImagePtr structure with functions to handle
+ *				 offscreen memory operations. 	
+ *
+ * Parameters.
+ *		pScrn	:Screen handler pointer having screen information.
+ * 
+ * Returns		: None
+ *
+ * Comments		:None
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXInitOffscreenImages(ScreenPtr pScrn)
+{
+   XF86OffscreenImagePtr offscreenImages;
+   DBLOG(1,"LXInitOffscreenImages()\n");
+
+   /* need to free this someplace */
+   if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))))
+      return;
+
+   offscreenImages[0].image = &Images[0];
+   offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+   offscreenImages[0].alloc_surface = LXAllocateSurface;
+   offscreenImages[0].free_surface = LXFreeSurface;
+   offscreenImages[0].display = LXDisplaySurface;
+   offscreenImages[0].stop = LXStopSurface;
+   offscreenImages[0].setAttribute = LXSetSurfaceAttribute;
+   offscreenImages[0].getAttribute = LXGetSurfaceAttribute;
+   offscreenImages[0].max_width = 1024;
+   offscreenImages[0].max_height = 1024;
+   offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
+   offscreenImages[0].attributes = Attributes;
+
+   xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1);
+}
+
+#endif /* !AMD_V4L2_VIDEO */
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_defs.h xf86-video-nsc-2.8.1/src/cim/cim_defs.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_defs.h	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_defs.h	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,732 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  * 
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  * 
+  * <DOC_AMD_STD>
+  * Cimarron hardware access macros.
+  * </DOC_AMD_STD>
+  * 
+  */
+
+#ifndef _cim_defs_h
+#define _cim_defs_h
+
+/*-----------------------------------------*/
+/*          MEMORY ACCESS MACROS           */
+/*-----------------------------------------*/
+
+#ifndef CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS
+
+#define READ_GP32(offset) \
+    (*(volatile unsigned long *)(cim_gp_ptr + (offset)))
+
+#define READ_REG32(offset) \
+    (*(volatile unsigned long *)(cim_vg_ptr + (offset)))
+
+#define READ_FB32(offset) \
+    (*(volatile unsigned long *)(cim_fb_ptr + (offset)))
+
+#define WRITE_GP32(offset, value) \
+	(*(volatile unsigned long *)(cim_gp_ptr + (offset))) = (value)
+
+#define WRITE_REG32(offset, value) \
+	(*(volatile unsigned long *)(cim_vg_ptr + (offset))) = (value)
+
+#define WRITE_COMMAND32(offset, value) \
+	(*(unsigned long *)(cim_cmd_ptr + (offset))) = (value)
+
+#define WRITE_COMMAND8(offset, value) \
+	(*(unsigned char *)(cim_cmd_ptr + (offset))) = (value)
+
+#define WRITE_FB32(offset, value) \
+	(*(unsigned long *)(cim_fb_ptr + (offset))) = (value)
+
+#define READ_VID32(offset) \
+    (*(volatile unsigned long *)(cim_vid_ptr + (offset)))
+
+#define WRITE_VID32(offset, value) \
+	(*(volatile unsigned long *)(cim_vid_ptr + (offset))) = (value)
+
+#define READ_VIP32(offset) \
+    (*(volatile unsigned long *)(cim_vip_ptr + (offset)))
+
+#define WRITE_VIP32(offset, value) \
+	(*(volatile unsigned long *)(cim_vip_ptr + (offset))) = (value)
+
+#define READ_VOP32(offset) \
+    (*(volatile unsigned long *)(cim_vid_ptr + (offset)))
+
+#define WRITE_VOP32(offset, value) \
+	(*(volatile unsigned long *)(cim_vid_ptr + (offset))) = (value)
+
+#endif
+
+/*-----------------------------------------*/
+/*            GP POLLING MACROS            */
+/*-----------------------------------------*/
+
+#define GP3_WAIT_WRAP(variable) \
+	while(((variable = READ_GP32 (GP3_CMD_READ)) > gp3_cmd_current) || \
+           (variable <= (gp3_cmd_top + GP3_BLT_COMMAND_SIZE + GP3_BLT_COMMAND_SIZE + 96)))
+
+#define GP3_WAIT_PRIMITIVE(variable) \
+	while (((variable = READ_GP32 (GP3_CMD_READ)) > gp3_cmd_current) && \
+            (variable <= (gp3_cmd_next + 96)))
+
+#define GP3_WAIT_BUSY \
+	while(READ_GP32 (GP3_BLT_STATUS) & GP3_BS_BLT_BUSY)
+
+#define GP3_WAIT_PENDING \
+	while(READ_GP32 (GP3_BLT_STATUS) & GP3_BS_BLT_PENDING)
+
+/*-----------------------------------------------------------------*/
+/* MSR MACROS                                                      */
+/* These macros facilitate interaction with the model specific     */
+/* registers in GeodeLX.  There are two included methods, direct   */
+/* access using the rdmsr and wrmsr opcodes and an indirect method */
+/* using VSAII.                                                    */
+/*-----------------------------------------------------------------*/
+
+#ifdef CIMARRON_INCLUDE_MSR_MACROS
+
+#if CIMARRON_MSR_DIRECT_ASM
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr_reg, device_add, data64_ptr)                                   \
+{                                                                                   \
+	unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+	unsigned long data_high, data_low;                                              \
+	_asm { mov ecx, msr_add   }                                                     \
+	_asm { rdmsr              }                                                     \
+	_asm { mov data_high, edx }                                                     \
+	_asm { mov data_low,  eax }                                                     \
+	                                                                                \
+	((Q_WORD *)(data64_ptr))->high = data_high;                                     \
+	((Q_WORD *)(data64_ptr))->low  = data_low;                                      \
+}
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Write the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr_reg, device_add, data64_ptr)                                  \
+{                                                                                   \
+	unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+	unsigned long data_high, data_low;                                              \
+	                                                                                \
+	data_high = ((Q_WORD *)(data64_ptr))->high;                                     \
+	data_low  = ((Q_WORD *)(data64_ptr))->low;                                      \
+		                                                                            \
+	_asm { mov ecx, msr_add   }                                                     \
+	_asm { mov edx, data_high }                                                     \
+	_asm { mov eax, data_low  }                                                     \
+	_asm { wrmsr              }                                                     \
+}
+
+#elif CIMARRON_MSR_VSA_IO
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr_reg, device_add, data64_ptr)                                   \
+{                                                                                   \
+	unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+	unsigned long data_high, data_low;                                              \
+		                                                                            \
+	_asm { mov    dx,  0x0AC1C      } 	                                            \
+	_asm { mov    eax, 0x0FC530007  }                                               \
+	_asm { out    dx, eax           }                                               \
+		                                                                            \
+	_asm { add    dl, 2             }                                               \
+	_asm { mov    ecx, msr_add      }                                               \
+	_asm { in     ax, dx            }                                               \
+	_asm { mov    data_high, edx    }                                               \
+	_asm { mov    data_low, eax     }                                               \
+		                                                                            \
+	((Q_WORD *)(data64_ptr))->high = data_high;                                     \
+	((Q_WORD *)(data64_ptr))->low  = data_low;                                      \
+}
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Write the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr_reg, device_add, data64_ptr)                                  \
+{                                                                                   \
+	unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+	unsigned long data_high, data_low;                                              \
+		                                                                            \
+	data_high = ((Q_WORD *)(data64_ptr))->high;                                     \
+	data_low  = ((Q_WORD *)(data64_ptr))->low;                                      \
+		                                                                            \
+	_asm { mov    dx,  0x0AC1C      } 	                                            \
+	_asm { mov    eax, 0x0FC530007  }                                               \
+	_asm { out    dx, eax           }                                               \
+		                                                                            \
+	_asm { add    dl, 2             }                                               \
+	_asm { mov    ecx, msr_add      }                                               \
+	_asm { mov    ebx, data_high    }                                               \
+	_asm { mov    eax, data_low }                                                   \
+		                                                                            \
+	_asm { mov    esi, 0 }                                                          \
+	_asm { mov    edi, 0 }                                                          \
+	_asm { out    dx, ax }                                                          \
+}
+
+#elif CIMARRON_MSR_ABSTRACTED_ASM
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr,adr,val)                   \
+     __asm__ __volatile__(                      \
+        " mov $0x0AC1C, %%edx\n"                \
+        " mov $0xFC530007, %%eax\n"             \
+        " out %%eax,%%dx\n"                     \
+        " add $2,%%dl\n"                        \
+        " in %%dx, %%ax"                        \
+        : "=a" ((val)->low), "=d" ((val)->high) \
+        : "c" (msr | adr))
+
+void gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr,
+                      unsigned long *ptrHigh, unsigned long *ptrLow);
+
+#define MSR_READ( MBD_MSR_CAP, address, val ) \
+        gfx_msr_asm_read( ((unsigned short)(MBD_MSR_CAP)), address, &((val)->high), &((val)->low) )
+
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Write the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr,adr,val)                                      \
+     { int d0, d1, d2, d3, d4;                                      \
+     __asm__ __volatile__(                                          \
+	" mov $d0, %%eax\n"                                         \
+	" mov $d1, %%ebx\n"                                         \
+        " mov $0x0AC1C, %%edx\n"                                    \
+        " mov $0xFC530007, %%eax\n"                                 \
+        " out %%eax,%%dx\n"                                         \
+        " add $2,%%dl\n"                                            \
+        " mov %5, %4\n"                                             \
+        " mov 0(%6), %1\n"                                          \
+        " mov 4(%6), %0\n"                                          \
+        " xor %3, %3\n"                                             \
+        " xor %2, %2\n"                                             \
+        " out %%ax, %%dx\n"                                         \
+	" pop %%ebx"                                                \
+        : "=&D" (d2), "=&S" (d3), "=c" (d4) : "2" (msr | adr), "3" (val) );                             \
+     }
+
+void gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr,
+                       unsigned long *ptrHigh, unsigned long *ptrLow);
+
+#define MSR_WRITE( MBD_MSR_CAP, address, val ) \
+        gfx_msr_asm_write( ((unsigned short)(MBD_MSR_CAP)), address, &((val)->high), &((val)->low) )
+
+#elif CIMARRON_MSR_KERNEL_ROUTINE
+
+#include "asm/msr.h"
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr_reg, device_add, data64_ptr)                                   \
+{                                                                                   \
+    unsigned long addr, val1, val2;                                                 \
+                                                                                    \
+	addr = device_add | msr_reg;                                                    \
+	rdmsr (addr, val1, val2);                                                       \
+                                                                                    \
+	((Q_WORD *)(data64_ptr))->high = val2;                                          \
+	((Q_WORD *)(data64_ptr))->low  = val1;	                                        \
+}
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Read the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr_reg, device_add, data64_ptr)                                  \
+{                                                                                   \
+	unsigned long addr, val1, val2;                                                 \
+                                                                                    \
+	val2 = ((Q_WORD *)(data64_ptr))->high;                                          \
+	val1 = ((Q_WORD *)(data64_ptr))->low;                                           \
+                                                                                    \
+	addr = (device_add & 0xFFFF0000) | (unsigned long)msr_reg;                      \
+	wrmsr(addr, val1, val2);                                                        \
+}
+
+#endif
+
+#endif /* #ifdef CIMARRON_INCLUDE_MSR_MACROS */
+
+/*-----------------------------------------------------------------*/
+/* STRING MACROS                                                   */
+/* These macros are included to facilitate the optimization of     */
+/* routines that write or copy large amounts of data.  Two vesions */
+/* of these macros are included.  One is intended for operating    */
+/* systems that allow the use of inline assembly, while the other  */
+/* is a pure C implementation for stricter operating systems.      */
+/*-----------------------------------------------------------------*/
+
+#ifdef CIMARRON_INCLUDE_STRING_MACROS
+
+#if CIMARRON_OPTIMIZE_ASSEMBLY
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING32   
+ * Write a series of DWORDs to the current command buffer offset  
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \
+{                                                                        \
+	_asm { cld                           }                               \
+	_asm { mov edi, cim_cmd_ptr          }                               \
+	_asm { add edi, offset               }                               \
+	_asm { mov esi, dataptr              }                               \
+	_asm { add esi, dataoffset           }                               \
+	_asm { mov ecx, dword_count          }                               \
+	_asm { rep movsd                     }                               \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_STRING32
+ * Write a series of DWORDS to video memory.
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_STRING32(offset, dataptr, dword_count)                  \
+{                                                                        \
+    unsigned long temp = (unsigned long)(dataptr);                       \
+	_asm { cld                           }                               \
+	_asm { mov edi, cim_fb_ptr           }                               \
+	_asm { add edi, offset               }                               \
+	_asm { mov esi, temp                 }                               \
+	_asm { mov ecx, dword_count          }                               \
+	_asm { rep movsd                     }                               \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_CONSTANT
+ * Write a constant DWORD to multiple video memory addresses
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_CONSTANT(offset, value, dword_count)                    \
+{                                                                        \
+	unsigned long outptr = (unsigned long)cim_fb_ptr + offset;           \
+	unsigned long dwords = dword_count;                                  \
+	_asm { cld                           }                               \
+	_asm { mov edi, outptr               }                               \
+	_asm { mov eax, value                }                               \
+	_asm { mov ecx, dwords               }                               \
+	_asm { rep stosd                     }                               \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING32
+ * Write a series of DWORDs to the GP host source register
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count)     \
+{                                                                        \
+	_asm { cld                           }                               \
+	_asm { mov edi, cim_gp_ptr           }                               \
+	_asm { add edi, GP3_HST_SRC_RANGE    }                               \
+	_asm { mov esi, dataptr              }                               \
+	_asm { add esi, dataoffset           }                               \
+	_asm { mov ecx, dword_count          }                               \
+	_asm { rep movsd                     }                               \
+}
+
+#elif CIMARRON_OPTIMIZE_FORLOOP
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING32   
+ * Write a series of DWORDs to the current command buffer offset  
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count)                   \
+{                                                                                          \
+	unsigned long i;                                                                       \
+	unsigned long tempdata = (unsigned long)dataptr + (dataoffset);                        \
+	unsigned long byte_off = 0;                                                            \
+	for (i = 0; i < dword_count; i++, byte_off += 4)                                       \
+		WRITE_COMMAND32 ((offset) + byte_off, *((unsigned long *)(tempdata + byte_off)));  \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_STRING32
+ * Write a series of DWORDS to video memory.
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_STRING32(offset, dataptr, dword_count)                               \
+{                                                                                     \
+	unsigned long i;                                                                  \
+	unsigned long tempdata = (unsigned long)dataptr;                                  \
+	unsigned long byte_off = 0;                                                       \
+	for (i = 0; i < dword_count; i++, byte_off += 4)                                  \
+		WRITE_FB32 ((offset) + byte_off, *((unsigned long *)(tempdata + byte_off)));  \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_CONSTANT
+ * Write a constant DWORD to multiple video memory addresses
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_CONSTANT(offset, value, dword_count)                                        \
+{                                                                                            \
+	unsigned long i;                                                                         \
+	unsigned long tempoffset = offset;                                                       \
+	for (i = 0; i < dword_count; i++, tempoffset += 4)                                       \
+		WRITE_FB32 (tempoffset, value);                                                      \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING32
+ * Write a series of DWORDs to the GP host source register
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count)                           \
+{                                                                                              \
+	unsigned long i;                                                                           \
+	unsigned long tempdata = (unsigned long)dataptr + (dataoffset);                            \
+	unsigned long byte_off = 0;                                                                \
+	for (i = 0; i < dword_count; i++, byte_off += 4)                                           \
+		WRITE_GP32 (byte_off + GP3_HST_SRC_RANGE, *((unsigned long *)(tempdata + byte_off)));  \
+}
+
+#elif CIMARRON_OPTIMIZE_ABSTRACTED_ASM
+
+#define move_dw(d,s,n)                                  \
+  __asm__ __volatile__(                                 \
+  " rep\n"                                              \
+  " movsl\n"                                            \
+  : "=&c" (d0), "=&S" (d1), "=&D" (d2)                  \
+  : "0" (n), "1" ((const char *)s), "2" ((char *)d)     \
+  : "memory")
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING32   
+ * Write a series of DWORDs to the current command buffer offset  
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \
+{                                                                        \
+    int d0, d1, d2;                                                      \
+    move_dw (cim_cmd_ptr+ ((unsigned long)(offset)),                     \
+        ((unsigned long)(dataptr)+(dataoffset)),                         \
+        dword_count);                                                    \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_STRING32
+ * Write a series of DWORDS to video memory.
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_STRING32(offset, dataptr, dword_count)                               \
+{                                                                                     \
+	unsigned long i;                                                                  \
+	unsigned long tempdata = (unsigned long)dataptr;                                  \
+	unsigned long byte_off = 0;                                                       \
+	for (i = 0; i < dword_count; i++, byte_off += 4)                                  \
+		WRITE_FB32 ((offset) + byte_off, *((unsigned long *)(tempdata + byte_off)));  \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_CONSTANT
+ * Write a constant DWORD to multiple video memory addresses
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_CONSTANT(offset, value, dword_count)                                        \
+{                                                                                            \
+	unsigned long i;                                                                         \
+	unsigned long tempoffset = offset;                                                       \
+	for (i = 0; i < dword_count; i++, tempoffset += 4)                                       \
+		WRITE_FB32 (tempoffset, value);                                                      \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING32
+ * Write a series of DWORDs to the GP host source register
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count)                           \
+{                                                                                              \
+	unsigned long i;                                                                           \
+	unsigned long tempdata = (unsigned long)dataptr + (dataoffset);                            \
+	unsigned long byte_off = 0;                                                                \
+	for (i = 0; i < dword_count; i++, byte_off += 4)                                           \
+		WRITE_GP32 (byte_off + GP3_HST_SRC_RANGE, *((unsigned long *)(tempdata + byte_off)));  \
+}
+
+#endif
+
+#endif /* #ifdef CIMARRON_INCLUDE_STRING_MACROS */
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING8
+ * Write a series of bytes to the current command buffer offset  
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING8(offset, dataptr, dataoffset, byte_count)   \
+{                                                                        \
+	unsigned long i;                                                     \
+	unsigned long array = (unsigned long)dataptr + (dataoffset);         \
+	for (i = 0; i < byte_count; i++)                                     \
+		WRITE_COMMAND8 ((offset) + i, *((unsigned char *)(array + i)));  \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING8
+ * Write a series of bytes to the host source register  
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING8(dataptr, dataoffset, byte_count)                          \
+{                                                                                           \
+	unsigned long temp1 = (unsigned long)dataptr + (dataoffset);                            \
+	unsigned long temp2 = 0;                                                                \
+	unsigned long shift = 0;                                                                \
+	unsigned long counter;                                                                  \
+    if (byte_count)                                                                         \
+    {                                                                                       \
+        for (counter = 0; counter < byte_count; counter++)                                  \
+	    {                                                                                   \
+		    temp2 |= ((unsigned long)(*((unsigned char *)(temp1 + counter)))) << shift;     \
+		    shift += 8;                                                                     \
+	    }                                                                                   \
+	    WRITE_GP32 (GP3_HST_SRC, temp2);                                                    \
+    }                                                                                       \
+}
+
+/*-----------------------------------------*/
+/*          CUSTOM STRING MACROS           */
+/*-----------------------------------------*/
+
+#ifndef CIMARRON_EXCLUDE_CUSTOM_MACROS
+
+#define WRITE_CUSTOM_COMMAND_STRING32 WRITE_COMMAND_STRING32
+#define WRITE_CUSTOM_COMMAND_STRING8  WRITE_COMMAND_STRING8
+
+#endif
+
+/*-----------------------------------------*/
+/*             IO ACCESS MACROS            */
+/*-----------------------------------------*/
+
+#ifdef CIMARRON_INCLUDE_IO_MACROS
+
+#if CIMARRON_IO_DIRECT_ACCESS
+
+/*-------------------------------------------
+ * OUTD
+ * Writes one DWORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTD(port, data) cim_outd(port, data)
+void cim_outd (unsigned short port, unsigned long data)
+{
+	_asm {
+		pushf
+		mov     eax, data
+		mov     dx, port
+		out     dx, eax
+		popf
+	}
+}
+
+/*-------------------------------------------
+ * IND
+ * Reads one DWORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define IND(port) cim_ind(port)
+unsigned long cim_ind (unsigned short port)
+{
+	unsigned long data;
+	_asm {
+		pushf
+		mov     dx, port
+		in      eax, dx
+		mov     data, eax
+		popf
+	}
+	return data;
+}
+
+/*-------------------------------------------
+ * OUTW
+ * Writes one WORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTW(port, data) cim_outw(port, data)
+void cim_outw (unsigned short port, unsigned short data)
+{
+	_asm {
+		pushf
+		mov     ax, data
+		mov     dx, port
+		out     dx, ax
+		popf
+	}
+}
+
+/*-------------------------------------------
+ * INW
+ * Reads one WORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define INW(port) cim_inw(port)
+unsigned short cim_inw (unsigned short port)
+{
+	unsigned short data;
+	_asm {
+		pushf
+		mov     dx, port
+		in      ax, dx
+		mov     data, ax
+		popf
+	}
+	return data;
+}
+
+/*-------------------------------------------
+ * OUTB
+ * Writes one BYTE to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTB(port, data) cim_outb(port, data)
+void cim_outb (unsigned short port, unsigned char data)
+{
+	_asm {
+		pushf
+		mov     al, data
+		mov     dx, port
+		out     dx, al
+		popf
+	}
+}
+
+/*-------------------------------------------
+ * INB
+ * Reads one BYTE from a single I/O address.
+ *-------------------------------------------*/
+
+#define INB(port) cim_inb(port)
+unsigned char cim_inb (unsigned short port)
+{
+	unsigned char data;
+	_asm {
+		pushf
+		mov     dx, port
+		in      al, dx
+		mov     data, al
+		popf
+	}
+	return data;
+}
+
+#elif CIMARRON_IO_ABSTRACTED_ASM
+
+/*-------------------------------------------
+ * OUTD
+ * Writes one DWORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTD(port, data) cim_outd(port, data)
+void cim_outd (unsigned short port, unsigned long data);
+void cim_outd (unsigned short port, unsigned long data)
+{
+	__asm__ __volatile__ ("outl %0,%w1" : : "a" (data), "Nd" (port));
+}
+
+/*-------------------------------------------
+ * IND
+ * Reads one DWORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define IND(port) cim_ind(port)
+unsigned long cim_ind (unsigned short port);
+unsigned long cim_ind (unsigned short port)
+{
+	unsigned long value;
+    __asm__ __volatile__ ("inl %w1,%0" : "=a" (value) : "Nd" (port) );
+
+    return value;
+}
+
+/*-------------------------------------------
+ * OUTW
+ * Writes one WORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTW(port, data) cim_outw(port, data)
+void cim_outw (unsigned short port, unsigned short data);
+void cim_outw (unsigned short port, unsigned short data)
+{
+	__asm__ volatile ("out %0,%1" : : "a" (data),"d" (port));
+}
+
+/*-------------------------------------------
+ * INW
+ * Reads one WORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define INW(port) cim_inw(port)
+unsigned short cim_inw (unsigned short port);
+unsigned short cim_inw (unsigned short port)
+{
+	unsigned short value;
+    __asm__ volatile ("in %1,%0" : "=a" (value) : "d" (port));
+    return value;
+}
+
+/*-------------------------------------------
+ * INB
+ * Reads one BYTE from a single I/O address.
+ *-------------------------------------------*/
+
+#define INB(port) cim_inb(port)
+unsigned char cim_inb(unsigned short port);
+unsigned char cim_inb(unsigned short port)
+{
+   unsigned char value;
+   __asm__ volatile ("inb %1,%0":"=a" (value):"d"(port));
+
+   return value;
+}
+
+/*-------------------------------------------
+ * OUTB
+ * Writes one BYTE to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTB(port) cim_outb(port)
+void cim_outb(unsigned short port, unsigned char data);
+void cim_outb(unsigned short port, unsigned char data)
+{
+   __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port));
+}
+
+#endif
+
+#endif /* CIMARRON_INCLUDE_IO_MACROS */
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_df.c xf86-video-nsc-2.8.1/src/cim/cim_df.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_df.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_df.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,2544 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron display filter routines.  These routines program the video hardware.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*---------------------------------------------------------------------------
+ * df_set_crt_enable
+ *
+ * This routine enables or disables CRT output.
+ *---------------------------------------------------------------------------*/
+
+int df_set_crt_enable (int crt_output)
+{
+	unsigned long config, misc;
+	
+	config = READ_VID32 (DF_DISPLAY_CONFIG);
+	misc   = READ_VID32 (DF_VID_MISC);
+	
+	switch (crt_output)
+	{
+		/* DISABLE DISPLAY */
+
+	    case DF_CRT_DISABLE:
+
+			config &= ~(DF_DCFG_DIS_EN   | DF_DCFG_HSYNC_EN |
+				        DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN);
+			misc |= DF_DAC_POWER_DOWN;
+			break;
+
+		/* ENABLE THE DISPLAY */
+
+		case DF_CRT_ENABLE:
+
+			config |= (DF_DCFG_DIS_EN   | DF_DCFG_HSYNC_EN |
+				       DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN);
+			misc &= ~(DF_DAC_POWER_DOWN  | DF_ANALOG_POWER_DOWN);
+			break;
+
+		/* HSYNC:OFF VSYNC:ON */
+
+		case DF_CRT_STANDBY:
+
+			config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN | DF_DCFG_DAC_BL_EN)) |
+				DF_DCFG_VSYNC_EN;
+			misc |= DF_DAC_POWER_DOWN;
+			break;
+
+		/* HSYNC:ON VSYNC:OFF */
+
+		case DF_CRT_SUSPEND:
+
+			config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN)) |
+				DF_DCFG_HSYNC_EN;
+			misc |= DF_DAC_POWER_DOWN;
+			break;
+
+		default:
+			return CIM_STATUS_INVALIDPARAMS;
+	}
+
+	WRITE_VID32 (DF_DISPLAY_CONFIG, config);
+	WRITE_VID32 (DF_VID_MISC, misc);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_panel_enable
+ *
+ * This routine enables or disables panel output.
+ *---------------------------------------------------------------------------*/
+
+int df_set_panel_enable (int enable)
+{
+	unsigned long pm;
+	
+	pm = READ_VID32 (DF_POWER_MANAGEMENT);
+
+	if (enable) pm |=  DF_PM_PANEL_ON;
+	else        pm &= ~DF_PM_PANEL_ON;
+
+	WRITE_VID32 (DF_POWER_MANAGEMENT, pm);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_configure_video_source
+ *
+ * This routine initializes all aspects of the source buffer for a video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_configure_video_source (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+	DF_VIDEO_SOURCE_PARAMS *video_source_even)
+{
+	unsigned long pitch, ctrl, vcfg;
+	unsigned long lock, vg_line, gcfg;
+	unsigned long width, size, scale;
+    unsigned long misc;
+
+	lock    = READ_REG32 (DC3_UNLOCK);
+	vg_line = READ_REG32 (DC3_LINE_SIZE);
+	gcfg    = READ_REG32 (DC3_GENERAL_CFG);
+	vcfg    = READ_VID32 (DF_VIDEO_CONFIG);
+	ctrl    = READ_VID32 (DF_VID_ALPHA_CONTROL);
+	scale   = READ_VID32 (DF_VIDEO_SCALER);
+
+    /* STORE THE DESIRED SCALING PROCEDURE */
+    /* Cimarron supports two modes when programming the scale and position  */
+    /* of the video window.  The first mode is designed to implicitly apply */
+    /* the graphics scale to any video operations.  The second applys the   */
+    /* video unchanged, allowing complete control by the user.  To allow    */
+    /* visibility between modules, the current mode is stored in a spare    */
+    /* bit in the DF miscellaneous register.                                */
+
+    misc = READ_VID32 (DF_VID_MISC);
+    if (video_source_odd->flags & DF_SOURCEFLAG_IMPLICITSCALING)
+        misc |= DF_USER_IMPLICIT_SCALING;
+    else
+        misc &= DF_USER_IMPLICIT_SCALING;
+    WRITE_VID32 (DF_VID_MISC, misc);
+
+	/* PARAMETER - VIDEO PITCH */
+
+	pitch = (video_source_odd->y_pitch >> 3) | ((video_source_odd->uv_pitch >> 3) << 16);
+	
+	/* PARAMETER - VIDEO FORMAT */
+
+	gcfg &= ~DC3_GCFG_YUV_420;
+	vcfg &= ~(DF_VCFG_VID_INP_FORMAT | DF_VCFG_4_2_0_MODE);
+	ctrl &= ~(DF_VIDEO_INPUT_IS_RGB  | DF_CSC_VIDEO_YUV_TO_RGB | DF_HD_VIDEO |
+		DF_YUV_CSC_EN);
+		
+	/* SELECT PIXEL ORDERING */
+
+	switch (video_source_odd->video_format & 3)
+	{
+		case 0: vcfg |= DF_VCFG_UYVY_FORMAT; break;
+		case 1: vcfg |= DF_VCFG_Y2YU_FORMAT; break;
+		case 2: vcfg |= DF_VCFG_YUYV_FORMAT; break;
+		case 3: vcfg |= DF_VCFG_YVYU_FORMAT; break;
+	}
+
+	/* SELECT SOURCE FORMAT (4:2:2, 4:2:0, RGB) */
+
+	switch (video_source_odd->video_format >> 2)
+	{
+		case 0:  ctrl |= DF_CSC_VIDEO_YUV_TO_RGB; break;
+		
+		case 1:  ctrl |= DF_CSC_VIDEO_YUV_TO_RGB;
+			     vcfg |= DF_VCFG_4_2_0_MODE;
+				 gcfg |= DC3_GCFG_YUV_420;
+				 break;
+		
+		case 2:  ctrl |= DF_VIDEO_INPUT_IS_RGB; break;
+		
+		default: return CIM_STATUS_INVALIDPARAMS;
+	}
+
+	/* ALIGN TO APPROPRIATE OUTPUT COLOR SPACE                             */
+	/* We have assumed until this point that the output color space is RGB */
+	/* and the input (if YUV) is always SDTV video.                        */
+
+	if (video_source_odd->flags & DF_SOURCEFLAG_HDTVSOURCE)
+		ctrl |= DF_HD_VIDEO;
+
+	if (ctrl & DF_CSC_GRAPHICS_RGB_TO_YUV)
+	{
+		/* YUV OUTPUT - DISABLE YUV->RGB AND ENABLE YUV->YUV */
+
+		ctrl &= ~DF_CSC_VIDEO_YUV_TO_RGB;
+
+		if ((!(ctrl & DF_HD_VIDEO) &&  (ctrl & DF_HD_GRAPHICS)) ||
+			 ((ctrl & DF_HD_VIDEO) && !(ctrl & DF_HD_GRAPHICS)))
+		{
+			ctrl |= DF_YUV_CSC_EN;
+		}
+	}
+
+	/* PARAMETER - DISPLAY FILTER BUFFER SIZE                        */
+	/* The line size in the video generator must be 32-byte aligned. */
+	/* However, smaller alignments are managed by setting the        */
+	/* appropriate pitch and clipping the video window.              */
+	
+	vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 |
+		      DF_VCFG_LINE_SIZE_BIT9);
+
+	size  = ((video_source_odd->width >> 1) + 7) & 0xFFF8;
+
+	vcfg |= (size & 0x00FF) << 8;
+	if (size & 0x0100) vcfg |= DF_VCFG_LINE_SIZE_BIT8;
+	if (size & 0x0200) vcfg |= DF_VCFG_LINE_SIZE_BIT9;
+
+	scale = (scale & ~0x7FF) | video_source_odd->height;
+
+	/* PARAMETER - VIDEO GENERATOR BUFFER SIZE */
+	
+	vg_line &= ~DC3_LINE_SIZE_VLS_MASK;
+
+	if (gcfg & DC3_GCFG_YUV_420)
+		width = ((video_source_odd->width >> 1) + 7) & 0xFFF8;
+	else
+		width = ((video_source_odd->width << 1) + 31) & 0xFFE0;
+
+	vg_line |= (width >> 3) << DC3_LINE_SIZE_VB_SHIFT;
+
+	/* WRITE ALL PARAMETERS AT ONCE */
+	
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
+	WRITE_VID32 (DF_VID_ALPHA_CONTROL, ctrl);
+	WRITE_VID32 (DF_VIDEO_SCALER, scale);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_LINE_SIZE, vg_line);
+	WRITE_REG32 (DC3_VID_YUV_PITCH, pitch);
+
+	/* WRITE EVEN OR ODD BUFFER OFFSETS                            */
+	/* The even buffer is only valid inside an interlaced display. */
+	
+    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+	{
+		WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET, video_source_even->y_offset);
+		WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET, video_source_even->u_offset);
+		WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET, video_source_even->v_offset);
+	}
+
+	WRITE_REG32 (DC3_VID_Y_ST_OFFSET, video_source_odd->y_offset);
+	WRITE_REG32 (DC3_VID_U_ST_OFFSET, video_source_odd->u_offset);
+	WRITE_REG32 (DC3_VID_V_ST_OFFSET, video_source_odd->v_offset);
+
+    WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_offsets
+ *
+ * This routine sets the starting offset for the video buffer(s).  The buffers
+ * can also be configured inside df_configure_video_source, but a separate
+ * routine is provided here to allow quick buffer flipping.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_offsets (int even, unsigned long y_offset,
+	unsigned long u_offset, unsigned long v_offset)
+{
+	unsigned long lock = READ_REG32 (DC3_UNLOCK);
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	
+    if (even)
+	{		
+		WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET, y_offset);
+		WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET, u_offset);
+		WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET, v_offset);
+	}
+	else
+	{
+		WRITE_REG32 (DC3_VID_Y_ST_OFFSET, y_offset);
+		WRITE_REG32 (DC3_VID_U_ST_OFFSET, u_offset);
+		WRITE_REG32 (DC3_VID_V_ST_OFFSET, v_offset);
+	}
+
+	WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_scale
+ *
+ * This routine programs the horizontal/vertical scale factors for video.  To
+ * disable scaling/filtering, this routine should be called with identical source
+ * and destination dimensions.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_scale (unsigned long src_width, unsigned long src_height,
+	unsigned long dst_width, unsigned long dst_height, unsigned long flags)
+{
+	unsigned long temp, misc;
+    unsigned long scale, gfxscale;
+    unsigned long fbactive, src;
+    unsigned long size, downscale;
+    unsigned long vcfg, gcfg, unlock;
+
+    /* APPLY THE GRAPHICS SCALE */
+    /* When requested by the user, we will adjust the video scale by the  */
+    /* current graphics scale factor.  This allows video to be programmed */
+    /* in terms of the graphics source resolution.                        */
+
+    misc = READ_VID32 (DF_VID_MISC);
+    if (misc & DF_USER_IMPLICIT_SCALING)
+    {
+        gfxscale = READ_REG32 (DC3_GFX_SCALE);
+        fbactive = READ_REG32 (DC3_FB_ACTIVE);
+
+        /* REVERSE ENGINEER THE SCALE FACTOR */
+        /* The graphics scale factor is (source / (dst - 1)), so a little */
+        /* math is performed to reverse engineer the correct scale for    */
+        /* video.                                                         */
+        /*                                                                */
+        /* F = (0x4000*S)/(D-1)  ->  (D/S) = (((0x4000*S)/F)+1)/S         */
+
+        scale =  gfxscale & 0xFFFF;
+        src   = (fbactive >> 16) + 1;
+        if (scale != 0x4000)
+        {
+            dst_width = dst_width * (((0x4000 * src) / scale) + 1);
+            dst_width /= src;
+        }
+
+        scale =  gfxscale >> 16;
+        src   = (fbactive & 0xFFFF) + 1;
+        if (scale != 0x4000)
+        {
+            dst_height = dst_height * (((0x4000 * src) / scale) + 1);
+            dst_height /= src;
+        }
+    }
+
+	/* CHECK FOR VALID SCALING FACTOR */
+	/* The display filter/video generator can support up to 8:1  */
+    /* horizontal downscale and up to 4:1 vertical downscale.    */
+    /* Scale factors above 4:1 horizontal and 2:1 horizontal     */
+    /* will have a quality impact.  However, at such large scale */
+    /* factors, it might not matter,                             */
+
+	if (((flags & DF_SCALEFLAG_CHANGEX) && dst_width  < (src_width >> 3)) ||
+        ((flags & DF_SCALEFLAG_CHANGEY) && dst_height < (src_height >> 2)))
+    {
+		return CIM_STATUS_INVALIDSCALE;
+    }
+
+    /* ENABLE OR DISABLE ADVANCED SCALING FEATURES          */
+    /* Scaling above 2:1 vertical and 4:1 horizontal relies */
+    /* on mechanisms beside the line filter.                */
+    
+    if (flags & DF_SCALEFLAG_CHANGEX)
+    {
+        scale = READ_VID32 (DF_VIDEO_SCALER);
+        vcfg  = READ_VID32 (DF_VIDEO_CONFIG);
+        vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 |
+		      DF_VCFG_LINE_SIZE_BIT9);
+        
+        if (dst_width < (src_width >> 2))
+        {            
+            src_width >>= 1;
+            WRITE_VID32 (DF_VIDEO_SCALER, scale | DF_SCALE_DOUBLE_H_DOWNSCALE);
+        }
+        else
+        {
+            WRITE_VID32 (DF_VIDEO_SCALER, scale & ~DF_SCALE_DOUBLE_H_DOWNSCALE);
+        }
+        
+        /* PROGRAM A NEW LINE SIZE */
+        /* The line size must be updated when using the Double Horizontal  */
+        /* Downscale (DHD) bit.  This is because the amount of VFIFO space */
+        /* consumed is effectively half in this mode.                      */
+
+        size  = ((src_width >> 1) + 7) & 0xFFF8;
+	    vcfg |= (size & 0x00FF) << 8;
+	    if (size & 0x0100) vcfg |= DF_VCFG_LINE_SIZE_BIT8;
+	    if (size & 0x0200) vcfg |= DF_VCFG_LINE_SIZE_BIT9;
+        WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
+        WRITE_VID32 (DF_VIDEO_XSCALE, ((0x10000 * src_width) / dst_width));
+    }
+    if (flags & DF_SCALEFLAG_CHANGEY)
+    {
+        unlock = READ_REG32 (DC3_UNLOCK);
+        gcfg   = READ_REG32 (DC3_GENERAL_CFG) & ~DC3_GCFG_VDSE;
+        WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+        if (dst_height < (src_height >> 1))
+        {
+            gcfg |= DC3_GCFG_VDSE;
+            downscale = READ_REG32 (DC3_VID_DS_DELTA) & ~DC3_DS_DELTA_MASK;
+            if (dst_height == (src_height >> 2))
+                downscale |= (0x3FFF << 18);
+            else
+                downscale |= (((src_height >> 1) << 14) / dst_height) << 18;
+            
+            WRITE_REG32 (DC3_VID_DS_DELTA, downscale);
+            WRITE_VID32 (DF_VIDEO_YSCALE, 0x20000);
+        }
+        else
+        {
+            WRITE_VID32 (DF_VIDEO_YSCALE, ((0x10000 * src_height) / dst_height));
+        }
+        WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+        WRITE_REG32 (DC3_UNLOCK, unlock);
+    }
+
+	/* CHECK IF SCALING IS DISABLED */
+	/* If no scaling occurs, we disable the hardware filter. */
+
+	temp = READ_VID32 (DF_VIDEO_CONFIG);
+	if ((READ_VID32 (DF_VIDEO_XSCALE) == 0x10000) &&
+		(READ_VID32 (DF_VIDEO_YSCALE) == 0x10000))
+	{
+		WRITE_VID32 (DF_VIDEO_CONFIG, (temp | DF_VCFG_SC_BYP));
+	}
+	else
+		WRITE_VID32 (DF_VIDEO_CONFIG, (temp & ~DF_VCFG_SC_BYP));
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_position
+ *
+ * This routine programs the position of the video window on the display.
+ * An indent parameter is also passed to this program to prevent artifacts
+ * when the video window is moved beyond the left edge of the screen.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_position (DF_VIDEO_POSITION *video_window)
+{
+	unsigned long vblankstart_even, vblankend_even, vsyncend_even, vtotal_even, vactive_even;
+    unsigned long hblankstart, hblankend, hsyncend, htotal, hactive;
+	unsigned long vblankstart, vblankend, vsyncend, vtotal, vactive;
+    unsigned long width, height, height_even;
+    unsigned long adjust, border_x, border_y, border_y_even;
+	unsigned long xstart, xend;
+	unsigned long ystart, yend;
+	unsigned long ckey_x, ckey_y;
+    unsigned long x_copy, y_copy;
+    unsigned long width_copy, height_copy;
+	unsigned long vcfg, initread;
+    unsigned long xscale, dst_clip;
+    unsigned long ypos, ypos_even;
+    unsigned long y, gfxscale;
+    unsigned long misc, fbactive;
+    unsigned long scale, src;
+    unsigned long irq_ctl;
+    unsigned long unlock;
+
+	hsyncend    = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	vsyncend    = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+    vblankend   = ((READ_REG32 (DC3_V_BLANK_TIMING)   >> 16) & 0xFFF) + 1;
+    hblankend   = ((READ_REG32 (DC3_H_BLANK_TIMING)   >> 16) & 0xFFF) + 1;
+	htotal      = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+	vtotal      = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+	vblankstart =  (READ_REG32 (DC3_V_BLANK_TIMING)  & 0xFFF) + 1;
+    hblankstart =  (READ_REG32 (DC3_H_BLANK_TIMING)  & 0xFFF) + 1;
+    hactive     =  (READ_REG32 (DC3_H_ACTIVE_TIMING) & 0xFFF) + 1;
+	vactive     =  (READ_REG32 (DC3_V_ACTIVE_TIMING) & 0xFFF) + 1;
+    unlock      =   READ_REG32 (DC3_UNLOCK);
+
+    /* INCLUDE BORDER IF REQUESTED */
+
+    if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+    {
+        border_x = htotal - hblankend;
+        border_y = vtotal - vblankend;
+        hactive = hblankstart + htotal - hblankend;
+        vactive = vblankstart + vtotal - vblankend;
+    }
+    else
+    {
+        border_x = border_y = 0;
+    }
+
+    /* APPLY THE GRAPHICS SCALE     */
+    /* Do not alter the input data. */
+
+    width_copy  = video_window->width;
+    height_copy = video_window->height;
+    x_copy = video_window->x;
+    y_copy = video_window->y;
+
+    misc = READ_VID32 (DF_VID_MISC);
+    if (misc & DF_USER_IMPLICIT_SCALING)
+    {
+        gfxscale = READ_REG32 (DC3_GFX_SCALE);
+        fbactive = READ_REG32 (DC3_FB_ACTIVE);
+
+        /* REVERSE ENGINEER THE SCALE FACTOR */
+
+        scale =  gfxscale & 0xFFFF;
+        src   = (fbactive >> 16) + 1;
+        if (scale != 0x4000)
+        {
+            width_copy = width_copy * (((0x4000 * src) / scale) + 1);
+            width_copy /= src;
+            x_copy = x_copy * (((0x4000 * src) / scale) + 1);
+            x_copy /= src;
+        }
+
+        scale =  gfxscale >> 16;
+        src   = (fbactive & 0xFFFF) + 1;
+        if (scale != 0x4000)
+        {
+            height_copy = height_copy * (((0x4000 * src) / scale) + 1);
+            height_copy /= src;
+            y_copy = y_copy * (((0x4000 * src) / scale) + 1);
+            y_copy /= src;
+        }
+    }
+
+    /* HANDLE INTERLACING */
+    /* When the output is interlaced, we must set the position and height */
+    /* on the fields and not on the composite image.                      */
+
+    if ((irq_ctl = READ_REG32 (DC3_IRQ_FILT_CTL)) & DC3_IRQFILT_INTL_EN)
+    {
+        vsyncend_even    = ((READ_REG32 (DC3_V_SYNC_EVEN)   >> 16) & 0xFFF) + 1;
+        vtotal_even      = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+        vblankend_even   = ((READ_REG32 (DC3_V_BLANK_EVEN)  >> 16) & 0xFFF) + 1;
+        vactive_even     =  (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
+        vblankstart_even =  (READ_REG32 (DC3_V_BLANK_EVEN)  & 0xFFF) + 1;
+
+        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+        {
+            border_y_even = vtotal_even- vblankend_even;
+            vactive_even = vblankstart_even + vtotal_even - vblankend_even;
+        }
+        else
+            border_y_even = 0;
+
+        /* THE ODD FIELD MUST ALWAYS PRECEDE THE EVEN FIELD */
+        /* This implies that we can never start video on an odd y position   */
+        /* in the composite image.  This is required because the only way to */
+        /* accomplish an odd y start would be to switch the buffer offsets,  */
+        /* which could have serious repercussions for genlocked VIP.         */
+
+        y = y_copy >> 1;
+
+        /* CALCULATE Y POSITION FOR ODD FIELD */
+        /* Clip the video window to the odd field timings. Note that the */
+        /* height in the odd field may be greater if the video height is */
+        /* odd.                                                          */
+
+        height = (height_copy + 1) >> 1;
+        if ((y + height) > vactive)
+		    height = vactive - y;
+
+        ystart = y + vtotal_even - vsyncend_even + 1;
+        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+            ystart -= border_y_even;
+
+        yend   = ystart + height;
+        ypos   = (yend << 16) | ystart;
+
+        /* CALCULATE Y POSITION FOR EVEN FIELD */
+
+        height_even = height_copy >> 1;
+        if ((y + height_even) > vactive_even)
+		    height_even = vactive_even - y;
+
+        ystart = y + vtotal - vsyncend + 1;
+        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+            ystart -= border_y;
+
+        yend = ystart + height_even;
+        ypos_even = (yend << 16) | ystart;
+
+        /* CALCULATE ACTUAL FRAME BUFFER HEIGHT */
+        /* The y position and height are used to determine the actual    */
+        /* placement of the color key region.  The region will either be */
+        /* the sum of the even and odd fields (for interlaced addressing */
+        /* or flicker filtering) or it will be the union of the two (for */
+        /* line doubling).  We must also adjust the region such that the */
+        /* origin (0, 0) is centered on the beginning of graphics data.  */
+        /* This is only a problem if video is being displayed over the   */
+        /* overscan area.                                                */
+
+        if ((READ_REG32 (DC3_GENLK_CTL) & DC3_GC_FLICKER_FILTER_ENABLE) ||
+            (irq_ctl & DC3_IRQFILT_INTL_ADDR))
+        {
+            y <<= 1;
+            height += height_even;
+            adjust = border_y + border_y_even;
+        }
+        else
+        {
+            adjust = border_y;
+            if (height_even > height)
+                height = height_even;
+        }
+        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+        {
+            if (y > adjust)
+            {
+                y -= adjust;
+                adjust = 0;
+            }
+            else
+            {
+                adjust -= y;
+                if (height > adjust)
+                    height -= adjust;
+                else
+                    height = 0;
+            }
+        }
+
+    }
+    else
+    {
+        y = y_copy;
+
+        height = height_copy;
+        if ((y + height) > vactive)
+		    height = vactive - y;
+
+        ystart = y + vtotal - vsyncend + 1;
+        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+            ystart -= border_y;
+
+        yend = ystart + height;
+        ypos = (yend << 16) | ystart;
+        ypos_even = 0;
+    }
+	
+    /* HORIZONTAL POSITION */
+    /* The horizontal values are identical for the even and odd field. */
+
+    width   = width_copy;
+	xstart  = x_copy + htotal - hsyncend - 14;
+    if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+        xstart -= border_x;
+
+	/* RIGHT CLIPPING */
+
+	if ((x_copy + width) > hactive)
+		width = hactive - x_copy;
+	
+	xend = xstart + width;
+	
+	/* CALCULATE LEFT CLIPPING PARAMETER */
+	/* The value passed in can be interpreted as destination pixels, in which   */
+	/* case the video scale is factored in, or as source pixels, in which case  */
+	/* the value is written directly.  Also, the display filter's initial read  */
+	/* address value is only programmable on 4-pixel increments.  However, we   */
+	/* can achieve an arbitrary left clip by adjusting the xstart value, as     */
+	/* there is a 14-clock delay in which to play.  Also, according to the      */
+	/* designers, 4:2:0 and 4:2:2 behave identically when setting the initial   */
+	/* read address.  The addition of scaling further complicates the           */
+    /* algorithm.  When setting the initial read address, it is in terms of     */
+    /* source pixels, while adjusting the xstart value is in destination pixels */
+    /* We may thus not be able to achieve a perfect clipping fit for scaled     */
+    /* video.   We compensate by including two clipping parameters in our       */
+    /* structure.  This allows us the user additional control and it allows us  */
+    /* to accurately convey to the user the state of clipping on the machine.   */
+
+	initread = video_window->left_clip;
+    dst_clip = 0;
+	if (!(video_window->flags & DF_POSFLAG_DIRECTCLIP))
+    {
+        xscale = READ_VID32 (DF_VIDEO_XSCALE) & 0xFFFFF;
+		initread =  (initread * xscale) / 0x10000;
+        if (xscale)
+            dst_clip = ((initread & 3) * 0x10000) / xscale;
+    }
+    else
+        dst_clip = video_window->dst_clip;
+		
+    /* LIMIT THE CLIP */
+    /* We technically have a 14 pixel window in which to play.  However, taking */
+    /* the entire 14 pixels makes the video timing a little hairy...  Also note */
+    /* that we cannot do this when performing panel centering, as the video     */
+    /* would then exceed the mode size.                                         */
+
+    if (dst_clip > 4)
+        dst_clip = 4;
+    if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+        dst_clip = 0;
+
+	xstart -= dst_clip;
+    	
+	vcfg = READ_VID32 (DF_VIDEO_CONFIG);
+	vcfg &= ~DF_VCFG_INIT_READ_MASK;
+	vcfg |= (initread >> 2) << 16;
+
+	/* SET COLOR KEY REGION */
+	/* We are assuming that color keying will never be desired outside   */
+	/* of the video region.  We adjust the color key region for graphics */
+    /* scaling.                                                          */
+
+    gfxscale = READ_REG32 (DC3_GFX_SCALE);
+
+    ckey_x =   ((x_copy * (gfxscale & 0xFFFF)) / 0x4000) |
+             ((((x_copy + width) * (gfxscale & 0xFFFF)) / 0x4000) << 16);
+	ckey_y =   ((y * (gfxscale >> 16)) / 0x4000) |
+             ((((y + height) * (gfxscale >> 16)) / 0x4000) << 16);
+
+	/* WRITE ALL PARAMETERS AT ONCE */
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_CLR_KEY_X, ckey_x);
+	WRITE_REG32 (DC3_CLR_KEY_Y, ckey_y);
+	WRITE_VID32 (DF_VIDEO_X_POS, (xend << 16) | xstart);
+	WRITE_VID32 (DF_VIDEO_Y_POS, ypos);
+    WRITE_VID32 (DF_VID_YPOS_EVEN, ypos_even);
+	WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_filter_coefficients
+ *
+ * This routine sets the horizontal and vertical filter coefficients for video
+ * scaling.  These coefficients are used for upscaling and downscaling video.
+ * If the phase256 parameter is 1, the coefficient arrays are used as single
+ * arrays of 256 phases for both vertical and horizontal scaling.  If the
+ * phase256 parameter is clear, the coefficient arrays are used as two 128-phase
+ * arrays.  The first 128 entries represent the phases for vertical scaling.
+ * The last 128 entries represent the phases for horizontal scaling.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_filter_coefficients (long taps[][4], int phase256)
+{
+	unsigned long scale, coeff0, coeff1;
+	unsigned long i;
+	long (*defaults)[2];
+
+	/* SET PHASE COUNT AND CHOOSE COEFFICIENT ARRAY */
+
+	scale = READ_VID32 (DF_VIDEO_SCALER);
+	if (phase256)
+	{
+		WRITE_VID32 (DF_VIDEO_SCALER, (scale & ~DF_SCALE_128_PHASES));
+		defaults = CimarronVideoFilter256;	
+	}
+	else
+	{
+		WRITE_VID32 (DF_VIDEO_SCALER, (scale | DF_SCALE_128_PHASES));
+		defaults = CimarronVideoFilter128;		
+	}
+
+	/* PROGRAM COEFFICIENTS */
+
+	for (i = 0; i < 256; i++)
+	{
+        if (!taps)
+        {
+            coeff0 = defaults[i][0];
+            coeff1 = defaults[i][1];
+        }
+        else
+        {
+		    if (taps[i][1] < 0)  coeff0 = -taps[i][1] | 0x8000;
+		    else                 coeff0 =  taps[i][1];
+
+		    coeff0 <<= 16;
+
+		    if (taps[i][0] < 0)  coeff0 |= -taps[i][0] | 0x8000;
+		    else                 coeff0 |=  taps[i][0];
+
+		
+
+		    if (taps[i][3] < 0)  coeff1 = -taps[i][3] | 0x8000;
+		    else                 coeff1 =  taps[i][3];
+
+		    coeff1 <<= 16;
+
+		    if (taps[i][2] < 0)  coeff1 |= -taps[i][2] | 0x8000;
+		    else                 coeff1 |=  taps[i][2];
+        }
+
+        WRITE_VID32 ((DF_COEFFICIENT_BASE + (i << 3)), coeff0);
+		WRITE_VID32 ((DF_COEFFICIENT_BASE + (i << 3) + 4), coeff1);
+	}
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_enable
+ *
+ * This routine enables or disables the video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_enable (int enable, unsigned long flags)
+{
+	unsigned long vcfg, lock, gcfg;
+    unsigned long dcfg, vg_ckey, fifo = 0;
+
+	vcfg = READ_VID32 (DF_VIDEO_CONFIG);
+	lock = READ_REG32 (DC3_UNLOCK);
+    gcfg = READ_REG32 (DC3_GENERAL_CFG);
+
+    /* SET VIDEO FIFO END WATERMARK */
+    /* The video FIFO end watermark is set to 0 when video is disabled  */
+    /* to allow low priority transactions in the VG.  Otherwise, the    */
+    /* priority will be forced high until the VG fills the video FIFO   */
+    /* by not fetching video.  That could take a while...  Note that    */
+    /* we set the end priority to be 4 greater than the start.  We      */
+    /* assume that the start priority has been configured by a modeset. */
+
+    dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~DC3_DCFG_VFHPEL_MASK;
+    if (enable)
+    {
+        fifo = ((dcfg >> 12) & 0x0000000F) + 4;
+        if (fifo > 0xF)
+            fifo = 0xF;
+    }
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg | (fifo << 16));
+
+	/* ENABLE OR DISABLE VIDEO */
+	/* The mechanism to fetch video data is enabled first and */
+	/* disabled last.                                         */
+
+	if (enable)
+	{
+        WRITE_REG32 (DC3_GENERAL_CFG, (gcfg | DC3_GCFG_VIDE));
+		WRITE_VID32 (DF_VIDEO_CONFIG, (vcfg | DF_VCFG_VID_EN));
+
+        /* DISABLE COLOR KEYING IF REQUESTED BY THE USER */
+
+        if (flags & DF_ENABLEFLAG_NOCOLORKEY)
+        {
+            /* OVERRIDE THE MODE TO COLOR KEYING */
+
+            dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+            WRITE_VID32 (DF_DISPLAY_CONFIG, (dcfg & ~DF_DCFG_VG_CK));
+
+            /* DISABLE COLOR KEYING IN THE VG */
+
+            vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+            WRITE_REG32 (DC3_COLOR_KEY, (vg_ckey & ~DC3_CLR_KEY_ENABLE));
+        }
+        else if (!(READ_VID32 (DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK))
+        {
+            /* OTHERWISE RE-ENABLE COLOR KEYING */
+
+            vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+            WRITE_REG32 (DC3_COLOR_KEY, (vg_ckey | DC3_CLR_KEY_ENABLE));
+        }
+	}
+	else
+	{
+		WRITE_VID32 (DF_VIDEO_CONFIG, (vcfg & ~DF_VCFG_VID_EN));
+        WRITE_REG32 (DC3_GENERAL_CFG, (gcfg & ~DC3_GCFG_VIDE));
+
+        /* DISABLE COLOR KEY WINDOW WHEN VIDEO IS INACTIVE         */
+        /* To mimic legacy functionality, we disble color keying   */
+        /* when the video window is not active.  We will restore   */
+        /* the enable when video is re-enabled if the appropriate  */
+        /* bit is set in display config.                           */
+
+        vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+        WRITE_REG32 (DC3_COLOR_KEY, (vg_ckey & ~DC3_CLR_KEY_ENABLE));
+	}
+	WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_color_key
+ *
+ * This routine configures the video color/chroma key mechanism.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_color_key (unsigned long key, unsigned long mask, int graphics)
+{
+	unsigned long lock, vg_ckey, df_dcfg;
+
+	vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+    lock    = READ_REG32 (DC3_UNLOCK);
+	df_dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+	
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	if (graphics)
+	{
+        /* COLOR KEY - USE VG HARDWARE */
+        /* Note that color key is never enabled unless a video window */
+        /* is active.  This is to match legacy behavior.              */
+
+		df_dcfg &= ~DF_DCFG_VG_CK;
+        vg_ckey = (vg_ckey & 0xFF000000) | (key & 0xFFFFFF);
+        if (READ_VID32 (DF_VIDEO_CONFIG) & DF_VCFG_VID_EN)
+            vg_ckey |=  DC3_CLR_KEY_ENABLE;
+        else
+            vg_ckey &= ~DC3_CLR_KEY_ENABLE;
+
+		WRITE_VID32 (DF_DISPLAY_CONFIG, df_dcfg);
+        WRITE_REG32 (DC3_COLOR_KEY, vg_ckey);
+		WRITE_REG32 (DC3_COLOR_MASK, (mask & 0xFFFFFF));
+	}
+	else
+	{
+		/* CHROMA KEY - USE DF HARDWARE */
+
+		df_dcfg |= DF_DCFG_VG_CK;
+		vg_ckey &= ~DC3_CLR_KEY_ENABLE;
+
+		WRITE_REG32 (DC3_COLOR_KEY, vg_ckey);
+		WRITE_VID32 (DF_DISPLAY_CONFIG, df_dcfg);
+		WRITE_VID32 (DF_VIDEO_COLOR_KEY, (key & 0xFFFFFF));
+		WRITE_VID32 (DF_VIDEO_COLOR_MASK, (mask & 0xFFFFFF));
+	}
+
+    WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_palette
+ *
+ * This routine loads the video hardware palette.  If a NULL pointer is
+ * specified, the palette is bypassed.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_palette (unsigned long *palette)
+{
+	unsigned long i, entry;
+    unsigned long misc, dcfg;
+
+	/* LOAD GEODE LX VIDEO PALETTE */
+
+	WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+	for (i = 0; i < 256; i++)
+	{
+		if (palette) entry = palette[i];
+		else entry = i | (i << 8) | (i << 16);
+		WRITE_VID32 (DF_PALETTE_DATA, entry);
+	}
+
+    /* ENABLE THE VIDEO PALETTE */
+    /* Ensure that the video palette has an effect by routing video data */
+    /* through the palette RAM and clearing the 'Bypass Both' bit.       */
+
+    dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+    misc = READ_VID32 (DF_VID_MISC);
+
+    dcfg |=  DF_DCFG_GV_PAL_BYP;
+    misc &= ~DF_GAMMA_BYPASS_BOTH;
+
+    WRITE_VID32 (DF_DISPLAY_CONFIG, dcfg);
+    WRITE_VID32 (DF_VID_MISC, misc);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_palette_entry
+ *
+ * This routine loads a single entry of the video hardware palette.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_palette_entry (unsigned long index, unsigned long palette)
+{
+    unsigned long misc, dcfg;
+
+	if (index > 0xFF)
+		return CIM_STATUS_INVALIDPARAMS;
+	
+	/* SET A SINGLE ENTRY */
+
+	WRITE_VID32 (DF_PALETTE_ADDRESS, index);
+	WRITE_VID32 (DF_PALETTE_DATA, palette);
+
+    /* ENABLE THE VIDEO PALETTE */
+    /* Ensure that the video palette has an effect by routing video data */
+    /* through the palette RAM and clearing the 'Bypass Both' bit.       */
+
+    dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+    misc = READ_VID32 (DF_VID_MISC);
+
+    dcfg |=  DF_DCFG_GV_PAL_BYP;
+    misc &= ~DF_GAMMA_BYPASS_BOTH;
+
+    WRITE_VID32 (DF_DISPLAY_CONFIG, dcfg);
+    WRITE_VID32 (DF_VID_MISC, misc);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_configure_video_cursor_color_key
+ *
+ * This routine configures the hardware video cursor color key mechanism.
+ *--------------------------------------------------------------------------*/
+
+int df_configure_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key)
+{	
+	unsigned long key;
+
+	if (cursor_color_key->select_color2 >= 24)
+		return CIM_STATUS_INVALIDPARAMS;
+
+	key = READ_VID32 (DF_CURSOR_COLOR_KEY) & DF_CURSOR_COLOR_KEY_ENABLE;
+	key = key | (cursor_color_key->key & 0xFFFFFF) | (cursor_color_key->select_color2 << 24);
+	
+	WRITE_VID32 (DF_CURSOR_COLOR_KEY, key);
+	WRITE_VID32 (DF_CURSOR_COLOR_MASK, (cursor_color_key->mask & 0xFFFFFF));
+	WRITE_VID32 (DF_CURSOR_COLOR_1, (cursor_color_key->color1 & 0xFFFFFF));
+	WRITE_VID32 (DF_CURSOR_COLOR_2, (cursor_color_key->color2 & 0xFFFFFF));
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_cursor_color_key_enable
+ *
+ * This routine enables or disables the video cursor color key.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_cursor_color_key_enable (int enable)
+{	
+	unsigned long temp = READ_VID32 (DF_CURSOR_COLOR_KEY);
+
+	if (enable) temp |=  DF_CURSOR_COLOR_KEY_ENABLE;
+	else        temp &= ~DF_CURSOR_COLOR_KEY_ENABLE;
+
+	WRITE_VID32 (DF_CURSOR_COLOR_KEY, temp);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_configure_alpha_window
+ *
+ * This routine configures one of the three hardware alpha regions.
+ *--------------------------------------------------------------------------*/
+
+int df_configure_alpha_window (int window, DF_ALPHA_REGION_PARAMS *alpha_data)
+{	
+	unsigned long vsyncend_even, vtotal_even, vactive_even;
+    unsigned long hsyncend, htotal, hactive;
+	unsigned long vsyncend, vtotal, vactive;
+    unsigned long alpha_ctl, pos;	
+	unsigned long hadjust, vadjust;
+    unsigned long y, height;
+	unsigned long xstart, xend;
+	unsigned long ystart, yend;
+    unsigned long x_copy, width_copy;
+    unsigned long y_copy, height_copy;
+    unsigned long scale, src, misc;
+    unsigned long gfxscale, fbactive;
+	unsigned long color;
+	
+	if (window > 2)
+		return CIM_STATUS_INVALIDPARAMS;
+
+	hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	htotal   = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+	vtotal   = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+	hactive  =  (READ_REG32 (DC3_H_ACTIVE_TIMING) & 0xFFF) + 1;
+	vactive  =  (READ_REG32 (DC3_V_ACTIVE_TIMING) & 0xFFF) + 1;
+
+    /* APPLY THE GRAPHICS SCALE */
+
+    width_copy  = alpha_data->width;
+    height_copy = alpha_data->height;
+    x_copy = alpha_data->x;
+    y_copy = alpha_data->y;
+
+    misc = READ_VID32 (DF_VID_MISC);
+    if (misc & DF_USER_IMPLICIT_SCALING)
+    {
+        gfxscale = READ_REG32 (DC3_GFX_SCALE);
+        fbactive = READ_REG32 (DC3_FB_ACTIVE);
+
+        /* REVERSE ENGINEER THE SCALE FACTOR */
+
+        scale =  gfxscale & 0xFFFF;
+        src   = (fbactive >> 16) + 1;
+        if (scale != 0x4000)
+        {
+            width_copy = width_copy * (((0x4000 * src) / scale) + 1);
+            width_copy /= src;
+            x_copy = x_copy * (((0x4000 * src) / scale) + 1);
+            x_copy /= src;
+        }
+
+        scale =  gfxscale >> 16;
+        src   = (fbactive & 0xFFFF) + 1;
+        if (scale != 0x4000)
+        {
+            height_copy = height_copy * (((0x4000 * src) / scale) + 1);
+            height_copy /= src;
+            y_copy = y_copy * (((0x4000 * src) / scale) + 1);
+            y_copy /= src;
+        }
+    }
+
+	/* SET PRIORITY */
+	/* Priority is the only alpha parameter that is not in a register that */
+	/* can be indexed based on the alpha window number.                    */
+	
+	pos = 16 + (window << 1);
+	alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL) & ~(3L << pos);
+	alpha_ctl |= (alpha_data->priority & 3) << pos;
+	WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha_ctl);
+
+    /* HANDLE INTERLACED MODES */
+
+    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+    {
+        vsyncend_even = ((READ_REG32 (DC3_V_SYNC_EVEN)   >> 16) & 0xFFF) + 1;
+        vtotal_even   = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+        vactive_even  =  (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
+
+        y = y_copy >> 1;
+
+        /* SET Y POSITION FOR ODD FIELD */
+
+        height = (height_copy + 1) >> 1;
+        vadjust = vtotal_even - vsyncend_even + 1;
+
+        ystart = y + vadjust;	
+	    yend   = y + vadjust + height;
+
+        if (yend > (vactive + vadjust))
+		    yend = vactive + vadjust;
+
+        WRITE_VID32 ((DF_ALPHA_YPOS_1 + (window << 5)), (ystart | (yend << 16)));
+
+        /* SET Y POSITION FOR EVEN FIELD */
+
+        height = height_copy >> 1;
+        vadjust = vtotal - vsyncend + 1;
+
+        ystart = y + vadjust;	
+	    yend   = y + vadjust + height;
+
+        if (yend > (vactive_even + vadjust))
+		    yend = vactive_even + vadjust;
+
+        WRITE_VID32 ((DF_VID_ALPHA_Y_EVEN_1 + (window << 3)), (ystart | (yend << 16)));
+    }
+    else
+    {
+        y = y_copy;
+        height = height_copy;
+        vadjust = vtotal - vsyncend + 1;
+
+        ystart = y + vadjust;
+	    yend   = y + vadjust + height;
+
+        if (yend > (vactive + vadjust))
+		    yend = vactive + vadjust;
+
+        WRITE_VID32 ((DF_ALPHA_YPOS_1 + (window << 5)), (ystart | (yend << 16)));
+    }
+
+	/* SET ALPHA X POSITION */
+    /* The x position is the same for both the odd and even fields. */
+
+	hadjust = htotal - hsyncend - 2;
+	
+	xstart = x_copy + hadjust;
+	xend   = x_copy + hadjust + width_copy;
+
+	if (xend > (hactive + hadjust))
+		xend = hactive + hadjust;
+	
+	WRITE_VID32 ((DF_ALPHA_XPOS_1 + (window << 5)), (xstart | (xend << 16)));
+	
+    /* SET COLOR REGISTER */
+
+	color = alpha_data->color & 0xFFFFFF;
+	if (alpha_data->flags & DF_ALPHAFLAG_COLORENABLED)
+		color |= DF_ALPHA_COLOR_ENABLE;
+
+	WRITE_VID32 ((DF_ALPHA_COLOR_1 + (window << 5)), color);
+	
+	/* SET ALPHA VALUE, DELTA AND PER PIXEL */
+
+	alpha_ctl  = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5)) & DF_ACTRL_WIN_ENABLE;
+	alpha_ctl |= (alpha_data->alpha_value & 0xFF) | DF_ACTRL_LOAD_ALPHA |
+		        (((unsigned long)alpha_data->delta & 0xFF) << 8);
+	if (alpha_data->flags & DF_ALPHAFLAG_PERPIXELENABLED)
+		alpha_ctl |= DF_ACTRL_PERPIXEL_EN;
+
+	WRITE_VID32 ((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_alpha_window_enable
+ *
+ * This routine enables or disables one of the three hardware alpha regions.
+ *--------------------------------------------------------------------------*/
+
+int df_set_alpha_window_enable (int window, int enable)
+{	
+	unsigned long alpha_ctl;
+	
+	if (window > 2)
+		return CIM_STATUS_INVALIDPARAMS;
+
+	alpha_ctl = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5));
+	if (enable) alpha_ctl |=  DF_ACTRL_WIN_ENABLE;
+	else        alpha_ctl &= ~DF_ACTRL_WIN_ENABLE;
+	WRITE_VID32 ((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_no_ck_outside_alpha
+ *
+ * This function affects how color/chroma keying is performed inside the video
+ * window.
+ *
+ * If enable is 1, color/chroma key comparison is performed only inside
+ * the enabled alpha windows. Outside the enabled alpha windows, video
+ * is displayed if color keying is enabled, or graphics is displayed if
+ * chroma keying is enabled.
+ * If enable is 0, color/chroma key comparison is performed inside the
+ * entire video window.
+ *--------------------------------------------------------------------------*/
+
+int df_set_no_ck_outside_alpha (int enable)
+{	
+	unsigned long value;
+
+	value = READ_VID32 (DF_VID_ALPHA_CONTROL);
+	if (enable) value |=  DF_NO_CK_OUTSIDE_ALPHA;
+	else        value &= ~DF_NO_CK_OUTSIDE_ALPHA;
+	WRITE_VID32 (DF_VID_ALPHA_CONTROL, value);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_request
+ *
+ * This routine sets the horizontal (pixel) and vertical (line) video request
+ * values.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_request (unsigned long x, unsigned long y)
+{	
+	unsigned long htotal, hsyncend;
+	unsigned long vtotal, vsyncend;
+
+	hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	htotal   = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+	vtotal   = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+
+	/* SET DISPLAY FILTER VIDEO REQUEST */
+	
+	x += htotal - hsyncend - 2;
+	y += vtotal - vsyncend + 1;
+	
+	if (x >= 0x1000 || y >= 0x800)
+		return CIM_STATUS_INVALIDPARAMS;
+	
+	WRITE_VID32(DF_VIDEO_REQUEST, (y | (x << 16)));
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_output_color_space
+ *
+ * This routine sets the color space used when combining graphics and video.
+ *--------------------------------------------------------------------------*/
+
+int df_set_output_color_space (int color_space)
+{	
+	unsigned long alpha_ctl;
+
+	alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL);
+
+	alpha_ctl &= ~(DF_CSC_GRAPHICS_RGB_TO_YUV | DF_CSC_VIDEO_YUV_TO_RGB |
+		DF_HD_GRAPHICS | DF_YUV_CSC_EN | DF_ALPHA_DRGB);
+
+	/* OUTPUT IS RGB */
+	/* Enable YUV->RGB CSC if necessary and enable alpha output if  */
+	/* requested.                                                   */
+
+	if (color_space == DF_OUTPUT_RGB || color_space == DF_OUTPUT_ARGB)
+	{
+		if (!(alpha_ctl & DF_VIDEO_INPUT_IS_RGB))
+			alpha_ctl |= DF_CSC_VIDEO_YUV_TO_RGB;
+		
+		if (color_space == DF_OUTPUT_ARGB)
+			alpha_ctl |= DF_ALPHA_DRGB;
+	}
+
+	/* OUTPUT IS YUV */
+	/* Enable YUV->YUV CSC if necessary and enable RGB->YUV CSC. */
+	
+	else if (color_space == DF_OUTPUT_SDTV || color_space == DF_OUTPUT_HDTV)
+	{
+		alpha_ctl |= DF_CSC_GRAPHICS_RGB_TO_YUV;
+
+		if ( ((alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_SDTV) ||
+		    (!(alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_HDTV))
+		{
+			alpha_ctl |= DF_YUV_CSC_EN;
+		}
+
+		if (color_space == DF_OUTPUT_HDTV)
+			alpha_ctl |= DF_HD_GRAPHICS;		
+	}
+	else
+		return CIM_STATUS_INVALIDPARAMS;
+
+	WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha_ctl);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_output_path
+ *
+ * This routine changes the current output path in the display filter.
+ *--------------------------------------------------------------------------*/
+
+int df_set_output_path (int format)
+{
+    unsigned long panel_tim2, panel_pm;
+    unsigned long output = 0;
+    Q_WORD msr_value;
+
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+    msr_value.low &= ~(DF_SIMULTANEOUS_CRT_FP | DF_CONFIG_OUTPUT_MASK);
+    panel_tim2 = READ_VID32 (DF_VIDEO_PANEL_TIM2);
+    panel_pm   = READ_VID32 (DF_POWER_MANAGEMENT);
+
+    if (format == DF_DISPLAY_CRT)
+    {
+        /* SiBZ #4188 */
+        /* When CRT output is selected, the DF drives the DISP_EN signal   */
+        /* with the CRT display enable.  As a consequence, systems that    */
+        /* wire the DISP_EN signal to the TFT backlight control will not   */
+        /* be able to set CRT-only output without leaving the backlight    */
+        /* enabled.  To workaround this issue, we are setting simultaneous */
+        /* TFT/CRT and disabling the TFT logic.  The only caveat to this   */
+        /* is that some TFT pins are shared with VIP 601 pins.  VIP 601    */
+        /* will thus not work when in this pseudo-CRT mode.  To address    */
+        /* THAT issue, normal CRT mode sets (in cim_vg.c) will set CRT     */
+        /* as the DF output format.  This will allow VIP 601 on CRT-only   */
+        /* systems without a TFT attached.                                 */
+
+        panel_pm &= ~DF_PM_PANEL_ON;
+        panel_tim2 |= DF_PMTIM2_TFT_PASSHTHROUGH;
+        output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP;
+    }
+    else if (format == DF_DISPLAY_FP || format == DF_DISPLAY_CRT_FP)
+    {
+        panel_pm |= DF_PM_PANEL_ON;
+        panel_tim2 &= ~DF_PMTIM2_TFT_PASSHTHROUGH;
+
+        if (format == DF_DISPLAY_FP)
+            output = DF_OUTPUT_PANEL;
+        else if (format == DF_DISPLAY_CRT_FP)
+            output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP;
+    }
+    else
+    {
+        switch (format)
+        {
+            case DF_DISPLAY_VOP:       output = DF_OUTPUT_VOP;                            break;
+            case DF_DISPLAY_DRGB:      output = DF_OUTPUT_DRGB;                           break;
+            case DF_DISPLAY_CRT_DRGB:  output = DF_OUTPUT_DRGB | DF_SIMULTANEOUS_CRT_FP;  break;
+            default:
+                return CIM_STATUS_INVALIDPARAMS;
+        }
+    }
+    msr_value.low |= output;
+    msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+    WRITE_VID32 (DF_VIDEO_PANEL_TIM2, panel_tim2);
+    WRITE_VID32 (DF_POWER_MANAGEMENT, panel_pm);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_test_video_flip_status
+ *
+ * This routine tests if a new video offset has been latched.
+ *--------------------------------------------------------------------------*/
+
+unsigned long df_test_video_flip_status (void)
+{	
+	return (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VFLIP);
+}
+
+/*---------------------------------------------------------------------------
+ * df_save_state
+ *
+ * This routine saves all persistent DF state information.
+ *---------------------------------------------------------------------------*/
+
+int df_save_state (DF_SAVE_RESTORE *df_state)
+{
+    unsigned long i;
+
+    /* READ ALL DF REGISTERS */
+
+    df_state->vcfg               = READ_VID32 (DF_VIDEO_CONFIG);
+    df_state->dcfg               = READ_VID32 (DF_DISPLAY_CONFIG);
+    df_state->video_x            = READ_VID32 (DF_VIDEO_X_POS);
+    df_state->video_y            = READ_VID32 (DF_VIDEO_Y_POS);
+    df_state->video_scaler       = READ_VID32 (DF_VIDEO_SCALER);
+    df_state->video_color_key    = READ_VID32 (DF_VIDEO_COLOR_KEY);
+    df_state->video_color_mask   = READ_VID32 (DF_VIDEO_COLOR_MASK);
+    df_state->sat_limit          = READ_VID32 (DF_SATURATION_LIMIT);
+    df_state->vid_misc           = READ_VID32 (DF_VID_MISC);
+    df_state->video_yscale       = READ_VID32 (DF_VIDEO_YSCALE);
+    df_state->video_xscale       = READ_VID32 (DF_VIDEO_XSCALE);
+    df_state->vid_alpha_control  = READ_VID32 (DF_VID_ALPHA_CONTROL);
+    df_state->cursor_key         = READ_VID32 (DF_CURSOR_COLOR_KEY);
+    df_state->cursor_mask        = READ_VID32 (DF_CURSOR_COLOR_MASK);
+    df_state->cursor_color1      = READ_VID32 (DF_CURSOR_COLOR_1);
+    df_state->cursor_color2      = READ_VID32 (DF_CURSOR_COLOR_2);
+    df_state->alpha_xpos1        = READ_VID32 (DF_ALPHA_XPOS_1);
+    df_state->alpha_ypos1        = READ_VID32 (DF_ALPHA_YPOS_1);
+    df_state->alpha_color1       = READ_VID32 (DF_ALPHA_COLOR_1);
+    df_state->alpha_control1     = READ_VID32 (DF_ALPHA_CONTROL_1);
+    df_state->alpha_xpos2        = READ_VID32 (DF_ALPHA_XPOS_2);
+    df_state->alpha_ypos2        = READ_VID32 (DF_ALPHA_YPOS_2);
+    df_state->alpha_color2       = READ_VID32 (DF_ALPHA_COLOR_2);
+    df_state->alpha_control2     = READ_VID32 (DF_ALPHA_CONTROL_2);
+    df_state->alpha_xpos3        = READ_VID32 (DF_ALPHA_XPOS_3);
+    df_state->alpha_ypos3        = READ_VID32 (DF_ALPHA_YPOS_3);
+    df_state->alpha_color3       = READ_VID32 (DF_ALPHA_COLOR_3);
+    df_state->alpha_control3     = READ_VID32 (DF_ALPHA_CONTROL_3);
+    df_state->vid_request        = READ_VID32 (DF_VIDEO_REQUEST);
+    df_state->vid_ypos_even      = READ_VID32 (DF_VID_YPOS_EVEN);
+    df_state->alpha_ypos_even1   = READ_VID32 (DF_VID_ALPHA_Y_EVEN_1);
+    df_state->alpha_ypos_even2   = READ_VID32 (DF_VID_ALPHA_Y_EVEN_2);
+    df_state->alpha_ypos_even3   = READ_VID32 (DF_VID_ALPHA_Y_EVEN_3);
+    df_state->panel_tim1         = READ_VID32 (DF_VIDEO_PANEL_TIM1);
+    df_state->panel_tim2         = READ_VID32 (DF_VIDEO_PANEL_TIM2);
+    df_state->panel_pm           = READ_VID32 (DF_POWER_MANAGEMENT);
+    df_state->panel_dither       = READ_VID32 (DF_DITHER_CONTROL);
+
+    /* READ DF PALETTE */
+
+    WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+	for (i = 0; i < 256; i++)
+        df_state->palette[i] = READ_VID32 (DF_PALETTE_DATA);
+
+    /* READ FILTER COEFFICIENTS */
+
+    for (i = 0; i < 512; i++)
+        df_state->coefficients[i] = READ_VID32 (DF_COEFFICIENT_BASE + (i << 2));
+
+    /* READ ALL DF MSRS */
+
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CAP,    &(df_state->msr_cap));
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &(df_state->msr_config));
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_SMI,    &(df_state->msr_smi));
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_ERROR,  &(df_state->msr_error));
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_PM,     &(df_state->msr_pm));
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG,   &(df_state->msr_diag));
+    msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF,   &(df_state->msr_df_diag));
+    msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL,       &(df_state->msr_pad_sel));
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_restore_state
+ *
+ * This routine restores all persistent DF state information.
+ *---------------------------------------------------------------------------*/
+
+int df_restore_state (DF_SAVE_RESTORE *df_state)
+{
+    unsigned long i;
+
+    /* CLEAR VCFG AND DCFG */
+
+    WRITE_VID32 (DF_VIDEO_CONFIG,   0);
+    WRITE_VID32 (DF_DISPLAY_CONFIG, 0);
+
+    /* RESTORE DF MSRS */
+
+    msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CAP,    &(df_state->msr_cap));
+    msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &(df_state->msr_config));
+    msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_SMI,    &(df_state->msr_smi));
+    msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_ERROR,  &(df_state->msr_error));
+    msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_PM,     &(df_state->msr_pm));
+    msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG,   &(df_state->msr_diag));
+    msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF,   &(df_state->msr_df_diag));
+    msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL,       &(df_state->msr_pad_sel));
+
+    /* RESTORE ALL DF REGISTERS */
+
+    WRITE_VID32 (DF_VIDEO_X_POS,           df_state->video_x);
+    WRITE_VID32 (DF_VIDEO_Y_POS,           df_state->video_y);
+    WRITE_VID32 (DF_VIDEO_SCALER,          df_state->video_scaler);
+    WRITE_VID32 (DF_VIDEO_COLOR_KEY,       df_state->video_color_key);
+    WRITE_VID32 (DF_VIDEO_COLOR_MASK,      df_state->video_color_mask);
+    WRITE_VID32 (DF_SATURATION_LIMIT,      df_state->sat_limit);
+    WRITE_VID32 (DF_VID_MISC,              df_state->vid_misc);
+    WRITE_VID32 (DF_VIDEO_YSCALE,          df_state->video_yscale);
+    WRITE_VID32 (DF_VIDEO_XSCALE,          df_state->video_xscale);
+    WRITE_VID32 (DF_VID_ALPHA_CONTROL,     df_state->vid_alpha_control);
+    WRITE_VID32 (DF_CURSOR_COLOR_KEY,      df_state->cursor_key);
+    WRITE_VID32 (DF_CURSOR_COLOR_MASK,     df_state->cursor_mask);
+    WRITE_VID32 (DF_CURSOR_COLOR_1,        df_state->cursor_color1);
+    WRITE_VID32 (DF_CURSOR_COLOR_2,        df_state->cursor_color2);
+    WRITE_VID32 (DF_ALPHA_XPOS_1,          df_state->alpha_xpos1);
+    WRITE_VID32 (DF_ALPHA_YPOS_1,          df_state->alpha_ypos1);
+    WRITE_VID32 (DF_ALPHA_COLOR_1,         df_state->alpha_color1);
+    WRITE_VID32 (DF_ALPHA_CONTROL_1,       df_state->alpha_control1);
+    WRITE_VID32 (DF_ALPHA_XPOS_2,          df_state->alpha_xpos2);
+    WRITE_VID32 (DF_ALPHA_YPOS_2,          df_state->alpha_ypos2);
+    WRITE_VID32 (DF_ALPHA_COLOR_2,         df_state->alpha_color2);
+    WRITE_VID32 (DF_ALPHA_CONTROL_2,       df_state->alpha_control1);
+    WRITE_VID32 (DF_ALPHA_XPOS_3,          df_state->alpha_xpos3);
+    WRITE_VID32 (DF_ALPHA_YPOS_3,          df_state->alpha_ypos3);
+    WRITE_VID32 (DF_ALPHA_COLOR_3,         df_state->alpha_color3);
+    WRITE_VID32 (DF_ALPHA_CONTROL_3,       df_state->alpha_control3);
+    WRITE_VID32 (DF_VIDEO_REQUEST,         df_state->vid_request);
+    WRITE_VID32 (DF_VID_YPOS_EVEN,         df_state->vid_ypos_even);
+    WRITE_VID32 (DF_VID_ALPHA_Y_EVEN_1,    df_state->alpha_ypos_even1);
+    WRITE_VID32 (DF_VID_ALPHA_Y_EVEN_2,    df_state->alpha_ypos_even2);
+    WRITE_VID32 (DF_VID_ALPHA_Y_EVEN_3,    df_state->alpha_ypos_even3);
+    WRITE_VID32 (DF_VIDEO_PANEL_TIM1,      df_state->panel_tim1);
+    WRITE_VID32 (DF_VIDEO_PANEL_TIM2,      df_state->panel_tim2);
+    WRITE_VID32 (DF_POWER_MANAGEMENT,      df_state->panel_pm);
+    WRITE_VID32 (DF_DITHER_CONTROL,        df_state->panel_dither);
+
+    /* RESTORE DF PALETTE */
+
+    WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+	for (i = 0; i < 256; i++)
+        WRITE_VID32 (DF_PALETTE_DATA, df_state->palette[i]);
+
+    /* RESTORE FILTER COEFFICIENTS */
+
+    for (i = 0; i < 512; i++)
+        WRITE_VID32 (DF_COEFFICIENT_BASE + (i << 2), df_state->coefficients[i]);
+
+    /* RESTORE DCFG AND VCFG */
+
+    WRITE_VID32 (DF_DISPLAY_CONFIG, df_state->dcfg);
+    WRITE_VID32 (DF_VIDEO_CONFIG, df_state->vcfg);
+
+    return CIM_STATUS_OK;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON DF READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging.  They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_DF_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * df_read_composite_crc
+ *
+ * This routine reads the CRC of the combination of graphics/video data.  This
+ * CRC checks data immediately before the CRT DACs.
+ *---------------------------------------------------------------------------*/
+
+unsigned long df_read_composite_crc (int crc_source)
+{
+    Q_WORD msr_value;
+	unsigned long crc;
+    unsigned long interlaced;
+    unsigned long line, field;
+    unsigned long timeout = 1000;
+
+	if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+		return 0xFFFFFFFF;
+
+	/* ENABLE 32-BIT CRCS */
+
+	msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+	msr_value.low |= DF_DIAG_32BIT_CRC;
+	msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+
+	/* RESET THE CRC */
+
+    WRITE_VID32 (DF_VID_CRC, 0);
+
+    /* WAIT FOR THE RESET TO BE LATCHED */
+
+    while ((READ_VID32 (DF_VID_CRC32) != 0x00000001) && timeout)
+        timeout--;
+
+    /* WAIT FOR THE CORRECT FIELD */
+    /* We use the VG line count and field indicator to determine when */
+    /* to kick off a CRC.                                             */
+
+    if (crc_source & DF_CRC_SOURCE_EVEN) field = 0;
+    else                                 field = DC3_LNCNT_EVEN_FIELD;
+
+    if ((interlaced = (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)))
+    {
+        /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+        /* Note that we wait for the field to be odd when CRCing the even */
+        /* field and vice versa.  This is because the CRC will not begin  */
+        /* until the following field.                                     */
+
+        do
+        {
+            line = READ_REG32 (DC3_LINE_CNT_STATUS);
+        } while ((line & DC3_LNCNT_EVEN_FIELD) != field    ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 10 ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 15);
+    }
+    else
+    {
+        /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+        if (crc_source & DF_CRC_SOURCE_EVEN)
+            return 0xFFFFFFFF;
+    }
+
+    /* ENABLE THE CRC */
+
+	WRITE_VID32 (DF_VID_CRC, 1);
+
+	/* WAIT FOR THE CRC TO BE COMPLETED */
+	
+    while (!(READ_VID32 (DF_VID_CRC) & 4))
+        ;
+	
+	crc = READ_VID32 (DF_VID_CRC32);
+
+	return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * df_read_composite_window_crc
+ *
+ * This routine reads the CRC of a rectangular subsection of the combination
+ * of graphics/video data.
+ *---------------------------------------------------------------------------*/
+
+unsigned long df_read_composite_window_crc (unsigned long x, unsigned long y,
+	unsigned long width, unsigned long height, int source)
+{
+    Q_WORD msr_value;
+    unsigned long interlaced;
+    unsigned long line, field;
+	unsigned long crc = 0;
+	unsigned long hsyncend, htotal, hsyncstart;
+	unsigned long vsyncend, vtotal, vsyncstart;
+    unsigned long hblankstart, hactive;
+    unsigned long vblankstart, vactive;
+
+    hsyncend    = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+    htotal      = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+    hsyncstart  =  (READ_REG32 (DC3_H_SYNC_TIMING) & 0xFFF) + 1;
+    hactive     =  (READ_REG32 (DC3_H_ACTIVE_TIMING) & 0xFFF) + 1;
+    hblankstart =  (READ_REG32 (DC3_H_BLANK_TIMING)  & 0xFFF) + 1;
+    if ((interlaced = (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)) &&
+        !(source & DF_CRC_SOURCE_EVEN))
+    {
+        vsyncend    = ((READ_REG32 (DC3_V_SYNC_EVEN)   >> 16) & 0xFFF) + 1;
+	    vtotal      = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+	    vsyncstart  =  (READ_REG32 (DC3_V_SYNC_EVEN) & 0xFFF) + 1;
+        vactive     =  (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
+        vblankstart =  (READ_REG32 (DC3_V_BLANK_EVEN)  & 0xFFF) + 1;
+    }
+    else
+    {	
+	    vsyncend    = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	    vtotal      = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+	    vsyncstart  =  (READ_REG32 (DC3_V_SYNC_TIMING) & 0xFFF) + 1;
+        vactive     =  (READ_REG32 (DC3_V_ACTIVE_TIMING) & 0xFFF) + 1;
+        vblankstart =  (READ_REG32 (DC3_V_BLANK_TIMING)  & 0xFFF) + 1;
+    }
+
+    /* TIMINGS MUST BE ACTIVE */
+
+	if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+		return 0xFFFFFFFF;
+
+    /* DISABLE GLCP ACTIONS */
+
+    msr_value.low  = 0;
+    msr_value.high = 0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+	/* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO DOT CLOCK */
+
+	msr_value.low = 5;
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+	msr_value.low = 0;
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+	msr_value.low = 3;
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+    /* USE H4 FUNCTION A FOR HSYNC AND H4 FUNCTION B FOR NOT HSYNC */
+    /* HSYNC is bit 30 for the DF                                  */
+
+    msr_value.high = 0x00000001;
+    msr_value.low  = 0xE0000FF0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+    /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+    /* VSYNC is bit 54 for VG and bit 29 for DF                    */
+
+    msr_value.high = 0x00000000;
+    msr_value.low  = 0x001D55AA;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+
+    /* M4 (XSTATE = 00 AND VSYNC HIGH) */
+    /* Goto state 01                   */
+    /* Note: VSync = H3A               */
+
+    msr_value.high = 0x00000001;
+    msr_value.low  = 0x000000A0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 4, &msr_value);
+
+    /* N0 (XSTATE = 01 AND VSYNC LOW) */
+    /* Goto state 02                  */
+    /* Note: VSync low = H3B          */
+
+    msr_value.high = 0x00040000;
+    msr_value.low  = 0x000000C0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL, &msr_value);
+
+    /* M5 (XSTATE = 10 AND VSYNC HIGH) */
+    /* Goto state 11                   */
+
+    msr_value.high = 0x00000001;
+    msr_value.low  = 0x00000120;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 5, &msr_value);
+
+    /* N1 (XSTATE = 10 and HSYNC LOW) */
+    /* Increment H. Counter           */
+    /* Note: HSync = H4               */
+
+    msr_value.high = 0x00080000;
+    msr_value.low  = 0x00000120;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 1, &msr_value);
+
+    /* M0 (XSTATE = 10 and H. COUNTER == LIMIT)  */
+    /* Clear H. Counter and increment V. Counter */
+
+    msr_value.high = 0x00000000;
+    msr_value.low  = 0x00000122;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL, &msr_value);
+
+    /* N4 (XSTATE = 10 && CMP0 <= H. COUNTER <= CMP1 && CMP2 <= V. COUNTER <= CMP3) */
+    /* CRC into REGB                                                                */
+
+    msr_value.high = 0x00000000;
+    msr_value.low  = 0x10C20120;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 4, &msr_value);
+
+    /* COMPARATOR 0 VALUE                                   */
+    /* Value = xstart + (htotal - hsync_end) - 1            */
+    /* The value will be adjusted for a border if necessary */
+
+    msr_value.low  = x + htotal - hsyncend - 1;
+    if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+        msr_value.low -= hblankstart - hactive;
+    msr_value.low--;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0, &msr_value);
+
+    /* COMPARATOR 1 VALUE                                    */
+    /* Value = xstart + (htotal - hsync_end - 1) - 1 + width */
+
+    msr_value.low  += width - 1;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 2, &msr_value);
+
+    /* COMPARATOR 2 VALUE                 */
+    /* Value = ystart + vtotal - vsyncend */
+
+    msr_value.low  = (y + vtotal - vsyncend) << 16;
+    if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+        msr_value.low -= (vblankstart - vactive) << 16;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 4, &msr_value);
+
+    /* COMPARATOR 3 VALUE                              */
+    /* Value = ystart + vtotal - vsyncend + height - 1 */
+
+    msr_value.low  += (height - 1) << 16;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 6, &msr_value);
+
+    /* COMPARATOR MASKS */
+    /* Comparators 0 and 1 refer to lower 16 bits of RegB */
+
+    msr_value.low = 0x0000FFFF;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0, &msr_value);
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 2, &msr_value);
+
+    /* Comparators 2 and 3 refer to upper 16 bits of RegB */
+
+    msr_value.low = 0xFFFF0000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 4, &msr_value);
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 6, &msr_value);
+
+    /* SET REGB MASK                                                */
+    /* We set the mask such that all only 24 bits of data are CRCed */
+
+    msr_value.low = 0x00FFFFFF;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGBMASK, &msr_value);
+
+    /* SET REGA LIMITS                              */
+    /* Lower counter uses htotal - sync_time - 1.   */
+    /* Upper counter is 0xFFFF to prevent rollover. */
+
+    msr_value.low = 0xFFFF0000 | (htotal - (hsyncend - hsyncstart) - 1);
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+    /* ACTIONS */
+
+    /* STATE 00->01 (SET 4M) */
+
+    msr_value.low = 0x000C0000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 14, &msr_value);
+
+    /* STATE 01->10 (SET 0N) */
+
+    msr_value.low = 0x0000000A;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 15, &msr_value);
+
+    /* STATE 10->11 (SET 5M) */
+
+    msr_value.low = 0x00C00000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 16, &msr_value);
+
+    /* CLEAR REGA WHEN TRANSITIONING TO STATE 10                 */
+    /* Do not clear RegB as the initial value must be 0x00000001 */
+
+    msr_value.low = 0x0000000A;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0, &msr_value);
+
+    /* REGISTER ACTION 1 */
+    /* CRC into RegB if cmp0 <= h.counter <= cmp1 && cmp2 <= v. counter < cmp3 && 7 xstate = 10 8 */
+    /* Increment h.counter if xstate = 10 and HSync is low.                                       */
+
+    msr_value.low = 0x000A00A0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 1, &msr_value);
+
+    /* REGISTER ACTION 2            */
+    /* Increment V. Counter in REGA */
+
+    msr_value.low = 0x0000000C;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 2, &msr_value);
+
+    /* SET REGB TO 0x00000001 */
+
+    msr_value.low = 0x00000001;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+
+    /* SET XSTATE TO 0 */
+
+    msr_value.low = 0x00000000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+
+    /* CLEAR ALL OTHER ACTIONS */
+	/* This prevents side-effects from previous accesses to the GLCP */
+	/* debug logic.                                                  */
+
+	msr_value.low  = 0x00000000;
+	msr_value.high = 0x00000000;
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 3, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 4, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 5, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 6, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 7, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 8, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 9, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 10, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 11, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 12, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 13, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 17, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 18, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 19, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 20, &msr_value);
+
+    /* WAIT FOR THE CORRECT FIELD */
+    /* We use the VG line count and field indicator to determine when */
+    /* to kick off a CRC.                                             */
+
+    if (source & DF_CRC_SOURCE_EVEN) field = 0;
+    else                             field = DC3_LNCNT_EVEN_FIELD;
+
+    if (interlaced)
+    {
+        /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+        /* Note that we wait for the field to be odd when CRCing the even */
+        /* field and vice versa.  This is because the CRC will not begin  */
+        /* until the following field.                                     */
+
+        do
+        {
+            line = READ_REG32 (DC3_LINE_CNT_STATUS);
+        } while ((line & DC3_LNCNT_EVEN_FIELD) != field    ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 1 ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 5);
+    }
+    else
+    {
+        /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+        if (source & DF_CRC_SOURCE_EVEN)
+            return 0xFFFFFFFF;
+    }
+
+    /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */
+
+	msr_value.high = 0;
+    msr_value.low  = 0x0000800B;
+	msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, &msr_value);
+
+    /* CONFIGURE DIAG CONTROL */
+    /* Set RegA action1 to increment lower 16 bits and clear at limit. (5)      */
+    /* Set RegA action2 to increment upper 16 bits. (6)                         */
+    /* Set RegB action1 to CRC32 (1)                                            */
+    /* Set all comparators to REGA override (0,1 lower mbus, 2,3 upper mbus)    */
+    /* Enable all actions                                                       */
+
+    msr_value.low = 0x80EA20A0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+	
+	/* DELAY TWO FRAMES */
+
+	while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+	while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+	while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+	while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+	while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+
+	/* VERIFY THAT XSTATE = 11 */
+
+	msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+	if ((msr_value.low & 3) == 3)
+	{
+		msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+		
+		crc = msr_value.low;
+	}
+
+	/* DISABLE DF DIAG BUS OUTPUTS */
+
+	msr_value.low  = 0x00000000;
+	msr_value.high = 0x00000000;
+	msr_write64 (MSR_DEVICE_GEODELX_DF,  MSR_GEODELINK_DIAG, &msr_value);
+
+	/* DISABLE GLCP ACTIONS */
+
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+    return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * df_read_panel_crc
+ *
+ * This routine reads the CRC for a frame of data after the panel dithering
+ * logic.
+ *---------------------------------------------------------------------------*/
+
+unsigned long df_read_panel_crc (void)
+{
+	Q_WORD msr_value;
+    unsigned long timeout = 1000;
+
+	if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+		return 0xFFFFFFFF;
+
+	/* ENABLE 32-BIT CRCS */
+
+	msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+	msr_value.low |= DF_DIAG_32BIT_CRC;
+	msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+
+	/* RESET CRC */
+
+	WRITE_VID32 (DF_PANEL_CRC, 0);
+
+    /* WAIT FOR THE RESET TO BE LATCHED */
+
+    while ((READ_VID32 (DF_PANEL_CRC32) != 0x00000001) && timeout)
+        timeout--;
+
+	WRITE_VID32 (DF_PANEL_CRC, 1);
+
+	/* WAIT FOR THE CRC TO BE COMPLETED */
+	
+    while (!(READ_VID32 (DF_PANEL_CRC) & 4))
+        ;
+
+	return READ_VID32 (DF_PANEL_CRC32);
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_enable
+ *
+ * This routine reads the enable status of the video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_enable (int *enable, unsigned long *flags)
+{
+    *enable = 0;
+    *flags  = 0;
+	if (READ_VID32 (DF_VIDEO_CONFIG) & DF_VCFG_VID_EN)
+    {
+		*enable = 1;
+
+        /* CHECK FOR COLOR KEY DISABLED */
+        /* Color keying can be completely disabled when video is enabled to */
+        /* allow unhindered per-pixel alpha blending.  As color keying is   */
+        /* always disabled when video is disabled, it is only possible to   */
+        /* test for this condition when video is enabled.                   */
+
+        if (!(READ_VID32 (DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK) &&
+            !(READ_REG32 (DC3_COLOR_KEY) & DC3_CLR_KEY_ENABLE))
+        {
+            *flags = DF_ENABLEFLAG_NOCOLORKEY;
+        }
+    }
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_source_configuration
+ *
+ * This routine reads the current configuration of the source buffers for the
+ * video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_source_configuration (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+	DF_VIDEO_SOURCE_PARAMS *video_source_even)
+{
+	unsigned long format, temp;
+	unsigned long size;
+
+	/* READ VIDEO FORMAT */
+
+	temp = READ_VID32 (DF_VIDEO_CONFIG);
+
+	format = (temp >> 2) & 3;
+	if (temp & DF_VCFG_4_2_0_MODE)
+		format |= 4;
+	else if (READ_VID32 (DF_VID_ALPHA_CONTROL) & DF_VIDEO_INPUT_IS_RGB)
+		format |= 8;
+	video_source_odd->video_format = format;
+
+	/* CHECK IF SOURCE IS HD VIDEO */
+
+	if (READ_VID32 (DF_VID_ALPHA_CONTROL) & DF_HD_VIDEO)
+		video_source_odd->flags = DF_SOURCEFLAG_HDTVSOURCE;
+	else
+		video_source_odd->flags = 0;
+
+    /* READ SCALING ALGORITHM */
+
+    if (READ_VID32 (DF_VID_MISC) & DF_USER_IMPLICIT_SCALING)
+        video_source_odd->flags |= DF_SOURCEFLAG_IMPLICITSCALING;
+
+	/* READ VIDEO PITCH */
+
+	temp = READ_REG32 (DC3_VID_YUV_PITCH);
+	video_source_odd->y_pitch  = (temp & 0xFFFF) << 3;
+	video_source_odd->uv_pitch = (temp >> 16) << 3;
+	
+	/* READ VIDEO SIZE */
+
+	temp = READ_VID32 (DF_VIDEO_CONFIG);
+	size = (temp >> 8) & 0xFF;
+	if (temp & DF_VCFG_LINE_SIZE_BIT8) size |= 0x100;
+	if (temp & DF_VCFG_LINE_SIZE_BIT9) size |= 0x200;
+
+	video_source_odd->width  = size << 1;
+	video_source_odd->height = READ_VID32 (DF_VIDEO_SCALER) & 0x7FF;
+
+	/* READ VIDEO OFFSETS */
+
+    video_source_odd->y_offset = READ_REG32 (DC3_VID_Y_ST_OFFSET) & 0xFFFFFFF;
+	video_source_odd->u_offset = READ_REG32 (DC3_VID_U_ST_OFFSET) & 0xFFFFFFF;
+	video_source_odd->v_offset = READ_REG32 (DC3_VID_V_ST_OFFSET) & 0xFFFFFFF;
+
+	if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+	{
+		video_source_even->y_offset = READ_REG32 (DC3_VID_EVEN_Y_ST_OFFSET) & 0xFFFFFFF;
+		video_source_even->u_offset = READ_REG32 (DC3_VID_EVEN_U_ST_OFFSET) & 0xFFFFFFF;
+		video_source_even->v_offset = READ_REG32 (DC3_VID_EVEN_V_ST_OFFSET) & 0xFFFFFFF;
+	}
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_position
+ *
+ * This routine reads the current position of the video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_position (DF_VIDEO_POSITION *video_window)
+{
+    unsigned long xreg, yreg, dst_clip, clip;
+    unsigned long height;
+	unsigned long xend, yend;
+	unsigned long hsyncend, htotal;
+	unsigned long vsyncend, vtotal;
+	unsigned long hadjust, vadjust;
+    unsigned long misc, gfxscale;
+    unsigned long temp;
+	long xstart, ystart;
+	
+	video_window->flags = DF_POSFLAG_DIRECTCLIP;
+
+	hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	htotal   = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+
+    /* ODD FIELD START COUNTS FROM THE EVEN FIELD TIMINGS */
+    /* We assume that the even field y position is always programmed */
+    /* to be just after the odd field.                               */
+
+    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+    {
+        vsyncend = ((READ_REG32 (DC3_V_SYNC_EVEN)   >> 16) & 0xFFF) + 1;
+	    vtotal   = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+    }
+    else
+    {
+        vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	    vtotal   = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+    }
+	
+	hadjust = htotal - hsyncend - 14;
+	vadjust = vtotal - vsyncend + 1;
+
+	xreg = READ_VID32 (DF_VIDEO_X_POS);
+	yreg = READ_VID32 (DF_VIDEO_Y_POS);
+
+	xstart = (xreg & 0xFFF) - hadjust;
+	ystart = (yreg & 0x7FF) - vadjust;
+	xend   = ((xreg >> 16) & 0xFFF) - hadjust;
+	yend   = ((yreg >> 16) & 0x7FF) - vadjust;
+	
+    height = yend - ystart;
+
+    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+    {
+        /* Y COORDINATE IS ACTUALLY 2X THE ODD FIELD START */
+
+        ystart <<= 1;
+
+        /* CALCULATE THE EXACT VIDEO HEIGHT */
+        /* The height of the video window is the sum of the */
+        /* odd and even field heights.                      */
+
+        yreg = READ_VID32 (DF_VID_YPOS_EVEN);
+        height += ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF);
+    }
+
+	clip = ((READ_VID32 (DF_VIDEO_CONFIG) >> 16) & 0x1FF) << 2;
+
+	/* ADJUST FOR CLIPPING VALUES THAT ARE NOT FOUR-PIXEL ALIGNED */
+
+    dst_clip = 0;
+	if (xstart < 0)
+	{
+		dst_clip += -xstart;
+		xstart = 0;
+	}
+
+    /* REVERSE THE GRAPHICS SCALE */
+
+    misc = READ_VID32 (DF_VID_MISC);
+    if (misc & DF_USER_IMPLICIT_SCALING)
+    {
+        gfxscale = READ_REG32 (DC3_GFX_SCALE);
+
+        if (gfxscale != 0x40004000)
+        {
+            temp = ystart + height;
+            temp = (temp * (gfxscale >> 16)) / 0x4000;
+
+            xstart = (xstart * (gfxscale & 0xFFFF)) / 0x4000;
+            xend   = (xend   * (gfxscale & 0xFFFF)) / 0x4000;
+            ystart = (ystart * (gfxscale >> 16)) / 0x4000;
+            height = temp - ystart;
+        }
+    }
+
+	video_window->left_clip = clip;
+    video_window->dst_clip  = dst_clip;
+	video_window->x         = xstart;
+	video_window->y         = ystart;
+	video_window->width     = xend - xstart;
+	video_window->height    = height;
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_scale
+ *
+ * This routine reads the current scale values for video scaling.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_scale (unsigned long *x_scale, unsigned long *y_scale)
+{
+	*x_scale = READ_VID32 (DF_VIDEO_XSCALE) & 0x000FFFFF;
+	*y_scale = READ_VID32 (DF_VIDEO_YSCALE) & 0x000FFFFF;
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_filter_coefficients
+ *
+ * This routine reads the coefficients for the video scaler/filter.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_filter_coefficients (long taps[][4], int *phase256)
+{
+	unsigned long i, temp;
+	long coeff;
+
+	if (READ_VID32 (DF_VIDEO_SCALER) & DF_SCALE_128_PHASES)
+		*phase256 = 0;
+	else
+		*phase256 = 1;
+
+	for (i = 0; i < 256; i++)
+	{
+		temp = READ_VID32 (DF_COEFFICIENT_BASE + (i << 3));
+
+		/* TAP 0 */
+
+		coeff = temp & 0x7FFF;
+		if (temp & 0x8000) coeff = -coeff;
+		taps[i][0] = coeff;
+
+		/* TAP 1 */
+
+		temp >>= 16;
+		coeff = temp & 0x7FFF;
+		if (temp & 0x8000) coeff = -coeff;
+		taps[i][1] = coeff;
+
+		temp = READ_VID32 (DF_COEFFICIENT_BASE + (i << 3) + 4);
+
+		/* TAP 2 */
+
+		coeff = temp & 0x7FFF;
+		if (temp & 0x8000) coeff = -coeff;
+		taps[i][2] = coeff;
+
+		/* TAP 3 */
+
+		temp >>= 16;
+		coeff = temp & 0x7FFF;
+		if (temp & 0x8000) coeff = -coeff;
+		taps[i][3] = coeff;
+	}
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_color_key
+ *
+ * This routine reads the current settings for hardware color/chroma keying.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_color_key (unsigned long *key, unsigned long *mask, int *graphics)
+{
+	unsigned long chroma = READ_VID32 (DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK;
+
+	if (chroma)
+	{
+		/* CHROMA KEY - READ KEY AND MASK FROM DF */
+
+		*graphics = 0;
+		*key  = READ_VID32 (DF_VIDEO_COLOR_KEY) & 0xFFFFFF;
+		*mask = READ_VID32 (DF_VIDEO_COLOR_MASK) & 0xFFFFFF;
+	}
+	else
+	{
+		*graphics = 1;
+
+		*key  = READ_REG32 (DC3_COLOR_KEY) & 0xFFFFFF;
+        *mask = READ_REG32 (DC3_COLOR_MASK) & 0xFFFFFF;
+	}
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_palette_entry
+ *
+ * This routine returns a single palette entry.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_palette_entry(unsigned long index, unsigned long *palette)
+{
+	if (index > 0xFF)
+		return CIM_STATUS_INVALIDPARAMS;
+
+	/* READ A SINGLE ENTRY */
+
+	WRITE_VID32 (DF_PALETTE_ADDRESS, index);
+	*palette = READ_VID32 (DF_PALETTE_DATA);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_palette
+ *
+ * This routine returns the entire video palette.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_palette (unsigned long *palette)
+{
+    unsigned long i;
+
+	WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+	for (i = 0; i < 256; i++)
+        palette[i] = READ_VID32 (DF_PALETTE_DATA);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_cursor_color_key
+ *
+ * This routine returns the current configuration for the hardware video cursor
+ * color key.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key)
+{
+	unsigned long key;
+
+	cursor_color_key->flags  = 0;
+	cursor_color_key->color1 = READ_VID32 (DF_CURSOR_COLOR_1) & 0xFFFFFF;
+	cursor_color_key->color2 = READ_VID32 (DF_CURSOR_COLOR_2) & 0xFFFFFF;
+	cursor_color_key->mask   = READ_VID32 (DF_CURSOR_COLOR_MASK) & 0xFFFFFF;
+
+	key = READ_VID32 (DF_CURSOR_COLOR_KEY);
+	cursor_color_key->key = key & 0xFFFFFF;
+	cursor_color_key->select_color2 = (key >> 24) & 0x1F;
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_cursor_color_key_enable
+ *
+ * This routine returns the current enable status of the hardware video cursor
+ * color key.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_cursor_color_key_enable (void)
+{
+	if (READ_VID32 (DF_CURSOR_COLOR_KEY) & DF_CURSOR_COLOR_KEY_ENABLE)
+		return 1;
+
+	return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_alpha_window_configuration
+ *
+ * This routine reads the current configuration for one of the three hardware
+ * alpha regions.
+ *---------------------------------------------------------------------------*/
+
+int df_get_alpha_window_configuration (int window, DF_ALPHA_REGION_PARAMS *alpha_data)
+{
+	unsigned long pos, color, alpha_ctl;
+	unsigned long hsyncend, htotal;
+	unsigned long vsyncend, vtotal;
+	unsigned long hadjust, vadjust;
+	unsigned long xreg, yreg;
+    unsigned long misc, gfxscale;
+    unsigned long temp;
+	char delta;
+	
+	if (window > 2)
+		return CIM_STATUS_INVALIDPARAMS;
+
+	hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	htotal   = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+    {
+	    vtotal   = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+        vsyncend = ((READ_REG32 (DC3_V_SYNC_EVEN)   >> 16) & 0xFFF) + 1;
+    }
+    else
+    {
+        vtotal   = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+        vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+    }
+
+	/* GET PRIORITY */
+
+	pos = 16 + (window << 1);
+	alpha_data->priority = (READ_VID32 (DF_VID_ALPHA_CONTROL) >> pos) & 3L;
+	
+	/* GET ALPHA WINDOW */
+
+	hadjust = htotal - hsyncend - 2;
+	vadjust = vtotal - vsyncend + 1;
+
+	xreg = READ_VID32 (DF_ALPHA_XPOS_1 + (window << 5));
+	yreg = READ_VID32 (DF_ALPHA_YPOS_1 + (window << 5));
+	alpha_data->width  = ((xreg >> 16) & 0xFFF) - (xreg & 0xFFF);
+	alpha_data->height = ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF);
+	alpha_data->x = (xreg & 0xFFF) - hadjust;
+	alpha_data->y = (yreg & 0x7FF) - vadjust;
+
+    /* REVERSE THE GRAPHICS SCALE */
+
+    misc = READ_VID32 (DF_VID_MISC);
+    if (misc & DF_USER_IMPLICIT_SCALING)
+    {
+        gfxscale = READ_REG32 (DC3_GFX_SCALE);
+        if (gfxscale != 0x40004000)
+        {
+            temp = alpha_data->y + alpha_data->height;
+            temp = (temp * (gfxscale >> 16)) / 0x4000;
+
+            alpha_data->x      = (alpha_data->x * (gfxscale & 0xFFFF)) / 0x4000;
+            alpha_data->width  = (alpha_data->width * (gfxscale & 0xFFFF)) / 0x4000;
+            alpha_data->y      = (alpha_data->y * (gfxscale >> 16)) / 0x4000;
+            alpha_data->height = temp - alpha_data->y;
+        }
+    }
+
+    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+    {
+        /* Y COORDINATE IS ACTUALLY 2X THE ODD FIELD START */
+
+        alpha_data->y <<= 1;
+
+        /* CALCULATE THE EXACT VIDEO HEIGHT */
+        /* The height of the video window is the sum of the */
+        /* odd and even field heights.                      */
+
+        yreg = READ_VID32 (DF_VID_ALPHA_Y_EVEN_1 + (window << 3));
+        alpha_data->height += ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF);
+    }
+
+	/* GET COLOR REGISTER */
+
+	color = READ_VID32 (DF_ALPHA_COLOR_1 + (window << 5));
+	alpha_data->color = color & 0xFFFFFF;
+	if (color & DF_ALPHA_COLOR_ENABLE)
+		alpha_data->flags = DF_ALPHAFLAG_COLORENABLED;
+	else
+		alpha_data->flags = 0;
+
+	/* GET ALPHA VALUE, DELTA AND PER PIXEL */
+
+	alpha_ctl = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5));
+	alpha_data->alpha_value = alpha_ctl & 0xFF;
+	if (alpha_ctl & DF_ACTRL_PERPIXEL_EN)
+		alpha_data->flags |= DF_ALPHAFLAG_PERPIXELENABLED;
+
+	delta = (char)((alpha_ctl >> 8) & 0xFF);
+	alpha_data->delta = (long)delta;
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_alpha_window_enable
+ *
+ * This routine reads the current enable status of one of the three hardware
+ * alpha regions.
+ *---------------------------------------------------------------------------*/
+
+int df_get_alpha_window_enable (int window)
+{
+	if (window > 2)
+		return 0;
+
+	if (READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5)) & DF_ACTRL_WIN_ENABLE)
+		return 1;
+
+	return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_request
+ *
+ * This routine reads the horizontal (pixel) and vertical (line) video request
+ * values.
+ *--------------------------------------------------------------------------*/
+
+int df_get_video_request (unsigned long *x, unsigned long *y)
+{	
+	unsigned long request;
+	unsigned long hsyncend, htotal;
+	unsigned long vsyncend, vtotal;
+
+	hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
+	htotal   = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+	vtotal   = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+
+	request = READ_VID32 (DF_VIDEO_REQUEST);
+	*x = ((request >> 16) & 0xFFF) - (htotal - hsyncend - 2);
+	*y =  (request & 0x7FF) - (vtotal - vsyncend + 1);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_output_color_space
+ *
+ * This routine sets the color space used when combining graphics and video.
+ *--------------------------------------------------------------------------*/
+
+int df_get_output_color_space (int *color_space)
+{	
+	unsigned long alpha_ctl;
+
+	alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL);
+
+    if ((alpha_ctl & DF_CSC_VIDEO_YUV_TO_RGB) ||
+       !(alpha_ctl & DF_CSC_GRAPHICS_RGB_TO_YUV))
+    {
+        if (alpha_ctl & DF_ALPHA_DRGB)
+            *color_space = DF_OUTPUT_ARGB;
+        else
+            *color_space = DF_OUTPUT_RGB;
+    }
+    else
+    {
+        *color_space = DF_OUTPUT_SDTV;
+
+        if (alpha_ctl & DF_HD_GRAPHICS)
+            *color_space = DF_OUTPUT_HDTV;
+    }
+
+    return CIM_STATUS_OK;
+}
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_filter.c xf86-video-nsc-2.8.1/src/cim/cim_filter.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_filter.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_filter.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,533 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron default video coefficients.
+  * </DOC_AMD_STD>
+  *
+  */
+
+long CimarronVideoFilter256[][2] =
+{
+	{ 0x10000000, 0x00000000 },  /*     0, 4096,    0,    0 */
+    { 0x10008008, 0x00000008 },  /*    -8, 4096,    8,    0 */
+    { 0x10008010, 0x80010011 },  /*   -16, 4096,   17,   -1 */
+    { 0x10008019, 0x8001001A },  /*   -25, 4096,   26,   -1 */
+    { 0x10008021, 0x80020023 },  /*   -33, 4096,   35,   -2 */
+    { 0x0FFF8029, 0x8003002D },  /*   -41, 4095,   45,   -3 */
+    { 0x0FFE8031, 0x80030036 },  /*   -49, 4094,   54,   -3 */
+    { 0x0FFC8038, 0x80040040 },  /*   -56, 4092,   64,   -4 */
+    { 0x0FFB8040, 0x8005004A },  /*   -64, 4091,   74,   -5 */
+    { 0x0FF88047, 0x80050054 },  /*   -71, 4088,   84,   -5 */
+    { 0x0FF6804E, 0x8006005E },  /*   -78, 4086,   94,   -6 */
+    { 0x0FF48055, 0x80070068 },  /*   -85, 4084,  104,   -7 */
+    { 0x0FF0805C, 0x80070073 },  /*   -92, 4080,  115,   -7 */
+    { 0x0FEE8063, 0x8008007D },  /*   -99, 4078,  125,   -8 */
+    { 0x0FEA8069, 0x80090088 },  /*  -105, 4074,  136,   -9 */
+    { 0x0FE78070, 0x800A0093 },  /*  -112, 4071,  147,  -10 */
+    { 0x0FE28076, 0x800A009E },  /*  -118, 4066,  158,  -10 */
+    { 0x0FDD807C, 0x800B00AA },  /*  -124, 4061,  170,  -11 */
+    { 0x0FD98082, 0x800C00B5 },  /*  -130, 4057,  181,  -12 */
+    { 0x0FD48088, 0x800D00C1 },  /*  -136, 4052,  193,  -13 */
+    { 0x0FCE808E, 0x800D00CD },  /*  -142, 4046,  205,  -13 */
+    { 0x0FC88093, 0x800E00D9 },  /*  -147, 4040,  217,  -14 */
+    { 0x0FC38099, 0x800F00E5 },  /*  -153, 4035,  229,  -15 */
+    { 0x0FBD809E, 0x801000F1 },  /*  -158, 4029,  241,  -16 */
+    { 0x0FB680A3, 0x801000FD },  /*  -163, 4022,  253,  -16 */
+    { 0x0FAF80A8, 0x8011010A },  /*  -168, 4015,  266,  -17 */
+    { 0x0FA880AD, 0x80120117 },  /*  -173, 4008,  279,  -18 */
+    { 0x0FA180B2, 0x80130124 },  /*  -178, 4001,  292,  -19 */
+    { 0x0F9980B6, 0x80140131 },  /*  -182, 3993,  305,  -20 */
+    { 0x0F9280BB, 0x8015013E },  /*  -187, 3986,  318,  -21 */
+    { 0x0F8880BF, 0x8015014C },  /*  -191, 3976,  332,  -21 */
+    { 0x0F8080C3, 0x80160159 },  /*  -195, 3968,  345,  -22 */
+    { 0x0F7880C8, 0x80170167 },  /*  -200, 3960,  359,  -23 */
+    { 0x0F6E80CB, 0x80180175 },  /*  -203, 3950,  373,  -24 */
+    { 0x0F6580CF, 0x80190183 },  /*  -207, 3941,  387,  -25 */
+    { 0x0F5C80D3, 0x801A0191 },  /*  -211, 3932,  401,  -26 */
+    { 0x0F5280D7, 0x801B01A0 },  /*  -215, 3922,  416,  -27 */
+    { 0x0F4880DA, 0x801C01AE },  /*  -218, 3912,  430,  -28 */
+    { 0x0F3D80DD, 0x801D01BD },  /*  -221, 3901,  445,  -29 */
+    { 0x0F3280E0, 0x801E01CC },  /*  -224, 3890,  460,  -30 */
+    { 0x0F2880E4, 0x801F01DB },  /*  -228, 3880,  475,  -31 */
+    { 0x0F1C80E6, 0x802001EA },  /*  -230, 3868,  490,  -32 */
+    { 0x0F1180E9, 0x802101F9 },  /*  -233, 3857,  505,  -33 */
+    { 0x0F0480EB, 0x80210208 },  /*  -235, 3844,  520,  -33 */
+    { 0x0EFA80EF, 0x80230218 },  /*  -239, 3834,  536,  -35 */
+    { 0x0EEC80F0, 0x80230227 },  /*  -240, 3820,  551,  -35 */
+    { 0x0EE080F3, 0x80240237 },  /*  -243, 3808,  567,  -36 */
+    { 0x0ED380F5, 0x80250247 },  /*  -245, 3795,  583,  -37 */
+    { 0x0EC780F7, 0x80270257 },  /*  -247, 3783,  599,  -39 */
+    { 0x0EB980F9, 0x80280268 },  /*  -249, 3769,  616,  -40 */
+    { 0x0EAC80FB, 0x80290278 },  /*  -251, 3756,  632,  -41 */
+    { 0x0E9E80FD, 0x802A0289 },  /*  -253, 3742,  649,  -42 */
+    { 0x0E9080FE, 0x802B0299 },  /*  -254, 3728,  665,  -43 */
+    { 0x0E838100, 0x802D02AA },  /*  -256, 3715,  682,  -45 */
+    { 0x0E758102, 0x802E02BB },  /*  -258, 3701,  699,  -46 */
+    { 0x0E668103, 0x802F02CC },  /*  -259, 3686,  716,  -47 */
+    { 0x0E568104, 0x803002DE },  /*  -260, 3670,  734,  -48 */
+    { 0x0E498106, 0x803202EF },  /*  -262, 3657,  751,  -50 */
+    { 0x0E398107, 0x80330301 },  /*  -263, 3641,  769,  -51 */
+    { 0x0E298108, 0x80340313 },  /*  -264, 3625,  787,  -52 */
+    { 0x0E1A8109, 0x80360325 },  /*  -265, 3610,  805,  -54 */
+    { 0x0E0B810A, 0x80370336 },  /*  -266, 3595,  822,  -55 */
+    { 0x0DFA810A, 0x80380348 },  /*  -266, 3578,  840,  -56 */
+    { 0x0DEA810B, 0x803A035B },  /*  -267, 3562,  859,  -58 */
+    { 0x0DDA810C, 0x803B036D },  /*  -268, 3546,  877,  -59 */
+    { 0x0DCA810C, 0x803D037F },  /*  -268, 3530,  895,  -61 */
+    { 0x0DB7810B, 0x803E0392 },  /*  -267, 3511,  914,  -62 */
+    { 0x0DA7810C, 0x804003A5 },  /*  -268, 3495,  933,  -64 */
+    { 0x0D95810C, 0x804103B8 },  /*  -268, 3477,  952,  -65 */
+    { 0x0D85810C, 0x804303CA },  /*  -268, 3461,  970,  -67 */
+    { 0x0D73810C, 0x804403DD },  /*  -268, 3443,  989,  -68 */
+    { 0x0D61810C, 0x804603F1 },  /*  -268, 3425, 1009,  -70 */
+    { 0x0D50810C, 0x80480404 },  /*  -268, 3408, 1028,  -72 */
+    { 0x0D3E810C, 0x80490417 },  /*  -268, 3390, 1047,  -73 */
+    { 0x0D2C810C, 0x804B042B },  /*  -268, 3372, 1067,  -75 */
+    { 0x0D1B810C, 0x804D043E },  /*  -268, 3355, 1086,  -77 */
+    { 0x0D07810B, 0x804E0452 },  /*  -267, 3335, 1106,  -78 */
+    { 0x0CF5810B, 0x80500466 },  /*  -267, 3317, 1126,  -80 */
+    { 0x0CE2810A, 0x8052047A },  /*  -266, 3298, 1146,  -82 */
+    { 0x0CCF810A, 0x8053048E },  /*  -266, 3279, 1166,  -83 */
+    { 0x0CBC8109, 0x805504A2 },  /*  -265, 3260, 1186,  -85 */
+    { 0x0CA98108, 0x805704B6 },  /*  -264, 3241, 1206,  -87 */
+    { 0x0C968108, 0x805904CB },  /*  -264, 3222, 1227,  -89 */
+    { 0x0C838107, 0x805B04DF },  /*  -263, 3203, 1247,  -91 */
+    { 0x0C6F8106, 0x805C04F3 },  /*  -262, 3183, 1267,  -92 */
+    { 0x0C5B8105, 0x805E0508 },  /*  -261, 3163, 1288,  -94 */
+    { 0x0C478104, 0x8060051D },  /*  -260, 3143, 1309,  -96 */
+    { 0x0C348103, 0x80620531 },  /*  -259, 3124, 1329,  -98 */
+    { 0x0C1F8102, 0x80640547 },  /*  -258, 3103, 1351, -100 */
+    { 0x0C0C8101, 0x8066055B },  /*  -257, 3084, 1371, -102 */
+    { 0x0BF88100, 0x80680570 },  /*  -256, 3064, 1392, -104 */
+    { 0x0BE380FE, 0x806A0585 },  /*  -254, 3043, 1413, -106 */
+    { 0x0BCF80FD, 0x806C059A },  /*  -253, 3023, 1434, -108 */
+    { 0x0BBA80FC, 0x806E05B0 },  /*  -252, 3002, 1456, -110 */
+    { 0x0BA480F9, 0x807005C5 },  /*  -249, 2980, 1477, -112 */
+    { 0x0B8F80F8, 0x807205DB },  /*  -248, 2959, 1499, -114 */
+    { 0x0B7A80F6, 0x807405F0 },  /*  -246, 2938, 1520, -116 */
+    { 0x0B6580F5, 0x80760606 },  /*  -245, 2917, 1542, -118 */
+    { 0x0B4F80F3, 0x8077061B },  /*  -243, 2895, 1563, -119 */
+    { 0x0B3A80F2, 0x80790631 },  /*  -242, 2874, 1585, -121 */
+    { 0x0B2480F0, 0x807B0647 },  /*  -240, 2852, 1607, -123 */
+    { 0x0B0F80EE, 0x807D065C },  /*  -238, 2831, 1628, -125 */
+    { 0x0AF980ED, 0x807F0673 },  /*  -237, 2809, 1651, -127 */
+    { 0x0AE480EB, 0x80810688 },  /*  -235, 2788, 1672, -129 */
+    { 0x0ACE80E9, 0x8084069F },  /*  -233, 2766, 1695, -132 */
+    { 0x0AB980E7, 0x808606B4 },  /*  -231, 2745, 1716, -134 */
+    { 0x0AA380E6, 0x808806CB },  /*  -230, 2723, 1739, -136 */
+    { 0x0A8D80E4, 0x808A06E1 },  /*  -228, 2701, 1761, -138 */
+    { 0x0A7780E2, 0x808C06F7 },  /*  -226, 2679, 1783, -140 */
+    { 0x0A6180E0, 0x808E070D },  /*  -224, 2657, 1805, -142 */
+    { 0x0A4B80DE, 0x80910724 },  /*  -222, 2635, 1828, -145 */
+    { 0x0A3580DC, 0x8093073A },  /*  -220, 2613, 1850, -147 */
+    { 0x0A1F80DA, 0x80950750 },  /*  -218, 2591, 1872, -149 */
+    { 0x0A0880D8, 0x80970767 },  /*  -216, 2568, 1895, -151 */
+    { 0x09F280D6, 0x8099077D },  /*  -214, 2546, 1917, -153 */
+    { 0x09DD80D4, 0x809C0793 },  /*  -212, 2525, 1939, -156 */
+    { 0x09C680D2, 0x809E07AA },  /*  -210, 2502, 1962, -158 */
+    { 0x09B080D0, 0x80A007C0 },  /*  -208, 2480, 1984, -160 */
+    { 0x099980CE, 0x80A207D7 },  /*  -206, 2457, 2007, -162 */
+    { 0x098380CB, 0x80A507ED },  /*  -203, 2435, 2029, -165 */
+    { 0x096C80C9, 0x80A70804 },  /*  -201, 2412, 2052, -167 */
+    { 0x095680C7, 0x80A9081A },  /*  -199, 2390, 2074, -169 */
+    { 0x094080C5, 0x80AB0830 },  /*  -197, 2368, 2096, -171 */
+    { 0x092980C3, 0x80AE0848 },  /*  -195, 2345, 2120, -174 */
+    { 0x091380C1, 0x80B0085E },  /*  -193, 2323, 2142, -176 */
+    { 0x08FC80BE, 0x80B20874 },  /*  -190, 2300, 2164, -178 */
+    { 0x08E580BC, 0x80B4088B },  /*  -188, 2277, 2187, -180 */
+    { 0x08D080BB, 0x80B708A2 },  /*  -187, 2256, 2210, -183 */
+    { 0x08B980B9, 0x80B908B9 },  /*  -185, 2233, 2233, -185 */
+    { 0x08A380B7, 0x80BB08CF },  /*  -183, 2211, 2255, -187 */
+    { 0x088B80B4, 0x80BC08E5 },  /*  -180, 2187, 2277, -188 */
+    { 0x087480B2, 0x80BE08FC },  /*  -178, 2164, 2300, -190 */
+    { 0x085E80B0, 0x80C10913 },  /*  -176, 2142, 2323, -193 */
+    { 0x084880AE, 0x80C30929 },  /*  -174, 2120, 2345, -195 */
+    { 0x083080AB, 0x80C50940 },  /*  -171, 2096, 2368, -197 */
+    { 0x081A80A9, 0x80C70956 },  /*  -169, 2074, 2390, -199 */
+    { 0x080480A7, 0x80C9096C },  /*  -167, 2052, 2412, -201 */
+    { 0x07ED80A5, 0x80CB0983 },  /*  -165, 2029, 2435, -203 */
+    { 0x07D780A2, 0x80CE0999 },  /*  -162, 2007, 2457, -206 */
+    { 0x07C080A0, 0x80D009B0 },  /*  -160, 1984, 2480, -208 */
+    { 0x07AA809E, 0x80D209C6 },  /*  -158, 1962, 2502, -210 */
+    { 0x0793809C, 0x80D409DD },  /*  -156, 1939, 2525, -212 */
+    { 0x077D8099, 0x80D609F2 },  /*  -153, 1917, 2546, -214 */
+    { 0x07668097, 0x80D80A09 },  /*  -151, 1894, 2569, -216 */
+    { 0x074F8095, 0x80DA0A20 },  /*  -149, 1871, 2592, -218 */
+    { 0x073A8093, 0x80DC0A35 },  /*  -147, 1850, 2613, -220 */
+    { 0x07238091, 0x80DE0A4C },  /*  -145, 1827, 2636, -222 */
+    { 0x070C808E, 0x80E00A62 },  /*  -142, 1804, 2658, -224 */
+    { 0x06F7808C, 0x80E20A77 },  /*  -140, 1783, 2679, -226 */
+    { 0x06E0808A, 0x80E40A8E },  /*  -138, 1760, 2702, -228 */
+    { 0x06CA8088, 0x80E60AA4 },  /*  -136, 1738, 2724, -230 */
+    { 0x06B48086, 0x80E70AB9 },  /*  -134, 1716, 2745, -231 */
+    { 0x069E8084, 0x80E90ACF },  /*  -132, 1694, 2767, -233 */
+    { 0x06878081, 0x80EB0AE5 },  /*  -129, 1671, 2789, -235 */
+    { 0x0672807F, 0x80ED0AFA },  /*  -127, 1650, 2810, -237 */
+    { 0x065C807D, 0x80EE0B0F },  /*  -125, 1628, 2831, -238 */
+    { 0x0646807B, 0x80F00B25 },  /*  -123, 1606, 2853, -240 */
+    { 0x06308079, 0x80F20B3B },  /*  -121, 1584, 2875, -242 */
+    { 0x061A8077, 0x80F30B50 },  /*  -119, 1562, 2896, -243 */
+    { 0x06068076, 0x80F50B65 },  /*  -118, 1542, 2917, -245 */
+    { 0x05F08074, 0x80F60B7A },  /*  -116, 1520, 2938, -246 */
+    { 0x05DB8072, 0x80F80B8F },  /*  -114, 1499, 2959, -248 */
+    { 0x05C58070, 0x80F90BA4 },  /*  -112, 1477, 2980, -249 */
+    { 0x05B1806E, 0x80FC0BB9 },  /*  -110, 1457, 3001, -252 */
+    { 0x059B806C, 0x80FD0BCE },  /*  -108, 1435, 3022, -253 */
+    { 0x0586806A, 0x80FE0BE2 },  /*  -106, 1414, 3042, -254 */
+    { 0x05718068, 0x81000BF7 },  /*  -104, 1393, 3063, -256 */
+    { 0x055C8066, 0x81010C0B },  /*  -102, 1372, 3083, -257 */
+    { 0x05478064, 0x81020C1F },  /*  -100, 1351, 3103, -258 */
+    { 0x05328062, 0x81030C33 },  /*   -98, 1330, 3123, -259 */
+    { 0x051D8060, 0x81040C47 },  /*   -96, 1309, 3143, -260 */
+    { 0x0508805E, 0x81050C5B },  /*   -94, 1288, 3163, -261 */
+    { 0x04F3805C, 0x81060C6F },  /*   -92, 1267, 3183, -262 */
+    { 0x04E0805B, 0x81070C82 },  /*   -91, 1248, 3202, -263 */
+    { 0x04CB8059, 0x81080C96 },  /*   -89, 1227, 3222, -264 */
+    { 0x04B68057, 0x81080CA9 },  /*   -87, 1206, 3241, -264 */
+    { 0x04A28055, 0x81090CBC },  /*   -85, 1186, 3260, -265 */
+    { 0x048E8053, 0x810A0CCF },  /*   -83, 1166, 3279, -266 */
+    { 0x047A8052, 0x810A0CE2 },  /*   -82, 1146, 3298, -266 */
+    { 0x04668050, 0x810B0CF5 },  /*   -80, 1126, 3317, -267 */
+    { 0x0451804E, 0x810B0D08 },  /*   -78, 1105, 3336, -267 */
+    { 0x043E804D, 0x810C0D1B },  /*   -77, 1086, 3355, -268 */
+    { 0x042B804B, 0x810C0D2C },  /*   -75, 1067, 3372, -268 */
+    { 0x04178049, 0x810C0D3E },  /*   -73, 1047, 3390, -268 */
+    { 0x04038048, 0x810C0D51 },  /*   -72, 1027, 3409, -268 */
+    { 0x03F08046, 0x810C0D62 },  /*   -70, 1008, 3426, -268 */
+    { 0x03DD8044, 0x810C0D73 },  /*   -68,  989, 3443, -268 */
+    { 0x03CA8043, 0x810C0D85 },  /*   -67,  970, 3461, -268 */
+    { 0x03B78041, 0x810C0D96 },  /*   -65,  951, 3478, -268 */
+    { 0x03A48040, 0x810C0DA8 },  /*   -64,  932, 3496, -268 */
+    { 0x0391803E, 0x810B0DB8 },  /*   -62,  913, 3512, -267 */
+    { 0x0380803D, 0x810C0DC9 },  /*   -61,  896, 3529, -268 */
+    { 0x036D803B, 0x810C0DDA },  /*   -59,  877, 3546, -268 */
+    { 0x035B803A, 0x810B0DEA },  /*   -58,  859, 3562, -267 */
+    { 0x03488038, 0x810A0DFA },  /*   -56,  840, 3578, -266 */
+    { 0x03368037, 0x810A0E0B },  /*   -55,  822, 3595, -266 */
+    { 0x03248036, 0x81090E1B },  /*   -54,  804, 3611, -265 */
+    { 0x03128034, 0x81080E2A },  /*   -52,  786, 3626, -264 */
+    { 0x03018033, 0x81070E39 },  /*   -51,  769, 3641, -263 */
+    { 0x02EF8032, 0x81060E49 },  /*   -50,  751, 3657, -262 */
+    { 0x02DE8030, 0x81040E56 },  /*   -48,  734, 3670, -260 */
+    { 0x02CC802F, 0x81030E66 },  /*   -47,  716, 3686, -259 */
+    { 0x02BB802E, 0x81020E75 },  /*   -46,  699, 3701, -258 */
+    { 0x02AA802D, 0x81000E83 },  /*   -45,  682, 3715, -256 */
+    { 0x0299802B, 0x80FE0E90 },  /*   -43,  665, 3728, -254 */
+    { 0x0288802A, 0x80FD0E9F },  /*   -42,  648, 3743, -253 */
+    { 0x02778029, 0x80FB0EAD },  /*   -41,  631, 3757, -251 */
+    { 0x02678028, 0x80F90EBA },  /*   -40,  615, 3770, -249 */
+    { 0x02568027, 0x80F70EC8 },  /*   -39,  598, 3784, -247 */
+    { 0x02468025, 0x80F50ED4 },  /*   -37,  582, 3796, -245 */
+    { 0x02368024, 0x80F30EE1 },  /*   -36,  566, 3809, -243 */
+    { 0x02268023, 0x80F00EED },  /*   -35,  550, 3821, -240 */
+    { 0x02188023, 0x80EF0EFA },  /*   -35,  536, 3834, -239 */
+    { 0x02078021, 0x80EB0F05 },  /*   -33,  519, 3845, -235 */
+    { 0x01F98021, 0x80E90F11 },  /*   -33,  505, 3857, -233 */
+    { 0x01EA8020, 0x80E60F1C },  /*   -32,  490, 3868, -230 */
+    { 0x01DC801F, 0x80E40F27 },  /*   -31,  476, 3879, -228 */
+    { 0x01CD801E, 0x80E00F31 },  /*   -30,  461, 3889, -224 */
+    { 0x01BE801D, 0x80DD0F3C },  /*   -29,  446, 3900, -221 */
+    { 0x01AF801C, 0x80DA0F47 },  /*   -28,  431, 3911, -218 */
+    { 0x01A1801B, 0x80D70F51 },  /*   -27,  417, 3921, -215 */
+    { 0x0192801A, 0x80D30F5B },  /*   -26,  402, 3931, -211 */
+    { 0x01848019, 0x80CF0F64 },  /*   -25,  388, 3940, -207 */
+    { 0x01768018, 0x80CB0F6D },  /*   -24,  374, 3949, -203 */
+    { 0x01688017, 0x80C80F77 },  /*   -23,  360, 3959, -200 */
+    { 0x015A8016, 0x80C30F7F },  /*   -22,  346, 3967, -195 */
+    { 0x014D8015, 0x80BF0F87 },  /*   -21,  333, 3975, -191 */
+    { 0x013F8015, 0x80BB0F91 },  /*   -21,  319, 3985, -187 */
+    { 0x01328014, 0x80B60F98 },  /*   -20,  306, 3992, -182 */
+    { 0x01258013, 0x80B20FA0 },  /*   -19,  293, 4000, -178 */
+    { 0x01188012, 0x80AD0FA7 },  /*   -18,  280, 4007, -173 */
+    { 0x010B8011, 0x80A80FAE },  /*   -17,  267, 4014, -168 */
+    { 0x00FE8010, 0x80A30FB5 },  /*   -16,  254, 4021, -163 */
+    { 0x00F28010, 0x809E0FBC },  /*   -16,  242, 4028, -158 */
+    { 0x00E6800F, 0x80990FC2 },  /*   -15,  230, 4034, -153 */
+    { 0x00DA800E, 0x80930FC7 },  /*   -14,  218, 4039, -147 */
+    { 0x00CE800D, 0x808E0FCD },  /*   -13,  206, 4045, -142 */
+    { 0x00C2800D, 0x80880FD3 },  /*   -13,  194, 4051, -136 */
+    { 0x00B6800C, 0x80820FD8 },  /*   -12,  182, 4056, -130 */
+    { 0x00AB800B, 0x807C0FDC },  /*   -11,  171, 4060, -124 */
+    { 0x009F800A, 0x80760FE1 },  /*   -10,  159, 4065, -118 */
+    { 0x0094800A, 0x80700FE6 },  /*   -10,  148, 4070, -112 */
+    { 0x00898009, 0x80690FE9 },  /*    -9,  137, 4073, -105 */
+    { 0x007E8008, 0x80630FED },  /*    -8,  126, 4077,  -99 */
+    { 0x00748007, 0x805C0FEF },  /*    -7,  116, 4079,  -92 */
+    { 0x00698007, 0x80550FF3 },  /*    -7,  105, 4083,  -85 */
+    { 0x005F8006, 0x804E0FF5 },  /*    -6,   95, 4085,  -78 */
+    { 0x00558005, 0x80470FF7 },  /*    -5,   85, 4087,  -71 */
+    { 0x004B8005, 0x80400FFA },  /*    -5,   75, 4090,  -64 */
+    { 0x00418004, 0x80380FFB },  /*    -4,   65, 4091,  -56 */
+    { 0x00378003, 0x80310FFD },  /*    -3,   55, 4093,  -49 */
+    { 0x002E8003, 0x80290FFE },  /*    -3,   46, 4094,  -41 */
+    { 0x00238002, 0x80211000 },  /*    -2,   35, 4096,  -33 */
+    { 0x001A8001, 0x80191000 },  /*    -1,   26, 4096,  -25 */
+    { 0x00118001, 0x80101000 },  /*    -1,   17, 4096,  -16 */
+    { 0x00080000, 0x80081000 },  /*     0,    8, 4096,   -8 */
+};
+
+long CimarronVideoFilter128[][2] =
+{
+	{ 0x10000000, 0x00000000 },  /*     0, 4096,    0,    0 */
+    { 0x10018011, 0x80010011 },  /*   -17, 4097,   17,   -1 */
+    { 0x10008021, 0x80020023 },  /*   -33, 4096,   35,   -2 */
+    { 0x0FFE8031, 0x80030036 },  /*   -49, 4094,   54,   -3 */
+    { 0x0FFB8040, 0x8005004A },  /*   -64, 4091,   74,   -5 */
+    { 0x0FF6804E, 0x8006005E },  /*   -78, 4086,   94,   -6 */
+    { 0x0FF0805C, 0x80070073 },  /*   -92, 4080,  115,   -7 */
+    { 0x0FEB806A, 0x80090088 },  /*  -106, 4075,  136,   -9 */
+    { 0x0FE18076, 0x800A009F },  /*  -118, 4065,  159,  -10 */
+    { 0x0FD98082, 0x800C00B5 },  /*  -130, 4057,  181,  -12 */
+    { 0x0FCE808E, 0x800D00CD },  /*  -142, 4046,  205,  -13 */
+    { 0x0FC38099, 0x800F00E5 },  /*  -153, 4035,  229,  -15 */
+    { 0x0FB680A4, 0x801000FE },  /*  -164, 4022,  254,  -16 */
+    { 0x0FA880AD, 0x80120117 },  /*  -173, 4008,  279,  -18 */
+    { 0x0F9A80B7, 0x80140131 },  /*  -183, 3994,  305,  -20 */
+    { 0x0F8980C0, 0x8015014C },  /*  -192, 3977,  332,  -21 */
+    { 0x0F7880C8, 0x80170167 },  /*  -200, 3960,  359,  -23 */
+    { 0x0F6680D0, 0x80190183 },  /*  -208, 3942,  387,  -25 */
+    { 0x0F5280D7, 0x801B01A0 },  /*  -215, 3922,  416,  -27 */
+    { 0x0F3E80DE, 0x801D01BD },  /*  -222, 3902,  445,  -29 */
+    { 0x0F2880E4, 0x801F01DB },  /*  -228, 3880,  475,  -31 */
+    { 0x0F1180EA, 0x802101FA },  /*  -234, 3857,  506,  -33 */
+    { 0x0EF880EE, 0x80220218 },  /*  -238, 3832,  536,  -34 */
+    { 0x0EDF80F3, 0x80240238 },  /*  -243, 3807,  568,  -36 */
+    { 0x0EC680F7, 0x80270258 },  /*  -247, 3782,  600,  -39 */
+    { 0x0EAB80FB, 0x80290279 },  /*  -251, 3755,  633,  -41 */
+    { 0x0E9080FF, 0x802B029A },  /*  -255, 3728,  666,  -43 */
+    { 0x0E748102, 0x802E02BC },  /*  -258, 3700,  700,  -46 */
+    { 0x0E588105, 0x803102DE },  /*  -261, 3672,  734,  -49 */
+    { 0x0E388107, 0x80330302 },  /*  -263, 3640,  770,  -51 */
+    { 0x0E1A8109, 0x80360325 },  /*  -265, 3610,  805,  -54 */
+    { 0x0DFB810B, 0x80390349 },  /*  -267, 3579,  841,  -57 */
+    { 0x0DDB810C, 0x803C036D },  /*  -268, 3547,  877,  -60 */
+    { 0x0DBA810D, 0x803F0392 },  /*  -269, 3514,  914,  -63 */
+    { 0x0D98810E, 0x804203B8 },  /*  -270, 3480,  952,  -66 */
+    { 0x0D74810D, 0x804503DE },  /*  -269, 3444,  990,  -69 */
+    { 0x0D50810D, 0x80480405 },  /*  -269, 3408, 1029,  -72 */
+    { 0x0D2C810C, 0x804B042B },  /*  -268, 3372, 1067,  -75 */
+    { 0x0D08810C, 0x804F0453 },  /*  -268, 3336, 1107,  -79 */
+    { 0x0CE3810B, 0x8052047A },  /*  -267, 3299, 1146,  -82 */
+    { 0x0CBD810A, 0x805604A3 },  /*  -266, 3261, 1187,  -86 */
+    { 0x0C968108, 0x805904CB },  /*  -264, 3222, 1227,  -89 */
+    { 0x0C708107, 0x805D04F4 },  /*  -263, 3184, 1268,  -93 */
+    { 0x0C488105, 0x8061051E },  /*  -261, 3144, 1310,  -97 */
+    { 0x0C208103, 0x80640547 },  /*  -259, 3104, 1351, -100 */
+    { 0x0BF78100, 0x80680571 },  /*  -256, 3063, 1393, -104 */
+    { 0x0BCF80FE, 0x806C059B },  /*  -254, 3023, 1435, -108 */
+    { 0x0BA480FA, 0x807005C6 },  /*  -250, 2980, 1478, -112 */
+    { 0x0B7A80F7, 0x807405F1 },  /*  -247, 2938, 1521, -116 */
+    { 0x0B4F80F4, 0x8077061C },  /*  -244, 2895, 1564, -119 */
+    { 0x0B2580F1, 0x807C0648 },  /*  -241, 2853, 1608, -124 */
+    { 0x0AFA80ED, 0x80800673 },  /*  -237, 2810, 1651, -128 */
+    { 0x0ACF80EA, 0x8084069F },  /*  -234, 2767, 1695, -132 */
+    { 0x0AA380E6, 0x808806CB },  /*  -230, 2723, 1739, -136 */
+    { 0x0A7880E2, 0x808D06F7 },  /*  -226, 2680, 1783, -141 */
+    { 0x0A4C80DF, 0x80910724 },  /*  -223, 2636, 1828, -145 */
+    { 0x0A2080DB, 0x80960751 },  /*  -219, 2592, 1873, -150 */
+    { 0x09F480D7, 0x809A077D },  /*  -215, 2548, 1917, -154 */
+    { 0x09C780D2, 0x809F07AA },  /*  -210, 2503, 1962, -159 */
+    { 0x099A80CE, 0x80A307D7 },  /*  -206, 2458, 2007, -163 */
+    { 0x096D80CA, 0x80A70804 },  /*  -202, 2413, 2052, -167 */
+    { 0x094180C6, 0x80AC0831 },  /*  -198, 2369, 2097, -172 */
+    { 0x091380C1, 0x80B0085E },  /*  -193, 2323, 2142, -176 */
+    { 0x08E780BE, 0x80B5088C },  /*  -190, 2279, 2188, -181 */
+    { 0x08B980B9, 0x80B908B9 },  /*  -185, 2233, 2233, -185 */
+    { 0x088C80B5, 0x80BE08E7 },  /*  -181, 2188, 2279, -190 */
+    { 0x085E80B0, 0x80C10913 },  /*  -176, 2142, 2323, -193 */
+    { 0x083180AC, 0x80C60941 },  /*  -172, 2097, 2369, -198 */
+    { 0x080480A7, 0x80CA096D },  /*  -167, 2052, 2413, -202 */
+    { 0x07D780A3, 0x80CE099A },  /*  -163, 2007, 2458, -206 */
+    { 0x07AA809F, 0x80D209C7 },  /*  -159, 1962, 2503, -210 */
+    { 0x077D809A, 0x80D709F4 },  /*  -154, 1917, 2548, -215 */
+    { 0x07518096, 0x80DB0A20 },  /*  -150, 1873, 2592, -219 */
+    { 0x07248091, 0x80DF0A4C },  /*  -145, 1828, 2636, -223 */
+    { 0x06F7808D, 0x80E20A78 },  /*  -141, 1783, 2680, -226 */
+    { 0x06CA8088, 0x80E60AA4 },  /*  -136, 1738, 2724, -230 */
+    { 0x069E8084, 0x80EA0AD0 },  /*  -132, 1694, 2768, -234 */
+    { 0x06738080, 0x80ED0AFA },  /*  -128, 1651, 2810, -237 */
+    { 0x0647807C, 0x80F10B26 },  /*  -124, 1607, 2854, -241 */
+    { 0x061B8077, 0x80F40B50 },  /*  -119, 1563, 2896, -244 */
+    { 0x05F18074, 0x80F70B7A },  /*  -116, 1521, 2938, -247 */
+    { 0x05C68070, 0x80FA0BA4 },  /*  -112, 1478, 2980, -250 */
+    { 0x059C806C, 0x80FE0BCE },  /*  -108, 1436, 3022, -254 */
+    { 0x05728068, 0x81000BF6 },  /*  -104, 1394, 3062, -256 */
+    { 0x05478064, 0x81030C20 },  /*  -100, 1351, 3104, -259 */
+    { 0x051E8061, 0x81050C48 },  /*   -97, 1310, 3144, -261 */
+    { 0x04F4805D, 0x81070C70 },  /*   -93, 1268, 3184, -263 */
+    { 0x04CB8059, 0x81080C96 },  /*   -89, 1227, 3222, -264 */
+    { 0x04A38056, 0x810A0CBD },  /*   -86, 1187, 3261, -266 */
+    { 0x047A8052, 0x810B0CE3 },  /*   -82, 1146, 3299, -267 */
+    { 0x0453804F, 0x810C0D08 },  /*   -79, 1107, 3336, -268 */
+    { 0x042B804B, 0x810C0D2C },  /*   -75, 1067, 3372, -268 */
+    { 0x04048048, 0x810D0D51 },  /*   -72, 1028, 3409, -269 */
+    { 0x03DE8045, 0x810D0D74 },  /*   -69,  990, 3444, -269 */
+    { 0x03B88042, 0x810E0D98 },  /*   -66,  952, 3480, -270 */
+    { 0x0393803F, 0x810D0DB9 },  /*   -63,  915, 3513, -269 */
+    { 0x036E803C, 0x810C0DDA },  /*   -60,  878, 3546, -268 */
+    { 0x03498039, 0x810B0DFB },  /*   -57,  841, 3579, -267 */
+    { 0x03258036, 0x81090E1A },  /*   -54,  805, 3610, -265 */
+    { 0x03018033, 0x81070E39 },  /*   -51,  769, 3641, -263 */
+    { 0x02DE8031, 0x81050E58 },  /*   -49,  734, 3672, -261 */
+    { 0x02BC802E, 0x81020E74 },  /*   -46,  700, 3700, -258 */
+    { 0x0299802B, 0x80FF0E91 },  /*   -43,  665, 3729, -255 */
+    { 0x02788029, 0x80FB0EAC },  /*   -41,  632, 3756, -251 */
+    { 0x02578027, 0x80F70EC7 },  /*   -39,  599, 3783, -247 */
+    { 0x02378024, 0x80F30EE0 },  /*   -36,  567, 3808, -243 */
+    { 0x02178022, 0x80EE0EF9 },  /*   -34,  535, 3833, -238 */
+    { 0x01FA8021, 0x80EA0F11 },  /*   -33,  506, 3857, -234 */
+    { 0x01DC801F, 0x80E40F27 },  /*   -31,  476, 3879, -228 */
+    { 0x01BE801D, 0x80DE0F3D },  /*   -29,  446, 3901, -222 */
+    { 0x01A1801B, 0x80D70F51 },  /*   -27,  417, 3921, -215 */
+    { 0x01848019, 0x80D00F65 },  /*   -25,  388, 3941, -208 */
+    { 0x01688017, 0x80C80F77 },  /*   -23,  360, 3959, -200 */
+    { 0x014D8015, 0x80C00F88 },  /*   -21,  333, 3976, -192 */
+    { 0x01328014, 0x80B70F99 },  /*   -20,  306, 3993, -183 */
+    { 0x01188012, 0x80AD0FA7 },  /*   -18,  280, 4007, -173 */
+    { 0x00FF8010, 0x80A40FB5 },  /*   -16,  255, 4021, -164 */
+    { 0x00E6800F, 0x80990FC2 },  /*   -15,  230, 4034, -153 */
+    { 0x00CE800D, 0x808E0FCD },  /*   -13,  206, 4045, -142 */
+    { 0x00B6800C, 0x80820FD8 },  /*   -12,  182, 4056, -130 */
+    { 0x00A0800A, 0x80760FE0 },  /*   -10,  160, 4064, -118 */
+    { 0x00898009, 0x806A0FEA },  /*    -9,  137, 4074, -106 */
+    { 0x00748007, 0x805C0FEF },  /*    -7,  116, 4079,  -92 */
+    { 0x005F8006, 0x804E0FF5 },  /*    -6,   95, 4085,  -78 */
+    { 0x004B8005, 0x80400FFA },  /*    -5,   75, 4090,  -64 */
+    { 0x00378003, 0x80310FFD },  /*    -3,   55, 4093,  -49 */
+    { 0x00238002, 0x80211000 },  /*    -2,   35, 4096,  -33 */
+    { 0x00118001, 0x80111001 },  /*    -1,   17, 4097,  -17 */
+    { 0x10000000, 0x00000000 },  /*     0, 4096,    0,    0 */
+    { 0x10018011, 0x80010011 },  /*   -17, 4097,   17,   -1 */
+    { 0x10008021, 0x80020023 },  /*   -33, 4096,   35,   -2 */
+    { 0x0FFE8031, 0x80030036 },  /*   -49, 4094,   54,   -3 */
+    { 0x0FFB8040, 0x8005004A },  /*   -64, 4091,   74,   -5 */
+    { 0x0FF6804E, 0x8006005E },  /*   -78, 4086,   94,   -6 */
+    { 0x0FF0805C, 0x80070073 },  /*   -92, 4080,  115,   -7 */
+    { 0x0FEB806A, 0x80090088 },  /*  -106, 4075,  136,   -9 */
+    { 0x0FE18076, 0x800A009F },  /*  -118, 4065,  159,  -10 */
+    { 0x0FD98082, 0x800C00B5 },  /*  -130, 4057,  181,  -12 */
+    { 0x0FCE808E, 0x800D00CD },  /*  -142, 4046,  205,  -13 */
+    { 0x0FC38099, 0x800F00E5 },  /*  -153, 4035,  229,  -15 */
+    { 0x0FB680A4, 0x801000FE },  /*  -164, 4022,  254,  -16 */
+    { 0x0FA880AD, 0x80120117 },  /*  -173, 4008,  279,  -18 */
+    { 0x0F9A80B7, 0x80140131 },  /*  -183, 3994,  305,  -20 */
+    { 0x0F8980C0, 0x8015014C },  /*  -192, 3977,  332,  -21 */
+    { 0x0F7880C8, 0x80170167 },  /*  -200, 3960,  359,  -23 */
+    { 0x0F6680D0, 0x80190183 },  /*  -208, 3942,  387,  -25 */
+    { 0x0F5280D7, 0x801B01A0 },  /*  -215, 3922,  416,  -27 */
+    { 0x0F3E80DE, 0x801D01BD },  /*  -222, 3902,  445,  -29 */
+    { 0x0F2880E4, 0x801F01DB },  /*  -228, 3880,  475,  -31 */
+    { 0x0F1180EA, 0x802101FA },  /*  -234, 3857,  506,  -33 */
+    { 0x0EF880EE, 0x80220218 },  /*  -238, 3832,  536,  -34 */
+    { 0x0EDF80F3, 0x80240238 },  /*  -243, 3807,  568,  -36 */
+    { 0x0EC680F7, 0x80270258 },  /*  -247, 3782,  600,  -39 */
+    { 0x0EAB80FB, 0x80290279 },  /*  -251, 3755,  633,  -41 */
+    { 0x0E9080FF, 0x802B029A },  /*  -255, 3728,  666,  -43 */
+    { 0x0E748102, 0x802E02BC },  /*  -258, 3700,  700,  -46 */
+    { 0x0E588105, 0x803102DE },  /*  -261, 3672,  734,  -49 */
+    { 0x0E388107, 0x80330302 },  /*  -263, 3640,  770,  -51 */
+    { 0x0E1A8109, 0x80360325 },  /*  -265, 3610,  805,  -54 */
+    { 0x0DFB810B, 0x80390349 },  /*  -267, 3579,  841,  -57 */
+    { 0x0DDB810C, 0x803C036D },  /*  -268, 3547,  877,  -60 */
+    { 0x0DBA810D, 0x803F0392 },  /*  -269, 3514,  914,  -63 */
+    { 0x0D98810E, 0x804203B8 },  /*  -270, 3480,  952,  -66 */
+    { 0x0D74810D, 0x804503DE },  /*  -269, 3444,  990,  -69 */
+    { 0x0D50810D, 0x80480405 },  /*  -269, 3408, 1029,  -72 */
+    { 0x0D2C810C, 0x804B042B },  /*  -268, 3372, 1067,  -75 */
+    { 0x0D08810C, 0x804F0453 },  /*  -268, 3336, 1107,  -79 */
+    { 0x0CE3810B, 0x8052047A },  /*  -267, 3299, 1146,  -82 */
+    { 0x0CBD810A, 0x805604A3 },  /*  -266, 3261, 1187,  -86 */
+    { 0x0C968108, 0x805904CB },  /*  -264, 3222, 1227,  -89 */
+    { 0x0C708107, 0x805D04F4 },  /*  -263, 3184, 1268,  -93 */
+    { 0x0C488105, 0x8061051E },  /*  -261, 3144, 1310,  -97 */
+    { 0x0C208103, 0x80640547 },  /*  -259, 3104, 1351, -100 */
+    { 0x0BF78100, 0x80680571 },  /*  -256, 3063, 1393, -104 */
+    { 0x0BCF80FE, 0x806C059B },  /*  -254, 3023, 1435, -108 */
+    { 0x0BA480FA, 0x807005C6 },  /*  -250, 2980, 1478, -112 */
+    { 0x0B7A80F7, 0x807405F1 },  /*  -247, 2938, 1521, -116 */
+    { 0x0B4F80F4, 0x8077061C },  /*  -244, 2895, 1564, -119 */
+    { 0x0B2580F1, 0x807C0648 },  /*  -241, 2853, 1608, -124 */
+    { 0x0AFA80ED, 0x80800673 },  /*  -237, 2810, 1651, -128 */
+    { 0x0ACF80EA, 0x8084069F },  /*  -234, 2767, 1695, -132 */
+    { 0x0AA380E6, 0x808806CB },  /*  -230, 2723, 1739, -136 */
+    { 0x0A7880E2, 0x808D06F7 },  /*  -226, 2680, 1783, -141 */
+    { 0x0A4C80DF, 0x80910724 },  /*  -223, 2636, 1828, -145 */
+    { 0x0A2080DB, 0x80960751 },  /*  -219, 2592, 1873, -150 */
+    { 0x09F480D7, 0x809A077D },  /*  -215, 2548, 1917, -154 */
+    { 0x09C780D2, 0x809F07AA },  /*  -210, 2503, 1962, -159 */
+    { 0x099A80CE, 0x80A307D7 },  /*  -206, 2458, 2007, -163 */
+    { 0x096D80CA, 0x80A70804 },  /*  -202, 2413, 2052, -167 */
+    { 0x094180C6, 0x80AC0831 },  /*  -198, 2369, 2097, -172 */
+    { 0x091380C1, 0x80B0085E },  /*  -193, 2323, 2142, -176 */
+    { 0x08E780BE, 0x80B5088C },  /*  -190, 2279, 2188, -181 */
+    { 0x08B980B9, 0x80B908B9 },  /*  -185, 2233, 2233, -185 */
+    { 0x088C80B5, 0x80BE08E7 },  /*  -181, 2188, 2279, -190 */
+    { 0x085E80B0, 0x80C10913 },  /*  -176, 2142, 2323, -193 */
+    { 0x083180AC, 0x80C60941 },  /*  -172, 2097, 2369, -198 */
+    { 0x080480A7, 0x80CA096D },  /*  -167, 2052, 2413, -202 */
+    { 0x07D780A3, 0x80CE099A },  /*  -163, 2007, 2458, -206 */
+    { 0x07AA809F, 0x80D209C7 },  /*  -159, 1962, 2503, -210 */
+    { 0x077D809A, 0x80D709F4 },  /*  -154, 1917, 2548, -215 */
+    { 0x07518096, 0x80DB0A20 },  /*  -150, 1873, 2592, -219 */
+    { 0x07248091, 0x80DF0A4C },  /*  -145, 1828, 2636, -223 */
+    { 0x06F7808D, 0x80E20A78 },  /*  -141, 1783, 2680, -226 */
+    { 0x06CA8088, 0x80E60AA4 },  /*  -136, 1738, 2724, -230 */
+    { 0x069E8084, 0x80EA0AD0 },  /*  -132, 1694, 2768, -234 */
+    { 0x06738080, 0x80ED0AFA },  /*  -128, 1651, 2810, -237 */
+    { 0x0647807C, 0x80F10B26 },  /*  -124, 1607, 2854, -241 */
+    { 0x061B8077, 0x80F40B50 },  /*  -119, 1563, 2896, -244 */
+    { 0x05F18074, 0x80F70B7A },  /*  -116, 1521, 2938, -247 */
+    { 0x05C68070, 0x80FA0BA4 },  /*  -112, 1478, 2980, -250 */
+    { 0x059C806C, 0x80FE0BCE },  /*  -108, 1436, 3022, -254 */
+    { 0x05728068, 0x81000BF6 },  /*  -104, 1394, 3062, -256 */
+    { 0x05478064, 0x81030C20 },  /*  -100, 1351, 3104, -259 */
+    { 0x051E8061, 0x81050C48 },  /*   -97, 1310, 3144, -261 */
+    { 0x04F4805D, 0x81070C70 },  /*   -93, 1268, 3184, -263 */
+    { 0x04CB8059, 0x81080C96 },  /*   -89, 1227, 3222, -264 */
+    { 0x04A38056, 0x810A0CBD },  /*   -86, 1187, 3261, -266 */
+    { 0x047A8052, 0x810B0CE3 },  /*   -82, 1146, 3299, -267 */
+    { 0x0453804F, 0x810C0D08 },  /*   -79, 1107, 3336, -268 */
+    { 0x042B804B, 0x810C0D2C },  /*   -75, 1067, 3372, -268 */
+    { 0x04048048, 0x810D0D51 },  /*   -72, 1028, 3409, -269 */
+    { 0x03DE8045, 0x810D0D74 },  /*   -69,  990, 3444, -269 */
+    { 0x03B88042, 0x810E0D98 },  /*   -66,  952, 3480, -270 */
+    { 0x0393803F, 0x810D0DB9 },  /*   -63,  915, 3513, -269 */
+    { 0x036E803C, 0x810C0DDA },  /*   -60,  878, 3546, -268 */
+    { 0x03498039, 0x810B0DFB },  /*   -57,  841, 3579, -267 */
+    { 0x03258036, 0x81090E1A },  /*   -54,  805, 3610, -265 */
+    { 0x03018033, 0x81070E39 },  /*   -51,  769, 3641, -263 */
+    { 0x02DE8031, 0x81050E58 },  /*   -49,  734, 3672, -261 */
+    { 0x02BC802E, 0x81020E74 },  /*   -46,  700, 3700, -258 */
+    { 0x0299802B, 0x80FF0E91 },  /*   -43,  665, 3729, -255 */
+    { 0x02788029, 0x80FB0EAC },  /*   -41,  632, 3756, -251 */
+    { 0x02578027, 0x80F70EC7 },  /*   -39,  599, 3783, -247 */
+    { 0x02378024, 0x80F30EE0 },  /*   -36,  567, 3808, -243 */
+    { 0x02178022, 0x80EE0EF9 },  /*   -34,  535, 3833, -238 */
+    { 0x01FA8021, 0x80EA0F11 },  /*   -33,  506, 3857, -234 */
+    { 0x01DC801F, 0x80E40F27 },  /*   -31,  476, 3879, -228 */
+    { 0x01BE801D, 0x80DE0F3D },  /*   -29,  446, 3901, -222 */
+    { 0x01A1801B, 0x80D70F51 },  /*   -27,  417, 3921, -215 */
+    { 0x01848019, 0x80D00F65 },  /*   -25,  388, 3941, -208 */
+    { 0x01688017, 0x80C80F77 },  /*   -23,  360, 3959, -200 */
+    { 0x014D8015, 0x80C00F88 },  /*   -21,  333, 3976, -192 */
+    { 0x01328014, 0x80B70F99 },  /*   -20,  306, 3993, -183 */
+    { 0x01188012, 0x80AD0FA7 },  /*   -18,  280, 4007, -173 */
+    { 0x00FF8010, 0x80A40FB5 },  /*   -16,  255, 4021, -164 */
+    { 0x00E6800F, 0x80990FC2 },  /*   -15,  230, 4034, -153 */
+    { 0x00CE800D, 0x808E0FCD },  /*   -13,  206, 4045, -142 */
+    { 0x00B6800C, 0x80820FD8 },  /*   -12,  182, 4056, -130 */
+    { 0x00A0800A, 0x80760FE0 },  /*   -10,  160, 4064, -118 */
+    { 0x00898009, 0x806A0FEA },  /*    -9,  137, 4074, -106 */
+    { 0x00748007, 0x805C0FEF },  /*    -7,  116, 4079,  -92 */
+    { 0x005F8006, 0x804E0FF5 },  /*    -6,   95, 4085,  -78 */
+    { 0x004B8005, 0x80400FFA },  /*    -5,   75, 4090,  -64 */
+    { 0x00378003, 0x80310FFD },  /*    -3,   55, 4093,  -49 */
+    { 0x00238002, 0x80211000 },  /*    -2,   35, 4096,  -33 */
+    { 0x00118001, 0x80111001 },  /*    -1,   17, 4097,  -17 */
+};
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_gp.c xf86-video-nsc-2.8.1/src/cim/cim_gp.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_gp.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_gp.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,3442 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron graphics processor routines.  These routines program the graphics
+  * hardware using the graphics command buffer.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*---------------------*/
+/* CIMARRON GP GLOBALS */
+/*---------------------*/
+
+CIMARRON_STATIC unsigned long gp3_bpp         = 0;
+CIMARRON_STATIC unsigned long gp3_ch3_bpp     = 0;
+CIMARRON_STATIC unsigned long gp3_pat_origin  = 0;
+CIMARRON_STATIC unsigned long gp3_buffer_lead = 0;
+CIMARRON_STATIC unsigned long gp3_cmd_header;
+CIMARRON_STATIC unsigned long gp3_cmd_top;
+CIMARRON_STATIC unsigned long gp3_cmd_bottom;
+CIMARRON_STATIC unsigned long gp3_cmd_current;
+CIMARRON_STATIC unsigned long gp3_cmd_next;
+CIMARRON_STATIC unsigned long gp3_blt_mode;
+CIMARRON_STATIC unsigned long gp3_vec_mode;
+CIMARRON_STATIC unsigned long gp3_raster_mode;
+CIMARRON_STATIC unsigned long gp3_pix_shift;
+CIMARRON_STATIC unsigned long gp3_ch3_pat;
+CIMARRON_STATIC unsigned long gp3_blt;
+CIMARRON_STATIC unsigned long gp3_blt_flags;
+CIMARRON_STATIC unsigned long gp3_src_stride;
+CIMARRON_STATIC unsigned long gp3_dst_stride;
+CIMARRON_STATIC unsigned long gp3_src_format;
+CIMARRON_STATIC unsigned long gp3_src_pix_shift;
+CIMARRON_STATIC unsigned long gp3_pat_format;
+CIMARRON_STATIC unsigned long gp3_pat_pix_shift;
+CIMARRON_STATIC unsigned long gp3_fb_base;
+CIMARRON_STATIC unsigned long gp3_vector_pattern_color;
+CIMARRON_STATIC unsigned long gp3_scratch_base;
+CIMARRON_STATIC unsigned long gp3_base_register;
+CIMARRON_STATIC unsigned long gp3_vec_pat;
+
+/*---------------------------------------------------------------------------
+ * gp_set_limit_on_buffer_lead
+ *
+ * This routine is used to specify the maximum number of bytes in the command
+ * buffer by which software can lead the graphics processor.  When declaring
+ * a BLT with the CIMGP_BLTFLAGS_LIMITBUFFER flag set, Cimarron will wait until
+ * the command buffer read and write pointers differ by no more than 'lead'
+ * bytes.  This can be useful to limit the time lag possible when creating a
+ * command buffer full of simple BLT commands.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_limit_on_buffer_lead (unsigned long lead)
+{	
+	gp3_buffer_lead = lead;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_command_buffer_base
+ *
+ * This routine is used to program the command buffer region in physical
+ * memory.  The command buffer start address must be 1MB aligned. start and
+ * stop refer to endpoints within the associated 16MB region.  Command buffers
+ * larger than 16MB are not supported.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_command_buffer_base (unsigned long address, unsigned long start,
+	unsigned long stop)
+{	
+	Q_WORD msr_value;
+
+	/* WAIT FOR IDLE */
+	/* Obviously, we cannot change the command buffer pointer while the GP */
+	/* is currently fetching commands.                                     */
+
+	gp_wait_until_idle();
+
+    /* WRITE THE COMMAND BUFFER BASE */
+
+	msr_read64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);
+	msr_value.low &= 0xF000FFFF;
+	msr_value.low |= (address >> 4) & 0x0FFF0000;
+	msr_write64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);
+
+    /* WRITE THE BASE OFFSETS */
+	/* We also reset the write and read pointers.  The hardware will */
+	/* automatically update the write pointer when the read pointer  */
+	/* is updated to prevent the hardware from getting confused when */
+	/* initializing a new command buffer.                            */
+
+	WRITE_GP32 (GP3_CMD_TOP, start);
+	WRITE_GP32 (GP3_CMD_BOT, stop);
+	WRITE_GP32 (GP3_CMD_READ, start);
+
+    /* SAVE THE BASE ADDRESSES */
+	/* These are used to determine the appropriate wrap point. */
+
+	gp3_cmd_current = gp3_cmd_top = start;
+	gp3_cmd_bottom  = stop;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_frame_buffer_base
+ *
+ * This routine is used to program the base address of the frame buffer in
+ * physical memory.  The frame buffer address must be 16MB aligned.  Cimarron
+ * tracks the base address because the maximum frame buffer size may exceed
+ * 16MB. Any primitive will thus program the corresponding 16MB region into all
+ * base offset registers as well as program the offset into the 16MB region.
+ * The size parameter is provided to allow Cimarron to claim the last 1MB of
+ * space to be used as a scratch area for workarounds or expanded functionality.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_frame_buffer_base (unsigned long address, unsigned long size)
+{	
+    gp3_scratch_base = size - GP3_SCRATCH_BUFFER_SIZE;
+	gp3_fb_base = address >> 24;
+    gp3_base_register = (gp3_fb_base << 24) | (gp3_fb_base << 14) | (gp3_fb_base << 4);
+    WRITE_GP32 (GP3_BASE_OFFSET, gp3_base_register);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_bpp
+ *
+ * This routine sets the output BPP of the GP.  The BPP used by the GP does
+ * not have to match the display BPP, but that is usually the case.  The
+ * supported BPP values are as follows:
+ *
+ *    8  - palettized 8BPP
+ *    12 - 4:4:4:4
+ *    15 - 1:5:5:5
+ *    16 - 0:5:6:5
+ *    32 - 8:8:8:8
+ *-------------------------------------------------------------------------*/
+
+void gp_set_bpp (int bpp)
+{
+	/* STORE BPP */
+	/* The bpp is not updated until the next call to gp_set_raster_mode. */
+	/* This allows the gp_set_bpp call to happen outside of a BLT.  It   */
+	/* also implies that no registers need be written in this routine.   */
+	
+	switch(bpp)
+	{
+		case 8:	
+			gp3_bpp       = GP3_RM_BPPFMT_332;
+			gp3_ch3_bpp   = GP3_CH3_SRC_3_3_2;
+			gp3_pix_shift = 0;
+			break;
+		case 12:
+			gp3_bpp       = GP3_RM_BPPFMT_4444;
+			gp3_ch3_bpp   = GP3_CH3_SRC_4_4_4_4;
+			gp3_pix_shift = 1;
+			break;
+		case 15:
+			gp3_bpp       = GP3_RM_BPPFMT_1555;
+			gp3_ch3_bpp   = GP3_CH3_SRC_1_5_5_5;
+			gp3_pix_shift = 1;
+			break;
+		case 16:
+			gp3_bpp       = GP3_RM_BPPFMT_565;
+			gp3_ch3_bpp   = GP3_CH3_SRC_0_5_6_5;
+			gp3_pix_shift = 1;
+			break;
+        case 24:
+        case 32:
+			gp3_bpp       = GP3_RM_BPPFMT_8888;
+			gp3_ch3_bpp   = GP3_CH3_SRC_8_8_8_8;
+			gp3_pix_shift = 2;
+			break;
+		default:
+			gp3_bpp       = GP3_RM_BPPFMT_332;
+			gp3_ch3_bpp   = GP3_CH3_SRC_3_3_2;
+			gp3_pix_shift = 0;
+			break;
+	}
+}
+
+/*---------------------------------------------------------------------------
+ * gp_declare_blt
+ *
+ * This routine is used to prepare for a 2D BLT.  Its primary function
+ * is to verify that enough room is available in the command buffer
+ * to hold a BLT command.  This command can be called multiple times if
+ * necessary.  For example, if a function calls this routine on entry, but
+ * later realizes that a LUT load command must be executed before the BLT,
+ * the application could call gp_set_color_pattern and then call
+ * gp_declare_blt to declare the BLT.  This is possible because the hardware
+ * buffer pointer is not updated until a new BLT is actually executed.  An
+ * application must take care not to call any routines that perform a buffer
+ * command, (such as gp_set_color_pattern) between gp_declare_blt and the
+ * routines used to program the BLT parameters.  In addition to checking for
+ * available space, this routine also performs the following actions:
+ *    - Sets the wrap bit if this BLT will pass close to the end of the buffer.
+ *    - Writes the command header.
+ *
+ * The available flags are defined as follows:
+ *   0x01 - Preserve the LUT
+ *   0x02 - Preserve the color pattern.
+ *   0x04 - Enable prefetch.
+ *-------------------------------------------------------------------------*/
+
+void gp_declare_blt (unsigned long flags)
+{	
+	unsigned long temp;
+
+	gp3_blt = 1;
+	gp3_blt_flags = flags;
+
+	/* SET ADDRESS OF NEXT COMMAND */
+	/* A summary of the command buffer logic is as follows:           */
+	/*  - If after a basic BLT we will not have room for the largest  */
+	/*    command (a full line of host source data), we set the wrap  */
+	/*    bit.  This will waste up to a whopping 8K of command buffer */
+	/*    space, but it simplifies the logic for all commands.        */
+	/* -  If we are wrapping, we have extra logic to ensure that we   */
+	/*    don't skip over the current GP read pointer.                */
+
+    gp3_cmd_next = gp3_cmd_current + GP3_BLT_COMMAND_SIZE;
+
+	/* CHECK WRAP CONDITION */
+
+	if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+	{
+		gp3_cmd_next   = gp3_cmd_top;
+		gp3_cmd_header = GP3_BLT_HDR_TYPE | GP3_BLT_HDR_WRAP;
+
+		/* WAIT FOR HARDWARE */
+		/* When wrapping, we must take steps to ensure that we do not    */
+		/* wrap over the current hardware read pointer.  We do this by   */
+		/* verifying that the hardware is not between us and the end of  */
+		/* the command buffer.  We also have a special case to make sure */
+		/* that the hardware is not currently reading the top of the     */
+		/* command buffer.                                               */
+
+		GP3_WAIT_WRAP(temp);
+	}
+	else
+	{
+		gp3_cmd_header = GP3_BLT_HDR_TYPE;
+
+		/* WAIT FOR AVAILABLE SPACE */
+
+		GP3_WAIT_PRIMITIVE(temp);
+	}
+
+    if (flags & CIMGP_BLTFLAGS_LIMITBUFFER)
+    {
+        while (1)
+        {
+            temp = READ_GP32 (GP3_CMD_READ);
+            if (((gp3_cmd_current >= temp) && ((gp3_cmd_current - temp) <= gp3_buffer_lead)) ||
+                ((gp3_cmd_current <  temp) && ((gp3_cmd_current + (gp3_cmd_bottom - temp)) <= gp3_buffer_lead)))
+            {
+                break;
+            }
+        }
+    }
+
+	/* SET THE CURRENT BUFFER POINTER */
+	/* We initialize a pointer to the current buffer base to avoid an */
+	/* extra addition for every buffer write.                         */
+
+	cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+    /* SET THE HAZARD BIT */
+
+    if (flags & CIMGP_BLTFLAGS_HAZARD)
+        gp3_cmd_header |= GP3_BLT_HDR_HAZARD_ENABLE;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_declare_vector
+ *
+ * This routine is used to prepare for a 2D vector.  It has no other function
+ * except to verify that enough room is available in the command buffer
+ * to hold a vector command.  The same rules that apply to BLTs apply to
+ * vectors. (See the documentation for gp_declare_blt).
+ *-------------------------------------------------------------------------*/
+
+void gp_declare_vector (unsigned long flags)
+{
+	unsigned long temp;
+
+	gp3_blt = 0;
+    gp3_blt_flags = flags;
+	
+	/* SET ADDRESS OF NEXT COMMAND                            */
+	/* The logic to force a wrap during a vector is identical */
+	/* to the BLT logic.                                      */
+
+    /* ALLOCATE SPACE FOR AN ADDITIONAL VECTOR TO CLEAR THE BYTE ENABLES */
+
+    gp3_cmd_next = gp3_cmd_current + GP3_VECTOR_COMMAND_SIZE + GP3_VECTOR_COMMAND_SIZE + 32;
+
+	/* CHECK WRAP CONDITION */
+
+	if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+	{
+		gp3_cmd_next   = gp3_cmd_top;
+		gp3_cmd_header = GP3_VEC_HDR_TYPE | GP3_VEC_HDR_WRAP;
+
+		/* CHECK WRAP CONDITION */
+
+		GP3_WAIT_WRAP(temp);
+	}
+	else
+	{
+		gp3_cmd_header = GP3_VEC_HDR_TYPE;
+
+		/* WAIT FOR AVAILABLE SPACE */
+
+		GP3_WAIT_PRIMITIVE(temp);
+
+        gp3_cmd_next -= GP3_VECTOR_COMMAND_SIZE + 32;
+	}
+
+    if (flags & CIMGP_BLTFLAGS_LIMITBUFFER)
+    {
+        while (1)
+        {
+            temp = READ_GP32 (GP3_CMD_READ);
+            if (((gp3_cmd_current >= temp) && ((gp3_cmd_current - temp) <= gp3_buffer_lead)) ||
+                ((gp3_cmd_current <  temp) && ((gp3_cmd_current + (gp3_cmd_bottom - temp)) <= gp3_buffer_lead)))
+            {
+                break;
+            }
+        }
+    }
+
+	cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+    /* SET THE HAZARD BIT */
+
+    if (flags & CIMGP_BLTFLAGS_HAZARD)
+        gp3_cmd_header |= GP3_VEC_HDR_HAZARD_ENABLE;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_write_parameters
+ *
+ * This routine is called to write all recent parameters to the hardware.
+ * This routine is necessary for any implementation that performs the setup
+ * for a BLT separate from the actual BLT.  An example would be a driver
+ * that prepares for multiple pattern fills by programming the ROP,
+ * pattern color and destination stride.  The driver might then perform
+ * repeated pattern fills with minimal effort.
+ *-------------------------------------------------------------------------*/
+
+void gp_write_parameters (void)
+{
+	/* WRITE THE COMMAND HEADER */
+	/* Command header is at offset 0 for BLTs and vectors */
+	
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	
+	/* INCREMENT THE CURRENT WRITE POINTER */
+
+	gp3_cmd_current = gp3_cmd_next;
+
+	/* UPDATE THE GP WRITE POINTER */
+
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_current);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_raster_operation
+ *
+ * This is generally the first routine called when programming a BLT.  This
+ * routine performs the following functions:
+ *   - Sets the initial value of the GP3_RASTER_MODE register in the buffer.
+ *   - Clears any 8x8 pattern if the ROP does not involve pattern data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_raster_operation (unsigned char ROP)
+{
+	gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE;
+
+	/* WRITE THE RASTER MODE REGISTER                                   */
+	/* This register is in the same location in BLT and vector commands */
+
+	gp3_raster_mode = gp3_bpp | (unsigned long)ROP;
+	WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);
+
+	/* CHECK IF DESTINATION IS REQUIRED */
+
+	if ((ROP & 0x55) ^ ((ROP >> 1) & 0x55))
+	{
+		gp3_blt_mode = GP3_BM_DST_REQ;
+		gp3_vec_mode = GP3_VM_DST_REQ;
+	}
+	else
+	{
+		gp3_blt_mode = gp3_vec_mode = 0;
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * gp_set_alpha_operation
+ *
+ * BLTs are generally one of two types, a ROPed BLT or a BLT composited using
+ * alpha blending.  For the latter, this routine is used to configure the
+ * mathematical function used to create the blended output.  This routine
+ * should generally be called first when programming a BLT.  The available
+ * parameters mirror the hardware and are described as follows:
+ *
+ * alpha_operation =
+ *   0 - alpha * A
+ *   1 - (1 - alpha) * B
+ *   2 - A + (1 - alpha)*B
+ *   3 - alpha*A + (1 - alpha)*B
+ *
+ * alpha_type =
+ *   0 - alpha component of channel A
+ *   1 - alpha component of channel B
+ *   2 - Constant alpha
+ *   3 - Constant 1
+ *   4 - The color components of channel A
+ *   5 - The color components of channel B
+ *   6 - Alpha comes from the alpha channel of the source before the source undergoes
+ *       color conversion.
+ *
+ * channel =
+ *   0 - Channel A = source, channel B = destination
+ *   1 - Channel B = source, channel A = destination
+ *
+ * apply_alpha =
+ *   1 - Apply alpha blend to only the RGB portion of the pixel.  This must be
+ *       set when the source or destination format do not include an alpha channel.
+ *   2 - Apply alpha blend only to the alpha portion of the pixel.  This implies
+ *       that both destination and source include an alpha channel.
+ *   3 - Apply alpha blend to both the RGB and alpha portions of the pixel.
+ *
+ * Alpha-blended vectors are not currently supported.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_alpha_operation (int alpha_operation, int alpha_type, int channel,
+	int apply_alpha, unsigned char alpha)
+{
+	gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE;
+	
+	/* THE AVAILABLE ALPHA DEFINITIONS FOLLOW THE HARDWARE       */
+	/* This allows us to avoid giant switch structures, but it   */
+	/* also implies that there is no mechanism to detect invalid */
+	/* parameters.                                               */
+
+	gp3_raster_mode = gp3_bpp | (unsigned long)alpha |
+		((unsigned long)apply_alpha     << 22) |
+		((unsigned long)alpha_operation << 20) |
+		((unsigned long)alpha_type      << 17) |
+		((unsigned long)channel         << 16);
+	
+	WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);
+
+	/* CHECK IF DESTINATION IS REQUIRED */
+
+	if ( (alpha_operation == CIMGP_ALPHA_TIMES_A &&
+          channel == CIMGP_CHANNEL_A_SOURCE &&
+          alpha_type != CIMGP_CHANNEL_B_ALPHA &&
+          alpha_type != CIMGP_ALPHA_FROM_RGB_B)  ||
+         (alpha_operation == CIMGP_BETA_TIMES_B &&
+          channel == CIMGP_CHANNEL_A_DEST &&
+          alpha_type != CIMGP_CHANNEL_A_ALPHA &&
+          alpha_type != CIMGP_ALPHA_FROM_RGB_A))
+    {
+        gp3_blt_mode = 0;
+    }
+    else
+        gp3_blt_mode = GP3_BM_DST_REQ;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_solid_pattern
+ *
+ * This routine is called to program the hardware for a solid pattern.  It need
+ * not be called for any other reason.  As a side effect, this routine will
+ * clear any 8x8 pattern data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_solid_pattern (unsigned long color)
+{
+	/* CHANNEL 3 IS NOT NEEDED FOR SOLID PATTERNS */
+
+	gp3_ch3_pat = 0;
+
+	/* SET SOLID PATTERN IN COMMAND BUFFER */
+	/* We are assuming that only one pattern type is ever set for a */
+	/* BLT.  We are also assuming that gp_set_raster_operation will */
+	/* be called before this routine.  With these assumptions, we   */
+	/* will thus never have to change the raster mode register for  */
+	/* solid patterns.                                              */
+
+	if (gp3_blt)
+	{
+		gp3_cmd_header |= GP3_BLT_HDR_PAT_CLR0_ENABLE;
+
+		WRITE_COMMAND32 (GP3_BLT_PAT_COLOR_0, color);
+	}
+	else
+	{
+		gp3_cmd_header |= GP3_VEC_HDR_PAT_CLR0_ENABLE;
+
+		WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, color);
+	}
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_mono_pattern
+ *
+ * This routine is called to program the hardware for a monochrome pattern.
+ * As a side effect, this routine will clear any 8x8 pattern data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_mono_pattern (unsigned long bgcolor, unsigned long fgcolor,
+	unsigned long data0, unsigned long data1, int transparent, int x, int y)
+{
+	/* CHANNEL 3 IS NOT NEEDED FOR MONOCHROME PATTERNS */
+
+	gp3_ch3_pat = 0;
+
+	/* UPDATE RASTER MODE REGISTER */
+
+	if (transparent) gp3_raster_mode |= GP3_RM_PAT_MONO | GP3_RM_PAT_TRANS;
+	else             gp3_raster_mode |= GP3_RM_PAT_MONO;
+		
+	gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE;
+
+	WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);	
+
+	/* SET MONOCHROME PATTERN DATA AND COLORS */
+
+	if (gp3_blt)
+	{
+		gp3_cmd_header |= (GP3_BLT_HDR_PAT_CLR0_ENABLE | GP3_BLT_HDR_PAT_CLR1_ENABLE |
+			GP3_BLT_HDR_PAT_DATA0_ENABLE | GP3_BLT_HDR_PAT_DATA1_ENABLE);
+
+		WRITE_COMMAND32 (GP3_BLT_PAT_COLOR_0, bgcolor);
+		WRITE_COMMAND32 (GP3_BLT_PAT_COLOR_1, fgcolor);
+		WRITE_COMMAND32 (GP3_BLT_PAT_DATA_0,  data0);
+		WRITE_COMMAND32 (GP3_BLT_PAT_DATA_1,  data1);
+	}
+	else
+	{
+		gp3_cmd_header |= (GP3_VEC_HDR_PAT_CLR0_ENABLE | GP3_VEC_HDR_PAT_CLR1_ENABLE |
+			GP3_VEC_HDR_PAT_DATA0_ENABLE | GP3_VEC_HDR_PAT_DATA1_ENABLE);
+
+		WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, bgcolor);
+		WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_1, fgcolor);
+		WRITE_COMMAND32 (GP3_VECTOR_PAT_DATA_0,  data0);
+		WRITE_COMMAND32 (GP3_VECTOR_PAT_DATA_1,  data1);
+	}
+
+	/* SAVE PATTERN ORIGIN */
+
+	gp3_pat_origin = ((unsigned long)y << 29) | (((unsigned long)x & 7) << 26);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_pattern_origin
+ *
+ * This routine overrides the pattern origins set in gp_set_mono_pattern or
+ * gp_set_color_pattern.  It is generally used to override the original
+ * pattern origin due to a change in clipping.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_pattern_origin (int x, int y)
+{
+	/* SAVE PATTERN ORIGIN */
+
+	gp3_pat_origin = ((unsigned long)y << 29) | (((unsigned long)x & 7) << 26);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_color_pattern
+ *
+ * This routine is called to program a 8x8 color pattern into the LUT hardware.
+ * Unlike the other pattern routines, this routine must be called before
+ * any gp_declare_xxxx routines.  The pattern that is programmed into the
+ * hardware will stay persistent for all subsequent primitives until one of
+ * the following conditions happens.
+ *   - Another pattern type is programmed.
+ *   - A color-conversion BLT rotation BLT.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_color_pattern (unsigned long *pattern, int format, int x, int y)
+{
+	unsigned long size_dwords, temp;
+	
+	gp3_ch3_pat = 1;
+
+	/* SAVE COLOR PATTERN SOURCE INFO */
+	/* Color patterns can be in a format different than the primary display. */
+	/* 4BPP patterns are not supported.                                      */
+	
+	gp3_pat_pix_shift = (unsigned long)((format >> 2) & 3);
+	gp3_pat_format = (((unsigned long)format & 0xF)  << 24) |
+		             (((unsigned long)format & 0x10) << 17) |
+					 GP3_CH3_COLOR_PAT_ENABLE               |
+					 GP3_CH3_C3EN;
+
+	size_dwords = (64 << gp3_pat_pix_shift) >> 2;
+
+	/* CHECK FOR WRAP AFTER LUT LOAD                 */
+	/* Primitive size is 12 plus the amount of data. */
+
+	gp3_cmd_next = gp3_cmd_current + (size_dwords << 2) + 12;
+	
+	if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+	{
+		gp3_cmd_next   = gp3_cmd_top;
+		gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_WRAP | GP3_LUT_HDR_DATA_ENABLE;
+
+		/* WAIT FOR HARDWARE           */
+		/* Same logic as BLT wrapping. */
+
+		GP3_WAIT_WRAP(temp);
+	}
+	else
+	{
+		gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE;
+
+		/* WAIT FOR AVAILABLE SPACE */
+
+		GP3_WAIT_PRIMITIVE(temp);
+	}
+
+	/* SAVE CURRENT BUFFER POINTER */
+
+	cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+	/* PREPARE FOR COMMAND BUFFER DATA WRITES                 */
+	/* Pattern data is contiguous DWORDs at LUT address 0x100 */
+
+	WRITE_COMMAND32 (0, gp3_cmd_header);
+	WRITE_COMMAND32 (4, 0x100);
+	WRITE_COMMAND32 (8, size_dwords | GP3_LUT_DATA_TYPE);	
+
+	/* WRITE ALL DATA */
+
+	WRITE_COMMAND_STRING32 (12, pattern, 0, size_dwords);
+
+	/* START OPERATION */
+
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+	/* SAVE PATTERN ORIGIN */
+
+	gp3_pat_origin = ((unsigned long)y << 29) | (((unsigned long)x & 7) << 26);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_mono_source
+ *
+ * This routine is called to program the colors for monochrome source data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_mono_source (unsigned long bgcolor, unsigned long fgcolor,
+	int transparent)
+{
+	/* UPDATE RASTER MODE REGISTER IF TRANSPARENT */
+
+	if (transparent)
+	{
+		gp3_cmd_header  |= GP3_BLT_HDR_RASTER_ENABLE;
+		gp3_raster_mode |= GP3_RM_SRC_TRANS;
+
+		WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);	
+	}
+
+	/* SET MONOCHROME SOURCE COLORS */
+	/* Note that this routine only sets the colors.  The actual */
+	/* source type is determined by the final output routine    */
+	/* (gp_mono_bitmap_xxx, gp_color_bitmap_xxx, etc.)          */
+
+	gp3_cmd_header |= GP3_BLT_HDR_SRC_FG_ENABLE | GP3_BLT_HDR_SRC_BG_ENABLE;
+
+	WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_FG, fgcolor);
+	WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_BG, bgcolor);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_solid_source
+ *
+ * This routine is called to program a solid source color.  A solid source
+ * color is used primarily for vectors or antialiased text.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_solid_source (unsigned long color)
+{
+	/* SET SOLID SOURCE COLOR */
+	/* The solid source register is in the same place for both BLTs and */
+	/* vectors.                                                         */
+
+	gp3_cmd_header |= GP3_BLT_HDR_SRC_FG_ENABLE;
+
+	WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_FG, color);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_source_transparency
+ *
+ * This routine sets the source transparency and mask to be used in future
+ * rendering operations.  Transparency is cleared by gp_set_raster_operation,
+ * so this routine should never be called first.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_source_transparency (unsigned long color, unsigned long mask)
+{
+	gp3_raster_mode |= GP3_RM_SRC_TRANS;
+	gp3_cmd_header  |= GP3_BLT_HDR_RASTER_ENABLE | GP3_BLT_HDR_SRC_FG_ENABLE |
+		GP3_BLT_HDR_SRC_BG_ENABLE;
+	
+	WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);	
+	WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_FG, color);
+	WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_BG, mask);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_program_lut
+ *
+ * This routine is called to program the hardware LUT with color-conversion
+ * information.  This routine should be called before any gp_declare_xxxx
+ * routines.
+ *
+ * colors   - Pointer to an array of DWORDs for color expansion.
+ *
+ * full_lut - Selector between 4BPP and 8BPP expansion. The hardware is
+ *            initialized with 16 dwords for 4BPP expansion and 256 dwords
+ *            for 8BPP expansion.
+ *-------------------------------------------------------------------------*/
+
+void gp_program_lut (unsigned long *colors, int full_lut)
+{
+	unsigned long size_dwords, temp;
+	
+	/* SIZE IS EITHER 16 DWORDS (4BPP) or 256 DWORDS (8BPP) */
+
+	if (full_lut) size_dwords = 256;
+	else          size_dwords = 16;
+
+	/* CHECK FOR WRAP AFTER LUT LOAD                 */
+	/* Primitive size is 12 plus the amount of data. */
+
+	gp3_cmd_next = gp3_cmd_current + (size_dwords << 2) + 12;
+	
+	if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+	{
+		gp3_cmd_next   = gp3_cmd_top;
+		gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_WRAP | GP3_LUT_HDR_DATA_ENABLE;
+
+		/* WAIT FOR HARDWARE           */
+		/* Same logic as BLT wrapping. */
+
+		GP3_WAIT_WRAP(temp);
+	}
+	else
+	{
+		gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE;
+
+		/* WAIT FOR AVAILABLE SPACE */
+
+		GP3_WAIT_PRIMITIVE(temp);
+	}
+
+	/* SAVE CURRENT BUFFER POINTER */
+
+	cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+	/* PREPARE FOR COMMAND BUFFER DATA WRITES             */
+	/* Pattern data is contiguous DWORDs at LUT address 0 */
+
+	WRITE_COMMAND32 (0, gp3_cmd_header);
+	WRITE_COMMAND32 (4, 0);
+	WRITE_COMMAND32 (8, (size_dwords | GP3_LUT_DATA_TYPE));	
+
+	/* WRITE ALL DATA */
+
+	WRITE_COMMAND_STRING32 (12, colors, 0, size_dwords);
+
+	/* START OPERATION */
+
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_vector_pattern
+ *
+ * This routine is called to program the hardware LUT with a vector pattern.
+ * A vector pattern is programmed as a 32-bit mask that specifies a
+ * transparency pattern.  A length parameter is used to specify patterns
+ * smaller than 32.  Note that vectors in Geode LX do not continue across corners.
+ * The beginning of each vector will always begin with bit 0 of the vector
+ * pattern.  It is the responsibility of the caller to update the pattern
+ * if an alternate behavior is desired.
+ *
+ * This routine faces the same restrictions of all routines that program
+ * the LUT, in that it must be called before any gp_declare_xxxx routines,
+ * it cannot be combined with an 8x8 color pattern, color conversion or
+ * rotation.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_vector_pattern (unsigned long pattern, unsigned long color, int length)
+{
+	unsigned long temp, mask;
+	
+	gp3_ch3_pat = 1;
+	gp3_vector_pattern_color = color;
+
+	/* CREATE SUITABLE PATTERN MASK */
+	/* The GP requires a minimum of four pixels in a vector pattern.  We */
+	/* can get around this restriction by doubling any patterns smaller  */
+	/* than 4 pixels.                                                    */
+
+	while (length < 4)
+	{
+		mask = 0xFFFFFFFF >> (32 - length);
+		pattern = (pattern << length) | (pattern & mask);
+		length <<= 1;
+	}
+	mask = 0xFFFFFFFF >> (32 - length);
+
+    gp3_vec_pat = pattern;
+
+	/* CHECK FOR WRAP AFTER LUT LOAD */
+
+	gp3_cmd_next = gp3_cmd_current + GP3_VECTOR_PATTERN_COMMAND_SIZE;
+	
+	if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+	{
+		gp3_cmd_next   = gp3_cmd_top;
+		gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_WRAP | GP3_LUT_HDR_DATA_ENABLE;
+
+		/* WAIT FOR HARDWARE           */
+		/* Same logic as BLT wrapping. */
+
+		GP3_WAIT_WRAP(temp);
+	}
+	else
+	{
+		gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE;
+
+		/* WAIT FOR AVAILABLE SPACE */
+
+		GP3_WAIT_PRIMITIVE(temp);
+	}
+
+	/* SAVE CURRENT BUFFER POINTER */
+
+	cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+	/* PREPARE FOR COMMAND BUFFER DATA WRITES      */
+	/* Pattern data is 2 DWORDs at 0x100 and 0x101 */
+
+	WRITE_COMMAND32 (0, gp3_cmd_header);
+	WRITE_COMMAND32 (4, 0x100);
+	WRITE_COMMAND32 (8, (2 | GP3_LUT_DATA_TYPE));	
+	WRITE_COMMAND32 (12, pattern);
+	WRITE_COMMAND32 (16, mask);
+
+	/* START OPERATION */
+
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_strides
+ *
+ * This routine is called to program the pitch between successive lines of
+ * data in the frame buffer.  The strides should be DWORD aligned and less
+ * than 64K.  These restrictions are not checked by the API.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_strides (unsigned long dst_stride, unsigned long src_stride)
+{
+	/* SAVE STRIDES */
+	/* The source stride may be needed later for channel 3 source data and */
+	/* we may need to use these strides in calculations.                   */
+
+	gp3_src_stride = src_stride;
+	gp3_dst_stride = dst_stride;
+
+	/* ENABLE STRIDES */
+	/* The stride register is in the same place for BLTs and vectors */
+
+	gp3_cmd_header |= GP3_BLT_HDR_STRIDE_ENABLE;
+
+	WRITE_COMMAND32 (GP3_BLT_STRIDE, ((src_stride << 16) | dst_stride));	
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_source_format
+ *
+ * This routine is used to program the format of source data used in subsequent
+ * color-conversion or rotation operations.  Note that 4BPP indexed and 8BPP
+ * indexed source formats cannot be used when rotating, as the LUT will be
+ * destroyed.  These formats also cannot be combined with an 8x8 color pattern.
+ * The supported formats mirror the hardware and are described as follows:
+ *
+ * 0  - 8BPP 3:3:2
+ * 1  - 8BPP indexed
+ * 4  - 16BPP 4:4:4:4
+ * 5  - 16BPP 1:5:5:5
+ * 6  - 16BPP 5:6:5
+ * 7  - 16BPP YUV
+ * 8  - 32BPP 8:8:8:8
+ * 13 - 4BPP indexed
+ * 20 - 16BPP 4:4:4:4 BGR
+ * 21 - 16BPP 1:5:5:5 BGR
+ * 22 - 16BPP 0:5:6:5 BGR
+ * 24 - 32BPP 8:8:8:8 BGR
+ *-------------------------------------------------------------------------*/
+
+void gp_set_source_format (int format)
+{
+	/* SAVE FORMAT */
+	/* We will combine the source format later when doing color conversion. */
+	/* We also save the pixel size for host source calculations.            */
+	/* Conveniently, the source formats are organized such that the upper   */
+	/* two bits of the nibble represent the pixel shift, with a pixel shift */
+	/* of 3 being a special case for 4BPP data.  Clever, yes?  Even more    */
+	/* clever, bit 4 indicates BGR ordering.                                */
+
+	gp3_src_pix_shift = (unsigned long)((format >> 2) & 3);
+	gp3_src_format = (((unsigned long)format & 0xF)  << 24) |
+		             (((unsigned long)format & 0x10) << 18);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_pattern_fill
+ *
+ * This routine is called to perform a simple pattern fill.  The pattern
+ * can be solid, monochrome or a preprogrammed 8x8 color pattern.  If
+ * the ROP involves source data, that source data will be constant.
+ *-------------------------------------------------------------------------*/
+
+void gp_pattern_fill (unsigned long dstoffset, unsigned long width, unsigned long height)
+{
+    unsigned long base_register;
+
+    base_register = (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK) |
+                   ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000));
+
+    /* ENABLE RELEVANT REGISTERS */
+	/* Note that we always enable and write the channel 3 mode, if only */
+	/* to turn it off.   Cimarron also always writes the base offset    */
+	/* register to allow operation with frame buffers larger than 16MB. */
+
+	gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE     |
+		              GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	/* WRITE THE REGISTERS COMMON TO ALL PATTERN TYPES */
+	/* The destination base is the frame buffer base plus whatever */
+	/* 4MB segment we happen to be BLTing to.                      */
+
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, ((width << 16) | height));
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base_register);
+	
+	/* CHECK 8X8 COLOR PATTERN CASE */
+
+	if (gp3_ch3_pat)
+	{
+		/* SET CHANNEL 3 PATTERN ORIGINS */
+
+		gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE;
+
+		/* INITIALIZE CHANNEL 3 PARAMETERS */
+
+		WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ((width << 16) | height));
+		WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset & 0x3FFFFF);
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+	}
+	else
+	{
+		/* DISABLE CHANNEL 3 AND USE NORMAL PATTERN ORIGINS */
+
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+	}
+	
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_screen_to_screen_blt
+ *
+ * This routine is called to perform a BLT from one location inside video
+ * memory to another location inside video memory.  The source and destination
+ * formats are assumed to be the current BPP.  Whenever possible, this routine
+ * tries to use channel 3 to fetch source data.  The BLT flags can affect this
+ * behavior in the following ways:
+ *   CIMGP_BLTFLAGS_PRES_COLOR_PAT
+ *      A color pattern is being stored in the channel 3 buffer.  It is either
+ *      being stored for a later BLT or being combined with the current source
+ *      data.  Channel 3 cannot be used to fetch source data or the pattern
+ *      will be overwritten.
+ *   CIMGP_BLTFLAGS_PRES_LUT
+ *      If the first flag is not set, this flag will limit the use of the
+ *      channel 3 buffer to 1K.
+ *-------------------------------------------------------------------------*/
+
+void gp_screen_to_screen_blt (unsigned long dstoffset, unsigned long srcoffset,
+	unsigned long width, unsigned long height, int flags)
+{
+	unsigned long base;
+	unsigned long ch3_flags = 0;
+	unsigned long blt_mode  = gp3_blt_mode;
+	unsigned long size = ((width << 16) | height);
+    unsigned long dstbase, srcbase;
+
+    /* CALCULATE BASE OFFSETS                                             */
+    /* We need to set the 4MB aligned base offsets before we add offsets  */
+    /* for negative BLTs.                                                 */
+
+    srcbase = srcoffset & 0xFFC00000;
+    dstbase = dstoffset & 0xFFC00000;
+    srcoffset &= 0x3FFFFF;
+    dstoffset &= 0x3FFFFF;
+
+    /* ADJUST OFFSETS BASED ON FLAGS */
+	/* We adjust the source and destination offsets to point to the first */
+	/* byte of the first pixel of the BLT.  This routine assumes that the */
+	/* source and destination regions do not wrap past the end of a 16MB  */
+	/* region.                                                            */
+
+	if (flags & CIMGP_NEGXDIR)
+	{
+		srcoffset += (width << gp3_pix_shift) - 1;
+		dstoffset += (width << gp3_pix_shift) - 1;
+		blt_mode  |= GP3_BM_NEG_XDIR;
+		ch3_flags |= GP3_CH3_NEG_XDIR;
+	}
+	if (flags & CIMGP_NEGYDIR)
+	{
+		srcoffset += (height - 1) * gp3_src_stride;
+		dstoffset += (height - 1) * gp3_dst_stride;
+		blt_mode  |= GP3_BM_NEG_YDIR;
+		ch3_flags |= GP3_CH3_NEG_YDIR;
+	}
+	
+	/* BRANCH BASED ON CHANNEL 3                                     */
+	/* If a color pattern is not being saved or used, channel 3 will */
+	/* be used to fetch source for maximum throughput.   Channel 3   */
+    /* is not used if transparency or alpha blending is enabled.     */
+
+	if (!(gp3_blt_flags & CIMGP_BLTFLAGS_PRES_COLOR_PAT) &&
+        !(gp3_raster_mode & GP3_RM_SRC_TRANS) &&
+        !(flags & CIMGP_NEGYDIR))
+	{
+		base = ((gp3_fb_base << 24) +  dstbase)        |
+		       ((gp3_fb_base << 4)  + (srcbase >> 20)) |
+                (gp3_base_register & GP3_BASE_OFFSET_SRCMASK);
+
+		gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE     |
+						  GP3_BLT_HDR_WIDHI_ENABLE       |
+						  GP3_BLT_HDR_CH3_STR_ENABLE     |
+						  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+						  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+						  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+						  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset | gp3_pat_origin));
+		WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, srcoffset);
+		WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+		WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+		WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+			  GP3_CH3_C3EN                                    |
+			  GP3_CH3_REPLACE_SOURCE                          |
+			  gp3_ch3_bpp                                     |
+			  gp3_src_stride                                  |
+			  ch3_flags                                       |
+			((gp3_blt_flags & CIMGP_ENABLE_PREFETCH)   << 17) |
+			((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+	}
+	else
+	{
+		/* CALCULATE BASE OFFSET REGISTER */
+
+		base = ((gp3_fb_base << 24) +  dstbase)        |
+		       ((gp3_fb_base << 14) + (srcbase >> 10)) |
+               (gp3_base_register & GP3_BASE_OFFSET_CH3MASK);
+
+		/* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS                */
+		/* We assume that a color pattern is being ROPed with source  */
+		/* data if the pattern type is color and the preserve pattern */
+		/* was set.                                                   */
+
+		blt_mode |= GP3_BM_SRC_FB;
+
+		gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+			              GP3_BLT_HDR_DST_OFF_ENABLE     |
+						  GP3_BLT_HDR_WIDHI_ENABLE       |
+                          GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+						  GP3_BLT_HDR_CH3_STR_ENABLE     |
+                          GP3_BLT_HDR_CH3_OFF_ENABLE     |
+						  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+						  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+		if (gp3_ch3_pat)
+		{
+			WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+			WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset);
+			WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format | ch3_flags);
+            WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+		}
+		else
+		{
+			WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset | gp3_pat_origin);
+			WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+		}
+		
+		WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, srcoffset);
+		WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+		WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+	}
+		
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_screen_to_screen_convert
+ *
+ * This routine is called to color-convert a rectangular region of the frame
+ * buffer into the current BPP. The format of the source region is programmed
+ * by gp_set_source_format.
+ *-------------------------------------------------------------------------*/
+
+void gp_screen_to_screen_convert (unsigned long dstoffset, unsigned long srcoffset,
+    unsigned long width, unsigned long height, int nibble)
+{
+	unsigned long size = ((width << 16) | height);
+	unsigned long ch3_offset = srcoffset & 0x3FFFFF;
+    unsigned long ch3_size, base;
+
+    base =  ((gp3_fb_base << 24) +  (dstoffset & 0xFFC00000))        |
+	        ((gp3_fb_base << 4)  + ((srcoffset & 0xFFC00000) >> 20)) |
+             (gp3_base_register & GP3_BASE_OFFSET_SRCMASK);
+
+	/* SET NIBBLE FOR 4BPP */
+	/* 4BPP is a special case in that it requires subpixel addressing.  The */
+	/* user must supply this information via the nibble parameter.  This    */
+	/* parameter is ignored for every other source format.                  */
+
+    ch3_size = size;
+	if (gp3_src_pix_shift == 3)
+		ch3_offset |= ((nibble & 1) << 25);
+    else if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+        ch3_size = ((((width * 3) + 3) >> 2) << 16) | height;
+
+	/* SET APPROPRIATE ENABLES */
+
+	gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE     |
+		              GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	/* WRITE ALL BLT REGISTERS */
+	
+	WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+	WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
+	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+		GP3_CH3_C3EN                                    |
+		GP3_CH3_REPLACE_SOURCE                          |
+		gp3_src_format                                  |
+	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20) |
+	  ((gp3_blt_flags & CIMGP_ENABLE_PREFETCH)   << 17) |
+	    gp3_src_stride);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+		
+	/* START THE BLT */
+
+    WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_color_bitmap_to_screen_blt
+ *
+ * This routine is called to BLT data from system memory into the frame buffer.
+ * 'srcy' is deliberately omitted to prevent extra calculations for simple
+ * applications that have no source indexes.
+ *-------------------------------------------------------------------------*/
+
+void gp_color_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+    unsigned long width, unsigned long height, unsigned char *data, long pitch)
+{
+	unsigned long indent, temp;
+	unsigned long total_dwords, size_dwords;
+	unsigned long dword_count, byte_count;
+	unsigned long size = ((width << 16) | height);
+	unsigned long srcoffset;
+		
+	/* ASSUME BITMAPS ARE DWORD ALIGNED */
+	/* We will offset into the source data in DWORD increments.  We */
+	/* set the source index to the remaining byte offset and        */
+	/* increment the size of each line to account for the dont-care */
+	/* pixel(s).                                                    */
+
+	indent    = srcx << gp3_pix_shift;
+	srcoffset = (indent & ~3L);
+	indent   &= 3;
+
+	/* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS                */
+	/* We assume that a color pattern is being ROPed with source  */
+	/* data if the pattern type is color and the preserve pattern */
+	/* was set.                                                   */
+
+	gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+		              GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	if (gp3_ch3_pat)
+	{
+		gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+		WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+        WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+	}
+	else
+	{
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+	}
+	
+	WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, indent);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET,
+		((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_HOST);
+		
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+	/* CALCULATE THE SIZE OF ONE LINE */
+
+	size = (width << gp3_pix_shift) + indent;
+	total_dwords = (size + 3) >> 2;
+	size_dwords  = (total_dwords << 2) + 8;
+	dword_count  = (size >> 2);
+	byte_count   = (size & 3);
+
+    /* CHECK FOR SMALL BLT CASE */
+
+    if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+        (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+    {
+        /* UPDATE THE COMMAND POINTER */
+
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+        /* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+	    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+            	
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+        /* WRITE DWORD COUNT */
+
+		WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+        while (height--)
+	    {
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    srcoffset += pitch;
+            cim_cmd_ptr += total_dwords << 2;
+	    }
+
+        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+    }
+    else
+    {
+	    /* WRITE DATA LINE BY LINE */
+	    /* Each line will be created as a separate command buffer entry to allow */
+	    /* line-by-line wrapping and to allow simultaneous rendering by the HW.  */
+    	
+	    while (height--)
+	    {
+		    /* UPDATE THE COMMAND POINTER */
+		    /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+		    /* This is created by adding gp3_cmd_current to the base pointer.        */
+
+		    cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		    /* CHECK IF A WRAP WILL BE NEEDED */
+
+		    gp3_cmd_next = gp3_cmd_current + size_dwords;
+		    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		    {
+			    gp3_cmd_next  = gp3_cmd_top;
+    			
+			    /* WAIT FOR HARDWARE */
+    			
+			    GP3_WAIT_WRAP(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				    GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+		    else
+		    {
+			    /* WAIT FOR AVAILABLE SPACE */
+
+			    GP3_WAIT_PRIMITIVE(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+
+		    /* WRITE DWORD COUNT */
+    		
+		    WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | total_dwords);
+
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    /* UPDATE POINTERS */
+
+		    srcoffset += pitch;
+		    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		    gp3_cmd_current = gp3_cmd_next;
+	    }
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_color_convert_blt
+ *
+ * This routine is called to convert data that is stored in system memory
+ * into the current graphics BPP.  The source format is programmed in
+ * gp_set_source_format.
+ *-------------------------------------------------------------------------*/
+
+void gp_color_convert_blt (unsigned long dstoffset, unsigned long srcx,
+    unsigned long width, unsigned long height, unsigned char *data, long pitch)
+{
+	unsigned long indent, temp;
+	unsigned long total_dwords, size_dwords;
+	unsigned long dword_count, byte_count;
+	unsigned long size = ((width << 16) | height);
+    unsigned long ch3_size;
+	unsigned long ch3_offset, srcoffset;
+    unsigned long base;
+		
+	/* ASSUME BITMAPS ARE DWORD ALIGNED */
+	/* We will offset into the source data in DWORD increments.  We  */
+	/* set the source index to the remaining byte offset and         */
+	/* increment the size of each line to account for the dont-care  */
+	/* pixel(s).   For 4BPP source data, we also set the appropriate */
+	/* nibble index.                                                 */
+	
+    /* CALCULATE THE SIZE OF ONE LINE */
+
+    if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+    {
+        /* HANDLE 24BPP */
+        /* Note that we do not do anything to guarantee that the source data        */
+        /* is DWORD aligned.  The logic here is that the source data will be        */
+        /* cacheable, in which case Geode LX will not lose any clocks for unaligned */
+        /* moves.  Also note that the channel 3 width is programmed as the          */
+        /* number of dwords, while the normal width is programmed as the number     */
+        /* of pixels.                                                               */
+
+        srcoffset  = srcx * 3;
+        ch3_offset = 0;
+        temp       = width * 3;
+        ch3_size   = (((temp + 3) >> 2) << 16) | height;
+    }
+    else
+    {
+        ch3_size = size;
+
+	    if (gp3_src_pix_shift == 3)
+	    {
+		    /* CALCULATE INDENT AND SOURCE OFFSET */
+
+		    indent     = (srcx >> 1);
+		    srcoffset  = (indent & ~3L);
+		    indent    &= 3;
+		    ch3_offset = indent | ((srcx & 1) << 25);
+
+		    temp = ((width + (srcx & 1) + 1) >> 1) + indent;
+	    }
+	    else
+	    {
+		    indent     = (srcx << gp3_src_pix_shift);
+		    srcoffset  = (indent & ~3L);
+		    indent    &= 3;
+		    ch3_offset = indent;
+
+		    temp = (width << gp3_src_pix_shift) + indent;
+	    }
+    }
+
+	total_dwords = (temp + 3) >> 2;
+	size_dwords  = (total_dwords << 2) + 8;
+	dword_count  = (temp >> 2);
+	byte_count   = (temp & 3);
+
+    base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+            (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+	/* SET APPROPRIATE ENABLES */
+
+	gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
+	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+	WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+		GP3_CH3_C3EN           |
+		GP3_CH3_REPLACE_SOURCE |
+		GP3_CH3_HST_SRC_ENABLE |
+		gp3_src_format         |
+	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+    if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+        (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+    {
+        /* UPDATE THE COMMAND POINTER */
+
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+        /* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+	    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+            	
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+        /* WRITE DWORD COUNT */
+
+		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+        while (height--)
+	    {
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    srcoffset += pitch;
+            cim_cmd_ptr += total_dwords << 2;
+	    }
+
+        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+    }
+    else
+    {
+	    /* WRITE DATA LINE BY LINE */
+	    /* Each line will be created as a separate command buffer entry to allow */
+	    /* line-by-line wrapping and to allow simultaneous rendering by the HW.  */
+    	
+	    while (height--)
+	    {
+		    /* UPDATE THE COMMAND POINTER */
+		    /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+		    /* This is created by adding gp3_cmd_current to the base pointer.        */
+
+		    cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		    /* CHECK IF A WRAP WILL BE NEEDED */
+
+		    gp3_cmd_next = gp3_cmd_current + size_dwords;
+		    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		    {
+			    gp3_cmd_next  = gp3_cmd_top;
+    			
+			    /* WAIT FOR HARDWARE */
+    			
+			    GP3_WAIT_WRAP(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				    GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+		    else
+		    {
+			    /* WAIT FOR AVAILABLE SPACE */
+
+			    GP3_WAIT_PRIMITIVE(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+
+		    /* WRITE DWORD COUNT */
+    		
+		    WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    /* UPDATE POINTERS */
+
+		    srcoffset += pitch;
+		    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		    gp3_cmd_current = gp3_cmd_next;
+	    }
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_custom_convert_blt
+ *
+ * This routine is identical to gp_color_convert_blt, except that the macro
+ * to write data to the frame buffer has been replaced with a new macro.  This
+ * allows a user to implement custom behavior when sending data, such as manually
+ * converting 24BPP to 32BPP, converting 2BPP to 4BPP or premultiplying alpha data.
+ *-------------------------------------------------------------------------*/
+
+void gp_custom_convert_blt (unsigned long dstoffset, unsigned long srcx,
+    unsigned long width, unsigned long height, unsigned char *data, long pitch)
+{
+	unsigned long indent, temp;
+	unsigned long total_dwords, size_dwords;
+	unsigned long dword_count, byte_count;
+	unsigned long size = ((width << 16) | height);
+	unsigned long ch3_offset, srcoffset;
+    unsigned long ch3_size, base;
+		
+	/* ASSUME BITMAPS ARE DWORD ALIGNED */
+	/* We will offset into the source data in DWORD increments.  We  */
+	/* set the source index to the remaining byte offset and         */
+	/* increment the size of each line to account for the dont-care  */
+	/* pixel(s).   For 4BPP source data, we also set the appropriate */
+	/* nibble index.                                                 */
+	
+    /* CALCULATE THE SIZE OF ONE LINE */
+
+    if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+    {
+        /* HANDLE 24BPP */
+        /* Note that we do not do anything to guarantee that the source data      */
+        /* is DWORD aligned.  The logic here is that the source data will be      */
+        /* cacheable, in which case Geode LX will not lose any clocks for unaligned */
+        /* moves.  Also note that the channel 3 width is programmed as the        */
+        /* number of dwords, while the normal width is programmed as the number   */
+        /* of pixels.                                                             */
+
+        srcoffset  = srcx * 3;
+        ch3_offset = 0;
+        temp       = width * 3;
+        ch3_size   = (((temp + 3) >> 2) << 16) | height;
+    }
+    else
+    {
+        ch3_size = size;
+
+	    if (gp3_src_pix_shift == 3)
+	    {
+		    /* CALCULATE INDENT AND SOURCE OFFSET */
+
+		    indent     = (srcx >> 1);
+		    srcoffset  = (indent & ~3L);
+		    indent    &= 3;
+		    ch3_offset = indent | ((srcx & 1) << 25);
+
+		    temp = ((width + (srcx & 1) + 1) >> 1) + indent;
+	    }
+	    else
+	    {
+		    indent     = (srcx << gp3_src_pix_shift);
+		    srcoffset  = (indent & ~3L);
+		    indent    &= 3;
+		    ch3_offset = indent;
+
+		    temp = (width << gp3_src_pix_shift) + indent;
+	    }
+    }
+
+	total_dwords = (temp + 3) >> 2;
+	size_dwords  = (total_dwords << 2) + 8;
+	dword_count  = (temp >> 2);
+	byte_count   = (temp & 3);
+
+    base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+           (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+	/* SET APPROPRIATE ENABLES */
+
+	gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
+	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+	WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+		GP3_CH3_C3EN           |
+		GP3_CH3_REPLACE_SOURCE |
+		GP3_CH3_HST_SRC_ENABLE |
+		gp3_src_format         |
+	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+    if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+        (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+    {
+        /* UPDATE THE COMMAND POINTER */
+
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+        /* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+	    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+            	
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+        /* WRITE DWORD COUNT */
+
+		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+        while (height--)
+	    {
+		    /* WRITE DATA */
+
+		    WRITE_CUSTOM_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_CUSTOM_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    srcoffset += pitch;
+            cim_cmd_ptr += total_dwords << 2;
+	    }
+
+        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+    }
+    else
+    {
+	    /* WRITE DATA LINE BY LINE */
+	    /* Each line will be created as a separate command buffer entry to allow */
+	    /* line-by-line wrapping and to allow simultaneous rendering by the HW.  */
+    	
+	    while (height--)
+	    {
+		    /* UPDATE THE COMMAND POINTER */
+		    /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+		    /* This is created by adding gp3_cmd_current to the base pointer.        */
+
+		    cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		    /* CHECK IF A WRAP WILL BE NEEDED */
+
+		    gp3_cmd_next = gp3_cmd_current + size_dwords;
+		    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		    {
+			    gp3_cmd_next  = gp3_cmd_top;
+    			
+			    /* WAIT FOR HARDWARE */
+    			
+			    GP3_WAIT_WRAP(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				    GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+		    else
+		    {
+			    /* WAIT FOR AVAILABLE SPACE */
+
+			    GP3_WAIT_PRIMITIVE(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+
+		    /* WRITE DWORD COUNT */
+    		
+		    WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+		    /* WRITE DATA */
+
+		    WRITE_CUSTOM_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_CUSTOM_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    /* UPDATE POINTERS */
+
+		    srcoffset += pitch;
+		    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		    gp3_cmd_current = gp3_cmd_next;
+	    }
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_rotate_blt
+ *
+ * This routine is called to rotate a rectangular area of video memory.  The
+ * data may be color converted during the rotation.  'Degrees' must be a
+ * multiple of 90 and indicates a clockwise rotation.  Width and height
+ * refer to the width and the height of the source.  The output
+ * destinations will be equal to the rotated dimensions.
+ *-------------------------------------------------------------------------*/
+
+void gp_rotate_blt (unsigned long dstoffset, unsigned long srcoffset,
+	unsigned long width, unsigned long height, int degrees)
+{
+	unsigned long sizein, sizeout;
+	unsigned long ch3_flags;
+    unsigned long base;
+
+    base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000))         |
+	       ((gp3_fb_base << 4)  + ((srcoffset & 0xFFC00000) >> 20)) |
+            (gp3_base_register & GP3_BASE_OFFSET_SRCMASK);
+
+    srcoffset &= 0x3FFFFF;
+    dstoffset &= 0x3FFFFF;
+
+	/* SET ROTATION PARAMETERS */
+
+	switch (degrees)
+	{
+		case 90:
+			srcoffset += (height - 1) * gp3_src_stride;
+			sizein     = ((width  << 16) | height);
+			sizeout    = ((height << 16) | width);
+			ch3_flags  = GP3_CH3_C3EN           |
+				         GP3_CH3_REPLACE_SOURCE |
+						 GP3_CH3_ROTATE_ENABLE  |
+						 GP3_CH3_NEG_YDIR;	
+			break;
+
+		case 180:
+			srcoffset += (height - 1) * gp3_src_stride;
+			srcoffset += (width << gp3_src_pix_shift) - 1;
+			sizein     = sizeout = ((width  << 16) | height);
+			ch3_flags  = GP3_CH3_C3EN           |
+				         GP3_CH3_REPLACE_SOURCE |
+						 GP3_CH3_NEG_YDIR       |
+						 GP3_CH3_NEG_XDIR;	
+			break;
+
+		case 270:
+			srcoffset +=  (width << gp3_src_pix_shift) - 1;
+			sizein     = ((width  << 16) | height);
+			sizeout    = ((height << 16) | width);
+			ch3_flags  = GP3_CH3_C3EN           |
+				         GP3_CH3_REPLACE_SOURCE |
+						 GP3_CH3_ROTATE_ENABLE  |
+						 GP3_CH3_NEG_XDIR;	
+			break;
+
+		default:
+			sizein     = sizeout = ((width  << 16) | height);
+			ch3_flags  = GP3_CH3_C3EN |
+				         GP3_CH3_REPLACE_SOURCE;
+			break;		
+	}
+
+	/* SET APPROPRIATE ENABLES                           */
+	/* We override the raster mode setting with a source */
+	/* copy ROP.                                         */
+
+	gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE      |
+		              GP3_BLT_HDR_DST_OFF_ENABLE     |
+		              GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	/* WRITE ALL BLT REGISTERS */
+	
+	WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_bpp | 0xCC);
+	WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, sizeout);
+	WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, sizein);
+	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, srcoffset);
+	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+		ch3_flags                                       |
+		gp3_src_format                                  |
+	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20) |
+	  ((gp3_blt_flags & CIMGP_ENABLE_PREFETCH)   << 17) |
+	    gp3_src_stride);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_mono_bitmap_to_screen_blt
+ *
+ * This routine expands and BLTs a monchrome bitmap that is stored in system
+ * memory into the framebuffer.  'data' points to an array of monochrome data.
+ * 'stride' indicates the pitch between successive lines of monochrome data.
+ * 'srcx' indicates the x coordinate within each line of blend data
+ * corresponding to the first pixel.  A y coordinate for the source is
+ * deliberately omitted to avoid extra calculation for simple cases that have
+ * no y index.  The calling program must adjust the data pointer accordingly.
+ *-------------------------------------------------------------------------*/
+
+void gp_mono_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+	unsigned long width, unsigned long height, unsigned char *data, long stride)
+{
+	unsigned long indent, temp;
+	unsigned long total_dwords, size_dwords;
+	unsigned long dword_count, byte_count;
+	unsigned long size = ((width << 16) | height);
+	unsigned long srcoffset, src_value;
+
+    /* ASSUME BITMAPS ARE DWORD ALIGNED */
+	/* We will offset into the source data in DWORD increments.  We */
+	/* set the source index to the remaining byte offset and        */
+	/* increment the size of each line to account for the dont-care */
+	/* pixel(s).                                                    */
+
+	indent    = (srcx >> 3);
+	srcoffset = (indent & ~3L);
+	indent   &= 3;
+	src_value = (indent | ((srcx & 7) << 26));
+
+    /* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS                */
+	/* We assume that a color pattern is being ROPed with source  */
+	/* data if the pattern type is color and the preserve pattern */
+	/* was set.                                                   */
+
+	gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+		              GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+                      GP3_BLT_HDR_RASTER_ENABLE      |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+    if (gp3_ch3_pat)
+	{
+		gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+		WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+        WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+	}
+	else
+	{
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+	}
+    if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+    {    
+        WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode | GP3_RM_SOURCE_INVERT);
+    }
+    else
+    {
+        WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode & ~GP3_RM_SOURCE_INVERT);
+    }
+	WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, src_value);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET,
+		((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_HOST | GP3_BM_SRC_MONO);
+		
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+	/* CALCULATE THE SIZE OF ONE LINE */
+
+	size = ((width + (srcx & 7) + 7) >> 3) + indent;
+	total_dwords = (size + 3) >> 2;
+	size_dwords  = (total_dwords << 2) + 8;
+	dword_count  = (size >> 2);
+	byte_count   = (size & 3);
+
+    /* CHECK FOR SMALL BLT CASE */
+    /* If the total amount of monochrome data is less than 50K and we have */
+    /* room in the command buffer, we will do all data writes in a single  */
+    /* data packet.                                                        */
+
+    if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+        (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+    {
+        /* UPDATE THE COMMAND POINTER */
+
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+        /* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+	    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+        	        	
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+        /* WRITE DWORD COUNT */
+        	
+		WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+        while (height--)
+	    {
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    srcoffset += stride;
+            cim_cmd_ptr += total_dwords << 2;
+	    }
+
+        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+    }
+    else
+    {
+	    /* WRITE DATA LINE BY LINE */
+	    /* Each line will be created as a separate command buffer entry to allow */
+	    /* line-by-line wrapping and to allow simultaneous rendering by the HW.  */
+    	
+	    while (height--)
+	    {
+		    /* UPDATE THE COMMAND POINTER */
+		    /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+		    /* This is created by adding gp3_cmd_current to the base pointer.        */
+
+		    cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		    /* CHECK IF A WRAP WILL BE NEEDED */
+
+		    gp3_cmd_next = gp3_cmd_current + size_dwords;
+		    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		    {
+			    gp3_cmd_next  = gp3_cmd_top;
+    			
+			    /* WAIT FOR HARDWARE */
+    			
+			    GP3_WAIT_WRAP(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				    GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+		    else
+		    {
+			    /* WAIT FOR AVAILABLE SPACE */
+
+			    GP3_WAIT_PRIMITIVE(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+
+		    /* WRITE DWORD COUNT */
+    		
+		    WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | total_dwords);
+
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    /* UPDATE POINTERS */
+
+		    srcoffset += stride;
+		    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		    gp3_cmd_current = gp3_cmd_next;
+        }
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_text_blt
+ *
+ * This routine expands and BLTs byte-packed monochrome data to the screen.
+ * There is assumed to be no x clipping involved in the BLT.
+ *-------------------------------------------------------------------------*/
+
+void gp_text_blt (unsigned long dstoffset, unsigned long width,
+	unsigned long height, unsigned char *data)
+{
+	unsigned long temp, dwords_total;
+	unsigned long dword_count, byte_count;
+	unsigned long size = ((width << 16) | height);
+    unsigned long srcoffset = 0;
+
+	/* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS                */
+	/* We assume that a color pattern is being ROPed with source  */
+	/* data if the pattern type is color and the preserve pattern */
+	/* was set.                                                   */
+
+	gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+		              GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+                      GP3_BLT_HDR_RASTER_ENABLE      |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+    if (gp3_ch3_pat)
+	{
+		gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+		WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+        WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+	}
+	else
+	{
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+	}
+    if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+    {    
+        WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode | GP3_RM_SOURCE_INVERT);
+    }
+    else
+    {
+        WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode & ~GP3_RM_SOURCE_INVERT);
+    }
+	
+	WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, 0);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET,
+		((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_HOST | GP3_BM_SRC_BP_MONO);
+		
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+	/* CALCULATE THE TOTAL NUMBER OF BYTES */
+
+	size = ((width + 7) >> 3) * height;
+
+	/* WRITE ALL DATA IN CHUNKS */
+
+	do
+	{
+		/* UPDATE THE COMMAND POINTER */
+	
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		if (size > 8192)
+		{
+			dword_count = 2048;
+			byte_count  = 0;
+			dwords_total = 2048;
+			size -= 8192;
+		}
+		else
+		{
+			dword_count = (size >> 2);
+			byte_count  = (size & 3);
+			dwords_total = (size + 3) >> 2;
+			size = 0;
+		}
+		gp3_cmd_next = gp3_cmd_current + (dwords_total << 2) + 8;
+
+		/* CHECK IF A WRAP WILL BE NEEDED */
+
+		if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+				
+			/* WAIT FOR HARDWARE */
+				
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			/* WAIT FOR AVAILABLE SPACE */
+
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+		/* WRITE DWORD COUNT */
+		
+		WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | dwords_total);
+
+		/* WRITE DATA */
+
+		WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			srcoffset + (dword_count << 2), byte_count);
+
+		WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+	
+        /* UPDATE THE SOURCE OFFSET */
+        /* We add a constant value because the code will loop only if the */
+        /* data exceeds 8192 bytes.                                       */
+
+        srcoffset += 8192;
+
+    } while (size);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_mono_expand_blt
+ *
+ * This routine expands monochrome data that is stored in video memory into
+ * the current BPP.  The source and destination regions are assumed not to
+ * overlap.  The pitch of the source data is specified in gp_set_strides.
+ * 'srcy' is deliberately omitted to prevent extra calculations for simple
+ * applications that have no source indexes.
+ *-------------------------------------------------------------------------*/
+
+void gp_mono_expand_blt (unsigned long dstoffset, unsigned long srcoffset,
+    unsigned long srcx, unsigned long width, unsigned long height, int byte_packed)
+{
+	unsigned long base;
+	unsigned long blt_mode;
+	unsigned long size = ((width << 16) | height);
+
+	/* ADJUST SOURCE OFFSET */
+
+	srcoffset += (srcx >> 3);
+    srcx &= 7;
+
+	/* CALCULATE BASE OFFSET REGISTER */
+
+	base = ((gp3_fb_base << 24) +  (dstoffset & 0xFFC00000))        |
+	       ((gp3_fb_base << 14) + ((srcoffset & 0xFFC00000) >> 10)) |
+            (gp3_base_register & GP3_BASE_OFFSET_CH3MASK);
+
+	/* SET THE SOURCE TYPE */
+
+	if (byte_packed)
+        blt_mode = gp3_blt_mode | GP3_BM_SRC_FB | GP3_BM_SRC_BP_MONO;
+	else
+		blt_mode = gp3_blt_mode | GP3_BM_SRC_FB | GP3_BM_SRC_MONO;
+
+	/* SET HEADER ENABLES */
+
+	gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+			          GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+                      GP3_BLT_HDR_RASTER_ENABLE      |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	/* ENABLE COLOR PATTERN IF APPLICABLE */
+
+    if (gp3_ch3_pat)
+	{
+		gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+		WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+        WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+	}
+	else
+	{
+		WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+		WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+	}
+    if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+    {    
+        WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode | GP3_RM_SOURCE_INVERT);
+    }
+    else
+    {
+        WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode & ~GP3_RM_SOURCE_INVERT);
+    }
+
+    WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);	
+	WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET,
+		(srcoffset & 0x3FFFFF) | (srcx << 26));
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+			
+    /* WORKAROUND FOR SIBZ #3744 */
+    /* Under extremely rare conditions, very narrow byte-packed mono BLTs can hang  */
+    /* the GP.  Even under the rare case, the bad condition will only happen        */
+    /* once every 16 lines.  The workaround is to break the offending BLT into a    */
+    /* a series of safer BLTs.  This method is preferred over a two-pass approach   */
+    /* because it does not require saving and restoring any GP state, such as the   */
+    /* ROP or mono colors.                                                          */
+
+    if ((gp3_blt_mode & GP3_BM_DST_REQ) && byte_packed && (gp3_pix_shift < 2) &&
+        (width < 5) && ((srcoffset & 0x1F) == 0x1F) && ((srcx + width) > 8))
+    {
+        unsigned long dstoff1, size1, org1;
+        unsigned long dstoff2, size2, org2;
+        unsigned long tempheight;
+
+        size1 = ((8 - srcx) << 16) | 1;
+        size2 = ((width + srcx - 8) << 16) | 1;
+        org1  = gp3_pat_origin;
+        org2  = (org1 & 0xE0000000) | ((org1 + ((8 - srcx) << 26)) & 0x1C000000);
+        dstoff1 = dstoffset & 0x3FFFFF;
+        dstoff2 = (dstoff1 + 8 - srcx) << gp3_pix_shift;
+
+        while (height)
+        {
+            /* DIVIDE THE FIRST LINE INTO TWO SINGLE LINE BLTS */
+
+            WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size1);
+            WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI,  size1);
+            WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, (srcoffset & 0x3FFFFF) | (srcx << 26));
+            WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoff1 | org1);
+            WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, org1);
+            WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	        WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+	        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	        gp3_cmd_current = gp3_cmd_next;
+            gp_wait_until_idle();
+
+            gp_declare_blt (gp3_blt_flags);
+            gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+			                  GP3_BLT_HDR_DST_OFF_ENABLE     |
+					          GP3_BLT_HDR_WIDHI_ENABLE       |
+					          GP3_BLT_HDR_BLT_MODE_ENABLE    |
+                              GP3_BLT_HDR_CH3_OFF_ENABLE     |
+                              GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+            WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size2);
+            WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI,  size2);
+            WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, ((srcoffset + 1) & 0x3FFFFF));
+            WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoff2 | org2);
+            WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, org2);
+            WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	        WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+	        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	        gp3_cmd_current = gp3_cmd_next;
+            gp_wait_until_idle();
+
+            if (--height)
+            {
+                org1 += 0x20000000;
+                org2 += 0x20000000;
+                dstoff1 += gp3_dst_stride;
+                dstoff2 += gp3_dst_stride;
+                srcoffset += 2;
+
+                /* THE NEXT 15 LINES ARE NOW 'SAFE' - THEY DO NOT SHOW THE PROBLEM */
+
+                tempheight = 15;
+                if (tempheight > height)
+                    tempheight = height;
+
+                gp_declare_blt (gp3_blt_flags);
+                gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+			                    GP3_BLT_HDR_DST_OFF_ENABLE     |
+					            GP3_BLT_HDR_WIDHI_ENABLE       |
+					            GP3_BLT_HDR_BLT_MODE_ENABLE    |
+                                GP3_BLT_HDR_CH3_OFF_ENABLE     |
+                                GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+                WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (width << 16) | tempheight);
+                WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI,  (width << 16) | tempheight);
+                WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, (srcoffset & 0x3FFFFF) | (srcx << 26));
+                WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoff1 | org1);
+                WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, org1);
+                WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	            WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+	            WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	            gp3_cmd_current = gp3_cmd_next;
+                gp_wait_until_idle();
+
+                height -= tempheight;
+
+                if (height)
+                {
+                    gp_declare_blt (gp3_blt_flags);
+                    gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE     |
+			                        GP3_BLT_HDR_DST_OFF_ENABLE     |
+					                GP3_BLT_HDR_WIDHI_ENABLE       |
+					                GP3_BLT_HDR_BLT_MODE_ENABLE    |
+                                    GP3_BLT_HDR_CH3_OFF_ENABLE     |
+                                    GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+                    /* ADJUST ORIGIN */
+                    /* If we get here, we added a full 15 lines which is equivalent */
+                    /* to subtracting one from the pattern y origin (adding 15).    */
+
+                    org1 -= 0x20000000;
+                    org2 -= 0x20000000;
+                    dstoff1 += (gp3_dst_stride * 15);
+                    dstoff2 += (gp3_dst_stride * 15);
+                    srcoffset += 30;
+                }
+            }
+        }
+        return;
+    }
+
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_antialiased_text
+ *
+ * This routine implements alpha blending between a constant source color and
+ * a destination region.  The degree of the blend is controlled by an array
+ * of 4BPP/8BPP values specified in 'data'.  'stride' indicates the pitch between
+ * successive lines of blend data.  'srcx' indicates the x coordinate within
+ * each line of blend data corresponding to the first pixel.  A y coordinate
+ * for the source is deliberately omitted to avoid extra calculation for simple
+ * cases that have no y index.  The calling program must adjust the data
+ * pointer accordingly.  'fourbpp' selects between 4BPP and 8BPP alpha.
+ *-------------------------------------------------------------------------*/
+
+void gp_antialiased_text (unsigned long dstoffset, unsigned long srcx,
+	unsigned long width, unsigned long height, unsigned char *data, long stride,
+	int fourbpp)
+{
+	unsigned long indent, temp;
+	unsigned long total_dwords, size_dwords;
+	unsigned long dword_count, byte_count;
+	unsigned long size = ((width << 16) | height);
+	unsigned long ch3_offset, srcoffset;
+    unsigned long base, depth_flag;
+
+    base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+            (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+	/* ENABLE ALL RELEVANT REGISTERS */
+	/* We override the raster mode register to force the */
+	/* correct alpha blend                               */
+
+	gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE      |
+		              GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+	/* CALCULATIONS BASED ON ALPHA DEPTH */
+	/* Although most antialiased text is 4BPP, the hardware supports */
+	/* a full 8BPP.  Either case is supported by this routine.       */
+
+	if (fourbpp)
+	{
+        depth_flag = GP3_CH3_SRC_4BPP_ALPHA;
+		indent     = (srcx >> 1);
+		srcoffset  = (indent & ~3L);
+		indent    &= 3;
+		ch3_offset = indent | ((srcx & 1) << 25);
+
+		temp = ((width + (srcx & 1) + 1) >> 1) + indent;
+	}
+	else
+	{
+        depth_flag  = GP3_CH3_SRC_8BPP_ALPHA;
+		indent     =  srcx;
+		srcoffset  = (indent & ~3L);
+		indent    &= 3;
+		ch3_offset = indent;
+
+		temp = width + indent;
+	}
+
+	total_dwords = (temp + 3) >> 2;
+	size_dwords  = (total_dwords << 2) + 8;
+	dword_count  = (temp >> 2);
+	byte_count   = (temp & 3);
+
+	/* SET RASTER MODE REGISTER */
+	/* Alpha blending will only apply to RGB when no alpha component is present. */
+	/* As 8BPP is not supported for this routine, the only alpha-less mode is    */
+	/* 5:6:5.                                                                    */
+
+	if (gp3_bpp == GP3_RM_BPPFMT_565)
+	{
+		WRITE_COMMAND32 (GP3_BLT_RASTER_MODE,
+			gp3_bpp                    |
+			GP3_RM_ALPHA_TO_RGB        |
+			GP3_RM_ALPHA_A_PLUS_BETA_B |
+			GP3_RM_SELECT_ALPHA_CHAN_3);
+	}
+	else
+	{
+		WRITE_COMMAND32 (GP3_BLT_RASTER_MODE,
+			gp3_bpp                    |
+			GP3_RM_ALPHA_ALL           |
+			GP3_RM_ALPHA_A_PLUS_BETA_B |
+			GP3_RM_SELECT_ALPHA_CHAN_3);
+	}
+
+	/* WRITE ALL REMAINING REGISTERS */
+
+	WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+	WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+		GP3_CH3_C3EN           |
+		GP3_CH3_HST_SRC_ENABLE |
+		depth_flag             |
+	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_DST_REQ);
+
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+	/* WRITE DATA LINE BY LINE */
+	/* Each line will be created as a separate command buffer entry to allow */
+	/* line-by-line wrapping and to allow simultaneous rendering by the HW.  */
+	
+    if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+        (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+    {
+        /* UPDATE THE COMMAND POINTER */
+
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+        /* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+	    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+        	        	
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+        /* WRITE DWORD COUNT */
+        	
+		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+        while (height--)
+	    {
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    srcoffset += stride;
+            cim_cmd_ptr += total_dwords << 2;
+	    }
+
+        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+    }
+    else
+    {
+	    while (height--)
+	    {
+		    /* UPDATE THE COMMAND POINTER */
+		    /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+		    /* This is created by adding gp3_cmd_current to the base pointer.        */
+
+		    cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		    /* CHECK IF A WRAP WILL BE NEEDED */
+
+		    gp3_cmd_next = gp3_cmd_current + size_dwords;
+		    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		    {
+			    gp3_cmd_next  = gp3_cmd_top;
+			
+			    /* WAIT FOR HARDWARE */
+			
+			    GP3_WAIT_WRAP(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				    GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+		    else
+		    {
+			    /* WAIT FOR AVAILABLE SPACE */
+
+			    GP3_WAIT_PRIMITIVE(temp);
+			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		    }
+
+		    /* WRITE DWORD COUNT */
+		
+		    WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+		    /* WRITE DATA */
+
+		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+			    srcoffset + (dword_count << 2), byte_count);
+
+		    /* UPDATE POINTERS */
+
+		    srcoffset += stride;
+		    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		    gp3_cmd_current = gp3_cmd_next;
+	    }
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_masked_blt
+ *
+ * This routine copies source data to the screen.  A monochrome mask is used
+ * to specify source transparency.
+ *-------------------------------------------------------------------------*/
+
+void gp_masked_blt (unsigned long dstoffset, unsigned long width,
+	unsigned long height, unsigned long mono_srcx, unsigned long color_srcx,
+	unsigned char *mono_mask, unsigned char *color_data, long mono_pitch,
+	long color_pitch)
+{
+    unsigned long indent, temp;
+	unsigned long total_dwords, size_dwords;
+	unsigned long dword_count, byte_count;
+	unsigned long srcoffset, size;
+    unsigned long i, ch3_offset, base;
+    unsigned long flags = 0;
+
+    if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+        flags = GP3_RM_SOURCE_INVERT;
+
+    /* MONO CALCULATIONS */
+
+    indent    = (mono_srcx >> 3);
+	srcoffset = (indent & ~3L);
+	indent   &= 3;
+
+    size = ((width + (mono_srcx & 7) + 7) >> 3) + indent;
+	total_dwords = (size + 3) >> 2;
+	size_dwords  = (total_dwords << 2) + 8;
+	dword_count  = (size >> 2);
+	byte_count   = (size & 3);
+	
+    base = ((gp3_fb_base << 24) + (gp3_scratch_base & 0xFFC00000)) |
+            (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+    gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE      |
+                      GP3_BLT_HDR_STRIDE_ENABLE      |
+                      GP3_BLT_HDR_DST_OFF_ENABLE     |
+                      GP3_BLT_HDR_WIDHI_ENABLE       |
+                      GP3_BLT_HDR_CH3_STR_ENABLE     |
+                      GP3_BLT_HDR_CH3_OFF_ENABLE     |
+                      GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+                      GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+                      GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+    WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, GP3_RM_BPPFMT_8888 | 0xCC);
+    WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 2));
+    WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, gp3_scratch_base & 0x3FFFFF);
+    WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (total_dwords << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (total_dwords << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, 0);
+    WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+    WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+        GP3_CH3_C3EN           |
+		GP3_CH3_REPLACE_SOURCE |
+		GP3_CH3_HST_SRC_ENABLE |
+        GP3_CH3_SRC_8_8_8_8    |
+      ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+    WRITE_COMMAND32 (GP3_BLT_MODE, 0);
+    WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+
+    /* START THE BLT */
+
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+    for (i = 0; i < height; i++)
+	{
+		/* UPDATE THE COMMAND POINTER */
+		/* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+		/* This is created by adding gp3_cmd_current to the base pointer.        */
+
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		/* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + size_dwords;
+		if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+    		
+			/* WAIT FOR HARDWARE */
+    		
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			/* WAIT FOR AVAILABLE SPACE */
+
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+		/* WRITE DWORD COUNT */
+    	
+		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+		/* WRITE DATA */
+
+		WRITE_COMMAND_STRING32 (8, mono_mask, srcoffset, dword_count);
+		WRITE_COMMAND_STRING8 (8 + (dword_count << 2), mono_mask,
+			srcoffset + (dword_count << 2), byte_count);
+
+		/* UPDATE POINTERS */
+
+		srcoffset += mono_pitch;
+		WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+	}
+
+    /* SECOND BLT */
+
+    gp_declare_blt (gp3_blt_flags | CIMGP_BLTFLAGS_HAZARD);
+
+    base = ((gp3_fb_base << 24) +  (dstoffset & 0xFFC00000))                          |
+	       ((gp3_fb_base << 14) + (((gp3_scratch_base + indent) & 0xFFC00000) >> 10)) |
+            (gp3_base_register & GP3_BASE_OFFSET_CH3MASK);
+
+    gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE      |
+                      GP3_BLT_HDR_STRIDE_ENABLE      |
+		              GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_SRC_OFF_ENABLE     |
+		              GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+    /* ENABLE TRANSPARENCY AND PATTERN COPY ROP */
+    /* The monochrome data is used as a mask but is otherwise not involved in */
+    /* the BLT.  The color data is routed through the pattern channel.        */
+
+    WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_bpp | 0xF0 | GP3_RM_SRC_TRANS | flags);
+    WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 18) | gp3_dst_stride);
+    WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset & 0x3FFFFF);
+    WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET,
+		((gp3_scratch_base + indent) & 0x3FFFFF ) | ((mono_srcx & 7) << 26));
+    WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (width << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI,  (width << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+
+    /* PROGRAM PARAMETERS FOR COLOR SOURCE DATA        */
+	/* Data may be color converted along the way.      */
+	
+	if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+    {
+        srcoffset  = color_srcx * 3;
+        ch3_offset = 0;
+        size       = width * 3;
+
+        WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (((size + 3) >> 2) << 16) | height);
+    }
+    else if (gp3_src_pix_shift == 3)
+	{
+		/* CALCULATE INDENT AND SOURCE OFFSET */
+
+		indent       = (color_srcx >> 1);
+		srcoffset    = (indent & ~3L);
+		indent      &= 3;
+		ch3_offset   = indent | ((color_srcx & 1) << 25);
+
+		size = ((width + (color_srcx & 1) + 1) >> 1) + indent;
+	}
+	else
+	{
+		indent      = (color_srcx << gp3_src_pix_shift);
+		srcoffset   = (indent & ~3L);
+		indent     &= 3;
+		ch3_offset  = indent;
+
+		size = (width << gp3_src_pix_shift) + indent;
+	}
+
+    total_dwords  = (size + 3) >> 2;
+	size_dwords   = (total_dwords << 2) + 8;
+	dword_count   = (size >> 2);
+	byte_count    = (size & 3);
+
+	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+		GP3_CH3_C3EN            |
+		GP3_CH3_HST_SRC_ENABLE  |
+		gp3_src_format          |
+	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_MONO | GP3_BM_SRC_FB);
+
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+	/* WRITE DATA LINE BY LINE */
+		
+	while (height--)
+	{
+		/* UPDATE THE COMMAND POINTER */
+		
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		/* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + size_dwords;
+		if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+						
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+		/* WRITE DWORD COUNT */
+		
+		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+		/* WRITE COLOR DATA TO THE COMMAND BUFFER */
+
+		WRITE_COMMAND_STRING32 (8, color_data, srcoffset, dword_count);
+		WRITE_COMMAND_STRING8 (8 + (dword_count << 2), color_data,
+			srcoffset + (dword_count << 2), byte_count);
+
+		/* UPDATE COMMAND BUFFER POINTERS */
+		/* We do this before writing the monochrome data because otherwise */
+		/* the GP could throttle the writes to the host source register    */
+		/* waiting for color data.  If the command buffer has not been     */
+		/* updated to load the color data...                               */
+
+		srcoffset += color_pitch;
+		WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_screen_to_screen_masked
+ *
+ * This routine performs a screen to screen BLT, using a monochrome mask to
+ * specify source transparency.  The source data is assumed to be in the
+ * current destination format and to not overlap the destination.
+ *-------------------------------------------------------------------------*/
+
+void gp_screen_to_screen_masked (unsigned long dstoffset, unsigned long srcoffset,
+    unsigned long width, unsigned long height, unsigned long mono_srcx,
+    unsigned char *mono_mask, long mono_pitch)
+{
+    unsigned long indent, temp;
+	unsigned long total_dwords, size_dwords;
+	unsigned long dword_count, byte_count;
+	unsigned long srcoff, size;
+    unsigned long i, base;
+    unsigned long flags = 0;
+
+    if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+        flags = GP3_RM_SOURCE_INVERT;
+
+    /* MONO CALCULATIONS */
+
+    indent    = (mono_srcx >> 3);
+	srcoff    = (indent & ~3L);
+	indent   &= 3;
+
+    size = ((width + (mono_srcx & 7) + 7) >> 3) + indent;
+	total_dwords = (size + 3) >> 2;
+	size_dwords  = (total_dwords << 2) + 8;
+	dword_count  = (size >> 2);
+	byte_count   = (size & 3);
+	
+    base = ((gp3_fb_base << 24) + (gp3_scratch_base & 0xFFC00000)) |
+            (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+    gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE      |
+                      GP3_BLT_HDR_STRIDE_ENABLE      |
+                      GP3_BLT_HDR_DST_OFF_ENABLE     |
+                      GP3_BLT_HDR_WIDHI_ENABLE       |
+                      GP3_BLT_HDR_CH3_STR_ENABLE     |
+                      GP3_BLT_HDR_CH3_OFF_ENABLE     |
+                      GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+                      GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+                      GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+    WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, GP3_RM_BPPFMT_8888 | 0xCC);
+    WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 2));
+    WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, gp3_scratch_base & 0x3FFFFF);
+    WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (total_dwords << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (total_dwords << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, 0);
+    WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+    WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+        GP3_CH3_C3EN           |
+		GP3_CH3_REPLACE_SOURCE |
+		GP3_CH3_HST_SRC_ENABLE |
+        GP3_CH3_SRC_8_8_8_8    |
+      ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+    WRITE_COMMAND32 (GP3_BLT_MODE, 0);
+    WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+
+    /* START THE BLT */
+
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+    for (i = 0; i < height; i++)
+	{
+		/* UPDATE THE COMMAND POINTER */
+		/* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+		/* This is created by adding gp3_cmd_current to the base pointer.        */
+
+		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+		/* CHECK IF A WRAP WILL BE NEEDED */
+
+		gp3_cmd_next = gp3_cmd_current + size_dwords;
+		if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+		{
+			gp3_cmd_next  = gp3_cmd_top;
+    		
+			/* WAIT FOR HARDWARE */
+    		
+			GP3_WAIT_WRAP(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+				GP3_DATA_LOAD_HDR_ENABLE);
+		}
+		else
+		{
+			/* WAIT FOR AVAILABLE SPACE */
+
+			GP3_WAIT_PRIMITIVE(temp);
+			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+		}
+
+		/* WRITE DWORD COUNT */
+    	
+		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+		/* WRITE DATA */
+
+		WRITE_COMMAND_STRING32 (8, mono_mask, srcoff, dword_count);
+		WRITE_COMMAND_STRING8 (8 + (dword_count << 2), mono_mask,
+			srcoff + (dword_count << 2), byte_count);
+
+		/* UPDATE POINTERS */
+
+		srcoff += mono_pitch;
+		WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+		gp3_cmd_current = gp3_cmd_next;
+	}
+
+    /* SECOND BLT */
+
+    gp_declare_blt (gp3_blt_flags | CIMGP_BLTFLAGS_HAZARD);
+
+    base = ((gp3_fb_base << 24) +  (dstoffset & 0xFFC00000))                          |
+	       ((gp3_fb_base << 14) + (((gp3_scratch_base + indent) & 0xFFC00000) >> 10)) |
+           ((gp3_fb_base << 4)  + ((srcoffset & 0xFFC00000) >> 20));
+
+    gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE      |
+                      GP3_BLT_HDR_STRIDE_ENABLE      |
+		              GP3_BLT_HDR_DST_OFF_ENABLE     |
+					  GP3_BLT_HDR_SRC_OFF_ENABLE     |
+		              GP3_BLT_HDR_WIDHI_ENABLE       |
+					  GP3_BLT_HDR_CH3_STR_ENABLE     |
+					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
+					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
+					  GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+    /* ENABLE TRANSPARENCY AND PATTERN COPY ROP */
+    /* The monochrome data is used as a mask but is otherwise not involved in */
+    /* the BLT.  The color data is routed through the pattern channel.        */
+
+    WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_bpp | 0xF0 | GP3_RM_SRC_TRANS | flags);
+    WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 18) | gp3_dst_stride);
+    WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset & 0x3FFFFF);
+    WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET,
+		((gp3_scratch_base + indent) & 0x3FFFFF ) | ((mono_srcx & 7) << 26));
+    WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (width << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI,  (width << 16) | height);
+    WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+
+    /* PROGRAM PARAMETERS FOR COLOR SOURCE DATA  */
+	
+	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, srcoffset & 0x3FFFFF);
+	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+		GP3_CH3_C3EN            |
+        gp3_ch3_bpp             |
+        gp3_src_stride          |
+	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_MONO | GP3_BM_SRC_FB);
+
+	/* START THE BLT */
+
+	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_bresenham_line
+ *
+ * This routine draws a vector using the specified Bresenham parameters.
+ * Currently this file does not support a routine that accepts the two
+ * endpoints of a vector and calculates the Bresenham parameters.  If it
+ * ever does, this routine is still required for vectors that have been
+ * clipped.
+ *-------------------------------------------------------------------------*/
+
+void gp_bresenham_line (unsigned long dstoffset, unsigned short length,
+	unsigned short initerr, unsigned short axialerr, unsigned short diagerr,
+	unsigned long flags)
+{
+    unsigned long base;
+    long offset;
+
+    /* HANDLE NEGATIVE VECTORS */
+    /* We have to be very careful with vectors that increment negatively   */
+    /* Our framebuffer scheme tries to align the destination of every      */
+    /* BLT or vector to the nearest 4MB-aligned boundary.  This is         */
+    /* necessary because the GP only supports offsets up to 16MB, but the  */
+    /* framebuffer can be over 128MB.  To solve this problem, the GP       */
+    /* base address registers are alignable to 4MB regions.  However, we   */
+    /* cannot simply align the dest offset when the vector goes negative.  */
+    /* The vector offset could underflow, causing the offset to jump from  */
+    /* near 0 to 16MB.  As we cannot accurately determine the last address */
+    /* that will be written in a vector short of walking the algorithm in  */
+    /* software, we do a worst case approximation.                         */
+
+    offset = dstoffset;
+    if (!(flags & CIMGP_POSMAJOR))
+    {
+        if (flags & CIMGP_YMAJOR)
+            offset -= length * gp3_dst_stride;
+        else
+            offset -= (length << gp3_pix_shift);
+
+        if (offset < 0)
+            offset = 0;
+    }
+    if (!(flags & CIMGP_POSMINOR))
+    {
+        if (flags & CIMGP_YMAJOR)
+            offset -= (length << gp3_pix_shift);
+        else
+            offset -= length * gp3_dst_stride;
+
+        if (offset < 0)
+            offset = 0;
+    }
+
+    offset &= 0xFFC00000;
+    dstoffset -= offset;
+
+    base = ((gp3_fb_base << 24) + offset) |
+            (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+    /* ENABLE RELEVANT REGISTERS */
+	/* Note that we always enable and write the channel 3 mode, if only */
+	/* to turn it off.   Cimarron also always writes the base offset    */
+	/* register to allow operation with frame buffers larger than 16MB. */
+
+	gp3_cmd_header |= GP3_VEC_HDR_DST_OFF_ENABLE     |
+		              GP3_VEC_HDR_VEC_ERR_ENABLE     |
+					  GP3_VEC_HDR_VEC_LEN_ENABLE     |
+					  GP3_VEC_HDR_BASE_OFFSET_ENABLE |
+					  GP3_VEC_HDR_CH3_STR_ENABLE     |
+					  GP3_VEC_HDR_VEC_MODE_ENABLE;
+
+	/* WRITE THE REGISTERS COMMON TO ALL PATTERN TYPES */
+	/* The destination base is the frame buffer base plus whatever */
+	/* 4MB segment we happen to be drawing to.                     */
+
+	WRITE_COMMAND32 (GP3_VECTOR_VEC_ERR,
+		(((unsigned long)axialerr << 16) | (unsigned long)diagerr));
+	WRITE_COMMAND32 (GP3_VECTOR_VEC_LEN,
+		(((unsigned long)length << 16)   | (unsigned long)initerr));
+	WRITE_COMMAND32 (GP3_VECTOR_BASE_OFFSET, base);
+	
+	/* CHECK VECTOR PATTERN CASE */
+
+	if (gp3_ch3_pat)
+	{
+		/* SET THE SOLID COLOR */
+		/* The color for vector patterns from channel 3 comes from */
+		/* the regular pattern registers.                          */
+
+		gp3_cmd_header |= GP3_VEC_HDR_PAT_CLR0_ENABLE;
+
+		WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, gp3_vector_pattern_color);
+
+		/* INITIALIZE CHANNEL 3 PARAMETERS */
+        /* We route the channel 3 output to the old source channel.  If the user */
+        /* sets a ROP that involves source, they will get unexpected results.    */
+
+		WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, dstoffset);
+		WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR,
+            GP3_CH3_C3EN | GP3_CH3_REPLACE_SOURCE | GP3_CH3_COLOR_PAT_ENABLE | GP3_CH3_SRC_8_8_8_8);
+	}
+	else
+	{
+		/* DISABLE CHANNEL 3 AND USE NORMAL PATTERN ORIGINS */
+
+		WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR, 0);
+		WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, (dstoffset | gp3_pat_origin));
+	}
+	
+	/* START THE VECTOR */
+
+    WRITE_COMMAND32 (GP3_VEC_CMD_HEADER, gp3_cmd_header);
+	WRITE_COMMAND32 (GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+
+    gp3_cmd_current = gp3_cmd_next;
+
+    /* ADD A SECOND VECTOR TO CLEAR THE BYTE ENABLES            */
+    /* We set a transparent pattern to clear the byte enables.  */
+    /* We then restore the previous pattern. (SiBZ #4001)       */
+
+    if (gp3_ch3_pat)
+    {
+        cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+        WRITE_COMMAND32 (0, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+	    WRITE_COMMAND32 (4, 0x100);
+	    WRITE_COMMAND32 (8, (1 | GP3_LUT_DATA_TYPE));	
+	    WRITE_COMMAND32 (12, 0);
+
+        /* DUMMY VECTOR */
+        /* We shouldn't need to write anything but vector mode and the length. */
+
+        WRITE_COMMAND32 (16, GP3_VEC_HDR_TYPE | GP3_VEC_HDR_VEC_MODE_ENABLE |
+            GP3_VEC_HDR_VEC_LEN_ENABLE);
+        WRITE_COMMAND32 (16 + GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+        WRITE_COMMAND32 (16 + GP3_VECTOR_VEC_LEN, (1 << 16) | (unsigned long)initerr);
+
+        WRITE_COMMAND32 (16 + GP3_VECTOR_COMMAND_SIZE, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+	    WRITE_COMMAND32 (20 + GP3_VECTOR_COMMAND_SIZE, 0x100);
+	    WRITE_COMMAND32 (24 + GP3_VECTOR_COMMAND_SIZE, (1 | GP3_LUT_DATA_TYPE));	
+	    WRITE_COMMAND32 (28 + GP3_VECTOR_COMMAND_SIZE, gp3_vec_pat);
+
+        gp3_cmd_current += 32 + GP3_VECTOR_COMMAND_SIZE;
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_line_from_endpoints
+ *
+ * This routine draws a vector from a set of rectangular coordinates.  The
+ * rectangle is assumed to use the currently specified destination stride.
+ *-------------------------------------------------------------------------*/
+
+void gp_line_from_endpoints (unsigned long dstoffset, unsigned long x0,
+    unsigned long y0, unsigned long x1, unsigned long y1, int inclusive)
+{
+    unsigned long base;
+    unsigned long length;
+    unsigned long flags;
+    unsigned short initerr, axialerr, diagerr;
+    long dx, dy, dmaj, dmin;
+    long offset;
+
+    /* ADJUST DESTINATION OFFSET BASED ON STARTING COORDINATE */
+
+    dstoffset += (x0 << gp3_pix_shift) + (y0 * gp3_dst_stride);
+
+    /* CALCULATE BRESENHAM TERMS */
+
+    dx = (long)x1 - (long)x0;
+    dy = (long)y1 - (long)y0;
+    if (dx < 0) dx = -dx;
+    if (dy < 0) dy = -dy;
+
+    if (dx >= dy)
+    {
+        dmaj = dx;
+        dmin = dy;
+        flags = 0;
+        if (x1 > x0) flags |= CIMGP_POSMAJOR;
+        if (y1 > y0) flags |= CIMGP_POSMINOR;
+    }
+    else
+    {
+        dmaj = dy;
+        dmin = dx;
+        flags = CIMGP_YMAJOR;
+        if (x1 > x0) flags |= CIMGP_POSMINOR;
+        if (y1 > y0) flags |= CIMGP_POSMAJOR;
+    }
+
+    axialerr = (unsigned short)(dmin << 1);
+    diagerr  = (unsigned short)((dmin-dmaj) << 1);
+    initerr  = (unsigned short)((dmin << 1) - dmaj);
+    if (!(flags & CIMGP_POSMINOR)) initerr--;
+
+    /* CHECK FOR NO WORK */
+
+    if (!dmaj)
+        return;
+
+    /* CHECK INCLUSIVE OR EXCLUSIVE */
+    /* An inclusive line can be accomplished by simply adding 1 to the */
+    /* line length.                                                    */
+
+    length = dmaj;
+    if (inclusive)
+        length++;
+
+    /* HANDLE NEGATIVE VECTORS */
+
+    offset = dstoffset;
+    if (!(flags & CIMGP_POSMAJOR))
+    {
+        if (flags & CIMGP_YMAJOR)
+            offset -= length * gp3_dst_stride;
+        else
+            offset -= (length << gp3_pix_shift);
+
+        if (offset < 0)
+            offset = 0;
+    }
+    if (!(flags & CIMGP_POSMINOR))
+    {
+        if (flags & CIMGP_YMAJOR)
+            offset -= (length << gp3_pix_shift);
+        else
+            offset -= length * gp3_dst_stride;
+
+        if (offset < 0)
+            offset = 0;
+    }
+
+    offset &= 0xFFC00000;
+    dstoffset -= offset;
+
+    base = ((gp3_fb_base << 24) + offset) |
+            (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+    /* ENABLE RELEVANT REGISTERS */
+	/* Note that we always enable and write the channel 3 mode, if only */
+	/* to turn it off.   Cimarron also always writes the base offset    */
+	/* register to allow operation with frame buffers larger than 16MB. */
+
+	gp3_cmd_header |= GP3_VEC_HDR_DST_OFF_ENABLE     |
+		              GP3_VEC_HDR_VEC_ERR_ENABLE     |
+					  GP3_VEC_HDR_VEC_LEN_ENABLE     |
+					  GP3_VEC_HDR_BASE_OFFSET_ENABLE |
+					  GP3_VEC_HDR_CH3_STR_ENABLE     |
+					  GP3_VEC_HDR_VEC_MODE_ENABLE;
+
+	/* WRITE THE REGISTERS COMMON TO ALL PATTERN TYPES */
+	/* The destination base is the frame buffer base plus whatever */
+	/* 4MB segment we happen to be drawing to.                     */
+
+	WRITE_COMMAND32 (GP3_VECTOR_VEC_ERR,
+		(((unsigned long)axialerr << 16) | (unsigned long)diagerr));
+	WRITE_COMMAND32 (GP3_VECTOR_VEC_LEN,
+		(((unsigned long)length << 16)   | (unsigned long)initerr));
+	WRITE_COMMAND32 (GP3_VECTOR_BASE_OFFSET, base);
+	
+	/* CHECK VECTOR PATTERN CASE */
+
+	if (gp3_ch3_pat)
+	{
+		/* SET THE SOLID COLOR */
+		/* The color for vector patterns from channel 3 comes from */
+		/* the regular pattern registers.                          */
+
+		gp3_cmd_header |= GP3_VEC_HDR_PAT_CLR0_ENABLE;
+
+		WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, gp3_vector_pattern_color);
+
+		/* INITIALIZE CHANNEL 3 PARAMETERS */
+        /* We route the channel 3 output to the old source channel.  If the user */
+        /* sets a ROP that involves source, they will get unexpected results.    */
+
+		WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, dstoffset);
+		WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR,
+            GP3_CH3_C3EN | GP3_CH3_REPLACE_SOURCE | GP3_CH3_COLOR_PAT_ENABLE | GP3_CH3_SRC_8_8_8_8);
+	}
+	else
+	{
+		/* DISABLE CHANNEL 3 AND USE NORMAL PATTERN ORIGINS */
+
+		WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR, 0);
+		WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, (dstoffset | gp3_pat_origin));
+	}
+	
+	/* START THE VECTOR */
+
+    WRITE_COMMAND32 (GP3_VEC_CMD_HEADER, gp3_cmd_header);
+	WRITE_COMMAND32 (GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+	gp3_cmd_current = gp3_cmd_next;
+
+    /* ADD A SECOND VECTOR TO CLEAR THE BYTE ENABLES            */
+    /* We set a transparent pattern to clear the byte enables.  */
+    /* We then restore the previous pattern.  (SiBZ #4001)      */
+
+    if (gp3_ch3_pat)
+    {
+        cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+        WRITE_COMMAND32 (0, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+	    WRITE_COMMAND32 (4, 0x100);
+	    WRITE_COMMAND32 (8, (1 | GP3_LUT_DATA_TYPE));	
+	    WRITE_COMMAND32 (12, 0);
+
+        /* DUMMY VECTOR */
+        /* We shouldn't need to write anything but vector mode and the length. */
+
+        WRITE_COMMAND32 (16, GP3_VEC_HDR_TYPE | GP3_VEC_HDR_VEC_MODE_ENABLE |
+            GP3_VEC_HDR_VEC_LEN_ENABLE);
+        WRITE_COMMAND32 (16 + GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+        WRITE_COMMAND32 (16 + GP3_VECTOR_VEC_LEN, (1 << 16) | (unsigned long)initerr);
+
+        WRITE_COMMAND32 (16 + GP3_VECTOR_COMMAND_SIZE, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+	    WRITE_COMMAND32 (20 + GP3_VECTOR_COMMAND_SIZE, 0x100);
+	    WRITE_COMMAND32 (24 + GP3_VECTOR_COMMAND_SIZE, (1 | GP3_LUT_DATA_TYPE));	
+	    WRITE_COMMAND32 (28 + GP3_VECTOR_COMMAND_SIZE, gp3_vec_pat);
+
+        gp3_cmd_current += 32 + GP3_VECTOR_COMMAND_SIZE;
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_wait_until_idle
+ *
+ * This routine stalls execution until the GP is no longer actively rendering.
+ *-------------------------------------------------------------------------*/
+
+void gp_wait_until_idle (void)
+{
+    unsigned long temp;
+    while (((temp = READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_BUSY) ||
+            !(temp & GP3_BS_CB_EMPTY))
+    {
+        ;
+    }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_test_blt_busy
+ *-------------------------------------------------------------------------*/
+
+int gp_test_blt_busy (void)
+{
+    unsigned long temp;
+
+    if (((temp = READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_BUSY) ||
+        !(temp & GP3_BS_CB_EMPTY))
+        return 1;
+	
+    return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_test_blt_pending
+ *-------------------------------------------------------------------------*/
+
+int gp_test_blt_pending (void)
+{
+    if ((READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_PENDING)
+        return 1;
+	
+    return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_wait_blt_pending
+ *-------------------------------------------------------------------------*/
+
+void gp_wait_blt_pending (void)
+{
+    while ((READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_PENDING)
+        ;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_save_state
+ *
+ * This routine saves all persistent GP information.
+ *-------------------------------------------------------------------------*/
+
+void gp_save_state (GP_SAVE_RESTORE *gp_state)
+{
+    Q_WORD msr_value;
+
+    gp_wait_until_idle();
+
+    msr_read64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);
+    gp_state->cmd_bottom  = READ_GP32 (GP3_CMD_BOT) & 0xFFFFFF;
+    gp_state->cmd_top     = READ_GP32 (GP3_CMD_TOP) & 0xFFFFFF;
+    gp_state->cmd_base    = (msr_value.low << 4) & 0xFFF00000;
+    gp_state->base_offset = READ_GP32 (GP3_BASE_OFFSET);
+
+    /* RESET THE READ POINTER */
+
+    gp_set_command_buffer_base (gp_state->cmd_base, gp_state->cmd_top, gp_state->cmd_bottom);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_restore_state
+ *
+ * This routine restores all persistent GP information.
+ *-------------------------------------------------------------------------*/
+
+void gp_restore_state (GP_SAVE_RESTORE *gp_state)
+{
+    gp_wait_until_idle();
+
+    WRITE_GP32 (GP3_BASE_OFFSET, gp_state->base_offset);
+
+    gp_set_command_buffer_base (gp_state->cmd_base, gp_state->cmd_top, gp_state->cmd_bottom);
+}
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_init.c xf86-video-nsc-2.8.1/src/cim/cim_init.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_init.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_init.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,209 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron initialization routines.  These routines detect a Geode LX and read
+  * all hardware base addresses.
+  * </DOC_AMD_STD>
+  *
+  */
+
+CIMARRON_STATIC unsigned long init_video_base = 0x80000900;
+
+/*---------------------------------------------------------------------------
+ * init_detect_cpu
+ *
+ * This routine verifies that a Geode LX is present and returns the processor revision
+ * ID.  For compatibility, this routine can also detect a Redcloud processor.
+ *     bits[24:16] = minor version
+ *     bits[15:8]  = major version
+ *     bits[7:0]   = type (1 = Geode GX, 2 = Geode LX)
+ *---------------------------------------------------------------------------*/
+
+int init_detect_cpu (unsigned long *cpu_revision, unsigned long *companion_revision)
+{
+	unsigned long bus, device, i;
+    unsigned long cpu_bus = 0, cpu_device = 0;
+	unsigned long address, data;
+	unsigned long num_bars, function;
+    int cpu_found, sb_found;
+	Q_WORD msr_value;
+
+	/* SEARCH THROUGH PCI BUS                                          */
+	/* We search the PCI bus for the Geode LX or Geode GX northbridge. */
+    /* We then verify that one of its functions is the graphics        */
+    /* controller and that all bars are filled in.                     */	
+	
+    cpu_found = sb_found = 0;
+	for (bus = 0; bus < 256; bus++)
+	{
+		for (device = 0; device < 21; device++)
+		{
+			address = 0x80000000 | (bus << 16) | (device << 11);
+
+			data = init_read_pci (address);
+
+			if (data == PCI_VENDOR_DEVICE_GEODEGX || data == PCI_VENDOR_DEVICE_GEODELX)
+            {
+                cpu_found = 1;
+                cpu_device = device;
+                cpu_bus = bus;
+                if (data == PCI_VENDOR_DEVICE_GEODEGX)
+		            *cpu_revision = CIM_CPU_GEODEGX;
+	            else
+		            *cpu_revision = CIM_CPU_GEODELX;
+            }
+            else if (data == PCI_VENDOR_5535 || data == PCI_VENDOR_5536)
+            {
+                sb_found = 1;
+                if (data == PCI_VENDOR_5535)
+		            *companion_revision = CIM_SB_5535;
+	            else
+		            *companion_revision = CIM_SB_5536;
+            }
+
+            if (cpu_found && sb_found)
+				break;
+		}
+		if (device != 21)
+			break;
+	}
+
+	if (bus == 256)
+	{
+		*cpu_revision = 0;
+		return CIM_STATUS_CPUNOTFOUND;
+	}
+		
+	msr_init_table();
+				
+	if (msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REVID, &msr_value) != CIM_STATUS_OK)
+	{
+		*cpu_revision = 0;
+		return CIM_STATUS_CPUNOTFOUND;
+	}
+
+	*cpu_revision |= ((msr_value.low & 0xF0) << 4) |
+		             ((msr_value.low & 0x0F) << 16);
+
+    if (msr_read64 (MSR_DEVICE_5535_GLCP, GLCP_REVID, &msr_value) != CIM_STATUS_OK)
+	{
+		*cpu_revision = 0;
+		return CIM_STATUS_CPUNOTFOUND;
+	}
+
+	*companion_revision |= ((msr_value.low & 0xF0) << 4) |
+		                   ((msr_value.low & 0x0F) << 16);
+
+	/* SEARCH ALL FUNCTIONS FOR INTEGRATED GRAPHICS */
+
+    num_bars = 0;
+	for (function = 0; function < 7; function++)
+	{
+		address = 0x80000000 | (cpu_bus << 16) | (cpu_device << 11) | (function << 8);
+		data = init_read_pci (address);
+
+		if (data == PCI_VENDOR_DEVICE_GEODEGX_VIDEO)
+		{
+			num_bars = 4;
+			break;
+		}
+		else if (data == PCI_VENDOR_DEVICE_GEODELX_VIDEO)
+		{
+			num_bars = 5;
+			break;
+		}
+	}
+
+	/* VERIFY THAT ALL BARS ARE PRESENT */
+
+	if (function == 7)
+		return CIM_STATUS_DISPLAYUNAVAILABLE;
+
+	for (i = 0; i < num_bars; i++)
+	{
+		data = init_read_pci (address + 0x10 + (i << 2));
+
+		if (data == 0 || data == 0xFFFFFFFF)
+			break;
+	}
+
+	if (i != num_bars)
+		return CIM_STATUS_DISPLAYUNAVAILABLE;
+	
+	/* SAVE VIDEO BASE ADDRESS FOR FUTURE CALLS */
+
+	init_video_base = address;
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * init_read_pci
+ *
+ * This routine reads an unsigned long value from a PCI address.
+ *---------------------------------------------------------------------------*/
+
+unsigned long init_read_pci	(unsigned long address)
+{	
+	OUTD (0xCF8, address);
+	return IND (0xCFC);
+}
+
+/*---------------------------------------------------------------------------
+ * init_read_base_addresses
+ *
+ * This routine reads all base addresses for the peripherals from the PCI BARs.
+ *---------------------------------------------------------------------------*/
+
+int init_read_base_addresses (INIT_BASE_ADDRESSES *base_addresses)
+{
+	unsigned long value;
+
+	/* READ ALL BASE ADDRESSES */
+	
+	base_addresses->framebuffer_base  = init_read_pci (init_video_base + 0x10);
+	base_addresses->gp_register_base  = init_read_pci (init_video_base + 0x14);
+	base_addresses->vg_register_base  = init_read_pci (init_video_base + 0x18);
+	base_addresses->df_register_base  = init_read_pci (init_video_base + 0x1C);
+	base_addresses->vip_register_base = init_read_pci (init_video_base + 0x20);
+	
+	/* READ FRAME BUFFER SIZE */
+	/* The frame buffer size is reported by a VSM in VSA II */
+	/* Virtual Register Class    = 0x02                    */
+	/* VG_MEM_SIZE (1MB units)   = 0x00                    */
+
+	OUTW (0xAC1C, 0xFC53);
+	OUTW (0xAC1C, 0x0200);
+
+	value = (unsigned long)(INW (0xAC1E)) & 0xFE;
+
+	base_addresses->framebuffer_size = value << 20;
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * init_read_cpu_frequency
+ *
+ * This routine returns the current CPU core frequency, in MHz.
+ *---------------------------------------------------------------------------*/
+
+int init_read_cpu_frequency (unsigned long *cpu_frequency)
+{
+	/* CPU SPEED IS REPORTED BY A VSM IN VSA II */
+	/* Virtual Register Class = 0x12 (Sysinfo)  */
+	/* CPU Speed Register     = 0x01            */
+
+	OUTW (0xAC1C, 0xFC53);
+	OUTW (0xAC1C, 0x1201);
+
+	*cpu_frequency = (unsigned long)(INW (0xAC1E));
+
+	return CIM_STATUS_OK;
+}
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_modes.c xf86-video-nsc-2.8.1/src/cim/cim_modes.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_modes.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_modes.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1822 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron mode tables.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*-------------------------------*/
+/*  PREDEFINED DISPLAY TIMINGS   */
+/*-------------------------------*/
+
+VG_DISPLAY_MODE CimarronDisplayModes[] =
+{
+    /* 320 x 240 PANEL */
+
+	{ VG_SUPPORTFLAG_75HZ  |                                       /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+	  VG_SUPPORTFLAG_PANEL,                                        /* Panel Mode.          */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT |                                       /* Panel output.        */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC |			   /* negative syncs       */
+	  VG_MODEFLAG_QVGA,                                            /* QVGA Panel size.     */
+	  320, 240,                                                    /* No scaling.          */
+	  320, 240,                                                    /* 320x240 active       */
+	  320, 240,                                                    /* 320x240 panel        */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0140, 0x0148, 0x0162, 0x0180, 0x0188, 0x0190,              /* horizontal timings   */
+	  0x00F0, 0x00F4, 0x00F9, 0x00FD, 0x00FF, 0x0104,              /* vertical timings     */
+	  (31L << 16)  | ((2000L * 65536L) / 10000L),                  /* freq = 31.2000 MHz    */
+	},
+
+	/* 640 x 400 */
+
+	{ VG_SUPPORTFLAG_70HZ  |                                       /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC,			                           /* negative HSYNC       */
+	  640, 400,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x280, 0x288, 0x290, 0x2F0, 0x318, 0x320,     	           /* horizontal timings   */
+	  0x190, 0x197, 0x19C, 0x19E, 0x1BA, 0x1C1,                    /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (25L << 16) | ((1750L * 65536L) / 10000L),                   /* freq = 25.175 MHz    */
+	},
+
+	/* 640x480 */
+
+	{ VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  640, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0288, 0x0290, 0x02E8, 0x0318, 0x0320,	           /* horizontal timings   */
+	  0x01E0, 0x01E8, 0x01EA, 0x01EC, 0x0205, 0x020D,              /* vertical timings     */
+	  0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+      (25L << 16) | ((1750L * 65536L) / 10000L),                   /* freq = 25.175 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_70HZ  |									   /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      640, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0280, 0x0298, 0x02D8, 0x0330, 0x0330,	           /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01E2, 0x01E5, 0x01F4, 0x01F4,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (28L << 16) | ((5600L * 65536L) / 10000L),                   /* freq = 28.560 MHz    */
+	},
+
+	{ VG_SUPPORTFLAG_72HZ  |									   /* refresh rate = 72    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  640, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0288, 0x0298, 0x02c0, 0x0338, 0x0340,	           /* horizontal timings   */
+	  0x01e0, 0x01e8, 0x01e9, 0x01ec, 0x0200, 0x0208,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (31L << 16) | ((5000L * 65536L) / 10000L),                   /* freq = 31.5 MHz      */
+	},
+
+	{ VG_SUPPORTFLAG_75HZ  |								       /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,               /* negative syncs       */
+	  640, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0280, 0x0290, 0x02D0, 0x0348, 0x0348,	           /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01F4, 0x01F4,	           /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (31L << 16) | ((5000L * 65536L) / 10000L),                   /* freq = 31.5 MHz      */
+	},
+
+	{ VG_SUPPORTFLAG_85HZ  |									   /* refresh rate = 85    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  640, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0280, 0x02B8, 0x02F0, 0x0340, 0x0340,              /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FD, 0x01FD,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (36L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 36.0 MHz      */
+	},
+
+    { VG_SUPPORTFLAG_90HZ  |									   /* refresh rate = 90    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      640, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0280, 0x02A0, 0x02E0, 0x0340, 0x0340,              /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FA, 0x01FA,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (37L << 16) | ((8890L * 65536L) / 10000L),                   /* freq = 37.889 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_100HZ | 									   /* refresh rate = 100   */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      640, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0280, 0x02A8, 0x02E8, 0x0350, 0x0350,              /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FD, 0x01FD,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (43L << 16) | ((1630L * 65536L) / 10000L),                   /* freq = 43.163 MHz    */
+	},
+
+	/* 640 x 480 PANEL */
+
+	{ VG_SUPPORTFLAG_60HZ  |                                       /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+	  VG_SUPPORTFLAG_PANEL,                                        /* Panel Mode.          */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT |                                       /* Panel output.        */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  640, 480,                                                    /* No scaling.          */
+	  640, 480,                                                    /* 640x480 active       */
+	  640, 480,                                                    /* 640x480 panel        */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320,     	       /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (25L << 16) | ((1750L * 65536L) / 10000L),                   /* freq = 25.175 MHz    */
+	},
+
+	/* 800x600 */
+
+	{ VG_SUPPORTFLAG_56HZ  |									       /* refresh rate = 56    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0338, 0x0380, 0x0400, 0x0400,	           /* horizontal timings   */
+	  0x0258, 0x0258, 0x0259, 0x025B, 0x0271, 0x0271,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (36L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 36.0 MHz      */
+	},
+
+	{ VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0328, 0x0348, 0x03D0, 0x0418, 0x0420,	           /* horizontal timings   */
+	  0x0258, 0x0258, 0x0259, 0x025D, 0x0274, 0x0274,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (40L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 40.00 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_70HZ  |									   /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0348, 0x0398, 0x0410, 0x0410,	           /* horizontal timings   */
+	  0x0258, 0x0258, 0x025c, 0x025F, 0x0274, 0x0274,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (45L << 16) | ((7200L * 65536L) / 10000L),                   /* freq = 45.72 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_72HZ  |									   /* refresh rate = 72    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0358, 0x03D0, 0x0410, 0x0410,              /* horizontal timings   */
+	  0x0258, 0x0258, 0x027D, 0x0283, 0x029A, 0x029A,	           /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (49L << 16) | ((5000L * 65536L) / 10000L),                   /* freq = 49.5 MHz      */
+	},
+
+	{ VG_SUPPORTFLAG_75HZ  |									   /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0330, 0x0380, 0x0420, 0x0420,              /* horizontal timings   */
+	  0x0258, 0x0258, 0x0259, 0x025C, 0x0271, 0x0271,	           /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (49L << 16) | ((5000L * 65536L) / 10000L),                   /* freq = 49.5 MHz      */
+	},
+
+	{ VG_SUPPORTFLAG_85HZ  |									   /* refresh rate = 85    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0340, 0x0380, 0x0418, 0x0418,              /* horizontal timings   */
+	  0x0258, 0x0258, 0x0259, 0x025C, 0x0277, 0x0277,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (56L << 16) | ((2500L * 65536L) / 10000L),                   /* freq = 56.25 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_90HZ  |									   /* refresh rate = 90    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0348, 0x03A0, 0x0420, 0x0420,              /* horizontal timings   */
+	  0x0258, 0x0258, 0x0259, 0x025C, 0x0278, 0x0278,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (60L << 16) | ((650L * 65536L) / 10000L),                    /* freq = 60.065 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_100HZ |									   /* refresh rate = 100   */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      0,
+      800, 600,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0350, 0x03A8, 0x0430, 0x0430,              /* horizontal timings   */
+	  0x0258, 0x0258, 0x0259, 0x025C, 0x0277, 0x027C,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (68L << 16) | ((1790L * 65536L) / 10000L),                   /* freq = 68.179 MHz    */
+	},
+
+	/* 800x600 PANEL */
+
+	{ VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+	  VG_SUPPORTFLAG_PANEL,                                        /* Panel Mode.          */
+	  VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT |                                       /* Panel output.        */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  800, 600,                                                    /* No scaling.          */
+	  800, 600,                                                    /* 800x600 active.      */
+	  800, 600,                                                    /* 800x600 panel        */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x0348, 0x03C8, 0x0420, 0x0420,	           /* horizontal timings   */
+	  0x0258, 0x0258, 0x0259, 0x025D, 0x0274, 0x0274,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (40L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 40.00 MHz     */
+	},
+
+	/* 1024x768 */
+
+	{ VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  1024, 768,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540,	           /* horizontal timings   */
+	  0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (65L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 65.00 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_70HZ  |									   /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  1024, 768,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0418, 0x04A0, 0x0530, 0x0530,              /* horizontal timings   */
+	  0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (75L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 75.0 MHz      */
+	},
+
+    { VG_SUPPORTFLAG_72HZ  |									   /* refresh rate = 72    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1024, 768,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0438, 0x04A8, 0x0550, 0x0550,              /* horizontal timings   */
+	  0x0300, 0x0300, 0x0304, 0x0307, 0x0324, 0x0324,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (78L << 16) | ((7500L * 65536L) / 10000L),                   /* freq = 78.75 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_75HZ  |								       /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1024, 768,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0410, 0x0470, 0x0520, 0x0520,              /* horizontal timings   */
+	  0x0300, 0x0300, 0x0301, 0x0304, 0x0320, 0x0320,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (78L << 16) | ((7500L * 65536L) / 10000L),                   /* freq = 78.75 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_85HZ  |									   /* refresh rate = 85    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1024, 768,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0430, 0x0490, 0x0560, 0x0560,              /* horizontal timings   */
+	  0x0300, 0x0300, 0x0301, 0x0304, 0x0328, 0x0328,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (94L << 16) | ((5000L * 65536L) / 10000L),                   /* freq = 94.50 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_90HZ  |									   /* refresh rate = 90    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1024, 768,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0440, 0x04B0, 0x0560, 0x0560,              /* horizontal timings   */
+	  0x0300, 0x0300, 0x0301, 0x0304, 0x0329, 0x0329,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+      (100L << 16) | ((1870L * 65536L) / 10000L),                  /* freq = 100.187 MHz   */
+	},
+
+    { VG_SUPPORTFLAG_100HZ |									   /* refresh rate = 100   */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1024, 768,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0448, 0x04B8, 0x0570, 0x0570,              /* horizontal timings   */
+	  0x0300, 0x0300, 0x0301, 0x0304, 0x032E, 0x032E,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (113L << 16) | ((3100L * 65536L) / 10000L),                  /* freq = 113.31 MHz    */
+	},
+
+	/* 1024x768 PANEL */
+
+	{ VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+	  VG_SUPPORTFLAG_PANEL,                                        /* Panel Mode.          */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT |                                       /* Panel output.        */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,               /* negative syncs       */
+	  1024, 768,                                                   /* No scaling.          */
+	  1024, 768,                                                   /* 1024x768 active.     */
+	  1024, 768,                                                   /* 1024x768 panel       */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540,	           /* horizontal timings   */
+	  0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (65L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 65.00 MHz     */
+	},
+
+	/* 1152x864 */
+
+    { VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1152, 864,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04C0, 0x0538, 0x05F0, 0x05F0,              /* horizontal timings   */
+      0x0360, 0x0360, 0x0361, 0x0364, 0x037F, 0x037F,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (81L << 16)  | ((6000L * 65536L) / 10000L),                  /* freq = 81.60 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_70HZ  |									   /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1152, 864,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04C8, 0x0540, 0x0600, 0x0600,              /* horizontal timings   */
+      0x0360, 0x0360, 0x0368, 0x036B, 0x038B, 0x038B,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (97L << 16)  | ((5200L * 65536L) / 10000L),                  /* freq = 97.52 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_72HZ  |									   /* refresh rate = 72    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1152, 864,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04C8, 0x0548, 0x0610, 0x0610,              /* horizontal timings   */
+      0x0360, 0x0360, 0x0367, 0x036A, 0x038B, 0x038B,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (101L << 16)  | ((4200L * 65536L) / 10000L),                 /* freq = 101.42 MHz    */
+	},
+
+	{ VG_SUPPORTFLAG_75HZ  |									   /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1152, 864,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04C0, 0x0540, 0x0640, 0x0640,              /* horizontal timings   */
+	  0x0360, 0x0360, 0x0361, 0x0364, 0x0384, 0x0384,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (108L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 108.00 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_85HZ  |									   /* refresh rate = 85    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1152, 864,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04C8, 0x0548, 0x0610, 0x0610,              /* horizontal timings   */
+      0x0360, 0x0360, 0x0363, 0x0366, 0x038B, 0x038B,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (119L << 16) | ((6500L * 65536L) / 10000L),                  /* freq = 119.65 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_90HZ  |									   /* refresh rate = 90    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1152, 864,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04D0, 0x0550, 0x0620, 0x0620,              /* horizontal timings   */
+      0x0360, 0x0360, 0x0369, 0x036C, 0x0396, 0x0396,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (129L << 16) | ((6000L * 65536L) / 10000L),                  /* freq = 129.60 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_100HZ  |									   /* refresh rate = 100   */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1152, 864,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04D0, 0x0550, 0x0620, 0x0620,              /* horizontal timings   */
+      0x0360, 0x0360, 0x0363, 0x0366, 0x0396, 0x0396,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (144L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 144.00 MHz    */
+	},
+
+    /* 1152x864 PANEL */
+
+    { VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+	  VG_SUPPORTFLAG_PANEL,                                        /* Panel Mode.          */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT |                                       /* Panel output.        */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+      1152, 864,                                                   /* No scaling.          */
+	  1152, 864,                                                   /* 1152x864 active.     */
+	  1152, 864,                                                   /* 1152x864 panel. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0480, 0x0480, 0x04C0, 0x0538, 0x05F0, 0x05F0,              /* horizontal timings   */
+      0x0360, 0x0360, 0x0361, 0x0364, 0x037F, 0x037F,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (81L << 16)  | ((6000L * 65536L) / 10000L),                  /* freq = 81.60 MHz     */
+	},
+  		
+	/* 1280x1024 */
+
+	{ VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1280, 1024,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0530, 0x05A0, 0x0698, 0x0698,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (108L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 108.00 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_70HZ  |									   /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1280, 1024,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0558, 0x05E0, 0x06C0, 0x06C0,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x0406, 0x0409, 0x042F, 0x042F,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (129L << 16) | ((6000L * 65536L) / 10000L),                  /* freq = 129.60 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_72HZ  |									   /* refresh rate = 72    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1280, 1024,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0558, 0x05E0, 0x06C0, 0x06C0,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x0407, 0x040A, 0x0431, 0x0431,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (133L << 16) | ((5000L * 65536L) / 10000L),                  /* freq = 133.50 MHz    */
+	},
+
+	{ VG_SUPPORTFLAG_75HZ  |									   /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1280, 1024,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0510, 0x05A0, 0x0698, 0x0698,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (135L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 135.0 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_85HZ  |									   /* refresh rate = 85    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1280, 1024,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0540, 0x05E0, 0x06C0, 0x06C0,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x0401, 0x0404, 0x0430, 0x0430,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (157L << 16) | ((5000L * 65536L) / 10000L),                  /* freq = 157.5 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_90HZ  |									   /* refresh rate = 90    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1280, 1024,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0560, 0x05F0, 0x06E0, 0x06E0,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x040C, 0x040F, 0x0442, 0x0442,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (172L << 16) | ((8000L * 65536L) / 10000L),                  /* freq = 172.80 MHz    */
+	},
+
+    { VG_SUPPORTFLAG_100HZ |									   /* refresh rate = 100   */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      0,
+      1280, 1024,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0560, 0x05F0, 0x06E0, 0x06E0,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x0406, 0x0409, 0x0442, 0x0442,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (192L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 192.00 MHz    */
+	},
+
+    /* 1280x1024 PANEL */
+	
+    { VG_SUPPORTFLAG_60HZ  |									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+	  VG_SUPPORTFLAG_PANEL,                                        /* Panel Mode.          */
+	  VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT |                                       /* Panel output.        */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  1280, 1024,                                                  /* No scaling.          */
+	  1280, 1024,                                                  /* 1280x1024 active.    */
+	  1280, 1024,                                                  /* 1280x1024 panel      */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0530, 0x05A0, 0x0698, 0x0698,              /* horizontal timings   */
+	  0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (108L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 108.00 MHz    */
+	},
+
+	/* 1600 x 1200 */
+
+	{ VG_SUPPORTFLAG_60HZ  |                                       /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1600, 1200,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (162L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 162.0 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_70HZ  |                                       /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1600, 1200,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (189L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 189.0 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_72HZ  |                                       /* refresh rate = 72    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1600, 1200,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x06B0, 0x0760, 0x0880, 0x0880,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04BD, 0x04C0, 0x04EF, 0x04EF,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (198L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 198.0 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_75HZ  |                                       /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1600, 1200,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (202L << 16) | ((5000L * 65536L) / 10000L),                  /* freq = 202.5 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_85HZ  |                                       /* refresh rate = 85    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1600, 1200,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (229L << 16) | ((5000L * 65536L) / 10000L),                  /* freq = 229.5 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_90HZ  |                                       /* refresh rate = 90    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1600, 1200,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x06C0, 0x0770, 0x08A0, 0x08A0,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04F0, 0x04F0,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (251L << 16) | ((1820L * 65536L) / 10000L),                  /* freq = 251.182 MHz   */
+	},
+
+    { VG_SUPPORTFLAG_100HZ |                                       /* refresh rate = 100   */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1600, 1200,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x06C0, 0x0770, 0x08A0, 0x08A0,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04F7, 0x04F7,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (280L << 16) | ((6400L * 65536L) / 10000L),                  /* freq = 280.64 MHz    */
+	},
+
+    /* 1600 x 1200  PANEL */
+
+	{ VG_SUPPORTFLAG_60HZ  |                                       /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+	  VG_SUPPORTFLAG_PANEL,                                        /* Panel Mode.          */
+      VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      VG_MODEFLAG_PANELOUT |                                       /* Panel output.        */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC,			   /* negative syncs       */
+	  1600, 1200,                                                  /* No scaling.          */
+	  1600, 1200,                                                  /* 1600x1200 Active.    */
+	  1600, 1200,                                                  /* 1600x1200 Panel.     */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,              /* horizontal timings   */
+	  0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (162L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 162.0 MHz     */
+	},
+
+	/* 1920x1440 */
+
+	{ VG_SUPPORTFLAG_60HZ  |                                       /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1920, 1440,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0780, 0x0780, 0x0800, 0x08D0, 0x0A28, 0x0A28,              /* horizontal timings   */
+	  0x05A0, 0x05A0, 0x05A1, 0x05A4, 0x05DC, 0x05DC,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (234L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 234.0 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_70HZ  |                                       /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1920, 1440,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0780, 0x0780, 0x0818, 0x08E8, 0x0A50, 0x0A50,              /* horizontal timings   */
+	  0x05A0, 0x05A0, 0x05A8, 0x05AB, 0x05E2, 0x05E2,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (278L << 16) | ((4000L * 65536L) / 10000L),                  /* freq = 278.4 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_72HZ  |                                       /* refresh rate = 70    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1920, 1440,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0780, 0x0780, 0x0818, 0x08E8, 0x0A50, 0x0A50,              /* horizontal timings   */
+	  0x05A0, 0x05A0, 0x05A4, 0x05A7, 0x05EB, 0x05EB,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (288L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 288.0 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_75HZ  |                                       /* refresh rate = 75    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1920, 1440,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0780, 0x0780, 0x0810, 0x08F0, 0x0A50, 0x0A50,              /* horizontal timings   */
+	  0x05A0, 0x05A0, 0x05A1, 0x05A4, 0x05DC, 0x05DC,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (297L << 16) | ((0000L * 65536L) / 10000L),                  /* freq = 297.0 MHz     */
+	},
+
+	{ VG_SUPPORTFLAG_85HZ  |                                       /* refresh rate = 85    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP,                 /* All BPP supported.   */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      0,
+      1920, 1440,                                                  /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0780, 0x0780, 0x0818, 0x08F0, 0x0A60, 0x0A60,              /* horizontal timings   */
+	  0x05A0, 0x05A0, 0x05A1, 0x05A4, 0x05E8, 0x05E8,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings      */
+	  (341L << 16) | ((3490L * 65536L) / 10000L),                  /* freq = 341.35 MHz    */
+	},
+
+/*-------------------------------*/
+/*     PREDEFINED TV TIMINGS     */
+/*-------------------------------*/
+
+    /* 720 x 480i NTSC */
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_NTSC  |                                       /* NTSC Mode.           */
+      VG_SUPPORTFLAG_ADV7171 | VG_SUPPORTFLAG_SAA7127 |
+      VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT,               /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_INTERLACED | VG_MODEFLAG_TVOUT |                 /* Interlaced TV output */
+	  VG_MODEFLAG_HALFCLOCK |                                      /* DotPLL = 1/2 VOP     */
+      VG_MODEFLAG_INT_FLICKER,                                     /* Flicker Filter Out   */
+      720, 480,                                                    /* No downscaling.      */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x02D0, 0x02D0, 0x02E1, 0x0320, 0x035A, 0x035A,              /* horizontal timings   */
+	  0x00F0, 0x00F0, 0x00F4, 0x00F8, 0x0107, 0x0107,              /* vertical timings     */
+      0x00F0, 0x00F0, 0x00F4, 0x00F8, 0x0106, 0x0106,              /* Even field timings   */
+	  (27L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 27.0 MHz      */
+	},
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_NTSC  |                                       /* NTSC Mode.           */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC |			   /* negative syncs       */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* TFT Output.          */
+      640, 480,                                                    /* No downscaling.      */
+	  640, 480,                                                    /* 640x480 active.      */
+	  640, 480,                                                    /* 640x480 panel.       */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0280, 0x0280, 0x0333, 0x0373, 0x03A8, 0x03A8,              /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01F5, 0x01F7, 0x020D, 0x020D,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+	  (25L << 16) | ((1750L * 65536L) / 10000L),                   /* freq = 25.175 MHz    */
+	},
+
+    /* 800 x 600 NTSC */
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_8X6_NTSC |                                    /* 800x600 NTSC.        */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC |			   /* negative syncs       */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* Panel output         */
+      800, 600,                                                    /* No downscaling.      */
+	  800, 600,                                                    /* 800x600 active.      */
+	  800, 600,                                                    /* 800x600 active.      */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x03A7, 0x03E7, 0x03F0, 0x03F0,              /* horizontal timings   */
+      0x0258, 0x0258, 0x026A, 0x0272, 0x028A, 0x028A,              /* vertical timings     */
+	  0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+      (40L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 40.000 MHz    */
+	},
+
+    /* 1024 x 768 NTSC */
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_10X7_NTSC |                                   /* 1024x768 NTSC.       */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_AVG_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC |			   /* negative syncs       */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* Panel output         */
+      1024, 768,                                                   /* No downscaling.      */
+	  1024, 768,                                                   /* 1024x768 active.     */
+	  1024, 768,                                                   /* 1024x768 active.     */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0490, 0x04D0, 0x04E0, 0x04E0,              /* horizontal timings   */
+      0x0300, 0x0300, 0x031B, 0x031D, 0x0339, 0x0339,              /* vertical timings     */
+	  0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+      (65L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 65.00 MHz     */
+	},
+
+    /* 720 x 576i PAL */
+
+    { VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_PAL   |                                       /* PAL Mode.            */
+      VG_SUPPORTFLAG_ADV7171 | VG_SUPPORTFLAG_SAA7127 |
+      VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT,               /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_TVOUT | VG_MODEFLAG_INTERLACED |                 /* Interlaced TV out.   */
+      VG_MODEFLAG_HALFCLOCK |                                      /* DotPLL = 1/2 VOP     */
+      VG_MODEFLAG_INT_FLICKER,                                     /* Flicker Filter Out   */
+	  720, 576,                                                    /* No downscaling.      */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x02D0, 0x02D0, 0x02E4, 0x0324, 0x0360, 0x0360,              /* horizontal timings   */
+	  0x0120, 0x0120, 0x0123, 0x0127, 0x0139, 0x0139,              /* vertical timings     */
+      0x0120, 0x0120, 0x0123, 0x0127, 0x0138, 0x0138,              /* Even timings         */
+	  (27L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 27.0 MHz      */
+	},
+
+    { VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_PAL   |                                       /* PAL Mode.            */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC |			   /* negative syncs       */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* Panel output.        */
+	  640, 480,                                                    /* No downscaling.      */
+	  640, 480,                                                    /* No mode dimensions.  */
+	  640, 480,                                                    /* 640x480 active.      */
+      0, 0, 0, 0, 0,                                               /* 640x480 panel.       */
+	  0x0280, 0x0280, 0x030F, 0x034F, 0x0360, 0x0360,              /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01F5, 0x01F7, 0x020D, 0x020D,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+	  (25L << 16) | ((1750L * 65536L) / 10000L),                   /* freq = 25.175 MHz    */
+	},
+
+    /* 800 x 600 PAL */
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_8X6_PAL |                                     /* 800x600 PAL.         */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC |			   /* negative syncs       */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* Panel output         */
+      800, 600,                                                    /* No downscaling.      */
+	  800, 600,                                                    /* 800x600 active.      */
+	  800, 600,                                                    /* 800x600 active.      */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0320, 0x0320, 0x03A7, 0x03E7, 0x03F0, 0x03F0,              /* horizontal timings   */
+      0x0258, 0x0258, 0x0270, 0x0272, 0x028A, 0x028A,              /* vertical timings     */
+	  0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+      (40L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 40.000 MHz    */
+	},
+
+    /* 1024 x 768 PAL */
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_10X7_PAL |                                    /* 1024x768 NTSC.       */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_AVG_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC |			   /* negative syncs       */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* Panel output         */
+      1024, 768,                                                   /* No downscaling.      */
+	  1024, 768,                                                   /* 1024x768 active.     */
+	  1024, 768,                                                   /* 1024x768 active.     */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0400, 0x0400, 0x0490, 0x04d0, 0x04e0, 0x04e0,              /* horizontal timings   */
+      0x0300, 0x0300, 0x031b, 0x031d, 0x0339, 0x0339,              /* vertical timings     */
+	  0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+      (65L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 65.00 MHz     */
+	},
+
+    /* 720 x 480p HDTV */
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_480P  |                                       /* 720x480P.            */
+      VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT,               /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_TVOUT,                                           /* Progressive TV out.  */
+	  720, 480,                                                    /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x02D0, 0x02D0, 0x02E0, 0x0328, 0x035A, 0x035A,              /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01E1, 0x01E3, 0x020D, 0x020D,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+	  (27L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 27.0 MHz      */
+	},
+
+    { VG_SUPPORTFLAG_60HZ | 									   /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_480P  |                                       /* 720x480P.            */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_LOW_BAND |                                       /* Low bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* Panel output.        */
+	  720, 480,                                                    /* No scaling.          */
+	  720, 480,                                                    /* 720x480 active.      */
+	  720, 480,                                                    /* 720x480 panel.       */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x02D0, 0x02D0, 0x02E3, 0x0323, 0x035A, 0x035A,              /* horizontal timings   */
+	  0x01E0, 0x01E0, 0x01E4, 0x01EA, 0x020D, 0x020D,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+	  (27L << 16) | ((0000L * 65536L) / 10000L),                   /* freq = 27.0 MHz      */
+	},
+
+    /* 1280x720p HDTV */
+
+	{ VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_720P  |                                       /* 1280x720P            */
+      VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT,               /* TV Mode.             */
+      VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      VG_MODEFLAG_TVOUT,                                           /* Progressive TV out   */
+	  1280, 720,                                                   /* No scaling.          */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0546, 0x0596, 0x0672, 0x0672,              /* horizontal timings   */
+	  0x02D0, 0x02D0, 0x02D3, 0x02D8, 0x02EE, 0x02EE,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* even timings         */
+	  (74L << 16) | ((2500L * 65536L) / 10000L),                   /* freq = 74.25 MHz     */
+	},
+
+    { VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_720P  |                                       /* 1280x720P            */
+      VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT,                 /* TV Mode.             */
+      VG_MODEFLAG_AVG_BAND |                                       /* Avg bandwidth mode.  */
+      VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK,            /* Panel output.        */
+	  1280, 720,                                                   /* No scaling.          */
+	  1280, 720,                                                   /* 1280x720 active.     */
+	  1280, 720,                                                   /* 1280x720 panel.      */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0500, 0x0500, 0x0547, 0x0597, 0x0672, 0x0672,              /* horizontal timings   */
+	  0x02D0, 0x02D0, 0x02D4, 0x02D9, 0x02EE, 0x02EE,              /* vertical timings     */
+      0, 0, 0, 0, 0, 0,                                            /* No even timings.     */
+	  (74L << 16) | ((2500L * 65536L) / 10000L),                   /* freq = 74.25 MHz     */
+	},
+
+    /* 1920x1080i HDTV */
+
+	{ VG_SUPPORTFLAG_60HZ  |                                       /* refresh rate = 60    */
+	  VG_SUPPORTFLAG_8BPP  | VG_SUPPORTFLAG_12BPP |
+      VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+      VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP |                /* All BPP supported.   */
+      VG_SUPPORTFLAG_1080I |                                       /* 1920x1080i Mode.     */
+      VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_FS454 |
+      VG_SUPPORTFLAG_TVOUT,                                        /* TV Mode.             */
+	  VG_MODEFLAG_HIGH_BAND |                                      /* High bandwidth mode. */
+      VG_MODEFLAG_INTERLACED | VG_MODEFLAG_TVOUT |                 /* Interlaced TV output */
+      VG_MODEFLAG_INT_ADDRESS | VG_MODEFLAG_INVERT_SHFCLK,         /* Interlaced addressing*/
+	  1920, 1080,                                                  /* 2:1 downscaling.     */
+	  0, 0,                                                        /* No mode dimensions.  */
+	  0, 0,                                                        /* No panel dimensions. */
+      0, 0, 0, 0, 0,                                               /* No panel registers   */
+	  0x0780, 0x0780, 0x07AD, 0x0805, 0x0898, 0x0898,     	       /* horizontal timings   */
+	  0x021C, 0x021C, 0x021E, 0x0226, 0x0233, 0x0233,              /* vertical timings     */
+      0x021C, 0x021C, 0x021E, 0x0226, 0x0232, 0x0232,              /* even field timings   */
+	  (74L << 16) | ((2500L * 65536L) / 10000L),                   /* freq = 74.25 MHz     */
+	},
+};
+
+#define NUM_CIMARRON_DISPLAY_MODES sizeof(CimarronDisplayModes) / sizeof(VG_DISPLAY_MODE)
+
+/*-----------------------------------*/
+/*  PREDEFINED PLL FREQUENCIES       */
+/*-----------------------------------*/
+
+PLL_FREQUENCY CimarronPLLFrequencies[] =
+{
+    { 0x000031AC, (24L << 16)  | ((9230L * 65536L) / 10000L) }, /* 24.9230, - 4,27,13 */
+    { 0x0000215D, (25L << 16)  | ((1750L * 65536L) / 10000L) }, /* 25.1750, - 3,22,14 */
+    { 0x00001087, (27L << 16)  | ((0000L * 65536L) / 10000L) }, /* 27.0000, - 2, 9, 8 */
+    { 0x0000216C, (28L << 16)  | ((3220L * 65536L) / 10000L) }, /* 28.3220, - 3,23,13 */
+    { 0x0000218D, (28L << 16)  | ((5600L * 65536L) / 10000L) }, /* 28.5600, - 3,25,14 */
+    { 0x000010C9, (31L << 16)  | ((2000L * 65536L) / 10000L) }, /* 31.2000, - 2,13,10 */
+    { 0x00003147, (31L << 16)  | ((5000L * 65536L) / 10000L) }, /* 31.5000, - 4,21, 8 */
+    { 0x000010A7, (33L << 16)  | ((320L  * 65536L) / 10000L) }, /* 33.0320, - 2,11, 8 */
+    { 0x00002159, (35L << 16)  | ((1120L * 65536L) / 10000L) }, /* 35.1120, - 3,22,10 */
+    { 0x00004249, (35L << 16)  | ((5000L * 65536L) / 10000L) }, /* 35.5000, - 5,37,10 */
+    { 0x00000057, (36L << 16)  | ((0000L * 65536L) / 10000L) }, /* 36.0000, - 1, 6, 8 */
+    { 0x0000219A, (37L << 16)  | ((8890L * 65536L) / 10000L) }, /* 37.8890, - 3,26,11 */
+    { 0x00002158, (39L << 16)  | ((1680L * 65536L) / 10000L) }, /* 39.1680, - 3,22, 9 */
+    { 0x00000045, (40L << 16)  | ((0000L * 65536L) / 10000L) }, /* 40.0000, - 1, 5, 6 */
+    { 0x00000089, (43L << 16)  | ((1630L * 65536L) / 10000L) }, /* 43.1630, - 1, 9,10 */
+    { 0x000010E7, (44L << 16)  | ((9000L * 65536L) / 10000L) }, /* 44.9000, - 2,15, 8 */
+    { 0x00002136, (45L << 16)  | ((7200L * 65536L) / 10000L) }, /* 45.7200, - 3,20, 7 */
+    { 0x00003207, (49L << 16)  | ((5000L * 65536L) / 10000L) }, /* 49.5000, - 4,33, 8 */
+    { 0x00002187, (50L << 16)  | ((0000L * 65536L) / 10000L) }, /* 50.0000, - 3,25, 8 */
+    { 0x00004286, (56L << 16)  | ((2500L * 65536L) / 10000L) }, /* 56.2500, - 5,41, 7 */
+    { 0x000010E5, (60L << 16)  | ((650L  * 65536L) / 10000L) }, /* 60.0650, - 2,15, 6 */
+    { 0x00004214, (65L << 16)  | ((0000L * 65536L) / 10000L) }, /* 65.0000, - 5,34, 5 */
+    { 0x00001105, (68L << 16)  | ((1790L * 65536L) / 10000L) }, /* 68.1790, - 2,17, 6 */
+    { 0x000031E4, (74L << 16)  | ((2500L * 65536L) / 10000L) }, /* 74.2500, - 4,31, 5 */
+    { 0x00003183, (75L << 16)  | ((0000L * 65536L) / 10000L) }, /* 75.0000, - 4,25, 4 */
+    { 0x00004284, (78L << 16)  | ((7500L * 65536L) / 10000L) }, /* 78.7500, - 5,41, 5 */
+    { 0x00001104, (81L << 16)  | ((6000L * 65536L) / 10000L) }, /* 81.6000, - 2,17, 5 */
+    { 0x00006363, (94L << 16)  | ((5000L * 65536L) / 10000L) }, /* 94.5000, - 7,55, 4 */
+    { 0x00005303, (97L << 16)  | ((5200L * 65536L) / 10000L) }, /* 97.5200, - 6,49, 4 */
+    { 0x00002183, (100L << 16) | ((1870L * 65536L) / 10000L) }, /* 100.187, - 3,25, 4 */
+    { 0x00002122, (101L << 16) | ((4200L * 65536L) / 10000L) }, /* 101.420, - 3,19, 3 */
+    { 0x00001081, (108L << 16) | ((0000L * 65536L) / 10000L) }, /* 108.00,  - 2, 9, 2 */
+    { 0x00006201, (113L << 16) | ((3100L * 65536L) / 10000L) }, /* 113.31,  - 7,33, 2 */
+    { 0x00000041, (119L << 16) | ((6500L * 65536L) / 10000L) }, /* 119.65,  - 1, 5, 2 */
+    { 0x000041A1, (129L << 16) | ((6000L * 65536L) / 10000L) }, /* 129.60,  - 5,27, 2 */
+    { 0x00002182, (133L << 16) | ((5000L * 65536L) / 10000L) }, /* 133.50,  - 3,25, 3 */
+    { 0x000041B1, (135L << 16) | ((0000L * 65536L) / 10000L) }, /* 135.00,  - 5,28, 2 */
+    { 0x00000051, (144L << 16) | ((0000L * 65536L) / 10000L) }, /* 144.00,  - 1, 6, 2 */
+    { 0x000041E1, (148L << 16) | ((5000L * 65536L) / 10000L) }, /* 148.50,  - 5,31, 2 */
+    { 0x000062D1, (157L << 16) | ((5000L * 65536L) / 10000L) }, /* 157.50,  - 7,46, 2 */
+    { 0x000031A1, (162L << 16) | ((0000L * 65536L) / 10000L) }, /* 162.00,  - 4,27, 2 */
+    { 0x00000061, (169L << 16) | ((2030L * 65536L) / 10000L) }, /* 169.203, - 1, 7, 2 */
+    { 0x00004231, (172L << 16) | ((8000L * 65536L) / 10000L) }, /* 172.800, - 5,36, 2 */
+    { 0x00002151, (175L << 16) | ((5000L * 65536L) / 10000L) }, /* 175.50,  - 3,22, 2 */
+    { 0x000052E1, (189L << 16) | ((0000L * 65536L) / 10000L) }, /* 189.00,  - 6,47, 2 */
+    { 0x00000071, (192L << 16) | ((0000L * 65536L) / 10000L) }, /* 192.00,  - 1, 8, 2 */
+    { 0x00003201, (198L << 16) | ((0000L * 65536L) / 10000L) }, /* 198.00,  - 4,33, 2 */
+    { 0x00004291, (202L << 16) | ((5000L * 65536L) / 10000L) }, /* 202.50,  - 5,42, 2 */
+    { 0x00001101, (204L << 16) | ((7500L * 65536L) / 10000L) }, /* 204.75,  - 2,17, 2 */
+    { 0x00007481, (218L << 16) | ((2500L * 65536L) / 10000L) }, /* 218.25,  - 8,73, 2 */
+    { 0x00004170, (229L << 16) | ((5000L * 65536L) / 10000L) }, /* 229.50,  - 5,24, 1 */
+    { 0x00006210, (234L << 16) | ((0000L * 65536L) / 10000L) }, /* 234.00,  - 7,34, 1 */
+    { 0x00003140, (251L << 16) | ((1820L * 65536L) / 10000L) }, /* 251.182, - 4,21, 1 */
+    { 0x00006250, (261L << 16) | ((0000L * 65536L) / 10000L) }, /* 261.00,  - 7,38, 1 */
+    { 0x000041C0, (278L << 16) | ((4000L * 65536L) / 10000L) }, /* 278.40,  - 5,29, 1 */
+    { 0x00005220, (280L << 16) | ((6400L * 65536L) / 10000L) }, /* 280.64,  - 6,35, 1 */
+    { 0x00000050, (288L << 16) | ((0000L * 65536L) / 10000L) }, /* 288.00,  - 1, 6, 1 */
+    { 0x000041E0, (297L << 16) | ((0000L * 65536L) / 10000L) }, /* 297.00,  - 5,31, 1 */
+    { 0x00002130, (320L << 16) | ((2070L * 65536L) / 10000L) }, /* 320.207, - 3,20, 1 */
+    { 0x00006310, (341L << 16) | ((3490L * 65536L) / 10000L) }  /* 341.349, - 7,50, 1 */
+};
+
+#define NUM_CIMARRON_PLL_FREQUENCIES sizeof(CimarronPLLFrequencies) / sizeof(PLL_FREQUENCY)
+
+/*-----------------------------------*/
+/*  PREDEFINED FILTER COEFFICIENTS   */
+/*-----------------------------------*/
+
+unsigned long CimarronHorizontalGraphicsFilter[][2] =
+{
+	{0x1284A7D5, 0x000017D5 }, /*  -43,  297,  296,  -43,    5  */
+    {0x12A497D7, 0x000013D6 }, /*  -41,  293,  298,  -42,    4  */
+    {0x12D48BD7, 0x000013D6 }, /*  -41,  290,  301,  -42,    4  */
+    {0x13147FD7, 0x000013D5 }, /*  -41,  287,  305,  -43,    4  */
+    {0x133473D8, 0x000013D5 }, /*  -40,  284,  307,  -43,    4  */
+    {0x136467D8, 0x000013D5 }, /*  -40,  281,  310,  -43,    4  */
+    {0x13945FD8, 0x000013D4 }, /*  -40,  279,  313,  -44,    4  */
+    {0x13B453D9, 0x000013D4 }, /*  -39,  276,  315,  -44,    4  */
+    {0x13E447D9, 0x000013D4 }, /*  -39,  273,  318,  -44,    4  */
+    {0x14143BDA, 0x000013D3 }, /*  -38,  270,  321,  -45,    4  */
+    {0x143433DA, 0x000013D3 }, /*  -38,  268,  323,  -45,    4  */
+    {0x146427DA, 0x000013D3 }, /*  -38,  265,  326,  -45,    4  */
+    {0x14941BDB, 0x000013D2 }, /*  -37,  262,  329,  -46,    4  */
+    {0x14C40FDB, 0x000013D2 }, /*  -37,  259,  332,  -46,    4  */
+    {0x14F407DA, 0x000017D1 }, /*  -38,  257,  335,  -47,    5  */
+    {0x1503FBDC, 0x000013D2 }, /*  -36,  254,  336,  -46,    4  */
+    {0x1543F3DB, 0x000017D0 }, /*  -37,  252,  340,  -48,    5  */
+    {0x1563E3DD, 0x000013D1 }, /*  -35,  248,  342,  -47,    4  */
+    {0x1593D7DD, 0x000013D1 }, /*  -35,  245,  345,  -47,    4  */
+    {0x15B3CFDD, 0x000013D1 }, /*  -35,  243,  347,  -47,    4  */
+    {0x15E3C3DE, 0x000013D0 }, /*  -34,  240,  350,  -48,    4  */
+    {0x1613B7DE, 0x000013D0 }, /*  -34,  237,  353,  -48,    4  */
+    {0x1633ABDF, 0x000013D0 }, /*  -33,  234,  355,  -48,    4  */
+    {0x16639FDF, 0x000013D0 }, /*  -33,  231,  358,  -48,    4  */
+    {0x167397E0, 0x000013D0 }, /*  -32,  229,  359,  -48,    4  */
+    {0x16B38BE0, 0x000013CF }, /*  -32,  226,  363,  -49,    4  */
+    {0x16E383DF, 0x000017CE }, /*  -33,  224,  366,  -50,    5  */
+    {0x170373E1, 0x000013CF }, /*  -31,  220,  368,  -49,    4  */
+    {0x17236BE1, 0x000013CF }, /*  -31,  218,  370,  -49,    4  */
+    {0x17435FE2, 0x000013CF }, /*  -30,  215,  372,  -49,    4  */
+    {0x177353E2, 0x000013CF }, /*  -30,  212,  375,  -49,    4  */
+    {0x17B34BE1, 0x000017CD }, /*  -31,  210,  379,  -51,    5  */
+    {0x17C33FE3, 0x000013CE }, /*  -29,  207,  380,  -50,    4  */
+    {0x17F333E3, 0x000013CE }, /*  -29,  204,  383,  -50,    4  */
+    {0x181327E4, 0x000013CE }, /*  -28,  201,  385,  -50,    4  */
+    {0x18431FE3, 0x000017CD }, /*  -29,  199,  388,  -51,    5  */
+    {0x186313E4, 0x000013CE }, /*  -28,  196,  390,  -50,    4  */
+    {0x188307E5, 0x000013CE }, /*  -27,  193,  392,  -50,    4  */
+    {0x18B2FBE5, 0x000013CE }, /*  -27,  190,  395,  -50,    4  */
+    {0x18C2F3E6, 0x000013CE }, /*  -26,  188,  396,  -50,    4  */
+    {0x18F2E7E6, 0x000013CE }, /*  -26,  185,  399,  -50,    4  */
+    {0x1912DBE7, 0x000013CE }, /*  -25,  182,  401,  -50,    4  */
+    {0x1952D3E6, 0x000017CC }, /*  -26,  180,  405,  -52,    5  */
+    {0x1972CBE6, 0x000017CC }, /*  -26,  178,  407,  -52,    5  */
+    {0x1992BFE7, 0x000017CC }, /*  -25,  175,  409,  -52,    5  */
+    {0x19C2B3E7, 0x000017CC }, /*  -25,  172,  412,  -52,    5  */
+    {0x19D2A7E9, 0x000013CD }, /*  -23,  169,  413,  -51,    4  */
+    {0x1A029FE8, 0x000017CC }, /*  -24,  167,  416,  -52,    5  */
+    {0x1A1293E9, 0x000013CE }, /*  -23,  164,  417,  -50,    4  */
+    {0x1A3287EA, 0x000013CE }, /*  -22,  161,  419,  -50,    4  */
+    {0x1A627FE9, 0x000017CD }, /*  -23,  159,  422,  -51,    5  */
+    {0x1A7273EB, 0x000013CE }, /*  -21,  156,  423,  -50,    4  */
+    {0x1AA267EB, 0x000013CE }, /*  -21,  153,  426,  -50,    4  */
+    {0x1AC25FEB, 0x000013CE }, /*  -21,  151,  428,  -50,    4  */
+    {0x1AE253EC, 0x000013CE }, /*  -20,  148,  430,  -50,    4  */
+    {0x1B124BEB, 0x000017CD }, /*  -21,  146,  433,  -51,    5  */
+    {0x1B223FED, 0x000013CE }, /*  -19,  143,  434,  -50,    4  */
+    {0x1B5237EC, 0x000017CD }, /*  -20,  141,  437,  -51,    5  */
+    {0x1B622BED, 0x000013CF }, /*  -19,  138,  438,  -49,    4  */
+    {0x1B821FEE, 0x000013CF }, /*  -18,  135,  440,  -49,    4  */
+    {0x1BA217EE, 0x000013CF }, /*  -18,  133,  442,  -49,    4  */
+    {0x1BC20BEF, 0x000013CF }, /*  -17,  130,  444,  -49,    4  */
+    {0x1BE203EF, 0x000013CF }, /*  -17,  128,  446,  -49,    4  */
+    {0x1C01FBEE, 0x000017CF }, /*  -18,  126,  448,  -49,    5  */
+    {0x1C11EFF0, 0x000013D0 }, /*  -16,  123,  449,  -48,    4  */
+    {0x1C41E7EF, 0x000017CF }, /*  -17,  121,  452,  -49,    5  */
+    {0x1C61DFEF, 0x000017CF }, /*  -17,  119,  454,  -49,    5  */
+    {0x1C61D3F1, 0x000013D1 }, /*  -15,  116,  454,  -47,    4  */
+    {0x1C91CBF0, 0x000017D0 }, /*  -16,  114,  457,  -48,    5  */
+    {0x1CA1BFF2, 0x000013D1 }, /*  -14,  111,  458,  -47,    4  */
+    {0x1CC1B3F2, 0x000013D2 }, /*  -14,  108,  460,  -46,    4  */
+    {0x1CE1AFF1, 0x000017D1 }, /*  -15,  107,  462,  -47,    5  */
+    {0x1CF1A3F3, 0x000013D2 }, /*  -13,  104,  463,  -46,    4  */
+    {0x1D1197F3, 0x000013D3 }, /*  -13,  101,  465,  -45,    4  */
+    {0x1D3197F2, 0x000013D2 }, /*  -14,  101,  467,  -46,    4  */
+    {0x1D518BF3, 0x000013D2 }, /*  -13,   98,  469,  -46,    4  */
+    {0x1D6183F3, 0x000013D3 }, /*  -13,   96,  470,  -45,    4  */
+    {0x1D817BF3, 0x000013D3 }, /*  -13,   94,  472,  -45,    4  */
+    {0x1D916FF4, 0x000013D4 }, /*  -12,   91,  473,  -44,    4  */
+    {0x1DB167F4, 0x000013D4 }, /*  -12,   89,  475,  -44,    4  */
+    {0x1DC15FF4, 0x000013D5 }, /*  -12,   87,  476,  -43,    4  */
+    {0x1DE153F5, 0x000013D5 }, /*  -11,   84,  478,  -43,    4  */
+    {0x1DF14BF5, 0x000013D6 }, /*  -11,   82,  479,  -42,    4  */
+    {0x1E1143F5, 0x000013D6 }, /*  -11,   80,  481,  -42,    4  */
+    {0x1E1137F7, 0x00000FD8 }, /*   -9,   77,  481,  -40,    3  */
+    {0x1E3133F6, 0x000013D7 }, /*  -10,   76,  483,  -41,    4  */
+    {0x1E412BF6, 0x000013D8 }, /*  -10,   74,  484,  -40,    4  */
+    {0x1E611FF7, 0x000013D8 }, /*   -9,   71,  486,  -40,    4  */
+    {0x1E7117F7, 0x000013D9 }, /*   -9,   69,  487,  -39,    4  */
+    {0x1E810FF7, 0x000013DA }, /*   -9,   67,  488,  -38,    4  */
+    {0x1E9107F8, 0x000013DA }, /*   -8,   65,  489,  -38,    4  */
+    {0x1EA0FFF8, 0x000013DB }, /*   -8,   63,  490,  -37,    4  */
+    {0x1EB0F3F9, 0x00000FDD }, /*   -7,   60,  491,  -35,    3  */
+    {0x1ED0EFF8, 0x000013DC }, /*   -8,   59,  493,  -36,    4  */
+    {0x1EE0E7F9, 0x00000FDD }, /*   -7,   57,  494,  -35,    3  */
+    {0x1EF0DFF9, 0x00000FDE }, /*   -7,   55,  495,  -34,    3  */
+    {0x1F00D7F9, 0x00000FDF }, /*   -7,   53,  496,  -33,    3  */
+    {0x1F10CFFA, 0x00000FDF }, /*   -6,   51,  497,  -33,    3  */
+    {0x1F20C7FA, 0x00000FE0 }, /*   -6,   49,  498,  -32,    3  */
+    {0x1F20C3FA, 0x00000FE1 }, /*   -6,   48,  498,  -31,    3  */
+    {0x1F30BBFA, 0x00000FE2 }, /*   -6,   46,  499,  -30,    3  */
+    {0x1F40AFFB, 0x00000FE3 }, /*   -5,   43,  500,  -29,    3  */
+    {0x1F50A7FB, 0x00000FE4 }, /*   -5,   41,  501,  -28,    3  */
+    {0x1F60A3FB, 0x00000FE4 }, /*   -5,   40,  502,  -28,    3  */
+    {0x1F709BFB, 0x00000FE5 }, /*   -5,   38,  503,  -27,    3  */
+    {0x1F7093FC, 0x00000FE6 }, /*   -4,   36,  503,  -26,    3  */
+    {0x1F808FFC, 0x00000BE7 }, /*   -4,   35,  504,  -25,    2  */
+    {0x1F9087FC, 0x00000BE8 }, /*   -4,   33,  505,  -24,    2  */
+    {0x1F9083FC, 0x00000BE9 }, /*   -4,   32,  505,  -23,    2  */
+    {0x1FA077FD, 0x00000BEA }, /*   -3,   29,  506,  -22,    2  */
+    {0x1FA073FD, 0x00000BEB }, /*   -3,   28,  506,  -21,    2  */
+    {0x1FB06BFD, 0x00000BEC }, /*   -3,   26,  507,  -20,    2  */
+    {0x1FC063FD, 0x00000BED }, /*   -3,   24,  508,  -19,    2  */
+    {0x1FC05BFE, 0x00000BEE }, /*   -2,   22,  508,  -18,    2  */
+    {0x1FC057FE, 0x00000BEF }, /*   -2,   21,  508,  -17,    2  */
+    {0x1FD053FE, 0x000007F0 }, /*   -2,   20,  509,  -16,    1  */
+    {0x1FD04BFE, 0x000007F2 }, /*   -2,   18,  509,  -14,    1  */
+    {0x1FE043FE, 0x000007F3 }, /*   -2,   16,  510,  -13,    1  */
+    {0x1FE03BFF, 0x000007F4 }, /*   -1,   14,  510,  -12,    1  */
+    {0x1FE037FF, 0x000007F5 }, /*   -1,   13,  510,  -11,    1  */
+    {0x1FE033FF, 0x000007F6 }, /*   -1,   12,  510,  -10,    1  */
+    {0x1FF02BFF, 0x000007F7 }, /*   -1,   10,  511,   -9,    1  */
+    {0x1FF027FF, 0x000003F9 }, /*   -1,    9,  511,   -7,    0  */
+    {0x1FF01C00, 0x000003FA }, /*    0,    7,  511,   -6,    0  */
+    {0x1FF01800, 0x000003FB }, /*    0,    6,  511,   -5,    0  */
+    {0x1FF01400, 0x000003FC }, /*    0,    5,  511,   -4,    0  */
+    {0x1FF00C00, 0x000003FE }, /*    0,    3,  511,   -2,    0  */
+    {0x1FF00800, 0x000003FF }, /*    0,    2,  511,   -1,    0  */
+    {0x1FF00400, 0x00000000 }, /*    0,    1,  511,    0,    0  */
+    {0x1FFFFC00, 0x00000002 }, /*    0,   -1,  511,    2,    0  */
+    {0x1FFFF800, 0x00000003 }, /*    0,   -2,  511,    3,    0  */
+    {0x1FFFF000, 0x00000005 }, /*    0,   -4,  511,    5,    0  */
+    {0x1FFFEC00, 0x00000006 }, /*    0,   -5,  511,    6,    0  */
+    {0x1FFFE800, 0x00000007 }, /*    0,   -6,  511,    7,    0  */
+    {0x1FFFE400, 0x000FFC09 }, /*    0,   -7,  511,    9,   -1  */
+    {0x1FFFDC01, 0x000FFC0A }, /*    1,   -9,  511,   10,   -1  */
+    {0x1FEFDC01, 0x000FFC0B }, /*    1,   -9,  510,   11,   -1  */
+    {0x1FEFD401, 0x000FFC0D }, /*    1,  -11,  510,   13,   -1  */
+    {0x1FEFD001, 0x000FFC0E }, /*    1,  -12,  510,   14,   -1  */
+    {0x1FEFCC01, 0x000FF810 }, /*    1,  -13,  510,   16,   -2  */
+    {0x1FDFCC01, 0x000FF811 }, /*    1,  -13,  509,   17,   -2  */
+    {0x1FDFC401, 0x000FF813 }, /*    1,  -15,  509,   19,   -2  */
+    {0x1FCFC002, 0x000FF814 }, /*    2,  -16,  508,   20,   -2  */
+    {0x1FCFB802, 0x000FF816 }, /*    2,  -18,  508,   22,   -2  */
+    {0x1FCFB402, 0x000FF418 }, /*    2,  -19,  508,   24,   -3  */
+    {0x1FBFB402, 0x000FF419 }, /*    2,  -19,  507,   25,   -3  */
+    {0x1FAFB002, 0x000FF41B }, /*    2,  -20,  506,   27,   -3  */
+    {0x1FAFA802, 0x000FF41D }, /*    2,  -22,  506,   29,   -3  */
+    {0x1F9FA802, 0x000FF01F }, /*    2,  -22,  505,   31,   -4  */
+    {0x1F9FA402, 0x000FF020 }, /*    2,  -23,  505,   32,   -4  */
+    {0x1F8FA002, 0x000FF022 }, /*    2,  -24,  504,   34,   -4  */
+    {0x1F7F9803, 0x000FF024 }, /*    3,  -26,  503,   36,   -4  */
+    {0x1F7F9403, 0x000FEC26 }, /*    3,  -27,  503,   38,   -5  */
+    {0x1F6F9003, 0x000FEC28 }, /*    3,  -28,  502,   40,   -5  */
+    {0x1F5F9003, 0x000FEC29 }, /*    3,  -28,  501,   41,   -5  */
+    {0x1F4F8C03, 0x000FEC2B }, /*    3,  -29,  500,   43,   -5  */
+    {0x1F3F8C03, 0x000FE82D }, /*    3,  -29,  499,   45,   -6  */
+    {0x1F2F8803, 0x000FE82F }, /*    3,  -30,  498,   47,   -6  */
+    {0x1F2F8003, 0x000FE831 }, /*    3,  -32,  498,   49,   -6  */
+    {0x1F1F7C03, 0x000FE833 }, /*    3,  -33,  497,   51,   -6  */
+    {0x1F0F7C03, 0x000FE435 }, /*    3,  -33,  496,   53,   -7  */
+    {0x1EFF7803, 0x000FE437 }, /*    3,  -34,  495,   55,   -7  */
+    {0x1EEF7403, 0x000FE439 }, /*    3,  -35,  494,   57,   -7  */
+    {0x1EDF7004, 0x000FE03B }, /*    4,  -36,  493,   59,   -8  */
+    {0x1EBF7403, 0x000FE43C }, /*    3,  -35,  491,   60,   -7  */
+    {0x1EAF6C04, 0x000FE03F }, /*    4,  -37,  490,   63,   -8  */
+    {0x1E9F6804, 0x000FE041 }, /*    4,  -38,  489,   65,   -8  */
+    {0x1E8F6804, 0x000FDC43 }, /*    4,  -38,  488,   67,   -9  */
+    {0x1E7F6404, 0x000FDC45 }, /*    4,  -39,  487,   69,   -9  */
+    {0x1E6F6004, 0x000FDC47 }, /*    4,  -40,  486,   71,   -9  */
+    {0x1E4F6404, 0x000FD849 }, /*    4,  -39,  484,   73,  -10  */
+    {0x1E3F6004, 0x000FD84B }, /*    4,  -40,  483,   75,  -10  */
+    {0x1E1F6003, 0x000FDC4D }, /*    3,  -40,  481,   77,   -9  */
+    {0x1E1F5804, 0x000FD450 }, /*    4,  -42,  481,   80,  -11  */
+    {0x1DFF5804, 0x000FD452 }, /*    4,  -42,  479,   82,  -11  */
+    {0x1DEF5404, 0x000FD454 }, /*    4,  -43,  478,   84,  -11  */
+    {0x1DCF5804, 0x000FD056 }, /*    4,  -42,  476,   86,  -12  */
+    {0x1DBF5004, 0x000FD059 }, /*    4,  -44,  475,   89,  -12  */
+    {0x1D9F5004, 0x000FD05B }, /*    4,  -44,  473,   91,  -12  */
+    {0x1D8F5004, 0x000FCC5D }, /*    4,  -44,  472,   93,  -13  */
+    {0x1D6F5004, 0x000FCC5F }, /*    4,  -44,  470,   95,  -13  */
+    {0x1D5F4804, 0x000FCC62 }, /*    4,  -46,  469,   98,  -13  */
+    {0x1D3F4C04, 0x000FC864 }, /*    4,  -45,  467,  100,  -14  */
+    {0x1D1F4C04, 0x000FCC65 }, /*    4,  -45,  465,  101,  -13  */
+    {0x1CFF4804, 0x000FCC68 }, /*    4,  -46,  463,  104,  -13  */
+    {0x1CEF4405, 0x000FC46B }, /*    5,  -47,  462,  107,  -15  */
+    {0x1CCF4804, 0x000FC86C }, /*    4,  -46,  460,  108,  -14  */
+    {0x1CAF4404, 0x000FC86F }, /*    4,  -47,  458,  111,  -14  */
+    {0x1C9F4005, 0x000FC072 }, /*    5,  -48,  457,  114,  -16  */
+    {0x1C6F4404, 0x000FC474 }, /*    4,  -47,  454,  116,  -15  */
+    {0x1C6F3C05, 0x000FBC77 }, /*    5,  -49,  454,  119,  -17  */
+    {0x1C4F3C05, 0x000FBC79 }, /*    5,  -49,  452,  121,  -17  */
+    {0x1C1F4004, 0x000FC07B }, /*    4,  -48,  449,  123,  -16  */
+    {0x1C0F3C05, 0x000FB87E }, /*    5,  -49,  448,  126,  -18  */
+    {0x1BEF3C04, 0x000FBC80 }, /*    4,  -49,  446,  128,  -17  */
+    {0x1BCF3C04, 0x000FBC82 }, /*    4,  -49,  444,  130,  -17  */
+    {0x1BAF3C04, 0x000FB885 }, /*    4,  -49,  442,  133,  -18  */
+    {0x1B8F3C04, 0x000FB887 }, /*    4,  -49,  440,  135,  -18  */
+    {0x1B6F3C04, 0x000FB48A }, /*    4,  -49,  438,  138,  -19  */
+    {0x1B5F3405, 0x000FB08D }, /*    5,  -51,  437,  141,  -20  */
+    {0x1B2F3804, 0x000FB48F }, /*    4,  -50,  434,  143,  -19  */
+    {0x1B1F3405, 0x000FAC92 }, /*    5,  -51,  433,  146,  -21  */
+    {0x1AEF3804, 0x000FB094 }, /*    4,  -50,  430,  148,  -20  */
+    {0x1ACF3804, 0x000FAC97 }, /*    4,  -50,  428,  151,  -21  */
+    {0x1AAF3804, 0x000FAC99 }, /*    4,  -50,  426,  153,  -21  */
+    {0x1A7F3804, 0x000FAC9C }, /*    4,  -50,  423,  156,  -21  */
+    {0x1A6F3405, 0x000FA49F }, /*    5,  -51,  422,  159,  -23  */
+    {0x1A3F3804, 0x000FA8A1 }, /*    4,  -50,  419,  161,  -22  */
+    {0x1A1F3804, 0x000FA4A4 }, /*    4,  -50,  417,  164,  -23  */
+    {0x1A0F3005, 0x000FA0A7 }, /*    5,  -52,  416,  167,  -24  */
+    {0x19DF3404, 0x000FA4A9 }, /*    4,  -51,  413,  169,  -23  */
+    {0x19CF3005, 0x000F9CAC }, /*    5,  -52,  412,  172,  -25  */
+    {0x199F3005, 0x000F9CAF }, /*    5,  -52,  409,  175,  -25  */
+    {0x197F3005, 0x000F98B2 }, /*    5,  -52,  407,  178,  -26  */
+    {0x195F3005, 0x000F98B4 }, /*    5,  -52,  405,  180,  -26  */
+    {0x191F3804, 0x000F9CB6 }, /*    4,  -50,  401,  182,  -25  */
+    {0x18FF3804, 0x000F98B9 }, /*    4,  -50,  399,  185,  -26  */
+    {0x18CF3804, 0x000F98BC }, /*    4,  -50,  396,  188,  -26  */
+    {0x18BF3804, 0x000F94BE }, /*    4,  -50,  395,  190,  -27  */
+    {0x188F3804, 0x000F94C1 }, /*    4,  -50,  392,  193,  -27  */
+    {0x186F3804, 0x000F90C4 }, /*    4,  -50,  390,  196,  -28  */
+    {0x184F3405, 0x000F8CC7 }, /*    5,  -51,  388,  199,  -29  */
+    {0x181F3804, 0x000F90C9 }, /*    4,  -50,  385,  201,  -28  */
+    {0x17FF3804, 0x000F8CCC }, /*    4,  -50,  383,  204,  -29  */
+    {0x17CF3804, 0x000F8CCF }, /*    4,  -50,  380,  207,  -29  */
+    {0x17BF3405, 0x000F84D2 }, /*    5,  -51,  379,  210,  -31  */
+    {0x177F3C04, 0x000F88D4 }, /*    4,  -49,  375,  212,  -30  */
+    {0x174F3C04, 0x000F88D7 }, /*    4,  -49,  372,  215,  -30  */
+    {0x172F3C04, 0x000F84DA }, /*    4,  -49,  370,  218,  -31  */
+    {0x170F3C04, 0x000F84DC }, /*    4,  -49,  368,  220,  -31  */
+    {0x16EF3805, 0x000F7CE0 }, /*    5,  -50,  366,  224,  -33  */
+    {0x16BF3C04, 0x000F80E2 }, /*    4,  -49,  363,  226,  -32  */
+    {0x167F4004, 0x000F80E5 }, /*    4,  -48,  359,  229,  -32  */
+    {0x166F4004, 0x000F7CE7 }, /*    4,  -48,  358,  231,  -33  */
+    {0x163F4004, 0x000F7CEA }, /*    4,  -48,  355,  234,  -33  */
+    {0x161F4004, 0x000F78ED }, /*    4,  -48,  353,  237,  -34  */
+    {0x15EF4004, 0x000F78F0 }, /*    4,  -48,  350,  240,  -34  */
+    {0x15BF4404, 0x000F74F3 }, /*    4,  -47,  347,  243,  -35  */
+    {0x159F4404, 0x000F74F5 }, /*    4,  -47,  345,  245,  -35  */
+    {0x156F4404, 0x000F74F8 }, /*    4,  -47,  342,  248,  -35  */
+    {0x154F4005, 0x000F6CFC }, /*    5,  -48,  340,  252,  -37  */
+    {0x150F4804, 0x000F70FE }, /*    4,  -46,  336,  254,  -36  */
+    {0x14FF4405, 0x000F6901 }, /*    5,  -47,  335,  257,  -38  */
+    {0x14CF4804, 0x000F6D03 }, /*    4,  -46,  332,  259,  -37  */
+    {0x149F4804, 0x000F6D06 }, /*    4,  -46,  329,  262,  -37  */
+    {0x146F4C04, 0x000F6909 }, /*    4,  -45,  326,  265,  -38  */
+    {0x143F4C04, 0x000F690C }, /*    4,  -45,  323,  268,  -38  */
+    {0x141F4C04, 0x000F690E }, /*    4,  -45,  321,  270,  -38  */
+    {0x13EF5004, 0x000F6511 }, /*    4,  -44,  318,  273,  -39  */
+    {0x13BF5004, 0x000F6514 }, /*    4,  -44,  315,  276,  -39  */
+    {0x139F5004, 0x000F6117 }, /*    4,  -44,  313,  279,  -40  */
+    {0x136F5404, 0x000F6119 }, /*    4,  -43,  310,  281,  -40  */
+    {0x133F5404, 0x000F611C }, /*    4,  -43,  307,  284,  -40  */
+    {0x131F5404, 0x000F5D1F }, /*    4,  -43,  305,  287,  -41  */
+    {0x12DF5C04, 0x000F5D21 }, /*    4,  -41,  301,  289,  -41  */
+    {0x12AF5C04, 0x000F5D24 }, /*    4,  -41,  298,  292,  -41  */
+};
+
+unsigned long CimarronVerticalGraphicsFilter[] =
+{
+	0x3F840D05, /* 261, 259,  -8  */
+    0x3F841D01, /* 257, 263,  -8  */
+    0x3F8428FE, /* 254, 266,  -8  */
+    0x3F8438FA, /* 250, 270,  -8  */
+    0x3F8444F7, /* 247, 273,  -8  */
+    0x3F8450F4, /* 244, 276,  -8  */
+    0x3F845CF1, /* 241, 279,  -8  */
+    0x3F8468EE, /* 238, 282,  -8  */
+    0x3F8474EB, /* 235, 285,  -8  */
+    0x3F8480E8, /* 232, 288,  -8  */
+    0x3F7490E5, /* 229, 292,  -9  */
+    0x3F749CE2, /* 226, 295,  -9  */
+    0x3F74ACDE, /* 222, 299,  -9  */
+    0x3F74B8DB, /* 219, 302,  -9  */
+    0x3F74C0D9, /* 217, 304,  -9  */
+    0x3F74CCD6, /* 214, 307,  -9  */
+    0x3F74D8D3, /* 211, 310,  -9  */
+    0x3F74E8CF, /* 207, 314,  -9  */
+    0x3F74F4CC, /* 204, 317,  -9  */
+    0x3F7500C9, /* 201, 320,  -9  */
+    0x3F750CC6, /* 198, 323,  -9  */
+    0x3F7518C3, /* 195, 326,  -9  */
+    0x3F7520C1, /* 193, 328,  -9  */
+    0x3F7530BD, /* 189, 332,  -9  */
+    0x3F753CBA, /* 186, 335,  -9  */
+    0x3F7548B7, /* 183, 338,  -9  */
+    0x3F6558B4, /* 180, 342, -10  */
+    0x3F6560B2, /* 178, 344, -10  */
+    0x3F656CAF, /* 175, 347, -10  */
+    0x3F6578AC, /* 172, 350, -10  */
+    0x3F6584A9, /* 169, 353, -10  */
+    0x3F658CA7, /* 167, 355, -10  */
+    0x3F6598A4, /* 164, 358, -10  */
+    0x3F65A8A0, /* 160, 362, -10  */
+    0x3F65B09E, /* 158, 364, -10  */
+    0x3F65BC9B, /* 155, 367, -10  */
+    0x3F65C499, /* 153, 369, -10  */
+    0x3F65D096, /* 150, 372, -10  */
+    0x3F55E093, /* 147, 376, -11  */
+    0x3F55E891, /* 145, 378, -11  */
+    0x3F55F48E, /* 142, 381, -11  */
+    0x3F56008B, /* 139, 384, -11  */
+    0x3F560C88, /* 136, 387, -11  */
+    0x3F561486, /* 134, 389, -11  */
+    0x3F562083, /* 131, 392, -11  */
+    0x3F562881, /* 129, 394, -11  */
+    0x3F56347E, /* 126, 397, -11  */
+    0x3F56407B, /* 123, 400, -11  */
+    0x3F564879, /* 121, 402, -11  */
+    0x3F465876, /* 118, 406, -12  */
+    0x3F466074, /* 116, 408, -12  */
+    0x3F466872, /* 114, 410, -12  */
+    0x3F46746F, /* 111, 413, -12  */
+    0x3F467C6D, /* 109, 415, -12  */
+    0x3F46846B, /* 107, 417, -12  */
+    0x3F468C69, /* 105, 419, -12  */
+    0x3F469866, /* 102, 422, -12  */
+    0x3F46A064, /* 100, 424, -12  */
+    0x3F46AC61, /*  97, 427, -12  */
+    0x3F46B45F, /*  95, 429, -12  */
+    0x3F46BC5D, /*  93, 431, -12  */
+    0x3F46C45B, /*  91, 433, -12  */
+    0x3F46CC59, /*  89, 435, -12  */
+    0x3F36DC56, /*  86, 439, -13  */
+    0x3F36E454, /*  84, 441, -13  */
+    0x3F36EC52, /*  82, 443, -13  */
+    0x3F36F450, /*  80, 445, -13  */
+    0x3F36FC4E, /*  78, 447, -13  */
+    0x3F37004D, /*  77, 448, -13  */
+    0x3F370C4A, /*  74, 451, -13  */
+    0x3F371448, /*  72, 453, -13  */
+    0x3F371C46, /*  70, 455, -13  */
+    0x3F372444, /*  68, 457, -13  */
+    0x3F372C42, /*  66, 459, -13  */
+    0x3F373440, /*  64, 461, -13  */
+    0x3F37383F, /*  63, 462, -13  */
+    0x3F37403D, /*  61, 464, -13  */
+    0x3F37483B, /*  59, 466, -13  */
+    0x3F375039, /*  57, 468, -13  */
+    0x3F375438, /*  56, 469, -13  */
+    0x3F375C36, /*  54, 471, -13  */
+    0x3F376434, /*  52, 473, -13  */
+    0x3F376833, /*  51, 474, -13  */
+    0x3F377031, /*  49, 476, -13  */
+    0x3F377430, /*  48, 477, -13  */
+    0x3F377C2E, /*  46, 479, -13  */
+    0x3F37842C, /*  44, 481, -13  */
+    0x3F37882B, /*  43, 482, -13  */
+    0x3F47882A, /*  42, 482, -12  */
+    0x3F479028, /*  40, 484, -12  */
+    0x3F479427, /*  39, 485, -12  */
+    0x3F479C25, /*  37, 487, -12  */
+    0x3F47A024, /*  36, 488, -12  */
+    0x3F47A822, /*  34, 490, -12  */
+    0x3F47AC21, /*  33, 491, -12  */
+    0x3F47B020, /*  32, 492, -12  */
+    0x3F57B01F, /*  31, 492, -11  */
+    0x3F57B81D, /*  29, 494, -11  */
+    0x3F57BC1C, /*  28, 495, -11  */
+    0x3F57C01B, /*  27, 496, -11  */
+    0x3F57C41A, /*  26, 497, -11  */
+    0x3F67C818, /*  24, 498, -10  */
+    0x3F67CC17, /*  23, 499, -10  */
+    0x3F67D016, /*  22, 500, -10  */
+    0x3F67D415, /*  21, 501, -10  */
+    0x3F67D814, /*  20, 502, -10  */
+    0x3F77D813, /*  19, 502,  -9  */
+    0x3F77DC12, /*  18, 503,  -9  */
+    0x3F77E011, /*  17, 504,  -9  */
+    0x3F87E010, /*  16, 504,  -8  */
+    0x3F87E40F, /*  15, 505,  -8  */
+    0x3F87E80E, /*  14, 506,  -8  */
+    0x3F97E80D, /*  13, 506,  -7  */
+    0x3F97EC0C, /*  12, 507,  -7  */
+    0x3F97F00B, /*  11, 508,  -7  */
+    0x3FA7F00A, /*  10, 508,  -6  */
+    0x3FA7F409, /*   9, 509,  -6  */
+    0x3FB7F408, /*   8, 509,  -5  */
+    0x3FB7F408, /*   8, 509,  -5  */
+    0x3FC7F806, /*   6, 510,  -4  */
+    0x3FC7F806, /*   6, 510,  -4  */
+    0x3FD7F805, /*   5, 510,  -3  */
+    0x3FD7FC04, /*   4, 511,  -3  */
+    0x3FE7FC03, /*   3, 511,  -2  */
+    0x3FE7FC03, /*   3, 511,  -2  */
+    0x3FF7FC02, /*   2, 511,  -1  */
+    0x3FF7FC02, /*   2, 511,  -1  */
+    0x0007FC01, /*   1, 511,   0  */
+    0x0007FC01, /*   1, 511,   0  */
+    0x0007FC01, /*   1, 511,   0  */
+    0x0027FFFF, /*  -1, 511,   2  */
+    0x0027FFFF, /*  -1, 511,   2  */
+    0x0037FFFE, /*  -2, 511,   3  */
+    0x0037FFFE, /*  -2, 511,   3  */
+    0x0047FFFD, /*  -3, 511,   4  */
+    0x0047FBFE, /*  -2, 510,   4  */
+    0x0057FBFD, /*  -3, 510,   5  */
+    0x0067FBFC, /*  -4, 510,   6  */
+    0x0077F7FC, /*  -4, 509,   7  */
+    0x0077F7FC, /*  -4, 509,   7  */
+    0x0087F7FB, /*  -5, 509,   8  */
+    0x0097F3FB, /*  -5, 508,   9  */
+    0x00A7F3FA, /*  -6, 508,  10  */
+    0x00B7EFFA, /*  -6, 507,  11  */
+    0x00C7EBFA, /*  -6, 506,  12  */
+    0x00D7EBF9, /*  -7, 506,  13  */
+    0x00E7E7F9, /*  -7, 505,  14  */
+    0x00F7E3F9, /*  -7, 504,  15  */
+    0x0107E3F8, /*  -8, 504,  16  */
+    0x0117DFF8, /*  -8, 503,  17  */
+    0x0127DBF8, /*  -8, 502,  18  */
+    0x0137DBF7, /*  -9, 502,  19  */
+    0x0147D7F7, /*  -9, 501,  20  */
+    0x0157D3F7, /*  -9, 500,  21  */
+    0x0167CFF7, /*  -9, 499,  22  */
+    0x0177CBF7, /*  -9, 498,  23  */
+    0x0197C7F6, /* -10, 497,  25  */
+    0x01A7C3F6, /* -10, 496,  26  */
+    0x01B7BFF6, /* -10, 495,  27  */
+    0x01C7BBF6, /* -10, 494,  28  */
+    0x01E7B3F6, /* -10, 492,  30  */
+    0x01F7B3F5, /* -11, 492,  31  */
+    0x0207AFF5, /* -11, 491,  32  */
+    0x0217ABF5, /* -11, 490,  33  */
+    0x0237A3F5, /* -11, 488,  35  */
+    0x02479FF5, /* -11, 487,  36  */
+    0x026797F5, /* -11, 485,  38  */
+    0x027793F5, /* -11, 484,  39  */
+    0x02978BF5, /* -11, 482,  41  */
+    0x02A78BF4, /* -12, 482,  42  */
+    0x02B787F4, /* -12, 481,  43  */
+    0x02D77FF4, /* -12, 479,  45  */
+    0x02F777F4, /* -12, 477,  47  */
+    0x030773F4, /* -12, 476,  48  */
+    0x03276BF4, /* -12, 474,  50  */
+    0x033767F4, /* -12, 473,  51  */
+    0x03575FF4, /* -12, 471,  53  */
+    0x037757F4, /* -12, 469,  55  */
+    0x038753F4, /* -12, 468,  56  */
+    0x03A74BF4, /* -12, 466,  58  */
+    0x03C743F4, /* -12, 464,  60  */
+    0x03E73BF4, /* -12, 462,  62  */
+    0x040737F3, /* -13, 461,  64  */
+    0x04272FF3, /* -13, 459,  66  */
+    0x044727F3, /* -13, 457,  68  */
+    0x04671FF3, /* -13, 455,  70  */
+    0x048717F3, /* -13, 453,  72  */
+    0x04A70FF3, /* -13, 451,  74  */
+    0x04C703F4, /* -12, 448,  76  */
+    0x04D6FFF4, /* -12, 447,  77  */
+    0x04F6F7F4, /* -12, 445,  79  */
+    0x0516EFF4, /* -12, 443,  81  */
+    0x0536E7F4, /* -12, 441,  83  */
+    0x0556DFF4, /* -12, 439,  85  */
+    0x0586CFF5, /* -11, 435,  88  */
+    0x05A6C7F5, /* -11, 433,  90  */
+    0x05C6BFF5, /* -11, 431,  92  */
+    0x05F6B7F4, /* -12, 429,  95  */
+    0x0616AFF4, /* -12, 427,  97  */
+    0x0636A3F5, /* -11, 424,  99  */
+    0x06569BF5, /* -11, 422, 101  */
+    0x06868FF5, /* -11, 419, 104  */
+    0x06A687F5, /* -11, 417, 106  */
+    0x06C67FF5, /* -11, 415, 108  */
+    0x06E677F5, /* -11, 413, 110  */
+    0x07166BF5, /* -11, 410, 113  */
+    0x073663F5, /* -11, 408, 115  */
+    0x07665BF4, /* -12, 406, 118  */
+    0x07964BF5, /* -11, 402, 121  */
+    0x07B643F5, /* -11, 400, 123  */
+    0x07D637F6, /* -10, 397, 125  */
+    0x08062BF6, /* -10, 394, 128  */
+    0x082623F6, /* -10, 392, 130  */
+    0x085617F6, /* -10, 389, 133  */
+    0x08760FF6, /* -10, 387, 135  */
+    0x08B603F5, /* -11, 384, 139  */
+    0x08D5F7F6, /* -10, 381, 141  */
+    0x0905EBF6, /* -10, 378, 144  */
+    0x0925E3F6, /* -10, 376, 146  */
+    0x0955D3F7, /*  -9, 372, 149  */
+    0x0985C7F7, /*  -9, 369, 152  */
+    0x09A5BFF7, /*  -9, 367, 154  */
+    0x09D5B3F7, /*  -9, 364, 157  */
+    0x0A05ABF6, /* -10, 362, 160  */
+    0x0A359BF7, /*  -9, 358, 163  */
+    0x0A658FF7, /*  -9, 355, 166  */
+    0x0A9587F6, /* -10, 353, 169  */
+    0x0AB57BF7, /*  -9, 350, 171  */
+    0x0AE56FF7, /*  -9, 347, 174  */
+    0x0B1563F7, /*  -9, 344, 177  */
+    0x0B455BF6, /* -10, 342, 180  */
+    0x0B754BF7, /*  -9, 338, 183  */
+    0x0BA53FF7, /*  -9, 335, 186  */
+    0x0BD533F7, /*  -9, 332, 189  */
+    0x0C0523F8, /*  -8, 328, 192  */
+    0x0C251BF8, /*  -8, 326, 194  */
+    0x0C550FF8, /*  -8, 323, 197  */
+    0x0C9503F7, /*  -9, 320, 201  */
+    0x0CC4F7F7, /*  -9, 317, 204  */
+    0x0CF4EBF7, /*  -9, 314, 207  */
+    0x0D24DBF8, /*  -8, 310, 210  */
+    0x0D54CFF8, /*  -8, 307, 213  */
+    0x0D84C3F8, /*  -8, 304, 216  */
+    0x0DB4BBF7, /*  -9, 302, 219  */
+    0x0DE4AFF7, /*  -9, 299, 222  */
+    0x0E149FF8, /*  -8, 295, 225  */
+    0x0E4493F8, /*  -8, 292, 228  */
+    0x0E7483F9, /*  -7, 288, 231  */
+    0x0EA477F9, /*  -7, 285, 234  */
+    0x0ED46BF9, /*  -7, 282, 237  */
+    0x0F045FF9, /*  -7, 279, 240  */
+    0x0F4453F8, /*  -8, 276, 244  */
+    0x0F7447F8, /*  -8, 273, 247  */
+    0x0FA43BF8, /*  -8, 270, 250  */
+    0x0FD42BF9, /*  -7, 266, 253  */
+    0x10041FF9, /*  -7, 263, 256  */
+};
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_msr.c xf86-video-nsc-2.8.1/src/cim/cim_msr.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_msr.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_msr.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,379 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron MSR access routines.  These routines allow the user to query the
+  * state of the GeodeLink Bus and read and write model-specfic registers.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*--------------------------------------------------------------*/
+/* MSR GLOBALS                                                  */
+/* These variables hold a local copy of the GeodeLink mapping   */
+/* as well as a lookup table for easy device addressing.        */
+/*--------------------------------------------------------------*/
+
+GEODELINK_NODE gliu_nodes[24];
+GEODELINK_NODE msr_dev_lookup[MSR_DEVICE_EMPTY];
+
+#define GET_DEVICE_ID(macrohigh, macrolow) ((macrolow >> 12) & 0xFF)
+
+/*---------------------------------------------------------------------------
+ * msr_init_table
+ *
+ * This routine intializes the internal MSR table in Cimarron.  This table is
+ * used for any MSR device accesses.
+ *---------------------------------------------------------------------------*/
+
+int	msr_init_table (void)
+{
+	Q_WORD msr_value;
+	unsigned int i, j;
+	int return_value = CIM_STATUS_OK;
+
+	/* CHECK FOR VALID GEODELINK CONFIGURATION                                     */
+	/* The CPU and the three GLIUs are assumed to be at known static addresses, so */
+	/* we will check the device IDs at these addresses as proof of a valid         */
+	/* GeodeLink configuration                                                     */
+
+	MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_VAIL, &msr_value);
+    if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_VAIL)
+       	return_value = CIM_STATUS_ERROR;
+
+	MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU0, &msr_value);
+    if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
+    	return_value = CIM_STATUS_ERROR;
+
+	MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU1, &msr_value);
+    if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
+    	return_value = CIM_STATUS_ERROR;
+
+	MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU2, &msr_value);
+    if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
+    	return_value = CIM_STATUS_ERROR;
+
+	if (return_value == CIM_STATUS_OK)
+	{
+		/* BUILD LOCAL COPY OF THE GEODELINK BUS */
+
+		msr_create_geodelink_table (gliu_nodes);
+
+		/* CLEAR TABLE STATUS */
+
+		for (i = 0; i < MSR_DEVICE_EMPTY; i++)
+			msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
+		
+		/* CREATE EASY LOOKUP TABLE FOR FUTURE HARDWARE ACCESS    */
+		/* Note that MSR_DEVICE_EMPTY is the index after the last */
+		/* available device.  Also note that we fill in known     */
+		/* devices before filling in the rest of the table.       */
+
+		msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU0].address_from_cpu   = MSR_ADDRESS_GLIU0;
+		msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU0].device_id          = MSR_DEVICE_PRESENT;
+		msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU1].address_from_cpu   = MSR_ADDRESS_GLIU1;
+		msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU1].device_id          = MSR_DEVICE_PRESENT;
+		msr_dev_lookup[MSR_DEVICE_5535_GLIU].address_from_cpu      = MSR_ADDRESS_GLIU2;
+		msr_dev_lookup[MSR_DEVICE_5535_GLIU].device_id             = MSR_DEVICE_PRESENT;
+		msr_dev_lookup[MSR_DEVICE_GEODELX_VAIL].address_from_cpu    = MSR_ADDRESS_VAIL;
+		msr_dev_lookup[MSR_DEVICE_GEODELX_VAIL].device_id           = MSR_DEVICE_PRESENT;
+
+		for (i = 0; i < MSR_DEVICE_EMPTY; i++)
+		{
+			if (msr_dev_lookup[i].device_id == MSR_DEVICE_NOTFOUND)
+			{
+				for (j = 0; j < 24; j++)
+				{
+					if (gliu_nodes[j].device_id == i)
+						break;					
+				}
+
+				if (j == 24)
+					msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
+				else
+				{
+					msr_dev_lookup[i].device_id = MSR_DEVICE_PRESENT;
+					msr_dev_lookup[i].address_from_cpu = gliu_nodes[j].address_from_cpu;
+				}
+			}
+		}	
+	}
+	else
+	{
+		/* ERROR OUT THE GEODELINK TABLES */
+
+		for (i = 0; i < 24; i++)
+		{
+			gliu_nodes[i].address_from_cpu = 0xFFFFFFFF;
+			gliu_nodes[i].device_id = MSR_DEVICE_EMPTY;
+		}
+
+		for (i = 0; i < MSR_DEVICE_EMPTY; i++)
+		{
+			msr_dev_lookup[i].address_from_cpu = 0xFFFFFFFF;
+			msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
+		}
+	}
+    return return_value;
+}
+
+/*---------------------------------------------------------------------------
+ * msr_create_geodelink_table
+ *
+ * This routine dumps the contents of the GeodeLink bus into an array of
+ * 24 GEODELINK_NODE structures.  Indexes 0-7 represent ports 0-7 of GLIU0,
+ * indexes 8-15 represent ports 0-7 of GLIU1 and indexes 16-23 represent
+ * ports 0-7 of GLIU2 (5535).
+ *---------------------------------------------------------------------------*/
+
+int msr_create_geodelink_table (GEODELINK_NODE *gliu_nodes)
+{
+	unsigned long mbiu_port_count, reflective;
+    unsigned long port, index;
+	unsigned long gliu_count = 0;
+	int glcp_count = 0;
+	int usb_count  = 0;
+	int mpci_count = 0;
+	Q_WORD msr_value;
+
+	/* ALL THREE GLIUS ARE IN ONE ARRAY                               */
+	/* Entries 0-7 contain the port information for GLIU0, entries    */
+	/* 8-15 contain GLIU1 and 15-23 contain GLIU2.  We perform the    */
+	/* enumeration in two passes.  The first simply fills in the      */
+	/* addresses and class codes at each node.  The second pass       */
+	/* translates the class codes into indexes into Cimarron's device */
+	/* lookup table.                                                  */
+
+	/* COUNT GLIU0 PORTS */
+
+	MSR_READ (MSR_GLIU_CAP, MSR_ADDRESS_GLIU0, &msr_value);
+	mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
+
+	/* FIND REFLECTIVE PORT */
+	/* Query the GLIU for the port through which we are communicating. */
+	/* We will avoid accesses to this port to avoid a self-reference.  */
+	
+	MSR_READ (MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU0, &msr_value);
+	reflective = msr_value.low & WHOAMI_MASK;
+
+	/* SPECIAL CASE FOR PORT 0 */
+	/* GLIU0 port 0 is a special case, as it points back to GLIU0.  GLIU0 */
+	/* responds at address 0x10000xxx, which does not equal 0 << 29.      */
+
+	gliu_nodes[0].address_from_cpu = MSR_ADDRESS_GLIU0;
+	gliu_nodes[0].device_id = MSR_CLASS_CODE_GLIU;
+
+	/* ENUMERATE ALL PORTS */
+
+	for (port = 1; port < 8; port++)
+	{
+		/* FILL IN ADDRESS */
+
+		gliu_nodes[port].address_from_cpu = port << 29;
+
+		if (port == reflective)
+			gliu_nodes[port].device_id = MSR_CLASS_CODE_REFLECTIVE;
+		else if (port > mbiu_port_count)
+			gliu_nodes[port].device_id = MSR_CLASS_CODE_UNPOPULATED;
+	    else
+		{
+			MSR_READ (MSR_GEODELINK_CAP, gliu_nodes[port].address_from_cpu, &msr_value);
+			gliu_nodes[port].device_id = GET_DEVICE_ID (msr_value.high, msr_value.low);
+		}
+	}
+	
+	/* COUNT GLIU1 PORTS */
+
+	MSR_READ (MSR_GLIU_CAP, MSR_ADDRESS_GLIU1, &msr_value);
+	mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
+
+	/* FIND REFLECTIVE PORT */
+	
+	MSR_READ (MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU1, &msr_value);
+	reflective = msr_value.low & WHOAMI_MASK;
+
+	/* ENUMERATE ALL PORTS */
+
+	for (port = 0; port < 8; port++)
+	{
+		index = port + 8;
+
+		/* FILL IN ADDRESS */
+
+		gliu_nodes[index].address_from_cpu = (0x02l << 29) + (port << 26);
+
+		if (port == reflective)
+			gliu_nodes[index].device_id = MSR_CLASS_CODE_REFLECTIVE;
+		else if (port > mbiu_port_count)
+			gliu_nodes[index].device_id = MSR_CLASS_CODE_UNPOPULATED;
+	    else
+		{
+			MSR_READ (MSR_GEODELINK_CAP, gliu_nodes[index].address_from_cpu, &msr_value);
+			gliu_nodes[index].device_id = GET_DEVICE_ID (msr_value.high, msr_value.low);
+		}
+	}
+
+	/* COUNT GLIU2 PORTS */
+
+	MSR_READ (MSR_GLIU_CAP, MSR_ADDRESS_GLIU2, &msr_value);
+	mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
+
+	/* FIND REFLECTIVE PORT */
+	
+	MSR_READ (MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU2, &msr_value);
+	reflective = msr_value.low & WHOAMI_MASK;
+
+    /* FILL IN PORT 0 AND 1 */
+    /* Port 0 on 5535 is MBIU2.  Port 1 is MPCI, but it is referenced at */
+    /* a special address.                                                */
+
+    gliu_nodes[16].address_from_cpu = MSR_ADDRESS_GLIU2;
+    gliu_nodes[16].device_id = MSR_CLASS_CODE_GLIU;
+
+    gliu_nodes[17].address_from_cpu = MSR_ADDRESS_5535MPCI;
+    gliu_nodes[17].device_id = MSR_CLASS_CODE_MPCI;
+
+	/* ENUMERATE ALL PORTS */
+
+	for (port = 2; port < 8; port++)
+	{
+		index = port + 16;
+
+		/* FILL IN ADDRESS */
+
+		gliu_nodes[index].address_from_cpu =
+			(0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
+
+		if (port == reflective)
+			gliu_nodes[index].device_id = MSR_CLASS_CODE_REFLECTIVE;
+		else if (port > mbiu_port_count)
+			gliu_nodes[index].device_id = MSR_CLASS_CODE_UNPOPULATED;
+	    else
+		{
+			MSR_READ (MSR_GEODELINK_CAP, gliu_nodes[index].address_from_cpu, &msr_value);
+			gliu_nodes[index].device_id = GET_DEVICE_ID (msr_value.high, msr_value.low);
+		}
+	}
+
+	/* SECOND PASS - TRANSLATION */
+	/* Now that the class codes for each device are stored in the  */
+	/* array, we walk through the array and translate the class    */
+	/* codes to table indexes.  For class codes that have multiple */
+	/* instances, the table indexes are sequential.                */
+
+	for (port = 0; port < 24; port++)
+	{
+		/* SPECIAL CASE FOR GLIU UNITS */
+		/* A GLIU can be both on another port and on its own port.  These  */
+		/* end up as the same address, but are shown as duplicate nodes in */
+		/* the GeodeLink table.                                            */
+
+		if ((port & 7) == 0)
+			gliu_count = port >> 3;
+
+		switch (gliu_nodes[port].device_id)
+		{
+			/* UNPOPULATED OR REFLECTIVE NODES */
+
+			case MSR_CLASS_CODE_UNPOPULATED: index = MSR_DEVICE_EMPTY;       break;	
+			case MSR_CLASS_CODE_REFLECTIVE:  index = MSR_DEVICE_REFLECTIVE;  break;
+			
+			/* KNOWN CLASS CODES */
+			
+			case MSR_CLASS_CODE_GLIU: index = MSR_DEVICE_GEODELX_GLIU0 + gliu_count++;  break;
+			case MSR_CLASS_CODE_GLCP: index = MSR_DEVICE_GEODELX_GLCP  + glcp_count++;  break;
+			case MSR_CLASS_CODE_MPCI: index = MSR_DEVICE_GEODELX_MPCI  + mpci_count++;  break;
+			case MSR_CLASS_CODE_USB:  index = MSR_DEVICE_5535_USB2 + usb_count++; break;
+            case MSR_CLASS_CODE_USB2: index = MSR_DEVICE_5536_USB_2_0; break;
+			case MSR_CLASS_CODE_ATAC: index = MSR_DEVICE_5535_ATAC;    break;
+			case MSR_CLASS_CODE_MDD:  index = MSR_DEVICE_5535_MDD;     break;
+			case MSR_CLASS_CODE_ACC:  index = MSR_DEVICE_5535_ACC;     break;
+			case MSR_CLASS_CODE_MC:   index = MSR_DEVICE_GEODELX_MC;   break;
+			case MSR_CLASS_CODE_GP:   index = MSR_DEVICE_GEODELX_GP;   break;
+			case MSR_CLASS_CODE_VG:   index = MSR_DEVICE_GEODELX_VG;   break;
+			case MSR_CLASS_CODE_DF:   index = MSR_DEVICE_GEODELX_DF;   break;
+			case MSR_CLASS_CODE_FG:   index = MSR_DEVICE_GEODELX_FG;   break;
+			case MSR_CLASS_CODE_VIP:  index = MSR_DEVICE_GEODELX_VIP;  break;
+			case MSR_CLASS_CODE_AES:  index = MSR_DEVICE_GEODELX_AES;  break;
+			case MSR_CLASS_CODE_VAIL: index = MSR_DEVICE_GEODELX_VAIL; break;
+			default: index = MSR_DEVICE_EMPTY; break;
+		}
+
+		gliu_nodes[port].device_id = index;
+	}
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * msr_create_device_list
+ *
+ * This routine dumps a list of all known GeodeLX/5535 devices as well as their
+ * respective status and address.
+ *---------------------------------------------------------------------------*/
+
+int msr_create_device_list (GEODELINK_NODE *gliu_nodes, int max_devices)
+{
+	int i, count;
+
+	if (max_devices < MSR_DEVICE_EMPTY) count = max_devices;
+	else                                count = MSR_DEVICE_EMPTY;
+
+	for (i = 0; i < count; i++)
+	{
+		gliu_nodes[i].address_from_cpu = msr_dev_lookup[i].address_from_cpu;
+		gliu_nodes[i].device_id        = msr_dev_lookup[i].device_id;
+	}
+
+	return CIM_STATUS_OK;
+}
+
+/*--------------------------------------------------------------------
+ * msr_read64
+ *
+ * Performs a 64-bit read from 'msr_register' in device 'device'.  'device' is
+ * an index into Cimarron's table of known GeodeLink devices.
+ *-------------------------------------------------------------------*/
+
+int msr_read64 (unsigned long device, unsigned long msr_register,
+	Q_WORD *msr_value)
+{
+	if (device < MSR_DEVICE_EMPTY)
+	{
+		if (msr_dev_lookup[device].device_id == MSR_DEVICE_PRESENT)
+		{
+			MSR_READ (msr_register, msr_dev_lookup[device].address_from_cpu, msr_value);
+			return CIM_STATUS_OK;
+		}
+	}
+
+    msr_value->low = msr_value->high = 0;
+	return CIM_STATUS_DEVNOTFOUND;
+}
+
+/*--------------------------------------------------------------------
+ * msr_write64
+ *
+ * Performs a 64-bit write to 'msr_register' in device 'device'.  'device' is
+ * an index into Cimarron's table of known GeodeLink devices.
+ *-------------------------------------------------------------------*/
+
+int msr_write64 (unsigned long device, unsigned long msr_register,
+	Q_WORD *msr_value)
+{
+	if (device < MSR_DEVICE_EMPTY)
+	{
+		if (msr_dev_lookup[device].device_id == MSR_DEVICE_PRESENT)
+		{
+			MSR_WRITE (msr_register, msr_dev_lookup[device].address_from_cpu, msr_value);
+			return CIM_STATUS_OK;
+		}
+	}
+	return CIM_STATUS_DEVNOTFOUND;
+}
+
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_parm.h xf86-video-nsc-2.8.1/src/cim/cim_parm.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_parm.h	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_parm.h	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1268 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron user definitions.
+  * </DOC_AMD_STD>
+  *
+  */
+
+#ifndef _cim_parm_h
+#define _cim_parm_h
+
+/*===================================================*/
+/*       CIMARRON RETURN VALUE DEFINITIONS           */
+/*===================================================*/
+
+#define CIM_STATUS_OK                     0x00000000
+#define CIM_STATUS_ERROR                  0x00000001
+#define CIM_STATUS_INVALIDPARAMS          0x00000002
+#define CIM_STATUS_DEVNOTFOUND            0x00000004
+#define CIM_STATUS_INVALIDSCALE           0x00000008
+#define CIM_STATUS_INEXACTMATCH           0x00000010
+#define CIM_STATUS_NOLOCK                 0x00000020
+#define CIM_STATUS_CPUNOTFOUND            0x00000040
+#define CIM_STATUS_DISPLAYUNAVAILABLE     0x00000080
+#define CIM_STATUS_NOTFOUND               0x00000100
+
+/*===================================================*/
+/*       CIMARRON CPU DEFINITIONS                    */
+/*===================================================*/
+
+#define CIM_CPU_GEODEGX                   0x00000001
+#define CIM_CPU_GEODELX                   0x00000002
+
+#define CIM_SB_5535                       0x00000001
+#define CIM_SB_5536                       0x00000002
+
+/*===================================================*/
+/* MSR PARAMETERS                                    */
+/*===================================================*/
+
+/*-------------------------------------------------------------*/
+/* GEODELINK DEVICE IDS                                        */
+/* These values uniquely identify all known GeodeLink devices  */
+/* in GeodeLX and its companion, 5535/6.  For multiple devices */
+/* of the same class (GLIU, USB, etc.) the table order is used */
+/* to to identify the expected device order, in terms of on    */
+/* which GLIU the device is found, and on which port.          */
+/*-------------------------------------------------------------*/
+
+#define MSR_DEVICE_GEODELX_GLIU0          0x00
+#define MSR_DEVICE_GEODELX_GLIU1          0x01
+#define MSR_DEVICE_5535_GLIU              0x02
+#define MSR_DEVICE_GEODELX_GLCP           0x03
+#define MSR_DEVICE_5535_GLCP              0x04
+#define MSR_DEVICE_GEODELX_MPCI           0x05
+#define MSR_DEVICE_5535_MPCI              0x06
+#define MSR_DEVICE_GEODELX_MC             0x07
+#define MSR_DEVICE_GEODELX_GP             0x08
+#define MSR_DEVICE_GEODELX_VG             0x09
+#define MSR_DEVICE_GEODELX_VIP            0x0A
+#define MSR_DEVICE_GEODELX_AES            0x0B
+#define MSR_DEVICE_GEODELX_DF             0x0C
+#define MSR_DEVICE_GEODELX_FG             0x0D
+#define MSR_DEVICE_GEODELX_VAIL           0x0E
+#define MSR_DEVICE_5536_USB_2_0           0x0F
+#define MSR_DEVICE_5535_USB2              0x10
+#define MSR_DEVICE_5535_USB1              0x11
+#define MSR_DEVICE_5535_ATAC              0x12
+#define MSR_DEVICE_5535_MDD               0x13
+#define MSR_DEVICE_5535_ACC               0x14
+#define MSR_DEVICE_EMPTY                  0x15
+#define MSR_DEVICE_REFLECTIVE             0x16
+#define MSR_DEVICE_PRESENT                0x17
+#define MSR_DEVICE_NOTFOUND               0x18
+
+/*---------------------------------------------*/
+/* GEODELINK TABLE ENTRY                       */
+/* The following structure represents one port */
+/* on a GeodeLink Interface Unit (GLIU)        */
+/*---------------------------------------------*/
+
+typedef struct tagGeodeLinkNode
+{
+	unsigned long address_from_cpu;
+	unsigned long device_id;
+
+} GEODELINK_NODE;
+
+/*---------------------------------------------*/
+/* QWORD DATA STRUCTURE                        */
+/* 64-bit data structure for MSR acess.        */
+/*---------------------------------------------*/
+
+typedef struct tagQ_WORD
+{
+	unsigned long high;
+	unsigned long low;
+
+} Q_WORD;
+
+/*===================================================*/
+/*       INITIALIZATION USER PARAMETERS              */
+/*===================================================*/
+
+typedef struct tagInitBaseAddresses
+{
+	unsigned long framebuffer_base;
+	unsigned long gp_register_base;
+	unsigned long vg_register_base;
+	unsigned long df_register_base;
+	unsigned long vip_register_base;
+	unsigned long framebuffer_size;
+
+} INIT_BASE_ADDRESSES;
+
+/*===================================================*/
+/*          GP USER PARAMETER DEFINITIONS            */
+/*===================================================*/
+
+/*---------------------------*/
+/* GP_DECLARE_BLT PARAMETERS */
+/*---------------------------*/
+
+#define CIMGP_BLTFLAGS_PRES_LUT          0x0001
+#define CIMGP_BLTFLAGS_PRES_COLOR_PAT    0x0002
+#define CIMGP_ENABLE_PREFETCH            0x0004
+#define CIMGP_BLTFLAGS_HAZARD            0x0008
+#define CIMGP_BLTFLAGS_INVERTMONO        0x0010
+#define CIMGP_BLTFLAGS_LIMITBUFFER       0x0020
+
+/*-----------------------------------*/
+/* GP_SET_ALPHA_OPERATION PARAMETERS */
+/*-----------------------------------*/
+
+#define CIMGP_APPLY_BLEND_TO_RGB         1
+#define CIMGP_APPLY_BLEND_TO_ALPHA       2
+#define CIMGP_APPLY_BLEND_TO_ALL         3
+
+#define CIMGP_ALPHA_TIMES_A              0
+#define CIMGP_BETA_TIMES_B               1
+#define CIMGP_A_PLUS_BETA_B              2
+#define CIMGP_ALPHA_A_PLUS_BETA_B        3
+
+#define CIMGP_CHANNEL_A_ALPHA            0
+#define CIMGP_CHANNEL_B_ALPHA            1
+#define CIMGP_CONSTANT_ALPHA             2
+#define CIMGP_ALPHA_EQUALS_ONE           3
+#define CIMGP_ALPHA_FROM_RGB_A           4
+#define CIMGP_ALPHA_FROM_RGB_B           5
+#define CIMGP_CONVERTED_ALPHA            6
+
+#define CIMGP_CHANNEL_A_SOURCE           0
+#define CIMGP_CHANNEL_A_DEST             1
+
+/*---------------------------------*/
+/* GP_SET_SOURCE_FORMAT PARAMETERS */
+/*---------------------------------*/
+
+#define CIMGP_SOURCE_FMT_3_3_2           0x00
+#define CIMGP_SOURCE_FMT_8BPP_INDEXED    0x01
+#define CIMGP_SOURCE_FMT_4_4_4_4         0x04
+#define CIMGP_SOURCE_FMT_12BPP_BGR       0x14
+#define CIMGP_SOURCE_FMT_1_5_5_5         0x05
+#define CIMGP_SOURCE_FMT_15BPP_BGR       0x15
+#define CIMGP_SOURCE_FMT_0_5_6_5         0x06
+#define CIMGP_SOURCE_FMT_16BPP_BGR       0x16
+#define CIMGP_SOURCE_FMT_YUYV            0x07
+#define CIMGP_SOURCE_FMT_UYVY            0x17
+#define CIMGP_SOURCE_FMT_8_8_8_8         0x08
+#define CIMGP_SOURCE_FMT_32BPP_BGR       0x18
+#define CIMGP_SOURCE_FMT_24BPP           0x0B
+#define CIMGP_SOURCE_FMT_4BPP_INDEXED    0x0D
+
+/*------------------------------------*/
+/* GP_SCREEN_TO_SCREEN_BLT PARAMETERS */
+/*------------------------------------*/
+
+#define CIMGP_NEGXDIR                    1
+#define CIMGP_NEGYDIR                    2
+
+/*------------------------------------*/
+/* GP_BRESENHAM_LINE PARAMETERS       */
+/*------------------------------------*/
+
+#define CIMGP_YMAJOR                     1
+#define CIMGP_POSMAJOR                   2
+#define CIMGP_POSMINOR                   4
+
+/*----------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING GP STATE */
+/*----------------------------------------------*/
+
+typedef struct tagGPSaveRestore
+{
+    unsigned long base_offset;
+    unsigned long cmd_top;
+    unsigned long cmd_bottom;
+    unsigned long cmd_base;
+    unsigned long cmd_read;
+
+} GP_SAVE_RESTORE;
+
+/*===================================================*/
+/*          VG USER PARAMETER DEFINITIONS            */
+/*===================================================*/
+
+/*-------------------------------------------*/
+/*       SUPPORTED TV ENCODERS               */
+/*-------------------------------------------*/
+
+#define VG_ENCODER_ADV7171                0x0001
+#define VG_ENCODER_SAA7127                0x0002
+#define VG_ENCODER_FS454                  0x0003
+#define VG_ENCODER_ADV7300                0x0004
+
+/*-------------------------------------------*/
+/*       SUPPORTED TV RESOLUTIONS            */
+/*-------------------------------------------*/
+
+#define VG_TVMODE_NTSC                    0x00000000
+#define VG_TVMODE_PAL                     0x00000001
+#define VG_TVMODE_480P                    0x00000002
+#define VG_TVMODE_720P                    0x00000003
+#define VG_TVMODE_1080I                   0x00000004
+#define VG_TVMODE_6X4_NTSC                0x00000005
+#define VG_TVMODE_8X6_NTSC                0x00000006
+#define VG_TVMODE_10X7_NTSC               0x00000007
+#define VG_TVMODE_6X4_PAL                 0x00000008
+#define VG_TVMODE_8X6_PAL                 0x00000009
+#define VG_TVMODE_10X7_PAL                0x0000000A
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR SETTING A DISPLAY MODE */
+/*-------------------------------------------*/
+
+#define VG_SUPPORTFLAG_8BPP               0x00000001
+#define VG_SUPPORTFLAG_12BPP              0x00000002
+#define VG_SUPPORTFLAG_15BPP              0x00000004
+#define VG_SUPPORTFLAG_16BPP              0x00000008
+#define VG_SUPPORTFLAG_24BPP              0x00000010
+#define VG_SUPPORTFLAG_32BPP              0x00000020
+#define VG_SUPPORTFLAG_56HZ               0x00000040
+#define VG_SUPPORTFLAG_60HZ               0x00000080
+#define VG_SUPPORTFLAG_70HZ               0x00000100
+#define VG_SUPPORTFLAG_72HZ               0x00000200
+#define VG_SUPPORTFLAG_75HZ               0x00000400
+#define VG_SUPPORTFLAG_85HZ               0x00000800
+#define VG_SUPPORTFLAG_90HZ               0x00001000
+#define VG_SUPPORTFLAG_100HZ              0x00002000
+#define VG_SUPPORTFLAG_HZMASK             0x00003FC0
+#define VG_SUPPORTFLAG_ADV7171            0x00004000
+#define VG_SUPPORTFLAG_SAA7127            0x00008000
+#define VG_SUPPORTFLAG_FS454              0x00010000
+#define VG_SUPPORTFLAG_ADV7300            0x00020000
+#define VG_SUPPORTFLAG_ENCODERMASK        0x0003C000
+#define VG_SUPPORTFLAG_PANEL              0x00040000
+#define VG_SUPPORTFLAG_TVOUT              0x00080000
+#define VG_SUPPORTFLAG_NTSC               0x00000000
+#define VG_SUPPORTFLAG_PAL                0x00100000
+#define VG_SUPPORTFLAG_480P               0x00200000
+#define VG_SUPPORTFLAG_720P               0x00300000
+#define VG_SUPPORTFLAG_1080I              0x00400000
+#define VG_SUPPORTFLAG_6X4_NTSC           0x00500000
+#define VG_SUPPORTFLAG_8X6_NTSC           0x00600000
+#define VG_SUPPORTFLAG_10X7_NTSC          0x00700000
+#define VG_SUPPORTFLAG_6X4_PAL            0x00800000
+#define VG_SUPPORTFLAG_8X6_PAL            0x00900000
+#define VG_SUPPORTFLAG_10X7_PAL           0x00A00000
+#define VG_SUPPORTFLAG_TVMODEMASK         0x00F00000
+
+#define VG_MODEFLAG_NEG_HSYNC             0x00000001
+#define VG_MODEFLAG_NEG_VSYNC             0x00000002
+#define VG_MODEFLAG_INTERLACED            0x00000004
+#define VG_MODEFLAG_PANELOUT              0x00000008
+#define VG_MODEFLAG_CENTERED              0x00000010
+#define VG_MODEFLAG_LINEARPITCH           0x00000020
+#define VG_MODEFLAG_TVOUT                 0x00000040
+#define VG_MODEFLAG_HALFCLOCK             0x00000080
+#define VG_MODEFLAG_QVGA                  0x00000100
+#define VG_MODEFLAG_EXCLUDEPLL            0x00000200
+#define VG_MODEFLAG_NOPANELTIMINGS        0x00000400
+#define VG_MODEFLAG_XVGA_TFT              0x00000800
+#define VG_MODEFLAG_CUSTOM_PANEL          0x00001000
+#define VG_MODEFLAG_CRT_AND_FP            0x00002000
+#define VG_MODEFLAG_LOW_BAND              0x00000000
+#define VG_MODEFLAG_AVG_BAND              0x00004000
+#define VG_MODEFLAG_HIGH_BAND             0x00008000
+#define VG_MODEFLAG_LEGACY_BAND           0x0000C000
+#define VG_MODEFLAG_BANDWIDTHMASK         0x0000C000
+#define VG_MODEFLAG_OVERRIDE_BAND         0x00010000
+#define VG_MODEFLAG_INT_ADDRESS           0x00000000
+#define VG_MODEFLAG_INT_LINEDOUBLE        0x00020000
+#define VG_MODEFLAG_INT_FLICKER           0x00040000
+#define VG_MODEFLAG_INT_MASK              0x00060000
+#define VG_MODEFLAG_INT_OVERRIDE          0x00080000
+#define VG_MODEFLAG_INVERT_SHFCLK         0x00100000
+#define VG_MODEFLAG_MANUAL_FREQUENCY      0x00200000
+#define VG_MODEFLAG_PLL_BYPASS            0x00400000
+#define VG_MODEFLAG_VIP_TO_DOT_CLOCK      0x00800000
+
+#define VG_MODEFLAG_VALIDUSERFLAGS        (VG_MODEFLAG_CRT_AND_FP     | \
+                                           VG_MODEFLAG_XVGA_TFT       | \
+                                           VG_MODEFLAG_NOPANELTIMINGS | \
+                                           VG_MODEFLAG_EXCLUDEPLL     | \
+                                           VG_MODEFLAG_LINEARPITCH)
+
+typedef struct tagVGDisplayMode
+{
+	/* DISPLAY MODE FLAGS */
+	/* Includes BPP, refresh rate information, interlacing, etc. */
+
+    unsigned long internal_flags;
+	unsigned long flags;
+
+	/* SOURCE RESOLUTION */
+	/* The following values reflect the resolution of the data in the frame */
+	/* buffer.  These values are used to enable scaling and filtering.      */
+
+	unsigned long src_width;
+	unsigned long src_height;
+
+	/* PANEL SETTINGS */
+	/* These allow a user to set a panel mode through the vg_set_custom_mode */
+	/* routine.  These values are only relevant if the VG_MODEFLAG_PANEL is  */
+	/* also set.                                                             */
+
+	unsigned long mode_width;
+	unsigned long mode_height;
+	unsigned long panel_width;
+	unsigned long panel_height;
+    unsigned long panel_tim1;
+    unsigned long panel_tim2;
+    unsigned long panel_dither_ctl;
+    unsigned long panel_pad_sel_low;
+    unsigned long panel_pad_sel_high;
+
+	/* OUTPUT TIMINGS */
+	/* If the active width and height do not match the source */
+	/* dimensions the graphics data will be scaled.           */
+
+	unsigned long hactive;
+	unsigned long hblankstart;
+	unsigned long hsyncstart;
+	unsigned long hsyncend;
+	unsigned long hblankend;
+	unsigned long htotal;
+
+	unsigned long vactive;
+	unsigned long vblankstart;
+	unsigned long vsyncstart;
+	unsigned long vsyncend;
+	unsigned long vblankend;
+	unsigned long vtotal;
+
+    unsigned long vactive_even;
+	unsigned long vblankstart_even;
+	unsigned long vsyncstart_even;
+	unsigned long vsyncend_even;
+	unsigned long vblankend_even;
+	unsigned long vtotal_even;
+
+	/* CLOCK FREQUENCY */
+
+	unsigned long frequency;
+
+} VG_DISPLAY_MODE;
+
+/*-------------------------------------------*/
+/*                PLL FLAGS                  */
+/*-------------------------------------------*/
+
+#define VG_PLL_DIVIDE_BY_2                0x00000001
+#define VG_PLL_DIVIDE_BY_4                0x00000002
+#define VG_PLL_BYPASS                     0x00000004
+#define VG_PLL_MANUAL                     0x00000008
+#define VG_PLL_VIP_CLOCK                  0x00000010
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR QUERYING DISPLAY MODES */
+/*-------------------------------------------*/
+
+typedef struct tagQueryDisplayMode
+{
+    int interlaced;
+    int halfclock;
+	unsigned long active_width;
+	unsigned long active_height;
+	unsigned long panel_width;
+	unsigned long panel_height;
+	unsigned long total_width;
+	unsigned long total_height;
+	unsigned long bpp;
+	unsigned long hz;
+	unsigned long frequency;
+	unsigned long query_flags;
+    unsigned long encoder;
+    unsigned long tvmode;
+
+} VG_QUERY_MODE;
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR QUERYING CURSOR DATA   */
+/*-------------------------------------------*/
+
+typedef struct tagCursorData
+{
+	int enable;
+	int color_cursor;
+	unsigned long cursor_offset;
+	unsigned long cursor_x;
+	unsigned long cursor_y;
+	unsigned long clipx;
+	unsigned long clipy;
+	unsigned long mono_color0;
+	unsigned long mono_color1;
+	unsigned long flags;
+
+} VG_CURSOR_DATA;
+
+/*------------------------------------------------*/
+/*          VG INTERRUPT STATUS SOURCES           */
+/*------------------------------------------------*/
+
+#define VG_INT_LINE_MATCH                 0x00010000
+#define VG_INT_VSYNC_LOSS                 0x00020000
+
+/*------------------------------------------------*/
+/* USER STRUCTURE FOR SETTING COMPRESSION DATA    */
+/*------------------------------------------------*/
+
+typedef struct tagCompressionData
+{
+	unsigned long compression_offset;
+	unsigned long pitch;
+	unsigned long size;
+	unsigned long flags;
+
+} VG_COMPRESSION_DATA;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING LINE INTERRUPTS  */
+/*-------------------------------------------------*/
+
+typedef struct tagInterruptInfo
+{
+	unsigned long line;
+	unsigned long flags;
+	int enable;
+
+} VG_INTERRUPT_PARAMS;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR PANNING THE DESKTOP          */
+/*-------------------------------------------------*/
+
+typedef struct tagPanningInfo
+{
+	unsigned long start_x;
+	unsigned long start_y;
+	int start_updated;
+
+} VG_PANNING_COORDINATES;
+
+/*--------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING THE VG STATE */
+/*--------------------------------------------------*/
+
+typedef struct tagVGSaveRestore
+{
+    /* VG REGISTERS */
+
+    unsigned long unlock;
+    unsigned long gcfg;
+    unsigned long dcfg;
+    unsigned long arb_cfg;
+    unsigned long fb_offset;
+    unsigned long cb_offset;
+    unsigned long cursor_offset;
+    unsigned long video_y_offset;
+    unsigned long video_u_offset;
+    unsigned long video_v_offset;
+    unsigned long dv_top;
+    unsigned long line_size;
+    unsigned long gfx_pitch;
+    unsigned long video_yuv_pitch;
+    unsigned long h_active;
+    unsigned long h_blank;
+    unsigned long h_sync;
+    unsigned long v_active;
+    unsigned long v_blank;
+    unsigned long v_sync;
+    unsigned long fb_active;
+    unsigned long cursor_x;
+    unsigned long cursor_y;
+    unsigned long vid_ds_delta;
+    unsigned long fb_base;
+    unsigned long dv_ctl;
+    unsigned long gfx_scale;
+    unsigned long irq_ctl;
+    unsigned long vbi_even_ctl;
+    unsigned long vbi_odd_ctl;
+    unsigned long vbi_hor_ctl;
+    unsigned long vbi_odd_line_enable;
+    unsigned long vbi_even_line_enable;
+    unsigned long vbi_pitch;
+    unsigned long color_key;
+    unsigned long color_key_mask;
+    unsigned long color_key_x;
+    unsigned long color_key_y;
+    unsigned long irq;
+    unsigned long genlk_ctl;
+    unsigned long vid_y_even_offset;
+    unsigned long vid_u_even_offset;
+    unsigned long vid_v_even_offset;
+    unsigned long vactive_even;
+    unsigned long vblank_even;
+    unsigned long vsync_even;
+    unsigned long h_coeff[512];
+    unsigned long v_coeff[256];
+    unsigned long palette[261];
+    unsigned long cursor_data[3072];
+    unsigned long dot_pll;
+    unsigned long pll_flags;
+
+    /* VG MSRS */
+
+    Q_WORD msr_cap;
+    Q_WORD msr_config;
+    Q_WORD msr_smi;
+    Q_WORD msr_error;
+    Q_WORD msr_pm;
+    Q_WORD msr_diag;
+    Q_WORD msr_spare;
+    Q_WORD msr_ram_ctl;
+
+} VG_SAVE_RESTORE;
+
+/*-------------------------------------------*/
+/* VG_GET_DISPLAY_MODE_INDEX PARAMETERS      */
+/*-------------------------------------------*/
+
+#define VG_QUERYFLAG_ACTIVEWIDTH          0x00000001
+#define VG_QUERYFLAG_ACTIVEHEIGHT         0x00000002
+#define VG_QUERYFLAG_TOTALWIDTH           0x00000004
+#define VG_QUERYFLAG_TOTALHEIGHT          0x00000008
+#define VG_QUERYFLAG_BPP                  0x00000010
+#define VG_QUERYFLAG_REFRESH              0x00000020
+#define VG_QUERYFLAG_PIXELCLOCK           0x00000040
+#define VG_QUERYFLAG_PIXELCLOCK_APPROX    0x00000080
+#define VG_QUERYFLAG_PANEL                0x00000100
+#define VG_QUERYFLAG_PANELWIDTH           0x00000200
+#define VG_QUERYFLAG_PANELHEIGHT          0x00000400
+#define VG_QUERYFLAG_TVOUT                0x00000800
+#define VG_QUERYFLAG_INTERLACED           0x00001000
+#define VG_QUERYFLAG_HALFCLOCK            0x00002000
+#define VG_QUERYFLAG_ENCODER              0x00004000
+#define VG_QUERYFLAG_TVMODE               0x00008000
+
+/*-----------------------------------------------*/
+/*         VG FLICKER FILTER SETTINGS            */
+/*-----------------------------------------------*/
+
+#define VG_FLICKER_FILTER_NONE            0x00000000
+#define VG_FLICKER_FILTER_1_16            0x10000000
+#define VG_FLICKER_FILTER_1_8             0x20000000
+#define VG_FLICKER_FILTER_1_4             0x40000000
+#define VG_FLICKER_FILTER_5_16            0x50000000
+#define VG_FLICKER_FILTER_MASK            0xF0000000
+
+/*-----------------------------------------------*/
+/*            VG CRC SOURCES                     */
+/*-----------------------------------------------*/
+
+#define VG_CRC_SOURCE_PREFILTER           0x00000000
+#define VG_CRC_SOURCE_PREFLICKER          0x00000001
+#define VG_CRC_SOURCE_POSTFLICKER         0x00000002
+#define VG_CRC_SOURCE_PREFILTER_EVEN      0x00000010
+#define VG_CRC_SOURCE_PREFLICKER_EVEN     0x00000011
+#define VG_CRC_SOURCE_POSTFLICKER_EVEN    0x00000012
+#define VG_CRC_SOURCE_EVEN                0x00000010
+
+/*===================================================*/
+/* DISPLAY FILTER PARAMETERS                         */
+/*===================================================*/
+
+/*-----------------------------------------------*/
+/*         VIDEO FORMAT DEFINITIONS              */
+/*-----------------------------------------------*/
+
+#define DF_VIDFMT_UYVY                    0x0000
+#define DF_VIDFMT_Y2YU                    0x0001
+#define DF_VIDFMT_YUYV                    0x0002
+#define DF_VIDFMT_YVYU                    0x0003
+#define DF_VIDFMT_Y0Y1Y2Y3                0x0004
+#define DF_VIDFMT_Y3Y2Y1Y0                0x0005
+#define DF_VIDFMT_Y1Y0Y3Y2                0x0006
+#define DF_VIDFMT_Y1Y2Y3Y0                0x0007
+#define DF_VIDFMT_RGB                     0x0008
+#define DF_VIDFMT_P2M_P2L_P1M_P1L         0x0009
+#define DF_VIDFMT_P1M_P1L_P2M_P2L         0x000A
+#define DF_VIDFMT_P1M_P2L_P2M_P1L         0x000B
+
+/*-----------------------------------------------*/
+/*             CRT ENABLE STATES                 */
+/*-----------------------------------------------*/
+
+#define DF_CRT_DISABLE                    0x0000
+#define DF_CRT_ENABLE                     0x0001
+#define DF_CRT_STANDBY                    0x0002
+#define DF_CRT_SUSPEND                    0x0003
+
+/*-----------------------------------------------*/
+/*             VIDEO SCALING FLAGS               */
+/*-----------------------------------------------*/
+
+#define DF_SCALEFLAG_CHANGEX              0x0001
+#define DF_SCALEFLAG_CHANGEY              0x0002
+
+/*-----------------------------------------------*/
+/*       DISPLAY FILTER COLOR SPACES             */
+/*-----------------------------------------------*/
+
+#define DF_OUTPUT_RGB                     0x0001
+#define DF_OUTPUT_ARGB                    0x0002
+#define DF_OUTPUT_SDTV                    0x0003
+#define DF_OUTPUT_HDTV                    0x0004
+
+/*-----------------------------------------------*/
+/*       DISPLAY FILTER OUTPUT PATHS             */
+/*-----------------------------------------------*/
+
+#define DF_DISPLAY_CRT                    0x0001
+#define DF_DISPLAY_FP                     0x0002
+#define DF_DISPLAY_CRT_FP                 0x0003
+#define DF_DISPLAY_VOP                    0x0004
+#define DF_DISPLAY_DRGB                   0x0005
+#define DF_DISPLAY_CRT_DRGB               0x0006
+
+/*-----------------------------------------------*/
+/*       WINDOWED CRC DATA SOURCES               */
+/*-----------------------------------------------*/
+
+#define DF_CRC_SOURCE_GFX_DATA            0x0000
+#define DF_CRC_SOURCE_CRT_RGB             0x0001
+#define DF_CRC_SOURCE_FP_DATA             0x0002
+
+/*-----------------------------------------------*/
+/*          VIDEO ENABLE FLAGS                   */
+/*-----------------------------------------------*/
+
+#define DF_ENABLEFLAG_NOCOLORKEY          0x0001
+
+/*-----------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING A VIDEO SOURCE */
+/*-----------------------------------------------*/
+
+#define DF_SOURCEFLAG_HDTVSOURCE          0x0001
+#define DF_SOURCEFLAG_IMPLICITSCALING     0x0002
+
+typedef struct tagVideoSourceInfo
+{
+	unsigned long video_format;
+	unsigned long y_offset;
+	unsigned long u_offset;
+	unsigned long v_offset;
+	unsigned long y_pitch;
+	unsigned long uv_pitch;
+	unsigned long width;
+	unsigned long height;
+	unsigned long flags;
+
+} DF_VIDEO_SOURCE_PARAMS;
+
+/*---------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING THE VIDEO POSITION */
+/*---------------------------------------------------*/
+
+#define DF_POSFLAG_DIRECTCLIP             0x0001
+#define DF_POSFLAG_INCLUDEBORDER          0x0002
+
+typedef struct tagVideoPosition
+{
+	long x;
+	long y;
+	unsigned long width;
+	unsigned long height;
+	unsigned long left_clip;
+    unsigned long dst_clip;
+	unsigned long flags;
+
+} DF_VIDEO_POSITION;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING THE VIDEO CURSOR */
+/*-------------------------------------------------*/
+
+typedef struct tagVideoCursorInfo
+{
+	unsigned long key;
+	unsigned long mask;
+	unsigned long color1;
+	unsigned long color2;
+	unsigned long select_color2;
+	unsigned long flags;
+
+} DF_VIDEO_CURSOR_PARAMS;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING AN ALPHA REGION  */
+/*-------------------------------------------------*/
+
+#define DF_ALPHAFLAG_COLORENABLED         0x0001
+#define DF_ALPHAFLAG_PERPIXELENABLED      0x0002
+
+typedef struct tagAlphaRegionInfo
+{
+	unsigned long x;
+	unsigned long y;
+	unsigned long width;
+	unsigned long height;
+	unsigned long alpha_value;
+	unsigned long priority;
+	unsigned long color;
+	unsigned long flags;
+	long delta;
+
+} DF_ALPHA_REGION_PARAMS;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING DF DATA     */
+/*-------------------------------------------------*/
+
+typedef struct tagDFSaveRestore
+{
+    unsigned long vcfg;
+    unsigned long dcfg;
+    unsigned long video_x;
+    unsigned long video_y;
+    unsigned long video_scaler;
+    unsigned long video_color_key;
+    unsigned long video_color_mask;
+    unsigned long sat_limit;
+    unsigned long vid_misc;
+    unsigned long video_yscale;
+    unsigned long video_xscale;
+    unsigned long vid_alpha_control;
+    unsigned long cursor_key;
+    unsigned long cursor_mask;
+    unsigned long cursor_color1;
+    unsigned long cursor_color2;
+    unsigned long alpha_xpos1;
+    unsigned long alpha_ypos1;
+    unsigned long alpha_color1;
+    unsigned long alpha_control1;
+    unsigned long alpha_xpos2;
+    unsigned long alpha_ypos2;
+    unsigned long alpha_color2;
+    unsigned long alpha_control2;
+    unsigned long alpha_xpos3;
+    unsigned long alpha_ypos3;
+    unsigned long alpha_color3;
+    unsigned long alpha_control3;
+    unsigned long vid_request;
+    unsigned long vid_ypos_even;
+    unsigned long alpha_ypos_even1;
+    unsigned long alpha_ypos_even2;
+    unsigned long alpha_ypos_even3;
+    unsigned long panel_tim1;
+    unsigned long panel_tim2;
+    unsigned long panel_pm;
+    unsigned long panel_dither;
+
+    unsigned long palette[256];
+    unsigned long coefficients[512];
+
+    /* DF MSRS */
+
+    Q_WORD msr_cap;
+    Q_WORD msr_config;
+    Q_WORD msr_smi;
+    Q_WORD msr_error;
+    Q_WORD msr_pm;
+    Q_WORD msr_diag;
+    Q_WORD msr_df_diag;
+    Q_WORD msr_pad_sel;
+
+} DF_SAVE_RESTORE;
+
+/*-----------------------------------------------*/
+/*            DF CRC SOURCES                     */
+/*-----------------------------------------------*/
+
+#define DF_CRC_SOURCE_ODD_FIELD           0x00000100
+#define DF_CRC_SOURCE_EVEN_FIELD          0x00001000
+#define DF_CRC_SOURCE_EVEN                0x00001000
+
+/*===================================================*/
+/*          VIP USER PARAMETER DEFINITIONS           */
+/*===================================================*/
+
+#define VIP_MODEFLAG_VSYNCACTIVEHIGH      0x00000001
+#define VIP_MODEFLAG_HSYNCACTIVEHIGH      0x00000002
+
+/*---------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING 601 SETTINGS */
+/*---------------------------------------------*/
+
+typedef struct _TAG_VIP601PARAMS
+{
+    unsigned long   flags;
+    unsigned long   horz_start;
+    unsigned long   width;
+    unsigned long   vert_start_even;
+    unsigned long   even_height;
+    unsigned long   vert_start_odd;
+    unsigned long   odd_height;
+    unsigned long   vbi_start;
+    unsigned long   vbi_height;
+    unsigned long   odd_detect_start;
+    unsigned long   odd_detect_end;
+
+} VIP_601PARAMS;
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING A VIP MODE */
+/*-------------------------------------------*/
+
+/* VIP MODE FLAGS */
+
+#define VIP_MODEFLAG_PLANARCAPTURE        0x00000001
+#define VIP_MODEFLAG_INVERTPOLARITY       0x00000002
+#define VIP_MODEFLAG_PROGRESSIVE          0x00000004
+#define VIP_MODEFLAG_DISABLEZERODETECT    0x00000008
+#define VIP_MODEFLAG_ENABLEREPEATFLAG     0x00000010
+#define VIP_MODEFLAG_10BITANCILLARY       0x00000020
+#define VIP_MODEFLAG_TOGGLEEACHFIELD      0x00000040
+#define VIP_MODEFLAG_INVERTTASKPOLARITY   0x00000080
+#define VIP_MODEFLAG_FLIPMESSAGEWHENFULL  0x00000100
+
+/* VIP CAPTURE ENABLE FLAGS */
+
+#define VIP_ENABLE_TASKA                  0x00000100
+#define VIP_ENABLE_TASKA_VBI              0x00000200
+#define VIP_ENABLE_TASKB                  0x00000400
+#define VIP_ENABLE_TASKB_VBI              0x00000800
+#define VIP_ENABLE_ANCILLARY              0x00001000
+#define VIP_ENABLE_ALL                    0x00001F00
+
+/* VIP CAPTURE MODE FLAGS */
+
+#define VIP_MODE_IDLE                     0x00000000
+#define VIP_MODE_VIP2_8BIT                0x00000002
+#define VIP_MODE_VIP2_16BIT               0x00000004
+#define VIP_MODE_VIP1_8BIT                0x00000006
+#define VIP_MODE_MSG                      0x00000008
+#define VIP_MODE_DATA                     0x0000000A
+#define VIP_MODE_8BIT601                  0x0000000C
+#define VIP_MODE_16BIT601                 0x0000000E
+
+/* 4:2:0 PLANAR CAPTURE METHODS */
+
+#define VIP_420CAPTURE_EVERYLINE          0x00000001
+#define VIP_420CAPTURE_ALTERNATINGLINES   0x00000002
+#define VIP_420CAPTURE_ALTERNATINGFIELDS  0x00000003
+
+typedef struct _TAG_SETMODEBUFFER
+{
+    unsigned long   flags;
+	unsigned long	stream_enables;
+	unsigned long	operating_mode;	
+    unsigned long   planar_capture;
+    VIP_601PARAMS   vip601_settings;
+
+} VIPSETMODEBUFFER;
+
+/*-----------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VG/VIP GENLOCK */
+/*-----------------------------------------------*/
+
+/* LOSS OF VIDEO DETECTION FLAGS */
+
+#define VIP_VDE_RUNAWAY_LINE              0x00800000
+#define VIP_VDE_VERTICAL_TIMING           0x00400000
+#define VIP_VDE_CLOCKS_PER_LINE           0x00200000
+#define VIP_VDE_LOST_CLOCK                0x00100000
+
+/* VIP VSYNC SELECT FOR THE VG */
+
+#define VIP_VGSYNC_NONE                  0x00000000
+#define VIP_VGSYNC_START_FRAME           0x00000001
+#define VIP_VGSYNC_FALLING_EDGE_VBLANK   0x00000002
+#define VIP_VGSYNC_RISING_EDGE_VBLANK    0x00000003
+#define VIP_VGSYNC_FALLING_EDGE_FIELD    0x00000004
+#define VIP_VGSYNC_RISING_EDGE_FIELD     0x00000005
+#define VIP_VGSYNC_VIP_CURRENT_LINE      0x00000006
+#define VIP_VGSYNC_MSG_INT               0x00000007
+
+/* VIP FIELD SELECT FOR THE VG */
+
+#define VIP_VGFIELD_INPUT                0x00000000
+#define VIP_VGFIELD_INPUT_INV            0x00000008
+#define VIP_VGFIELD_ACTIVE_PAGE          0x00000010
+#define VIP_VGFIELD_ACTIVE_PAGE_IN       0x00000018
+
+/*--------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING THE VG VSYNC GENLOCK    */
+/*--------------------------------------------------------*/
+
+typedef struct _TAG_GENLOCKBUFFER
+{
+    unsigned long   vip_signal_loss;
+    unsigned long   vsync_to_vg;
+    unsigned long   field_to_vg;
+	unsigned long	genlock_skew;
+    int				enable_timeout;
+
+} VIPGENLOCKBUFFER;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP ANCILLARY CAPTURE */
+/*------------------------------------------------------*/
+
+typedef struct _TAG_ANCILLARYBUFFER
+{
+	unsigned long	msg1_base;
+	unsigned long	msg2_base;
+	unsigned long	msg_size;
+
+} VIPANCILLARYBUFFER;
+
+/*----------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP CAPTURE BUFFERS */
+/*----------------------------------------------------*/
+
+#define VIP_INPUTFLAG_VBI                 0x00000001
+#define VIP_INPUTFLAG_INVERTPOLARITY      0x00000002
+#define VIP_INPUTFLAG_PLANAR              0x00000004
+
+#define VIP_MAX_BUFFERS                   10
+
+#define VIP_BUFFER_TASK_A                 0x0000
+#define VIP_BUFFER_TASK_B                 0x0001
+#define VIP_BUFFER_MAX_TASKS              0x0002
+
+#define	VIP_BUFFER_A                      0x0000
+#define	VIP_BUFFER_B                      0x0001
+#define	VIP_BUFFER_ANC                    0x0002
+#define VIP_BUFFER_MSG                    0x0003
+#define VIP_BUFFER_601                    0x0004
+#define VIP_BUFFER_A_ODD                  0x0005
+#define VIP_BUFFER_A_EVEN                 0x0006
+#define VIP_BUFFER_B_ODD                  0x0007
+#define VIP_BUFFER_B_EVEN                 0x0008
+
+typedef struct _TAG_INPUTBUFFER_ADDR
+{
+    unsigned long	even_base[VIP_MAX_BUFFERS];
+	unsigned long	odd_base[VIP_MAX_BUFFERS];
+	unsigned long	y_pitch;
+    unsigned long   uv_pitch;
+    unsigned long	odd_uoffset;
+	unsigned long	odd_voffset;
+	unsigned long	even_uoffset;
+	unsigned long	even_voffset;
+	unsigned long	vbi_even_base;
+	unsigned long	vbi_odd_base;
+
+} VIPINPUTBUFFER_ADDR;
+
+typedef struct _TAG_SETINPUTBUFFER
+{
+    unsigned long           flags;
+	VIPINPUTBUFFER_ADDR     offsets[VIP_BUFFER_MAX_TASKS];
+	unsigned long           current_buffer;
+
+    VIPANCILLARYBUFFER ancillaryData;
+
+} VIPINPUTBUFFER;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP SUBWINDOW CAPTURE */
+/*------------------------------------------------------*/
+
+typedef struct _TAG_SUBWINDOWBUFFER
+{
+	int				enable;
+	unsigned long	start;
+	unsigned long	stop;
+
+} VIPSUBWINDOWBUFFER;
+
+/*--------------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING VIP REGISTERS      */
+/*--------------------------------------------------------*/
+
+typedef struct _TAG_VIPSTATEBUFFER
+{
+	unsigned long control1;
+	unsigned long control2;
+    unsigned long vip_int;
+	unsigned long current_target;
+	unsigned long max_address;
+	unsigned long taska_evenbase;
+	unsigned long taska_oddbase;
+	unsigned long taska_vbi_evenbase;
+	unsigned long taska_vbi_oddbase;
+	unsigned long taska_data_pitch;
+    unsigned long control3;
+	unsigned long taska_v_oddoffset;
+	unsigned long taska_u_oddoffset;
+	unsigned long taskb_evenbase;
+	unsigned long taskb_oddbase;
+	unsigned long taskb_vbi_evenbase;
+	unsigned long taskb_vbi_oddbase;
+	unsigned long taskb_pitch;
+	unsigned long taskb_voffset;
+	unsigned long taskb_uoffset;
+	unsigned long msg1_base;
+	unsigned long msg2_base;
+	unsigned long msg_size;
+	unsigned long page_offset;
+	unsigned long vert_start_stop;
+	unsigned long vsync_err_count;
+    unsigned long taska_u_evenoffset;
+    unsigned long taska_v_evenoffset;
+
+    Q_WORD  msr_config;
+    Q_WORD  msr_smi;
+    Q_WORD  msr_pm;
+    Q_WORD  msr_diag;
+
+} VIPSTATEBUFFER;
+
+/*--------------------------------------------------------*/
+/* VIP_SET_CAPTURE_STATE USER PARAMETERS                  */
+/*--------------------------------------------------------*/
+
+#define VIP_STOPCAPTURE                   0x0000
+#define VIP_STOPCAPTUREATLINEEND          0x0001
+#define VIP_STOPCAPTUREATFIELDEND         0x0002
+#define VIP_STOPCAPTUREATFRAMEEND         0x0003
+#define VIP_STARTCAPTUREATNEXTLINE        0x0004
+#define VIP_STARTCAPTUREATNEXTFIELD       0x0005
+#define VIP_STARTCAPTUREATNEXTFRAME       0x0006
+#define VIP_STARTCAPTURE                  0x0007
+
+/*--------------------------------------------------------*/
+/* VIP_CONFIGURE_FIFO USER PARAMETERS                     */
+/*--------------------------------------------------------*/
+
+#define VIP_VIDEOTHRESHOLD                0x3000
+#define	VIP_ANCILLARYTHRESHOLD            0x3001
+#define	VIP_VIDEOFLUSH                    0x3002
+#define VIP_ANCILLARYFLUSH                0x3003
+
+/*--------------------------------------------------------*/
+/* VIP_SET_INTERRUPT_ENABLE USER DEFINITIONS              */
+/*--------------------------------------------------------*/
+
+#define VIP_INT_FIFO_ERROR                0x80000000
+#define VIP_INT_FIFO_WRAP                 0x40000000
+#define VIP_INT_FIFO_OVERFLOW             0x20000000
+#define VIP_INT_FIFO_THRESHOLD            0x10000000
+#define VIP_INT_LONGLINE                  0x08000000
+#define VIP_INT_VERTICAL_TIMING           0x04000000
+#define VIP_INT_ACTIVE_PIXELS             0x02000000
+#define VIP_INT_CLOCK_INPUT	              0x01000000
+#define VIP_INT_ANC_CHECKSUM_PARITY       0x00800000
+#define VIP_INT_MSG_BUFFER_FULL           0x00400000
+#define VIP_INT_END_VBLANK                0x00200000
+#define VIP_INT_START_VBLANK              0x00100000
+#define VIP_INT_START_EVEN                0x00080000
+#define VIP_INT_START_ODD                 0x00040000
+#define VIP_INT_LINE_MATCH_TARGET         0x00020000
+#define VIP_ALL_INTERRUPTS                0xFFFE0000
+
+/*--------------------------------------------------------*/
+/* VIP_GET_CURRENT_FIELD RETURN VALUES                    */
+/*--------------------------------------------------------*/
+
+#define VIP_ODD_FIELD                     1
+#define VIP_EVEN_FIELD                    0
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR QUERYING VIP CAPABILITIES    */
+/*-------------------------------------------------*/
+
+typedef struct _TAG_CAPABILITIESBUFFER
+{
+	unsigned long	revision_id;
+	unsigned long	device_id;
+	unsigned long	n_clock_domains;
+	unsigned long	n_smi_registers;
+
+} VIPCAPABILITIESBUFFER;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP POWER        */
+/*-------------------------------------------------*/
+
+typedef struct _TAG_POWERBUFFER
+{
+	int           glink_clock_mode;
+	int           vip_clock_mode;
+
+} VIPPOWERBUFFER;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP PRIORITIES   */
+/*-------------------------------------------------*/
+
+typedef struct _TAG_PRIORITYBUFFER
+{
+	unsigned long	secondary;
+	unsigned long	primary;
+	unsigned long	pid;
+
+} VIPPRIORITYBUFFER;
+
+/*--------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP DEBUG OUTPUTS */
+/*--------------------------------------------------*/
+
+#define VIP_DIAG_UPPER_GLINK_MASTER       0x00010000
+#define VIP_DIAG_UPPER_GLINK_SLAVE        0x00020000
+#define VIP_DIAG_UPPER_GLINK_SLAVE_MMREG  0x00040000
+#define VIP_DIAG_UPPER_Y_BUFFER           0x00080000
+#define VIP_DIAG_UPPER_A_BUFFER           0x00100000
+#define VIP_DIAG_UPPER_FIFO_OUTPUT        0x00200000
+#define VIP_DIAG_UPPER_FIFO_INPUT         0x01000000
+#define VIP_DIAG_UPPER_FORMATTER          0x02000000
+#define VIP_DIAG_UPPER_INPUT_CONTROL      0x04000000
+
+#define VIP_DIAG_LOWER_GLINK_MASTER       0x00000001
+#define VIP_DIAG_LOWER_GLINK_SLAVE        0x00000002
+#define VIP_DIAG_LOWER_GLINK_SLAVE_MMREG  0x00000004
+#define VIP_DIAG_LOWER_Y_BUFFER           0x00000008
+#define VIP_DIAG_LOWER_A_BUFFER           0x00000010
+#define VIP_DIAG_LOWER_FIFO_OUTPUT        0x00000020
+#define VIP_DIAG_LOWER_FIFO_INPUT         0x00000100
+#define VIP_DIAG_LOWER_FORMATTER          0x00000200
+#define VIP_DIAG_LOWER_INPUT_CONTROL      0x00000400
+
+typedef struct _TAG_DEBUGBUFFER
+{
+	unsigned long	bist;
+	unsigned long	enable_upper;
+	unsigned long	select_upper;
+	unsigned long	enable_lower;
+	unsigned long	select_lower;
+
+} VIPDEBUGBUFFER;
+
+
+/*===================================================*/
+/*          VOP USER PARAMETER DEFINITIONS           */
+/*===================================================*/
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VBI CAPTURE           */
+/*------------------------------------------------------*/
+
+typedef struct _TAG_VBIWINDOWBUFFER
+{
+	long	        horz_start;
+	unsigned long	vbi_width;
+	unsigned long	odd_line_capture_mask;
+	unsigned long	even_line_capture_mask;
+	unsigned long	odd_line_offset;
+	unsigned long	even_line_offset;
+	unsigned long	even_address_offset;
+	unsigned long	odd_address_offset;
+	unsigned long	data_size;
+	unsigned long	data_pitch;
+    int             enable_upscale;
+    int             horz_from_hsync;
+
+} VOPVBIWINDOWBUFFER;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING 601 FOR VOP           */
+/*------------------------------------------------------*/
+
+#define VOP_601_INVERT_DISPE              0x00080000
+#define VOP_601_INVERT_VSYNC              0x00040000
+#define VOP_601_INVERT_HSYNC              0x00020000
+
+#define VOP_VSYNC_EARLIER_BY4             0x00000000
+#define VOP_VSYNC_EARLIER_BY2             0x00004000
+#define VOP_VSYNC_NOSHIFT                 0x00008000
+#define VOP_VSYNC_LATER_BY_X              0x0000C000
+
+#define VOP_601_YUV_8BIT                  0x00000000
+#define VOP_601_YUV_16BIT                 0x00000001
+#define VOP_601_RGB_8_8_8                 0x00000002
+#define VOP_601_YUV_4_4_4                 0x00000003
+
+typedef struct _TAG_VOP601
+{
+    unsigned long flags;
+    unsigned long vsync_shift;
+    unsigned long vsync_shift_count;
+    unsigned long output_mode;
+
+} VOP_601DATA;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VOP OUTPUT            */
+/*------------------------------------------------------*/
+
+/* VOP FLAGS */
+
+#define VOP_FLAG_SINGLECHIPCOMPAT         0x00000001
+#define VOP_FLAG_EXTENDEDSAV              0x00000002
+#define VOP_FLAG_VBI                      0x00000008
+#define VOP_FLAG_TASK                     0x00000010
+#define VOP_FLAG_SWAP_UV                  0x00000020
+#define VOP_FLAG_SWAP_VBI                 0x00000040
+
+/* 4:4:2 TO 4:2:2 DECIMATION */
+
+#define VOP_422MODE_COSITED               0x00000000
+#define VOP_422MODE_INTERSPERSED          0x00000010
+#define VOP_422MODE_ALTERNATING           0x00000020
+
+/* VOP OPERATING MODES */
+
+#define VOP_MODE_DISABLED                 0x00000000
+#define VOP_MODE_VIP11                    0x00000001
+#define VOP_MODE_CCIR656                  0x00000002
+#define VOP_MODE_VIP20_8BIT               0x00000003
+#define VOP_MODE_VIP20_16BIT              0x00000004
+#define VOP_MODE_601                      0x00000005
+
+/* VSYNC OUT SELECT FLAGS */
+
+#define VOP_MB_SYNCSEL_DISABLED           0x00000000
+#define VOP_MB_SYNCSEL_VG                 0x00000020
+#define VOP_MB_SYNCSEL_VG_INV             0x00000040
+#define VOP_MB_SYNCSEL_STATREG17          0x00000060
+#define VOP_MB_SYNCSEL_STATREG17_INV      0x00000080
+
+typedef struct _TAG_VOPMODECONFIGURATIONBUFFER
+{
+    unsigned long flags;
+    unsigned long mode;
+	unsigned long conversion_mode;
+    unsigned long vsync_out;
+    VOP_601DATA vop601;
+
+} VOPCONFIGURATIONBUFFER;
+
+/*--------------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING VOP REGISTERS      */
+/*--------------------------------------------------------*/
+
+typedef struct _TAG_VOPSTATEBUFFER
+{
+	unsigned long	config;
+} VOPSTATEBUFFER;
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_regs.h xf86-video-nsc-2.8.1/src/cim/cim_regs.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_regs.h	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1233 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron register definitions
+  * </DOC_AMD_STD>
+  *
+  */
+
+#ifndef _cim_regs_h
+#define _cim_regs_h
+
+/*----------------------------------------------------------------*/
+/*                GRAPHICS PROCESSOR DEFINITIONS                  */
+/*----------------------------------------------------------------*/
+
+/*----------------------------*/
+/* COMMAND BUFFER DEFINITIONS */
+/*----------------------------*/
+
+#define GP3_BLT_COMMAND_SIZE			    68			/* 18 DWORDS                             */
+#define GP3_VECTOR_COMMAND_SIZE             56          /* 14 DWORDS                             */
+#define GP3_4BPP_LUT_COMMAND_SIZE           76          /* 16 DWORDS + 3 CMD DWORDS              */
+#define GP3_8BPP_LUT_COMMAND_SIZE           1036        /* 256 DWORDS + 3 CMD DWORDS             */
+#define GP3_VECTOR_PATTERN_COMMAND_SIZE     20          /* 2 DWORDS + 3 CMD DWORDS               */
+#define GP3_MAX_COMMAND_SIZE                9000        /* 8K + WORKAROUND SPACE                 */
+#define GP3_SCRATCH_BUFFER_SIZE             0x100000    /* 1MB SCRATCH BUFFER                    */
+#define GP3_BLT_1PASS_SIZE                  0xC7F8      /* (50K - 8) is largest 1-Pass load size */
+
+/*-------------------------------------*/
+/* BLT COMMAND BUFFER REGISTER OFFSETS */
+/*-------------------------------------*/
+
+#define GP3_BLT_CMD_HEADER				    0x00000000
+#define GP3_BLT_RASTER_MODE                 0x00000004
+#define GP3_BLT_DST_OFFSET				    0x00000008
+#define GP3_BLT_SRC_OFFSET				    0x0000000C
+#define GP3_BLT_STRIDE					    0x00000010
+#define GP3_BLT_WID_HEIGHT				    0x00000014
+#define GP3_BLT_SRC_COLOR_FG			    0x00000018
+#define GP3_BLT_SRC_COLOR_BG			    0x0000001C
+#define GP3_BLT_PAT_COLOR_0				    0x00000020
+#define GP3_BLT_PAT_COLOR_1				    0x00000024
+#define GP3_BLT_PAT_DATA_0				    0x00000028
+#define GP3_BLT_PAT_DATA_1				    0x0000002C
+#define GP3_BLT_CH3_OFFSET				    0x00000030
+#define GP3_BLT_CH3_MODE_STR			    0x00000034
+#define GP3_BLT_CH3_WIDHI				    0x00000038
+#define GP3_BLT_BASE_OFFSET				    0x0000003C
+#define GP3_BLT_MODE					    0x00000040
+
+/*-----------------------------------------------------------------*/
+/* VECTOR COMMAND BUFFER REGISTER OFFSETS                          */
+/* Some of these are identical to the BLT registers (and we will   */
+/* be assumed to be such in the Cimarron code, but they are listed */
+/* here for clarity and for future changes.                        */
+/*-----------------------------------------------------------------*/
+
+#define GP3_VEC_CMD_HEADER				    0x00000000
+#define GP3_VECTOR_RASTER_MODE			    0x00000004
+#define GP3_VECTOR_DST_OFFSET			    0x00000008
+#define GP3_VECTOR_VEC_ERR				    0x0000000C
+#define GP3_VECTOR_STRIDE				    0x00000010
+#define GP3_VECTOR_VEC_LEN				    0x00000014
+#define GP3_VECTOR_SRC_COLOR_FG			    0x00000018
+#define GP3_VECTOR_PAT_COLOR_0			    0x0000001C
+#define GP3_VECTOR_PAT_COLOR_1			    0x00000020
+#define GP3_VECTOR_PAT_DATA_0			    0x00000024
+#define GP3_VECTOR_PAT_DATA_1			    0x00000028
+#define GP3_VECTOR_CH3_MODE_STR			    0x0000002C
+#define GP3_VECTOR_BASE_OFFSET			    0x00000030
+#define GP3_VECTOR_MODE					    0x00000034
+
+/*---------------------------------------------------*/
+/* GP REGISTER DEFINITIONS                           */
+/* Addresses for writing or reading directly to/from */
+/* the graphics processor.                           */
+/*---------------------------------------------------*/
+
+#define GP3_DST_OFFSET                      0x00000000
+#define GP3_SRC_OFFSET                      0x00000004
+#define GP3_VEC_ERR                         0x00000004
+#define GP3_STRIDE                          0x00000008
+#define GP3_WID_HEIGHT                      0x0000000C
+#define GP3_VEC_LEN                         0x0000000C
+#define GP3_SRC_COLOR_FG                    0x00000010
+#define GP3_SRC_COLOR_BG                    0x00000014
+#define GP3_PAT_COLOR_0                     0x00000018
+#define GP3_PAT_COLOR_1                     0x0000001C
+#define GP3_PAT_COLOR_2                     0x00000020
+#define GP3_PAT_COLOR_3                     0x00000024
+#define GP3_PAT_COLOR_4                     0x00000028
+#define GP3_PAT_COLOR_5                     0x0000002C
+#define GP3_PAT_DATA_0                      0x00000030
+#define GP3_PAT_DATA_1                      0x00000034
+#define GP3_RASTER_MODE                     0x00000038
+#define GP3_VEC_MODE                        0x0000003C
+#define GP3_BLT_MODE                        0x00000040
+#define GP3_BLT_STATUS                      0x00000044
+#define GP3_HST_SRC                         0x00000048
+#define GP3_BASE_OFFSET                     0x0000004C
+#define GP3_CMD_TOP                         0x00000050
+#define GP3_CMD_BOT                         0x00000054
+#define GP3_CMD_READ					    0x00000058
+#define GP3_CMD_WRITE					    0x0000005C
+#define GP3_CH3_OFFSET                      0x00000060
+#define GP3_CH3_MODE_STR                    0x00000064
+#define GP3_CH3_WIDHI                       0x00000068
+#define GP3_CH3_HST_SRC                     0x0000006C
+#define GP3_LUT_ADDRESS                     0x00000070
+#define GP3_LUT_DATA                        0x00000074
+#define GP3_INT_CTL                         0x00000078
+#define GP3_HST_SRC_RANGE                   0x00000100
+
+/*------------------------*/
+/* REGISTER BIT FIELDS    */
+/*------------------------*/
+
+/* GP3_BLT_CMD_HEADER BIT DEFINITIONS */
+
+#define GP3_BLT_HDR_WRAP				    0x80000000
+#define GP3_BLT_HDR_TYPE				    0x00000000
+#define GP3_BLT_HDR_HAZARD_ENABLE           0x10000000
+#define GP3_BLT_HDR_RASTER_ENABLE		    0x00000001
+#define GP3_BLT_HDR_DST_OFF_ENABLE		    0x00000002
+#define GP3_BLT_HDR_SRC_OFF_ENABLE          0x00000004
+#define GP3_BLT_HDR_STRIDE_ENABLE		    0x00000008
+#define GP3_BLT_HDR_WIDHI_ENABLE		    0x00000010
+#define GP3_BLT_HDR_SRC_FG_ENABLE		    0x00000020
+#define GP3_BLT_HDR_SRC_BG_ENABLE		    0x00000040
+#define GP3_BLT_HDR_PAT_CLR0_ENABLE		    0x00000080
+#define GP3_BLT_HDR_PAT_CLR1_ENABLE		    0x00000100
+#define GP3_BLT_HDR_PAT_DATA0_ENABLE	    0x00000200
+#define GP3_BLT_HDR_PAT_DATA1_ENABLE        0x00000400
+#define GP3_BLT_HDR_CH3_OFF_ENABLE          0x00000800
+#define GP3_BLT_HDR_CH3_STR_ENABLE          0x00001000
+#define GP3_BLT_HDR_CH3_WIDHI_ENABLE        0x00002000
+#define GP3_BLT_HDR_BASE_OFFSET_ENABLE      0x00004000
+#define GP3_BLT_HDR_BLT_MODE_ENABLE         0x00008000
+
+/* GP3_VEC_CMD_HEADER BIT DEFINITIONS */
+
+#define GP3_VEC_HDR_WRAP				    0x80000000
+#define GP3_VEC_HDR_TYPE				    0x20000000
+#define GP3_VEC_HDR_HAZARD_ENABLE           0x10000000
+#define GP3_VEC_HDR_RASTER_ENABLE		    0x00000001
+#define GP3_VEC_HDR_DST_OFF_ENABLE		    0x00000002
+#define GP3_VEC_HDR_VEC_ERR_ENABLE          0x00000004
+#define GP3_VEC_HDR_STRIDE_ENABLE		    0x00000008
+#define GP3_VEC_HDR_VEC_LEN_ENABLE		    0x00000010
+#define GP3_VEC_HDR_SRC_FG_ENABLE		    0x00000020
+#define GP3_VEC_HDR_PAT_CLR0_ENABLE		    0x00000040
+#define GP3_VEC_HDR_PAT_CLR1_ENABLE		    0x00000080
+#define GP3_VEC_HDR_PAT_DATA0_ENABLE	    0x00000100
+#define GP3_VEC_HDR_PAT_DATA1_ENABLE        0x00000200
+#define GP3_VEC_HDR_CH3_STR_ENABLE          0x00000400
+#define GP3_VEC_HDR_BASE_OFFSET_ENABLE      0x00000800
+#define GP3_VEC_HDR_VEC_MODE_ENABLE         0x00001000
+
+/* GP3_RASTER_MODE BIT DEFINITIONS */
+
+#define GP3_RM_BPPFMT_332				    0x00000000	/* 8 BPP, palettized    	*/
+#define GP3_RM_BPPFMT_4444				    0x40000000	/* 16 BPP, 4:4:4:4			*/
+#define GP3_RM_BPPFMT_1555				    0x50000000	/* 16 BPP, 1:5:5:5			*/
+#define GP3_RM_BPPFMT_565				    0x60000000	/* 16 BPP, 5:6:5			*/
+#define GP3_RM_BPPFMT_8888				    0x80000000	/* 32 BPP, 8:8:8:8			*/
+#define GP3_RM_ALPHA_ALL				    0x00C00000  /* Alpha enable             */
+#define GP3_RM_ALPHA_TO_RGB				    0x00400000  /* Alpha applies to RGB     */
+#define GP3_RM_ALPHA_TO_ALPHA			    0x00800000  /* Alpha applies to alpha   */
+#define GP3_RM_ALPHA_OP_MASK			    0x00300000  /* Alpha operation          */
+#define GP3_RM_ALPHA_TIMES_A			    0x00000000  /* Alpha * A                */
+#define GP3_RM_BETA_TIMES_B				    0x00100000  /* (1-alpha) * B            */
+#define GP3_RM_A_PLUS_BETA_B			    0x00200000  /* A + (1-alpha) * B        */
+#define GP3_RM_ALPHA_A_PLUS_BETA_B		    0x00300000  /* alpha * A + (1 - alpha)B */
+#define GP3_RM_ALPHA_SELECT				    0x000E0000  /* Alpha Select             */
+#define GP3_RM_SELECT_ALPHA_A			    0x00000000  /* Alpha from channel A     */
+#define GP3_RM_SELECT_ALPHA_B			    0x00020000  /* Alpha from channel B     */
+#define GP3_RM_SELECT_ALPHA_R			    0x00040000  /* Registered alpha         */
+#define GP3_RM_SELECT_ALPHA_1			    0x00060000  /* Constant 1               */
+#define GP3_RM_SELECT_ALPHA_CHAN_A		    0x00080000  /* RGB Values from A        */
+#define GP3_RM_SELECT_ALPHA_CHAN_B		    0x000A0000  /* RGB Values from B        */
+#define GP3_RM_SELECT_ALPHA_CHAN_3          0x000C0000  /* Alpha from channel 3     */
+#define GP3_RM_DEST_FROM_CHAN_A			    0x00010000  /* Alpha channel select     */
+#define GP3_RM_PATTERN_INVERT               0x00001000  /* Invert monochrome pat    */
+#define GP3_RM_SOURCE_INVERT                0x00002000  /* Invert monochrome src    */
+#define GP3_RM_PAT_FLAGS				    0x00000700  /* pattern related bits		*/
+#define GP3_RM_PAT_MONO					    0x00000100  /* monochrome pattern		*/
+#define GP3_RM_PAT_COLOR				    0x00000200  /* color pattern			*/
+#define GP3_RM_PAT_TRANS				    0x00000400	/* pattern transparency		*/
+#define GP3_RM_SRC_TRANS				    0x00000800	/* source transparency		*/
+
+/* GP3_VECTOR_MODE REGISTER DESCRIPTIONS */
+
+#define GP3_VM_DST_REQ					    0x00000008	/* dst data required		*/
+#define GP3_VM_THROTTLE					    0x00000010  /* sync to VBLANK			*/
+
+/* GP3_BLT_MODE REGISTER DEFINITIONS */
+
+#define GP3_BM_SRC_FB					    0x00000001  /* src = frame buffer		*/
+#define GP3_BM_SRC_HOST					    0x00000002  /* src = host register		*/
+#define GP3_BM_DST_REQ					    0x00000004  /* dst data required		*/
+#define GP3_BM_SRC_MONO					    0x00000040  /* monochrome source data   */
+#define GP3_BM_SRC_BP_MONO				    0x00000080  /* Byte-packed monochrome   */
+#define GP3_BM_NEG_YDIR					    0x00000100  /* negative Y direction		*/
+#define GP3_BM_NEG_XDIR					    0x00000200  /* negative X direction		*/
+#define GP3_BM_THROTTLE					    0x00000400  /* sync to VBLANK			*/
+
+/* GP3_BLT_STATUS REGISTER DEFINITIONS */
+
+#define GP3_BS_BLT_BUSY					    0x00000001  /* GP is not idle			*/
+#define GP3_BS_BLT_PENDING				    0x00000004	/* second BLT is pending	*/
+#define GP3_BS_HALF_EMPTY				    0x00000008  /* src FIFO half empty		*/
+#define GP3_BS_CB_EMPTY                     0x00000010  /* Command buffer empty.    */
+
+/* GP3_CH3_MODE_STR REGISTER DEFINITIONS */
+
+#define GP3_CH3_C3EN                        0x80000000
+#define GP3_CH3_REPLACE_SOURCE              0x40000000
+#define GP3_CH3_NEG_XDIR                    0x20000000
+#define GP3_CH3_NEG_YDIR                    0x10000000
+#define GP3_CH3_SRC_FMT_MASK                0x0f000000
+#define GP3_CH3_SRC_3_3_2                   0x00000000
+#define GP3_CH3_SRC_8BPP_INDEXED            0x01000000
+#define GP3_CH3_SRC_8BPP_ALPHA              0x02000000
+#define GP3_CH3_SRC_4_4_4_4                 0x04000000
+#define GP3_CH3_SRC_1_5_5_5                 0x05000000
+#define GP3_CH3_SRC_0_5_6_5                 0x06000000
+#define GP3_CH3_SRC_Y_U_V                   0x07000000
+#define GP3_CH3_SRC_8_8_8_8                 0x08000000
+#define GP3_CH3_SRC_24BPP_PACKED            0x0B000000
+#define GP3_CH3_SRC_4BPP_INDEXED            0x0D000000
+#define GP3_CH3_SRC_4BPP_ALPHA              0x0E000000
+#define GP3_CH3_SRC_MASK                    0x0F000000
+#define GP3_CH3_ROTATE_ENABLE               0x00800000
+#define GP3_CH3_BGR_ORDER                   0x00400000
+#define GP3_CH3_COLOR_PAT_ENABLE            0x00200000
+#define GP3_CH3_PRESERVE_LUT                0x00100000
+#define GP3_CH3_PREFETCH_ENABLE             0x00080000
+#define GP3_CH3_HST_SRC_ENABLE			    0x00040000
+#define GP3_CH3_STRIDE_MASK                 0x0000FFFF
+
+/* DATA AND LUT LOAD BIT DEFINITIONS */
+
+#define GP3_LUT_HDR_WRAP                    0x80000000
+#define GP3_LUT_HDR_TYPE				    0x40000000
+#define GP3_LUT_HDR_DATA_ENABLE             0x00000003
+#define GP3_DATA_LOAD_HDR_WRAP              0x80000000
+#define GP3_DATA_LOAD_HDR_TYPE              0x60000000
+#define GP3_DATA_LOAD_HDR_ENABLE            0x00000001
+
+#define GP3_HOST_SOURCE_TYPE			    0x00000000
+#define GP3_CH3_HOST_SOURCE_TYPE		    0x20000000
+#define GP3_OLD_PATTERN_COLORS			    0x40000000
+#define GP3_LUT_DATA_TYPE				    0x60000000
+
+#define GP3_BASE_OFFSET_DSTMASK             0xFFC00000
+#define GP3_BASE_OFFSET_SRCMASK             0x003FF000
+#define GP3_BASE_OFFSET_CH3MASK             0x00000FFC
+
+/*----------------------------------------------------------------*/
+/*                  VIDEO GENERATOR DEFINITIONS                   */
+/*----------------------------------------------------------------*/
+
+#define DC3_UNLOCK                          0x00000000  /* Unlock register               */
+#define DC3_GENERAL_CFG                     0x00000004  /* Config registers              */
+#define DC3_DISPLAY_CFG                     0x00000008
+#define DC3_ARB_CFG                         0x0000000C
+
+#define DC3_FB_ST_OFFSET                    0x00000010  /* Frame buffer start offset     */
+#define DC3_CB_ST_OFFSET                    0x00000014  /* Compression start offset      */
+#define DC3_CURS_ST_OFFSET                  0x00000018  /* Cursor buffer start offset    */
+#define DC3_VID_Y_ST_OFFSET                 0x00000020  /* Video Y Buffer start offset   */
+#define DC3_VID_U_ST_OFFSET                 0x00000024  /* Video U Buffer start offset   */
+#define DC3_VID_V_ST_OFFSET                 0x00000028  /* Video V Buffer start offset   */
+#define DC3_DV_TOP                          0x0000002C  /* DV Ram Limit Register         */
+#define DC3_LINE_SIZE                       0x00000030  /* Video, CB, and FB line sizes  */
+#define DC3_GFX_PITCH                       0x00000034  /* FB and DB skip counts         */
+#define DC3_VID_YUV_PITCH                   0x00000038  /* Y, U and V buffer skip counts */
+
+#define DC3_H_ACTIVE_TIMING                 0x00000040  /* Horizontal timings            */
+#define DC3_H_BLANK_TIMING                  0x00000044
+#define DC3_H_SYNC_TIMING                   0x00000048
+#define DC3_V_ACTIVE_TIMING                 0x00000050  /* Vertical Timings              */
+#define DC3_V_BLANK_TIMING                  0x00000054
+#define DC3_V_SYNC_TIMING                   0x00000058
+#define DC3_FB_ACTIVE                       0x0000005C
+
+#define DC3_CURSOR_X                        0x00000060  /* Cursor X position             */
+#define DC3_CURSOR_Y                        0x00000064  /* Cursor Y Position             */
+#define DC3_LINE_CNT_STATUS                 0x0000006C
+
+#define DC3_PAL_ADDRESS                     0x00000070  /* Palette Address               */
+#define DC3_PAL_DATA                        0x00000074  /* Palette Data                  */
+#define DC3_DFIFO_DIAG                      0x00000078  /* Display FIFO diagnostic       */
+#define DC3_CFIFO_DIAG                      0x0000007C  /* Compression FIFO diagnostic   */
+
+#define DC3_VID_DS_DELTA                    0x00000080  /* Vertical Downscaling fraction */
+
+#define DC3_PHY_MEM_OFFSET                  0x00000084  /* VG Base Address Register      */
+#define DC3_DV_CTL                          0x00000088  /* Dirty-Valid Control Register  */
+#define DC3_DV_ACC                          0x0000008C  /* Dirty-Valid RAM Access        */
+
+#define DC3_GFX_SCALE                       0x00000090  /* Graphics Scaling              */
+#define DC3_IRQ_FILT_CTL                    0x00000094  /* VBlank interrupt and filters  */
+#define DC3_FILT_COEFF1                     0x00000098
+#define DC3_FILT_COEFF2                     0x0000009C
+
+#define DC3_VBI_EVEN_CTL                    0x000000A0  /* VBI Data Buffer Controls      */
+#define DC3_VBI_ODD_CTL                     0x000000A4
+#define DC3_VBI_HOR                         0x000000A8
+#define DC3_VBI_LN_ODD                      0x000000AC
+#define DC3_VBI_LN_EVEN                     0x000000B0
+#define DC3_VBI_PITCH                       0x000000B4
+
+#define DC3_COLOR_KEY                       0x000000B8  /* Graphics color key            */
+#define DC3_COLOR_MASK                      0x000000BC  /* Graphics color key mask       */
+#define DC3_CLR_KEY_X                       0x000000C0
+#define DC3_CLR_KEY_Y                       0x000000C4
+
+#define DC3_IRQ                             0x000000C8
+#define DC3_GENLK_CTL                       0x000000D4
+
+#define DC3_VID_EVEN_Y_ST_OFFSET            0x000000D8  /* Even field video buffers      */
+#define DC3_VID_EVEN_U_ST_OFFSET            0x000000DC
+#define DC3_VID_EVEN_V_ST_OFFSET            0x000000E0
+
+#define DC3_V_ACTIVE_EVEN                   0x000000E4  /* Even field timing registers   */
+#define DC3_V_BLANK_EVEN                    0x000000E8
+#define DC3_V_SYNC_EVEN                     0x000000EC
+
+/* UNLOCK VALUE */
+
+#define DC3_UNLOCK_VALUE		            0x00004758		/* used to unlock DC regs	*/
+
+/* VG GEODELINK DEVICE SMI MSR FIELDS */
+
+#define DC3_VG_BL_MASK                      0x00000001
+#define DC3_MISC_MASK                       0x00000002
+#define DC3_ISR0_MASK                       0x00000004
+#define DC3_VGA_BL_MASK                     0x00000008
+#define DC3_CRTCIO_MSK                      0x00000010
+#define DC3_VG_BLANK_SMI                    0x00000001
+#define DC3_MISC_SMI                        0x00000002
+#define DC3_ISR0_SMI                        0x00000004
+#define DC3_VGA_BLANK_SMI                   0x00000008
+#define DC3_CRTCIO_SMI                      0x00000010
+
+/* DC3_GENERAL_CFG BIT FIELDS */
+
+#define DC3_GCFG_DBUG                       0x80000000
+#define DC3_GCFG_DBSL                       0x40000000
+#define DC3_GCFG_CFRW                       0x20000000
+#define DC3_GCFG_DIAG                       0x10000000
+#define DC3_GCFG_CRC_MODE                   0x08000000
+#define DC3_GCFG_SGFR                       0x04000000
+#define DC3_GCFG_SGRE                       0x02000000
+#define DC3_GCFG_SIGE                       0x01000000
+#define DC3_GCFG_SIG_SEL                    0x00800000
+#define DC3_GCFG_YUV_420                    0x00100000
+#define DC3_GCFG_VDSE                       0x00080000
+#define DC3_GCFG_VGAFT                      0x00040000
+#define DC3_GCFG_FDTY                       0x00020000
+#define DC3_GCFG_STFM                       0x00010000
+#define DC3_GCFG_DFHPEL_MASK                0x0000F000
+#define DC3_GCFG_DFHPSL_MASK                0x00000F00
+#define DC3_GCFG_VGAE                       0x00000080
+#define DC3_GCFG_DECE                       0x00000040
+#define DC3_GCFG_CMPE                       0x00000020
+#define DC3_GCFG_FILT_SIG_SEL               0x00000010
+#define DC3_GCFG_VIDE                       0x00000008
+#define DC3_GCFG_CLR_CUR                    0x00000004
+#define DC3_GCFG_CURE                       0x00000002
+#define DC3_GCFG_DFLE                       0x00000001
+
+/* DC3_DISPLAY_CFG BIT FIELDS */
+
+#define DC3_DCFG_VISL                       0x08000000
+#define DC3_DCFG_FRLK                       0x04000000
+#define DC3_DCFG_PALB                       0x02000000
+#define DC3_DCFG_DCEN                       0x01000000
+#define DC3_DCFG_VFHPEL_MASK                0x000F0000
+#define DC3_DCFG_VFHPSL_MASK                0x0000F000
+#define DC3_DCFG_16BPP_MODE_MASK            0x00000C00
+#define DC3_DCFG_16BPP                      0x00000000
+#define DC3_DCFG_15BPP                      0x00000400
+#define DC3_DCFG_12BPP                      0x00000800
+#define DC3_DCFG_DISP_MODE_MASK             0x00000300
+#define DC3_DCFG_DISP_MODE_8BPP             0x00000000
+#define DC3_DCFG_DISP_MODE_16BPP            0x00000100
+#define DC3_DCFG_DISP_MODE_24BPP            0x00000200
+#define DC3_DCFG_DISP_MODE_32BPP            0x00000300
+#define DC3_DCFG_TRUP                       0x00000040
+#define DC3_DCFG_VDEN                       0x00000010
+#define DC3_DCFG_GDEN                       0x00000008
+#define DC3_DCFG_TGEN                       0x00000001
+
+/* DC3_ARB_CFG BIT FIELDS */
+
+#define DC3_ACFG_LB_LOAD_WM_EN              0x00100000
+#define DC3_ACFG_LB_LOAD_WM_MASK            0x000F0000
+#define DC3_ACFG_LPEN_END_COUNT_MASK        0x0000FE00
+#define DC3_ACFG_HPEN_SBINV                 0x00000100
+#define DC3_ACFG_HPEN_FB_INV_HALFSB         0x00000080
+#define DC3_ACFG_HPEN_FB_INV_SBRD           0x00000040
+#define DC3_ACFG_HPEN_FB_INV                0x00000020
+#define DC3_ACFG_HPEN_1LB_INV               0x00000010
+#define DC3_ACFG_HPEN_2LB_INV               0x00000008
+#define DC3_ACFG_HPEN_3LB_INV               0x00000004
+#define DC3_ACFG_HPEN_LB_FILL               0x00000002
+#define DC3_ACFG_LPEN_VSYNC                 0x00000001
+
+/* DC3_FB_ST_OFFSET BIT FIELDS */
+
+#define DC3_FB_ST_OFFSET_MASK               0x0FFFFFFF
+
+/* DC3_CB_ST_OFFSET BIT FIELDS */
+
+#define DC3_CB_ST_OFFSET_MASK               0x0FFFFFFF
+
+/* DC3_CURS_ST_OFFSET BIT FIELDS */
+
+#define DC3_CURS_ST_OFFSET_MASK             0x0FFFFFFF
+
+/* DC3_ICON_ST_OFFSET BIT FIELDS */
+
+#define DC3_ICON_ST_OFFSET_MASK             0x0FFFFFFF
+
+/* DC3_VID_Y_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_Y_ST_OFFSET_MASK            0x0FFFFFFF
+
+/* DC3_VID_U_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_U_ST_OFFSET_MASK            0x0FFFFFFF
+
+/* DC3_VID_V_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_V_ST_OFFSET_MASK            0x0FFFFFFF
+
+/* DC3_DV_TOP BIT FIELDS */
+
+#define DC3_DVTOP_ENABLE                    0x00000001
+#define DC3_DVTOP_MAX_MASK                  0x00FFFC00
+#define DC3_DVTOP_MAX_SHIFT                 10
+
+/* DC3_LINE_SIZE BIT FIELDS */
+
+#define DC3_LINE_SIZE_VLS_MASK              0x3FF00000
+#define DC3_LINE_SIZE_CBLS_MASK             0x0007F000
+#define DC3_LINE_SIZE_FBLS_MASK             0x000003FF
+#define DC3_LINE_SIZE_CB_SHIFT              12
+#define DC3_LINE_SIZE_VB_SHIFT              20
+
+/* DC3_GFX_PITCH BIT FIELDS */
+
+#define DC3_GFX_PITCH_CBP_MASK              0xFFFF0000
+#define DC3_GFX_PITCH_FBP_MASK              0x0000FFFF
+
+/* DC3_VID_YUV_PITCH BIT FIELDS */
+
+#define DC3_YUV_PITCH_UVP_MASK              0xFFFF0000
+#define DC3_YUV_PITCH_YBP_MASK              0x0000FFFF
+
+/* DC3_H_ACTIVE_TIMING BIT FIELDS */
+
+#define DC3_HAT_HT_MASK                     0x0FF80000
+#define DC3_HAT_HA_MASK                     0x00000FF8
+
+/* DC3_H_BLANK_TIMING BIT FIELDS */
+
+#define DC3_HBT_HBE_MASK                    0x0FF80000
+#define DC3_HBT_HBS_MASK                    0x00000FF8
+
+/* DC3_H_SYNC_TIMING BIT FIELDS */
+
+#define DC3_HST_HSE_MASK                    0x0FF80000
+#define DC3_HST_HSS_MASK                    0x00000FF8
+
+/* DC3_V_ACTIVE_TIMING BIT FIELDS */
+
+#define DC3_VAT_VT_MASK                     0x07FF0000
+#define DC3_VAT_VA_MASK                     0x000007FF
+
+/* DC3_V_BLANK_TIMING BIT FIELDS */
+
+#define DC3_VBT_VBE_MASK                    0x07FF0000
+#define DC3_VBT_VBS_MASK                    0x000007FF
+
+/* DC3_V_SYNC_TIMING BIT FIELDS */
+
+#define DC3_VST_VSE_MASK                    0x07FF0000
+#define DC3_VST_VSS_MASK                    0x000007FF
+
+/* DC3_LINE_CNT_STATUS BIT FIELDS     */
+
+#define DC3_LNCNT_DNA                       0x80000000
+#define DC3_LNCNT_VNA                       0x40000000
+#define DC3_LNCNT_VSA                       0x20000000
+#define DC3_LNCNT_VINT                      0x10000000
+#define DC3_LNCNT_FLIP                      0x08000000
+#define DC3_LNCNT_V_LINE_CNT                0x07FF0000
+#define DC3_LNCNT_VFLIP                     0x00008000
+#define DC3_LNCNT_SIGC                      0x00004000
+#define DC3_LNCNT_EVEN_FIELD                0x00002000
+#define DC3_LNCNT_SS_LINE_CMP               0x000007FF
+
+/* DC3_VID_DS_DELTA BIT FIELDS */
+
+#define DC3_DS_DELTA_MASK                   0xFFFC0000
+#define DC3_601_VSYNC_SHIFT_MASK            0x00000FFF
+#define DC3_601_VSYNC_SHIFT_ENABLE          0x00008000
+
+/* DC3_DV_CTL BIT DEFINITIONS */
+
+#define DC3_DV_LINE_SIZE_MASK               0x00000C00
+#define DC3_DV_LINE_SIZE_1024               0x00000000
+#define DC3_DV_LINE_SIZE_2048               0x00000400
+#define DC3_DV_LINE_SIZE_4096               0x00000800
+#define DC3_DV_LINE_SIZE_8192               0x00000C00
+
+/* DC3_IRQ_FILT_CTL DEFINITIONS */
+
+#define DC3_IRQFILT_LB_MASK                 0x80000200
+#define DC3_IRQFILT_LB_COEFF                0x00000000
+#define DC3_IRQFILT_SCALER_FILTER           0x00000200
+#define DC3_IRQFILT_SYNCHRONIZER            0x80000000
+#define DC3_IRQFILT_FLICKER_FILTER          0x80000200
+#define DC3_IRQFILT_LB_SEL_MASK             0x60000000
+#define DC3_IRQFILT_INTL_ADDR               0x10000000
+#define DC3_IRQFILT_LINE_MASK               0x07FF0000
+#define DC3_IRQFILT_ALPHA_FILT_EN           0x00004000
+#define DC3_IRQFILT_GFX_FILT_EN             0x00001000
+#define DC3_IRQFILT_INTL_EN                 0x00000800
+#define DC3_IRQFILT_H_FILT_SEL              0x00000400
+#define DC3_IRQFILT_LB_ADDR                 0x00000100
+
+/* DC3_VBI_EVEN_CTL DEFINITIONS */
+
+#define DC3_VBI_EVEN_ENABLE_CRC             (1L << 31)
+#define DC3_VBI_EVEN_CTL_ENABLE_16          (1L << 30)
+#define DC3_VBI_EVEN_CTL_UPSCALE            (1L << 29)
+#define DC3_VBI_ENABLE                      (1L << 28)
+#define DC3_VBI_EVEN_CTL_OFFSET_MASK        0x0FFFFFFF
+
+/* DC3_VBI_ODD_CTL DEFINITIONS */
+
+#define DC3_VBI_ODD_CTL_OFFSET_MASK         0x0FFFFFFF
+
+/* DC3_VBI_HOR BIT DEFINITIONS */
+
+#define DC3_VBI_HOR_END_SHIFT               16
+#define DC3_VBI_HOR_END_MASK				0x0FFF0000
+#define DC3_VBI_HOR_START_MASK				0x00000FFF
+
+/* DC3_VBI_LN_ODD BIT DEFINITIONS */
+
+#define DC3_VBI_ODD_ENABLE_SHIFT            2
+#define DC3_VBI_ODD_ENABLE_MASK             0x01FFFFFC
+#define DC3_VBI_ODD_LINE_SHIFT              25
+#define DC3_VBI_ODD_LINE_MASK               0xFE000000
+
+/* DC3_VBI_LN_EVEN BIT DEFINITIONS */
+
+#define DC3_VBI_EVEN_ENABLE_SHIFT           2
+#define DC3_VBI_EVEN_ENABLE_MASK			0x01FFFFFC
+#define DC3_VBI_EVEN_LINE_SHIFT             25
+#define DC3_VBI_EVEN_LINE_MASK				0xFE000000
+
+/* DC3_COLOR_KEY DEFINITIONS */
+
+#define DC3_CLR_KEY_DATA_MASK               0x00FFFFFF
+#define DC3_CLR_KEY_ENABLE                  0x01000000
+
+/* DC3_IRQ DEFINITIONS */
+
+#define DC3_IRQ_MASK                        0x00000001
+#define DC3_VSYNC_IRQ_MASK                  0x00000002
+#define DC3_IRQ_STATUS                      0x00010000
+#define DC3_VSYNC_IRQ_STATUS                0x00020000
+
+/* DC3_GENLK_CTL DEFINITIONS */
+
+#define DC3_GC_FLICKER_FILTER_NONE          0x00000000
+#define DC3_GC_FLICKER_FILTER_1_16          0x10000000
+#define DC3_GC_FLICKER_FILTER_1_8           0x20000000
+#define DC3_GC_FLICKER_FILTER_1_4           0x40000000
+#define DC3_GC_FLICKER_FILTER_5_16          0x50000000
+#define DC3_GC_FLICKER_FILTER_MASK          0xF0000000
+#define DC3_GC_ALPHA_FLICK_ENABLE           0x02000000
+#define DC3_GC_FLICKER_FILTER_ENABLE        0x01000000
+#define DC3_GC_VIP_VID_OK                   0x00800000
+#define DC3_GC_GENLK_ACTIVE                 0x00400000
+#define DC3_GC_SKEW_WAIT                    0x00200000
+#define DC3_GC_VSYNC_WAIT                   0x00100000
+#define DC3_GC_GENLOCK_TO_ENABLE            0x00080000
+#define DC3_GC_GENLOCK_ENABLE               0x00040000
+#define DC3_GC_GENLOCK_SKEW_MASK            0x0003FFFF
+
+/* VGA DEFINITIONS */
+
+#define DC3_SEQUENCER_INDEX                 0x03C4
+#define DC3_SEQUENCER_DATA                  0x03C5
+#define DC3_SEQUENCER_RESET                 0x00
+#define DC3_SEQUENCER_CLK_MODE              0x01
+
+#define DC3_RESET_VGA_DISP_ENABLE           0x03
+#define DC3_CLK_MODE_SCREEN_OFF             0x20
+
+/* DOT CLOCK FREQUENCY STRUCTURE */
+/* Note that m, n and p refer to the register m, n and p  */
+/* and not the m, n and p from the PLL equation.  The PLL */
+/* equation adds 1 to each value.                         */
+
+typedef struct tagPLLFrequency
+{
+	unsigned long pll_value;
+    unsigned long frequency;
+
+} PLL_FREQUENCY;
+
+/* VG MSRS */
+
+#define DC3_SPARE_MSR                       0x2011
+#define DC3_RAM_CTL                         0x2012
+
+/* DC3_SPARE_MSR DEFINITIONS */
+
+#define DC3_SPARE_DISABLE_CFIFO_HGO         0x00000800
+#define DC3_SPARE_VFIFO_ARB_SELECT          0x00000400
+#define DC3_SPARE_WM_LPEN_OVRD              0x00000200
+#define DC3_SPARE_LOAD_WM_LPEN_MASK         0x00000100
+#define DC3_SPARE_DISABLE_INIT_VID_PRI      0x00000080
+#define DC3_SPARE_DISABLE_VFIFO_WM          0x00000040
+#define DC3_SPARE_DISABLE_CWD_CHECK         0x00000020
+#define DC3_SPARE_PIX8_PAN_FIX              0x00000010
+#define DC3_SPARE_FIRST_REQ_MASK            0x00000002
+
+/* VG DIAG DEFINITIONS */
+
+#define DC3_MBD_DIAG_EN0                    0x00008000
+#define DC3_MBD_DIAG_EN1                    0x80000000
+#define DC3_DIAG_DOT_CRTC_DP                0x00000082
+#define DC3_DIAG_DOT_CRTC_DP_HIGH           0x00820000
+#define DC3_DIAG_EVEN_FIELD                 0x00002000
+
+/*----------------------------------------------------------------*/
+/*                DISPLAY FILTER DEFINITIONS                      */
+/*----------------------------------------------------------------*/
+
+#define DF_VIDEO_CONFIG 		            0x00000000
+#define DF_DISPLAY_CONFIG                   0x00000008
+#define DF_VIDEO_X_POS                      0x00000010
+#define DF_VIDEO_Y_POS                      0x00000018
+#define DF_VIDEO_SCALER                     0x00000020
+#define DF_VIDEO_COLOR_KEY			        0x00000028
+#define DF_VIDEO_COLOR_MASK			        0x00000030
+#define DF_PALETTE_ADDRESS 			        0x00000038
+#define DF_PALETTE_DATA	 			        0x00000040
+#define DF_SATURATION_LIMIT                 0x00000048
+#define DF_VID_MISC					        0x00000050
+#define DF_VIDEO_YSCALE                     0x00000060
+#define DF_VIDEO_XSCALE                     0x00000068
+#define DF_VID_CRC                          0x00000088
+#define DF_VID_CRC32                        0x00000090
+#define DF_VID_ALPHA_CONTROL                0x00000098
+#define DF_CURSOR_COLOR_KEY                 0x000000A0
+#define DF_CURSOR_COLOR_MASK                0x000000A8
+#define DF_CURSOR_COLOR_1                   0x000000B0
+#define DF_CURSOR_COLOR_2                   0x000000B8
+#define DF_ALPHA_XPOS_1                     0x000000C0
+#define DF_ALPHA_YPOS_1                     0x000000C8
+#define DF_ALPHA_COLOR_1                    0x000000D0
+#define DF_ALPHA_CONTROL_1                  0x000000D8
+#define DF_ALPHA_XPOS_2                     0x000000E0
+#define DF_ALPHA_YPOS_2                     0x000000E8
+#define DF_ALPHA_COLOR_2                    0x000000F0
+#define DF_ALPHA_CONTROL_2                  0x000000F8
+#define DF_ALPHA_XPOS_3                     0x00000100
+#define DF_ALPHA_YPOS_3                     0x00000108
+#define DF_ALPHA_COLOR_3                    0x00000110
+#define DF_ALPHA_CONTROL_3                  0x00000118
+#define DF_VIDEO_REQUEST                    0x00000120
+#define DF_ALPHA_WATCH                      0x00000128
+#define DF_VIDEO_TEST_MODE                  0x00000130
+#define DF_VID_YPOS_EVEN                    0x00000138
+#define DF_VID_ALPHA_Y_EVEN_1               0x00000140
+#define DF_VID_ALPHA_Y_EVEN_2               0x00000148
+#define DF_VID_ALPHA_Y_EVEN_3               0x00000150
+#define DF_VIDEO_PANEL_TIM1                 0x00000400
+#define DF_VIDEO_PANEL_TIM2                 0x00000408
+#define DF_POWER_MANAGEMENT                 0x00000410
+#define DF_DITHER_CONTROL                   0x00000418
+#define DF_DITHER_ACCESS                    0x00000448
+#define DF_DITHER_DATA                      0x00000450
+#define DF_PANEL_CRC                        0x00000458
+#define DF_PANEL_CRC32                      0x00000468
+#define DF_COEFFICIENT_BASE                 0x00001000
+
+/* DF_VIDEO_CONFIG BIT DEFINITIONS */
+
+#define DF_VCFG_VID_EN                      0x00000001	
+#define DF_VCFG_VID_INP_FORMAT              0x0000000C	
+#define DF_VCFG_SC_BYP                      0x00000020
+#define DF_VCFG_LINE_SIZE_LOWER_MASK        0x0000FF00	
+#define DF_VCFG_INIT_READ_MASK              0x01FF0000	
+#define DF_VCFG_LINE_SIZE_BIT8              0x08000000
+#define DF_VCFG_LINE_SIZE_BIT9              0x04000000
+#define DF_VCFG_4_2_0_MODE                  0x10000000	
+#define DF_VCFG_UYVY_FORMAT                 0x00000000
+#define DF_VCFG_Y2YU_FORMAT                 0x00000004
+#define DF_VCFG_YUYV_FORMAT                 0x00000008
+#define DF_VCFG_YVYU_FORMAT                 0x0000000C
+
+/* DF_DISPLAY_CONFIG BIT DEFINITIONS */
+
+#define DF_DCFG_DIS_EN                      0x00000001	
+#define DF_DCFG_HSYNC_EN                    0x00000002	
+#define DF_DCFG_VSYNC_EN                    0x00000004	
+#define DF_DCFG_DAC_BL_EN                   0x00000008		
+#define DF_DCFG_CRT_HSYNC_POL               0x00000100	
+#define DF_DCFG_CRT_VSYNC_POL               0x00000200		
+#define DF_DCFG_CRT_SYNC_SKW_MASK           0x0001C000
+#define DF_DCFG_CRT_SYNC_SKW_INIT           0x00010000
+#define DF_DCFG_PWR_SEQ_DLY_MASK            0x000E0000
+#define DF_DCFG_PWR_SEQ_DLY_INIT            0x00080000
+#define DF_DCFG_VG_CK                       0x00100000
+#define DF_DCFG_GV_PAL_BYP                  0x00200000
+#define DF_DAC_VREF                         0x04000000
+
+/* DF_VID_MISC BIT DEFINITIONS */
+
+#define DF_GAMMA_BYPASS_BOTH                0x00000001
+#define DF_DAC_POWER_DOWN                   0x00000400
+#define DF_ANALOG_POWER_DOWN                0x00000800
+#define DF_USER_IMPLICIT_SCALING            0x00001000
+
+/* DF_VID_ALPHA_CONTROL DEFINITIONS */
+
+#define DF_HD_VIDEO                         0x00000040
+#define DF_YUV_CSC_EN                       0x00000080
+#define DF_NO_CK_OUTSIDE_ALPHA              0x00000100
+#define DF_HD_GRAPHICS                      0x00000200
+#define DF_CSC_VIDEO_YUV_TO_RGB             0x00000400
+#define DF_CSC_GRAPHICS_RGB_TO_YUV          0x00000800
+#define DF_CSC_VOP_RGB_TO_YUV               0x00001000
+#define DF_VIDEO_INPUT_IS_RGB               0x00002000
+#define DF_VID_ALPHA_EN                     0x00004000
+#define DF_ALPHA_DRGB                       0x00008000
+
+/* VIDEO CURSOR COLOR KEY DEFINITIONS */
+
+#define DF_CURSOR_COLOR_KEY_ENABLE          0x20000000
+
+/* ALPHA COLOR BIT DEFINITION */
+
+#define DF_ALPHA_COLOR_ENABLE               0x01000000
+
+/* ALPHA CONTROL BIT DEFINITIONS */
+
+#define DF_ACTRL_WIN_ENABLE                 0x00010000
+#define DF_ACTRL_LOAD_ALPHA	                0x00020000
+#define DF_ACTRL_PERPIXEL_EN                0x00040000
+
+/* DF_VIDEO_SCALER DEFINITIONS */
+
+#define DF_SCALE_128_PHASES                 0x00002000
+#define DF_SCALE_DOUBLE_H_DOWNSCALE         0x00004000
+
+/* DEFAULT PANEL TIMINGS DEFINITIONS */
+
+#define DF_DEFAULT_TFT_PMTIM1               0x00000000
+#define DF_DEFAULT_XVGA_PMTIM1              0x00000000
+#define DF_DEFAULT_TFT_PMTIM2               0x08C00000
+#define DF_DEFAULT_XVGA_PMTIM2              0x08C10000
+#define DF_DEFAULT_TFT_PAD_SEL_LOW          0xDFFFFFFF
+#define DF_DEFAULT_TFT_PAD_SEL_HIGH         0x0000003F
+#define DF_DEFAULT_XVGA_PAD_SEL_LOW         0x00000000
+#define DF_DEFAULT_XVGA_PAD_SEL_HIGH        0x00000000
+#define DF_DEFAULT_DITHCTL                  0x00000070
+#define DF_DEFAULT_TV_PAD_SEL_HIGH          0x000000BF
+#define DF_DEFAULT_TV_PAD_SEL_LOW           0xDFFFFFFF
+#define DF_INVERT_VOP_CLOCK                 0x00000080
+
+/* DF_VIDEO_PANEL_TIM2 DEFINITIONS */
+
+#define DF_PMTIM2_TFT_PASSHTHROUGH          0x40000000
+
+/* DF_POWER_MANAGEMENT DEFINITIONS */
+
+#define DF_PM_PANEL_ON                      0x01000000
+#define DF_PM_INVERT_SHFCLK                 0x00002000
+
+/* DISPLAY FILTER MSRS */
+
+#define DF_MBD_MSR_DIAG_DF                  0x2010
+#define DF_MSR_PAD_SEL                      0x2011
+#define DF_DIAG_32BIT_CRC                   0x80000000
+
+#define DF_OUTPUT_CRT                       0x00000000
+#define DF_OUTPUT_PANEL                     0x00000008
+#define DF_OUTPUT_VOP                       0x00000030
+#define DF_OUTPUT_DRGB                      0x00000038
+#define DF_SIMULTANEOUS_CRT_FP              0x00008000
+#define DF_CONFIG_OUTPUT_MASK               0x00000038
+
+/*----------------------------------------------------------------*/
+/*                       MSR DEFINITIONS                          */
+/*----------------------------------------------------------------*/
+
+/*----------------------------*/
+/* STATIC GEODELINK ADRESSES  */
+/*----------------------------*/
+
+#define MSR_ADDRESS_GLIU0                   0x10000000
+#define MSR_ADDRESS_GLIU1                   0x40000000
+#define MSR_ADDRESS_GLIU2                   0x51010000
+#define MSR_ADDRESS_5535MPCI                0x51000000
+#define MSR_ADDRESS_VAIL                    0x00000000
+
+/*----------------------------*/
+/* UNIVERSAL DEVICE MSRS      */
+/*----------------------------*/
+
+#define MSR_GEODELINK_CAP                   0x2000
+#define MSR_GEODELINK_CONFIG                0x2001
+#define MSR_GEODELINK_SMI                   0x2002
+#define MSR_GEODELINK_ERROR                 0x2003
+#define MSR_GEODELINK_PM                    0x2004
+#define MSR_GEODELINK_DIAG                  0x2005
+
+/*----------------------------*/
+/* DEVICE CLASS CODES         */
+/*----------------------------*/
+
+#define MSR_CLASS_CODE_GLIU                 0x01
+#define MSR_CLASS_CODE_GLCP                 0x02
+#define MSR_CLASS_CODE_MPCI                 0x05
+#define MSR_CLASS_CODE_MC                   0x20
+#define MSR_CLASS_CODE_GP                   0x3D
+#define MSR_CLASS_CODE_VG                   0x3E
+#define MSR_CLASS_CODE_DF                   0x3F
+#define MSR_CLASS_CODE_FG                   0xF0
+#define MSR_CLASS_CODE_VAIL                 0x86
+#define MSR_CLASS_CODE_USB                  0x42
+#define MSR_CLASS_CODE_USB2                 0x43
+#define MSR_CLASS_CODE_ATAC	                0x47
+#define MSR_CLASS_CODE_MDD 	                0xDF
+#define MSR_CLASS_CODE_ACC 	                0x33
+#define MSR_CLASS_CODE_AES                  0x30
+#define MSR_CLASS_CODE_VIP                  0x3C
+#define MSR_CLASS_CODE_REFLECTIVE           0xFFF
+#define MSR_CLASS_CODE_UNPOPULATED          0x7FF
+
+/*----------------------------*/
+/*   GLIU MSR DEFINITIONS     */
+/*----------------------------*/
+
+#define MSR_GLIU_CAP                        0x0086
+#define MSR_GLIU_WHOAMI			            0x008B
+
+#define NUM_PORTS_MASK                      0x00380000
+#define NUM_PORTS_SHIFT                     19
+#define WHOAMI_MASK			                0x07
+
+/*----------------------------*/
+/*   GLCP MSR DEFINITIONS     */
+/*----------------------------*/
+
+#define GLCP_CLKOFF                         0x0010
+#define GLCP_CLKACTIVE                      0x0011
+#define GLCP_CLKDISABLE                     0x0012
+#define GLCP_CLK4ACK                        0x0013
+#define GLCP_SYS_RSTPLL                     0x0014
+#define GLCP_DOTPLL                         0x0015
+#define GLCP_DBGCLKCTL                      0x0016
+#define GLCP_REVID                          0x0017
+#define GLCP_RAW_DIAG                       0x0028
+#define GLCP_SETM0CTL                       0x0040
+#define GLCP_SETN0CTL                       0x0048
+#define GLCP_CMPVAL0                        0x0050
+#define GLCP_CMPMASK0                       0x0051
+#define GLCP_REGA                           0x0058
+#define GLCP_REGB                           0x0059
+#define GLCP_REGAMASK                       0x005A
+#define GLCP_REGAVAL                        0x005B
+#define GLCP_REGBMASK                       0x005C
+#define GLCP_REGBVAL                        0x005D
+#define GLCP_FIFOCTL                        0x005E
+#define GLCP_DIAGCTL                        0x005F
+#define GLCP_H0CTL                          0x0060
+#define GLCP_XSTATE                         0x0066
+#define GLCP_YSTATE                         0x0067
+#define GLCP_ACTION0                        0x0068
+
+/* GLCP_DOTPLL DEFINITIONS */
+
+#define GLCP_DOTPLL_RESET                   0x00000001
+#define GLCP_DOTPLL_BYPASS                  0x00008000
+#define GLCP_DOTPLL_HALFPIX                 0x01000000
+#define GLCP_DOTPLL_LOCK                    0x02000000
+#define GLCP_DOTPLL_VIPCLK                  0x00008000
+#define GLCP_DOTPLL_DIV4                    0x00010000
+
+/* GLCP DIAG DEFINITIONS */
+
+#define GLCP_MBD_DIAG_SEL0                  0x00000007
+#define GLCP_MBD_DIAG_EN0                   0x00008000
+#define GLCP_MBD_DIAG_SEL1                  0x00070000
+#define GLCP_MBD_DIAG_EN1                   0x80000000
+
+/*--------------------------------*/
+/* DISPLAY FILTER MSR DEFINITIONS */
+/*--------------------------------*/
+
+/* DISPLAY FILTER MBD_MSR_DIAG DEFINITIONS */
+
+#define DF_MBD_DIAG_SEL0                    0x00007FFF
+#define DF_MBD_DIAG_EN0                     0x00008000
+#define DF_MBD_DIAG_SEL1                    0x7FFF0000
+#define DF_MBD_DIAG_EN1                     0x80000000
+
+/* DISPLAY FILTER MBD_MSR_CONFIG DEFINITIONS */
+
+#define DF_CONFIG_FMT_MASK                  0x00000038
+#define DF_CONFIG_FMT_CRT                   0x00000000
+#define DF_CONFIG_FMT_FP                    0x00000008
+
+/*----------------------------------------------------------------*/
+/*                       PCI DEFINITIONS                          */
+/*----------------------------------------------------------------*/
+
+#define PCI_VENDOR_DEVICE_GEODEGX           0x0028100B
+#define PCI_VENDOR_DEVICE_GEODEGX_VIDEO     0x0030100B
+#define PCI_VENDOR_DEVICE_GEODELX           0x20801022
+#define PCI_VENDOR_DEVICE_GEODELX_VIDEO     0x20811022
+#define PCI_VENDOR_5535                     0x002B100B
+#define PCI_VENDOR_5536                     0x20901022
+
+/*----------------------------------------------------------------*/
+/*                       VIP DEFINITIONS                          */
+/*----------------------------------------------------------------*/
+
+#define VIP_CONTROL1                        0x00000000
+#define VIP_CONTROL2                        0x00000004
+#define VIP_STATUS                          0x00000008
+#define VIP_INTERRUPT                       0x0000000C
+#define VIP_CURRENT_TARGET                  0x00000010
+#define VIP_MAX_ADDRESS                     0x00000014
+#define	VIP_TASKA_VID_EVEN_BASE             0x00000018
+#define	VIP_TASKA_VID_ODD_BASE              0x0000001C
+#define	VIP_TASKA_VBI_EVEN_BASE             0x00000020
+#define	VIP_TASKA_VBI_ODD_BASE              0x00000024
+#define VIP_TASKA_VID_PITCH                 0x00000028
+#define VIP_CONTROL3                        0x0000002C
+#define VIP_TASKA_V_OFFSET                  0x00000030
+#define VIP_TASKA_U_OFFSET                  0x00000034
+#define	VIP_TASKB_VID_EVEN_BASE             0x00000038
+#define VIP_601_HORZ_END                    0x00000038
+#define	VIP_TASKB_VID_ODD_BASE              0x0000003C
+#define	VIP_601_HORZ_START                  0x0000003C
+#define	VIP_TASKB_VBI_EVEN_BASE             0x00000040
+#define	VIP_601_VBI_END                     0x00000040
+#define	VIP_TASKB_VBI_ODD_BASE              0x00000044
+#define	VIP_601_VBI_START                   0x00000044
+#define VIP_TASKB_VID_PITCH                 0x00000048
+#define VIP_601_EVEN_START_STOP             0x00000048
+#define VIP_TASKB_V_OFFSET                  0x00000050
+#define VIP_ODD_FIELD_DETECT                0x00000050
+#define VIP_TASKB_U_OFFSET                  0x00000054
+#define	VIP_ANC_MSG1_BASE                   0x00000058
+#define	VIP_ANC_MSG2_BASE                   0x0000005C
+#define	VIP_ANC_MSG_SIZE                    0x00000060
+#define VIP_PAGE_OFFSET                     0x00000068
+#define VIP_VERTICAL_START_STOP             0x0000006C
+#define VIP_601_ODD_START_STOP              0x0000006C
+#define VIP_FIFO_ADDRESS                    0x00000070
+#define VIP_FIFO_DATA                       0x00000074
+#define VIP_VSYNC_ERR_COUNT                 0x00000078
+#define VIP_TASKA_U_EVEN_OFFSET             0x0000007C
+#define VIP_TASKA_V_EVEN_OFFSET             0x00000080
+
+/* INDIVIDUAL REGISTER BIT DEFINITIONS                          */
+/* Multibit register subsets are expressed as a mask and shift. */
+/* Single bit values are represented as a mask.                 */
+
+/* VIP_CONTROL1 REGISTER DEFINITIONS */
+
+#define VIP_CONTROL1_DEFAULT_ANC_FF         2
+#define VIP_CONTROL1_ANC_FF_MASK            0xE0000000
+#define VIP_CONTROL1_ANC_FF_SHIFT           29
+
+#define VIP_CONTROL1_DEFAULT_VID_FF         2
+#define VIP_CONTROL1_VID_FF_MASK            0x1F000000
+#define VIP_CONTROL1_VID_FF_SHIFT           24
+
+#define VIP_CONTROL1_VDE_FF_MASK            0x00F00000
+#define VIP_CONTROL1_VDE_FF_SHIFT           20
+
+#define VIP_CONTROL1_NON_INTERLACED         (1L << 19)
+#define VIP_CONTROL1_MSG_STRM_CTRL          (1L << 18)
+#define VIP_CONTROL1_DISABLE_ZERO_DETECT    (1L << 17)
+#define VIP_CONTROL1_DISABLE_DECIMATION     (1L << 16)
+
+#define VIP_CONTROL1_CAPTURE_ENABLE_MASK    0x0000FF00
+#define VIP_CONTROL1_CAPTURE_ENABLE_SHIFT   8
+
+#define VIP_CONTROL1_RUNMODE_MASK           0x000000E0
+#define VIP_CONTROL1_RUNMODE_SHIFT          5
+
+#define VIP_CONTROL1_PLANAR                 (1L << 4)
+
+#define VIP_CONTROL1_MODE_MASK              0x0000000E
+#define VIP_CONTROL1_MODE_SHIFT             1
+
+#define VIP_CONTROL1_RESET                  0x00000001
+
+/* VIP_CONTROL2 REGISTER DEFINITIONS */
+
+#define VIP_CONTROL2_INVERT_POLARITY        (1L << 31)
+#define VIP_CONTROL2_ADD_ERROR_ENABLE       (1L << 30)
+#define VIP_CONTROL2_REPEAT_ENABLE          (1L << 29)
+#define VIP_CONTROL2_SWC_ENABLE             (1L << 28)
+#define VIP_CONTROL2_ANC10                  (1L << 27)
+#define VIP_CONTROL2_ANCPEN                 (1L << 26)
+#define VIP_CONTROL2_LOOPBACK_ENABLE        (1L << 25)
+#define VIP_CONTROL2_FIFO_ACCESS            (1L << 24)
+#define VIP_CONTROL2_VERTERROR_ENABLE       (1L << 15)
+
+#define VIP_CONTROL2_PAGECNT_MASK           0x00E00000
+#define VIP_CONTROL2_PAGECNT_SHIFT          21
+
+#define VIP_CONTROL2_DEFAULT_ANCTH          5
+#define VIP_CONTROL2_ANCTH_MASK             0x001F0000
+#define VIP_CONTROL2_ANCTH_SHIFT            16
+
+#define VIP_CONTROL2_DEFAULT_VIDTH_420      19
+#define VIP_CONTROL2_DEFAULT_VIDTH_422      19
+#define VIP_CONTROL2_VIDTH_MASK             0x00007F00
+#define VIP_CONTROL2_VIDTH_SHIFT            8
+
+#define VIP_CONTROL2_SYNC2PIN_MASK          0x000000E0
+#define VIP_CONTROL2_SYNC2PIN_SHIFT         5
+
+#define VIP_CONTROL2_FIELD2VG_MASK          0x00000018
+#define VIP_CONTROL2_FIELD2VG_SHIFT         3
+
+#define VIP_CONTROL2_SYNC2VG_MASK           0x00000007
+#define VIP_CONTROL2_SYNC2VG_SHIFT          0
+
+/* VIP_CONTROL3 REGISTER DEFINITIONS */
+
+#define VIP_CONTROL3_PLANAR_DEINT           0x00000400
+#define VIP_CONTROL3_BASE_UPDATE            0x00000200
+#define VIP_CONTROL3_DISABLE_OVERFLOW       0x00000100
+#define VIP_CONTROL3_DECIMATE_EVEN          0x00000080
+#define VIP_CONTROL3_TASK_POLARITY          0x00000040
+#define VIP_CONTROL3_VSYNC_POLARITY         0x00000020
+#define VIP_CONTROL3_HSYNC_POLARITY         0x00000010
+#define VIP_CONTROL3_FIFO_RESET             0x00000001
+
+/* VIP_STATUS REGISTER DEFINITIONS */
+
+#define VIP_STATUS_ANC_COUNT_MASK           0xFF000000
+#define VIP_STATUS_ANC_COUNT_SHIFT          24
+
+#define VIP_STATUS_FIFO_ERROR               0x00700000
+#define VIP_STATUS_ERROR_SHIFT              20
+#define VIP_STATUS_DEC_COUNT                (1L << 18)
+#define VIP_STATUS_SYNCOUT                  (1L << 17)
+#define VIP_STATUS_BASEREG_NOTUPDT          (1L << 16)
+#define VIP_STATUS_MSGBUFF_ERR              (1L << 14)
+#define VIP_STATUS_MSGBUFF2_FULL            (1L << 13)
+#define VIP_STATUS_MSGBUFF1_FULL            (1L << 12)
+#define VIP_STATUS_WRITES_COMPLETE          (1L << 9)
+#define VIP_STATUS_FIFO_EMPTY               (1L << 8)
+#define VIP_STATUS_FIELD                    (1L << 4)
+#define VIP_STATUS_VBLANK                   (1L << 3)
+
+#define VIP_STATUS_RUN_MASK                 0x00000007
+#define VIP_STATUS_RUN_SHIFT                0
+
+/* VIP_CURRENT_TARGET REGISTER DEFINITIONS */
+
+#define VIP_CTARGET_TLINE_MASK              0xFFFF0000
+#define VIP_CTARGET_TLINE_SHIFT             16
+
+#define VIP_CTARGET_CLINE_MASK              0x0000FFFF
+#define VIP_CTARGET_CLINE_SHIFT             0
+
+/* VIP_MAX_ADDRESS REGISTER DEFINITIONS */
+
+#define VIP_MAXADDR_MASK                    0xFFFFFFFF
+#define VIP_MAXADDR_SHIFT                   0
+
+/* VIP BUFFER PITCH DEFINITIONS */
+
+#define VIP_TASK_PITCH_MASK                 0x0000FFFF
+#define VIP_TASK_PITCH_SHIFT                0
+
+/* VERTICAL START/STOP */
+
+#define VIP_VSTART_VERTEND_MASK             0x0FFF0000
+#define VIP_VSTART_VERTEND_SHIFT            16
+
+#define VIP_VSTART_VERTSTART_MASK           0x00000FFF
+#define VIP_VSTART_VERTSTART_SHIFT          0
+
+/* VIP FIFO ADDRESS DEFINITIONS */
+
+#define VIP_FIFO_ADDRESS_MASK               0x000000FF
+#define VIP_FIFO_ADDRESS_SHIFT              0
+
+/* VIP VSYNC ERROR DEFINITIONS */
+
+#define VIP_VSYNC_ERR_WINDOW_MASK           0xFF000000
+#define VIP_VSYNC_ERR_WINDOW_SHIFT          24
+
+#define VIP_VSYNC_ERR_COUNT_MASK            0x00FFFFFF
+#define VIP_VSYNC_ERR_COUNT_SHIFT           0
+
+/*---------------------*/
+/* VIP MSR DEFINITIONS */
+/*---------------------*/
+
+/* CAPABILITIES */
+
+#define VIP_MSR_CAP_NSMI_MASK               0xF8000000
+#define VIP_MSR_CAP_NSMI_SHIFT              27		
+#define VIP_MSR_CAP_NCLK_MASK               0x07000000
+#define VIP_MSR_CAP_NCLK_SHIFT              24
+#define VIP_MSR_CAP_DEVID_MASK              0x00FFFF00
+#define VIP_MSR_CAP_DEVID_SHIFT             8
+#define VIP_MSR_CAP_REVID_MASK              0x000000FF
+#define VIP_MSR_CAP_REVID_SHIFT             0
+
+/* MASTER CONFIG */
+
+#define VIP_MSR_MCR_SECOND_PRIORITY_MASK    0x00000700
+#define VIP_MSR_MCR_SECOND_PRIORITY_SHIFT   8
+#define VIP_MSR_MCR_PRIMARY_PRIORITY_MASK   0x00000070
+#define VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT  4
+#define VIP_MSR_MCR_PID_MASK                0x00000007
+#define VIP_MSR_MCR_PID_SHIFT               0
+
+/* VIP SMI */
+
+#define VIP_MSR_SMI_FIFO_OVERFLOW           (1L << 29)
+#define VIP_MSR_SMI_FIFO_THRESHOLD          (1L << 28)
+#define VIP_MSR_SMI_LONGLINE                (1L << 27)
+#define VIP_MSR_SMI_VERTICAL_TIMING         (1L << 26)
+#define VIP_MSR_SMI_ACTIVE_PIXELS           (1L << 25)
+#define VIP_MSR_SMI_CLOCK_INPUT             (1L << 24)
+#define VIP_MSR_SMI_ANC_CHECKSUM_PARITY     (1L << 23)
+#define VIP_MSR_SMI_MSG_BUFFER_FULL         (1L << 22)
+#define VIP_MSR_SMI_END_VBLANK              (1L << 21)
+#define VIP_MSR_SMI_START_VBLANK            (1L << 20)
+#define VIP_MSR_SMI_START_EVEN              (1L << 19)
+#define VIP_MSR_SMI_START_ODD               (1L << 18)
+#define VIP_MSR_SMI_LINE_MATCH_TARGET       (1L << 17)
+#define VIP_MSR_SMI_GLINK                   (1L << 16)
+
+/* VIP ERROR */
+
+#define VIP_MSR_ERROR_ADDRESS_MASK          (1L << 17)
+#define VIP_MSR_ERROR_ADDRESS_SHIFT         17
+#define VIP_MSR_ERROR_ADDRESS_ENABLE        (1L << 1)
+#define VIP_MSR_ERROR_ADDRESS_EN_SHIFT      1
+#define VIP_MSR_ERROR_TYPE_MASK             (1L << 16)
+#define VIP_MSR_ERROR_TYPE_SHIFT            16
+#define VIP_MSR_ERROR_TYPE_ENABLE           1
+#define VIP_MSR_ERROR_TYPE_EN_SHIFT         0
+
+/* VIP POWER */
+
+#define VIP_MSR_POWER_GLINK                 (1L << 0)
+#define VIP_MSR_POWER_CLOCK                 (1L << 2)
+
+/* VIP DIAG */
+
+#define VIP_MSR_DIAG_BIST_WMASK             0x00000003
+#define VIP_MSR_DIAG_BIST_RMASK             0x00000007
+#define VIP_MSR_DIAG_BIST_SHIFT             0
+
+#define VIP_MSR_DIAG_MSB_ENABLE             (1L << 31)
+#define VIP_MSR_DIAG_SEL_UPPER_MASK         0x7FFF0000	
+#define VIP_MSR_DIAG_SEL_UPPER_SHIFT        16
+#define VIP_MSR_DIAG_LSB_ENABLE             (1L << 15)
+#define VIP_MSR_DIAG_SEL_LOWER_MASK         0x00007FFF	
+#define VIP_MSR_DIAG_SEL_LOWER_SHIFT        0
+
+/*----------------------------------------------------------------*/
+/*                       VOP DEFINITIONS                          */
+/*----------------------------------------------------------------*/
+
+#define VOP_CONFIGURATION                   0x00000800
+#define VOP_SIGNATURE                       0x00000808
+
+/* VOP_CONFIGURATION BIT DEFINITIONS */
+
+#define VOP_CONFIG_SWAPVBI                  0x01000000
+#define VOP_CONFIG_RGBMODE                  0x00200000
+#define VOP_CONFIG_SIGVAL                   0x00100000
+#define VOP_CONFIG_INVERT_DISPE             0x00080000
+#define VOP_CONFIG_INVERT_VSYNC             0x00040000
+#define VOP_CONFIG_INVERT_HSYNC             0x00020000
+#define VOP_CONFIG_SWAPUV                   0x00010000
+#define VOP_CONFIG_VSYNC_MASK               0x0000C000
+#define VOP_CONFIG_DISABLE_DECIMATE         0x00002000
+#define VOP_CONFIG_ENABLE_601               0x00001000
+#define VOP_CONFIG_VBI                      0x00000800
+#define VOP_CONFIG_TASK                     0x00000200
+#define VOP_CONFIG_SIG_FREE_RUN             0x00000100
+#define VOP_CONFIG_ENABLE_SIGNATURE         0x00000080
+#define VOP_CONFIG_SC_COMPATIBLE            0x00000040
+#define VOP_CONFIG_422_COSITED              0x00000000
+#define VOP_CONFIG_422_INTERSPERSED         0x00000010
+#define VOP_CONFIG_422_ALTERNATING          0x00000020
+#define VOP_CONFIG_422_MASK                 0x00000030
+#define VOP_CONFIG_EXTENDED_SAV             0x00000008
+#define VOP_CONFIG_VIP2_16BIT               0x00000004
+#define VOP_CONFIG_DISABLED                 0x00000000
+#define VOP_CONFIG_VIP1_1                   0x00000001
+#define VOP_CONFIG_VIP2_0                   0x00000002
+#define VOP_CONFIG_CCIR656                  0x00000003
+#define VOP_CONFIG_MODE_MASK                0x00000003
+
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_rtns.h xf86-video-nsc-2.8.1/src/cim/cim_rtns.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_rtns.h	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_rtns.h	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,338 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron function prototypes.
+  * </DOC_AMD_STD>
+  *
+  */
+
+#ifndef _cim_rtns_h
+#define _cim_rtns_h
+
+/* INCLUDE USER PARAMETER DEFINITIONS */
+
+#include "cim_parm.h"
+
+/* COMPILER OPTION FOR C++ PROGRAMS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*--------------------------*/
+/* CIMARRON MEMORY POINTERS */
+/*--------------------------*/
+
+extern unsigned char *cim_gp_ptr;
+extern unsigned char *cim_fb_ptr;
+extern unsigned char *cim_cmd_base_ptr;
+extern unsigned char *cim_cmd_ptr;
+extern unsigned char *cim_vid_ptr;
+extern unsigned char *cim_vip_ptr;
+extern unsigned char *cim_vg_ptr;
+
+/*----------------------------------------*/
+/* INITIALIZATION ROUTINE DEFINITIONS     */
+/*----------------------------------------*/
+
+int init_detect_cpu (unsigned long *cpu_revision, unsigned long *companion_revision);
+unsigned long init_read_pci	(unsigned long address);
+int init_read_base_addresses (INIT_BASE_ADDRESSES *base_addresses);
+int init_read_cpu_frequency (unsigned long *cpu_frequency);
+
+/*----------------------------------------*/
+/* GRAPHICS PROCESSOR ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+void gp_set_limit_on_buffer_lead (unsigned long lead);
+void gp_set_command_buffer_base (unsigned long address, unsigned long start,
+	unsigned long stop);
+void gp_set_frame_buffer_base (unsigned long address, unsigned long size);
+void gp_set_bpp (int bpp);
+void gp_declare_blt (unsigned long flags);
+void gp_declare_vector (unsigned long flags);
+void gp_write_parameters (void);
+void gp_set_raster_operation (unsigned char ROP);
+void gp_set_alpha_operation (int alpha_operation, int alpha_type, int channel,
+	int apply_alpha, unsigned char alpha);
+void gp_set_solid_pattern (unsigned long color);
+void gp_set_mono_pattern (unsigned long bgcolor, unsigned long fgcolor,
+	unsigned long data0, unsigned long data1, int transparent, int x, int y);
+void gp_set_pattern_origin (int x, int y);
+void gp_set_color_pattern (unsigned long *pattern, int format, int x, int y);
+void gp_set_mono_source (unsigned long bgcolor, unsigned long fgcolor,
+	int transparent);
+void gp_set_solid_source (unsigned long color);
+void gp_set_source_transparency (unsigned long color, unsigned long mask);
+void gp_program_lut (unsigned long *colors, int full_lut);
+void gp_set_vector_pattern (unsigned long pattern, unsigned long color, int length);
+void gp_set_strides (unsigned long dst_stride, unsigned long src_stride);
+void gp_set_source_format (int format);
+void gp_pattern_fill (unsigned long dstoffset, unsigned long width, unsigned long height);
+void gp_screen_to_screen_blt (unsigned long dstoffset, unsigned long srcoffset,
+	unsigned long width, unsigned long height, int flags);
+void gp_screen_to_screen_convert (unsigned long dstoffset, unsigned long srcoffset,
+    unsigned long width, unsigned long height, int nibble);
+void gp_color_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+    unsigned long width, unsigned long height, unsigned char *data, long pitch);
+void gp_color_convert_blt (unsigned long dstoffset, unsigned long srcx,
+    unsigned long width, unsigned long height, unsigned char *data, long pitch);
+void gp_custom_convert_blt (unsigned long dstoffset, unsigned long srcx,
+    unsigned long width, unsigned long height, unsigned char *data, long pitch);
+void gp_rotate_blt (unsigned long dstoffset, unsigned long srcoffset,
+	unsigned long width, unsigned long height, int degrees);
+void gp_mono_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+	unsigned long width, unsigned long height, unsigned char *data, long stride);
+void gp_text_blt (unsigned long dstoffset, unsigned long width,
+	unsigned long height, unsigned char *data);
+void gp_mono_expand_blt (unsigned long dstoffset, unsigned long srcoffset,
+    unsigned long srcx, unsigned long width, unsigned long height, int byte_packed);
+void gp_antialiased_text (unsigned long dstoffset, unsigned long srcx,
+	unsigned long width, unsigned long height, unsigned char *data, long stride,
+	int fourbpp);
+void gp_masked_blt (unsigned long dstoffset, unsigned long width,
+	unsigned long height, unsigned long mono_srcx, unsigned long color_srcx,
+	unsigned char *mono_mask, unsigned char *color_data, long mono_pitch,
+	long color_pitch);
+void gp_screen_to_screen_masked (unsigned long dstoffset, unsigned long srcoffset,
+    unsigned long width, unsigned long height, unsigned long mono_srcx,
+    unsigned char *mono_mask, long mono_pitch);
+void gp_bresenham_line (unsigned long dstoffset, unsigned short length,
+	unsigned short initerr, unsigned short axialerr, unsigned short diagerr,
+	unsigned long flags);
+void gp_line_from_endpoints (unsigned long dstoffset, unsigned long x0,
+    unsigned long y0, unsigned long x1, unsigned long y1, int inclusive);
+
+int gp_test_blt_pending (void);
+void gp_wait_blt_pending (void);
+void gp_wait_until_idle (void);
+int gp_test_blt_busy (void);
+void gp_save_state (GP_SAVE_RESTORE *gp_state);
+void gp_restore_state (GP_SAVE_RESTORE *gp_state);
+
+/*----------------------------------------*/
+/* VIDEO GENERATOR ROUTINE DEFINITIONS    */
+/*----------------------------------------*/
+
+int vg_delay_milliseconds (unsigned long ms);
+int vg_set_display_mode (unsigned long src_width, unsigned long src_height,
+	unsigned long dst_width, unsigned long dst_height, int bpp, int hz,
+    unsigned long flags);
+int vg_set_panel_mode (unsigned long src_width, unsigned long src_height,
+	unsigned long dst_width,   unsigned long dst_height,
+	unsigned long panel_width, unsigned long panel_height,
+	int bpp, unsigned long flags);
+int vg_set_tv_mode (unsigned long *src_width, unsigned long *src_height,
+    unsigned long encoder, unsigned long tvres, int bpp, unsigned long flags,
+    unsigned long h_overscan, unsigned long v_overscan);
+int vg_set_custom_mode (VG_DISPLAY_MODE *mode_params, int bpp);
+int vg_set_display_bpp (int bpp);
+int vg_get_display_mode_index (VG_QUERY_MODE *query);
+int vg_get_display_mode_information (unsigned int index, VG_DISPLAY_MODE *vg_mode);
+int vg_get_display_mode_count (void);
+int vg_get_current_display_mode (VG_DISPLAY_MODE *current_display, int *bpp);
+int vg_set_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3]);
+int vg_configure_flicker_filter (unsigned long flicker_strength, int flicker_alpha);
+int vg_set_clock_frequency (unsigned long frequency, unsigned long pll_flags);
+int vg_set_border_color (unsigned long border_color);
+int vg_set_cursor_enable(int enable);
+int vg_set_mono_cursor_colors (unsigned long bkcolor, unsigned long fgcolor);
+int vg_set_cursor_position(long xpos, long ypos, VG_PANNING_COORDINATES *panning);
+int vg_set_mono_cursor_shape32(unsigned long memoffset, unsigned long *andmask,
+	unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot);
+int vg_set_mono_cursor_shape64(unsigned long memoffset, unsigned long *andmask,
+	unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot);
+int vg_set_color_cursor_shape (unsigned long memoffset, unsigned char *data,
+	unsigned long width, unsigned long height, long pitch,
+	unsigned long x_hotspot, unsigned long y_hotspot);
+int vg_pan_desktop (unsigned long x, unsigned long y, VG_PANNING_COORDINATES *panning);
+int vg_set_display_offset (unsigned long address);
+int vg_set_display_pitch (unsigned long pitch);
+int vg_set_display_palette_entry (unsigned long index, unsigned long palette);
+int vg_set_display_palette (unsigned long *palette);
+int vg_set_compression_enable (int enable);
+int vg_configure_compression (VG_COMPRESSION_DATA *comp_data);
+int vg_test_timing_active (void);
+int vg_test_vertical_active (void);
+int vg_wait_vertical_blank(void);
+int vg_test_even_field(void);
+int vg_configure_line_interrupt (VG_INTERRUPT_PARAMS *interrupt_info);
+unsigned long vg_test_and_clear_interrupt (void);
+unsigned long vg_test_flip_status (void);
+int vg_save_state (VG_SAVE_RESTORE *vg_state);
+int vg_restore_state (VG_SAVE_RESTORE *vg_state);
+
+/*----------------------------------------*/
+/* VIDEO GENERATOR READ ROUTINES          */
+/*----------------------------------------*/
+
+unsigned long vg_read_graphics_crc (int crc_source);
+unsigned long vg_read_window_crc (int crc_source, unsigned long x, unsigned long y,
+    unsigned long width, unsigned long height);
+int vg_get_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3]);
+int vg_get_flicker_filter_configuration (unsigned long *strength, int *flicker_alpha);
+unsigned long vg_get_display_pitch (void);
+unsigned long vg_get_frame_buffer_line_size (void);
+unsigned long vg_get_current_vline (void);
+unsigned long vg_get_display_offset (void);
+int vg_get_cursor_info (VG_CURSOR_DATA *cursor_data);
+int vg_get_display_palette_entry (unsigned long index, unsigned long *entry);
+unsigned long vg_get_border_color (void);
+int vg_get_display_palette (unsigned long *palette);
+int vg_get_compression_info (VG_COMPRESSION_DATA *comp_data);
+int vg_get_compression_enable (void);
+int vg_get_valid_bit (int line);
+
+/*----------------------------------------*/
+/* DISPLAY FILTER ROUTINE DEFINITIONS     */
+/*----------------------------------------*/
+
+int df_set_crt_enable (int crt_output);
+int df_set_panel_enable (int panel_output);
+int df_configure_video_source (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+	DF_VIDEO_SOURCE_PARAMS *video_source_even);
+int df_set_video_offsets (int even, unsigned long y_offset,
+	unsigned long u_offset, unsigned long v_offset);
+int df_set_video_scale (unsigned long src_width, unsigned long src_height,
+	unsigned long dst_width, unsigned long dst_height, unsigned long flags);
+int df_set_video_position (DF_VIDEO_POSITION *video_window);
+int df_set_video_filter_coefficients (long taps[][4], int phase256);
+int df_set_video_enable (int enable, unsigned long flags);
+int df_set_video_color_key (unsigned long key, unsigned long mask, int graphics);
+int df_set_video_palette (unsigned long *palette);
+int df_set_video_palette_entry (unsigned long index, unsigned long palette);
+int df_configure_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key);
+int df_set_video_cursor_color_key_enable (int enable);
+int df_configure_alpha_window (int window, DF_ALPHA_REGION_PARAMS *alpha_data);
+int df_set_alpha_window_enable (int window, int enable);
+int df_set_no_ck_outside_alpha (int enable);
+int df_set_video_request (unsigned long x, unsigned long y);
+int df_set_output_color_space (int color_space);
+int df_set_output_path (int format);
+unsigned long df_test_video_flip_status (void);
+int df_save_state (DF_SAVE_RESTORE *gp_state);
+int df_restore_state (DF_SAVE_RESTORE *gp_state);
+
+/*----------------------------------------*/
+/*    DISPLAY FILTER READ ROUTINES        */
+/*----------------------------------------*/
+
+unsigned long df_read_composite_crc (int crc_source);
+unsigned long df_read_composite_window_crc (unsigned long x, unsigned long y,
+	unsigned long width, unsigned long height, int source);
+unsigned long df_read_panel_crc (void);
+int df_get_video_enable (int *enable, unsigned long *flags);
+int df_get_video_source_configuration (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+	DF_VIDEO_SOURCE_PARAMS *video_source_even);
+int df_get_video_position (DF_VIDEO_POSITION *video_window);
+int df_get_video_scale (unsigned long *x_scale, unsigned long *y_scale);
+int df_get_video_filter_coefficients (long taps[][4], int *phase256);
+int df_get_video_color_key (unsigned long *key, unsigned long *mask, int *graphics);
+int df_get_video_palette_entry(unsigned long index, unsigned long *palette);
+int df_get_video_palette (unsigned long *palette);
+int df_get_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key);
+int df_get_video_cursor_color_key_enable (void);
+int df_get_alpha_window_configuration (int window, DF_ALPHA_REGION_PARAMS *alpha_data);
+int df_get_alpha_window_enable (int window);
+int df_get_video_request (unsigned long *x, unsigned long *y);
+int df_get_output_color_space (int *color_space);
+
+/*----------------------------------------*/
+/*        MSR ROUTINE DEFINITIONS         */
+/*----------------------------------------*/
+
+int	msr_init_table (void);
+int msr_create_geodelink_table (GEODELINK_NODE *gliu_nodes);
+int msr_create_device_list (GEODELINK_NODE *gliu_nodes, int max_devices);
+int msr_read64 (unsigned long device, unsigned long msr_register,
+	Q_WORD *msr_value);
+int msr_write64 (unsigned long device, unsigned long msr_register,
+	Q_WORD *msr_value);
+
+/*----------------------------------------*/
+/*        VIP ROUTINE DEFINITIONS         */
+/*----------------------------------------*/
+
+int vip_initialize (VIPSETMODEBUFFER *buffer);
+int vip_update_601_params (VIP_601PARAMS *buffer);
+int vip_terminate (void);
+int vip_configure_capture_buffers (int buffer_type, VIPINPUTBUFFER *buffer);
+int vip_toggle_video_offsets (int buffer_type, VIPINPUTBUFFER *buffer);
+int vip_max_address_enable (unsigned long max_address, int enable);
+int vip_set_interrupt_enable (unsigned long mask, int enable);
+unsigned long vip_get_interrupt_state (void);
+int vip_set_capture_state (unsigned long state);
+int vip_set_vsync_error (unsigned long vertical_count, unsigned long window_before,
+    unsigned long window_after, int enable);
+int vip_configure_fifo (unsigned long fifo_type, unsigned long fifo_size);
+int vip_set_loopback_enable (int bEnable);
+int vip_configure_genlock (VIPGENLOCKBUFFER *buffer);
+int vip_set_genlock_enable (int bEnable);
+int vip_configure_pages (int page_count, unsigned long page_offset);
+int vip_set_interrupt_line (int line);
+int vip_reset (void);
+int vip_set_subwindow_enable (VIPSUBWINDOWBUFFER *buffer);
+int vip_reset_interrupt_state (unsigned long interrupt_mask);
+
+int vip_save_state(VIPSTATEBUFFER *save_buffer);
+int vip_restore_state(VIPSTATEBUFFER *restore_buffer);
+int vip_set_power_characteristics (VIPPOWERBUFFER *buffer);
+int vip_set_priority_characteristics (VIPPRIORITYBUFFER *buffer);
+int vip_set_debug_characteristics (VIPDEBUGBUFFER *buffer);
+int vip_test_genlock_active (void);
+int vip_test_signal_status (void);
+unsigned long vip_get_current_field (void);
+
+/*----------------------------------------*/
+/*        VIP READ ROUTINES               */
+/*----------------------------------------*/
+
+int vip_get_current_mode (VIPSETMODEBUFFER *buffer);
+int vip_get_601_configuration (VIP_601PARAMS *buffer);
+int vip_get_buffer_configuration (int buffer_type, VIPINPUTBUFFER *buffer);
+int vip_get_genlock_configuration (VIPGENLOCKBUFFER *buffer);
+int vip_get_genlock_enable (void);
+int vip_is_buffer_update_latched (void);
+unsigned long vip_get_capture_state (void);
+unsigned long vip_get_current_line (void);
+unsigned long vip_read_fifo (unsigned long fifo_address);
+int vip_write_fifo (unsigned long fifo_address, unsigned long fifo_data);
+int vip_enable_fifo_access (int enable);
+int vip_get_capability_characteristics (VIPCAPABILITIESBUFFER *buffer);
+int vip_get_power_characteristics (VIPPOWERBUFFER *buffer);
+int vip_get_priority_characteristics (VIPPRIORITYBUFFER *buffer);
+
+/*----------------------------------------*/
+/*        VOP ROUTINE DEFINITIONS         */
+/*----------------------------------------*/
+
+int vop_set_vbi_window (VOPVBIWINDOWBUFFER *buffer);
+int vop_enable_vbi_output (int enable);
+int vop_set_configuration (VOPCONFIGURATIONBUFFER *config);
+int vop_save_state(VOPSTATEBUFFER *save_buffer);
+int vop_restore_state(VOPSTATEBUFFER *save_buffer);
+
+/*----------------------------------------*/
+/*        VOP READ ROUTINES               */
+/*----------------------------------------*/
+
+int vop_get_current_mode (VOPCONFIGURATIONBUFFER *config);
+int vop_get_vbi_configuration (VOPVBIWINDOWBUFFER *buffer);
+int vop_get_vbi_enable (void);
+unsigned long vop_get_crc (void);
+unsigned long vop_read_vbi_crc(void);
+
+/* CLOSE BRACKET FOR C++ COMPLILATION */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_version.h xf86-video-nsc-2.8.1/src/cim/cim_version.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_version.h	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_version.h	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,15 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron Version information
+  * </DOC_AMD_STD>
+  *
+  */
+
+#define CIMARRON_REVISION   30103
\ No newline at end of file
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_vg.c xf86-video-nsc-2.8.1/src/cim/cim_vg.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_vg.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_vg.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,3599 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron display controller routines.  These routines program the display
+  * mode and configure the hardware cursor and video buffers.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*---------------------*/
+/* CIMARRON VG GLOBALS */
+/*---------------------*/
+
+CIMARRON_STATIC unsigned long vg3_x_hotspot      = 0;
+CIMARRON_STATIC unsigned long vg3_y_hotspot      = 0;
+CIMARRON_STATIC unsigned long vg3_cursor_offset  = 0;
+CIMARRON_STATIC unsigned long vg3_mode_width     = 0;
+CIMARRON_STATIC unsigned long vg3_mode_height    = 0;
+CIMARRON_STATIC unsigned long vg3_panel_width    = 0;
+CIMARRON_STATIC unsigned long vg3_panel_height   = 0;
+CIMARRON_STATIC unsigned long vg3_delta_x        = 0;
+CIMARRON_STATIC unsigned long vg3_delta_y        = 0;
+CIMARRON_STATIC unsigned long vg3_bpp            = 0;
+
+CIMARRON_STATIC unsigned long vg3_color_cursor   = 0;
+CIMARRON_STATIC unsigned long vg3_panel_enable   = 0;
+
+/*---------------------------------------------------------------------------
+ * vg_delay_milliseconds
+ *
+ * This routine delays for a number of milliseconds based on a crude
+ * delay loop.
+ *---------------------------------------------------------------------------*/
+
+int vg_delay_milliseconds (unsigned long ms)
+{
+	/* ASSUME 500 MHZ 20 CLOCKS PER READ */
+
+	unsigned long loop = ms * 25000;
+	while (loop-- > 0)
+	{
+		READ_REG32 (DC3_UNLOCK);
+	}
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_mode
+ *
+ * This routine sets a CRT display mode using predefined Cimarron timings.  The
+ * source width and height are specified to allow scaling.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_mode (unsigned long src_width, unsigned long src_height,
+	unsigned long dst_width, unsigned long dst_height, int bpp, int hz,
+    unsigned long flags)
+{
+	VG_QUERY_MODE crt_query;
+	VG_DISPLAY_MODE crt_mode;
+	int mode;
+
+	crt_query.active_width  = dst_width;
+	crt_query.active_height = dst_height;
+	crt_query.bpp           = bpp;
+	crt_query.hz            = hz;
+	crt_query.query_flags   = VG_QUERYFLAG_ACTIVEWIDTH  |
+		                      VG_QUERYFLAG_ACTIVEHEIGHT |
+							  VG_QUERYFLAG_BPP          |
+							  VG_QUERYFLAG_REFRESH;
+
+	mode = vg_get_display_mode_index (&crt_query);
+	if (mode >= 0)
+	{
+		crt_mode = CimarronDisplayModes[mode];
+		crt_mode.src_width  = src_width;
+		crt_mode.src_height = src_height;
+
+        /* ADD USER-REQUESTED FLAGS */
+
+        crt_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);
+
+        if (flags & VG_MODEFLAG_OVERRIDE_BAND)
+        {
+            crt_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
+            crt_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
+        }
+        if (flags & VG_MODEFLAG_INT_OVERRIDE)
+        {
+            crt_mode.flags &= ~VG_MODEFLAG_INT_MASK;
+            crt_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
+        }
+
+		return vg_set_custom_mode (&crt_mode, bpp);
+	}
+	return CIM_STATUS_ERROR;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_panel_mode
+ *
+ * This routine sets a panel mode using predefined Cimarron fixed timings.  The
+ * source width and height specify the width and height of the data in the frame
+ * buffer.  The destination width and height specify the width and height of
+ * the active data to be displayed.  The panel width and height specify the
+ * dimensions of the panel.  This interface allows the user to scale or center
+ * graphics data or both.  To perform scaling, the src width or height should
+ * be different than the destination width or height.  To perform centering or
+ * panning, the destination width and height should be different than the panel
+ * resolution.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_panel_mode (unsigned long src_width, unsigned long src_height,
+	unsigned long dst_width,   unsigned long dst_height,
+	unsigned long panel_width, unsigned long panel_height,
+	int bpp, unsigned long flags)
+{
+    unsigned long sync_width;
+    unsigned long sync_offset;
+	VG_QUERY_MODE panel_query;
+	VG_DISPLAY_MODE panel_mode;
+	int mode;
+
+	/* SEARCH CIMARRON'S TABLE OF PREDEFINED PANEL MODES                   */
+	/* If the destination resolution is larger than the panel resolution,  */
+	/* panning will be performed.  However, the timings for a panned mode  */
+	/* are identical to the timings without panning.  To save space in the */
+	/* mode tables, there are no additional table entries for modes with   */
+	/* panning.  Instead, we read the timings for a mode without panning   */
+	/* and override the structure entries that specify the width and       */
+	/* height of the mode.  We perform a similar procedure for centered    */
+    /* modes, except that certain timing parameters are dynamically        */
+    /* calculated.                                                         */
+
+	panel_query.active_width  = panel_width;
+	panel_query.active_height = panel_height;
+	panel_query.panel_width   = panel_width;
+	panel_query.panel_height  = panel_height;
+	panel_query.bpp           = bpp;
+	panel_query.query_flags   = VG_QUERYFLAG_ACTIVEWIDTH  |
+		                        VG_QUERYFLAG_ACTIVEHEIGHT |
+							    VG_QUERYFLAG_PANELWIDTH   |
+							    VG_QUERYFLAG_PANELHEIGHT  |
+								VG_QUERYFLAG_PANEL        |
+							    VG_QUERYFLAG_BPP;
+
+	mode = vg_get_display_mode_index (&panel_query);
+
+	/* COPY THE DATA FROM THE MODE TABLE TO A TEMPORARY STRUCTURE */
+
+	if (mode >= 0)
+	{
+		panel_mode = CimarronDisplayModes[mode];
+		panel_mode.mode_width  = dst_width;
+		panel_mode.mode_height = dst_height;
+		panel_mode.src_width   = src_width;
+		panel_mode.src_height  = src_height;
+
+        /* ADD USER-REQUESTED FLAGS */
+
+        panel_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);
+
+        if (flags & VG_MODEFLAG_OVERRIDE_BAND)
+        {
+            panel_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
+            panel_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
+        }
+        if (flags & VG_MODEFLAG_INT_OVERRIDE)
+        {
+            panel_mode.flags &= ~VG_MODEFLAG_INT_MASK;
+            panel_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
+        }
+
+        /* DYNAMICALLY CALCULATE CENTERED TIMINGS */
+        /* For centered timings the blank start and blank end are set to  */
+        /* half the difference between the mode dimension and the panel   */
+        /* dimension.  The sync pulse preserves the width and offset from */
+        /* blanking whenever possible.                                    */
+
+        if (dst_width < panel_width)
+        {
+            sync_width  = panel_mode.hsyncend   - panel_mode.hsyncstart;
+            sync_offset = panel_mode.hsyncstart - panel_mode.hblankstart;
+
+            panel_mode.hactive     = dst_width;
+            panel_mode.hblankstart = panel_mode.hactive + ((panel_width - dst_width) >> 1);
+            panel_mode.hblankend   = panel_mode.htotal - ((panel_width - dst_width) >> 1);
+            panel_mode.hsyncstart  = panel_mode.hblankstart + sync_offset;
+            panel_mode.hsyncend    = panel_mode.hsyncstart + sync_width;
+
+            panel_mode.flags |= VG_MODEFLAG_CENTERED;
+        }
+        if (dst_height < panel_height)
+        {
+            sync_width  = panel_mode.vsyncend   - panel_mode.vsyncstart;
+            sync_offset = panel_mode.vsyncstart - panel_mode.vblankstart;
+
+            panel_mode.vactive     = dst_height;
+            panel_mode.vblankstart = panel_mode.vactive + ((panel_height - dst_height) >> 1);
+            panel_mode.vblankend   = panel_mode.vtotal - ((panel_height - dst_height) >> 1);
+            panel_mode.vsyncstart  = panel_mode.vblankstart + sync_offset;
+            panel_mode.vsyncend    = panel_mode.vsyncstart + sync_width;
+
+            panel_mode.flags |= VG_MODEFLAG_CENTERED;
+        }
+		return vg_set_custom_mode (&panel_mode, bpp);
+	}
+	return CIM_STATUS_ERROR;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_tv_mode
+ *
+ * This routine sets a TV display mode using predefined Cimarron timings.  The
+ * source width and height are specified to allow scaling.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_tv_mode (unsigned long *src_width, unsigned long *src_height,
+    unsigned long encoder, unsigned long tvres, int bpp, unsigned long flags,
+    unsigned long h_overscan, unsigned long v_overscan)
+{
+    unsigned long sync_width;
+    unsigned long sync_offset;
+	VG_QUERY_MODE tv_query;
+	VG_DISPLAY_MODE tv_mode;
+	int mode;
+
+    if (!src_width || !src_height)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	tv_query.bpp           = bpp;
+    tv_query.encoder       = encoder;
+    tv_query.tvmode        = tvres;
+	tv_query.query_flags   = VG_QUERYFLAG_BPP          |
+                             VG_QUERYFLAG_TVOUT        |
+                             VG_QUERYFLAG_ENCODER      |
+                             VG_QUERYFLAG_TVMODE;
+
+	mode = vg_get_display_mode_index (&tv_query);
+	if (mode >= 0)
+	{
+        /* RETRIEVE THE UNSCALED RESOLUTION */
+        /* As we are indexing here simply by a mode and encoder, the actual      */
+        /* timings may vary.  A 0 value for source or height will thus query the */
+        /* unscaled resolution.                                                  */
+
+        if (!(*src_width) || !(*src_height))
+        {
+            *src_width  = CimarronDisplayModes[mode].hactive - (h_overscan << 1);
+            *src_height = CimarronDisplayModes[mode].vactive;
+
+            if (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INTERLACED)
+            {
+                if (((flags & VG_MODEFLAG_INT_OVERRIDE) &&
+                      (flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_LINEDOUBLE) ||
+                   (!(flags & VG_MODEFLAG_INT_OVERRIDE) &&
+                      (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_LINEDOUBLE))
+                {
+                    if (CimarronDisplayModes[mode].vactive_even > CimarronDisplayModes[mode].vactive)
+                        *src_height = CimarronDisplayModes[mode].vactive_even;
+
+                    /* ONLY 1/2 THE OVERSCAN FOR LINE DOUBLED MODES */
+
+                    *src_height -= v_overscan;
+                }
+                else
+                {
+                    *src_height += CimarronDisplayModes[mode].vactive_even;
+                    *src_height -= v_overscan << 1;
+                }
+            }
+            else
+            {
+                *src_height -= v_overscan << 1;
+            }
+
+            return CIM_STATUS_OK;
+        }
+
+		tv_mode = CimarronDisplayModes[mode];
+		tv_mode.src_width  = *src_width;
+		tv_mode.src_height = *src_height;
+
+        /* ADD USER-REQUESTED FLAGS */
+
+        tv_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);
+
+        if (flags & VG_MODEFLAG_OVERRIDE_BAND)
+        {
+            tv_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
+            tv_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
+        }
+        if (flags & VG_MODEFLAG_INT_OVERRIDE)
+        {
+            tv_mode.flags &= ~VG_MODEFLAG_INT_MASK;
+            tv_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
+        }
+
+        /* ADJUST FOR OVERSCAN */
+
+        if (h_overscan)
+        {
+            sync_width  = tv_mode.hsyncend   - tv_mode.hsyncstart;
+            sync_offset = tv_mode.hsyncstart - tv_mode.hblankstart;
+
+            tv_mode.hactive    -= h_overscan << 1;
+            tv_mode.hblankstart = tv_mode.hactive + h_overscan;
+            tv_mode.hblankend   = tv_mode.htotal  - h_overscan;
+            tv_mode.hsyncstart  = tv_mode.hblankstart + sync_offset;
+            tv_mode.hsyncend    = tv_mode.hsyncstart  + sync_width;
+
+            tv_mode.flags |= VG_MODEFLAG_CENTERED;
+        }
+        if (v_overscan)
+        {
+            sync_width  = tv_mode.vsyncend   - tv_mode.vsyncstart;
+            sync_offset = tv_mode.vsyncstart - tv_mode.vblankstart;
+
+            if (tv_mode.flags & VG_MODEFLAG_INTERLACED)
+            {
+                tv_mode.vactive    -= v_overscan;
+                tv_mode.vblankstart = tv_mode.vactive + (v_overscan >> 1);
+                tv_mode.vblankend   = tv_mode.vtotal  - (v_overscan >> 1);
+                tv_mode.vsyncstart  = tv_mode.vblankstart + sync_offset;
+                tv_mode.vsyncend    = tv_mode.vsyncstart  + sync_width;
+
+                sync_width  = tv_mode.vsyncend_even   - tv_mode.vsyncstart_even;
+                sync_offset = tv_mode.vsyncstart_even - tv_mode.vblankstart_even;
+
+                tv_mode.vactive_even    -= v_overscan;
+                tv_mode.vblankstart_even = tv_mode.vactive_even + (v_overscan >> 1);
+                tv_mode.vblankend_even   = tv_mode.vtotal_even  - (v_overscan >> 1);
+                tv_mode.vsyncstart_even  = tv_mode.vblankstart_even + sync_offset;
+                tv_mode.vsyncend_even    = tv_mode.vsyncstart_even  + sync_width;
+            }
+            else
+            {
+                tv_mode.vactive    -= v_overscan << 1;
+                tv_mode.vblankstart = tv_mode.vactive + v_overscan;
+                tv_mode.vblankend   = tv_mode.vtotal  - v_overscan;
+                tv_mode.vsyncstart  = tv_mode.vblankstart + sync_offset;
+                tv_mode.vsyncend    = tv_mode.vsyncstart  + sync_width;
+            }
+
+            tv_mode.flags |= VG_MODEFLAG_CENTERED;
+        }
+
+        /* TV MODES WILL NEVER ALLOW PANNING */
+
+        tv_mode.panel_width  = tv_mode.hactive;
+        tv_mode.panel_height = tv_mode.vactive;
+        tv_mode.mode_width   = tv_mode.hactive;
+        tv_mode.mode_height  = tv_mode.vactive;
+
+		return vg_set_custom_mode (&tv_mode, bpp);
+	}
+	return CIM_STATUS_ERROR;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_custom_mode
+ *
+ * This routine sets a display mode.  The API is structured such that this routine
+ * can be called from four sources:
+ *   - vg_set_display_mode
+ *   - vg_set_panel_mode
+ *   - vg_set_tv_mode
+ *   - directly by the user for a custom mode.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_custom_mode (VG_DISPLAY_MODE *mode_params, int bpp)
+{
+	unsigned long config, misc, temp;
+    unsigned long irq_ctl, genlk_ctl;
+	unsigned long unlock, flags;
+	unsigned long acfg, gcfg, dcfg;
+	unsigned long size, line_size, pitch;
+	unsigned long bpp_mask, dv_size;
+	unsigned long hscale, vscale, starting_width;
+    unsigned long starting_height, output_height;
+    Q_WORD msr_value;
+
+    /* DETERMINE DIMENSIONS FOR SCALING */
+    /* Scaling is performed before flicker filtering and interlacing */
+
+    output_height = mode_params->vactive;
+
+    if (mode_params->flags & VG_MODEFLAG_INTERLACED)
+    {
+        /* EVEN AND ODD FIELDS ARE SEPARATE */
+        /* The composite image height is the sum of the height of both fields */
+
+        if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER ||
+            (mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS)
+        {
+            output_height += mode_params->vactive_even;
+        }
+
+        /* LINE DOUBLING */
+        /* The composite image height is the greater of the two field heights. */
+
+        else if (mode_params->vactive_even > output_height)
+            output_height = mode_params->vactive_even;
+    }
+
+	/* CHECK FOR VALID SCALING FACTOR */
+	/* GeodeLX supports only 2:1 vertical downscale (before interlacing) and */
+	/* 2:1 horizontal downscale.  The source width when scaling must be      */
+    /* less than or equal to 1024 pixels.  The destination can be any size,  */
+    /* except when flicker filtering is enabled.                             */
+
+    irq_ctl = 0;
+    if (mode_params->flags & VG_MODEFLAG_PANELOUT)
+    {
+        if (mode_params->src_width != mode_params->mode_width)
+	    {
+            starting_width = (mode_params->hactive * mode_params->src_width) / mode_params->mode_width;
+		    hscale = (mode_params->src_width << 14) / (mode_params->mode_width - 1);
+		    irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+	    }
+	    else
+	    {
+            starting_width = mode_params->hactive;
+		    hscale = 0x4000;
+	    }
+	    if (mode_params->src_height != mode_params->mode_height)
+	    {
+            starting_height = (output_height * mode_params->src_height) / mode_params->mode_height;
+		    vscale = (mode_params->src_height << 14) / (mode_params->mode_height - 1);
+		    irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+	    }
+	    else
+	    {
+            starting_height = output_height;
+		    vscale = 0x4000;
+	    }
+    }
+    else
+    {
+        starting_width  = mode_params->src_width;
+        starting_height = mode_params->src_height;
+	    if (mode_params->src_width != mode_params->hactive)
+	    {
+		    hscale = (mode_params->src_width << 14) / (mode_params->hactive - 1);
+		    irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+	    }
+	    else
+	    {
+		    hscale = 0x4000;
+	    }
+	    if (mode_params->src_height != output_height)
+	    {
+		    vscale = (mode_params->src_height << 14) / (output_height - 1);
+		    irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+	    }
+	    else
+	    {
+		    vscale = 0x4000;
+	    }
+    }
+
+    starting_width = (starting_width + 7) & 0xFFFF8;
+
+    if (mode_params->hactive < (starting_width  >> 1) ||
+        output_height < (starting_height >> 1)        ||
+       (irq_ctl && (starting_width > 1024)))
+    {
+        return CIM_STATUS_INVALIDSCALE;
+    }
+
+    /* VERIFY INTERLACED SCALING */
+    /* The output width must be less than or equal to 1024 pixels when the */
+    /* flicker filter is enabled.  Also, scaling should be disabled when   */
+    /* the interlacing mode is set to interlaced addressing.               */
+
+    if (mode_params->flags & VG_MODEFLAG_INTERLACED)
+    {
+        if ((((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER) &&
+               (mode_params->hactive > 1024))                                                 ||
+            (((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS) && irq_ctl))
+        {
+            return CIM_STATUS_INVALIDSCALE;
+        }
+    }
+			
+	/* CHECK FOR VALID BPP */
+	
+	switch (bpp)
+	{
+		case 8:  bpp_mask = DC3_DCFG_DISP_MODE_8BPP;  break;
+	    case 24: bpp_mask = DC3_DCFG_DISP_MODE_24BPP; break;
+		case 32: bpp_mask = DC3_DCFG_DISP_MODE_32BPP; break;
+		case 12: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP; break;
+		case 15: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP; break;
+		case 16: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP; break;
+		default: return CIM_STATUS_INVALIDPARAMS;
+	}
+
+	vg3_bpp = bpp;
+
+	/* CLEAR PANNING OFFSETS */
+
+	vg3_delta_x = 0;
+	vg3_delta_y = 0;
+
+	/* SAVE PANEL PARAMETERS */
+
+	if (mode_params->flags & VG_MODEFLAG_PANELOUT)
+	{
+		vg3_panel_enable = 1;
+		vg3_panel_width  = mode_params->panel_width;
+		vg3_panel_height = mode_params->panel_height;
+		vg3_mode_width   = mode_params->mode_width;
+		vg3_mode_height  = mode_params->mode_height;
+
+        /* INVERT THE SHIFT CLOCK IF REQUESTED */
+        /* Note that we avoid writing the power management register if */
+        /* we can help it.                                             */
+
+        temp = READ_VID32 (DF_POWER_MANAGEMENT);
+        if ((mode_params->flags & VG_MODEFLAG_INVERT_SHFCLK) &&
+           !(temp & DF_PM_INVERT_SHFCLK))
+        {
+            WRITE_VID32 (DF_POWER_MANAGEMENT, (temp | DF_PM_INVERT_SHFCLK));
+        }
+        else if (!(mode_params->flags & VG_MODEFLAG_INVERT_SHFCLK) &&
+                  (temp & DF_PM_INVERT_SHFCLK))
+        {
+            WRITE_VID32 (DF_POWER_MANAGEMENT, (temp & ~DF_PM_INVERT_SHFCLK));
+        }
+
+        /* SET PANEL TIMING VALUES */
+
+        if (!(mode_params->flags & VG_MODEFLAG_NOPANELTIMINGS))
+        {
+            unsigned long pmtim1, pmtim2, dith_ctl;
+
+            if (mode_params->flags & VG_MODEFLAG_XVGA_TFT)
+            {
+                pmtim1   = DF_DEFAULT_XVGA_PMTIM1;
+                pmtim2   = DF_DEFAULT_XVGA_PMTIM2;
+                dith_ctl = DF_DEFAULT_DITHCTL;
+                msr_value.low  = DF_DEFAULT_XVGA_PAD_SEL_LOW;
+                msr_value.high = DF_DEFAULT_XVGA_PAD_SEL_HIGH;
+            }
+            else if (mode_params->flags & VG_MODEFLAG_CUSTOM_PANEL)
+            {
+                pmtim1   = mode_params->panel_tim1;
+                pmtim2   = mode_params->panel_tim2;
+                dith_ctl = mode_params->panel_dither_ctl;
+                msr_value.low  = mode_params->panel_pad_sel_low;
+                msr_value.high = mode_params->panel_pad_sel_high;
+            }
+            else
+            {
+                pmtim1   = DF_DEFAULT_TFT_PMTIM1;
+                pmtim2   = DF_DEFAULT_TFT_PMTIM2;
+                dith_ctl = DF_DEFAULT_DITHCTL;
+                msr_value.low  = DF_DEFAULT_TFT_PAD_SEL_LOW;
+                msr_value.high = DF_DEFAULT_TFT_PAD_SEL_HIGH;
+
+            }
+            WRITE_VID32 (DF_VIDEO_PANEL_TIM1, pmtim1);
+            WRITE_VID32 (DF_VIDEO_PANEL_TIM2, pmtim2);
+            WRITE_VID32 (DF_DITHER_CONTROL, dith_ctl);
+            msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+        }
+
+        /* SET APPROPRIATE PANEL OUTPUT MODE */
+
+        msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+        msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+        msr_value.low |=  DF_OUTPUT_PANEL;
+        if (mode_params->flags & VG_MODEFLAG_CRT_AND_FP)
+            msr_value.low |=  DF_SIMULTANEOUS_CRT_FP;
+        else
+            msr_value.low &= ~DF_SIMULTANEOUS_CRT_FP;
+
+        msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+	}
+    else if (mode_params->flags & VG_MODEFLAG_TVOUT)
+    {
+        vg3_panel_enable = 0;
+
+        /* SET APPROPRIATE TV OUTPUT MODE */
+
+        msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+        msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+        msr_value.low |=  DF_OUTPUT_PANEL;
+        if (mode_params->flags & VG_MODEFLAG_CRT_AND_FP)
+            msr_value.low |=  DF_SIMULTANEOUS_CRT_FP;
+        else
+            msr_value.low &= ~DF_SIMULTANEOUS_CRT_FP;
+
+        msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+        /* CONFIGURE PADS FOR VOP OUTPUT */
+        /* Note that the VOP clock is currently always inverted. */
+
+        msr_value.low  = DF_DEFAULT_TV_PAD_SEL_LOW;
+        msr_value.high = DF_DEFAULT_TV_PAD_SEL_HIGH;
+        msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+    }
+	else
+    {
+		vg3_panel_enable = 0;
+
+        /* SET OUTPUT TO CRT ONLY */
+
+        msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+        msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+        msr_value.low |=  DF_OUTPUT_CRT;
+        msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+    }
+
+	/* SET UNLOCK VALUE */
+
+	unlock = READ_REG32 (DC3_UNLOCK);
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+    /*-------------------------------------------------------------------*/
+    /* MAKE THE SYSTEM "SAFE"                                            */
+    /* Before setting a mode, we first ensure that the system is in a    */
+    /* benign quiescent state.  This involves disabling compression and  */
+    /* all interrupt sources.  It also involves terminating all accesses */
+    /* to memory, including video, FIFO load, VIP and the GP.            */
+    /*-------------------------------------------------------------------*/
+
+    /* DISABLE VGA */
+    /* VGA *MUST* be turned off before TGEN is enabled.  If not, a condition */
+    /* will result where VGA Enable is waiting for a VSync to be latched but */
+    /* a VSync will not be generated until VGA is disabled.                  */
+	
+    temp = READ_REG32 (DC3_GENERAL_CFG) & ~DC3_GCFG_VGAE;
+	
+    /* DISABLE VIDEO (INCLUDING ALPHA WINDOWS) */
+
+	WRITE_VID32 (DF_ALPHA_CONTROL_1, 0);
+	WRITE_VID32 (DF_ALPHA_CONTROL_1 + 32, 0);
+	WRITE_VID32 (DF_ALPHA_CONTROL_1 + 64, 0);
+	
+	WRITE_REG32 (DC3_GENERAL_CFG, (temp & ~DC3_GCFG_VIDE));
+	temp = READ_VID32 (DF_VIDEO_CONFIG);
+	WRITE_VID32 (DF_VIDEO_CONFIG, (temp & ~DF_VCFG_VID_EN));
+
+    /* DISABLE VG INTERRUPTS */
+
+    WRITE_REG32 (DC3_IRQ, DC3_IRQ_MASK | DC3_VSYNC_IRQ_MASK |
+        DC3_IRQ_STATUS | DC3_VSYNC_IRQ_STATUS);
+
+    /* DISABLE GENLOCK */
+
+    genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
+    WRITE_REG32 (DC3_GENLK_CTL, (genlk_ctl & ~DC3_GC_GENLOCK_ENABLE));
+
+    /* DISABLE VIP CAPTURE AND VIP INTERRUPTS */
+
+    WRITE_VIP32 (VIP_CONTROL1, 0);
+    WRITE_VIP32 (VIP_CONTROL2, 0);
+    WRITE_VIP32 (VIP_INTERRUPT, VIP_ALL_INTERRUPTS | (VIP_ALL_INTERRUPTS >> 16));
+
+    /* DISABLE COLOR KEYING */
+    /* The color key mechanism should be disabled whenever a mode switch occurs. */
+
+    temp = READ_REG32 (DC3_COLOR_KEY);
+    WRITE_REG32 (DC3_COLOR_KEY, (temp & ~DC3_CLR_KEY_ENABLE));
+	
+    /* BLANK THE DISPLAY */
+    /* Note that we never blank the panel.  Most flat panels have very long      */
+    /* latency requirements when setting their power low.  Some panels require   */
+    /* upwards of 500ms before VDD goes high again.  Needless to say, we are not */
+    /* planning to take over one half a second inside this routine.              */
+
+	misc   = READ_VID32 (DF_VID_MISC);
+	config = READ_VID32 (DF_DISPLAY_CONFIG);
+	
+	WRITE_VID32 (DF_VID_MISC, (misc | DF_DAC_POWER_DOWN));
+	WRITE_VID32 (DF_DISPLAY_CONFIG, (config & ~(DF_DCFG_DIS_EN   | DF_DCFG_HSYNC_EN |
+		DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN)));
+
+	/* DISABLE COMPRESSION  */
+
+	gcfg = READ_REG32 (DC3_GENERAL_CFG);
+	gcfg &= ~(DC3_GCFG_CMPE | DC3_GCFG_DECE);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+	/* DISABLE THE TIMING GENERATOR */
+
+	dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+    dcfg &= ~DC3_DCFG_TGEN;
+    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+	
+	/* WAIT FOR PENDING MEMORY REQUESTS */
+	
+	vg_delay_milliseconds(1);
+
+    /* DISABLE DISPLAY FIFO LOAD */
+
+    gcfg &= ~DC3_GCFG_DFLE;
+    WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	gcfg = 0;
+	dcfg = 0;
+
+    /* WAIT FOR THE GP TO BE IDLE (JUST IN CASE) */
+
+    while (((temp = READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_BUSY) ||
+           !(temp & GP3_BS_CB_EMPTY))
+    {
+        ;
+    }
+
+	/* SET THE DOT CLOCK FREQUENCY */
+
+    if (!(mode_params->flags & VG_MODEFLAG_EXCLUDEPLL))
+    {
+	    if (mode_params->flags & VG_MODEFLAG_HALFCLOCK)
+		    flags = VG_PLL_DIVIDE_BY_2;
+	    else if (mode_params->flags & VG_MODEFLAG_QVGA)
+		    flags = VG_PLL_DIVIDE_BY_4;
+	    else
+		    flags = 0;
+
+        /* ALLOW DOTREF TO BE USED AS THE PLL            */
+        /* This is useful for some external TV encoders. */
+
+        if (mode_params->flags & VG_MODEFLAG_PLL_BYPASS)
+            flags |= VG_PLL_BYPASS;
+
+        /* ALLOW THE USER TO MANUALLY ENTER THE MSR VALUE */
+
+        if (mode_params->flags & VG_MODEFLAG_MANUAL_FREQUENCY)
+            flags |= VG_PLL_MANUAL;
+        if (mode_params->flags & VG_MODEFLAG_VIP_TO_DOT_CLOCK)
+            flags |= VG_PLL_VIP_CLOCK;
+
+	    vg_set_clock_frequency (mode_params->frequency, flags);
+    }
+	
+	/* CLEAR ALL BUFFER OFFSETS */
+
+	WRITE_REG32 (DC3_FB_ST_OFFSET,   0);
+	WRITE_REG32 (DC3_CB_ST_OFFSET,   0);
+	WRITE_REG32 (DC3_CURS_ST_OFFSET, 0);
+
+    genlk_ctl = READ_REG32 (DC3_GENLK_CTL) & ~(DC3_GC_ALPHA_FLICK_ENABLE |
+        DC3_GC_FLICKER_FILTER_ENABLE | DC3_GC_FLICKER_FILTER_MASK);
+
+	/* ENABLE INTERLACING */
+
+    if (mode_params->flags & VG_MODEFLAG_INTERLACED)
+    {
+        irq_ctl |= DC3_IRQFILT_INTL_EN;
+
+        if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS)
+            irq_ctl |= DC3_IRQFILT_INTL_ADDR;
+        else if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER)
+        {
+            genlk_ctl |= DC3_GC_FLICKER_FILTER_1_8 | DC3_GC_FLICKER_FILTER_ENABLE |
+                DC3_GC_ALPHA_FLICK_ENABLE;
+        }
+    }
+	
+	WRITE_REG32 (DC3_GFX_SCALE, (vscale << 16) | (hscale & 0xFFFF));
+	WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_ctl);
+    WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
+
+	/* SET LINE SIZE AND PITCH */
+	/* The line size and pitch are calculated from the src_width parameter    */
+	/* passed in to this routine.  All other parameters are ignored.          */
+	/* The pitch is set either to a power of 2 to allow efficient             */
+	/* compression or to a linear value to allow efficient memory management. */
+	
+    switch (bpp)
+    {
+        case 8:
+            size = mode_params->src_width;
+            line_size = starting_width;
+            break;
+
+        case 12:
+        case 15:
+        case 16:
+
+            size = mode_params->src_width << 1;
+            line_size = starting_width << 1;
+            break;
+
+        case 24:
+        case 32:
+        default:
+
+            size = mode_params->src_width << 2;
+            line_size = starting_width << 2; break;
+    }
+		
+	/* CALCULATE DV RAM SETTINGS AND POWER OF 2 PITCH */
+
+	pitch = 1024;
+	dv_size = DC3_DV_LINE_SIZE_1024;
+	
+	if (size > 1024) { pitch = 2048; dv_size = DC3_DV_LINE_SIZE_2048; }
+	if (size > 2048) { pitch = 4096; dv_size = DC3_DV_LINE_SIZE_4096; }
+	if (size > 4096) { pitch = 8192; dv_size = DC3_DV_LINE_SIZE_8192; }
+	
+	/* OVERRIDE SETTINGS FOR LINEAR PITCH */
+
+	if (mode_params->flags & VG_MODEFLAG_LINEARPITCH)
+	{
+        unsigned long max;
+        if (pitch != size)
+        {
+            /* CALCULATE MAXIMUM ADDRESS (1K ALIGNED) */
+
+            max = size * output_height;
+            max = (max + 0x3FF) & 0xFFFFFC00;
+            WRITE_REG32 (DC3_DV_TOP, max | DC3_DVTOP_ENABLE);
+
+		    gcfg  |= DC3_GCFG_FDTY;
+		    pitch  = size;
+        }
+        else
+        {
+            WRITE_REG32 (DC3_DV_TOP, 0);
+        }
+	}
+
+	/* WRITE PITCH AND DV RAM SETTINGS */
+	/* The DV RAM line length is programmed at a power of 2 boundary */
+	/* in case the user wants to toggle back to a power of 2 pitch   */
+	/* later.  It could happen...                                    */
+
+	temp = READ_REG32 (DC3_DV_CTL);
+	WRITE_REG32 (DC3_GFX_PITCH, pitch >> 3);
+	WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dv_size);
+
+	/* SET THE LINE SIZE */
+
+	WRITE_REG32 (DC3_LINE_SIZE, (line_size + 7) >> 3);
+
+	/* ALWAYS ENABLE VIDEO AND GRAPHICS DATA            */
+	/* These bits are relics from a previous design and */
+	/* should always be enabled.                        */
+
+	dcfg |= (DC3_DCFG_VDEN | DC3_DCFG_GDEN);
+	
+	/* SET PIXEL FORMAT */	
+
+	dcfg |= bpp_mask;
+
+	/* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
+	/* AND VERT. INT. SELECT                                      */
+
+    dcfg |= (unsigned long)(DC3_DCFG_TGEN | DC3_DCFG_TRUP | DC3_DCFG_PALB | DC3_DCFG_VISL);
+
+    /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */
+    /* Note that the bandwidth setting gets upgraded when scaling or flicker */
+    /* filtering are enabled, as they require more data throughput.          */
+
+    msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+    msr_value.low &= ~(DC3_SPARE_DISABLE_CFIFO_HGO    | DC3_SPARE_VFIFO_ARB_SELECT |
+                       DC3_SPARE_LOAD_WM_LPEN_MASK    | DC3_SPARE_WM_LPEN_OVRD     |
+                       DC3_SPARE_DISABLE_INIT_VID_PRI | DC3_SPARE_DISABLE_VFIFO_WM);
+
+    if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_HIGH_BAND  ||
+       ((mode_params->flags & VG_MODEFLAG_INTERLACED) &&
+           (mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER) ||
+        (irq_ctl & DC3_IRQFILT_GFX_FILT_EN))
+    {
+        /* HIGH BANDWIDTH */
+        /* Set agressive watermarks and disallow forced low priority */
+
+        gcfg |= 0x0000BA01;
+        dcfg |= 0x000EA000;
+        acfg  = 0x001A0201;
+
+        msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
+                         DC3_SPARE_WM_LPEN_OVRD;
+    }
+    else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_AVG_BAND)
+    {
+        /* AVERAGE BANDWIDTH */
+        /* Set average watermarks and allow small regions of forced low priority. */
+
+        gcfg |= 0x0000B601;
+        dcfg |= 0x00009000;
+        acfg  = 0x00160001;
+
+        msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
+                         DC3_SPARE_WM_LPEN_OVRD;
+
+        /* SET THE NUMBER OF LOW PRIORITY LINES TO 1/2 THE TOTAL AVAILABLE */
+
+        temp  = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
+        temp -=  (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
+	    temp >>= 1;
+        if (temp > 127)
+            temp = 127;
+
+        acfg |= temp << 9;
+    }
+    else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_LOW_BAND)
+    {
+        /* LOW BANDWIDTH */
+        /* Set low watermarks and allow larger regions of forced low priority. */
+
+        gcfg |= 0x00009501;
+        dcfg |= 0x00008000;
+        acfg  = 0x00150001;
+
+        msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
+                         DC3_SPARE_WM_LPEN_OVRD;
+
+        /* SET THE NUMBER OF LOW PRIORITY LINES TO 3/4 THE TOTAL AVAILABLE */
+
+        temp  = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
+        temp -=  (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
+	    temp  = (temp * 3) >> 2;
+        if (temp > 127)
+            temp = 127;
+
+        acfg |= temp << 9;
+    }
+    else
+    {
+        /* LEGACY CHARACTERISTICS */
+        /* Arbitration from a single set of watermarks. */
+
+        gcfg |= 0x0000B601;
+        msr_value.low |= DC3_SPARE_DISABLE_VFIFO_WM | DC3_SPARE_DISABLE_INIT_VID_PRI;
+        acfg = 0;
+    }
+
+    msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+
+	/* ENABLE FLAT PANEL CENTERING                          */
+	/* For panel modes having a resolution smaller than the */
+	/* panel resolution, turn on data centering.            */
+
+	if (mode_params->flags & VG_MODEFLAG_CENTERED)
+	    dcfg |= DC3_DCFG_DCEN;
+
+	/* COMBINE AND SET TIMING VALUES */
+
+	temp = (mode_params->hactive - 1) | ((mode_params->htotal - 1) << 16);
+	WRITE_REG32(DC3_H_ACTIVE_TIMING, temp);
+	temp = (mode_params->hblankstart - 1) | ((mode_params->hblankend - 1) << 16);
+	WRITE_REG32(DC3_H_BLANK_TIMING, temp);
+	temp = (mode_params->hsyncstart - 1) | ((mode_params->hsyncend - 1) << 16);
+	WRITE_REG32(DC3_H_SYNC_TIMING, temp);
+	temp = (mode_params->vactive - 1) | ((mode_params->vtotal - 1) << 16);
+	WRITE_REG32(DC3_V_ACTIVE_TIMING, temp);
+	temp =	(mode_params->vblankstart - 1) | ((mode_params->vblankend - 1) << 16);
+	WRITE_REG32(DC3_V_BLANK_TIMING, temp);
+	temp = (mode_params->vsyncstart - 1) | ((mode_params->vsyncend - 1) << 16);
+	WRITE_REG32(DC3_V_SYNC_TIMING, temp);
+    temp = (mode_params->vactive_even - 1) | ((mode_params->vtotal_even - 1) << 16);
+	WRITE_REG32(DC3_V_ACTIVE_EVEN, temp);
+	temp =	(mode_params->vblankstart_even - 1) | ((mode_params->vblankend_even - 1) << 16);
+	WRITE_REG32(DC3_V_BLANK_EVEN, temp);
+	temp = (mode_params->vsyncstart_even - 1) | ((mode_params->vsyncend_even - 1) << 16);
+	WRITE_REG32(DC3_V_SYNC_EVEN, temp);
+	
+    /* SET THE VIDEO REQUEST REGISTER */
+
+    WRITE_VID32 (DF_VIDEO_REQUEST, 0);
+
+	/* SET SOURCE DIMENSIONS */
+
+	WRITE_REG32 (DC3_FB_ACTIVE, ((starting_width - 1) << 16) |
+		(starting_height - 1));
+
+	/* SET SYNC POLARITIES */
+
+	temp = READ_VID32 (DF_DISPLAY_CONFIG);
+
+	temp &= ~(DF_DCFG_CRT_SYNC_SKW_MASK | DF_DCFG_PWR_SEQ_DLY_MASK |
+		      DF_DCFG_CRT_HSYNC_POL     | DF_DCFG_CRT_VSYNC_POL);
+
+    temp |= (DF_DCFG_CRT_SYNC_SKW_INIT |
+			 DF_DCFG_PWR_SEQ_DLY_INIT  |
+             DF_DCFG_GV_PAL_BYP);
+
+	if (mode_params->flags & VG_MODEFLAG_NEG_HSYNC)
+		temp |= DF_DCFG_CRT_HSYNC_POL;
+	if (mode_params->flags & VG_MODEFLAG_NEG_VSYNC)
+		temp |= DF_DCFG_CRT_VSYNC_POL;
+
+	WRITE_VID32 (DF_DISPLAY_CONFIG, temp);
+
+    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+    WRITE_REG32 (DC3_ARB_CFG, acfg);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+	/* RESTORE VALUE OF DC3_UNLOCK */
+
+	WRITE_REG32(DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_bpp
+ *
+ * This routine changes the display BPP on the fly.  It is intended only to 
+ * switch between pixel depths of the same pixel size 24<->32 or 15<->16, NOT
+ * between pixel depths of differing sizes 16<->32
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_bpp (int bpp)
+{
+    unsigned long unlock, dcfg, bpp_mask;
+
+    switch (bpp)
+	{
+		case 8:  bpp_mask = DC3_DCFG_DISP_MODE_8BPP;  break;
+	    case 24: bpp_mask = DC3_DCFG_DISP_MODE_24BPP; break;
+		case 32: bpp_mask = DC3_DCFG_DISP_MODE_32BPP; break;
+		case 12: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP; break;
+		case 15: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP; break;
+		case 16: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP; break;
+		default: return CIM_STATUS_INVALIDPARAMS;
+	}
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~(DC3_DCFG_DISP_MODE_MASK | DC3_DCFG_16BPP_MODE_MASK);
+    dcfg |= bpp_mask;
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_mode_index
+ *
+ * This routine searches the Cimarron mode table for a mode that matches the
+ * input parameters.  If a match is found, the return value is the index into
+ * the mode table.  If no match is found, the return value is -1.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_display_mode_index (VG_QUERY_MODE *query)
+{
+	unsigned int mode;
+	unsigned long hz_flag  = 0xFFFFFFFF;
+	unsigned long bpp_flag = 0xFFFFFFFF;
+    unsigned long enc_flag = 0xFFFFFFFF;
+    unsigned long tv_flag  = 0;
+    unsigned long interlaced = 0;
+    unsigned long halfclock  = 0;
+    long minimum = 0x7FFFFFFF;
+    long diff;
+    int match = -1;
+
+	if (!query || !query->query_flags)
+		return -1;
+
+	if (query->query_flags & VG_QUERYFLAG_REFRESH)
+	{
+		/* SET FLAGS TO MATCH REFRESH RATE */
+
+		if      (query->hz == 56)  hz_flag = VG_SUPPORTFLAG_56HZ;
+		else if (query->hz == 60)  hz_flag = VG_SUPPORTFLAG_60HZ;
+		else if (query->hz == 70)  hz_flag = VG_SUPPORTFLAG_70HZ;
+		else if (query->hz == 72)  hz_flag = VG_SUPPORTFLAG_72HZ;
+		else if (query->hz == 75)  hz_flag = VG_SUPPORTFLAG_75HZ;
+		else if (query->hz == 85)  hz_flag = VG_SUPPORTFLAG_85HZ;
+        else if (query->hz == 90)  hz_flag = VG_SUPPORTFLAG_90HZ;
+        else if (query->hz == 100) hz_flag = VG_SUPPORTFLAG_100HZ;
+		else                       hz_flag = 0;
+	}
+	
+	if (query->query_flags & VG_QUERYFLAG_BPP)
+	{
+		/* SET BPP FLAGS TO LIMIT MODE SELECTION */
+
+		if      (query->bpp == 8)  bpp_flag = VG_SUPPORTFLAG_8BPP;
+		else if (query->bpp == 12) bpp_flag = VG_SUPPORTFLAG_12BPP;
+		else if (query->bpp == 15) bpp_flag = VG_SUPPORTFLAG_15BPP;
+		else if (query->bpp == 16) bpp_flag = VG_SUPPORTFLAG_16BPP;
+		else if (query->bpp == 24) bpp_flag = VG_SUPPORTFLAG_24BPP;
+		else if (query->bpp == 32) bpp_flag = VG_SUPPORTFLAG_32BPP;
+		else                       bpp_flag = 0;
+	}
+
+    if (query->query_flags & VG_QUERYFLAG_ENCODER)
+    {
+        /* SET ENCODER FLAGS TO LIMIT MODE SELECTION */
+
+        if      (query->encoder == VG_ENCODER_ADV7171) enc_flag = VG_SUPPORTFLAG_ADV7171;
+        else if (query->encoder == VG_ENCODER_SAA7127) enc_flag = VG_SUPPORTFLAG_SAA7127;
+        else if (query->encoder == VG_ENCODER_FS454)   enc_flag = VG_SUPPORTFLAG_FS454;
+        else if (query->encoder == VG_ENCODER_ADV7300) enc_flag = VG_SUPPORTFLAG_ADV7300;
+        else                                           enc_flag = 0;
+    }
+
+    if (query->query_flags & VG_QUERYFLAG_TVMODE)
+    {
+        /* SET ENCODER FLAGS TO LIMIT MODE SELECTION */
+
+        if      (query->tvmode == VG_TVMODE_NTSC)      tv_flag = VG_SUPPORTFLAG_NTSC;
+        else if (query->tvmode == VG_TVMODE_PAL)       tv_flag = VG_SUPPORTFLAG_PAL;
+        else if (query->tvmode == VG_TVMODE_480P)      tv_flag = VG_SUPPORTFLAG_480P;
+        else if (query->tvmode == VG_TVMODE_720P)      tv_flag = VG_SUPPORTFLAG_720P;
+        else if (query->tvmode == VG_TVMODE_1080I)     tv_flag = VG_SUPPORTFLAG_1080I;
+        else if (query->tvmode == VG_TVMODE_6X4_NTSC)  tv_flag = VG_SUPPORTFLAG_6X4_NTSC;
+        else if (query->tvmode == VG_TVMODE_8X6_NTSC)  tv_flag = VG_SUPPORTFLAG_8X6_NTSC;
+        else if (query->tvmode == VG_TVMODE_10X7_NTSC) tv_flag = VG_SUPPORTFLAG_10X7_NTSC;
+        else if (query->tvmode == VG_TVMODE_6X4_PAL)   tv_flag = VG_SUPPORTFLAG_6X4_PAL;
+        else if (query->tvmode == VG_TVMODE_8X6_PAL)   tv_flag = VG_SUPPORTFLAG_8X6_PAL;
+        else if (query->tvmode == VG_TVMODE_10X7_PAL)  tv_flag = VG_SUPPORTFLAG_10X7_PAL;
+        else                                           tv_flag = 0xFFFFFFFF;
+    }
+
+    /* SET APPROPRIATE TV AND VOP FLAGS */
+
+    if (query->query_flags & VG_QUERYFLAG_INTERLACED)
+        interlaced = query->interlaced ? VG_MODEFLAG_INTERLACED : 0;
+    if (query->query_flags & VG_QUERYFLAG_HALFCLOCK)
+        halfclock = query->halfclock  ? VG_MODEFLAG_HALFCLOCK  : 0;
+
+	/* CHECK FOR INVALID REQUEST */
+
+	if (!hz_flag || !bpp_flag || !enc_flag || tv_flag == 0xFFFFFFFF)
+		return -1;
+
+	/* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+
+	for (mode = 0; mode < NUM_CIMARRON_DISPLAY_MODES; mode++)
+	{
+		if ( (!(query->query_flags & VG_QUERYFLAG_PANEL)        ||
+			   (CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_PANEL))          &&
+			 (!(query->query_flags & VG_QUERYFLAG_TVOUT)        ||
+			   (CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_TVOUT))          &&
+			 (!(query->query_flags & VG_QUERYFLAG_INTERLACED)   ||
+			   (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INTERLACED) == interlaced)   &&
+             (!(query->query_flags & VG_QUERYFLAG_HALFCLOCK)    ||
+			   (CimarronDisplayModes[mode].flags & VG_MODEFLAG_HALFCLOCK) == halfclock)     &&
+			 (!(query->query_flags & VG_QUERYFLAG_PANELWIDTH)   ||
+			   (CimarronDisplayModes[mode].panel_width == query->panel_width))              &&
+			 (!(query->query_flags & VG_QUERYFLAG_PANELHEIGHT)  ||
+			   (CimarronDisplayModes[mode].panel_height == query->panel_height))            &&
+			 (!(query->query_flags & VG_QUERYFLAG_ACTIVEWIDTH)  ||
+			   (CimarronDisplayModes[mode].hactive == query->active_width))                 &&
+			 (!(query->query_flags & VG_QUERYFLAG_ACTIVEHEIGHT) ||
+			   (CimarronDisplayModes[mode].vactive == query->active_height))                &&
+			 (!(query->query_flags & VG_QUERYFLAG_TOTALWIDTH)   ||
+			   (CimarronDisplayModes[mode].htotal == query->total_width))                   &&
+			 (!(query->query_flags & VG_QUERYFLAG_TOTALHEIGHT)  ||
+			   (CimarronDisplayModes[mode].vtotal == query->total_height))                  &&
+			 (!(query->query_flags & VG_QUERYFLAG_BPP)          ||
+			   (CimarronDisplayModes[mode].internal_flags & bpp_flag))                      &&
+			 (!(query->query_flags & VG_QUERYFLAG_REFRESH)      ||
+			   (CimarronDisplayModes[mode].internal_flags & hz_flag))                       &&
+             (!(query->query_flags & VG_QUERYFLAG_ENCODER)      ||
+			   (CimarronDisplayModes[mode].internal_flags & enc_flag))                      &&
+             (!(query->query_flags & VG_QUERYFLAG_TVMODE)       ||
+			  ((CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_TVMODEMASK) == tv_flag)) &&
+			 (!(query->query_flags & VG_QUERYFLAG_PIXELCLOCK)   ||
+			   (CimarronDisplayModes[mode].frequency == query->frequency)))
+		{
+            /* ALLOW SEARCHING BASED ON AN APPROXIMATE PIXEL CLOCK */
+
+            if (query->query_flags & VG_QUERYFLAG_PIXELCLOCK_APPROX)
+            {
+                diff = query->frequency - CimarronDisplayModes[mode].frequency;
+                if (diff < 0)
+                    diff = -diff;
+
+                if (diff < minimum)
+                {
+                    minimum = diff;
+                    match = mode;
+                }
+            }
+            else
+            {
+                match = mode;
+                break;
+            }
+		}
+	}
+
+    /* RETURN DISPLAY MODE INDEX */
+
+	return match;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_mode_information
+ *
+ * This routine retrieves all information for a display mode contained
+ * within Cimarron's mode tables.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_display_mode_information (unsigned int index, VG_DISPLAY_MODE *vg_mode)
+{
+	if (index > NUM_CIMARRON_DISPLAY_MODES)
+		return CIM_STATUS_INVALIDPARAMS;
+
+	*vg_mode = CimarronDisplayModes[index];
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_mode_count
+ *
+ * This routine retrieves the count of all predefined Cimarron modes.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_display_mode_count (void)
+{
+	return NUM_CIMARRON_DISPLAY_MODES;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_current_display_mode
+ *
+ * This routine retrieves the settings for the current display.  This includes
+ * any panel settings.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_current_display_mode (VG_DISPLAY_MODE *current_display, int *bpp)
+{
+	Q_WORD msr_value;
+	unsigned long active, blank, sync;
+	unsigned long i, m, n, p;
+	unsigned long genlk, irq, temp;
+	unsigned long flags  = 0;
+    unsigned long iflags = 0;
+
+	/* READ THE CURRENT HORIZONTAL DISPLAY TIMINGS */
+
+	active = READ_REG32 (DC3_H_ACTIVE_TIMING);
+	blank  = READ_REG32 (DC3_H_BLANK_TIMING);
+	sync   = READ_REG32 (DC3_H_SYNC_TIMING);
+
+	current_display->hactive     = (active & 0xFFF) + 1;
+	current_display->hblankstart = (blank  & 0xFFF) + 1;
+	current_display->hsyncstart  = (sync   & 0xFFF) + 1;
+	
+	current_display->htotal    = ((active >> 16) & 0xFFF) + 1;
+	current_display->hblankend = ((blank  >> 16) & 0xFFF) + 1;
+	current_display->hsyncend  = ((sync   >> 16) & 0xFFF) + 1;
+
+	/* READ THE CURRENT VERTICAL DISPLAY TIMINGS */
+
+	active = READ_REG32 (DC3_V_ACTIVE_TIMING);
+	blank  = READ_REG32 (DC3_V_BLANK_TIMING);
+	sync   = READ_REG32 (DC3_V_SYNC_TIMING);
+
+	current_display->vactive     = (active & 0x7FF) + 1;
+	current_display->vblankstart = (blank  & 0x7FF) + 1;
+	current_display->vsyncstart  = (sync   & 0x7FF) + 1;
+	
+	current_display->vtotal    = ((active >> 16) & 0x7FF) + 1;
+	current_display->vblankend = ((blank  >> 16) & 0x7FF) + 1;
+	current_display->vsyncend  = ((sync   >> 16) & 0x7FF) + 1;
+
+    /* READ THE CURRENT EVEN FIELD VERTICAL DISPLAY TIMINGS */
+
+	active = READ_REG32 (DC3_V_ACTIVE_EVEN);
+	blank  = READ_REG32 (DC3_V_BLANK_EVEN);
+	sync   = READ_REG32 (DC3_V_SYNC_EVEN);
+
+	current_display->vactive_even     = (active & 0x7FF) + 1;
+	current_display->vblankstart_even = (blank  & 0x7FF) + 1;
+	current_display->vsyncstart_even  = (sync   & 0x7FF) + 1;
+	
+	current_display->vtotal_even    = ((active >> 16) & 0x7FF) + 1;
+	current_display->vblankend_even = ((blank  >> 16) & 0x7FF) + 1;
+	current_display->vsyncend_even  = ((sync   >> 16) & 0x7FF) + 1;
+
+	/* READ THE CURRENT SOURCE DIMENSIONS                      */
+	/* The DC3_FB_ACTIVE register is only used when scaling is enabled.   */
+	/* As the goal of this routine is to return a structure that can be   */
+	/* passed to vg_set_custom_mode to exactly recreate the current mode, */
+	/* we must check the status of the scaler/filter.                     */
+
+    genlk = READ_REG32 (DC3_GENLK_CTL);
+	irq   = READ_REG32 (DC3_IRQ_FILT_CTL);
+	temp  = READ_REG32 (DC3_FB_ACTIVE);
+	
+	current_display->src_height = (temp & 0xFFFF) + 1;
+    current_display->src_width = ((temp >> 16) & 0xFFF8) + 8;
+	
+	/* READ THE CURRENT PANEL CONFIGURATION */
+	/* We can only infer some of the panel settings based on hardware */
+	/* (like when panning).  We will instead assume that the current  */
+	/* mode was set using Cimarron and use the panel variables inside */
+	/* Cimarron when returning the current mode information.          */
+
+	if (vg3_panel_enable)
+	{
+        Q_WORD msr_value;
+
+		flags |= VG_MODEFLAG_PANELOUT;
+
+		current_display->panel_width  = vg3_panel_width;
+		current_display->panel_height = vg3_panel_height;
+		current_display->mode_width   = vg3_mode_width;
+		current_display->mode_height  = vg3_mode_height;
+
+		if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+			flags |= VG_MODEFLAG_CENTERED;
+
+        msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+        current_display->panel_tim1         = READ_VID32 (DF_VIDEO_PANEL_TIM1);
+        current_display->panel_tim2         = READ_VID32 (DF_VIDEO_PANEL_TIM2);
+        current_display->panel_dither_ctl   = READ_VID32 (DF_DITHER_CONTROL);
+        current_display->panel_pad_sel_low  = msr_value.low;
+        current_display->panel_pad_sel_high = msr_value.high;
+	}
+	
+	/* SET MISCELLANEOUS MODE FLAGS */
+	
+	/* INTERLACED */
+
+	if (irq & DC3_IRQFILT_INTL_EN)
+    {
+        flags |= VG_MODEFLAG_INTERLACED;
+        if (irq & DC3_IRQFILT_INTL_ADDR)
+            flags |= VG_MODEFLAG_INT_ADDRESS;
+        else if (genlk & DC3_GC_FLICKER_FILTER_ENABLE)
+            flags |= VG_MODEFLAG_INT_FLICKER;
+        else
+            flags |= VG_MODEFLAG_INT_LINEDOUBLE;
+    }
+	
+	/* POLARITIES */
+
+	temp = READ_VID32 (DF_DISPLAY_CONFIG);
+	if (temp & DF_DCFG_CRT_HSYNC_POL)
+		flags |= VG_MODEFLAG_NEG_HSYNC;
+	if (temp & DF_DCFG_CRT_VSYNC_POL)
+		flags |= VG_MODEFLAG_NEG_VSYNC;
+
+	/* BPP */
+
+	temp = READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DISP_MODE_MASK;
+	if (temp == DC3_DCFG_DISP_MODE_8BPP)
+    {
+		iflags |= VG_SUPPORTFLAG_8BPP;
+        *bpp = 8;
+    }
+	else if (temp == DC3_DCFG_DISP_MODE_24BPP)
+    {
+        iflags |= VG_SUPPORTFLAG_24BPP;
+        *bpp = 24;
+    }
+	else if (temp == DC3_DCFG_DISP_MODE_32BPP)
+    {
+        iflags |= VG_SUPPORTFLAG_32BPP;
+        *bpp = 32;
+    }
+	else if (temp == DC3_DCFG_DISP_MODE_16BPP)
+	{
+		temp = READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_16BPP_MODE_MASK;
+		if (temp == DC3_DCFG_16BPP)
+        {
+            iflags |= VG_SUPPORTFLAG_16BPP;
+            *bpp = 16;
+        }
+		else if (temp == DC3_DCFG_15BPP)
+        {
+            iflags |= VG_SUPPORTFLAG_15BPP;
+            *bpp = 15;
+        }
+		else if (temp == DC3_DCFG_12BPP)
+        {
+            iflags |= VG_SUPPORTFLAG_12BPP;
+            *bpp = 12;
+        }
+	}
+
+    /* TV RELATED FLAGS */
+
+    msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+    if (msr_value.high & DF_INVERT_VOP_CLOCK)
+        flags |= VG_MODEFLAG_TVOUT;
+
+    /* LINEAR PITCH */
+
+    temp = (READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3;
+    if (temp != 1024 && temp != 2048 && temp != 4096 && temp != 8192)
+        flags |= VG_MODEFLAG_LINEARPITCH;
+
+    /* SIMULTANEOUS CRT/FP */
+
+    msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+    if (msr_value.low & DF_SIMULTANEOUS_CRT_FP)
+        flags |= VG_MODEFLAG_CRT_AND_FP;
+
+    /* SET PLL-RELATED FLAGS */
+
+    msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+    if (msr_value.high & GLCP_DOTPLL_DIV4)
+        flags |= VG_MODEFLAG_QVGA;
+    if (msr_value.low & GLCP_DOTPLL_HALFPIX)
+        flags |= VG_MODEFLAG_HALFCLOCK;
+
+    /* SAVE THE FLAGS IN THE MODE STRUCTURE */
+
+    current_display->internal_flags = iflags;
+    current_display->flags = flags;
+
+	/* READ PIXEL CLOCK FREQUENCY */
+	/* We first search for an exact match.  If none is found, we try */
+	/* a fixed point calculation and return CIM_STATUS_INEXACTMATCH. */
+	
+	for (i = 0; i < NUM_CIMARRON_PLL_FREQUENCIES; i++)
+	{
+		if (CimarronPLLFrequencies[i].pll_value == msr_value.high)
+			break;
+	}
+
+	if (i == NUM_CIMARRON_PLL_FREQUENCIES)
+	{
+		/* ATTEMPT 16.16 CALCULATION */
+		/* We assume the input frequency is 48 MHz, which is represented   */
+		/* in 16.16 fixed point as 0x300000. The PLL calculation is:       */
+		/*                             n + 1                               */
+		/*   Fout =  48.000   *    --------------                          */
+		/*                         m + 1   *  p + 1                        */
+
+        p =  msr_value.high & 0xF;
+	    n = (msr_value.high >> 4)  & 0xFF;
+	    m = (msr_value.high >> 12) & 0x7;
+		current_display->frequency = (0x300000 * (n + 1)) / ((p + 1) * (m + 1));
+
+		return CIM_STATUS_INEXACTMATCH;
+	}
+
+	current_display->frequency = CimarronPLLFrequencies[i].frequency;
+
+	/* NOW SEARCH FOR AN IDENTICAL MODE */
+	/* This is just to inform the user that an exact match was found.   */
+	/* With an exact match, the user can use the refresh rate flag that */
+	/* is returned in the VG_DISPLAY_MODE structure.                    */
+
+	for (i = 0; i < NUM_CIMARRON_DISPLAY_MODES; i++)
+	{
+		if ((CimarronDisplayModes[i].flags & current_display->flags)             &&
+			 CimarronDisplayModes[i].frequency   == current_display->frequency   &&
+			 CimarronDisplayModes[i].hactive     == current_display->hactive     &&
+			 CimarronDisplayModes[i].hblankstart == current_display->hblankstart &&
+			 CimarronDisplayModes[i].hsyncstart  == current_display->hsyncstart  &&
+			 CimarronDisplayModes[i].hsyncend    == current_display->hsyncend    &&
+			 CimarronDisplayModes[i].hblankend   == current_display->hblankend   &&			
+			 CimarronDisplayModes[i].htotal      == current_display->htotal      &&
+			 CimarronDisplayModes[i].vactive     == current_display->vactive     &&
+			 CimarronDisplayModes[i].vblankstart == current_display->vblankstart &&
+			 CimarronDisplayModes[i].vsyncstart  == current_display->vsyncstart  &&
+			 CimarronDisplayModes[i].vsyncend    == current_display->vsyncend    &&
+			 CimarronDisplayModes[i].vblankend   == current_display->vblankend   &&			
+			 CimarronDisplayModes[i].vtotal      == current_display->vtotal)
+		{
+			break;
+		}
+	}
+
+	if (i == NUM_CIMARRON_DISPLAY_MODES)
+		return CIM_STATUS_INEXACTMATCH;
+
+	current_display->internal_flags |= (CimarronDisplayModes[i].internal_flags & VG_SUPPORTFLAG_HZMASK);
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_scaler_filter_coefficients
+ *
+ * This routine sets the vertical and horizontal filter coefficients for
+ * graphics scaling.  If either of the input arrays is specified as NULL, a
+ * set of default coeffecients will be used.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3])
+{
+	unsigned long irqfilt, i;
+	unsigned long temp0, temp1;
+    unsigned long lock;
+	
+	/* ENABLE ACCESS TO THE HORIZONTAL COEFFICIENTS */
+
+	irqfilt  = READ_REG32 (DC3_IRQ_FILT_CTL);
+	irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+	
+    /* UNLOCK THE COEFFICIENT REGISTERS */
+
+    lock = READ_REG32 (DC3_UNLOCK);
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	/* WRITE COEFFICIENTS */
+	/* Coefficient indexes do not auto-increment, so we must */
+	/* write the address for every phase                     */
+
+	for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+        if (!h_taps)
+        {
+            temp0 = CimarronHorizontalGraphicsFilter[i][0];
+            temp1 = CimarronHorizontalGraphicsFilter[i][1];
+        }
+        else
+        {
+		    temp0 =  ((unsigned long)h_taps[i][0] & 0x3FF)        |
+                    (((unsigned long)h_taps[i][1] & 0x3FF) << 10) |
+                    (((unsigned long)h_taps[i][2] & 0x3FF) << 20);
+
+		    temp1  = ((unsigned long)h_taps[i][3] & 0x3FF)        |
+			        (((unsigned long)h_taps[i][4] & 0x3FF) << 10);
+        }
+        WRITE_REG32 (DC3_FILT_COEFF1, temp0);
+        WRITE_REG32 (DC3_FILT_COEFF2, temp1);
+	}
+
+	/* ENABLE ACCESS TO THE VERTICAL COEFFICIENTS */
+
+	irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+	/* WRITE COEFFICIENTS */
+
+	for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+        if (!v_taps)
+        {
+            temp0 = CimarronVerticalGraphicsFilter[i];
+        }
+        else
+        {
+		    temp0 =  ((unsigned long)v_taps[i][0] & 0x3FF)        |
+                    (((unsigned long)v_taps[i][1] & 0x3FF) << 10) |
+                    (((unsigned long)v_taps[i][2] & 0x3FF) << 20);
+        }
+
+		WRITE_REG32 (DC3_FILT_COEFF1, temp0);
+	}
+
+    WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_configure_flicker_filter
+ *
+ * This routine updates the VG flicker filter settings when in an interlaced
+ * mode.  Note that flicker filtering is enabled inside a mode set.  This routine
+ * is provided to change from the default flicker filter setting of
+ * 1/4, 1/2, 1/4.
+ *---------------------------------------------------------------------------*/
+
+int vg_configure_flicker_filter (unsigned long flicker_strength, int flicker_alpha)
+{
+    unsigned long unlock;
+    unsigned long genlk_ctl;
+
+    /* CHECK FOR VALID FLICKER SETTING */
+
+    if (flicker_strength != VG_FLICKER_FILTER_NONE &&
+        flicker_strength != VG_FLICKER_FILTER_1_16 &&
+        flicker_strength != VG_FLICKER_FILTER_1_8  &&
+        flicker_strength != VG_FLICKER_FILTER_1_4  &&
+        flicker_strength != VG_FLICKER_FILTER_5_16)
+    {
+        return CIM_STATUS_INVALIDPARAMS;
+    }
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    genlk_ctl  = READ_REG32 (DC3_GENLK_CTL) & ~(DC3_GC_FLICKER_FILTER_MASK | DC3_GC_ALPHA_FLICK_ENABLE);
+    genlk_ctl |= flicker_strength;
+    if (flicker_alpha)
+        genlk_ctl |= DC3_GC_ALPHA_FLICK_ENABLE;
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_clock_frequency
+ *
+ * This routine sets the frequency of the dot clock.  The input to this routine
+ * is a 16.16 fraction.  If an exact match is not found, this routine will program
+ * the closest available frequency and return CIM_STATUS_INEXACTMATCH.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_clock_frequency (unsigned long frequency, unsigned long pll_flags)
+{
+	Q_WORD msr_value;
+	unsigned long timeout;
+	unsigned long index = 0;
+	unsigned long unlock, i;
+    unsigned long pll_high, pll_low;
+	long diff, min = 0;
+
+	/* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY         */
+	/* Search the table for the closest frequency (16.16 format). */
+    /* This search is skipped if the user is manually specifying  */
+    /* the MSR value.                                             */
+
+    pll_low  = 0;
+    if (!(pll_flags & VG_PLL_MANUAL))
+    {
+	    min = (long)CimarronPLLFrequencies[0].frequency - (long)frequency;
+	    if (min < 0L)
+		    min = -min;
+
+	    for (i = 1; i < NUM_CIMARRON_PLL_FREQUENCIES; i++)
+	    {
+		    diff = (long)CimarronPLLFrequencies[i].frequency - (long)frequency;
+		    if (diff < 0L)
+			    diff = -diff;
+
+		    if (diff < min)
+		    {
+			    min = diff;
+			    index = i;
+		    }
+	    }
+
+        pll_high = CimarronPLLFrequencies[index].pll_value & 0x00007FFF;
+    }
+    else
+    {
+        pll_high = frequency;
+    }
+
+    if (pll_flags & VG_PLL_DIVIDE_BY_2)
+		pll_low |= GLCP_DOTPLL_HALFPIX;
+	if (pll_flags & VG_PLL_DIVIDE_BY_4)
+		pll_high |= GLCP_DOTPLL_DIV4;
+    if (pll_flags & VG_PLL_BYPASS)
+        pll_low |= GLCP_DOTPLL_BYPASS;
+    if (pll_flags & VG_PLL_VIP_CLOCK)
+        pll_high |= GLCP_DOTPLL_VIPCLK;
+
+	/* VERIFY THAT WE ARE NOT WRITING WHAT IS ALREADY IN THE REGISTERS */
+    /* The Dot PLL reset bit is tied to VDD for flat panels.  This can */
+    /* cause a brief drop in flat panel power, which can cause serious */
+    /* glitches on some panels.                                        */
+
+	msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+    if ((msr_value.low & GLCP_DOTPLL_LOCK) &&
+       ((msr_value.low & (GLCP_DOTPLL_HALFPIX | GLCP_DOTPLL_BYPASS)) == pll_low) &&
+        (msr_value.high == pll_high))
+    {
+        return CIM_STATUS_OK;
+    }
+
+    /* PROGRAM THE SETTINGS WITH THE RESET BIT SET */
+	/* Clear the bypass bit to ensure that the programmed */
+	/* M, N and P values are being used.                  */
+
+    msr_value.high = pll_high;
+	msr_value.low &= ~(GLCP_DOTPLL_BYPASS | GLCP_DOTPLL_HALFPIX);
+    msr_value.low |=  (pll_low | 0x00000001);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+    /* WAIT FOR THE LOCK BIT */
+    /* The PLL spec states that the PLL may take up to 100 us to */
+    /* properly lock.  Furthermore, the lock signal is not 100%  */
+    /* reliable.  To address this, we add a hefty delay followed */
+    /* by a polling loop that times out after a 1000 reads.      */
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    for (timeout = 0; timeout < 1280; timeout++)
+        WRITE_REG32 (DC3_UNLOCK, unlock);
+
+    for (timeout = 0; timeout < 1000; timeout++)
+    {
+        msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+        if (msr_value.low & GLCP_DOTPLL_LOCK)
+            break;
+    }
+
+    /* CLEAR THE RESET BIT */
+
+	msr_value.low &= 0xFFFFFFFE;
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+	/* DID THE PLL SUCCESSFULLY LOCK? */
+
+	if (!(msr_value.low & GLCP_DOTPLL_LOCK))
+		return CIM_STATUS_NOLOCK;
+
+	/* RETURN THE APPROPRIATE CODE */
+
+	if (min == 0)
+		return CIM_STATUS_OK;
+	else
+		return CIM_STATUS_INEXACTMATCH;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_border_color
+ *
+ * This routine sets the color used as the border in centered panel modes.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_border_color (unsigned long border_color)
+{
+    unsigned long lock = READ_REG32 (DC3_UNLOCK);
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_PAL_ADDRESS, 0x104);
+	WRITE_REG32 (DC3_PAL_DATA, border_color);
+    WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_cursor_enable
+ *
+ * This routine enables or disables the hardware cursor.  This routine should
+ * only be called after the hardware cursor has been completely configured.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_cursor_enable(int enable)
+{
+    unsigned long unlock, gcfg;
+	
+	/* SET OR CLEAR CURSOR ENABLE BIT */
+
+	unlock = READ_REG32(DC3_UNLOCK);
+	gcfg   = READ_REG32(DC3_GENERAL_CFG);
+	if (enable) gcfg |=   DC3_GCFG_CURE;
+	else        gcfg &= ~(DC3_GCFG_CURE);	
+
+	/* WRITE NEW REGISTER VALUE */
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_mono_cursor_colors
+ *
+ * This routine sets the colors of the hardware monochrome cursor.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_mono_cursor_colors (unsigned long bkcolor, unsigned long fgcolor)
+{
+    unsigned long lock = READ_REG32 (DC3_UNLOCK);
+
+	/* SET CURSOR COLORS */
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_PAL_ADDRESS, 0x100);
+	WRITE_REG32 (DC3_PAL_DATA, bkcolor);
+	WRITE_REG32 (DC3_PAL_DATA, fgcolor);
+    WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_cursor_position
+ *
+ * This routine sets the position of the hardware cursor.  The cursor hotspots
+ * and memory offset must have been specified in an earlier call to
+ * a vg_set_cursor_shape_XX routine.  The coordinates passed to this routine
+ * generally specify the focal point of the cursor, NOT the upper left coordinate of
+ * the cursor pattern.  However, for operating systems that do not include a hotspot
+ * the input parameters may be negative.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_cursor_position (long xpos, long ypos, VG_PANNING_COORDINATES *panning)
+{
+	unsigned long unlock, memoffset;
+    unsigned long gcfg;
+	long x, xoffset;
+	long y, yoffset;
+
+	memoffset = vg3_cursor_offset;
+	x = xpos - (long) vg3_x_hotspot;
+	y = ypos - (long) vg3_y_hotspot;
+	
+	/* HANDLE NEGATIVE COORDINATES                                      */
+	/* This routine supports operating systems that use negative        */
+	/* coordinates, instead of positive coordinates with an appropriate */
+	/* hotspot.                                                         */
+
+	if (xpos < 0) xpos = 0;
+	if (ypos < 0) ypos = 0;
+
+	if (x < -63) return CIM_STATUS_INVALIDPARAMS;
+	if (y < -63) return CIM_STATUS_INVALIDPARAMS;
+	
+	if (vg3_panel_enable)
+	{
+		if ((vg3_mode_width > vg3_panel_width) || (vg3_mode_height > vg3_panel_height))
+		{
+			vg_pan_desktop (xpos, ypos, panning);
+			x = x - (unsigned short)vg3_delta_x;
+			y = y - (unsigned short)vg3_delta_y;
+		}
+        else
+        {
+            panning->start_x = 0;
+            panning->start_y = 0;
+            panning->start_updated = 0;
+        }
+	}
+
+	/* ADJUST OFFSETS */
+	/* Cursor movement and panning work as follows:  The cursor position   */
+	/* refers to where the hotspot of the cursor is located.  However, for */
+	/* non-zero hotspots, the cursor buffer actually begins before the     */
+	/* specified position.                                                 */
+
+	if (x < 0) { xoffset = -x; x = 0; }
+	else       { xoffset = 0;         }
+	if (y < 0) { yoffset = -y; y = 0; }
+	else       { yoffset = 0;         }
+
+	if (vg3_color_cursor) memoffset += (unsigned long) yoffset * 192;
+	else                  memoffset += (unsigned long) yoffset << 4;
+
+    /* SET COLOR CURSOR BIT */
+
+    gcfg = READ_REG32(DC3_GENERAL_CFG);
+	if (vg3_color_cursor)
+		gcfg |= DC3_GCFG_CLR_CUR;
+	else
+		gcfg &= ~DC3_GCFG_CLR_CUR;
+
+	/* SET CURSOR POSITION */
+
+	unlock = READ_REG32(DC3_UNLOCK);
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_CURS_ST_OFFSET, memoffset);
+    WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_CURSOR_X, (unsigned long) x |
+		(((unsigned long) xoffset) << 11));
+	WRITE_REG32 (DC3_CURSOR_Y, (unsigned long) y |
+		(((unsigned long) yoffset) << 11));
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_mono_cursor_shape32
+ *
+ * This routine loads 32x32 cursor data into the cursor buffer in graphics memory.
+ * The outside of the GeodeLX cursor buffer is padded with transparency.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_mono_cursor_shape32 (unsigned long memoffset, unsigned long *andmask,
+	unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot)
+{
+	int i;
+
+	/* SAVE THE CURSOR OFFSET AND HOTSPOTS                               */
+	/* These are reused later when updating the cursor position, panning */
+	/* and clipping the cursor pointer.                                  */
+
+	vg3_x_hotspot     = x_hotspot;
+	vg3_y_hotspot     = y_hotspot;
+	vg3_cursor_offset = memoffset;
+	vg3_color_cursor  = 0;
+
+	for (i = 0; i < 32; i++)
+	{
+		/* EVEN QWORDS CONTAIN THE AND MASK */
+
+		WRITE_FB32 (memoffset, 0xFFFFFFFF);
+		WRITE_FB32 (memoffset + 4, andmask[i]);
+
+		/* ODD QWORDS CONTAIN THE XOR MASK  */
+
+		WRITE_FB32 (memoffset + 8, 0x00000000);
+		WRITE_FB32 (memoffset + 12, xormask[i]);
+
+		memoffset += 16;
+	}
+
+	/* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
+
+	for (i = 0; i < 32; i++)
+	{
+		WRITE_FB32 (memoffset,      0xFFFFFFFF);
+		WRITE_FB32 (memoffset + 4,  0xFFFFFFFF);
+		WRITE_FB32 (memoffset + 8,  0x00000000);
+		WRITE_FB32 (memoffset + 12, 0x00000000);
+
+		memoffset += 16;
+	}
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_mono_cursor_shape64
+ *
+ * This routine loads 64x64 cursor data into the cursor buffer in graphics memory.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_mono_cursor_shape64 (unsigned long memoffset, unsigned long *andmask,
+	unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot)
+{	
+	int i;
+
+	/* SAVE THE CURSOR OFFSET AND HOTSPOTS                               */
+	/* These are reused later when updating the cursor position, panning */
+	/* and clipping the cursor pointer.                                  */
+
+	vg3_x_hotspot     = x_hotspot;
+	vg3_y_hotspot     = y_hotspot;
+	vg3_cursor_offset = memoffset;
+	vg3_color_cursor  = 0;
+
+	for (i = 0; i < 128; i += 2)
+	{
+		/* EVEN QWORDS CONTAIN THE AND MASK */
+		/* We invert the dwords to prevent the calling            */
+		/* application from having to think in terms of Qwords.   */
+		/* The hardware data order is actually 63:0, or 31:0 of   */
+		/* the second dword followed by 31:0 of the first dword.  */
+		
+		WRITE_FB32 (memoffset, andmask[i + 1]);
+		WRITE_FB32 (memoffset + 4, andmask[i]);
+
+		/* ODD QWORDS CONTAIN THE XOR MASK  */
+
+		WRITE_FB32 (memoffset + 8, xormask[i + 1]);
+		WRITE_FB32 (memoffset + 12, xormask[i]);
+
+		memoffset += 16;
+	}
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_color_cursor_shape
+ *
+ * This routine loads 8:8:8:8 cursor data into the color cursor buffer.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_color_cursor_shape (unsigned long memoffset, unsigned char *data,
+	unsigned long width, unsigned long height, long pitch,
+	unsigned long x_hotspot, unsigned long y_hotspot)
+{
+	unsigned long y;
+
+	/* SAVE THE CURSOR OFFSET AND HOTSPOTS                               */
+	/* These are reused later when updating the cursor position, panning */
+	/* and clipping the cursor pointer.                                  */
+
+	vg3_x_hotspot     = x_hotspot;
+	vg3_y_hotspot     = y_hotspot;
+	vg3_cursor_offset = memoffset;
+	vg3_color_cursor  = 1;
+
+	/* WRITE THE CURSOR DATA */
+	/* The outside edges of the color cursor are filled with transparency */
+	/* The cursor buffer dimensions are 48x64.                            */
+
+	for (y = 0; y < height; y++)
+	{
+		/* WRITE THE ACTIVE AND TRANSPARENT DATA */
+		/* We implement this as a macro in our dedication to squeaking */
+		/* every ounce of performance out of our code...               */
+
+		WRITE_FB_STRING32 (memoffset, data, width);
+		WRITE_FB_CONSTANT ((memoffset + (width << 2)), 0, (48 - width));
+
+		/* INCREMENT PAST THE LINE */
+		
+		memoffset += 192;
+		data += pitch;
+	}
+
+	/* WRITE THE EXTRA TRANSPARENT LINES */
+	/* Write the lines in one big bulk setting. */
+
+	WRITE_FB_CONSTANT (memoffset, 0, ((64 - height) * 48));
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_pan_desktop
+ *
+ * This routine sets the correct display offset based on the current cursor
+ * position.
+ *---------------------------------------------------------------------------*/
+
+int vg_pan_desktop (unsigned long x, unsigned long y, VG_PANNING_COORDINATES *panning)
+{
+	unsigned long modeShiftPerPixel;
+    unsigned long modeBytesPerScanline;
+    unsigned long startAddress;
+
+	/* TEST FOR NO-WORK */
+
+	if (x >= vg3_delta_x && x < (vg3_panel_width  + vg3_delta_x) &&
+		y >= vg3_delta_y && y < (vg3_panel_height + vg3_delta_y))
+    {
+        panning->start_x = vg3_delta_x;
+        panning->start_y = vg3_delta_y;
+        panning->start_updated = 0;
+		return CIM_STATUS_OK;
+    }
+
+    if (vg3_bpp == 24) modeShiftPerPixel = 2;
+    else               modeShiftPerPixel = (vg3_bpp + 7) >> 4;
+
+	modeBytesPerScanline = (READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3;
+
+	/* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY       */
+	/* Test the boundary conditions for each coordinate and update */
+	/* all variables and the starting offset accordingly.          */
+	
+	if (x < vg3_delta_x)
+		vg3_delta_x = x;
+
+	else if (x >= (vg3_delta_x + vg3_panel_width))
+		vg3_delta_x = x - vg3_panel_width + 1;
+
+	if (y < vg3_delta_y)
+		vg3_delta_y = y;
+
+	else if (y >= (vg3_delta_y + vg3_panel_height))
+		vg3_delta_y = y - vg3_panel_height + 1;
+
+	/* CALCULATE THE START OFFSET */
+
+	startAddress = (vg3_delta_x << modeShiftPerPixel) + (vg3_delta_y * modeBytesPerScanline);
+	
+	vg_set_display_offset (startAddress);
+
+    panning->start_updated = 1;
+    panning->start_x = vg3_delta_x;
+    panning->start_y = vg3_delta_y;
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_offset
+ *
+ * This routine sets the start address of the frame buffer.  It is
+ * typically used to pan across a virtual desktop (frame buffer larger than
+ * the displayed screen) or to flip the display between multiple buffers.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_offset (unsigned long address)
+{
+	unsigned long lock, gcfg;
+
+	lock = READ_REG32 (DC3_UNLOCK);
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	/* DISABLE COMPRESSION */
+	/* When setting a non-zero display offset, we must disable display  */
+	/* compression.  We could maintain a variable and re-enable         */
+	/* compression when the offset returns to zero.  However, that      */
+	/* creates additional complexity for applications that perform      */
+	/* graphics animation.  Re-enabling compression each time would     */
+	/* be tedious and slow for such applications, implying that they    */
+	/* would have to disable compression before starting the animation. */
+	/* We will instead disable compression and force the user to        */
+	/* re-enable compression when they are ready.                       */
+
+	if (address != 0)
+	{
+		if (READ_REG32 (DC3_GENERAL_CFG) & DC3_GCFG_CMPE)
+		{
+			gcfg = READ_REG32 (DC3_GENERAL_CFG);
+			WRITE_REG32 (DC3_GENERAL_CFG, (gcfg & ~(DC3_GCFG_CMPE | DC3_GCFG_DECE)));
+		}
+	}
+
+	WRITE_REG32 (DC3_FB_ST_OFFSET, address);
+	WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_pitch
+ *
+ * This routine sets the stride between successive lines of data in the frame
+ * buffer.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_pitch (unsigned long pitch)
+{
+	unsigned long temp, dvsize, dvtop, value;
+	unsigned long lock = READ_REG32(DC3_UNLOCK);
+	
+	value = READ_REG32(DC3_GFX_PITCH) & 0xFFFF0000;
+	value |= (pitch >> 3);
+
+	/* PROGRAM THE DISPLAY PITCH */
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_GFX_PITCH, value);
+
+	/* SET THE COMPRESSION BEHAVIOR BASED ON THE PITCH              */
+	/* Strides that are not a power of two will not work with line  */
+	/* by line compression.  For these cases, we enable full-screen */
+	/* compression.  In this mode, any write to the frame buffer    */
+	/* region marks the entire frame as dirty.   Also, the DV line  */
+    /* size must be updated when the pitch is programmed outside of */
+    /* the power of 2 range specified in a mode set.                */
+
+    if      (pitch > 4096) { dvsize = DC3_DV_LINE_SIZE_8192; }
+	else if (pitch > 2048) { dvsize = DC3_DV_LINE_SIZE_4096; }
+    else if (pitch > 1024) { dvsize = DC3_DV_LINE_SIZE_2048; }
+    else                   { dvsize = DC3_DV_LINE_SIZE_1024; }
+	
+    temp = READ_REG32 (DC3_DV_CTL);
+    WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dvsize | 0x00000001);
+
+	value = READ_REG32 (DC3_GENERAL_CFG);
+
+	if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
+    {
+		value &= ~DC3_GCFG_FDTY;
+        dvtop  = 0;
+    }
+    else
+    {
+		value |=  DC3_GCFG_FDTY;
+
+        dvtop  = (READ_REG32 (DC3_FB_ACTIVE) & 0xFFF) + 1;
+        dvtop  = ((dvtop * pitch) + 0x3FF) & 0xFFFFFC00;
+        dvtop |= DC3_DVTOP_ENABLE;
+    }
+
+	WRITE_REG32 (DC3_GENERAL_CFG, value);
+    WRITE_REG32 (DC3_DV_TOP, dvtop);
+	WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_palette_entry
+ *
+ * This routine sets a single 8BPP palette entry in the display controller.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_palette_entry (unsigned long index, unsigned long palette)
+{
+    unsigned long dcfg, unlock;
+
+	if (index > 0xFF)
+		return CIM_STATUS_INVALIDPARAMS;
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    dcfg   = READ_REG32 (DC3_DISPLAY_CFG);
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg & ~DC3_DCFG_PALB);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	WRITE_REG32 (DC3_PAL_ADDRESS, index);
+	WRITE_REG32 (DC3_PAL_DATA, palette);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_palette
+ *
+ * This routine sets the entire palette in the display controller.
+ * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_palette (unsigned long *palette)
+{
+	unsigned long unlock, dcfg, i;
+	WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+	
+	if (palette)
+	{
+        unlock = READ_REG32 (DC3_UNLOCK);
+        dcfg   = READ_REG32 (DC3_DISPLAY_CFG);
+
+        WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+        WRITE_REG32 (DC3_DISPLAY_CFG, dcfg & ~DC3_DCFG_PALB);
+        WRITE_REG32 (DC3_UNLOCK, unlock);
+
+		for (i = 0; i < 256; i++)
+		    WRITE_REG32 (DC3_PAL_DATA, palette[i]);
+		
+		return CIM_STATUS_OK;
+	}
+	return CIM_STATUS_INVALIDPARAMS;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_compression_enable
+ *
+ * This routine enables or disables display compression.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_compression_enable (int enable)
+{
+    Q_WORD msr_value;
+	unsigned long unlock, gcfg;
+	unsigned long temp;
+
+	unlock = READ_REG32 (DC3_UNLOCK);
+	gcfg   = READ_REG32 (DC3_GENERAL_CFG);
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	if (enable)
+	{
+		/* DO NOT ENABLE IF THE DISPLAY OFFSET IS NOT ZERO */
+		
+		if (READ_REG32 (DC3_FB_ST_OFFSET) & 0x0FFFFFFF)
+			return CIM_STATUS_ERROR;
+
+        /* ENABLE BIT 1 IN THE VG SPARE MSR */
+        /* The bus can hang when the VG attempts to merge compression writes. */
+        /* No performance is lost due to the GeodeLink QUACK features in      */
+        /* GeodeLX.  We also enable the command word check for a valid        */
+        /* compression header.                                                */
+
+        msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+        msr_value.low |=  DC3_SPARE_FIRST_REQ_MASK;
+        msr_value.low &= ~DC3_SPARE_DISABLE_CWD_CHECK;
+        msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+
+		/* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
+		/* We don't want the controller to think that old lines are still     */
+		/* valid.  Writing a 1 to bit 0 of the DV Control register will force */
+		/* the hardware to clear all the valid bits.                          */
+
+		temp = READ_REG32 (DC3_DV_CTL);
+		WRITE_REG32 (DC3_DV_CTL, temp | 0x00000001);
+
+		/* ENABLE COMPRESSION BITS */
+
+		gcfg |= DC3_GCFG_CMPE | DC3_GCFG_DECE;
+	}
+	else
+	{
+		gcfg &= ~(DC3_GCFG_CMPE | DC3_GCFG_DECE);
+	}
+
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_configure_compression
+ *
+ * This routine configures all aspects of display compression, including pitch,
+ * size and the offset of the compression buffer.
+ *---------------------------------------------------------------------------*/
+
+int vg_configure_compression (VG_COMPRESSION_DATA *comp_data)
+{
+	unsigned long delta, size;
+	unsigned long comp_size, unlock;
+
+	/* CHECK FOR VALID PARAMETERS */
+	/* The maximum size for the compression buffer is 544 bytes (with    */
+	/* the header)  Also, the pitch cannot be less than the line size    */
+	/* and the compression buffer offset must be 16-byte aligned.        */
+
+	if (comp_data->size > 544 || comp_data->pitch < comp_data->size ||
+		comp_data->compression_offset & 0x0F)
+	{
+		return CIM_STATUS_INVALIDPARAMS;
+	}
+
+	/* SUBTRACT 32 FROM SIZE                                           */
+	/* The display controller will actually write 4 extra QWords.  So, */
+	/* if we assume that "size" refers to the allocated size, we must  */
+	/* subtract 32 bytes.                                              */
+
+    comp_size = comp_data->size - 32;
+
+	/* CALCULATE REGISTER VALUES */
+
+	unlock = READ_REG32 (DC3_UNLOCK);
+	size   = READ_REG32 (DC3_LINE_SIZE) & ~DC3_LINE_SIZE_CBLS_MASK;
+	delta  = READ_REG32 (DC3_GFX_PITCH) & ~DC3_GFX_PITCH_CBP_MASK;
+
+	size  |= ((comp_size  >> 3) + 1) << DC3_LINE_SIZE_CB_SHIFT;
+	delta |= ((comp_data->pitch >> 3) << 16);
+
+	/* WRITE COMPRESSION PARAMETERS */
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_CB_ST_OFFSET, comp_data->compression_offset);
+	WRITE_REG32 (DC3_LINE_SIZE, size);
+	WRITE_REG32 (DC3_GFX_PITCH, delta);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_timing_active
+ *
+ * This routine checks the status of the display timing generator.
+ *---------------------------------------------------------------------------*/
+
+int vg_test_timing_active (void)
+{
+	if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)
+		return 1;
+	
+	return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_vertical_active
+ *
+ * This routine checks if the display is currently in the middle of a frame
+ * (not in the VBlank interval)
+ *---------------------------------------------------------------------------*/
+
+int vg_test_vertical_active (void)
+{
+	if (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA)
+		return 0;
+
+	return 1;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_wait_vertical_blank
+ *
+ * This routine waits until the beginning of the vertical blank interval.
+ * When the display is already in vertical blank, this routine will wait until
+ * the beginning of the next vertical blank.
+ *---------------------------------------------------------------------------*/
+
+int vg_wait_vertical_blank(void)
+{
+	if (vg_test_timing_active())
+	{
+		while (!vg_test_vertical_active());
+		while (vg_test_vertical_active());
+	}
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_even_field
+ *
+ * This routine tests the odd/even status of the current VG output field.
+ *---------------------------------------------------------------------------*/
+
+int vg_test_even_field(void)
+{
+	if (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_EVEN_FIELD)
+        return 1;
+
+    return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_configure_line_interrupt
+ *
+ * This routine configures the display controller's line count interrupt.  This
+ * interrupt can be used to interrupt mid-frame or to interrupt at the beginning
+ * of vertical blank.
+ *---------------------------------------------------------------------------*/
+
+int vg_configure_line_interrupt (VG_INTERRUPT_PARAMS *interrupt_info)
+{
+	unsigned long irq_line, irq_enable;
+    unsigned long lock;
+	
+	irq_line   = READ_REG32 (DC3_IRQ_FILT_CTL);
+	irq_enable = READ_REG32 (DC3_IRQ);
+    lock       = READ_REG32 (DC3_UNLOCK);
+	
+	irq_line = (irq_line & ~DC3_IRQFILT_LINE_MASK) | ((interrupt_info->line << 16) & DC3_IRQFILT_LINE_MASK);
+
+	/* ENABLE OR DISABLE THE INTERRUPT */
+	/* The line count is set before enabling and after disabling to  */
+	/* minimize spurious interrupts.  The line count is set even     */
+	/* when interrupts are disabled to allow polling-based or debug  */
+	/* applications.                                                 */
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	if (interrupt_info->enable)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_line);
+		WRITE_REG32 (DC3_IRQ, ((irq_enable & ~DC3_IRQ_MASK) | DC3_IRQ_STATUS));
+	}
+	else
+	{
+		WRITE_REG32 (DC3_IRQ, (irq_enable | DC3_IRQ_MASK));
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_line);
+	}
+    WRITE_REG32 (DC3_UNLOCK, lock);
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_and_clear_interrupt
+ *
+ * This routine resets any pending interrupt in the video generator.  The return
+ * value indicates the interrupt status prior to the reset.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_test_and_clear_interrupt (void)
+{
+	unsigned long irq_enable;
+    unsigned long lock;
+	
+	irq_enable = READ_REG32 (DC3_IRQ);
+    lock       = READ_REG32 (DC3_UNLOCK);
+
+    /* NO ACTION IF INTERRUPTS ARE MASKED */
+    /* We are assuming that a driver or application will not want to receive */
+    /* the status of the interrupt when it is masked.                        */
+
+    if ((irq_enable & (DC3_IRQ_MASK | DC3_VSYNC_IRQ_MASK)) == (DC3_IRQ_MASK | DC3_VSYNC_IRQ_MASK))
+        return 0;
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_IRQ, irq_enable);
+    WRITE_REG32 (DC3_UNLOCK, lock);
+	
+    return (irq_enable & (DC3_IRQ_STATUS | DC3_VSYNC_IRQ_STATUS));
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_flip_status
+ *
+ * This routine tests if a new display offset has been latched.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_test_flip_status (void)
+{
+    return (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_FLIP);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_save_state
+ *
+ * This routine saves all persistent VG state information.
+ *---------------------------------------------------------------------------*/
+
+int vg_save_state (VG_SAVE_RESTORE *vg_state)
+{
+    Q_WORD msr_value;
+    unsigned long irqfilt;
+    unsigned long offset, i;
+    unsigned long lock;
+
+    /* READ ALL CURRENT REGISTER SETTINGS */
+
+    vg_state->unlock                = READ_REG32 (DC3_UNLOCK);
+    vg_state->gcfg                  = READ_REG32 (DC3_GENERAL_CFG);
+    vg_state->dcfg                  = READ_REG32 (DC3_DISPLAY_CFG);
+    vg_state->arb_cfg               = READ_REG32 (DC3_ARB_CFG);
+    vg_state->fb_offset             = READ_REG32 (DC3_FB_ST_OFFSET);
+    vg_state->cb_offset             = READ_REG32 (DC3_CB_ST_OFFSET);
+    vg_state->cursor_offset         = READ_REG32 (DC3_CURS_ST_OFFSET);
+    vg_state->video_y_offset        = READ_REG32 (DC3_VID_Y_ST_OFFSET);
+    vg_state->video_u_offset        = READ_REG32 (DC3_VID_U_ST_OFFSET);
+    vg_state->video_v_offset        = READ_REG32 (DC3_VID_V_ST_OFFSET);
+    vg_state->dv_top                = READ_REG32 (DC3_DV_TOP);
+    vg_state->line_size             = READ_REG32 (DC3_LINE_SIZE);
+    vg_state->gfx_pitch             = READ_REG32 (DC3_GFX_PITCH);
+    vg_state->video_yuv_pitch       = READ_REG32 (DC3_VID_YUV_PITCH);
+    vg_state->h_active              = READ_REG32 (DC3_H_ACTIVE_TIMING);
+    vg_state->h_blank               = READ_REG32 (DC3_H_BLANK_TIMING);
+    vg_state->h_sync                = READ_REG32 (DC3_H_SYNC_TIMING);
+    vg_state->v_active              = READ_REG32 (DC3_V_ACTIVE_TIMING);
+    vg_state->v_blank               = READ_REG32 (DC3_V_BLANK_TIMING);
+    vg_state->v_sync                = READ_REG32 (DC3_V_SYNC_TIMING);
+    vg_state->fb_active             = READ_REG32 (DC3_FB_ACTIVE);
+    vg_state->cursor_x              = READ_REG32 (DC3_CURSOR_X);
+    vg_state->cursor_y              = READ_REG32 (DC3_CURSOR_Y);
+    vg_state->vid_ds_delta          = READ_REG32 (DC3_VID_DS_DELTA);
+    vg_state->fb_base               = READ_REG32 (DC3_PHY_MEM_OFFSET);
+    vg_state->dv_ctl                = READ_REG32 (DC3_DV_CTL);
+    vg_state->gfx_scale             = READ_REG32 (DC3_GFX_SCALE);
+    vg_state->irq_ctl               = READ_REG32 (DC3_IRQ_FILT_CTL);
+    vg_state->vbi_even_ctl          = READ_REG32 (DC3_VBI_EVEN_CTL);
+    vg_state->vbi_odd_ctl           = READ_REG32 (DC3_VBI_ODD_CTL);
+    vg_state->vbi_hor_ctl           = READ_REG32 (DC3_VBI_HOR);
+    vg_state->vbi_odd_line_enable   = READ_REG32 (DC3_VBI_LN_ODD);
+    vg_state->vbi_even_line_enable  = READ_REG32 (DC3_VBI_LN_EVEN);
+    vg_state->vbi_pitch             = READ_REG32 (DC3_VBI_PITCH);
+    vg_state->color_key             = READ_REG32 (DC3_COLOR_KEY);
+    vg_state->color_key_mask        = READ_REG32 (DC3_COLOR_MASK);
+    vg_state->color_key_x           = READ_REG32 (DC3_CLR_KEY_X);
+    vg_state->color_key_y           = READ_REG32 (DC3_CLR_KEY_Y);
+    vg_state->irq                   = READ_REG32 (DC3_IRQ);
+    vg_state->genlk_ctl             = READ_REG32 (DC3_GENLK_CTL);
+    vg_state->vid_y_even_offset     = READ_REG32 (DC3_VID_EVEN_Y_ST_OFFSET);
+    vg_state->vid_u_even_offset     = READ_REG32 (DC3_VID_EVEN_U_ST_OFFSET);
+    vg_state->vid_v_even_offset     = READ_REG32 (DC3_VID_EVEN_V_ST_OFFSET);
+    vg_state->vactive_even          = READ_REG32 (DC3_V_ACTIVE_EVEN);
+    vg_state->vblank_even           = READ_REG32 (DC3_V_BLANK_EVEN);
+    vg_state->vsync_even            = READ_REG32 (DC3_V_SYNC_EVEN);
+
+    /* READ THE CURRENT PALETTE */
+
+    lock = READ_REG32 (DC3_UNLOCK);
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+    for (i = 0; i < 261; i++)
+        vg_state->palette[i] = READ_REG32 (DC3_PAL_DATA);
+
+    /* READ THE CURRENT FILTER COEFFICIENTS */
+
+	/* ENABLE ACCESS TO THE HORIZONTAL COEFFICIENTS */
+
+	irqfilt  = READ_REG32 (DC3_IRQ_FILT_CTL);
+	irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+	
+	/* READ HORIZONTAL COEFFICIENTS */
+
+    for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+        vg_state->h_coeff[(i << 1)]     = READ_REG32 (DC3_FILT_COEFF1);
+        vg_state->h_coeff[(i << 1) + 1] = READ_REG32 (DC3_FILT_COEFF2);
+	}
+
+	/* ENABLE ACCESS TO THE VERTICAL COEFFICIENTS */
+
+	irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+	/* READ COEFFICIENTS */
+
+	for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+        vg_state->v_coeff[i] = READ_REG32 (DC3_FILT_COEFF1);
+	}
+
+    /* READ THE CURSOR DATA */
+
+    offset = READ_REG32 (DC3_CURS_ST_OFFSET) & 0x0FFFFFFF;
+    for (i = 0; i < 3072; i++)
+        vg_state->cursor_data[i] = READ_FB32 (offset + (i << 2));
+
+    /* READ THE CURRENT PLL */
+
+    msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+    vg_state->pll_flags = 0;
+    for (i = 0; i < NUM_CIMARRON_PLL_FREQUENCIES; i++)
+    {
+        if (CimarronPLLFrequencies[i].pll_value == (msr_value.high & 0x7FFF))
+        {
+            vg_state->dot_pll = CimarronPLLFrequencies[i].frequency;
+            break;
+        }
+    }
+
+    if (i == NUM_CIMARRON_PLL_FREQUENCIES)
+    {
+	    /* NO MATCH */
+        /* Enter the frequency as a manual frequency. */
+
+	    vg_state->dot_pll = msr_value.high;
+        vg_state->pll_flags |= VG_PLL_MANUAL;
+    }
+    if (msr_value.low & GLCP_DOTPLL_HALFPIX)
+    	vg_state->pll_flags |= VG_PLL_DIVIDE_BY_2;
+    if (msr_value.low & GLCP_DOTPLL_BYPASS)
+        vg_state->pll_flags |= VG_PLL_BYPASS;
+    if (msr_value.high & GLCP_DOTPLL_DIV4)
+        vg_state->pll_flags |= VG_PLL_DIVIDE_BY_4;
+    if (msr_value.high & GLCP_DOTPLL_VIPCLK)
+        vg_state->pll_flags |= VG_PLL_VIP_CLOCK;
+
+    /* READ ALL VG MSRS */
+
+    msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CAP,    &(vg_state->msr_cap));
+    msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CONFIG, &(vg_state->msr_config));
+    msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_SMI,    &(vg_state->msr_smi));
+    msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_ERROR,  &(vg_state->msr_error));
+    msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_PM,     &(vg_state->msr_pm));
+    msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG,   &(vg_state->msr_diag));
+    msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR,        &(vg_state->msr_spare));
+    msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_RAM_CTL,          &(vg_state->msr_ram_ctl));
+
+    WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_restore_state
+ *
+ * This routine restores all persistent VG state information.
+ *---------------------------------------------------------------------------*/
+
+int vg_restore_state (VG_SAVE_RESTORE *vg_state)
+{
+    unsigned long irqfilt, i;
+	unsigned long memoffset;
+
+    /* TEMPORARILY UNLOCK ALL REGISTERS */
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+    /* RESTORE THE FRAME BUFFER OFFSET */
+
+    WRITE_REG32 (DC3_PHY_MEM_OFFSET, vg_state->fb_base);
+
+    /* BLANK GCFG AND DCFG */
+
+    WRITE_REG32 (DC3_GENERAL_CFG, 0);
+    WRITE_REG32 (DC3_DISPLAY_CFG, 0);
+
+    /* RESTORE ALL REGISTERS */
+
+    WRITE_REG32 (DC3_ARB_CFG,               vg_state->arb_cfg);
+    WRITE_REG32 (DC3_FB_ST_OFFSET,          vg_state->fb_offset);
+    WRITE_REG32 (DC3_CB_ST_OFFSET,          vg_state->cb_offset);
+    WRITE_REG32 (DC3_CURS_ST_OFFSET,        vg_state->cursor_offset);
+    WRITE_REG32 (DC3_VID_Y_ST_OFFSET,       vg_state->video_y_offset);
+    WRITE_REG32 (DC3_VID_U_ST_OFFSET,       vg_state->video_u_offset);
+    WRITE_REG32 (DC3_VID_V_ST_OFFSET,       vg_state->video_v_offset);
+    WRITE_REG32 (DC3_DV_TOP,                vg_state->dv_top);
+    WRITE_REG32 (DC3_LINE_SIZE,             vg_state->line_size);
+    WRITE_REG32 (DC3_GFX_PITCH,             vg_state->gfx_pitch);
+    WRITE_REG32 (DC3_VID_YUV_PITCH,         vg_state->video_yuv_pitch);
+    WRITE_REG32 (DC3_H_ACTIVE_TIMING,       vg_state->h_active);
+    WRITE_REG32 (DC3_H_BLANK_TIMING,        vg_state->h_blank);
+    WRITE_REG32 (DC3_H_SYNC_TIMING,         vg_state->h_sync);
+    WRITE_REG32 (DC3_V_ACTIVE_TIMING,       vg_state->v_active);
+    WRITE_REG32 (DC3_V_BLANK_TIMING,        vg_state->v_blank);
+    WRITE_REG32 (DC3_V_SYNC_TIMING,         vg_state->v_sync);
+    WRITE_REG32 (DC3_FB_ACTIVE,             vg_state->fb_active);
+    WRITE_REG32 (DC3_CURSOR_X,              vg_state->cursor_x);
+    WRITE_REG32 (DC3_CURSOR_Y,              vg_state->cursor_y);
+    WRITE_REG32 (DC3_VID_DS_DELTA,          vg_state->vid_ds_delta);
+    WRITE_REG32 (DC3_PHY_MEM_OFFSET,        vg_state->fb_base);
+    WRITE_REG32 (DC3_DV_CTL,                vg_state->dv_ctl | 0x00000001);
+    WRITE_REG32 (DC3_GFX_SCALE,             vg_state->gfx_scale);
+    WRITE_REG32 (DC3_IRQ_FILT_CTL,          vg_state->irq_ctl);
+    WRITE_REG32 (DC3_VBI_EVEN_CTL,          vg_state->vbi_even_ctl);
+    WRITE_REG32 (DC3_VBI_ODD_CTL,           vg_state->vbi_odd_ctl);
+    WRITE_REG32 (DC3_VBI_HOR,               vg_state->vbi_hor_ctl);
+    WRITE_REG32 (DC3_VBI_LN_ODD,            vg_state->vbi_odd_line_enable);
+    WRITE_REG32 (DC3_VBI_LN_EVEN,           vg_state->vbi_even_line_enable);
+    WRITE_REG32 (DC3_VBI_PITCH,             vg_state->vbi_pitch);
+    WRITE_REG32 (DC3_COLOR_KEY,             vg_state->color_key);
+    WRITE_REG32 (DC3_COLOR_MASK,            vg_state->color_key_mask);
+    WRITE_REG32 (DC3_CLR_KEY_X,             vg_state->color_key_x);
+    WRITE_REG32 (DC3_CLR_KEY_Y,             vg_state->color_key_y);
+    WRITE_REG32 (DC3_IRQ,                   vg_state->irq);
+    WRITE_REG32 (DC3_GENLK_CTL,             vg_state->genlk_ctl);
+    WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET,  vg_state->vid_y_even_offset);
+    WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET,  vg_state->vid_u_even_offset);
+    WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET,  vg_state->vid_v_even_offset);
+    WRITE_REG32 (DC3_V_ACTIVE_EVEN,         vg_state->vactive_even);
+    WRITE_REG32 (DC3_V_BLANK_EVEN,          vg_state->vblank_even);
+    WRITE_REG32 (DC3_V_SYNC_EVEN,           vg_state->vsync_even);
+
+    /* RESTORE THE PALETTE */
+
+    WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+    for (i = 0; i < 261; i++)
+        WRITE_REG32 (DC3_PAL_DATA, vg_state->palette[i]);
+
+    /* RESTORE THE HORIZONTAL FILTER COEFFICIENTS */
+
+	irqfilt  = READ_REG32 (DC3_IRQ_FILT_CTL);
+	irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+
+    for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+        WRITE_REG32 (DC3_FILT_COEFF1, vg_state->h_coeff[(i << 1)]);
+        WRITE_REG32 (DC3_FILT_COEFF2, vg_state->h_coeff[(i << 1) + 1]);
+	}
+
+	/* RESTORE VERTICAL COEFFICIENTS */
+
+	irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+	for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+        WRITE_REG32 (DC3_FILT_COEFF1, vg_state->v_coeff[i]);
+	}
+
+    /* RESTORE THE CURSOR DATA */
+
+    memoffset = READ_REG32 (DC3_CURS_ST_OFFSET) & 0x0FFFFFFF;
+    WRITE_FB_STRING32 (memoffset, (unsigned char *)&(vg_state->cursor_data[0]), 3072);
+
+    /* RESTORE THE PLL */
+    /* Use a common routine to use common code to poll for lock bit */
+
+    vg_set_clock_frequency (vg_state->dot_pll, vg_state->pll_flags);
+
+    /* RESTORE ALL VG MSRS */
+
+    msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CAP,    &(vg_state->msr_cap));
+    msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CONFIG, &(vg_state->msr_config));
+    msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_SMI,    &(vg_state->msr_smi));
+    msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_ERROR,  &(vg_state->msr_error));
+    msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_PM,     &(vg_state->msr_pm));
+    msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG,   &(vg_state->msr_diag));
+    msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR,        &(vg_state->msr_spare));
+    msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_RAM_CTL,          &(vg_state->msr_ram_ctl));
+
+    /* NOW RESTORE GCFG AND DCFG */
+
+    WRITE_REG32 (DC3_DISPLAY_CFG, vg_state->dcfg);
+	WRITE_REG32 (DC3_GENERAL_CFG, vg_state->gcfg);
+
+    /* FINALLY RESTORE UNLOCK */
+
+    WRITE_REG32 (DC3_UNLOCK, vg_state->unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON VG READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging.  They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_VG_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * vg_read_graphics_crc
+ *
+ * This routine reads the Cyclic Redundancy Check (CRC) value for the graphics
+ * frame.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_read_graphics_crc (int crc_source)
+{
+    unsigned long gcfg, unlock;
+	unsigned long crc, vbi_even;
+    unsigned long interlaced;
+    unsigned long line, field;
+
+	if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+		return 0xFFFFFFFF;
+
+	unlock   = READ_REG32 (DC3_UNLOCK);
+	gcfg     = READ_REG32 (DC3_GENERAL_CFG);
+    vbi_even = READ_REG32 (DC3_VBI_EVEN_CTL);
+
+    vbi_even &= ~DC3_VBI_EVEN_ENABLE_CRC;
+
+	gcfg |=   DC3_GCFG_SGRE | DC3_GCFG_CRC_MODE;
+	gcfg &= ~(DC3_GCFG_SGFR | DC3_GCFG_SIG_SEL | DC3_GCFG_FILT_SIG_SEL);
+
+    switch (crc_source)
+    {
+        case VG_CRC_SOURCE_PREFILTER_EVEN:
+        case VG_CRC_SOURCE_PREFILTER:        gcfg |= DC3_GCFG_SIG_SEL;      break;
+        case VG_CRC_SOURCE_PREFLICKER:
+        case VG_CRC_SOURCE_PREFLICKER_EVEN:  gcfg |= DC3_GCFG_FILT_SIG_SEL; break;
+        case VG_CRC_SOURCE_POSTFLICKER:
+        case VG_CRC_SOURCE_POSTFLICKER_EVEN: /* NO WORK */                  break;
+
+        default:
+            return 0xFFFFFFFF;
+    }
+
+    if (crc_source & VG_CRC_SOURCE_EVEN) field = 0;
+    else                                 field = DC3_LNCNT_EVEN_FIELD;
+
+    if ((interlaced = (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)))
+    {
+        /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+        /* Note that we wait for the field to be odd when CRCing the even */
+        /* field and vice versa.  This is because the CRC will not begin  */
+        /* until the following field.                                     */
+
+        do
+        {
+            line = READ_REG32 (DC3_LINE_CNT_STATUS);
+        } while ((line & DC3_LNCNT_EVEN_FIELD) != field    ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 10 ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 15);
+    }
+    else
+    {
+        /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+        if (crc_source & VG_CRC_SOURCE_EVEN)
+            return 0xFFFFFFFF;
+    }
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_VBI_EVEN_CTL, vbi_even);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg & ~DC3_GCFG_SIGE);
+    WRITE_REG32 (DC3_GENERAL_CFG, gcfg |  DC3_GCFG_SIGE);
+
+	/* WAIT FOR THE CRC TO BE COMPLETED */
+
+	while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_SIGC))
+		;
+
+	/* READ THE COMPLETED CRC */
+
+	crc = READ_REG32 (DC3_PAL_DATA);
+
+	/* RESTORE THE PALETTE SETTINGS */
+
+	gcfg &= ~DC3_GCFG_SGRE;
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_read_window_crc
+ *
+ * This routine reads the Cyclic Redundancy Check (CRC) value for a sub-section
+ * of the frame.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_read_window_crc (int crc_source, unsigned long x, unsigned long y,
+    unsigned long width, unsigned long height)
+{
+    Q_WORD msr_value;
+	unsigned long crc = 0;
+    unsigned long hactive, hblankstart;
+    unsigned long htotal,  hblankend;
+    unsigned long line, field;
+    unsigned long diag;
+
+    hactive     = ((READ_REG32 (DC3_H_ACTIVE_TIMING)) & 0xFFF) + 1;
+    hblankstart = ((READ_REG32 (DC3_H_BLANK_TIMING))  & 0xFFF) + 1;
+    htotal      = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+    hblankend   = ((READ_REG32 (DC3_H_BLANK_TIMING)  >> 16) & 0xFFF) + 1;
+
+    /* TIMINGS MUST BE ACTIVE */
+
+	if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+		return 0xFFFFFFFF;
+
+    /* DISABLE GLCP ACTIONS */
+
+    msr_value.low  = 0;
+    msr_value.high = 0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+    if ((x == 0 && width == 1) || x == 1)
+    {
+        /* SPECIAL CASE FOR X == 0 */
+        /* The comparator output is a clock late in the MCP, so we cannot */
+        /* easily catch the first pixel.  If the first pixel is desired,  */
+        /* we will insert a special state machine to CRC just the first   */
+        /* pixel.                                                         */
+
+        /* N2 - DISPE HIGH AND Y == 1 */
+        /* Goto state YState = 2      */
+
+        msr_value.high = 0x00000002;
+        msr_value.low  = 0x00000C00;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 2, &msr_value);
+
+        /* M3 - DISPE HIGH AND Y == 0 */
+        /* Goto YState = 1            */
+
+        msr_value.high = 0x00000002;
+        msr_value.low  = 0x00000A00;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 3, &msr_value);
+
+        /* N3 - DISPE LOW  */
+        /* Goto YState = 0 */
+
+        msr_value.high = 0x00080000;
+        msr_value.low  = 0x00000000;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 3, &msr_value);
+
+        /* Y0 -> Y1 (SET M3) */
+
+        msr_value.high = 0x00000000;
+        msr_value.low  = 0x0000C000;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 18, &msr_value);
+
+        /* Y1 -> Y0 (SET N3) */
+
+        msr_value.low = 0x0000A000;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 17, &msr_value);
+
+        /* Y1 -> Y2 (SET N2) */
+
+        msr_value.low = 0x00000A00;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 19, &msr_value);
+
+        /* N5 (XSTATE = 10 && CMP2 <= V. COUNTER <= CMP3) && DISPE && Y == 0 */
+        /* CRC into REGB                                                     */
+
+        msr_value.high = 0x00000002;
+        msr_value.low  = 0x10800B20;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 5, &msr_value);
+
+        /* N6 (XSTATE = 10 && CMP2 <= V. COUNTER <= CMP3) && DISPE && Y == 1 */
+        /* CRC into REGB                                                     */
+
+        msr_value.high = 0x00000002;
+        msr_value.low  = 0x10800D20;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 6, &msr_value);
+    }
+
+    /* M4 (XSTATE = 00 AND VSYNC HIGH) */
+    /* Goto state 01                   */
+    /* Note: VSync = H3A               */
+
+    msr_value.high = 0x00000001;
+    msr_value.low  = 0x000000A0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 4, &msr_value);
+
+    /* N0 (XSTATE = 01 AND VSYNC LOW) */
+    /* Goto state 02                  */
+    /* Note: VSync low = H3B          */
+
+    msr_value.high = 0x00040000;
+    msr_value.low  = 0x000000C0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL, &msr_value);
+
+    /* M5 (XSTATE = 10 AND VSYNC HIGH) */
+    /* Goto state 11                   */
+
+    msr_value.high = 0x00000001;
+    msr_value.low  = 0x00000120;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 5, &msr_value);
+
+    /* N1 (XSTATE = 10 and DISPE HIGH) */
+    /* Increment H. Counter           */
+    /* Note: DispE = H4               */
+
+    msr_value.high = 0x00000002;
+    msr_value.low  = 0x00000120;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 1, &msr_value);
+
+    /* M0 (XSTATE = 10 and H. COUNTER == LIMIT)  */
+    /* Clear H. Counter and increment V. Counter */
+
+    msr_value.high = 0x00000000;
+    msr_value.low  = 0x00000122;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL, &msr_value);
+
+    /* N4 (XSTATE = 10 && CMP0 <= H. COUNTER <= CMP1 && CMP2 <= V. COUNTER <= CMP3) && DISPE */
+    /* CRC into REGB                                                                         */
+
+    msr_value.high = 0x00000002;
+    msr_value.low  = 0x10C20120;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 4, &msr_value);
+
+    /* COMPARATOR 0 VALUE                                         */
+    /* We subtract 1 to account for a pipeline delay in the GLCP. */
+    /* When the x coordinate is 0, we must play a special game.   */
+    /* If the width is exactly 1, we will set up a state machine  */
+    /* to only CRC the first pixel.  Otherwise, we will set it    */
+    /* as an OR combination of a state that CRCs the first pixel  */
+    /* and a state that CRCs 1 clock delayed width (width - 1)    */
+
+    msr_value.high = 0;
+    if (x > 1) msr_value.low = (x - 1) & 0xFFFF;
+    else       msr_value.low = x;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0, &msr_value);
+
+    /* COMPARATOR 1 VALUE */
+
+    if ((x == 0 || x == 1) && width > 1) msr_value.low += width - 2;
+    else                                 msr_value.low += width - 1;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 2, &msr_value);
+
+    /* COMPARATOR 2 VALUE */
+
+    msr_value.low = y << 16;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 4, &msr_value);
+
+    /* COMPARATOR 3 VALUE */
+
+    msr_value.low += (height - 1) << 16;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 6, &msr_value);
+
+    /* COMPARATOR MASKS */
+    /* Comparators 0 and 1 refer to lower 16 bits of RegB */
+
+    msr_value.low = 0x0000FFFF;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0, &msr_value);
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 2, &msr_value);
+
+    /* Comparators 2 and 3 refer to upper 16 bits of RegB */
+
+    msr_value.low = 0xFFFF0000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 4, &msr_value);
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 6, &msr_value);
+
+    /* SET REGB MASK                                               */
+    /* We set the mask such that all all 32 bits of data are CRCed */
+
+    msr_value.low = 0xFFFFFFFF;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGBMASK, &msr_value);
+
+    /* ACTIONS */
+
+    /* STATE 00->01 (SET 4M) */
+
+    msr_value.low = 0x000C0000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 14, &msr_value);
+
+    /* STATE 01->10 (SET 0N) */
+
+    msr_value.low = 0x0000000A;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 15, &msr_value);
+
+    /* STATE 10->11 (SET 5M) */
+
+    msr_value.low = 0x00C00000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 16, &msr_value);
+
+    /* CLEAR REGA WHEN TRANSITIONING TO STATE 10                 */
+    /* Do not clear RegB as the initial value must be 0x00000001 */
+
+    msr_value.low = 0x0000000A;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0, &msr_value);
+
+    /* REGISTER ACTION 1 */
+    /* CRC into RegB if cmp0 <= h.counter <= cmp1 && cmp2 <= v. counter < cmp3 && 7 xstate = 10 */
+    /* Increment h.counter if xstate = 10 and HSync is low.                                     */
+
+    msr_value.low = 0x000A00A0;
+    if (x == 0 && width == 1)
+        msr_value.low  = 0x00A000A0;
+    else if (x == 1 && width == 1)
+        msr_value.low = 0x0A0000A0;
+    else if (x == 1 && width > 1)
+        msr_value.low |= 0x0A000000;
+
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 1, &msr_value);
+
+    /* REGISTER ACTION 2            */
+    /* Increment V. Counter in REGA */
+
+    msr_value.low = 0x0000000C;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 2, &msr_value);
+
+    /* SET REGB TO 0x00000001 */
+
+    msr_value.low = 0x00000001;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+
+    /* SET XSTATE TO 0 */
+
+    msr_value.low = 0x00000000;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+
+    /* SET YSTATE TO 0 */
+
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_YSTATE, &msr_value);
+
+    /* CLEAR ALL OTHER ACTIONS */
+	/* This prevents side-effects from previous accesses to the GLCP */
+	/* debug logic.                                                  */
+
+	msr_value.low  = 0x00000000;
+	msr_value.high = 0x00000000;
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 3, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 4, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 5, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 6, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 7, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 8, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 9, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 10, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 11, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 12, &msr_value);
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 13, &msr_value);	
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 20, &msr_value);
+
+    /* SET DIAG SETTINGS BASED ON DESIRED CRC */
+
+    if (crc_source == VG_CRC_SOURCE_POSTFLICKER || crc_source == VG_CRC_SOURCE_POSTFLICKER_EVEN)
+    {
+        diag = 0x80808086;
+
+        /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO DOT CLOCK */
+
+	    msr_value.high = 0;
+	    msr_value.low  = 5;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+	    msr_value.low = 0;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+	    msr_value.low = 3;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+        /* SET REGA LIMITS                              */
+        /* Lower counter uses pixels/line               */
+        /* Upper counter is 0xFFFF to prevent rollover. */
+
+        msr_value.low = 0xFFFF0000 | (hactive - 1);
+        if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+        {
+            msr_value.low += hblankstart - hactive;
+            msr_value.low += htotal      - hblankend;
+        }
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+        /* USE H4 FUNCTION A FOR DISPE AND H4 FUNCTION B FOR NOT DISPE */
+        /* DISPE is bit 34                                             */
+
+        msr_value.high = 0x00000002;
+        msr_value.low  = 0x20000FF0;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+        /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+        /* VSYNC is bit 32.                                            */
+
+        msr_value.high = 0x00000000;
+        msr_value.low  = 0x002055AA;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+    }
+    else if (crc_source == VG_CRC_SOURCE_PREFLICKER || crc_source == VG_CRC_SOURCE_PREFLICKER_EVEN)
+    {
+        diag = 0x801F8032;
+
+        /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO GEODELINK CLOCK */
+
+	    msr_value.high = 0;
+	    msr_value.low  = 5;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+	    msr_value.low = 0;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+	    msr_value.low = 2;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+        /* SET REGA LIMITS                              */
+        /* Lower counter uses pixels/line               */
+        /* Upper counter is 0xFFFF to prevent rollover. */
+
+        msr_value.low = 0xFFFF0000 | (hactive - 1);
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+        /* USE H4 FUNCTION A FOR DISPE AND H4 FUNCTION B FOR NOT DISPE */
+        /* DISPE is bit 47                                             */
+
+        msr_value.high = 0x00000002;
+        msr_value.low  = 0xF0000FF0;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+        /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+        /* VSYNC is bit 45.                                            */
+
+        msr_value.high = 0x00000000;
+        msr_value.low  = 0x002D55AA;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+    }
+    else
+    {
+        /* PREFILTER CRC */
+
+        diag = 0x80138048;
+        msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG, &msr_value);
+
+        /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO GEODELINK CLOCK */
+
+        msr_value.high = 0;
+	    msr_value.low  = 5;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+	    msr_value.low = 0;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+	    msr_value.low = 2;
+	    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+        /* SET REGA LIMITS                                      */
+        /* Lower counter uses pixels/line                       */
+        /* Upper counter is 0xFFFF to prevent rollover.         */
+        /* Note that we are assuming that the number of         */
+        /* source pixels is specified in the FB_ACTIVE register */
+
+        msr_value.low = 0xFFFF0000 | ((READ_REG32 (DC3_FB_ACTIVE) >> 16) & 0xFFF);
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+        /* USE H4 FUNCTION A FOR DISPE AND H4 FUNCTION B FOR NOT DISPE */
+        /* DISPE is bit 55                                             */
+
+        msr_value.high = 0x00000003;
+        msr_value.low  = 0x70000FF0;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+        /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+        /* VSYNC is bit 53.                                            */
+
+        msr_value.high = 0x00000000;
+        msr_value.low  = 0x003555AA;
+        msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+    }
+
+    /* WAIT FOR THE CORRECT FIELD */
+    /* We use the VG line count and field indicator to determine when */
+    /* to kick off a CRC.                                             */
+
+    if (crc_source & VG_CRC_SOURCE_EVEN) field = 0;
+    else                                 field = DC3_LNCNT_EVEN_FIELD;
+
+    if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+    {
+        /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+        /* Note that we wait for the field to be odd when CRCing the even */
+        /* field and vice versa.  This is because the CRC will not begin  */
+        /* until the following field.                                     */
+
+        do
+        {
+            line = READ_REG32 (DC3_LINE_CNT_STATUS);
+        } while ((line & DC3_LNCNT_EVEN_FIELD) != field    ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 1 ||
+                ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 5);
+    }
+    else
+    {
+        /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+        if (crc_source & VG_CRC_SOURCE_EVEN)
+            return 0xFFFFFFFF;
+    }
+
+    /* UPDATE VG DIAG OUTPUT */
+
+    msr_value.high = 0;
+    msr_value.low  = diag;
+    msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG, &msr_value);
+
+    /* CONFIGURE DIAG CONTROL */
+    /* Set RegA action1 to increment lower 16 bits and clear at limit. (5)      */
+    /* Set RegA action2 to increment upper 16 bits. (6)                         */
+    /* Set RegB action1 to CRC32 (1)                                            */
+    /* Set all comparators to REGA override (0,1 lower mbus, 2,3 upper mbus)    */
+    /* Enable all actions                                                       */
+
+    msr_value.low = 0x80EA20A0;
+    msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+	
+	/* DELAY TWO FRAMES */
+
+    while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+	while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+	while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+	while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+	while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+
+	/* VERIFY THAT XSTATE = 11 */
+
+	msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+	if ((msr_value.low & 3) == 3)
+	{
+		msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+		
+		crc = msr_value.low;
+	}
+
+	/* DISABLE VG DIAG BUS OUTPUTS */
+
+	msr_value.low  = 0x00000000;
+	msr_value.high = 0x00000000;
+	msr_write64 (MSR_DEVICE_GEODELX_VG,  MSR_GEODELINK_DIAG, &msr_value);
+
+	/* DISABLE GLCP ACTIONS */
+
+	msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+    return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_scaler_filter_coefficients
+ *
+ * This routine gets the vertical and horizontal filter coefficients for
+ * graphics scaling.  The coefficients are sign extended to 32-bit values.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3])
+{
+	unsigned long irqfilt, i;
+	unsigned long temp;
+    long coeff0, coeff1, coeff2;
+    unsigned long lock;
+    	
+	/* ENABLE ACCESS TO THE HORIZONTAL COEFFICIENTS */
+
+    lock     = READ_REG32 (DC3_UNLOCK);
+	irqfilt  = READ_REG32 (DC3_IRQ_FILT_CTL);
+	irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+	
+	/* WRITE COEFFICIENTS */
+	/* Coefficient indexes do not auto-increment, so we must */
+	/* write the address for every phase                     */
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+        temp = READ_REG32 (DC3_FILT_COEFF1);
+        coeff0 = (temp & 0x3FF);
+        coeff1 = (temp >> 10) & 0x3FF;
+        coeff2 = (temp >> 20) & 0x3FF;
+
+        h_taps[i][0] = (coeff0 << 22) >> 22;
+        h_taps[i][1] = (coeff1 << 22) >> 22;
+        h_taps[i][2] = (coeff2 << 22) >> 22;
+
+        temp = READ_REG32 (DC3_FILT_COEFF2);
+        coeff0 = (temp & 0x3FF);
+        coeff1 = (temp >> 10) & 0x3FF;
+
+        h_taps[i][3] = (coeff0 << 22) >> 22;
+        h_taps[i][4] = (coeff1 << 22) >> 22;
+	}
+
+	/* ENABLE ACCESS TO THE VERTICAL COEFFICIENTS */
+
+	irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+	/* WRITE COEFFICIENTS */
+
+	for (i = 0; i < 256; i++)
+	{
+		WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+        temp = READ_REG32 (DC3_FILT_COEFF1);
+        coeff0 = (temp & 0x3FF);
+        coeff1 = (temp >> 10) & 0x3FF;
+        coeff2 = (temp >> 20) & 0x3FF;
+
+        v_taps[i][0] = (coeff0 << 22) >> 22;
+        v_taps[i][1] = (coeff1 << 22) >> 22;
+        v_taps[i][2] = (coeff2 << 22) >> 22;
+	}
+
+    WRITE_REG32 (DC3_UNLOCK, lock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_flicker_filter_configuration
+ *
+ * This routine returns the current VG flicker filter configuration.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_flicker_filter_configuration (unsigned long *strength, int *flicker_alpha)
+{
+    unsigned long genlk_ctl;
+
+    if (!strength || !flicker_alpha)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
+    *strength = genlk_ctl & DC3_GC_FLICKER_FILTER_MASK;
+    if (genlk_ctl & DC3_GC_ALPHA_FLICK_ENABLE)
+        *flicker_alpha = 1;
+    else
+        *flicker_alpha = 0;
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_pitch
+ *
+ * This routine returns the current stride between successive lines of frame
+ * buffer data.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_display_pitch (void)
+{
+	return ((READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_frame_buffer_line_size
+ *
+ * This routine returns the current size in bytes of one line of frame buffer
+ * data.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_frame_buffer_line_size (void)
+{
+	return ((READ_REG32 (DC3_LINE_SIZE) & 0x3FF) << 3);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_current_vline
+ *
+ * This routine returns the number of the current line that is being displayed
+ * by the display controller.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_current_vline (void)
+{
+	unsigned long current_line;
+	
+	/* READ THE REGISTER TWICE TO ENSURE THAT THE VALUE IS NOT TRANSITIONING */
+	
+	do
+	{
+		current_line  = READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT;
+	}
+	while (current_line != (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT));
+		
+	return (current_line >> 16);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_offset
+ *
+ * This routine returns the offset into the frame buffer for the first pixel
+ * of the display.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_display_offset (void)
+{
+	return (READ_REG32(DC3_FB_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_cursor_info
+ *
+ * This routine returns the current settings for the hardware cursor.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_cursor_info (VG_CURSOR_DATA *cursor_data)
+{
+	unsigned long temp;
+
+	/* CURSOR OFFSET */
+
+	cursor_data->cursor_offset = READ_REG32 (DC3_CURS_ST_OFFSET) & 0x0FFFFFFF;
+	
+	/* CURSOR X POSITION */
+
+	temp = READ_REG32 (DC3_CURSOR_X);
+	cursor_data->cursor_x = temp & 0x7FF;
+	cursor_data->clipx = (temp >> 11) & 0x3F;
+
+	/* CURSOR Y POSITION */
+
+	temp = READ_REG32 (DC3_CURSOR_Y);
+	cursor_data->cursor_y = temp & 0x7FF;
+	cursor_data->clipy = (temp >> 11) & 0x3F;
+
+	/* CURSOR COLORS */
+
+	WRITE_REG32 (DC3_PAL_ADDRESS, 0x100);
+	cursor_data->mono_color0 = READ_REG32 (DC3_PAL_DATA);
+	cursor_data->mono_color1 = READ_REG32 (DC3_PAL_DATA);
+
+	/* CURSOR ENABLES */
+
+	temp = READ_REG32 (DC3_GENERAL_CFG);
+	if (temp & DC3_GCFG_CURE)    cursor_data->enable = 1;
+	else                         cursor_data->enable = 0;
+	if (temp & DC3_GCFG_CLR_CUR) cursor_data->color_cursor = 1;
+	else                         cursor_data->color_cursor = 0;
+	
+	return CIM_STATUS_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_display_palette_entry
+ *
+ * This routine reads a single entry in the 8BPP display palette.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_display_palette_entry (unsigned long index, unsigned long *entry)
+{
+	if (index > 0xFF)
+		return CIM_STATUS_INVALIDPARAMS;
+
+	WRITE_REG32 (DC3_PAL_ADDRESS, index);
+	*entry = READ_REG32 (DC3_PAL_DATA);
+	
+	return CIM_STATUS_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_border_color
+ *
+ * This routine reads the current border color for centered displays.
+ *----------------------------------------------------------------------------*/
+
+unsigned long vg_get_border_color (void)
+{
+	WRITE_REG32 (DC3_PAL_ADDRESS,  0x104);
+	return READ_REG32 (DC3_PAL_DATA);
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_display_palette
+ *
+ * This routines reads the entire contents of the display palette into a buffer.
+ * The display palette consists of 256 X:R:G:B values.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_display_palette (unsigned long *palette)
+{
+	unsigned long i;
+
+	if (palette)
+	{
+		WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+		for (i = 0; i < 256; i++)
+		{
+			palette[i] = READ_REG32 (DC3_PAL_DATA);
+		}
+        return CIM_STATUS_OK;
+	}
+	return CIM_STATUS_INVALIDPARAMS;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_compression_info
+ *
+ * This routines reads the current status of the display compression hardware.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_compression_info (VG_COMPRESSION_DATA *comp_data)
+{
+	comp_data->compression_offset = READ_REG32 (DC3_CB_ST_OFFSET) & 0x0FFFFFFF;
+	comp_data->pitch =  (READ_REG32 (DC3_GFX_PITCH) >> 13) & 0x7FFF8;
+	comp_data->size  = ((READ_REG32 (DC3_LINE_SIZE) >> (DC3_LINE_SIZE_CB_SHIFT - 3)) & 0x3F8) + 24;
+
+	return CIM_STATUS_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_compression_enable
+ *
+ * This routines reads the current enable status of the display compression hardware.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_compression_enable (void)
+{
+	if (READ_REG32 (DC3_GENERAL_CFG) & DC3_GCFG_CMPE)
+		return 1;
+	
+	return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_valid_bit
+ *----------------------------------------------------------------------------*/
+
+int vg_get_valid_bit (int line)
+{
+	unsigned long offset;
+	unsigned long valid;
+    unsigned long lock;
+	
+    lock    = READ_REG32 (DC3_UNLOCK);
+	offset  = READ_REG32 (DC3_PHY_MEM_OFFSET) & 0xFF000000;
+	offset |= line;
+
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_PHY_MEM_OFFSET, offset);
+    WRITE_REG32 (DC3_UNLOCK, lock);
+	valid = READ_REG32 (DC3_DV_ACC) & 2;
+	
+	if (valid) return 1;
+	return 0;
+}
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_vip.c xf86-video-nsc-2.8.1/src/cim/cim_vip.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_vip.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_vip.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1565 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron VIP configuration routines.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*---------------------------------------------------------------------------
+ * vip_initialize
+ *
+ * This routine initializes the internal module state and prepares the
+ * module for subsequent VIP orientated activities.
+ *---------------------------------------------------------------------------*/
+
+int vip_initialize(VIPSETMODEBUFFER *buffer)
+{
+    unsigned long vip_control1, vip_control2, vip_control3;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	vip_control1  = 0;
+	vip_control2  = 0;
+    vip_control3  = 0;
+
+	/* CONFIGURE CONTROL WORDS BASED ON MODE STRUCTURE                  */
+    /* Note that some of the input parameters match the register fields */
+    /* they represent.                                                  */
+
+    /* STREAM ENABLES */
+
+	vip_control1 |= buffer->stream_enables;
+	
+    /* VIP CAPTURE MODE */
+
+    vip_control1 |= buffer->operating_mode;
+		
+    /* HANDLE PLANAR CAPTURE */
+
+    if (buffer->flags & VIP_MODEFLAG_PLANARCAPTURE)
+    {
+        vip_control1 |= VIP_CONTROL1_PLANAR;
+
+        if (buffer->planar_capture == VIP_420CAPTURE_EVERYLINE)
+        {
+            vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
+        }
+        else if (buffer->planar_capture == VIP_420CAPTURE_ALTERNATINGFIELDS)
+        {
+            if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
+                return CIM_STATUS_INVALIDPARAMS;
+
+            vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
+            vip_control3 |= VIP_CONTROL3_DECIMATE_EVEN;
+        }
+        else if (buffer->planar_capture != VIP_420CAPTURE_ALTERNATINGLINES)
+            return CIM_STATUS_INVALIDPARAMS;
+
+        /* CONFIGURE THE VIDEO FIFO THRESHOLD BASED ON THE FIFO DEPTH */
+
+        vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_420 << VIP_CONTROL2_VIDTH_SHIFT;
+
+    }
+    else
+    {
+        vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_422 << VIP_CONTROL2_VIDTH_SHIFT;
+    }
+
+    /* CONFIGURE DEFAULT ANCILARRY THRESHOLD AND VIDEO FLUSH VALUES */
+
+    vip_control2 |= VIP_CONTROL2_DEFAULT_ANCTH  << VIP_CONTROL2_ANCTH_SHIFT;
+    vip_control1 |= VIP_CONTROL1_DEFAULT_ANC_FF << VIP_CONTROL1_ANC_FF_SHIFT;
+    vip_control1 |= VIP_CONTROL1_DEFAULT_VID_FF << VIP_CONTROL1_VID_FF_SHIFT;
+
+    /* PROGRAM VIP OPTIONS */
+    /* The options are sanitized based on the current configuration. */
+
+    if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
+        vip_control1 |= VIP_CONTROL1_NON_INTERLACED;
+    else
+    {
+        if (buffer->flags & VIP_MODEFLAG_TOGGLEEACHFIELD)
+            vip_control3 |= VIP_CONTROL3_BASE_UPDATE;
+        if (buffer->flags & VIP_MODEFLAG_INVERTPOLARITY)
+            vip_control2 |= VIP_CONTROL2_INVERT_POLARITY;
+    }
+
+    if ((buffer->operating_mode == VIP_MODE_MSG ||
+         buffer->operating_mode == VIP_MODE_DATA) &&
+        (buffer->flags & VIP_MODEFLAG_FLIPMESSAGEWHENFULL))
+    {
+        vip_control1 |= VIP_CONTROL1_MSG_STRM_CTRL;
+    }
+
+    else if (buffer->operating_mode == VIP_MODE_VIP2_8BIT ||
+             buffer->operating_mode == VIP_MODE_VIP2_16BIT)
+    {
+        if (buffer->flags & VIP_MODEFLAG_ENABLEREPEATFLAG)
+            vip_control2 |= VIP_CONTROL2_REPEAT_ENABLE;
+        if (buffer->flags & VIP_MODEFLAG_INVERTTASKPOLARITY)
+            vip_control3 |= VIP_CONTROL3_TASK_POLARITY;
+    }
+
+	if (buffer->flags & VIP_MODEFLAG_DISABLEZERODETECT)
+        vip_control1 |= VIP_CONTROL1_DISABLE_ZERO_DETECT;	
+    if (buffer->flags & VIP_MODEFLAG_10BITANCILLARY)
+        vip_control2 |= VIP_CONTROL2_ANC10;
+        	
+    /* WRITE THE CONTROL REGISTERS */
+    /* The control registers are kept 'live' to allow separate instances of */
+    /* Cimarron to control the VIP hardware.                                */
+
+    WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+    WRITE_VIP32 (VIP_CONTROL3, vip_control3);
+
+    /* CONFIGURE 601 PARAMETERS */
+
+    if (buffer->operating_mode == VIP_MODE_8BIT601 ||
+        buffer->operating_mode == VIP_MODE_16BIT601)
+    {
+        vip_update_601_params (&buffer->vip601_settings);
+    }
+
+    return CIM_STATUS_OK;	
+}
+
+/*---------------------------------------------------------------------------
+ * vip_update_601_params
+ *
+ * This routine configures all aspects of 601 VIP data capture, including
+ * start and stop timings and input polarities.
+ *---------------------------------------------------------------------------*/
+
+int vip_update_601_params (VIP_601PARAMS *buffer)
+{
+    unsigned long vip_control3, vip_control1;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    vip_control1 = READ_VIP32 (VIP_CONTROL3);
+    vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+    if (buffer->flags & VIP_MODEFLAG_VSYNCACTIVEHIGH) vip_control3 |=  VIP_CONTROL3_VSYNC_POLARITY;
+    else                                              vip_control3 &= ~VIP_CONTROL3_VSYNC_POLARITY;
+    if (buffer->flags & VIP_MODEFLAG_HSYNCACTIVEHIGH) vip_control3 |=  VIP_CONTROL3_HSYNC_POLARITY;
+    else                                              vip_control3 &= ~VIP_CONTROL3_HSYNC_POLARITY;
+
+    WRITE_VIP32 (VIP_CONTROL3,       vip_control3);
+    WRITE_VIP32 (VIP_601_HORZ_START, buffer->horz_start);
+    WRITE_VIP32 (VIP_601_VBI_START,  buffer->vbi_start);
+    WRITE_VIP32 (VIP_601_VBI_END,    buffer->vbi_start + buffer->vbi_height - 1);
+    WRITE_VIP32 (VIP_601_EVEN_START_STOP,
+        buffer->vert_start_even | ((buffer->vert_start_even + buffer->even_height - 1) << 16));
+    WRITE_VIP32 (VIP_601_ODD_START_STOP,
+        buffer->vert_start_odd | ((buffer->vert_start_odd + buffer->odd_height - 1) << 16));
+    WRITE_VIP32 (VIP_ODD_FIELD_DETECT,
+        buffer->odd_detect_start | (buffer->odd_detect_end << 16));
+
+    /* SPECIAL CASE FOR HORIZONTAL DATA */
+    /* 601 horizontal parameters are based on the number of clocks and not the */
+    /* number of pixels.                                                       */
+
+    if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601)
+        WRITE_VIP32 (VIP_601_HORZ_END,   buffer->horz_start + (buffer->width << 1) + 3);
+    else
+        WRITE_VIP32 (VIP_601_HORZ_END,   buffer->horz_start + buffer->width + 3);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_capture_buffers
+ *
+ * This routine configures the base offsets for video, ancillary or message
+ * mode capture.  The input structure can also contain multiple offsets, such
+ * that the calling application can avoid updating the structure for each flip.
+ *
+ * The new buffer addresses are written to the hardware registers although
+ * they may not be latched immediately. Calling vip_is_buffer_update_latched
+ * allows the determination of whether the update has occured.
+ *
+ * Review the Cimarron VIP API documentation to determine which buffer addresses are
+ * latched immediately.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_capture_buffers (int buffer_type, VIPINPUTBUFFER *buffer)
+{
+    VIPINPUTBUFFER_ADDR *offsets;
+    unsigned long cur_buffer = buffer->current_buffer;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	if (buffer_type == VIP_BUFFER_A || buffer_type == VIP_BUFFER_601)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+        /* SET VIDEO PITCH */
+
+        WRITE_VIP32 (VIP_TASKA_VID_PITCH, offsets->y_pitch | (offsets->uv_pitch << 16));
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+        {
+            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE,  offsets->vbi_even_base);
+                WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_odd_base);
+            }
+        }
+        else
+        {
+            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE,  offsets->vbi_odd_base);
+                WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_even_base);
+            }
+        }
+
+        /* SET 4:2:0 OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+        {
+            WRITE_VIP32 (VIP_TASKA_U_OFFSET, offsets->odd_uoffset);
+            WRITE_VIP32 (VIP_TASKA_V_OFFSET, offsets->odd_voffset);
+            WRITE_VIP32 (VIP_TASKA_U_EVEN_OFFSET, offsets->even_uoffset);
+            WRITE_VIP32 (VIP_TASKA_V_EVEN_OFFSET, offsets->even_voffset);
+        }
+    }
+    else if (buffer_type == VIP_BUFFER_B)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+        /* SET VIDEO PITCH */
+
+        WRITE_VIP32 (VIP_TASKB_VID_PITCH, offsets->y_pitch | (offsets->uv_pitch << 16));
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+        {
+            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE,  offsets->vbi_even_base);
+                WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_odd_base);
+            }
+        }
+        else
+        {
+            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE,  offsets->vbi_odd_base);
+                WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_even_base);
+            }
+        }
+
+        /* SET 4:2:0 OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+        {
+            WRITE_VIP32 (VIP_TASKB_U_OFFSET, offsets->odd_uoffset);
+            WRITE_VIP32 (VIP_TASKB_V_OFFSET, offsets->odd_voffset);
+        }
+    }
+    else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG)
+    {
+        WRITE_VIP32(VIP_ANC_MSG1_BASE, buffer->ancillaryData.msg1_base);
+		WRITE_VIP32(VIP_ANC_MSG2_BASE, buffer->ancillaryData.msg2_base);
+		WRITE_VIP32(VIP_ANC_MSG_SIZE,  buffer->ancillaryData.msg_size);
+    }
+    else
+    {
+        return CIM_STATUS_INVALIDPARAMS;
+    }
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_toggle_vip_video_offsets
+ *
+ * This routine updates the offsets for video capture.  It is a simplified
+ * version of vip_configure_capture_buffers that is designed to be called from
+ * interrupt service routines or other buffer flipping applications that
+ * require low latency.
+ *---------------------------------------------------------------------------*/
+
+int vip_toggle_video_offsets (int buffer_type, VIPINPUTBUFFER *buffer)
+{
+    unsigned long cur_buffer = buffer->current_buffer;
+    VIPINPUTBUFFER_ADDR *offsets;
+
+	if (buffer_type == VIP_BUFFER_A)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+        {
+            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+        }
+        else
+        {
+            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+        }
+    }
+    else if (buffer_type == VIP_BUFFER_B)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+        {
+            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+        }
+        else
+        {
+            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
+            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+        }
+    }
+    else if (buffer_type == VIP_BUFFER_A_ODD)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
+        else
+            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
+    }
+    else if (buffer_type == VIP_BUFFER_A_EVEN)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+        else
+            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE,  offsets->even_base[cur_buffer]);
+    }
+    else if (buffer_type == VIP_BUFFER_B_ODD)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
+        else
+            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
+    }
+    else if (buffer_type == VIP_BUFFER_B_EVEN)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+        /* SET BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+        else
+            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+    }
+    else
+        return CIM_STATUS_INVALIDPARAMS;
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_capture_state
+ *
+ * This routine takes the current control word definition ( stored in locals )
+ * adds in the specified state, and writes the control word.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_capture_state (unsigned long state)
+{
+    unsigned long vip_control1, vip_control3;
+
+    /* UPDATE THE CURRENT CAPTURE MODE */
+
+    vip_control1  =  READ_VIP32 (VIP_CONTROL1);
+    vip_control3  =  READ_VIP32 (VIP_CONTROL3);
+	vip_control1 &= ~VIP_CONTROL1_RUNMODE_MASK;
+	vip_control1 |= (state << VIP_CONTROL1_RUNMODE_SHIFT);
+
+	WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+	
+    if (state >= VIP_STARTCAPTUREATNEXTLINE)
+    {
+        /* WHACK VIP RESET */
+        /* The VIP can get confused when switching between capture settings, such as */
+        /* between linear and planar.  We will thus whack VIP reset when enabling    */
+        /* capture to ensure a pristine VIP state.                                   */
+
+        WRITE_VIP32 (VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET);
+        WRITE_VIP32 (VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET);
+        WRITE_VIP32 (VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET);
+    }
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_terminate
+ *
+ * This routine stops VIP capture and resets the VIP internal state.
+ *---------------------------------------------------------------------------*/
+
+int vip_terminate (void)
+{
+    unsigned long timeout = 50000;
+
+    /* DISABLE AND CLEAR ALL VIP INTERRUPTS */
+
+    WRITE_VIP32 (VIP_INTERRUPT, VIP_ALL_INTERRUPTS | (VIP_ALL_INTERRUPTS >> 16));
+
+    /* DISABLE VIP CAPTURE */
+    /* We will try to let the VIP FIFO flush before shutting it down. */
+
+    WRITE_VIP32 (VIP_CONTROL1, 0);
+    while (timeout)
+    {
+        timeout--;
+        if (READ_VIP32 (VIP_STATUS) & VIP_STATUS_WRITES_COMPLETE)
+            break;
+    }
+
+	/* RESET THE HARDWARE REGISTERS */
+    /* Note that we enable VIP reset to allow clock gating to lower VIP */
+    /* power consumption.                                               */
+	
+    WRITE_VIP32 (VIP_CONTROL1, VIP_CONTROL1_RESET);
+    WRITE_VIP32 (VIP_CONTROL3, VIP_CONTROL3_FIFO_RESET);
+	WRITE_VIP32 (VIP_CONTROL2, 0);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_fifo
+ *
+ * This routine sets the desired threshold or flush for the specified fifo.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_fifo (unsigned long fifo_type, unsigned long fifo_size)
+{
+    unsigned long vip_control1, vip_control2;
+
+    vip_control1 = READ_VIP32 (VIP_CONTROL1);
+    vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+	switch (fifo_type)
+    {
+		case VIP_VIDEOTHRESHOLD:
+			vip_control2 &= ~VIP_CONTROL2_VIDTH_MASK;
+			vip_control2 |= (fifo_size << VIP_CONTROL2_VIDTH_SHIFT) & VIP_CONTROL2_VIDTH_MASK;
+		    break;
+
+		case VIP_ANCILLARYTHRESHOLD:
+			vip_control2 &= ~VIP_CONTROL2_ANCTH_MASK;
+			vip_control2 |= (fifo_size << VIP_CONTROL2_ANCTH_SHIFT) & VIP_CONTROL2_ANCTH_MASK;
+		    break;
+
+		case VIP_VIDEOFLUSH:
+			vip_control1 &= ~VIP_CONTROL1_VID_FF_MASK;
+			vip_control1 |= ((fifo_size >> 2) << VIP_CONTROL1_VID_FF_SHIFT) & VIP_CONTROL1_VID_FF_MASK;
+		    break;
+
+		case VIP_ANCILLARYFLUSH:
+			vip_control1 &= ~VIP_CONTROL1_ANC_FF_MASK;
+			vip_control1 |= ((fifo_size >> 2) << VIP_CONTROL1_ANC_FF_SHIFT) & VIP_CONTROL1_ANC_FF_MASK;
+		    break;
+
+        default:
+            return CIM_STATUS_INVALIDPARAMS;
+	}
+
+    WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_interrupt_enable
+ *
+ * This routine accepts a mask of interrupts to be enabled/disabled and
+ * an enable flag.
+ *
+ * For each mask match, the interrupt will be enabled or disabled based on
+ * enable
+ *---------------------------------------------------------------------------*/
+
+int vip_set_interrupt_enable (unsigned long mask, int enable)
+{
+    /* CHECK IF ANY VALID INTERRUPTS ARE BEING CHANGED */
+
+    if (mask & VIP_ALL_INTERRUPTS)
+    {
+        unsigned long int_enable = READ_VIP32(VIP_INTERRUPT) & 0xFFFF;
+
+        /* SET OR CLEAR THE MASK BITS */
+        /* Note that the upper 16-bits of the register are 0 after this */
+        /* operation.  This prevents us from indadvertently clearing a  */
+        /* pending interrupt by enabling/disabling another one.         */
+
+        if (enable) int_enable &= ~(mask >> 16);
+        else        int_enable |=  (mask >> 16);
+
+        WRITE_VIP32 (VIP_INTERRUPT, int_enable);
+    }
+	
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_vsync_error
+ *
+ * This routine defines a region that is used to determine if the vsync is
+ * within an acceptable range. This definition is accomplished using
+ * a count and a vertical window.  The count specifies the exact number
+ * of clocks expected for one field.  The window parameters specify the number
+ * of clocks variation allowed before and after the expected vsync.  For
+ * example, if vertical_count is 1000, window_before is 5 and window_after
+ * is 12, VSync will be considered valid if it occurs between 995 and 1012
+ * clocks after the last VSync.  The total window size (window_before + window_after)
+ * cannot exceed 255.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_vsync_error (unsigned long vertical_count, unsigned long window_before,
+    unsigned long window_after, int enable)
+{
+    unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+    unsigned long temp;
+
+    if (enable)
+    {
+        /* CREATE THE VERTICAL WINDOW */
+        /* The VIP uses two counters.  The first counter defines the minimum clock count */
+        /* before a valid VSync can occur.  The second counter starts after the first    */
+        /* completes and defines the acceptable region of variation.                     */
+
+        temp  = ((window_before + window_after) << VIP_VSYNC_ERR_WINDOW_SHIFT) & VIP_VSYNC_ERR_WINDOW_MASK;
+	    temp |= (vertical_count - window_before) & VIP_VSYNC_ERR_COUNT_MASK;
+    	
+        vip_control2 |= VIP_CONTROL2_VERTERROR_ENABLE;
+
+	    WRITE_VIP32(VIP_VSYNC_ERR_COUNT, temp);
+    }
+    else
+    {
+        vip_control2 &= ~VIP_CONTROL2_VERTERROR_ENABLE;
+    }
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_max_address_enable
+ *
+ * This routine specifies the maximum address to which the the hardware should
+ * write during data storage. If this value is exceeded an error is generated,
+ * (this may be monitored using the appropriate interrupt flags - see
+ * vip_set_interrupt_enable)
+ *---------------------------------------------------------------------------*/
+
+int vip_max_address_enable (unsigned long max_address, int enable)
+{
+    unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+	if (enable)
+    {
+		/* ENABLE THE CONTROL BIT */
+
+		vip_control2 |= VIP_CONTROL2_ADD_ERROR_ENABLE;
+		
+		WRITE_VIP32(VIP_MAX_ADDRESS, max_address & VIP_MAXADDR_MASK);
+	}
+	else
+    {
+		/* DISABLE DETECTION */
+
+		vip_control2 &= ~VIP_CONTROL2_ADD_ERROR_ENABLE;
+	}
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_loopback_enable
+ *
+ * This routine enables/disables internal loopback functionality.  When
+ * loopback is enabled, the VOP outputs are rerouted to the VIP inputs
+ * internal to the chip.  No loopback connector is required.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_loopback_enable(int enable)
+{
+    unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+	if (enable) vip_control2 |=  VIP_CONTROL2_LOOPBACK_ENABLE;
+	else         vip_control2 &= ~VIP_CONTROL2_LOOPBACK_ENABLE;
+	
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_genlock
+ *
+ * This routine configures genlock functionality.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_genlock (VIPGENLOCKBUFFER *buffer)
+{
+	unsigned long vip_control1, vip_control2;
+    unsigned long unlock, genlk_ctl;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    unlock       = READ_REG32 (DC3_UNLOCK);
+    genlk_ctl    = READ_REG32 (DC3_GENLK_CTL);
+    vip_control1 = READ_VIP32 (VIP_CONTROL1);
+    vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+    /* UPDATE VIDEO DETECTION */
+    /* These flags are used to indicate the ways in which the VIP signal can */
+    /* be considered 'lost'.                                                 */
+
+    vip_control1 &= ~VIP_CONTROL1_VDE_FF_MASK;
+    vip_control2 &= ~(VIP_CONTROL2_FIELD2VG_MASK | VIP_CONTROL2_SYNC2VG_MASK);
+    vip_control1 |= buffer->vip_signal_loss;
+
+    /* UPDATE FIELD AND VSYNC INFORMATION */
+    /* These flags control how and when the even/odd field and Vsync */
+    /* information is communicated to the VG.                        */
+
+    vip_control2 |= buffer->field_to_vg;
+    vip_control2 |= buffer->vsync_to_vg;
+
+    /* ENABLE OR DISABLE GENLOCK TIMEOUT */
+    /* Enabling genlock timeout allows the VG to revert to its own sync */
+    /* timings when the VIP input is lost.  Note that the VIP will not  */
+    /* know the signal is lost unless the appropriate error detection   */
+    /* flags have been enabled inside vip_initialize.                   */
+
+	if (buffer->enable_timeout) genlk_ctl |=  DC3_GC_GENLOCK_TO_ENABLE;
+	else                        genlk_ctl &= ~DC3_GC_GENLOCK_TO_ENABLE;
+	
+	genlk_ctl &= ~DC3_GC_GENLOCK_SKEW_MASK;
+	genlk_ctl |= buffer->genlock_skew & DC3_GC_GENLOCK_SKEW_MASK;
+	
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
+    WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_genlock_enable
+ *
+ * This routine enables/disables genlock inside the VG.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_genlock_enable (int enable)
+{
+	unsigned long unlock, temp;
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    temp   = READ_REG32 (DC3_GENLK_CTL);
+
+	if (enable) temp |=  DC3_GC_GENLOCK_ENABLE;
+	else        temp &= ~DC3_GC_GENLOCK_ENABLE;
+	
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_GENLK_CTL, temp);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_power_characteristics
+ *
+ * This routine takes a VIPPOWERBUFFER structure, and selectively sets the
+ * GeodeLink power and/or Vip clock power states.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_power_characteristics (VIPPOWERBUFFER *buffer)
+{
+	Q_WORD q_word;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+	
+	q_word.low = q_word.high = 0;
+
+    /* ENABLE GEODELINK CLOCK GATING */
+	
+    if (buffer->glink_clock_mode)
+		q_word.low |= VIP_MSR_POWER_GLINK;
+	
+    /* ENABLE VIP CLOCK GATING */
+
+	if (buffer->vip_clock_mode)
+		q_word.low |= VIP_MSR_POWER_CLOCK;
+	
+    /* WRITE THE NEW VALUE */
+
+    msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
+		
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_priority_characteristics
+ *
+ * This routine programs the VIP GeodeLink priority characteristics
+ *---------------------------------------------------------------------------*/
+
+int vip_set_priority_characteristics (VIPPRIORITYBUFFER *buffer)
+{
+	Q_WORD q_word;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	q_word.low = q_word.high = 0;
+
+	q_word.low |= (buffer->secondary << VIP_MSR_MCR_SECOND_PRIORITY_SHIFT)  & VIP_MSR_MCR_SECOND_PRIORITY_MASK;
+	q_word.low |= (buffer->primary   << VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT) & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK;
+	q_word.low |= (buffer->pid       << VIP_MSR_MCR_PID_SHIFT)              & VIP_MSR_MCR_PID_MASK;
+
+	msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_debug_characteristics
+ *
+ * This routine configures the debug data that is exposed over the diag bus.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_debug_characteristics (VIPDEBUGBUFFER *buffer)
+{
+	Q_WORD q_word;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	q_word.low = q_word.high = 0;
+
+	q_word.high |= (buffer->bist << VIP_MSR_DIAG_BIST_SHIFT) & VIP_MSR_DIAG_BIST_WMASK;
+	q_word.low  |= (buffer->enable_upper ? VIP_MSR_DIAG_MSB_ENABLE : 0x00000000);
+	q_word.low  |= (buffer->select_upper << VIP_MSR_DIAG_SEL_UPPER_SHIFT) & VIP_MSR_DIAG_SEL_UPPER_MASK;
+	q_word.low  |= (buffer->enable_lower ? VIP_MSR_DIAG_LSB_ENABLE : 0x00000000 );
+	q_word.low  |= (buffer->select_lower << VIP_MSR_DIAG_SEL_LOWER_SHIFT) & VIP_MSR_DIAG_SEL_LOWER_MASK;
+
+	msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &q_word);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_pages
+ *
+ * This routine sets the number of pages, and their offset from each other.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_pages (int page_count, unsigned long page_offset)
+{
+    unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+	/* SET THE NEW PAGE COUNT */
+
+	vip_control2 &= ~VIP_CONTROL2_PAGECNT_MASK;
+	vip_control2 |= (page_count << VIP_CONTROL2_PAGECNT_SHIFT) & VIP_CONTROL2_PAGECNT_MASK;	
+	
+    /* WRITE THE PAGE OFFSET */
+
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+	WRITE_VIP32 (VIP_PAGE_OFFSET, page_offset);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_interrupt_line
+ *
+ * This routine sets the line at which a line interrupt should be generated.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_interrupt_line (int line)
+{
+	WRITE_VIP32 (VIP_CURRENT_TARGET, (line << VIP_CTARGET_TLINE_SHIFT) & VIP_CTARGET_TLINE_MASK);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_reset
+ *
+ * This routine does a one-shot enable of the VIP hardware.  It is useful
+ * for handling unrecoverable VIP errors.
+ *---------------------------------------------------------------------------*/
+
+int vip_reset (void)
+{
+    unsigned long vip_control1, vip_control3;
+
+    /* INVERT THE PAUSE BIT */
+
+    vip_control1 = READ_VIP32 (VIP_CONTROL1);
+    vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+    WRITE_VIP32 (VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET);
+    WRITE_VIP32 (VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET);
+	WRITE_VIP32 (VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET);
+    	
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_subwindow_enable
+ *
+ * This routine turns on SubWindow capture, that is a portion of the incoming
+ * signal is captured rather than the entire frame. The window always has
+ * the same width as the frame, only the vertical component can be
+ * modified.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_subwindow_enable (VIPSUBWINDOWBUFFER *buffer)
+{
+    unsigned long vip_control2;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+	
+    vip_control2 = READ_VIP32 (VIP_CONTROL2);
+	if (buffer->enable)
+    {
+        /* WRITE THE WINDOW VALUE */
+
+        WRITE_VIP32(VIP_VERTICAL_START_STOP,
+            ((buffer->stop  << VIP_VSTART_VERTEND_SHIFT)   & VIP_VSTART_VERTEND_MASK) |
+            ((buffer->start << VIP_VSTART_VERTSTART_SHIFT) & VIP_VSTART_VERTSTART_MASK));
+
+		/* ENABLE IN THE CONTROL REGISTER */
+
+		vip_control2 |= VIP_CONTROL2_SWC_ENABLE;
+	}
+	else
+    {
+		/* DISABLE SUBWINDOW CAPTURE IN THE CONTROL REGISTER */
+
+		vip_control2 &= ~VIP_CONTROL2_SWC_ENABLE;
+	}
+    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_reset_interrupt_state
+ *
+ * This routine resets the state of one or more interrupts.
+ *---------------------------------------------------------------------------*/
+
+int vip_reset_interrupt_state(unsigned long interrupt_mask)
+{
+	unsigned long temp;
+
+	temp = READ_VIP32(VIP_INTERRUPT);
+    WRITE_VIP32 (VIP_INTERRUPT, temp | (interrupt_mask & VIP_ALL_INTERRUPTS));
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_save_state
+ *
+ * This routine saves the necessary register contents in order to restore
+ * at a later point to the same state.
+ *
+ * NOTE: Capture state is forced to OFF in this routine
+ *---------------------------------------------------------------------------*/
+
+int vip_save_state(VIPSTATEBUFFER *save_buffer)
+{
+	if (!save_buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    /* FORCE CAPTURE TO BE DISABLED */
+    		
+    vip_set_capture_state (VIP_STOPCAPTURE);
+
+	/* READ AND SAVE THE REGISTER CONTENTS */
+
+	save_buffer->control1				= READ_VIP32(VIP_CONTROL1);
+	save_buffer->control2				= READ_VIP32(VIP_CONTROL2);
+    save_buffer->vip_int                = READ_VIP32(VIP_INTERRUPT);
+    save_buffer->current_target		    = READ_VIP32(VIP_CURRENT_TARGET);
+	save_buffer->max_address			= READ_VIP32(VIP_MAX_ADDRESS);
+	save_buffer->taska_evenbase		    = READ_VIP32(VIP_TASKA_VID_EVEN_BASE);
+	save_buffer->taska_oddbase			= READ_VIP32(VIP_TASKA_VID_ODD_BASE);
+	save_buffer->taska_vbi_evenbase		= READ_VIP32(VIP_TASKA_VBI_EVEN_BASE);
+	save_buffer->taska_vbi_oddbase		= READ_VIP32(VIP_TASKA_VBI_ODD_BASE);
+	save_buffer->taska_data_pitch		= READ_VIP32(VIP_TASKA_VID_PITCH);
+    save_buffer->control3               = READ_VIP32(VIP_CONTROL3);
+    save_buffer->taska_v_oddoffset		= READ_VIP32(VIP_TASKA_U_OFFSET);
+	save_buffer->taska_u_oddoffset		= READ_VIP32(VIP_TASKA_V_OFFSET);
+	save_buffer->taskb_evenbase		    = READ_VIP32(VIP_TASKB_VID_EVEN_BASE);
+	save_buffer->taskb_oddbase			= READ_VIP32(VIP_TASKB_VID_ODD_BASE);
+	save_buffer->taskb_vbi_evenbase		= READ_VIP32(VIP_TASKB_VBI_EVEN_BASE);
+	save_buffer->taskb_vbi_oddbase		= READ_VIP32(VIP_TASKB_VBI_ODD_BASE);
+	save_buffer->taskb_pitch		    = READ_VIP32(VIP_TASKB_VID_PITCH);
+	save_buffer->taskb_voffset			= READ_VIP32(VIP_TASKB_U_OFFSET);
+	save_buffer->taskb_uoffset			= READ_VIP32(VIP_TASKB_V_OFFSET);
+	save_buffer->msg1_base			    = READ_VIP32(VIP_ANC_MSG1_BASE);
+	save_buffer->msg2_base			    = READ_VIP32(VIP_ANC_MSG2_BASE);
+	save_buffer->msg_size			    = READ_VIP32(VIP_ANC_MSG_SIZE);
+	save_buffer->page_offset			= READ_VIP32(VIP_PAGE_OFFSET);
+	save_buffer->vert_start_stop	    = READ_VIP32(VIP_VERTICAL_START_STOP);
+	save_buffer->vsync_err_count		= READ_VIP32(VIP_VSYNC_ERR_COUNT);
+    save_buffer->taska_u_evenoffset     = READ_VIP32(VIP_TASKA_U_EVEN_OFFSET);
+    save_buffer->taska_v_evenoffset     = READ_VIP32(VIP_TASKA_V_EVEN_OFFSET);
+	
+    /* READ ALL VIP MSRS */
+
+    msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &(save_buffer->msr_config));
+    msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI,    &(save_buffer->msr_smi));
+    msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM,     &(save_buffer->msr_pm));
+    msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG,   &(save_buffer->msr_diag));
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_restore_state
+ *
+ * This routine restores the state of the vip registers - which were
+ * previously saved using vip_save_state.
+ *---------------------------------------------------------------------------*/
+
+int vip_restore_state (VIPSTATEBUFFER *restore_buffer)
+{
+    if (!restore_buffer)
+        return CIM_STATUS_OK;
+
+	/* RESTORE THE REGISTERS */
+
+	WRITE_VIP32(VIP_CURRENT_TARGET,         restore_buffer->current_target);
+	WRITE_VIP32(VIP_MAX_ADDRESS,            restore_buffer->max_address);
+	WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE,    restore_buffer->taska_evenbase);
+	WRITE_VIP32(VIP_TASKA_VID_ODD_BASE,     restore_buffer->taska_oddbase);
+	WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE,    restore_buffer->taska_vbi_evenbase);
+	WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE,     restore_buffer->taska_vbi_oddbase);
+	WRITE_VIP32(VIP_TASKA_VID_PITCH,        restore_buffer->taska_data_pitch);
+    WRITE_VIP32(VIP_CONTROL3,               restore_buffer->control3);
+	WRITE_VIP32(VIP_TASKA_U_OFFSET,         restore_buffer->taska_v_oddoffset);
+	WRITE_VIP32(VIP_TASKA_V_OFFSET,         restore_buffer->taska_u_oddoffset);
+	WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE,    restore_buffer->taskb_evenbase);
+	WRITE_VIP32(VIP_TASKB_VID_ODD_BASE,     restore_buffer->taskb_oddbase);
+	WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE,    restore_buffer->taskb_vbi_evenbase);
+	WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE,     restore_buffer->taskb_vbi_oddbase);
+	WRITE_VIP32(VIP_TASKB_VID_PITCH,        restore_buffer->taskb_pitch);
+	WRITE_VIP32(VIP_TASKB_U_OFFSET,         restore_buffer->taskb_voffset);
+	WRITE_VIP32(VIP_TASKB_V_OFFSET,         restore_buffer->taskb_uoffset);
+	WRITE_VIP32(VIP_ANC_MSG1_BASE,          restore_buffer->msg1_base);
+	WRITE_VIP32(VIP_ANC_MSG2_BASE,          restore_buffer->msg2_base);
+	WRITE_VIP32(VIP_ANC_MSG_SIZE,           restore_buffer->msg_size);
+	WRITE_VIP32(VIP_PAGE_OFFSET,            restore_buffer->page_offset);
+	WRITE_VIP32(VIP_VERTICAL_START_STOP,    restore_buffer->vert_start_stop);
+	WRITE_VIP32(VIP_VSYNC_ERR_COUNT,        restore_buffer->vsync_err_count);
+    WRITE_VIP32(VIP_TASKA_U_EVEN_OFFSET,    restore_buffer->taska_u_evenoffset);
+    WRITE_VIP32(VIP_TASKA_V_EVEN_OFFSET,    restore_buffer->taska_v_evenoffset);
+	
+    /* RESTORE THE VIP MSRS */
+
+    msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &(restore_buffer->msr_config));
+    msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI,    &(restore_buffer->msr_smi));
+    msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM,     &(restore_buffer->msr_pm));
+    msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG,   &(restore_buffer->msr_diag));
+
+    /* RESTORE THE CONTROL WORDS LAST */
+
+	WRITE_VIP32(VIP_CONTROL1, restore_buffer->control1);
+	WRITE_VIP32(VIP_CONTROL2, restore_buffer->control2);
+    WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_interrupt_state
+ *
+ * This routine returns the current interrupt state of the system. The
+ * rv can be tested with the following flags to determine if the appropriate
+ * event has occured.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_interrupt_state(void)
+{	
+    unsigned long interrupt_mask = READ_VIP32(VIP_INTERRUPT);
+
+    return (~(interrupt_mask << 16) & interrupt_mask & VIP_ALL_INTERRUPTS);
+}
+
+/*---------------------------------------------------------------------------
+ * vip_test_genlock_active
+ *
+ * This routine reads the live status of the genlock connection between the VIP
+ * and VG blocks.
+ *---------------------------------------------------------------------------*/
+
+int vip_test_genlock_active (void)
+{
+    if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_GENLK_ACTIVE)
+        return 1;
+
+    return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_test_signal_status
+ *
+ * This routine reads the live signal status coming into the VIP block.
+ *---------------------------------------------------------------------------*/
+
+int vip_test_signal_status (void)
+{
+    if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_VIP_VID_OK)
+        return 1;
+
+    return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_current_field
+ *
+ * This routine returns the current field being received.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_current_field (void)
+{
+	if (READ_VIP32(VIP_STATUS) & VIP_STATUS_FIELD)
+        return VIP_EVEN_FIELD;
+
+    return VIP_ODD_FIELD;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON VIP READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging.  They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_VIP_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * vip_get_current_mode
+ *
+ * This routine reads the current VIP operating mode.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_current_mode (VIPSETMODEBUFFER *buffer)
+{
+    unsigned long vip_control1, vip_control2, vip_control3;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    vip_control1 = READ_VIP32 (VIP_CONTROL1);
+    vip_control2 = READ_VIP32 (VIP_CONTROL2);
+    vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+    /* READ CURRENT OPERATING MODE AND ENABLES */
+
+    buffer->stream_enables = vip_control1 & VIP_ENABLE_ALL;
+    buffer->operating_mode = vip_control1 & VIP_CONTROL1_MODE_MASK;
+
+    /* READ CURRENT PLANAR CAPTURE SETTINGS */
+
+    buffer->flags = 0;
+    buffer->planar_capture = 0;
+    if (vip_control1 & VIP_CONTROL1_PLANAR)
+    {
+        buffer->flags |= VIP_MODEFLAG_PLANARCAPTURE;
+        if (vip_control1 & VIP_CONTROL1_DISABLE_DECIMATION)
+        {
+            if (vip_control3 & VIP_CONTROL3_DECIMATE_EVEN)
+                buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGFIELDS;
+            else
+                buffer->planar_capture = VIP_420CAPTURE_EVERYLINE;
+        }
+        else
+            buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGLINES;
+    }
+
+    /* READ MISCELLANEOUS FLAGS */
+
+    if (vip_control1 & VIP_CONTROL1_NON_INTERLACED)
+        buffer->flags |= VIP_MODEFLAG_PROGRESSIVE;
+    if (vip_control3 & VIP_CONTROL3_BASE_UPDATE)
+        buffer->flags |= VIP_MODEFLAG_TOGGLEEACHFIELD;
+    if (vip_control2 & VIP_CONTROL2_INVERT_POLARITY)
+        buffer->flags |= VIP_MODEFLAG_INVERTPOLARITY;
+    if (vip_control1 & VIP_CONTROL1_MSG_STRM_CTRL)
+        buffer->flags |= VIP_MODEFLAG_FLIPMESSAGEWHENFULL;
+    if (vip_control2 & VIP_CONTROL2_REPEAT_ENABLE)
+        buffer->flags |= VIP_MODEFLAG_ENABLEREPEATFLAG;
+    if (vip_control3 & VIP_CONTROL3_TASK_POLARITY)
+        buffer->flags |= VIP_MODEFLAG_INVERTTASKPOLARITY;
+    if (vip_control1 & VIP_CONTROL1_DISABLE_ZERO_DETECT)
+        buffer->flags |= VIP_MODEFLAG_DISABLEZERODETECT;
+    if (vip_control2 & VIP_CONTROL2_ANC10)
+        buffer->flags |= VIP_MODEFLAG_10BITANCILLARY;
+
+    /* READ THE CURRENT VIP 601 SETTINGS */
+
+    vip_get_601_configuration (&buffer->vip601_settings);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_601_configuration
+ *
+ * This routine returns the current 601 configuration information.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_601_configuration (VIP_601PARAMS *buffer)
+{
+    unsigned long vip_control3, vip_control1;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    vip_control1 = READ_VIP32 (VIP_CONTROL3);
+    vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+    buffer->flags = 0;
+    if (vip_control3 & VIP_CONTROL3_VSYNC_POLARITY) buffer->flags |= VIP_MODEFLAG_VSYNCACTIVEHIGH;
+    if (vip_control3 & VIP_CONTROL3_HSYNC_POLARITY) buffer->flags |= VIP_MODEFLAG_HSYNCACTIVEHIGH;
+
+    buffer->horz_start          =  READ_VIP32 (VIP_601_HORZ_START);
+    buffer->vbi_start           =  READ_VIP32 (VIP_601_VBI_START);
+    buffer->vbi_height          =  READ_VIP32 (VIP_601_VBI_END) - buffer->vbi_start + 1;
+    buffer->vert_start_even     =  READ_VIP32 (VIP_601_EVEN_START_STOP) & 0xFFFF;
+    buffer->even_height         = (READ_VIP32 (VIP_601_EVEN_START_STOP) >> 16) - buffer->vert_start_even + 1;
+    buffer->vert_start_odd      =  READ_VIP32 (VIP_601_ODD_START_STOP) & 0xFFFF;
+    buffer->odd_height          = (READ_VIP32 (VIP_601_ODD_START_STOP) >> 16) - buffer->vert_start_odd + 1;
+    buffer->odd_detect_start    =  READ_VIP32 (VIP_ODD_FIELD_DETECT) & 0xFFFF;
+    buffer->odd_detect_end      =  READ_VIP32 (VIP_ODD_FIELD_DETECT) >> 16;
+
+    /* SPECIAL CASE FOR HORIZONTAL DATA */
+    /* 601 horizontal parameters are based on the number of clocks and not the */
+    /* number of pixels.                                                       */
+
+    if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601)
+        buffer->width = (READ_VIP32 (VIP_601_HORZ_END) - buffer->horz_start - 3) >> 1;
+    else
+        buffer->width = (READ_VIP32 (VIP_601_HORZ_END) - buffer->horz_start - 3);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_buffer_configuration
+ *
+ * This routine reads the current buffer configuration for Task A, Task B,
+ * ancillary or message data.  The current_buffer member indicates which
+ * array index should hold the new values for Task A or Task B data.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_buffer_configuration (int buffer_type, VIPINPUTBUFFER *buffer)
+{
+    unsigned long cur_buffer = buffer->current_buffer;
+    VIPINPUTBUFFER_ADDR *offsets;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	if (buffer_type == VIP_BUFFER_A)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+        /* READ VIDEO PITCH */
+
+        offsets->y_pitch  = READ_VIP32 (VIP_TASKA_VID_PITCH) & 0xFFFF;
+        offsets->uv_pitch = READ_VIP32 (VIP_TASKA_VID_PITCH) >> 16;
+
+        /* READ BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+        {
+            offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_ODD_BASE);
+            offsets->odd_base[cur_buffer]  = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE);
+
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                offsets->vbi_even_base = READ_VIP32 (VIP_TASKA_VBI_ODD_BASE);
+                offsets->vbi_odd_base  = READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE);
+            }
+        }
+        else
+        {
+            offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE);
+            offsets->odd_base[cur_buffer]  = READ_VIP32 (VIP_TASKA_VID_ODD_BASE);
+
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                offsets->vbi_even_base = READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE);
+                offsets->vbi_odd_base  = READ_VIP32 (VIP_TASKA_VBI_ODD_BASE);
+            }
+        }
+
+        /* READ 4:2:0 OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+        {
+            offsets->odd_uoffset  = READ_VIP32 (VIP_TASKA_U_OFFSET);
+            offsets->odd_voffset  = READ_VIP32 (VIP_TASKA_V_OFFSET);
+            offsets->even_uoffset = READ_VIP32 (VIP_TASKA_U_EVEN_OFFSET);
+            offsets->even_voffset = READ_VIP32 (VIP_TASKA_V_EVEN_OFFSET);
+        }
+    }
+    else if (buffer_type == VIP_BUFFER_B)
+    {
+        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+        /* READ VIDEO PITCH */
+
+        offsets->y_pitch  = READ_VIP32 (VIP_TASKB_VID_PITCH) & 0xFFFF;
+        offsets->uv_pitch = READ_VIP32 (VIP_TASKB_VID_PITCH) >> 16;
+
+        /* READ BASE OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+        {
+            offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_ODD_BASE);
+            offsets->odd_base[cur_buffer]  = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE);
+
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                offsets->vbi_even_base = READ_VIP32 (VIP_TASKB_VBI_ODD_BASE);
+                offsets->vbi_odd_base  = READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE);
+            }
+        }
+        else
+        {
+            offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE);
+            offsets->odd_base[cur_buffer]  = READ_VIP32 (VIP_TASKB_VID_ODD_BASE);
+
+            if (buffer->flags & VIP_INPUTFLAG_VBI)
+            {
+                offsets->vbi_even_base = READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE);
+                offsets->vbi_odd_base  = READ_VIP32 (VIP_TASKB_VBI_ODD_BASE);
+            }
+        }
+
+        /* READ 4:2:0 OFFSETS */
+
+        if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+        {
+            offsets->odd_uoffset = READ_VIP32 (VIP_TASKB_U_OFFSET);
+            offsets->odd_voffset = READ_VIP32 (VIP_TASKB_V_OFFSET);
+        }
+    }
+    else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG)
+    {
+        buffer->ancillaryData.msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE);
+		buffer->ancillaryData.msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE);
+		buffer->ancillaryData.msg_size  = READ_VIP32(VIP_ANC_MSG_SIZE);
+    }
+    else
+    {
+        return CIM_STATUS_INVALIDPARAMS;
+    }
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_genlock_configuration
+ *
+ * This routine reads the current genlock configuration.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_genlock_configuration (VIPGENLOCKBUFFER *buffer)
+{
+	unsigned long vip_control1, vip_control2;
+    unsigned long genlk_ctl;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    genlk_ctl    = READ_REG32 (DC3_GENLK_CTL);
+    vip_control1 = READ_VIP32 (VIP_CONTROL1);
+    vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+    /* READ ERROR DETECTION, CURRENT FIELD AND CURRENT VSYNC */
+    /* These flags are used to indicate the ways in which the VIP signal can */
+    /* be considered 'lost'.                                                 */
+
+    buffer->vip_signal_loss = vip_control1 & VIP_CONTROL1_VDE_FF_MASK;
+    buffer->field_to_vg     = vip_control2 & VIP_CONTROL2_FIELD2VG_MASK;
+    buffer->vsync_to_vg     = vip_control2 & VIP_CONTROL2_SYNC2VG_MASK;
+
+    /* GENLOCK TIMEOUT ENABLE */
+
+    buffer->enable_timeout = 0;
+    if (genlk_ctl & DC3_GC_GENLOCK_TO_ENABLE)
+        buffer->enable_timeout = 1;
+
+    /* GENLOCK SKEW */
+
+    buffer->genlock_skew = genlk_ctl & DC3_GC_GENLOCK_SKEW_MASK;
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_genlock_enable
+ *
+ * This routine returns the current enable status of genlock in the VG.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_genlock_enable (void)
+{
+    if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_GENLOCK_ENABLE)
+        return 1;
+
+    return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_is_buffer_update_latched
+ *
+ * This routine indicates whether changes to the VIP offsets have been latched by
+ * the hardware.
+ *---------------------------------------------------------------------------*/
+
+int vip_is_buffer_update_latched (void)
+{
+	return (!(READ_VIP32(VIP_STATUS) & VIP_STATUS_BASEREG_NOTUPDT));
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_capture_state
+ *
+ * This routine reads the current capture status of the VIP hardware.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_capture_state (void)
+{
+	return ((READ_VIP32(VIP_CONTROL1) & VIP_CONTROL1_RUNMODE_MASK) >> VIP_CONTROL1_RUNMODE_SHIFT);
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_current_line
+ *
+ * This routine returns the current line that is being processed.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_current_line (void)
+{
+	return (READ_VIP32(VIP_CURRENT_TARGET) & VIP_CTARGET_CLINE_MASK);
+}
+
+/*---------------------------------------------------------------------------
+ * vip_read_fifo
+ *
+ * This routine reads from the specified fifo address. As the fifo access
+ * enable should be disabled when running in normal vip mode, this routine
+ * enables and disables access around the read.
+ * DIAGNOSTIC USE ONLY
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_read_fifo(unsigned long dwFifoAddress)
+{
+    unsigned long fifo_data;
+
+	/* ENABLE FIFO ACCESS */
+
+	vip_enable_fifo_access (1);
+
+	/* NOW READ THE DATA */
+
+	WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
+    fifo_data = READ_VIP32(VIP_FIFO_DATA);
+
+	/* DISABLE FIFO ACCESS */
+
+	vip_enable_fifo_access (0);
+
+	return fifo_data;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_write_fifo
+ *
+ * SYNOPSIS:
+ * This routine writes to the specified fifo address. As the fifo access
+ * enable should be disabled when running in normal vip mode, this routine
+ * enables and disables access around the write.
+ * DIAGNOSTIC USE ONLY
+ *---------------------------------------------------------------------------*/
+
+int vip_write_fifo (unsigned long dwFifoAddress, unsigned long dwFifoData)
+{
+	/* ENABLE FIFO ACCESS */
+
+	vip_enable_fifo_access(1);
+
+	/* WRITE THE FIFO DATA */
+
+	WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
+	WRITE_VIP32(VIP_FIFO_DATA, dwFifoData);
+
+	/* DISABLE FIFO ACCESS */
+
+	vip_enable_fifo_access(0);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_enable_fifo_access
+ *
+ * This routine enables/disables access to the vip fifo.
+ * DIAGNOSTIC USE ONLY
+ *---------------------------------------------------------------------------*/
+
+int vip_enable_fifo_access (int enable)
+{
+	unsigned long cw2;
+	
+	cw2 = READ_VIP32(VIP_CONTROL2);
+	
+	if (enable) cw2 |=  VIP_CONTROL2_FIFO_ACCESS;
+	else         cw2 &= ~VIP_CONTROL2_FIFO_ACCESS;
+	
+	WRITE_VIP32(VIP_CONTROL2, cw2);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_power_characteristics
+ *
+ * This routine returns the current VIP clock gating state in a VIPPOWERBUFFER.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_power_characteristics(VIPPOWERBUFFER *buffer)
+{
+	Q_WORD	q_word;
+	
+	if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	/* READ THE EXISTING STATE */
+		
+    msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
+
+    /* DECODE THE CLOCK GATING BITS */
+		
+	buffer->glink_clock_mode = (int)(q_word.low & VIP_MSR_POWER_GLINK);
+	buffer->vip_clock_mode	 = (int)(q_word.low & VIP_MSR_POWER_CLOCK);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_priority_characteristics
+ *
+ * This routine returns the priority characteristics in the supplied
+ * VIPPRIORITYBUFFER.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_priority_characteristics(VIPPRIORITYBUFFER *buffer)
+{
+	Q_WORD	q_word;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	/* READ THE CURRENT STATE */
+
+	msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
+
+	/* DECODE THE PRIORITIES */
+
+	buffer->secondary	= (q_word.low & VIP_MSR_MCR_SECOND_PRIORITY_MASK) >> VIP_MSR_MCR_SECOND_PRIORITY_SHIFT;
+	buffer->primary		= (q_word.low & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK) >> VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT;
+	buffer->pid			=  q_word.low & VIP_MSR_MCR_PID_MASK;
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_capability_characteristics
+ *
+ * This routine returns revision information for the device.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_capability_characteristics(VIPCAPABILITIESBUFFER *buffer)
+{
+    Q_WORD q_word ;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	/* READ THE CURRENT MSR CONTENTS */
+
+	msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CAP, &q_word);
+	
+    /* DECODE THE REVISIONS */
+
+	buffer->revision_id     = (q_word.low & VIP_MSR_CAP_REVID_MASK) >> VIP_MSR_CAP_REVID_SHIFT;
+	buffer->device_id       = (q_word.low & VIP_MSR_CAP_DEVID_MASK) >> VIP_MSR_CAP_DEVID_SHIFT;
+	buffer->n_clock_domains = (q_word.low & VIP_MSR_CAP_NCLK_MASK)  >> VIP_MSR_CAP_NCLK_SHIFT;
+	buffer->n_smi_registers = (q_word.low & VIP_MSR_CAP_NSMI_MASK)  >> VIP_MSR_CAP_NSMI_SHIFT;
+	
+	return CIM_STATUS_OK;
+}
+
+
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_vop.c xf86-video-nsc-2.8.1/src/cim/cim_vop.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_vop.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_vop.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,564 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Cimarron VOP configuration routines.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*---------------------------------------------------------------------------
+ * vop_set_vbi_window
+ *
+ * This routine configures the output position and location in memory of
+ * VBI data.
+ *---------------------------------------------------------------------------*/
+
+int vop_set_vbi_window (VOPVBIWINDOWBUFFER *buffer)
+{
+    unsigned long unlock, temp;
+    unsigned long hstart, hstop;
+    unsigned long htotal, hsyncstart;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;	
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+    /* PROGRAM HORIZONTAL POSITION */
+    /* The horizontal position is a little tricky.  The counter for the horizontal    */
+    /* timings is reused for the VBI counter.  Consequently, the horizontal start     */
+    /* and stop values are based off the beginning of active data.  However, the      */
+    /* VG has a quirk.  If the counter start position is before the beginning of      */
+    /* HSync, it applies to the previous line.  If the counter is after the           */
+    /* beginning of HSync it applies to the current line.  So, for one line           */
+    /* the real range can be thought of as HSync_start to (HSync_start + htotal - 1). */
+    /* However, the counters must be between 0 and htotal - 1.  When placing VBI      */
+    /* data before the start of active data, the horizontal end position will thus    */
+    /* be *less* than the horizontal start.                                           */
+
+    htotal     = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+    hsyncstart =  (READ_REG32 (DC3_H_SYNC_TIMING) & 0xFFF) + 1;
+
+    if (buffer->horz_from_hsync)
+    {
+        /* VERIFY THAT THE INPUT IS VALID */
+
+        if (buffer->horz_start < 0 || (buffer->horz_start + buffer->vbi_width) > htotal)
+            return CIM_STATUS_INVALIDPARAMS;
+
+        hstart = buffer->horz_start + hsyncstart;
+    }
+    else
+    {
+        /* VERIFY THAT THE INPUT IS VALID */
+
+        if (buffer->horz_start < ((long)hsyncstart - (long)htotal) ||
+            buffer->horz_start > (long)hsyncstart ||
+            buffer->vbi_width > htotal)
+        {
+            return CIM_STATUS_INVALIDPARAMS;
+        }
+
+        hstart = buffer->horz_start + htotal;
+    }
+
+    hstop = hstart + buffer->vbi_width;
+    if (hstart > htotal) hstart -= htotal;
+    if (hstop  > htotal) hstop  -= htotal;
+    hstart--;
+    hstop--;
+	WRITE_REG32 (DC3_VBI_HOR, ((hstop << DC3_VBI_HOR_END_SHIFT) & DC3_VBI_HOR_END_MASK) |
+        (hstart & DC3_VBI_HOR_START_MASK));
+	
+    /* WRITE LINE CAPTURE MASKS */
+
+	WRITE_REG32 (DC3_VBI_LN_ODD, ((buffer->odd_line_offset << DC3_VBI_ODD_LINE_SHIFT) & DC3_VBI_ODD_LINE_MASK) |
+        (buffer->odd_line_capture_mask & DC3_VBI_ODD_ENABLE_MASK));
+
+    WRITE_REG32 (DC3_VBI_LN_EVEN, ((buffer->even_line_offset << DC3_VBI_EVEN_LINE_SHIFT) & DC3_VBI_EVEN_LINE_MASK) |
+        (buffer->even_line_capture_mask & DC3_VBI_EVEN_ENABLE_MASK));
+
+	/* PROGRAM SOURCE OFFSETS */
+    /* Start with the even offsets.  Note that we always enable 16-bit VBI, as this */
+    /* is the only way to get VBI data on each VOP clock.                           */
+
+	temp  = READ_REG32 (DC3_VBI_EVEN_CTL) & ~DC3_VBI_EVEN_CTL_OFFSET_MASK;
+    temp |= DC3_VBI_EVEN_CTL_ENABLE_16;
+    if (buffer->enable_upscale)
+        temp |= DC3_VBI_EVEN_CTL_UPSCALE;
+	WRITE_REG32 (DC3_VBI_EVEN_CTL, temp | (buffer->even_address_offset & DC3_VBI_EVEN_CTL_OFFSET_MASK));
+	
+    /* ODD OFFSET */
+
+	temp = READ_REG32 (DC3_VBI_ODD_CTL) & ~DC3_VBI_ODD_CTL_OFFSET_MASK;
+	WRITE_REG32 (DC3_VBI_ODD_CTL, temp | (buffer->odd_address_offset & DC3_VBI_ODD_CTL_OFFSET_MASK));
+	
+    /* PITCH */
+
+	temp = ((buffer->data_size >> 3) << 16) | ((buffer->data_pitch >> 3) & 0x0000FFFF);
+	WRITE_REG32(DC3_VBI_PITCH, temp);
+	
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_enable_vbi_output
+ *
+ * This routine enables/disables VBI fetching inside the video generator.
+ *---------------------------------------------------------------------------*/
+
+int vop_enable_vbi_output (int enable)
+{
+	unsigned long unlock, temp;
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    temp   = READ_REG32 (DC3_VBI_EVEN_CTL);
+
+	if (enable) temp |=  DC3_VBI_ENABLE;
+	else        temp &= ~DC3_VBI_ENABLE;
+	
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_VBI_EVEN_CTL, temp);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+
+    return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_set_configuration
+ *
+ * This routine is passed a VOP_CONFIGURATION structure that contains all
+ * the necessary information to configure VOP output.
+ *---------------------------------------------------------------------------*/
+
+int vop_set_configuration (VOPCONFIGURATIONBUFFER *config)
+{
+    unsigned long vop_config = 0;
+    unsigned long alpha, control2;
+    unsigned long unlock;
+    unsigned long delta;
+    Q_WORD msr_value;
+    int rgb = 0;
+		
+    if (!config)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+    delta  = READ_REG32 (DC3_VID_DS_DELTA) & DC3_DS_DELTA_MASK;
+
+    /* OVERRIDE THE OUTPUT SETTINGS TO ENABLE VOP OUTPUT */
+
+    if (config->mode != VOP_MODE_DISABLED)
+    {
+        msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+        msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+        msr_value.low |=  DF_OUTPUT_VOP;
+        msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+    }
+
+	/* SET THE UNIVERSAL VOP OPTIONS */
+
+    if (config->flags & VOP_FLAG_SWAP_UV)   vop_config |= VOP_CONFIG_SWAPUV;
+    if (config->flags & VOP_FLAG_SWAP_VBI)  vop_config |= VOP_CONFIG_SWAPVBI;
+
+    /* SET THE MODE SPECIFIC PARAMETERS */
+
+    if (config->mode == VOP_MODE_601)
+    {
+        vop_config |= config->vop601.flags;
+        vop_config |= config->vop601.vsync_shift;
+        vop_config |= VOP_CONFIG_ENABLE_601 | VOP_CONFIG_VIP2_0;
+
+        switch (config->vop601.output_mode)
+        {
+            case VOP_601_YUV_16BIT:
+                vop_config |= VOP_CONFIG_VIP2_16BIT;
+                break;
+            case VOP_601_YUV_4_4_4:
+                vop_config |= VOP_CONFIG_DISABLE_DECIMATE;
+                break;
+            case VOP_601_RGB_8_8_8:
+                vop_config |= VOP_CONFIG_DISABLE_DECIMATE | VOP_CONFIG_RGBMODE;
+                rgb = 1;
+                break;
+        }
+
+        if (config->vop601.vsync_shift == VOP_VSYNC_LATER_BY_X)
+        {
+            delta |= (config->vop601.vsync_shift_count & DC3_601_VSYNC_SHIFT_MASK);
+            delta |= DC3_601_VSYNC_SHIFT_ENABLE;
+        }
+    }
+    else
+    {
+        if (config->flags & VOP_FLAG_VBI)               vop_config |= VOP_CONFIG_VBI;
+	    if (config->flags & VOP_FLAG_TASK)              vop_config |= VOP_CONFIG_TASK;
+        if (config->flags & VOP_FLAG_SINGLECHIPCOMPAT)  vop_config |= VOP_CONFIG_SC_COMPATIBLE;
+	    if (config->flags & VOP_FLAG_EXTENDEDSAV)       vop_config |= VOP_CONFIG_EXTENDED_SAV;
+
+        switch (config->mode)
+        {
+            case VOP_MODE_DISABLED:
+                vop_config |= VOP_CONFIG_DISABLED;
+                break;
+            case VOP_MODE_VIP11:
+                vop_config |= VOP_CONFIG_VIP1_1;
+                break;
+            case VOP_MODE_CCIR656:
+                vop_config |= VOP_CONFIG_CCIR656;
+                break;
+            case VOP_MODE_VIP20_8BIT:
+                vop_config |= VOP_CONFIG_VIP2_0;
+                break;
+            case VOP_MODE_VIP20_16BIT:
+                vop_config |= VOP_CONFIG_VIP2_0 | VOP_CONFIG_VIP2_16BIT;
+                break;
+        }
+    }
+
+    /* SET THE 4:4:4 TO 4:2:2 DECIMATION ALGORITHM */
+
+	vop_config |= (config->conversion_mode);
+	
+    /* SET THE VSYNC OUT OPTIONS */
+
+    control2  = READ_VIP32 (VIP_CONTROL2) & ~VIP_CONTROL2_SYNC2PIN_MASK;
+    control2 |= config->vsync_out;
+    WRITE_VIP32 (VIP_CONTROL2, control2);
+
+    /* FORCE THE CORRECT VOP COLOR SPACE */
+    /* The output of the mixer will be either RGB or YUV.  We must enable */
+    /* or disable the VOP CSC based on the desired output format.         */
+
+    alpha = READ_VID32 (DF_VID_ALPHA_CONTROL);
+    if (!(alpha & DF_CSC_GRAPHICS_RGB_TO_YUV))
+    {
+        /* RGB OUTPUT FROM THE MIXER */
+
+        if (!rgb) alpha |=  DF_CSC_VOP_RGB_TO_YUV;
+        else      alpha &= ~DF_CSC_VOP_RGB_TO_YUV;
+    }
+    else
+    {
+        /* YUV OUTPUT FROM THE MIXER */
+        /* As there is no YUV->RGB VOP conversion, we simply disable the */
+        /* VOP CSC and trust that the user is competent.                 */
+
+        alpha &= ~DF_CSC_VOP_RGB_TO_YUV;
+    }
+
+	/* AND WRITE THE CONFIGURATION */
+
+    WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha);
+	WRITE_VOP32(VOP_CONFIGURATION, vop_config);
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_VID_DS_DELTA, delta);
+    WRITE_REG32 (DC3_UNLOCK, unlock);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_save_state
+ *
+ * This routine saves the necessary register contents in order to restore
+ * at a later point to the same state.  Note that the capture state is
+ * forced to OFF in this routine.
+ *---------------------------------------------------------------------------*/
+
+int vop_save_state (VOPSTATEBUFFER *save_buffer)
+{
+    if (!save_buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	save_buffer->config = READ_VOP32(VOP_CONFIGURATION);
+	
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_restore_state
+ *
+ * This routine restores the state of the vop registers - which were
+ * previously saved using vop_save_state.
+ *---------------------------------------------------------------------------*/
+
+int vop_restore_state (VOPSTATEBUFFER *restore_buffer)
+{
+	if (!restore_buffer)
+        return CIM_STATUS_INVALIDPARAMS;
+
+	WRITE_VOP32(VOP_CONFIGURATION, restore_buffer->config);
+	
+	return CIM_STATUS_OK;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON VOP READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging.  They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_VOP_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * vop_get_current_mode
+ *
+ * This routine reads the current VIP operating mode and stores it in the
+ * passed VOP_CONFIGURATION structure.
+ *---------------------------------------------------------------------------*/
+
+int vop_get_current_mode (VOPCONFIGURATIONBUFFER *config)
+{
+    unsigned long vop_config = 0;
+    unsigned long alpha;
+		
+    if (!config)
+        return CIM_STATUS_INVALIDPARAMS;
+
+    vop_config = READ_VOP32 (VOP_CONFIGURATION);
+    alpha = READ_VID32 (DF_VID_ALPHA_CONTROL);
+
+    /* READ THE CURRENT MODE */
+
+    switch (vop_config & VOP_CONFIG_MODE_MASK)
+    {
+        case VOP_CONFIG_DISABLED: config->mode = VOP_MODE_DISABLED; break;
+        case VOP_CONFIG_VIP1_1:   config->mode = VOP_MODE_VIP11;    break;
+        case VOP_CONFIG_CCIR656:  config->mode = VOP_MODE_CCIR656;  break;
+        case VOP_CONFIG_VIP2_0:
+
+            if (vop_config & VOP_CONFIG_ENABLE_601)
+                config->mode = VOP_MODE_601;
+            else if (vop_config & VOP_CONFIG_VIP2_16BIT)
+                config->mode = VOP_MODE_VIP20_16BIT;
+            else
+                config->mode = VOP_MODE_VIP20_8BIT;
+            break;
+    }
+
+    /* READ 601 SETTINGS */
+
+    config->vop601.flags = vop_config & (VOP_CONFIG_INVERT_DISPE |
+        VOP_CONFIG_INVERT_HSYNC | VOP_CONFIG_INVERT_VSYNC);
+
+    config->vop601.vsync_shift = vop_config & VOP_CONFIG_VSYNC_MASK;
+    config->vop601.vsync_shift_count = READ_REG32 (DC3_VID_DS_DELTA) & DC3_601_VSYNC_SHIFT_MASK;
+
+    if ((alpha & DF_CSC_GRAPHICS_RGB_TO_YUV) ||
+        (alpha & DF_CSC_VOP_RGB_TO_YUV))
+    {
+        /* YUV OUTPUT */
+
+        if (vop_config & VOP_CONFIG_DISABLE_DECIMATE)
+            config->vop601.output_mode = VOP_601_YUV_4_4_4;
+        else if (vop_config & VOP_CONFIG_VIP2_16BIT)
+            config->vop601.output_mode = VOP_601_YUV_16BIT;
+        else
+            config->vop601.output_mode = VOP_601_YUV_8BIT;
+    }
+    else
+    {
+        config->vop601.output_mode = VOP_601_RGB_8_8_8;
+    }
+
+    config->flags = 0;
+
+    /* READ THE UNIVERSAL VOP OPTIONS */
+
+    if (vop_config & VOP_CONFIG_SWAPUV)         config->flags |= VOP_FLAG_SWAP_UV;
+    if (vop_config & VOP_CONFIG_SWAPVBI)        config->flags |= VOP_FLAG_SWAP_VBI;
+    if (vop_config & VOP_CONFIG_VBI)            config->flags |= VOP_FLAG_VBI;
+    if (vop_config & VOP_CONFIG_TASK)           config->flags |= VOP_FLAG_TASK;
+    if (vop_config & VOP_CONFIG_SC_COMPATIBLE)  config->flags |= VOP_FLAG_SINGLECHIPCOMPAT;
+    if (vop_config & VOP_CONFIG_EXTENDED_SAV)   config->flags |= VOP_FLAG_EXTENDEDSAV;
+
+    config->conversion_mode = vop_config & VOP_CONFIG_422_MASK;
+
+    config->vsync_out = READ_VIP32 (VIP_CONTROL2) & VIP_CONTROL2_SYNC2PIN_MASK;
+		
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_get_vbi_window
+ *
+ * This routine reads the current VBI configuration for VOP output.
+ *---------------------------------------------------------------------------*/
+
+int vop_get_vbi_configuration (VOPVBIWINDOWBUFFER *buffer)
+{
+    unsigned long temp;
+    unsigned long hstart, hstop;
+    unsigned long htotal, hsyncstart;
+
+    if (!buffer)
+        return CIM_STATUS_INVALIDPARAMS;	
+
+    htotal     = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+    hsyncstart =  (READ_REG32 (DC3_H_SYNC_TIMING) & 0xFFF) + 1;
+
+    /* DECODE HORIZONTAL POSITION */
+    /* This is done according to the requested horizontal origin */
+
+    temp = READ_REG32 (DC3_VBI_HOR);
+    hstart =  (temp & DC3_VBI_HOR_START_MASK) + 1;
+    hstop  = ((temp & DC3_VBI_HOR_END_MASK) >> DC3_VBI_HOR_END_SHIFT) + 1;
+    if (buffer->horz_from_hsync)
+    {
+        buffer->horz_start = hstart + htotal - hsyncstart;
+        if (buffer->horz_start >= (long)htotal)
+            buffer->horz_start -= htotal;
+    }
+    else
+    {
+        if (hstart > hsyncstart)
+            buffer->horz_start = (long)hstart - (long)htotal;
+        else
+            buffer->horz_start = hstart;
+    }
+
+    if (hstop > hstart)
+        buffer->vbi_width = hstop - hstart;
+    else
+        buffer->vbi_width = (htotal - hstart) + hstop;
+
+    /* READ LINE MASKS */
+
+	temp = READ_REG32 (DC3_VBI_LN_ODD);
+    buffer->odd_line_offset = (temp & DC3_VBI_ODD_LINE_MASK) >> DC3_VBI_ODD_LINE_SHIFT;
+    buffer->odd_line_capture_mask = (temp & DC3_VBI_ODD_ENABLE_MASK);
+
+    temp = READ_REG32 (DC3_VBI_LN_EVEN);
+    buffer->even_line_offset = (temp & DC3_VBI_EVEN_LINE_MASK) >> DC3_VBI_EVEN_LINE_SHIFT;
+    buffer->even_line_capture_mask = (temp & DC3_VBI_EVEN_ENABLE_MASK);
+
+    /* READ VBI UPSCALE SETTINGS */	
+
+    buffer->enable_upscale = 0;
+	temp  = READ_REG32 (DC3_VBI_EVEN_CTL);
+    if (temp & DC3_VBI_EVEN_CTL_UPSCALE)
+        buffer->enable_upscale = 1;
+
+    /* READ SOURCE OFFSETS */
+
+    buffer->even_address_offset = temp & DC3_VBI_EVEN_CTL_OFFSET_MASK;
+	buffer->odd_address_offset  = READ_REG32 (DC3_VBI_ODD_CTL) & DC3_VBI_ODD_CTL_OFFSET_MASK;
+	
+    /* PITCH AND SIZE */
+
+    temp = READ_REG32 (DC3_VBI_PITCH);
+    buffer->data_size  = (temp >> 16) << 3;
+    buffer->data_pitch = (temp & 0xFFFF);
+
+	return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_get_vbi_enable
+ *
+ * This routine reads the current enable status of VBI output.
+ *---------------------------------------------------------------------------*/
+
+int vop_get_vbi_enable (void)
+{
+    if (READ_REG32 (DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE)
+        return 1;
+
+    return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_get_crc
+ *
+ * This routine returns a CRC of the current VOP data
+ ---------------------------------------------------------------------------*/
+
+unsigned long vop_get_crc(void)
+{
+	unsigned long crc;
+	unsigned long config = READ_VOP32(VOP_CONFIGURATION);
+    unsigned long timeout = 1000;
+
+	if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+		return 0xFFFFFFFF;
+
+	/* RESET CRC */
+
+	WRITE_VOP32 (VOP_CONFIGURATION, config & ~VOP_CONFIG_ENABLE_SIGNATURE);
+
+    /* WAIT FOR THE RESET TO BE LATCHED */
+
+    while ((READ_VOP32 (VOP_SIGNATURE) != 0x00000001) && timeout)
+        timeout--;
+
+    WRITE_VOP32 (VOP_CONFIGURATION, config |  VOP_CONFIG_ENABLE_SIGNATURE);
+
+	/* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
+	
+    while (!(READ_VOP32 (VOP_CONFIGURATION) & VOP_CONFIG_SIGVAL))
+        ;
+	
+	crc = READ_VOP32 (VOP_SIGNATURE);
+	
+	return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_read_vbi_crc
+ *
+ * This routine returns a CRC of the current VBI data
+ ---------------------------------------------------------------------------*/
+
+unsigned long vop_read_vbi_crc(void)
+{
+    unsigned long gcfg, unlock, vbi_even;
+	unsigned long crc;
+
+	if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN) ||
+        !(READ_REG32 (DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE))
+    {
+		return 0xFFFFFFFF;
+    }	
+
+	unlock   = READ_REG32 (DC3_UNLOCK);
+	gcfg     = READ_REG32 (DC3_GENERAL_CFG);
+    vbi_even = READ_REG32 (DC3_VBI_EVEN_CTL);
+
+	gcfg |=   DC3_GCFG_SGRE | DC3_GCFG_CRC_MODE;
+	gcfg &= ~(DC3_GCFG_SGFR | DC3_GCFG_SIG_SEL);
+    vbi_even |= DC3_VBI_EVEN_ENABLE_CRC;
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_VBI_EVEN_CTL, vbi_even);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg & ~DC3_GCFG_SIGE);
+    WRITE_REG32 (DC3_GENERAL_CFG, gcfg |  DC3_GCFG_SIGE);
+
+	/* WAIT FOR THE CRC TO BE COMPLETED */
+
+	while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_SIGC))
+		;
+
+	/* READ THE COMPLETED CRC */
+
+	crc = READ_REG32 (DC3_PAL_DATA);
+
+	/* RESTORE THE PALETTE SETTINGS */
+
+	gcfg &= ~DC3_GCFG_SGRE;
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return crc;
+}
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cimarron.c xf86-video-nsc-2.8.1/src/cim/cimarron.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cimarron.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cimarron.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,222 @@
+ /*
+  * <LIC_AMD_STD>
+  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  *
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  *
+  * <DOC_AMD_STD>
+  * Base include file for the Cimarron library. This file should be modified
+  * and included in any Cimarron-based project.
+  * </DOC_AMD_STD>
+  *
+  */
+
+/*----------------------------------------------------------------------*/
+/* MODULE SETTINGS                                                      */
+/* The following #defines affect which modules are included in the      */
+/* project.                                                             */
+/*----------------------------------------------------------------------*/
+
+#define CIMARRON_INCLUDE_GP                1
+#define CIMARRON_INCLUDE_VG                1
+#define CIMARRON_INCLUDE_VIP               1
+#define CIMARRON_INCLUDE_VOP               1
+#define CIMARRON_INCLUDE_VIDEO             1
+#define CIMARRON_INCLUDE_INIT              1
+
+#define CIMARRON_INCLUDE_VG_READ_ROUTINES  1
+#define CIMARRON_INCLUDE_DF_READ_ROUTINES  1
+#define CIMARRON_INCLUDE_VIP_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_VOP_READ_ROUTINES 1
+
+/*----------------------------------------------------------------------*/
+/* HARDWARE ACCESS SETTINGS                                             */
+/* The following #defines affect how the Cimarron macros access the     */
+/* hardware.  The hardware access macros are broken up into groups.     */
+/* Each group includes an enabling #define as well as several #define   */
+/* options that modify the macro configuration that is included.        */
+/* If the enabling define is deleted or all options are set to 0, the   */
+/* corresponding macros must be implemented by the user.   The          */
+/* combinations are explained as follows:                               */
+/* must be manually defined by the user. This allows a user to use the  */
+/* cim_defs.h file for only those macros that suit the needs of his/her */
+/* project.  For example, a user may need custom implementations of the */
+/* I/O and MSR macros, but may still want to use the default macros to  */
+/* read and write hardware registers. The combinations are explained as */
+/* follows:                                                             */
+/*                                                                      */
+/* Register Group:                                                      */
+/*   Disabling define:                                                  */
+/*       CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS                        */
+/*          Define this setting to exclude the register access macros.  */
+/*          This setting is the inverse of the other group settings in  */
+/*          that these macros are included by default.  This allows the */
+/*          cim_defs.h file to be included outside of cimarron.c for    */
+/*          basic operations.                                           */
+/*                                                                      */
+/* Memory Group:                                                        */
+/*   Enabling define:                                                   */
+/*       CIMARRON_INCLUDE_STRING_MACROS                                 */
+/*   Options:                                                           */
+/*       CIMARRON_OPTIMIZE_ASSEMBLY                                     */
+/*           Set to 1 to allow the use of inline assembly when writing  */
+/*           large chunks of data to memory.  Essentially, this allows  */
+/*           a rep movsd in place of a slower C for-loop.               */
+/*      CIMARRON_OPTIMIZE_FORLOOP                                       */
+/*           Define for C only data writes.                             */
+/*                                                                      */
+/* MSR Group:                                                           */
+/*   Enabling define:                                                   */
+/*      CIMARRON_INCLUDE_MSR_MACROS                                     */
+/*   Options:                                                           */
+/*      CIMARRON_MSR_DIRECT_ASM                                         */
+/*          Set to 1 to allow the use of the rdmsr and wrmsr opcodes in */
+/*          inline assembly.                                            */
+/*      CIMARRON_MSR_VSA_IO                                             */
+/*          Set to 1 to access MSRs using a VSAII virtual register.     */
+/*      CIMARRON_MSR_KERNEL_ROUTINE                                     */
+/*          Set to 1 to access MSRs using a wrapper routine in the      */
+/*          Linux kernel.                                               */
+/*                                                                      */
+/* IO Group:                                                            */
+/*   Enabling define:                                                   */
+/*      CIMARRON_INCLUDE_IO_MACROS                                      */
+/*   Options:                                                           */
+/*      CIMARRON_IO_DIRECT_ACCESS                                       */
+/*          Set to 1 to perform IO accesses using inline assembly.      */
+/*      CIMARRON_IO_ABSTRACTED_ASM                                      */
+/*          Set to 1 to perform IO using abstracted IO in Linux.        */
+/*                                                                      */
+/* Custom Group:                                                        */
+/*    Disabling define:                                                 */
+/*      CIMARRON_EXCLUDE_CUSTOM_MACROS                                  */
+/*          By default, the custom macros (the macros used by           */
+/*          gp_custom_convert_blt) are mapped to the normal command     */
+/*          string macros.  Setting this to 1 allows the user to        */
+/*          create a custom implementation.                             */
+/*----------------------------------------------------------------------*/
+
+/* UNCOMMENT THE FOLLOWING LINE TO EXCLUDE BASIC REGISTER ACCESS MACROS */
+
+/* #define CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS */
+
+#define CIMARRON_INCLUDE_STRING_MACROS
+#define CIMARRON_OPTIMIZE_ASSEMBLY         1
+#define CIMARRON_OPTIMIZE_FORLOOP          0
+#define CIMARRON_OPTIMIZE_ABSTRACTED_ASM   0
+
+#define CIMARRON_INCLUDE_MSR_MACROS
+#define CIMARRON_MSR_DIRECT_ASM            0
+#define CIMARRON_MSR_VSA_IO                1
+#define CIMARRON_MSR_ABSTRACTED_ASM        0
+#define CIMARRON_MSR_KERNEL_ROUTINE        0
+
+#define CIMARRON_INCLUDE_IO_MACROS
+#define CIMARRON_IO_DIRECT_ACCESS          1
+#define CIMARRON_IO_ABSTRACTED_ASM         0
+
+/* UNCOMMENT THE FOLLOWING LINE TO IMPLEMENT CUSTOM MACROS FOR GP_CUSTOM_CONVERT_BLT */
+
+/* #define CIMARRON_EXCLUDE_CUSTOM_MACROS */
+
+/*----------------------------------------------------------------------*/
+/* MODULE VARIABLES                                                     */
+/* The following #defines affect how global variables in each Cimarron  */
+/* module are defined.  These variables can be made static (to prevent  */
+/* naming conflicts) or they can be defined without the static keyword  */
+/* (to allow extern references).                                        */
+/*----------------------------------------------------------------------*/
+
+#if 1
+#define CIMARRON_STATIC static
+#else
+#define CIMARRON_STATIC
+#endif
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON GLOBAL VARIABLES                                            */
+/* These globals are used by the hardware access macros.  They must be  */
+/* initialized by the application to point to the memory-mapped         */
+/* registers of their respective blocks.                                */
+/*----------------------------------------------------------------------*/
+
+unsigned char *cim_gp_ptr         = (unsigned char *)0;
+unsigned char *cim_fb_ptr         = (unsigned char *)0;
+unsigned char *cim_cmd_base_ptr   = (unsigned char *)0;
+unsigned char *cim_cmd_ptr        = (unsigned char *)0;
+unsigned char *cim_vid_ptr        = (unsigned char *)0;
+unsigned char *cim_vip_ptr        = (unsigned char *)0;
+unsigned char *cim_vg_ptr         = (unsigned char *)0;
+
+/*----------------------------------------------------------------------*/
+/* INCLUDE RELEVANT CIMARRON HEADERS                                    */
+/*----------------------------------------------------------------------*/
+
+/* HARDWARE REGISTER DEFINITIONS */
+
+#include "cim_regs.h"
+
+/* ROUTINE DEFINITIONS */
+/* All routines have a prototype, even those that are not included    */
+/* via #ifdefs.  This prevents the user from having to include the    */
+/* correct #defines anywhere he/she wants to call a Cimarron routine. */
+
+#include "cim_rtns.h"
+
+/* HARDWARE ACCESS MACROS */
+
+#include "cim_defs.h"
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON MODULES                                                     */
+/* Modules and sub-modules are included based on user settings.  Note   */
+/* that excluding one or more modules may result in functionality       */
+/* holes.                                                               */
+/*----------------------------------------------------------------------*/
+
+/* GRAPHICS PROCESSOR */
+
+#if CIMARRON_INCLUDE_GP
+#include "cim_gp.c"
+#endif
+
+/* VIDEO GENERATOR */
+
+#if CIMARRON_INCLUDE_VG
+#include "cim_modes.c"
+#include "cim_vg.c"
+#endif
+
+/* DISPLAY FILTER */
+
+#if CIMARRON_INCLUDE_VIDEO
+#include "cim_filter.c"
+#include "cim_df.c"
+#endif
+
+/* INITIALIZATION AND DETECTION */
+
+#if CIMARRON_INCLUDE_INIT
+#include "cim_init.c"
+#endif
+
+/* VIP SUPPORT */
+
+#if CIMARRON_INCLUDE_VIP
+#include "cim_vip.c"
+#endif
+
+/* VOP SUPPORT */
+
+#if CIMARRON_INCLUDE_VOP
+#include "cim_vop.c"
+#endif
+
+/* MSR ACCESS */
+/* This module is used to access machine-specific registers. */
+/* It cannot be excluded from a project.                     */
+
+#include "cim_msr.c"
+
diff -urN xf86-video-nsc-2.8.1-orig/src/cim_dev.h xf86-video-nsc-2.8.1/src/cim_dev.h
--- xf86-video-nsc-2.8.1-orig/src/cim_dev.h	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim_dev.h	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,63 @@
+/* <LIC_AMD_STD>
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+ * </DOC_AMD_STD>  */
+
+#ifndef CIMDEV_H_
+#define CIMDEV_H_
+
+#define CIM_RESERVE_MEM 0x01
+#define CIM_FREE_MEM    0x02
+#define CIMDEV_MINOR_DEV 156
+
+/* Block flags */
+#define CIM_F_FREE    0x01  /* This block is marked as free */
+#define CIM_F_CMDBUF  0x02  /* GP command buffer flag */
+#define CIM_F_PRIVATE 0x04  /* This block is reserved only for its owner */
+#define CIM_F_PUBLIC  0x08  /* This block can be used by the world */
+
+typedef struct {
+
+  /* These fields get populated by the client */
+
+  char owner[10];
+  char name[15];
+  int flags;
+  int size;
+
+  /* These fields are populated by the device */
+
+  unsigned long offset;
+} cim_mem_req_t;
+
+typedef struct {
+  char owner[10];
+  unsigned long offset;
+} cim_mem_free_t;
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cimarron.c xf86-video-nsc-2.8.1/src/cimarron.c
--- xf86-video-nsc-2.8.1-orig/src/cimarron.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cimarron.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,239 @@
+/* <LIC_AMD_STD>
+ * Copyright (c) 2005 Advanced Micro Devices, Inc.
+ * 
+ * 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 THE 
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ * 
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * </LIC_AMD_STD>  */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD>  */
+/* <DOC_AMD_STD>
+  * Base include file for the Cimarron library. This file should be modified 
+  * and included in any Cimarron-based project.
+ * </DOC_AMD_STD>  */
+
+/*----------------------------------------------------------------------*/
+/* MODULE SETTINGS                                                      */
+/* The following #defines affect which modules are included in the      */
+/* project.                                                             */
+/*----------------------------------------------------------------------*/
+
+#define CIMARRON_INCLUDE_GP                1
+#define CIMARRON_INCLUDE_VG                1
+#define CIMARRON_INCLUDE_VIP               1
+#define CIMARRON_INCLUDE_VOP               1
+#define CIMARRON_INCLUDE_VIDEO             1
+#define CIMARRON_INCLUDE_INIT              1
+
+#define CIMARRON_INCLUDE_VG_READ_ROUTINES  1
+#define CIMARRON_INCLUDE_DF_READ_ROUTINES  1
+#define CIMARRON_INCLUDE_VIP_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_VOP_READ_ROUTINES 1
+
+/*----------------------------------------------------------------------*/
+/* HARDWARE ACCESS SETTINGS                                             */
+/* The following #defines affect how the Cimarron macros access the     */
+/* hardware.  The hardware access macros are broken up into groups.     */
+/* Each group includes an enabling #define as well as several #define   */
+/* options that modify the macro configuration that is included.        */
+/* If the enabling define is deleted or all options are set to 0, the   */
+/* corresponding macros must be implemented by the user.   The          */
+/* combinations are explained as follows:                               */
+/* must be manually defined by the user. This allows a user to use the  */
+/* cim_defs.h file for only those macros that suit the needs of his/her */
+/* project.  For example, a user may need custom implementations of the */
+/* I/O and MSR macros, but may still want to use the default macros to  */
+/* read and write hardware registers. The combinations are explained as */
+/* follows:                                                             */
+/*                                                                      */
+/* Register Group:                                                      */
+/*   Disabling define:                                                  */
+/*       CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS                        */
+/*          Define this setting to exclude the register access macros.  */
+/*          This setting is the inverse of the other group settings in  */
+/*          that these macros are included by default.  This allows the */
+/*          cim_defs.h file to be included outside of cimarron.c for    */
+/*          basic operations.                                           */
+/*                                                                      */
+/* Memory Group:                                                        */
+/*   Enabling define:                                                   */
+/*       CIMARRON_INCLUDE_STRING_MACROS                                 */
+/*   Options:                                                           */
+/*       CIMARRON_OPTIMIZE_ASSEMBLY                                     */
+/*           Set to 1 to allow the use of inline assembly when writing  */
+/*           large chunks of data to memory.  Essentially, this allows  */
+/*           a rep movsd in place of a slower C for-loop.               */
+/*      CIMARRON_OPTIMIZE_FORLOOP                                       */
+/*           Define for C only data writes.                             */
+/*                                                                      */
+/* MSR Group:                                                           */
+/*   Enabling define:                                                   */
+/*      CIMARRON_INCLUDE_MSR_MACROS                                     */
+/*   Options:                                                           */
+/*      CIMARRON_MSR_DIRECT_ASM                                         */
+/*          Set to 1 to allow the use of the rdmsr and wrmsr opcodes in */
+/*          inline assembly.                                            */
+/*      CIMARRON_MSR_VSA_IO                                             */
+/*          Set to 1 to access MSRs using a VSAII virtual register.     */
+/*      CIMARRON_MSR_KERNEL_ROUTINE                                     */
+/*          Set to 1 to access MSRs using a wrapper routine in the      */
+/*          Linux kernel.                                               */
+/*                                                                      */
+/* IO Group:                                                            */
+/*   Enabling define:                                                   */
+/*      CIMARRON_INCLUDE_IO_MACROS                                      */
+/*   Options:                                                           */
+/*      CIMARRON_IO_DIRECT_ACCESS                                       */
+/*          Set to 1 to perform IO accesses using inline assembly.      */
+/*      CIMARRON_IO_ABSTRACTED_ASM                                      */
+/*          Set to 1 to perform IO using abstracted IO in Linux.        */
+/*                                                                      */
+/* Custom Group:                                                        */
+/*    Disabling define:                                                 */
+/*      CIMARRON_EXCLUDE_CUSTOM_MACROS                                  */
+/*          By default, the custom macros (the macros used by           */
+/*          gp_custom_convert_blt) are mapped to the normal command     */
+/*          string macros.  Setting this to 1 allows the user to        */
+/*          create a custom implementation.                             */
+/*----------------------------------------------------------------------*/
+
+/* UNCOMMENT THE FOLLOWING LINE TO EXCLUDE BASIC REGISTER ACCESS MACROS */
+
+/* #define CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS */
+
+#define CIMARRON_INCLUDE_STRING_MACROS 
+#define CIMARRON_OPTIMIZE_ASSEMBLY         0
+#define CIMARRON_OPTIMIZE_FORLOOP          0
+#define CIMARRON_OPTIMIZE_ABSTRACTED_ASM   1
+  
+#define CIMARRON_INCLUDE_MSR_MACROS 
+#define CIMARRON_MSR_DIRECT_ASM            0
+#define CIMARRON_MSR_VSA_IO                0
+#define CIMARRON_MSR_ABSTRACTED_ASM        1
+#define CIMARRON_MSR_KERNEL_ROUTINE        0
+
+#define CIMARRON_INCLUDE_IO_MACROS 
+#define CIMARRON_IO_DIRECT_ACCESS          0
+#define CIMARRON_IO_ABSTRACTED_ASM         1
+
+/* UNCOMMENT THE FOLLOWING LINE TO IMPLEMENT CUSTOM MACROS FOR GP_CUSTOM_CONVERT_BLT */
+
+/* #define CIMARRON_EXCLUDE_CUSTOM_MACROS */
+
+/*----------------------------------------------------------------------*/
+/* MODULE VARIABLES                                                     */
+/* The following #defines affect how global variables in each Cimarron  */
+/* module are defined.  These variables can be made static (to prevent  */
+/* naming conflicts) or they can be defined without the static keyword  */
+/* (to allow extern references).                                        */
+/*----------------------------------------------------------------------*/
+
+#if 1
+#define CIMARRON_STATIC static
+#else
+#define CIMARRON_STATIC
+#endif
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON GLOBAL VARIABLES                                            */
+/* These globals are used by the hardware access macros.  They must be  */
+/* initialized by the application to point to the memory-mapped         */
+/* registers of their respective blocks.                                */
+/*----------------------------------------------------------------------*/
+
+unsigned char *cim_gp_ptr         = (unsigned char *)0;
+unsigned char *cim_fb_ptr         = (unsigned char *)0;
+unsigned char *cim_cmd_base_ptr   = (unsigned char *)0;
+unsigned char *cim_cmd_ptr        = (unsigned char *)0;
+unsigned char *cim_vid_ptr        = (unsigned char *)0;
+unsigned char *cim_vip_ptr        = (unsigned char *)0;
+unsigned char *cim_vg_ptr         = (unsigned char *)0;
+
+/*----------------------------------------------------------------------*/
+/* INCLUDE RELEVANT CIMARRON HEADERS                                    */
+/*----------------------------------------------------------------------*/
+
+/* HARDWARE REGISTER DEFINITIONS */
+
+#include "cim_regs.h"
+
+/* ROUTINE DEFINITIONS */
+/* All routines have a prototype, even those that are not included    */
+/* via #ifdefs.  This prevents the user from having to include the    */
+/* correct #defines anywhere he/she wants to call a Cimarron routine. */
+
+#include "cim_rtns.h"
+
+/* HARDWARE ACCESS MACROS */
+
+#include "cim_defs.h"
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON MODULES                                                     */
+/* Modules and sub-modules are included based on user settings.  Note   */
+/* that excluding one or more modules may result in functionality       */
+/* holes.                                                               */
+/*----------------------------------------------------------------------*/
+
+/* GRAPHICS PROCESSOR */
+
+#if CIMARRON_INCLUDE_GP
+#include "cim_gp.c"
+#endif
+
+/* VIDEO GENERATOR */
+
+#if CIMARRON_INCLUDE_VG
+#include "cim_modes.c"
+#include "cim_vg.c"
+#endif
+
+/* DISPLAY FILTER */
+
+#if CIMARRON_INCLUDE_VIDEO
+#include "cim_filter.c"
+#include "cim_df.c"
+#endif
+
+/* INITIALIZATION AND DETECTION */
+
+#if CIMARRON_INCLUDE_INIT
+#include "cim_init.c"
+#endif
+
+/* VIP SUPPORT */
+
+#if CIMARRON_INCLUDE_VIP
+#include "cim_vip.c"
+#endif
+
+/* VOP SUPPORT */
+
+#if CIMARRON_INCLUDE_VOP
+#include "cim_vop.c"
+#endif
+
+/* MSR ACCESS */
+/* This module is used to access machine-specific registers. */
+/* It cannot be excluded from a project.                     */
+
+#include "cim_msr.c"
+
diff -urN xf86-video-nsc-2.8.1-orig/src/gfx/disp_gu3.c xf86-video-nsc-2.8.1/src/gfx/disp_gu3.c
--- xf86-video-nsc-2.8.1-orig/src/gfx/disp_gu3.c	1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/gfx/disp_gu3.c	2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,2422 @@
+ /*
+  * 
+  * <LIC_AMD_STD>
+  * Copyright (C) <years> Advanced Micro Devices, Inc.  All Rights Reserved.
+  * </LIC_AMD_STD>
+  * 
+  * <CTL_AMD_STD>
+  * </CTL_AMD_STD>
+  * 
+  * <DOC_AMD_STD>
+  * This file contains routines for the second generation display controller.  
+  * </DOC_AMD_STD>
+  * 
+  */
+
+void gu3_enable_compression(void);		            /* private routine definition */
+void gu3_disable_compression(void);		            /* private routine definition */
+int gfx_set_display_control(int sync_polarities);	/* private routine definition */
+void gfx_reset_video (void);	
+int gu3_set_specified_mode(DISPLAYMODE *pMode, int bpp);
+		 
+ /*-----------------------------------------------------------------------------
+ * WARNING!!!! INACCURATE DELAY MECHANISM
+ *
+ * In an effort to keep the code self contained and operating system 
+ * independent, the delay loop just performs reads of a display controller
+ * register.  This time will vary for faster processors.  The delay can always
+ * be longer than intended, only effecting the time of the mode switch 
+ * (obviously want it to still be under a second).  Problems with the hardware
+ * only arise if the delay is not long enough.  
+ *-----------------------------------------------------------------------------
+ */
+
+#define CSTL_READS_PER_MILLISECOND 15000L
+
+#if GFX_DISPLAY_DYNAMIC
+void gu3_delay_milliseconds(unsigned long milliseconds)
+#else
+void gfx_delay_milliseconds(unsigned long milliseconds)
+#endif
+{
+	/* ASSUME 300 MHZ 20 CLOCKS PER READ */
+
+	unsigned long loop;
+	loop = milliseconds * CSTL_READS_PER_MILLISECOND;
+	while (loop-- > 0)
+	{
+		READ_REG32 (DC3_UNLOCK);
+	}
+}
+
+#if GFX_DISPLAY_DYNAMIC
+void gu3_delay_microseconds(unsigned long microseconds)
+#else
+void gfx_delay_microseconds(unsigned long microseconds)
+#endif
+{
+	/* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */
+
+
+	unsigned long loop_count = microseconds * 15;
+	
+	while (loop_count-- > 0)
+	{
+		READ_REG32 (DC3_UNLOCK);
+	}
+}
+	
+/*-----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_BPP
+ *
+ * This routine programs the bpp in the display controller.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_bpp(unsigned short bpp)
+#else
+int gfx_set_display_bpp(unsigned short bpp)
+#endif
+{
+    unsigned long dcfg, lock;
+
+	dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~(DC3_DCFG_DISP_MODE_MASK | DC3_DCFG_16BPP_MODE_MASK);
+	lock = READ_REG32 (DC3_UNLOCK);
+
+	switch (bpp)
+	{
+	    case 12: dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP); break;
+		case 15: dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP); break;
+		case 16: dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP); break;
+		case 32: dcfg |= (DC3_DCFG_DISP_MODE_24BPP);  break;
+		case 8:  dcfg |= (DC3_DCFG_DISP_MODE_8BPP);   break;
+		default: return GFX_STATUS_BAD_PARAMETER;
+	}
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+	WRITE_REG32 (DC3_UNLOCK, lock);
+
+	/* SET BPP IN GRAPHICS PIPELINE */
+
+	gfx_set_bpp (bpp);
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * gu3_set_specified_mode (private routine)
+ * This routine uses the parameters in the specified display mode structure
+ * to program the display controller hardware.  
+ *-----------------------------------------------------------------------------
+ */
+int gu3_set_specified_mode(DISPLAYMODE *pMode, int bpp)
+{
+    Q_WORD msr_value;
+	unsigned long unlock, value;
+	unsigned long acfg, gcfg, dcfg;
+	unsigned long size, pitch;
+	unsigned long bpp_mask, temp, dv_size;
+	
+	/* CHECK WHETHER TIMING CHANGE IS ALLOWED */
+	/* Flag used for locking also overrides timing change restriction */
+
+	if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
+		return GFX_STATUS_ERROR;
+	
+	/* CLEAR PANNING OFFSETS */
+
+	DeltaX = 0;
+	DeltaY = 0;
+	panelLeft = 0;
+	panelTop  = 0;
+
+	/* SET GLOBAL FLAG */
+	
+	if (pMode->flags & GFX_MODE_LOCK_TIMING)
+		gfx_timing_lock = 1;
+
+	/* CHECK FOR VALID BPP                          */
+	/* As this function can be called directly from */
+	/* gfx_set_display_timings, we must correct any */
+	/* invalid bpp settings.                        */
+
+	switch (bpp)
+	{
+	    case 12: bpp_mask = 0x00000900; break;
+		case 15: bpp_mask = 0x00000500; break;
+		case 16: bpp_mask = 0x00000100; break;
+		case 32: bpp_mask = 0x00000200; break;
+		default: bpp_mask = 0x00000000; bpp = 8; break;
+	}
+
+	gbpp = bpp;
+
+	/* DISABLE COMPRESSION */
+
+	gu3_disable_compression();
+
+	/* ALSO DISABLE VIDEO */
+	/* Use private "reset video" routine to do all that is needed. */
+	/* SC1200, for example, also disables the alpha blending regions. */
+
+	gfx_reset_video();
+
+	/* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+
+	unlock = READ_REG32 (DC3_UNLOCK);
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	/* READ THE CURRENT REGISTER VALUES */
+
+    gcfg = READ_REG32 (DC3_GENERAL_CFG);
+    dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+
+    /* BLANK THE DISPLAY IN THE DISPLAY FILTER */
+
+	gfx_set_crt_enable (0);
+
+    /* DISABLE THE TIMING GENERATOR */
+
+    dcfg &= ~(unsigned long)DC3_DCFG_TGEN;						  
+    WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+	
+	/* DELAY: WAIT FOR PENDING MEMORY REQUESTS                            */
+	/* This delay is used to make sure that all pending requests to the   */
+	/* memory controller have completed before disabling the FIFO load.   */
+    
+	gfx_delay_milliseconds(1);
+
+    /* DISABLE DISPLAY FIFO LOAD */
+
+    gcfg &= ~(unsigned long)DC3_GCFG_DFLE;
+    WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+	/* PRESERVE VIDEO INFORMATION */
+
+	gcfg &= (unsigned long)(DC3_GCFG_YUVM | DC3_GCFG_VDSE);
+	dcfg  = 0;
+
+    /* DISABLE VGA */
+    /* VGA *MUST* be turned off before TGEN is enabled.  If not, a condition */
+    /* will result where VGA Enable is waiting for a VSync to be latched but */
+    /* a VSync will not be generated until VGA is disabled.                  */
+	
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+	/* SET THE DOT CLOCK FREQUENCY             */
+	/* Mask off the divide by two bit (bit 31) */
+
+	gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
+
+	/* DELAY: WAIT FOR THE PLL TO SETTLE */
+	/* This allows the dot clock frequency that was just set to settle. */
+
+	gfx_delay_milliseconds(1);
+
+	/* SET THE GX DISPLAY CONTROLLER PARAMETERS */
+
+	WRITE_REG32 (DC3_FB_ST_OFFSET,   0);
+	WRITE_REG32 (DC3_CB_ST_OFFSET,   0);
+	WRITE_REG32 (DC3_CURS_ST_OFFSET, 0);
+
+	/* SET LINE SIZE AND PITCH */
+	/* 1. Flat Panels must use the mode width and not  */
+	/*    the timing width to set the pitch.           */
+	/* 2. Mode sets will use a pitch that is aligned   */
+	/*    on a 1K boundary to preserve legacy.  The    */
+	/*    pitch can be overridden by a subsequent call */
+	/*    to gfx_set_display_pitch.                    */
+
+	if (PanelEnable) 
+		size = ModeWidth;
+	else 
+		size = pMode->hactive;
+	
+	if (bpp > 8)  size <<= 1;
+	if (bpp > 16) size <<= 1;
+		
+	pitch = 1024;
+	dv_size = DC3_DV_LINE_SIZE_1024;
+	
+	if (size > 1024)
+	{
+		pitch = 2048;
+		dv_size = DC3_DV_LINE_SIZE_2048;
+	}
+	if (size > 2048) 
+	{
+		pitch = 4096;
+		dv_size = DC3_DV_LINE_SIZE_4096;
+	}
+	if (size > 4096)
+	{
+		pitch = 8192;
+		dv_size = DC3_DV_LINE_SIZE_8192;
+	}
+	WRITE_REG32(DC3_GFX_PITCH, pitch >> 3);
+
+	/* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */
+
+	temp = READ_REG32 (DC3_DV_CTL);
+	WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dv_size);
+
+	if (PanelEnable) 
+	{
+		size = pMode->hactive;
+		if (bpp > 8)  size <<= 1;
+		if (bpp > 16) size <<= 1;
+	}
+
+	WRITE_REG32 (DC3_LINE_SIZE, ((size >> 3)));
+
+	/* ALWAYS ENABLE VIDEO AND GRAPHICS DATA            */
+	/* These bits are relics from a previous design and */
+	/* should always be enabled.                        */
+
+	dcfg |= (unsigned long)(DC3_DCFG_VDEN | DC3_DCFG_GDEN);
+	
+	/* SET PIXEL FORMAT */
+
+	dcfg |= bpp_mask;
+
+	/* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
+	/* AND VERT. INT. SELECT                                      */
+
+	dcfg |= (unsigned long)(DC3_DCFG_TGEN | DC3_DCFG_TRUP | DC3_DCFG_PALB | DC3_DCFG_VISL);
+
+	/* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE     */
+	
+    gcfg |= 0x0000BA01;
+    dcfg |= 0x000EA000;
+    acfg  = 0x001A0000;
+	
+    /* SET THE DISPLAY CHARACTERISTICS FOR HIGH BANDWIDTH CASES */
+
+    gfx_msr_read (RC_ID_VG, DC3_VG_SPARE_MSR, &msr_value);
+    msr_value.low &= ~(VG_SPARE_DISABLE_CFIFO_HGO    | VG_SPARE_VFIFO_ARB_SELECT |
+                       VG_SPARE_LOAD_WM_LPEN_MASK    | VG_SPARE_WM_LPEN_OVRD     |
+                       VG_SPARE_DISABLE_INIT_VID_PRI | VG_SPARE_DISABLE_VFIFO_WM);
+    msr_value.low |= VG_SPARE_DISABLE_CFIFO_HGO | VG_SPARE_VFIFO_ARB_SELECT;
+    gfx_msr_write (RC_ID_VG, DC3_VG_SPARE_MSR, &msr_value);
+    WRITE_REG32 (DC3_ARB_CFG, acfg);
+  
+	/* ENABLE FLAT PANEL CENTERING                          */
+	/* For panel modes having a resolution smaller than the */
+	/* panel resolution, turn on data centering.            */
+
+	if (PanelEnable && ModeWidth < PanelWidth) 
+	    dcfg |= DC3_DCFG_DCEN;
+
+    /* SET THE GRAPHICS SCALE */
+    /* We do not support graphics scaling, but we need to ensure that the */
+    /* scale is set correctly none the less.                              */
+
+    WRITE_REG32 (DC3_GFX_SCALE, 0x40004000);
+    WRITE_REG32 (DC3_IRQ_CTL, 0);
+
+	/* COMBINE AND SET TIMING VALUES */
+
+	value = (unsigned long) (pMode->hactive - 1) |
+		  (((unsigned long) (pMode->htotal  - 1)) << 16);
+	WRITE_REG32(DC3_H_ACTIVE_TIMING, value);
+	value = (unsigned long) (pMode->hblankstart - 1) |
+		  (((unsigned long) (pMode->hblankend   - 1)) << 16);
+	WRITE_REG32(DC3_H_BLANK_TIMING, value);
+	value = (unsigned long) (pMode->hsyncstart - 1) |
+		  (((unsigned long) (pMode->hsyncend   - 1)) << 16);
+	WRITE_REG32(DC3_H_SYNC_TIMING, value);
+	value = (unsigned long) (pMode->vactive - 1) |
+		  (((unsigned long) (pMode->vtotal  - 1)) << 16);
+	WRITE_REG32(DC3_V_ACTIVE_TIMING, value);
+	value = (unsigned long) (pMode->vblankstart - 1) |
+		  (((unsigned long) (pMode->vblankend - 1)) << 16);
+	WRITE_REG32(DC3_V_BLANK_TIMING, value);
+	value = (unsigned long) (pMode->vsyncstart - 1) |
+		  (((unsigned long) (pMode->vsyncend - 1)) << 16);
+	WRITE_REG32(DC3_V_SYNC_TIMING, value);
+		
+	WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);	
+
+	/* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+
+	gfx_set_display_control (((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
+		                     ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
+
+	/* RESTORE VALUE OF DC3_UNLOCK */
+
+	WRITE_REG32(DC3_UNLOCK, unlock);
+
+	/* RESET THE PITCH VALUES IN THE GP */
+	
+	gfx_reset_pitch ((unsigned short)pitch);
+
+	gfx_set_bpp ((unsigned short)bpp);
+
+	return GFX_STATUS_OK;
+}
+
+ /*----------------------------------------------------------------------------
+ * GFX_IS_DISPLAY_MODE_SUPPORTED
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------  
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#else
+int gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#endif
+{
+	unsigned int mode;
+	unsigned long hz_flag = 0, bpp_flag = 0;
+
+	/* SET FLAGS TO MATCH REFRESH RATE */
+
+	if (hz == 56)  hz_flag = GFX_MODE_56HZ;
+	if (hz == 60)  hz_flag = GFX_MODE_60HZ;
+	if (hz == 70)  hz_flag = GFX_MODE_70HZ;
+	if (hz == 72)  hz_flag = GFX_MODE_72HZ;
+	if (hz == 75)  hz_flag = GFX_MODE_75HZ;
+	if (hz == 85)  hz_flag = GFX_MODE_85HZ;
+    if (hz == 90)  hz_flag = GFX_MODE_90HZ;
+    if (hz == 100) hz_flag = GFX_MODE_100HZ;
+	
+	/* SET BPP FLAGS TO LIMIT MODE SELECTION */
+
+	switch (bpp)
+	{
+	    case 8:  bpp_flag = GFX_MODE_8BPP;  break;
+		case 12: bpp_flag = GFX_MODE_12BPP; break;
+		case 15: bpp_flag = GFX_MODE_15BPP; break;
+		case 16: bpp_flag = GFX_MODE_16BPP; break;
+		case 32: bpp_flag = GFX_MODE_24BPP; break;
+		default: return (-1);
+	}
+
+	/* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+
+	for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) 
+	{
+		if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
+			(DisplayParams[mode].vactive == (unsigned short)yres) &&
+			(DisplayParams[mode].flags & hz_flag) &&
+			(DisplayParams[mode].flags & bpp_flag)) 
+		{
+
+			/* CASTLE DOES NOT SUPPORT EMULATED VGA MODES */
+
+			if ((DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) ||
+				(DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE))
+				continue;
+
+			/* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
+
+			return(mode);
+		}
+	} 
+	return(-1);
+} 
+
+/*----------------------------------------------------------------------------
+ * gfx_set_display_mode
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------  
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_mode(int xres, int yres, int bpp, int hz)
+#else
+int gfx_set_display_mode(int xres, int yres, int bpp, int hz)
+#endif
+{
+	int mode;
+
+	/* DISABLE FLAT PANEL */
+	/* Flat Panel settings are enabled by the function gfx_set_fixed_timings */
+	/* and disabled by gfx_set_display_mode.                                 */
+
+	PanelEnable = 0;
+
+	mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
+	if(mode >= 0)
+	{
+		if (gu3_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK)
+			return(1);
+	}
+	return(0);
+} 
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_TIMINGS
+ *
+ * This routine sets the display controller mode using the specified timing
+ * values (as opposed to using the tables internal to Durango).
+ *
+ * Returns GFX_STATUS_OK ON SUCCESS, GFX_STATUS_ERROR otherwise.
+ *----------------------------------------------------------------------------  
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_timings(unsigned short bpp, unsigned short flags, 
+	unsigned short hactive, unsigned short hblankstart, 
+	unsigned short hsyncstart, unsigned short hsyncend,
+	unsigned short hblankend, unsigned short htotal,
+	unsigned short vactive, unsigned short vblankstart, 
+	unsigned short vsyncstart, unsigned short vsyncend,
+	unsigned short vblankend, unsigned short vtotal,
+	unsigned long frequency)
+#else
+int gfx_set_display_timings(unsigned short bpp, unsigned short flags, 
+	unsigned short hactive, unsigned short hblankstart, 
+	unsigned short hsyncstart, unsigned short hsyncend,
+	unsigned short hblankend, unsigned short htotal,
+	unsigned short vactive, unsigned short vblankstart, 
+	unsigned short vsyncstart, unsigned short vsyncend,
+	unsigned short vblankend, unsigned short vtotal,
+	unsigned long frequency)
+#endif
+{
+	/* SET MODE STRUCTURE WITH SPECIFIED VALUES */
+
+	gfx_display_mode.flags = 0;
+	if (flags & 1) gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
+	if (flags & 2) gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
+	if (flags & 0x1000) gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
+	gfx_display_mode.hactive = hactive;
+	gfx_display_mode.hblankstart = hblankstart;
+	gfx_display_mode.hsyncstart = hsyncstart;
+	gfx_display_mode.hsyncend = hsyncend;
+	gfx_display_mode.hblankend = hblankend;
+	gfx_display_mode.htotal = htotal;
+	gfx_display_mode.vactive = vactive;
+	gfx_display_mode.vblankstart = vblankstart;
+	gfx_display_mode.vsyncstart = vsyncstart;
+	gfx_display_mode.vsyncend = vsyncend;
+	gfx_display_mode.vblankend = vblankend;
+	gfx_display_mode.vtotal = vtotal;
+	gfx_display_mode.frequency = frequency;
+
+	/* CALL ROUTINE TO SET MODE */
+
+	return (gu3_set_specified_mode(&gfx_display_mode, bpp));
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_VTOTAL
+ *
+ * This routine sets the display controller vertical total to
+ * "vtotal". As a side effect it also sets vertical blank end.
+ * It should be used when only this value needs to be changed,
+ * due to speed considerations.
+ *
+ * Note: it is the caller's responsibility to make sure that
+ * a legal vtotal is used, i.e. that "vtotal" is greater than or
+ * equal to vsync end.
+ *
+ * Always returns 0.
+ *----------------------------------------------------------------------------  
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_vtotal(unsigned short vtotal)
+#else
+int gfx_set_vtotal(unsigned short vtotal)
+#endif
+{
+	unsigned long unlock, dcfg, vactive, vblank;
+
+    /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+
+	unlock = READ_REG32(DC3_UNLOCK);
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	/* READ THE CURRENT RC VALUES */
+
+    dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+	vactive = READ_REG32 (DC3_V_ACTIVE_TIMING);
+	vblank  = READ_REG32 (DC3_V_BLANK_TIMING);
+
+	/* DISABLE TIMING REGISTER UPDATES */
+
+	WRITE_REG32 (DC3_DISPLAY_CFG, dcfg & ~(unsigned long)DC3_DCFG_TRUP);
+
+	/* WRITE NEW TIMING VALUES */
+
+	WRITE_REG32 (DC3_V_ACTIVE_TIMING, (vactive & DC3_VAT_VA_MASK)  | (unsigned long)(vtotal - 1) << 16);
+	WRITE_REG32 (DC3_V_BLANK_TIMING,  (vblank  & DC3_VBT_VBS_MASK) | (unsigned long)(vtotal - 1) << 16);
+
+	/* RESTORE OLD RC VALUES */
+
+	WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+
+	return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_pitch
+ *
+ * This routine sets the pitch of the frame buffer to the specified value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_pitch(unsigned short pitch)
+#else
+void gfx_set_display_pitch(unsigned short pitch)
+#endif
+{		
+	unsigned long value = 0;
+	unsigned long lock = READ_REG32(DC3_UNLOCK);
+	
+	value = READ_REG32(DC3_GFX_PITCH) & 0xFFFF0000;
+	value |= (pitch >> 3);
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32(DC3_GFX_PITCH, value);
+
+	/* SET RENDERING PITCHES TO MATCH */
+
+	gfx_reset_pitch(pitch);
+
+	/* SET THE FRAME DIRTY MODE                  */
+	/* Non-standard pitches, i.e. pitches that   */
+	/* are not 1K, 2K or 4K must mark the entire */
+	/* frame as dirty when writing to the frame  */
+	/* buffer.                                   */
+
+	value = READ_REG32 (DC3_GENERAL_CFG);
+
+	if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
+		value &= ~(unsigned long)(DC3_GCFG_FDTY);
+	else
+		value |=  (unsigned long)(DC3_GCFG_FDTY);
+
+	WRITE_REG32 (DC3_GENERAL_CFG, value);
+	WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_offset
+ *
+ * This routine sets the start address of the frame buffer.  It is 
+ * typically used to pan across a virtual desktop (frame buffer larger than 
+ * the displayed screen) or to flip the display between multiple buffers.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_offset(unsigned long offset)
+#else
+void gfx_set_display_offset(unsigned long offset)
+#endif
+{
+	/* UPDATE FRAME BUFFER OFFSET */
+	unsigned long lock;
+	lock = READ_REG32(DC3_UNLOCK);
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	
+	/* START ADDRESS EFFECTS DISPLAY COMPRESSION */
+	/* Disable compression for non-zero start addresss values.            */
+	/* Enable compression if offset is zero and comression is intended to */
+	/* be enabled from a previous call to "gfx_set_compression_enable".   */
+	/* Compression should be disabled BEFORE the offset is changed        */
+	/* and enabled AFTER the offset is changed.                           */
+	
+	if (offset == 0)
+	{
+		WRITE_REG32(DC3_FB_ST_OFFSET, offset);
+		if (gfx_compression_enabled)
+		{
+			/* WAIT FOR THE OFFSET TO BE LATCHED */
+			gfx_wait_vertical_blank ();
+			gu3_enable_compression();
+		}
+	}
+	else
+	{
+		/* ONLY DISABLE COMPRESSION ONCE */
+
+		if (gfx_compression_active)
+			gu3_disable_compression();
+
+		WRITE_REG32(DC3_FB_ST_OFFSET, offset);
+	}
+
+	WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette_entry
+ *
+ * This routine sets an palette entry in the display controller.
+ * A 32-bit X:R:G:B value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_palette_entry(unsigned long index, unsigned long palette)
+#else
+int gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+	if (index > 0xFF)
+		return GFX_STATUS_BAD_PARAMETER;
+
+	WRITE_REG32(DC3_PAL_ADDRESS, index);
+	WRITE_REG32(DC3_PAL_DATA, palette);
+
+	return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette
+ *
+ * This routine sets the entire palette in the display controller.
+ * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_palette(unsigned long *palette)
+#else
+int gfx_set_display_palette(unsigned long *palette)
+#endif
+{
+	unsigned long i;
+	WRITE_REG32(DC3_PAL_ADDRESS, 0);
+	
+	if (palette)
+	{
+		for (i = 0; i < 256; i++)
+		{
+		    WRITE_REG32(DC3_PAL_DATA, palette[i]);
+		}
+	}
+	return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_enable
+ *
+ * This routine enables or disables the hardware cursor.  
+ *
+ * WARNING: The cursor start offset must be set by setting the cursor 
+ * position before calling this routine to assure that memory reads do not
+ * go past the end of graphics memory (this can hang GXm).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_enable(int enable)
+#else
+void gfx_set_cursor_enable(int enable)
+#endif
+{
+    unsigned long unlock, gcfg;
+	
+	/* SET OR CLEAR CURSOR ENABLE BIT */
+
+	unlock = READ_REG32(DC3_UNLOCK);
+	gcfg   = READ_REG32(DC3_GENERAL_CFG);
+	if (enable) gcfg |=   DC3_GCFG_CURE;
+	else        gcfg &= ~(DC3_GCFG_CURE);
+
+	/* WRITE NEW REGISTER VALUE */
+
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_colors
+ *
+ * This routine sets the colors of the hardware cursor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#else
+void gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#endif
+{
+	/* SET CURSOR COLORS */
+
+	WRITE_REG32(DC3_PAL_ADDRESS, 0x100);
+	WRITE_REG32(DC3_PAL_DATA, bkcolor);
+	WRITE_REG32(DC3_PAL_DATA, fgcolor);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_position
+ *
+ * This routine sets the position of the hardware cusror.  The starting
+ * offset of the cursor buffer must be specified so that the routine can 
+ * properly clip scanlines if the cursor is off the top of the screen.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_position(unsigned long memoffset, 
+	unsigned short xpos, unsigned short ypos, 
+	unsigned short xhotspot, unsigned short yhotspot)
+#else
+void gfx_set_cursor_position(unsigned long memoffset, 
+	unsigned short xpos, unsigned short ypos, 
+	unsigned short xhotspot, unsigned short yhotspot)
+#endif
+{
+    unsigned long unlock;
+
+	short x = (short) xpos - (short) xhotspot;
+	short y = (short) ypos - (short) yhotspot;
+	short xoffset = 0;
+	short yoffset = 0;
+	if (x < -63) return;
+	if (y < -63) return;
+	
+	if (PanelEnable) 
+	{
+		if (( ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) 
+		{ 
+			gfx_enable_panning(xpos, ypos);
+			x = x - (unsigned short)panelLeft;
+			y = y - (unsigned short)panelTop;
+		}
+	}
+
+	/* ADJUST OFFSETS */
+	/* Cursor movement and panning work as follows:  The cursor position   */
+	/* refers to where the hotspot of the cursor is located.  However, for */
+	/* non-zero hotspots, the cursor buffer actually begins before the     */
+	/* specified position.                                                 */
+
+	if (x < 0) { xoffset = -x; x = 0; }
+	if (y < 0) { yoffset = -y; y = 0; }
+	memoffset += (unsigned long) yoffset << 4;
+
+	/* SET CURSOR POSITION */
+
+	unlock = READ_REG32(DC3_UNLOCK);
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32(DC3_CURS_ST_OFFSET, memoffset);
+	WRITE_REG32(DC3_CURSOR_X, (unsigned long) x |
+		(((unsigned long) xoffset) << 11));
+	WRITE_REG32(DC3_CURSOR_Y, (unsigned long) y | 
+		(((unsigned long) yoffset) << 11));
+	WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape32
+ *
+ * This routine loads 32x32 cursor data into the cursor buffer in graphics memory.
+ * As the Castle cursor is actually 64x64, we must pad the outside of the 
+ * cursor data with transparent pixels.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_shape32(unsigned long memoffset, 
+	unsigned long *andmask, unsigned long *xormask)
+#else
+void gfx_set_cursor_shape32(unsigned long memoffset, 
+	unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+	int i;
+
+	for (i = 0; i < 32; i++)
+	{
+		/* EVEN QWORDS CONTAIN THE AND MASK */
+
+		WRITE_FB32 (memoffset, 0xFFFFFFFF);
+		WRITE_FB32 (memoffset + 4, andmask[i]);
+
+		/* ODD QWORDS CONTAIN THE XOR MASK  */
+
+		WRITE_FB32 (memoffset + 8, 0x00000000);
+		WRITE_FB32 (memoffset + 12, xormask[i]);
+
+		memoffset += 16;
+	}
+
+	/* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
+
+	for (i = 0; i < 32; i++)
+	{
+		WRITE_FB32 (memoffset,      0xFFFFFFFF);
+		WRITE_FB32 (memoffset + 4,  0xFFFFFFFF);
+		WRITE_FB32 (memoffset + 8,  0x00000000);
+		WRITE_FB32 (memoffset + 12, 0x00000000);
+
+		memoffset += 16;
+	}
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape64
+ *
+ * This routine loads 64x64 cursor data into the cursor buffer in graphics memory.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_shape64(unsigned long memoffset, 
+	unsigned long *andmask, unsigned long *xormask)
+#else
+void gfx_set_cursor_shape64(unsigned long memoffset, 
+	unsigned long *andmask, unsigned long *xormask)
+#endif
+{	
+	int i;
+
+	for (i = 0; i < 128; i += 2)
+	{
+		/* EVEN QWORDS CONTAIN THE AND MASK */
+		/* We invert the dwords to prevent the calling            */
+		/* application from having to think in terms of Qwords.   */
+		/* The hardware data order is actually 63:0, or 31:0 of   */
+		/* the second dword followed by 31:0 of the first dword.  */
+		
+		WRITE_FB32 (memoffset, andmask[i + 1]);
+		WRITE_FB32 (memoffset + 4, andmask[i]);
+
+		/* ODD QWORDS CONTAIN THE XOR MASK  */
+
+		WRITE_FB32 (memoffset + 8, xormask[i + 1]);
+		WRITE_FB32 (memoffset + 12, xormask[i]);
+
+		memoffset += 16;
+	}
+}
+
+/*---------------------------------------------------------------------------
+ * gu3_enable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It enables display compression.
+ *---------------------------------------------------------------------------
+ */
+void gu3_enable_compression(void)
+{
+	unsigned long unlock, gcfg, temp;
+
+	/* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
+
+	if (READ_REG32(DC3_FB_ST_OFFSET) & 0x0FFFFFFF)
+		return;
+	
+	/* SET GLOBAL INDICATOR */
+
+	gfx_compression_active = 1;
+
+	/* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
+	/* Software is required to do this before enabling compression.   */
+	/* Don't want controller to think that old lines are still valid. */
+	/* Writing a 1 to bit 0 of the DV Control register will force the */
+	/* hardware to clear all the valid bits.                          */
+
+    unlock = READ_REG32 (DC3_UNLOCK);
+	temp   = READ_REG32 (DC3_DV_CTL);
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+    WRITE_REG32 (DC3_DV_CTL, temp | 0x00000001);
+
+	/* TURN ON COMPRESSION CONTROL BITS */
+	
+	gcfg   = READ_REG32 (DC3_GENERAL_CFG);
+	gcfg  |= DC3_GCFG_CMPE | DC3_GCFG_DECE;
+	
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gu3_disable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It disables display compression.
+ *---------------------------------------------------------------------------
+ */
+void gu3_disable_compression(void)
+{
+	unsigned long unlock, gcfg;
+
+	/* SET GLOBAL INDICATOR */
+
+	gfx_compression_active = 0;
+
+	/* TURN OFF COMPRESSION CONTROL BITS */
+
+	unlock = READ_REG32(DC3_UNLOCK);
+	gcfg = READ_REG32(DC3_GENERAL_CFG);
+	gcfg &= ~(DC3_GCFG_CMPE | DC3_GCFG_DECE);
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_enable
+ *
+ * This routine enables or disables display compression.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_enable(int enable)
+#else
+int gfx_set_compression_enable(int enable)
+#endif
+{
+	/* SET GLOBAL VARIABLE FOR INDENDED STATE */
+	/* Compression can only be enabled for non-zero start address values. */
+	/* Keep state to enable compression on start address changes. */
+
+	gfx_compression_enabled = enable;
+	if (enable) gu3_enable_compression();
+	else gu3_disable_compression();
+	return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_offset
+ *
+ * This routine sets the base offset for the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_offset(unsigned long offset)
+#else
+int gfx_set_compression_offset(unsigned long offset)
+#endif
+{
+	unsigned long lock;
+	
+	/* MUST BE 16-BYTE ALIGNED FOR CASTLE */
+
+	if (offset & 0x0F) return(1);
+
+	/* SET REGISTER VALUE */
+
+	lock = READ_REG32(DC3_UNLOCK);
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32(DC3_CB_ST_OFFSET, offset & 0x0FFFFFFF);
+	WRITE_REG32(DC3_UNLOCK, lock);
+
+	return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_pitch
+ *
+ * This routine sets the pitch, in bytes, of the compression buffer. 
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_pitch(unsigned short pitch)
+#else
+int gfx_set_compression_pitch(unsigned short pitch)
+#endif
+{
+	unsigned long lock, line_delta;
+	
+	lock = READ_REG32(DC3_UNLOCK);
+
+	/* SET REGISTER VALUE */
+
+	line_delta = READ_REG32(DC3_GFX_PITCH) & 0x0000FFFF;
+	line_delta |= (((unsigned long)pitch << 13) & 0xFFFF0000);
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32(DC3_GFX_PITCH, line_delta);
+	WRITE_REG32(DC3_UNLOCK, lock);
+	return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_size
+ *
+ * This routine sets the line size of the compression buffer, which is the
+ * maximum number of bytes allowed to store a compressed line.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_size(unsigned short size)
+#else
+int gfx_set_compression_size(unsigned short size)
+#endif
+{
+	unsigned long lock, buf_size;
+
+	/* SUBTRACT 32 FROM SIZE                          */
+	/* The display controller will actually write     */
+	/* 4 extra QWords.  So, if we assume that "size"  */
+	/* refers to the allocated size, we must subtract */
+	/* 32 bytes.                                      */
+
+	size -= 32;
+	
+	/* SET REGISTER VALUE */
+
+	lock = READ_REG32(DC3_UNLOCK);
+	buf_size = READ_REG32(DC3_LINE_SIZE) & ~DC3_LINE_SIZE_CBLS_MASK;
+	buf_size |= ((((unsigned long)size >> 3) + 1) & 0x7F) << DC3_LINE_SIZE_CB_SHIFT;
+	WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32(DC3_LINE_SIZE, buf_size);
+	WRITE_REG32(DC3_UNLOCK, lock);
+	return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_color_key (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_color_key".  It abstracts the 
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_color_key (unsigned long key, unsigned long mask, int enable)
+#else
+void gfx_set_display_video_color_key (unsigned long key, unsigned long mask, int enable)
+#endif
+{
+    unsigned long colorkey = 0;
+    unsigned long lock;
+	
+	if (enable)
+		colorkey = (key & 0xFFFFFF) | DC3_CLR_KEY_ENABLE;
+
+    lock = READ_REG32 (DC3_UNLOCK);
+    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+	WRITE_REG32 (DC3_COLOR_KEY, colorkey);
+    WRITE_REG32 (DC3_COLOR_MASK, (mask & 0xFFFFFF));
+
+    WRITE_REG32 (DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_format".  It abstracts the 
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_format(unsigned long format)
+#else
+void gfx_set_display_video_format(unsigned long format)
+#endif
+{
+	unsigned long gcfg, lock;
+
+	lock = READ_REG32 (DC3_UNLOCK);
+	gcfg = READ_REG32 (DC3_GENERAL_CFG);
+
+   	switch (format)
+	{
+		case VIDEO_FORMAT_Y0Y1Y2Y3:
+		case VIDEO_FORMAT_Y3Y2Y1Y0:
+		case VIDEO_FORMAT_Y1Y0Y3Y2:
+		case VIDEO_FORMAT_Y1Y2Y3Y0:
+
+			gcfg |= DC3_GCFG_YUVM;
+			break;
+
+		default:
+
+			gcfg &= ~DC3_GCFG_YUVM;
+			break;
+	}
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_enable".  It abstracts the 
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_enable(int enable)
+#else
+void gfx_set_display_video_enable(int enable)
+#endif
+{
+   	unsigned long lock, gcfg, dcfg;
+
+	/* READ CURRENT VALUES */
+
+	lock = READ_REG32 (DC3_UNLOCK);
+	gcfg = READ_REG32 (DC3_GENERAL_CFG);
+	dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+
+	/* SET OR CLEAR VIDEO ENABLE IN GENERAL_CFG */
+
+	if (enable) gcfg |=  DC3_GCFG_VIDE;
+	else        gcfg &= ~DC3_GCFG_VIDE;
+
+	/* WRITE REGISTER */
+
+	WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+	WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+	WRITE_REG32 (DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_size".  It abstracts the 
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_size(unsigned short width, unsigned short height)
+#else
+void gfx_set_display_video_size(unsigned short width, unsigned short height)
+#endif
+{
+	unsigned long lock, value, yuv_420;
+
+	/* READ CURRENT VALUES */
+
+	lock     = READ_REG32 (DC3_UNLOCK);
+	value    = READ_REG32 (DC3_LINE_SIZE) & ~DC3_LINE_SIZE_VLS_MASK;
+	yuv_420  = READ_REG32 (DC3_GENERAL_CFG) & DC3_GCFG_YUVM;
+		
+	/* LINE WIDTH IS 1/4 FOR 4:2:0 VIDEO */
+	/* All data must be