diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile	2001-01-24 01:06:21.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile	2002-04-04 16:05:44.000000000 +0200
@@ -1,13 +1,13 @@
-XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile,v 1.10 2000/11/03 18:46:11 eich Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile,v 1.12 2002/04/04 14:05:44 eich Exp $
 #define IHaveModules
 #include <Server.tmpl>
 
 
 SRCS = neo_driver.c neo_bank.c neo_cursor.c neo_2097.c neo_2070.c \
-	neo_2090.c neo_2200.c neo_i2c.c neo_shadow.c neo_dga.c
+	neo_2090.c neo_2200.c neo_i2c.c neo_shadow.c neo_dga.c neo_video.c
 
 OBJS = neo_driver.o neo_bank.o neo_cursor.o neo_2097.o neo_2070.o \
-	neo_2090.o neo_2200.o neo_i2c.o neo_shadow.o neo_dga.o
+	neo_2090.o neo_2200.o neo_i2c.o neo_shadow.o neo_dga.o neo_video.o
 
 DEFINES = -DPSZ=8
 
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c	2000-09-26 01:57:08.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c	2002-04-04 16:05:44.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c,v 1.2 1999/06/27 14:08:08 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c,v 1.4 2002/04/04 14:05:44 eich Exp $ */
 
 /*
  * The original Precision Insight driver for
@@ -104,8 +104,6 @@
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     NEOPtr nPtr = NEOPTR(pScrn);
     NEOACLPtr nAcl = NEOACLPTR(pScrn);
-    BoxRec AvailFBArea;
-    int lines;
 
     nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
     if(!infoPtr) return FALSE;
@@ -158,23 +156,7 @@
     default:
 	return FALSE;
     }
-
-    /* Initialize for widths */
-    nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth;
-    lines = nAcl->cacheEnd /
-      (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
-    if(lines > 1024) lines = 1024;
-
-    AvailFBArea.x1 = 0;
-    AvailFBArea.y1 = 0;
-    AvailFBArea.x2 = pScrn->displayWidth;
-    AvailFBArea.y2 = lines;
-    xf86InitFBManager(pScreen, &AvailFBArea); 
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-               "Using %i scanlines of offscreen memory for pixmap caching\n",
-                lines - pScrn->virtualY);
-
+    
     return(XAAInit(pScreen, infoPtr));
 
 }
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c	2001-10-01 15:44:07.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c	2002-04-04 16:05:44.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c,v 1.3 2000/09/19 12:46:17 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c,v 1.6 2002/04/04 14:05:44 eich Exp $ */
 
 /*
  * The original Precision Insight driver for
@@ -101,8 +101,6 @@
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     NEOPtr nPtr = NEOPTR(pScrn);
     NEOACLPtr nAcl = NEOACLPTR(pScrn);
-    BoxRec AvailFBArea;
-    int lines;
 
     nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
     if(!infoPtr) return FALSE;
@@ -197,20 +195,6 @@
 
     nAcl->BltCntlFlags |= NEO_BC3_FIFO_EN;
 
-    lines =  nAcl->cacheEnd /
-      (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
-    if(lines > 1024) lines = 1024;
-
-    AvailFBArea.x1 = 0;
-    AvailFBArea.y1 = 0;
-    AvailFBArea.x2 = pScrn->displayWidth;
-    AvailFBArea.y2 = lines;
-    xf86InitFBManager(pScreen, &AvailFBArea); 
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-               "Using %i scanlines of offscreen memory for pixmap caching\n",
-                lines - pScrn->virtualY);
-
     return(XAAInit(pScreen, infoPtr));
 }
 
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c	2001-10-01 15:44:07.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c	2002-10-09 00:14:09.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c,v 1.6 2000/10/02 18:42:25 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c,v 1.10 2002/10/08 22:14:09 tsi Exp $ */
 
 /*
  * The original Precision Insight driver for
@@ -77,6 +77,7 @@
 							int w, int h,
 							int skipleft);
 static void Neo2097SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+#if 0
 static void Neo2097SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
 					      int patternx,
 					      int patterny,
@@ -87,6 +88,7 @@
 						int patterny, 
 						int x, int y,
 						int w, int h);
+#endif
 static void Neo2097SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
                                 unsigned int planemask,
                                 int transparency_color, int bpp, int depth);
@@ -123,8 +125,6 @@
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     NEOPtr nPtr = NEOPTR(pScrn);
     NEOACLPtr nAcl = NEOACLPTR(pScrn);
-    int lines;
-    BoxRec AvailFBArea;
 
     nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
     if(!infoPtr) return FALSE;
@@ -245,21 +245,7 @@
     default:
 	return FALSE;
     }
-
-    lines =  nAcl->cacheEnd /
-      (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
-    if(lines > 1024) lines = 1024;
-
-    AvailFBArea.x1 = 0;
-    AvailFBArea.y1 = 0;
-    AvailFBArea.x2 = pScrn->displayWidth;
-    AvailFBArea.y2 = lines;
-    xf86InitFBManager(pScreen, &AvailFBArea); 
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-               "Using %i scanlines of offscreen memory for pixmap caching\n",
-	        lines - pScrn->virtualY);
-
+    
     return(XAAInit(pScreen, infoPtr));
 }
 
@@ -454,6 +440,7 @@
 #endif
 }
 
+#if 0
 static void
 Neo2097SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
 				     int patternx,
@@ -513,7 +500,7 @@
     OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
     OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
 }
-
+#endif
 
 static void 
 Neo2097SetupForScanlineImageWrite(        
@@ -555,5 +542,3 @@
 ){
     /* should I be checking for fifo slots here ? */
 }
-
-
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c	2001-10-28 04:33:42.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c	2002-10-09 00:14:10.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c,v 1.14 2001/10/01 13:44:07 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c,v 1.18 2002/10/08 22:14:10 tsi Exp $ */
 /*
  * The original Precision Insight driver for
  * XFree86 v.3.3 has been sponsored by Red Hat.
@@ -78,6 +78,7 @@
 							int w, int h,
 							int skipleft);
 static void Neo2200SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+#if 0
 static void Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
 					       int patternx,
 					       int patterny,
@@ -90,7 +91,7 @@
 						 int patterny, 
 						 int x, int y,
 						 int w, int h);
-
+#endif
 
 
 static unsigned int neo2200Rop[16] = {
@@ -120,8 +121,6 @@
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     NEOPtr nPtr = NEOPTR(pScrn);
     NEOACLPtr nAcl = NEOACLPTR(pScrn);
-    BoxRec AvailFBArea;
-    int lines;
 
     nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
     if(!infoPtr) return FALSE;
@@ -213,7 +212,9 @@
         nAcl->PixelWidth = 2;
 	break;
     case 24:
-	if (nPtr->NeoChipset == NM2360) {
+	if (nPtr->noAccelSet || nPtr->NeoChipset == NM2230
+	    || nPtr->NeoChipset == NM2360
+	    || nPtr->NeoChipset == NM2380) {
 	    nAcl->BltModeFlags = NEO_MODE1_DEPTH24;
             nAcl->PixelWidth = 3;
 	} else
@@ -251,19 +252,6 @@
 	return FALSE;
     }
 
-    lines =  nAcl->cacheEnd /
-      (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
-    if(lines > 1024) lines = 1024;
-
-    AvailFBArea.x1 = 0;
-    AvailFBArea.y1 = 0;
-    AvailFBArea.x2 = pScrn->displayWidth;
-    AvailFBArea.y2 = lines;
-    xf86InitFBManager(pScreen, &AvailFBArea); 
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-               "Using %i scanlines of offscreen memory for pixmap caching\n",
-                lines - pScrn->virtualY);
 
     return(XAAInit(pScreen, infoPtr));
 }
@@ -482,7 +470,7 @@
     NEOPtr nPtr = NEOPTR(pScrn);
 
     WAIT_ENGINE_IDLE();
-    OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+    OUTREG(NEOREG_DSTSTARTOFF, (y <<16) | (x & 0xffff));
     OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
 }
 
@@ -590,6 +578,7 @@
 #endif
 }
 
+#if 0
 static void
 Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
 				     int patternx,
@@ -657,5 +646,4 @@
     OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
     OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
 }
-
-
+#endif
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c	2001-10-28 04:33:42.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c	2001-10-28 04:33:42.000000000 +0100
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.7 2000/11/03 18:46:11 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.8 2001/10/28 03:33:42 tsi Exp $ */
 
 /*
  * The original Precision Insight driver for
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c	2001-10-01 15:44:07.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c	2002-04-04 16:05:44.000000000 +0200
@@ -21,7 +21,7 @@
  *
  * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
  */
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c,v 1.2 2000/09/25 23:57:09 mvojkovi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c,v 1.5 2002/04/04 14:05:44 eich Exp $ */
 
 #include "xf86.h"
 #include "xf86_OSproc.h"
@@ -43,8 +43,10 @@
 static void NEO_SetViewport(ScrnInfoPtr, int, int, int);
 static void NEO_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
 static void NEO_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+#if 0
 static void NEO_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 
 					unsigned long);
+#endif
 
 static
 DGAFunctionRec NEODGAFuncs = {
@@ -76,7 +78,7 @@
    imlines =  (pScrn->videoRam * 1024) /
       (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
 
-   pixlines = (imlines > 1024 && !pNEO->noAccel)  ? 1024 : imlines;
+   pixlines =  (imlines > 1024 && !pNEO->noAccel)  ? 1024 : imlines;
 
    pMode = firstMode = pScrn->modes;
 
@@ -184,7 +186,7 @@
 ){
    NEOPtr pNEO = NEOPTR(pScrn);
    vgaHWPtr hwp = VGAHWPTR(pScrn);
-
+   
    NEOAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
    /* wait for retrace */
    while((hwp->readST01(hwp) & 0x08));
@@ -240,7 +242,7 @@
     }
 }
 
-
+#if 0
 static void 
 NEO_BlitTransRect(
    ScrnInfoPtr pScrn, 
@@ -252,7 +254,7 @@
   /* this one should be separate since the XAA function would
      prohibit usage of ~0 as the key */
 }
-
+#endif
 
 static Bool 
 NEO_OpenFramebuffer(
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c	2001-11-30 13:11:57.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c	2002-09-16 20:05:57.000000000 +0200
@@ -22,7 +22,15 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.57 2001/10/01 13:44:07 eich Exp $ */
+
+/*
+ * Copyright 1998, 1999 Egbert Eich
+ * Copyright 2000, 2001 SuSE GmbH, Author: Egbert Eich
+ * Copyright 2002 SuSE Linux AG, Author: Egbert Eich
+ * Copyright 2002 Shigehiro Nomura
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.63 2002/09/16 18:05:57 eich Exp $ */
 
 /*
  * The original Precision Insight driver for
@@ -229,6 +237,47 @@
 	0.0		/* VRefresh */
 };
 
+static DisplayModeRec neo1024x480Mode = {
+	NULL,           /* prev */
+	NULL,           /* next */   
+	"1024x480",      /* identifier of this mode */
+	MODE_OK,        /* mode status */
+	M_T_BUILTIN,    /* mode type */
+	45900,		/* Clock frequency */
+	1024,		/* HDisplay */
+	1048,		/* HSyncStart */
+	1184,		/* HSyncEnd */
+	1344,		/* HTotal */
+	0,		/* HSkew */
+	480,		/* VDisplay */
+	480,		/* VSyncStart */
+	486,		/* VSyncEnd */
+	488,		/* VTotal */
+	0,		/* VScan */
+	V_PHSYNC | V_PVSYNC,	/* Flags */
+	-1,		/* ClockIndex */
+	45900,		/* SynthClock */
+	1024,		/* CRTC HDisplay */
+	1024,            /* CRTC HBlankStart */
+	1048,            /* CRTC HSyncStart */
+	1184,           /* CRTC HSyncEnd */
+	1072,            /* CRTC HBlankEnd */
+	1344,           /* CRTC HTotal */
+	0,              /* CRTC HSkew */
+	480,		/* CRTC VDisplay */
+	480,		/* CRTC VBlankStart */
+	480,		/* CRTC VSyncStart */
+	486,		/* CRTC VSyncEnd */
+	487,		/* CRTC VBlankEnd */
+	488,		/* CRTC VTotal */
+	FALSE,		/* CrtcHAdjusted */
+	FALSE,		/* CrtcVAdjusted */
+	0,		/* PrivSize */
+	NULL,		/* Private */
+	0.0,		/* HSync */
+	0.0		/* VRefresh */
+};
+
 /*
  * This contains the functions needed by the server after loading the driver
  * module.  It must be supplied, and gets passed back by the SetupProc
@@ -299,7 +348,11 @@
     OPTION_PROG_LCD_MODE_REGS,
     OPTION_PROG_LCD_MODE_STRETCH,
     OPTION_OVERRIDE_VALIDATE_MODE,
+    OPTION_SHOWCACHE,
     OPTION_ROTATE,
+    OPTION_VIDEO_KEY,
+    OPTION_OVERLAYMEM,
+    OPTION_VIDEO_INTERLACE,
     OPTION_DISPLAY_HEIGHT_480,
     OPTION_STRANGE_LOCKUPS
 } NEOOpts;
@@ -314,6 +367,7 @@
     { OPTION_LCD_STRETCH, "NoStretch",	OPTV_BOOLEAN,	{0}, FALSE },
     { OPTION_SHADOW_FB,   "ShadowFB",	OPTV_BOOLEAN,	{0}, FALSE },
     { OPTION_PCI_BURST,	 "pciBurst",	OPTV_BOOLEAN,   {0}, FALSE },
+    { OPTION_SHOWCACHE,  "ShowCache",   OPTV_BOOLEAN,	{0}, FALSE },
     { OPTION_ROTATE, 	 "Rotate",	OPTV_ANYSTR,	{0}, FALSE },
     { OPTION_PROG_LCD_MODE_REGS, "progLcdModeRegs",
       OPTV_BOOLEAN, {0}, FALSE },
@@ -321,6 +375,10 @@
       OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode",
       OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_VIDEO_KEY, "VideoKey",     OPTV_INTEGER,   {0}, FALSE },
+    { OPTION_OVERLAYMEM, "OverlayMem",  OPTV_INTEGER,   {0}, FALSE },
+    { OPTION_VIDEO_INTERLACE, "Interlace",
+      OPTV_INTEGER,   {0}, FALSE },
     { -1,                  NULL,           OPTV_NONE,	{0}, FALSE }
 };
 
@@ -335,6 +393,7 @@
     { OPTION_SHADOW_FB,  "ShadowFB",	OPTV_BOOLEAN,	{0}, FALSE },
     { OPTION_LCD_STRETCH,"NoStretch",	OPTV_BOOLEAN,	{0}, FALSE },
     { OPTION_PCI_BURST,	 "pciBurst",	OPTV_BOOLEAN,	{0}, FALSE },
+    { OPTION_SHOWCACHE,  "ShowCache",   OPTV_BOOLEAN,	{0}, FALSE },
     { OPTION_ROTATE, 	 "Rotate",	OPTV_ANYSTR,	{0}, FALSE },
     { OPTION_STRANGE_LOCKUPS, "StrangeLockups", OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DISPLAY_HEIGHT_480, "DisplayHeight480",
@@ -345,6 +404,10 @@
       OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode",
       OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_VIDEO_KEY, "VideoKey",     OPTV_INTEGER,   {0}, FALSE },
+    { OPTION_OVERLAYMEM, "OverlayMem",  OPTV_INTEGER,   {0}, FALSE },
+    { OPTION_VIDEO_INTERLACE, "Interlace",
+      OPTV_INTEGER,   {0}, FALSE },
     { -1,                  NULL,           OPTV_NONE,	{0}, FALSE }
 };
 
@@ -470,7 +533,7 @@
 	 * The return value must be non-NULL on success even though there
 	 * is no TearDownProc.
 	 */
-	return (pointer)1;
+  	return (pointer)1;
     } else {
 	if (errmaj) *errmaj = LDR_ONCEONLY;
 	return NULL;
@@ -662,6 +725,7 @@
     int w;
     int apertureSize;
     Bool height_480 = FALSE;
+    Bool lcdCenterOptSet = FALSE;
     char *s;
     
     if (flags & PROBE_DETECT)  {
@@ -971,14 +1035,15 @@
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, nPtr->Options);
 
     xf86GetOptValBool(nPtr->Options, OPTION_NOLINEAR_MODE,&nPtr->noLinear);
-    xf86GetOptValBool(nPtr->Options, OPTION_NOACCEL,&nPtr->noAccel);
     xf86GetOptValBool(nPtr->Options, OPTION_SW_CURSOR,&nPtr->swCursor);
     xf86GetOptValBool(nPtr->Options, OPTION_NO_MMIO,&nPtr->noMMIO);
     xf86GetOptValBool(nPtr->Options, OPTION_INTERN_DISP,&nPtr->internDisp);
     xf86GetOptValBool(nPtr->Options, OPTION_EXTERN_DISP,&nPtr->externDisp);
-    xf86GetOptValBool(nPtr->Options, OPTION_LCD_CENTER,&nPtr->lcdCenter);
+    if (xf86GetOptValBool(nPtr->Options, OPTION_LCD_CENTER,&nPtr->lcdCenter))
+	lcdCenterOptSet = TRUE;
     xf86GetOptValBool(nPtr->Options, OPTION_LCD_STRETCH,&nPtr->noLcdStretch);
     xf86GetOptValBool(nPtr->Options, OPTION_SHADOW_FB,&nPtr->shadowFB);
+    xf86GetOptValBool(nPtr->Options, OPTION_SHOWCACHE,&nPtr->showcache);
     nPtr->onPciBurst = TRUE;
     xf86GetOptValBool(nPtr->Options, OPTION_PCI_BURST,&nPtr->onPciBurst);
     xf86GetOptValBool(nPtr->Options,
@@ -991,6 +1056,8 @@
     xf86GetOptValBool(nPtr->Options, OPTION_DISPLAY_HEIGHT_480,&height_480);
     xf86GetOptValBool(nPtr->Options, OPTION_STRANGE_LOCKUPS,
 		      &nPtr->strangeLockups);
+    nPtr->noAccelSet =
+	xf86GetOptValBool(nPtr->Options, OPTION_NOACCEL,&nPtr->noAccel);
     
     nPtr->rotate = 0;
     if ((s = xf86GetOptValString(nPtr->Options, OPTION_ROTATE))) {
@@ -1014,11 +1081,50 @@
 		       "Valid options are \"CW\" or \"CCW\"\n");
       }
     }
+#ifdef XvExtension
+    if(xf86GetOptValInteger(nPtr->Options,
+			    OPTION_VIDEO_KEY, &(nPtr->videoKey))) {
+        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
+		   nPtr->videoKey);
+    } else {
+        nPtr->videoKey = (1 << pScrn->offset.red) | 
+	    (1 << pScrn->offset.green) |
+	    (((pScrn->mask.blue >> pScrn->offset.blue) - 1)
+	     << pScrn->offset.blue); 
+    }
+    if(xf86GetOptValInteger(nPtr->Options, OPTION_OVERLAYMEM,
+			    &(nPtr->overlay))) {
+        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+		   "reserve %d bytes for overlay.\n", nPtr->overlay);
+    } else {
+	nPtr->overlay = 0;
+    }
+    nPtr->interlace = 0;
+    if(xf86GetOptValInteger(nPtr->Options, OPTION_VIDEO_INTERLACE,
+			    &(nPtr->interlace))) {
+	if (nPtr->interlace >= 0  &&  nPtr->interlace <= 2){
+	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "interlace flag = %d\n",
+		       nPtr->interlace);
+	} else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+		       "\"%s\" is not a valid value for "
+		       "Option \"Interlaced\"\n", s);
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid options are  0..2\n");
+        }
+    }
+#endif /* XvExtension */
 
-    if (height_480 && nPtr->NeoPanelWidth == 800) {
+
+    if (height_480
+	&& (nPtr->NeoPanelWidth == 800 || nPtr->NeoPanelWidth == 1024)) {
 	xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
 		   "Overriding Panel height: Set to 480\n");
 	nPtr->NeoPanelHeight = 480;
+	xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
+		   "Disabling LCD stretching for panel height 480\n");
+	nPtr->noLcdStretch = TRUE;
+	if (!lcdCenterOptSet)
+	    nPtr->lcdCenter = TRUE;
     }
     
     if (nPtr->internDisp && nPtr->externDisp)
@@ -1069,6 +1175,9 @@
     if (nPtr->strangeLockups)
 	xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
 		   "Option StrangeLockups set: disabling some acceleration\n");
+    if (nPtr->showcache)
+	xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
+		   "Show chache for debugging\n");
     if (nPtr->shadowFB) {
 	if (nPtr->noLinear) {
     	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1096,6 +1205,8 @@
 	nPtr->NeoLinearAddr = 0;
     }
 
+    nPtr->NeoMMIOAddr2 = 0;
+    nPtr->NeoMMIOBase2 = NULL;
     if (nPtr->pEnt->device->IOBase && !nPtr->noMMIO) {
 	/* XXX Check this matches a PCI base address */
 	nPtr->NeoMMIOAddr = nPtr->pEnt->device->IOBase;
@@ -1113,7 +1224,7 @@
 		       "FB base address is set at 0x%X.\n",
 		       nPtr->NeoLinearAddr);
 	}
-	if (!nPtr->NeoMMIOAddr) {
+	if (!nPtr->NeoMMIOAddr && !nPtr->noMMIO) {
 	    switch (nPtr->NeoChipset) {
 	    case NM2070 :
 		nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000;
@@ -1129,11 +1240,17 @@
 	    case NM2360:
 	    case NM2380:
 		nPtr->NeoMMIOAddr = nPtr->PciInfo->memBase[1];
+		nPtr->NeoMMIOAddr2 = nPtr->PciInfo->memBase[2];
 		break;
 	    }
 	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
 		       "MMIO base address is set at 0x%X.\n",
 		       nPtr->NeoMMIOAddr);
+	    if (nPtr->NeoMMIOAddr2 != 0){
+	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+		           "MMIO base address2 is set at 0x%X.\n",
+		           nPtr->NeoMMIOAddr2);
+	    }
 	}
 	/* XXX What about VGA resources in OPERATING mode? */
 	if (xf86RegisterResources(nPtr->pEnt->index, NULL, ResExclusive))
@@ -1152,7 +1269,7 @@
 		       "FB base address is set at 0x%X.\n",
 		       nPtr->NeoLinearAddr);
 	}
-	if (!nPtr->NeoMMIOAddr) {
+	if (!nPtr->NeoMMIOAddr && !nPtr->noMMIO) {
 	    nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000;
 	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
 		       "MMIO base address is set at 0x%X.\n",
@@ -1210,9 +1327,13 @@
     apertureSize = (pScrn->videoRam * 1024) - nPtr->NeoCursorMem;
 
    if ((nPtr->NeoPanelWidth == 800) && (nPtr->NeoPanelHeight == 480)) {
-    neo800x480Mode.next = pScrn->monitor->Modes;
-    pScrn->monitor->Modes = &neo800x480Mode;
-}
+       neo800x480Mode.next = pScrn->monitor->Modes;
+       pScrn->monitor->Modes = &neo800x480Mode;
+   }
+   if ((nPtr->NeoPanelWidth == 1024) && (nPtr->NeoPanelHeight == 480)) {
+       neo1024x480Mode.next = pScrn->monitor->Modes;
+       pScrn->monitor->Modes = &neo1024x480Mode;
+   }
     /*
      * For external displays, limit the width to 1024 pixels or less.
      */
@@ -1293,6 +1414,10 @@
     /* Should we re-save the text mode on each VT enter? */
     if(!neoModeInit(pScrn, pScrn->currentMode))
       return FALSE;
+#ifdef XvExtension
+    if (nPtr->video)
+	NEOResetVideo(pScrn);
+#endif
     if (nPtr->NeoHWCursorShown) 
 	NeoShowCursor(pScrn);
     NEOAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);    
@@ -1384,12 +1509,12 @@
     /* Map the Neo memory and possible MMIO areas */
     if (!neoMapMem(pScrn))
 	return FALSE;
-
+    
     /*
      * next we save the current state and setup the first mode
      */
     neoSave(pScrn);
-
+    
     if (!neoModeInit(pScrn,pScrn->currentMode))
 	return FALSE;
     vgaHWSaveScreen(pScreen,SCREEN_SAVER_ON);
@@ -1431,7 +1556,7 @@
 	nPtr->ShadowPtr = NULL;
 	FBStart = nPtr->NeoFbBase;
     }
-
+    
     ret = fbScreenInit(pScreen, FBStart,
 			    width, height,
 			    pScrn->xDpi, pScrn->yDpi,
@@ -1509,13 +1634,14 @@
 		   nPtr->NeoLinearAddr);
 	/* Setup pointers to free space in video ram */
 	allocatebase = (pScrn->videoRam << 10);
-	freespace = allocatebase - pScrn->displayWidth * 
+	freespace = allocatebase - pScrn->displayWidth *
 	    pScrn->virtualY * (pScrn->bitsPerPixel >> 3);
 	currentaddr = allocatebase;
 	xf86DrvMsg(scrnIndex, X_PROBED,
 		   "%d bytes off-screen memory available\n", freespace);
 
-	if (nPtr->swCursor || nPtr->noMMIO) {
+	nAcl->CursorAddress = 0;
+	if (nPtr->swCursor || !nPtr->NeoMMIOBase) {
 	    xf86DrvMsg(scrnIndex, X_CONFIG,
 		       "Using Software Cursor.\n");
 	} else if (nPtr->NeoCursorMem <= freespace) {
@@ -1527,42 +1653,79 @@
 	    nAcl->CursorAddress = currentaddr;
 	    xf86DrvMsg(scrnIndex, X_INFO,
 		       "Using H/W Cursor.\n"); 
-	} else xf86DrvMsg(scrnIndex, X_ERROR,
-			  "Too little space for H/W cursor.\n");
+	} else {
+	    xf86DrvMsg(scrnIndex, X_ERROR,
+		       "Too little space for H/W cursor.\n");
+	}
 	
-	if (!nPtr->noAccel && nPtr->noMMIO)
+	if (!nPtr->noAccel && !nPtr->NeoMMIOBase)
 	  xf86DrvMsg(pScrn->scrnIndex,X_INFO,
 		     "Acceleration disabled when not using MMIO\n");
 
+#ifdef XvExtension
+	if (nPtr->overlay > 0){
+	    if (nPtr->overlay > freespace){
+		xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+			   "Can not reserve %d bytes for overlay. "
+			   "Resize to %d bytes.\n",
+			   nPtr->overlay, freespace);
+		nPtr->overlay = freespace;
+	    }
+	    currentaddr -= nPtr->overlay;
+	    freespace -= nPtr->overlay;
+	    nPtr->overlay_offset = currentaddr;
+	    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Overlay at 0x%x\n",
+		       nPtr->overlay_offset);
+	}
+#endif /* XvExtension */
+	nAcl->cacheStart = currentaddr - freespace;
+	nAcl->cacheEnd = currentaddr;
+	freespace = 0;
+	if (nAcl->cacheStart < nAcl->cacheEnd) {
+	    BoxRec AvailFBArea;
+	    int lines = nAcl->cacheEnd /
+		(pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+	    if (!nPtr->noAccel && nPtr->NeoMMIOBase && lines > 1024) 
+		lines = 1024;
+	    AvailFBArea.x1 = 0;
+	    AvailFBArea.y1 = 0;
+	    AvailFBArea.x2 = pScrn->displayWidth;
+	    AvailFBArea.y2 = lines;
+	    xf86InitFBManager(pScreen, &AvailFBArea); 
+	    
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
+		       "Using %i scanlines of offscreen memory \n",
+		       lines - pScrn->virtualY);
+	}
+
 	/* Setup the acceleration primitives */
-	if (!nPtr->noAccel && !nPtr->noMMIO) {
-	    nAcl->cacheStart = currentaddr - freespace;
-	    nAcl->cacheEnd = currentaddr;
-	    freespace = 0;
+	if (!nPtr->noAccel && nPtr->NeoMMIOBase) {
+	    Bool ret = FALSE;
 	    if (nAcl->cacheStart >= nAcl->cacheEnd) {
 		xf86DrvMsg(scrnIndex, X_ERROR,
 			   "Too little space for pixmap cache.\n");
-	    }
+	    } 	    
 	    switch(nPtr->NeoChipset) {
 	    case NM2070 :
-		Neo2070AccelInit(pScreen);
+		ret = Neo2070AccelInit(pScreen);
 		break;
 	    case NM2090 :
 	    case NM2093 :
-		Neo2090AccelInit(pScreen);
+		ret = Neo2090AccelInit(pScreen);
 		break;
 	    case NM2097 :
 	    case NM2160 :
-		Neo2097AccelInit(pScreen);
+		ret = Neo2097AccelInit(pScreen);
 		break;
 	    case NM2200 :
 	    case NM2230 :
 	    case NM2360 :
 	    case NM2380 :
-	        Neo2200AccelInit(pScreen);
+	        ret = Neo2200AccelInit(pScreen);
 		break;
 	    }
-	    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Acceleration Initialized\n");
+	    xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+		       "Acceleration %s Initialized\n",ret ? "" : "not");
 	} 
 
 	miInitializeBackingStore(pScreen);
@@ -1624,6 +1787,8 @@
 
     pScrn->racIoFlags = pScrn->racMemFlags = racflag;
 
+    NEOInitVideo(pScreen);
+
     pScreen->SaveScreen = vgaHWSaveScreen;
 
     /* Setup DPMS mode */
@@ -1635,18 +1800,7 @@
         pScrn->memPhysBase = (unsigned long)nPtr->NeoFbBase;
 	pScrn->fbOffset = 0;
     }
-
-#ifdef XvExtension
-    {
-        XF86VideoAdaptorPtr *ptr;
-	int n;
-	
-	n = xf86XVListGenericAdaptors(pScrn,&ptr);
-	if (n)
-	    xf86XVScreenInit(pScreen, ptr, n);
-    }
-#endif
-
+    
     /* Wrap the current CloseScreen function */
     nPtr->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = NEOCloseScreen;
@@ -1677,11 +1831,21 @@
     int Base; 
 
     pScrn = xf86Screens[scrnIndex];
-    Base = (y * pScrn->displayWidth + x) >> 2;
     hwp = VGAHWPTR(pScrn);
     nPtr = NEOPTR(pScrn);
-    /* Scale Base by the number of bytes per pixel. */
 
+    if (nPtr->showcache && y) {
+	int lastline = nPtr->NeoFbMapSize / 
+	    ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8);
+	
+	lastline -= pScrn->currentMode->VDisplay;
+	y += pScrn->virtualY - 1;
+        if (y > lastline) y = lastline;
+    }
+
+    Base = (y * pScrn->displayWidth + x) >> 2;
+
+    /* Scale Base by the number of bytes per pixel. */
     switch (pScrn->depth) {
     case  8 :
 	break;
@@ -1730,6 +1894,7 @@
 	if (nPtr->NeoHWCursorShown)
 	    NeoHideCursor(pScrn);
 	neoRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &nPtr->NeoSavedReg, TRUE);
+
 	neoLock(pScrn);
 	neoUnmapMem(pScrn);
     }
@@ -1796,6 +1961,8 @@
 	    case 1024 :
 		if (mode->VDisplay == 768)
 		    return(MODE_OK);
+		if ((mode->VDisplay == 480) && (nPtr->NeoPanelHeight == 480))
+		    return(MODE_OK);
 		break;
 	    case  800 :
 		if (mode->VDisplay == 600) 
@@ -1807,6 +1974,14 @@
 		if (mode->VDisplay == 480)
 		    return(MODE_OK);
 		break;
+#if 1
+	    case 320:
+		if (mode->VDisplay == 240)
+		    return(MODE_OK);
+		break;
+#endif
+	    default:
+		break;
 	    }
 
 	    xf86DrvMsg(scrnIndex, X_INFO, "Removing mode (%dx%d) that won't "
@@ -1845,12 +2020,18 @@
 
     if (!nPtr->noLinear) {
 	if (!nPtr->noMMIO) {
-	    if (nPtr->pEnt->location.type == BUS_PCI)
+	    if (nPtr->pEnt->location.type == BUS_PCI){
 		nPtr->NeoMMIOBase =
 		    xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
 				  nPtr->PciTag, nPtr->NeoMMIOAddr,
 				  0x200000L);
-	    else
+		if (nPtr->NeoMMIOAddr2 != 0){
+		    nPtr->NeoMMIOBase2 =
+		        xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+				      nPtr->PciTag, nPtr->NeoMMIOAddr2,
+				      0x100000L);
+		}
+	    } else
 		nPtr->NeoMMIOBase =
 		    xf86MapVidMem(pScrn->scrnIndex,
 				  VIDMEM_MMIO, nPtr->NeoMMIOAddr,
@@ -1889,8 +2070,14 @@
     NEOPtr nPtr = NEOPTR(pScrn);
 
     if (!nPtr->noLinear) {
-      xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase, 0x200000L);
+      if (nPtr->NeoMMIOBase)
+	  xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase,
+			  0x200000L);
       nPtr->NeoMMIOBase = NULL;
+      if (nPtr->NeoMMIOBase2)
+	  xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase2,
+			  0x100000L);
+      nPtr->NeoMMIOBase2 = NULL;
       xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoFbBase,
 		    nPtr->NeoFbMapSize); 
     }
@@ -2000,6 +2187,14 @@
     Bool noProgramShadowRegs;
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     NEOPtr nPtr = NEOPTR(pScrn);
+    Bool prog_lcd;
+
+    /*
+     * If display is external only and we want internal
+     * we need to program the shadow registers.
+     */
+    prog_lcd = (((VGArGR(0x20) & 0x3) == 0x1) && nPtr->internDisp);
+
     
     /*
      * Convoluted logic for shadow register programming.
@@ -2011,7 +2206,7 @@
     case NM2070:
 	/* Program the shadow regs by default */
 	noProgramShadowRegs = FALSE;
-	if (!nPtr->progLcdRegs)
+	if (!nPtr->progLcdRegs && !prog_lcd)
 	    noProgramShadowRegs = TRUE;
 
 	if (restore->PanelDispCntlReg2 & 0x84) {
@@ -2032,7 +2227,7 @@
     default:
 	/* Don't program the shadow regs by default */
 	noProgramShadowRegs = TRUE;
-	if (nPtr->progLcdRegs)
+	if (nPtr->progLcdRegs || prog_lcd)
 	    noProgramShadowRegs = FALSE;
 
 	if (restore->PanelDispCntlReg2 & 0x84) {
@@ -2044,7 +2239,7 @@
     }
 
     if (noProgramShadowRegs) {
-	xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,3,"Not programming shadow registers\n");
+	xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,5,"Not programming shadow registers\n");
 	if (nPtr->NeoSavedReg.reg){
 	    for (i = 0x40; i <= 0x59; i++) {
 		VGAwCR(i, nPtr->NeoSavedReg.reg->CR[i]);
@@ -2080,112 +2275,149 @@
 	    break;
 	case 800 :
 	    switch (nPtr->NeoPanelHeight) {
-		case 600:
-		    VGAwCR(0x40,0x7F);
-		    VGAwCR(0x41,0x63);
-		    VGAwCR(0x42,0x02);
-		    VGAwCR(0x43,0x6C);
-		    VGAwCR(0x44,0x1C);
-		    VGAwCR(0x45,0x72);
-		    VGAwCR(0x46,0xE0);
-		    VGAwCR(0x47,0x58);
-		    VGAwCR(0x48,0x0C);
-		    VGAwCR(0x49,0x57);
-		    VGAwCR(0x4A,0x73);
-		    VGAwCR(0x4B,0x3D);
-		    VGAwCR(0x4C,0x31);
-		    VGAwCR(0x4D,0x01);
-		    VGAwCR(0x4E,0x36);
-		    VGAwCR(0x4F,0x1E);
-		    if (nPtr->NeoChipset != NM2070) {
-			VGAwCR(0x50,0x6B);
-			VGAwCR(0x51,0x4F);
-			VGAwCR(0x52,0x0E);
-			VGAwCR(0x53,0x58);
-			VGAwCR(0x54,0x88);
-			VGAwCR(0x55,0x33);
-			VGAwCR(0x56,0x27);
-			VGAwCR(0x57,0x16);
-			VGAwCR(0x58,0x2C);
-			VGAwCR(0x59,0x94);
-		    }
-		    break;
-	    case 480:
-		    VGAwCR(0x40,0x7F);
-		    VGAwCR(0x41,0x63);
-		    VGAwCR(0x42,0x02);
-		    VGAwCR(0x43,0x6B);
-		    VGAwCR(0x44,0x1B);
-		    VGAwCR(0x45,0x72);
-		    VGAwCR(0x46,0xE0);
-		    VGAwCR(0x47,0x1C);
-		    VGAwCR(0x48,0x00);
-		    VGAwCR(0x49,0x57);
-		    VGAwCR(0x4A,0x73);
-		    VGAwCR(0x4B,0x3E);
-		    VGAwCR(0x4C,0x31);
-		    VGAwCR(0x4D,0x01);
-		    VGAwCR(0x4E,0x36);
-		    VGAwCR(0x4F,0x1E);
+	    case 600:
+		VGAwCR(0x40,0x7F);
+		VGAwCR(0x41,0x63);
+		VGAwCR(0x42,0x02);
+		VGAwCR(0x43,0x6C);
+		VGAwCR(0x44,0x1C);
+		VGAwCR(0x45,0x72);
+		VGAwCR(0x46,0xE0);
+		VGAwCR(0x47,0x58);
+		VGAwCR(0x48,0x0C);
+		VGAwCR(0x49,0x57);
+		VGAwCR(0x4A,0x73);
+		VGAwCR(0x4B,0x3D);
+		VGAwCR(0x4C,0x31);
+		VGAwCR(0x4D,0x01);
+		VGAwCR(0x4E,0x36);
+		VGAwCR(0x4F,0x1E);
+		if (nPtr->NeoChipset != NM2070) {
 		    VGAwCR(0x50,0x6B);
 		    VGAwCR(0x51,0x4F);
 		    VGAwCR(0x52,0x0E);
-		    VGAwCR(0x53,0x57);
-		    VGAwCR(0x54,0x87);
+		    VGAwCR(0x53,0x58);
+		    VGAwCR(0x54,0x88);
 		    VGAwCR(0x55,0x33);
 		    VGAwCR(0x56,0x27);
 		    VGAwCR(0x57,0x16);
 		    VGAwCR(0x58,0x2C);
 		    VGAwCR(0x59,0x94);
-		    break;
+		}
+		break;
+	    case 480:
+		VGAwCR(0x40,0x7F);
+		VGAwCR(0x41,0x63);
+		VGAwCR(0x42,0x02);
+		VGAwCR(0x43,0x6B);
+		VGAwCR(0x44,0x1B);
+		VGAwCR(0x45,0x72);
+		VGAwCR(0x46,0xE0);
+		VGAwCR(0x47,0x1C);
+		VGAwCR(0x48,0x00);
+		VGAwCR(0x49,0x57);
+		VGAwCR(0x4A,0x73);
+		VGAwCR(0x4B,0x3E);
+		VGAwCR(0x4C,0x31);
+		VGAwCR(0x4D,0x01);
+		VGAwCR(0x4E,0x36);
+		VGAwCR(0x4F,0x1E);
+		VGAwCR(0x50,0x6B);
+		VGAwCR(0x51,0x4F);
+		VGAwCR(0x52,0x0E);
+		VGAwCR(0x53,0x57);
+		VGAwCR(0x54,0x87);
+		VGAwCR(0x55,0x33);
+		VGAwCR(0x56,0x27);
+		VGAwCR(0x57,0x16);
+		VGAwCR(0x58,0x2C);
+		VGAwCR(0x59,0x94);
+		break;
 		break;
 		/* Not done */
 	    }
 	    break;
 	case 1024 :
-	    VGAwCR(0x40,0xA3);
-	    VGAwCR(0x41,0x7F);
-	    VGAwCR(0x42,0x06);
-	    VGAwCR(0x43,0x85);
-	    VGAwCR(0x44,0x96);
-	    VGAwCR(0x45,0x24);
-	    VGAwCR(0x46,0xE5);
-	    VGAwCR(0x47,0x02);
-	    VGAwCR(0x48,0x08);
-	    VGAwCR(0x49,0xFF);
-	    VGAwCR(0x4A,0x25);
-	    VGAwCR(0x4B,0x4F);
-	    VGAwCR(0x4C,0x40);
-	    VGAwCR(0x4D,0x00);
-	    VGAwCR(0x4E,0x44);
-	    VGAwCR(0x4F,0x0C);
-	    VGAwCR(0x50,0x7A);
-	    VGAwCR(0x51,0x56);
-	    VGAwCR(0x52,0x00);
-	    VGAwCR(0x53,0x5D);
-	    VGAwCR(0x54,0x0E);
-	    VGAwCR(0x55,0x3B);
-	    VGAwCR(0x56,0x2B);
-	    VGAwCR(0x57,0x00);
-	    VGAwCR(0x58,0x2F);
-	    VGAwCR(0x59,0x18);
-	    VGAwCR(0x60,0x88);
-	    VGAwCR(0x61,0x63);
-	    VGAwCR(0x62,0x0B);
-	    VGAwCR(0x63,0x69);
-	    VGAwCR(0x64,0x1A);
+	    switch (nPtr->NeoPanelHeight) {
+	    case 768:
+		VGAwCR(0x40,0xA3);
+		VGAwCR(0x41,0x7F);
+		VGAwCR(0x42,0x06);
+		VGAwCR(0x43,0x85);
+		VGAwCR(0x44,0x96);
+		VGAwCR(0x45,0x24);
+		VGAwCR(0x46,0xE5);
+		VGAwCR(0x47,0x02);
+		VGAwCR(0x48,0x08);
+		VGAwCR(0x49,0xFF);
+		VGAwCR(0x4A,0x25);
+		VGAwCR(0x4B,0x4F);
+		VGAwCR(0x4C,0x40);
+		VGAwCR(0x4D,0x00);
+		VGAwCR(0x4E,0x44);
+		VGAwCR(0x4F,0x0C);
+		VGAwCR(0x50,0x7A);
+		VGAwCR(0x51,0x56);
+		VGAwCR(0x52,0x00);
+		VGAwCR(0x53,0x5D);
+		VGAwCR(0x54,0x0E);
+		VGAwCR(0x55,0x3B);
+		VGAwCR(0x56,0x2B);
+		VGAwCR(0x57,0x00);
+		VGAwCR(0x58,0x2F);
+		VGAwCR(0x59,0x18);
+		VGAwCR(0x60,0x88);
+		VGAwCR(0x61,0x63);
+		VGAwCR(0x62,0x0B);
+		VGAwCR(0x63,0x69);
+		VGAwCR(0x64,0x1A);
+		break;
+	    case 480:
+		VGAwCR(0x40,0xA3);
+		VGAwCR(0x41,0x7F);
+		VGAwCR(0x42,0x1B);
+		VGAwCR(0x43,0x89);
+		VGAwCR(0x44,0x16);
+		VGAwCR(0x45,0x0B);
+		VGAwCR(0x46,0x2C);
+		VGAwCR(0x47,0xE8);
+		VGAwCR(0x48,0x0C);
+		VGAwCR(0x49,0xE7);
+		VGAwCR(0x4A,0x09);
+		VGAwCR(0x4B,0x4F);
+		VGAwCR(0x4C,0x40);
+		VGAwCR(0x4D,0x00);
+		VGAwCR(0x4E,0x44);
+		VGAwCR(0x4F,0x0C);
+		VGAwCR(0x50,0x7A);
+		VGAwCR(0x51,0x56);
+		VGAwCR(0x52,0x00);
+		VGAwCR(0x53,0x5D);
+		VGAwCR(0x54,0x0E);
+		VGAwCR(0x55,0x3B);
+		VGAwCR(0x56,0x2A);
+		VGAwCR(0x57,0x00);
+		VGAwCR(0x58,0x2F);
+		VGAwCR(0x59,0x18);
+		VGAwCR(0x60,0x88);
+		VGAwCR(0x61,0x63);
+		VGAwCR(0x62,0x0B);
+		VGAwCR(0x63,0x69);
+		VGAwCR(0x64,0x1A);
+		break;
+	    }
 	    break;
 	case 1280:
 #ifdef NOT_DONE
 	    VGAwCR(0x40,0x?? );
             .
-	    .
-	    .
-	    VGAwCR(0x64,0x?? );
-	    break;
+		.
+		.
+		VGAwCR(0x64,0x?? );
+		break;
 #else
-            /* Probe should prevent this case for now */
-            FatalError("1280 panel support incomplete\n");
+		/* Probe should prevent this case for now */
+		FatalError("1280 panel support incomplete\n");
 #endif
 	}
     }
@@ -2200,7 +2432,7 @@
     unsigned char temp;
     int i;
     Bool clock_hi = FALSE;
-    
+
     vgaHWProtect(pScrn,TRUE);		/* Blank the screen */
     
     VGAwGR(0x09,0x26);
@@ -2220,6 +2452,7 @@
      * any reserved bits.
      */
     temp = VGArGR(0x90);
+
     switch (nPtr->NeoChipset) {
     case NM2070 :
 	temp &= 0xF0; /* Save bits 7:4 */
@@ -2238,6 +2471,7 @@
 	break;
     }
     VGAwGR(0x90,temp);
+
     /*
      * In some rare cases a lockup might occur if we don't delay
      * here. (Reported by Miles Lane)
@@ -2256,7 +2490,6 @@
      * had time to take effect.
      */
     xf86UDelay(200000);
-
     /*
      * This function handles restoring the generic VGA registers.  */
     vgaHWRestore(pScrn, VgaReg,
@@ -2273,6 +2506,7 @@
     VGAwGR(0x11, restore->SysIfaceCntl2);
     VGAwGR(0x15, restore->SingleAddrPage);
     VGAwGR(0x16, restore->DualAddrPage);
+
     temp = VGArGR(0x20);
     switch (nPtr->NeoChipset) {
     case NM2070 :
@@ -2295,6 +2529,7 @@
 	break;
     }
     VGAwGR(0x20, temp);
+
     temp = VGArGR(0x25);
     temp &= 0x38; /* Save bits 5:3 */
     temp |= (restore->PanelDispCntlReg2 & ~0x38);
@@ -2349,7 +2584,7 @@
     }
     if (restore->biosMode)
 	VGAwCR(0x23,restore->biosMode);
-    
+
     if (restore->reg) {
 	VGAwCR(0x23,restore->reg->CR[0x23]);
 	VGAwCR(0x25,restore->reg->CR[0x25]);
@@ -2371,13 +2606,13 @@
 	    VGAwGR(i, restore->reg->GR[i]);
 	}
     }
+
     /* Program vertical extension register */
     if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230
 	|| nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) {
 	VGAwCR(0x70, restore->VerticalExt);
     }
-
-
+    
     vgaHWProtect(pScrn, FALSE);		/* Turn on screen */
 
 }
@@ -2392,7 +2627,8 @@
     NeoRegPtr NeoNew = &nPtr->NeoModeReg;
     vgaRegPtr NeoStd = &hwp->ModeReg;
     Bool noLcdStretch = nPtr->noLcdStretch;
-
+    int clockMul = 1;
+    
     neoUnlock(pScrn);
 
     /*
@@ -2559,7 +2795,7 @@
     } else if (mode->Flags & V_DBLSCAN) {
 	nAcl->NoCursorMode = TRUE;
     }
-
+        
     /*
      * If the screen is to be centerd, turn on the centering for the
      * various modes.
@@ -2574,32 +2810,57 @@
     NeoNew->PanelHorizCenterReg3 = 0x00;
     NeoNew->PanelHorizCenterReg4 = 0x00;
     NeoNew->PanelHorizCenterReg5 = 0x00;
-
+    
     if (nPtr->lcdCenter &&
 	(NeoNew->PanelDispCntlReg1 & 0x02)) {
+	Bool doCenter = FALSE;
+	
+	hoffset = 0;
+	voffset = 0;
 	if (mode->HDisplay == nPtr->NeoPanelWidth) {
 	    /*
 	     * No centering required when the requested display width
 	     * equals the panel width.
 	     */
 	} else {
-	    NeoNew->PanelDispCntlReg2 |= 0x01;
 	    NeoNew->PanelDispCntlReg3 |= 0x10;
-
-	    /* Calculate the horizontal and vertical offsets. */
 	    if (noLcdStretch) {
-		hoffset = ((nPtr->NeoPanelWidth - mode->HDisplay) >> 4) - 1;
-		voffset = ((nPtr->NeoPanelHeight - mode->VDisplay) >> 1) - 2;
+		/* Calculate the horizontal offsets. */
+		int HDisplay = mode->HDisplay
+		    << ((mode->VDisplay < 480) ? 1 : 0);
+		hoffset = ((nPtr->NeoPanelWidth - HDisplay) >> 4) - 1;
+		if (mode->VDisplay <= 480)
+		    hoffset >>= 1;
+		doCenter = TRUE;
 	    } else {
 		/* Stretched modes cannot be centered. */
 		hoffset = 0;
+	    }
+	}
+	if (mode->VDisplay == nPtr->NeoPanelHeight) {
+	    /*
+	     * No centering required when the requested display width
+	     * equals the panel width.
+	     */
+	} else {	
+	    NeoNew->PanelDispCntlReg2 |= 0x01;
+	    if (noLcdStretch) {
+		/* Calculate the vertical offsets. */
+		int VDisplay = mode->VDisplay
+		    << ((mode->Flags | V_DBLSCAN) ? 1 : 0);
+		voffset = ((nPtr->NeoPanelHeight - VDisplay) >> 1) - 2;
+		doCenter = TRUE;
+	    } else {
+		/* Stretched modes cannot be centered. */
 		voffset = 0;
 	    }
+	}
 
+	if (doCenter) {
 	    switch (mode->HDisplay) {
 	    case  320 : /* Needs testing.  KEM -- 24 May 98 */
-		NeoNew->PanelHorizCenterReg3 = hoffset;
-		NeoNew->PanelVertCenterReg2  = voffset;
+  		NeoNew->PanelHorizCenterReg3 = hoffset;
+		NeoNew->PanelVertCenterReg3  = voffset;
 		break;
 	    case  400 : /* Needs testing.  KEM -- 24 May 98 */
 		NeoNew->PanelHorizCenterReg4 = hoffset;
@@ -2632,6 +2893,25 @@
 	    }
 	}
     }
+    
+#ifdef XvExtension
+    if (!noLcdStretch &&
+	(NeoNew->PanelDispCntlReg1 & 0x02))  {
+	if (mode->HDisplay != nPtr->NeoPanelWidth)
+	    nPtr->videoHZoom = (double)nPtr->NeoPanelWidth/mode->HDisplay;
+	if (mode->VDisplay != nPtr->NeoPanelHeight)
+	    nPtr->videoVZoom = (double)nPtr->NeoPanelHeight/mode->VDisplay;
+    } else {
+	nPtr->videoHZoom = 1.0;
+	nPtr->videoVZoom = 1.0;
+    }
+#endif
+
+    if (mode->VDisplay <= 480) {
+	NeoStd->Sequencer[1] |= 0x8;
+	clockMul = 2;
+    }
+    
     NeoNew->biosMode = neoFindMode(mode->HDisplay,mode->VDisplay,pScrn->depth);
     
     /*
@@ -2649,7 +2929,7 @@
      * Calculate the VCLK that most closely matches the requested dot
      * clock.
      */
-    neoCalcVCLK(pScrn, mode->SynthClock);
+    neoCalcVCLK(pScrn, mode->SynthClock*clockMul);
 
     /* Since we program the clocks ourselves, always use VCLK3. */
     NeoStd->MiscOutReg |= 0x0C;
@@ -2764,9 +3044,8 @@
     }
 
     /* Turn the screen on/off */
-    outb(0x3C4, 0x01);
-    SEQ01 |= inb(0x3C5) & ~0x20;
-    outb(0x3C5, SEQ01);
+    SEQ01 |= VGArSR(0x01) & ~0x20;
+    VGAwSR(0x01, SEQ01);
 
     /* Turn the LCD on/off */
     LCD_on |= VGArGR(0x20) & ~0x02;
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h	2001-10-01 15:44:07.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h	2002-09-16 20:05:57.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.17 2000/11/03 18:46:11 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.22 2002/09/16 18:05:57 eich Exp $ */
 
 /*
  * The original Precision Insight driver for
@@ -60,6 +60,11 @@
 
 #include "xf86i2c.h"
 
+#ifdef XvExtension
+# include "xf86xv.h"
+# include "Xv.h"
+#endif /* XvExtension */
+
 /*
  * Driver data structures.
  */
@@ -121,6 +126,10 @@
 /* in neo_dga.c */
 Bool NEODGAInit(ScreenPtr pScreen);
 
+/* in neo_video.c */
+extern void NEOInitVideo(ScreenPtr pScreen);
+extern void NEOResetVideo(ScrnInfoPtr pScrn);
+
 /* shadow regs */
 
 #define NEO_EXT_CR_MAX 0x85
@@ -154,6 +163,7 @@
     unsigned char PanelHorizCenterReg3;
     unsigned char PanelHorizCenterReg4;
     unsigned char PanelHorizCenterReg5;
+    unsigned char Sequencer1;
     Bool ProgramVCLK;
     unsigned char VCLK3NumeratorLow;
     unsigned char VCLK3NumeratorHigh;
@@ -199,6 +209,8 @@
     unsigned long NeoMMIOAddr;
     unsigned long NeoLinearAddr;
     unsigned char* NeoMMIOBase;
+    unsigned long NeoMMIOAddr2;
+    unsigned char* NeoMMIOBase2;
     unsigned char* NeoFbBase;
     long NeoFbMapSize;
     unsigned long vgaIOBase;
@@ -224,6 +236,7 @@
     OptionInfoPtr Options;
     Bool noLinear;
     Bool noAccel;
+    Bool noAccelSet;
     Bool swCursor;
     Bool noMMIO;
     Bool internDisp;
@@ -249,6 +262,17 @@
     RefreshAreaFuncPtr refreshArea;
     void	(*PointerMoved)(int index, int x, int y);
     int rotate;
+    Bool showcache;
+#ifdef XvExtension
+    Bool video;
+    double videoHZoom;
+    double videoVZoom;
+    XF86VideoAdaptorPtr overlayAdaptor;
+    int overlay;
+    int overlay_offset;
+    int videoKey;
+    int interlace;
+#endif /* XvExtension */
 } NEORec, *NEOPtr;
 
 typedef struct {
@@ -264,18 +288,20 @@
 #define GRAX	0x3CE
 
 /* vga IO functions */
-#define VGArCR(index) hwp->readCrtc(hwp,index)
-#define VGAwCR(index,val) hwp->writeCrtc(hwp,index,val)
-#define VGArGR(index) hwp->readGr(hwp,index)
-#define VGAwGR(index,val) hwp->writeGr(hwp,index,val)
+#define VGArCR(index)		(*hwp->readCrtc)(hwp, index)
+#define VGAwCR(index, val)	(*hwp->writeCrtc)(hwp, index, val)
+#define VGArGR(index)		(*hwp->readGr)(hwp, index)
+#define VGAwGR(index, val)	(*hwp->writeGr)(hwp, index, val)
+#define VGArSR(index)		(*hwp->readSeq)(hwp, index)
+#define VGAwSR(index, val)	(*hwp->writeSeq)(hwp, index, val)
 
 /* memory mapped register access macros */
-#define INREG8(addr) MMIO_IN8(nPtr->NeoMMIOBase, (addr))
-#define INREG16(addr) MMIO_IN16(nPtr->NeoMMIOBase, (addr))
-#define INREG(addr) MMIO_IN32(nPtr->NeoMMIOBase, (addr))
-#define OUTREG8(addr, val) MMIO_OUT8(nPtr->NeoMMIOBase, (addr), (val))
-#define OUTREG16(addr, val) MMIO_OUT16(nPtr->NeoMMIOBase, (addr), (val))
-#define OUTREG(addr, val) MMIO_OUT32(nPtr->NeoMMIOBase, (addr), (val))
+#define INREG8(addr)		MMIO_IN8(nPtr->NeoMMIOBase, addr)
+#define INREG16(addr)		MMIO_IN16(nPtr->NeoMMIOBase, addr)
+#define INREG(addr)		MMIO_IN32(nPtr->NeoMMIOBase, addr)
+#define OUTREG8(addr, val)	MMIO_OUT8(nPtr->NeoMMIOBase, addr, val)
+#define OUTREG16(addr, val)	MMIO_OUT16(nPtr->NeoMMIOBase, addr, val)
+#define OUTREG(addr, val)	MMIO_OUT32(nPtr->NeoMMIOBase, addr, val)
 
 /* This swizzle macro is to support the manipulation of cursor masks when
  * the sprite moves off the left edge of the display.  This code is
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c	2000-11-03 19:46:11.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c	2002-09-16 20:05:58.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.1 1999/04/17 07:06:26 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.4 2002/09/16 18:05:58 eich Exp $ */
 
 /*
  * The original Precision Insight driver for
@@ -79,8 +79,8 @@
     NEOPtr pNeo = NEOPTR(pScrn);
     I2CBusPtr I2CPtr;
 
-
     I2CPtr = xf86CreateI2CBusRec();
+
     if(!I2CPtr) return FALSE;
 
     pNeo->I2C = I2CPtr;
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h	1999-04-17 09:06:27.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h	1999-04-17 09:06:27.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86$ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h,v 1.1 1999/04/17 07:06:27 dawes Exp $ */
 
 /*
  * The original Precision Insight driver for
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neomagic.man xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neomagic.man
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neomagic.man	2001-12-17 21:52:32.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neomagic.man	2001-12-17 21:52:32.000000000 +0100
@@ -1,4 +1,4 @@
-.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neomagic.man,v 1.2 2001/01/27 18:20:51 dawes Exp $ 
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neomagic.man,v 1.3 2001/12/17 20:52:32 dawes Exp $ 
 .\" shorthand for double quote that works everywhere.
 .ds q \N'34'
 .TH NEOMAGIC __drivermansuffix__ __vendorversion__
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h	1999-04-17 09:06:29.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h	1999-04-17 09:06:29.000000000 +0200
@@ -22,7 +22,7 @@
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **********************************************************************/
-/* $XFree86$ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h,v 1.1 1999/04/17 07:06:29 dawes Exp $ */
 
 /*
  * The original Precision Insight driver for
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c	2001-06-14 04:23:49.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c	2001-06-14 04:23:49.000000000 +0200
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c,v 1.2 2000/11/03 18:46:11 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c,v 1.3 2001/06/14 02:23:49 keithp Exp $ */
 
 /*
    Copyright (c) 1999, 2000 The XFree86 Project Inc. 
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.c xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.c
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.c	1970-01-01 01:00:00.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.c	2002-09-16 20:05:58.000000000 +0200
@@ -0,0 +1,1233 @@
+/**********************************************************************
+Copyright 2002 by Shigehiro Nomura.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Shigehiro Nomura not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  Shigehiro Nomura
+and its suppliers make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or 
+implied warranty.
+
+SHIGEHIRO NOMURA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL SHIGEHIRO NOMURA AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+
+/*
+ * Copyright 2002 SuSE Linux AG, Author: Egbert Eich
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.c,v 1.3 2002/09/16 18:05:58 eich Exp $ */
+
+#include "neo.h"
+#include "neo_video.h"
+
+#define nElems(x)		(sizeof(x) / sizeof(x[0]))
+#define MAKE_ATOM(a)	MakeAtom(a, sizeof(a) - 1, TRUE)
+
+#if defined(XvExtension)
+
+#include "dixstruct.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+static XF86VideoAdaptorPtr NEOSetupVideo(ScreenPtr);
+
+static int NEOPutVideo(ScrnInfoPtr, short, short, short, short, 
+		       short, short, short, short, RegionPtr, pointer);
+
+static void NEOStopVideo(ScrnInfoPtr, pointer, Bool);
+static int NEOSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int NEOGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);
+static void NEOQueryBestSize(ScrnInfoPtr, Bool, short, short, short, 
+			     short, unsigned int *, unsigned int *, pointer);
+static int NEOPutImage(ScrnInfoPtr, short, short, short, short, short, short, 
+		       short, short, int, unsigned char *, short, short, Bool,
+		       RegionPtr, pointer);
+static int NEOQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, 
+				   unsigned short *, int *, int *);
+
+static Bool RegionsEqual(RegionPtr, RegionPtr);
+static void NEODisplayVideo(ScrnInfoPtr, int, int, short, short, int, int, 
+			    int, int, int, BoxPtr, short, short, short, short);
+
+static void NEOInitOffscreenImages(ScreenPtr);
+static FBLinearPtr NEOAllocateMemory(ScrnInfoPtr, FBLinearPtr, int);
+static void NEOCopyData(unsigned char *, unsigned char *, int, int, int, int);
+static void NEOCopyYV12Data(unsigned char *, unsigned char *, unsigned char *,
+			    unsigned char *, int, int, int, int, int);
+
+static int NEOAllocSurface(ScrnInfoPtr, int, unsigned short, unsigned short, 
+			   XF86SurfacePtr);
+static int NEOFreeSurface(XF86SurfacePtr);
+static int NEODisplaySurface(XF86SurfacePtr, short, short, short, short, 
+			     short, short, short, short, RegionPtr clipBoxes);
+static int NEOStopSurface(XF86SurfacePtr);
+static int NEOGetSurfaceAttribute(ScrnInfoPtr, Atom, INT32 *);
+static int NEOSetSurfaceAttribute(ScrnInfoPtr, Atom, INT32);
+
+static Atom xvColorKey, xvBrightness, xvInterlace;
+
+void
+NEOInitVideo(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    NEOPtr nPtr = NEOPTR(pScrn);
+    XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
+    XF86VideoAdaptorPtr newAdaptor = NULL;
+    int numAdaptors;
+
+    numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors);
+
+    if (nPtr->NeoChipset >= NM2160 
+	&& !nPtr->noLinear 
+	&& nPtr->NeoMMIOBase2 != NULL){
+	nPtr->video = TRUE;
+	newAdaptor = NEOSetupVideo(pScreen);
+	NEOInitOffscreenImages(pScreen);
+    } else
+	nPtr->video = FALSE;
+
+    if (newAdaptor){
+	if (!numAdaptors){
+	    numAdaptors = 1;
+	    overlayAdaptors = &newAdaptor;
+	} else {
+	    newAdaptors = xalloc((numAdaptors + 1) 
+				 * sizeof(XF86VideoAdaptorPtr*));
+	    if (newAdaptors){
+		memcpy(newAdaptors, overlayAdaptors, 
+		       numAdaptors * sizeof(XF86VideoAdaptorPtr));
+		newAdaptors[numAdaptors++] = newAdaptor;
+		overlayAdaptors = newAdaptors;
+	    }
+	}
+    }
+
+    if (numAdaptors)
+	xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors);
+
+    if (newAdaptors)
+	xfree(newAdaptors);
+}
+
+static XF86VideoEncodingRec NEOVideoEncodings[] =
+{
+    {
+	NEO_VIDEO_VIDEO,
+	"XV_VIDEO",
+	1024, 1024,
+	{1, 1}
+    },
+    {
+	NEO_VIDEO_IMAGE,
+	"XV_IMAGE",
+	1024, 1024,
+	{1, 1}
+    }
+};
+
+static XF86VideoFormatRec NEOVideoFormats[] =
+{
+    {  8, PseudoColor },
+    { 15, TrueColor },
+    { 16, TrueColor },
+    { 24, TrueColor },
+};
+
+static XF86AttributeRec NEOVideoAttributes[] =
+{
+    {
+	XvSettable | XvGettable,
+	0x000000, 0xFFFFFF,
+	"XV_COLORKEY"
+    },
+    {
+	XvSettable | XvGettable,
+	-128, 127,
+	"XV_BRIGHTNESS"
+    },
+    {
+	XvSettable | XvGettable,
+	0,2,
+	"XV_INTERLACE"
+    },
+};
+
+static XF86ImageRec NEOVideoImages[] =
+{
+    XVIMAGE_YUY2,
+    XVIMAGE_YV12,
+    XVIMAGE_I420,
+    {
+	FOURCC_RV15,
+	XvRGB,
+	LSBFirst,
+	{ 'R', 'V' ,'1', '5',
+	  0x00,'5',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	16,
+	XvPacked,
+	1,
+	15, 0x001F, 0x03E0, 0x7C00,
+	0, 0, 0,
+	0, 0, 0,
+	0, 0, 0,
+	{ 'R', 'V', 'B' },
+	XvTopToBottom
+    },
+    {
+	FOURCC_RV16,
+	XvRGB,
+	LSBFirst,
+	{ 'R', 'V' ,'1', '6',
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
+	16,
+	XvPacked,
+	1,
+	16, 0x001F, 0x07E0, 0xF800,
+	0, 0, 0,
+	0, 0, 0,
+	0, 0, 0,
+	{ 'R', 'V', 'B' },
+	XvTopToBottom
+    }
+};
+
+static XF86VideoAdaptorPtr
+NEOSetupVideo(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    NEOPtr nPtr = NEOPTR(pScrn);
+    NEOPortPtr pPriv;
+    XF86VideoAdaptorPtr overlayAdaptor;
+    int i;
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOSetupVideo\n");
+#endif
+    if ((overlayAdaptor = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+			      sizeof(DevUnion) + 
+			      sizeof(NEOPortRec))) == NULL){
+	return (NULL);
+    }
+
+    overlayAdaptor->type = XvInputMask | XvImageMask | XvWindowMask 
+	| XvOutputMask | XvVideoMask;
+    overlayAdaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+    overlayAdaptor->name = "NeoMagic Video Engine";
+    overlayAdaptor->nEncodings = nElems(NEOVideoEncodings);
+    overlayAdaptor->pEncodings = NEOVideoEncodings;
+    for (i = 0; i < nElems(NEOVideoEncodings); i++){
+	NEOVideoEncodings[i].width = 1024;
+	NEOVideoEncodings[i].height = 1024;
+    }
+    overlayAdaptor->nFormats = nElems(NEOVideoFormats);
+    overlayAdaptor->pFormats = NEOVideoFormats;
+    overlayAdaptor->nPorts = 1;
+    overlayAdaptor->pPortPrivates = (DevUnion*) &overlayAdaptor[1];
+    overlayAdaptor->pPortPrivates[0].ptr = 
+	(pointer) &overlayAdaptor->pPortPrivates[1];
+    overlayAdaptor->nAttributes = nElems(NEOVideoAttributes);
+    overlayAdaptor->pAttributes = NEOVideoAttributes;
+    overlayAdaptor->nImages = nElems(NEOVideoImages);
+    overlayAdaptor->pImages = NEOVideoImages;
+
+    overlayAdaptor->PutVideo = NEOPutVideo;
+    overlayAdaptor->PutStill = NULL;
+    overlayAdaptor->GetVideo = NULL;
+    overlayAdaptor->GetStill = NULL;
+
+    overlayAdaptor->StopVideo = NEOStopVideo;
+    overlayAdaptor->SetPortAttribute = NEOSetPortAttribute;
+    overlayAdaptor->GetPortAttribute = NEOGetPortAttribute;
+    overlayAdaptor->QueryBestSize = NEOQueryBestSize;
+    overlayAdaptor->PutImage = NEOPutImage;
+    overlayAdaptor->QueryImageAttributes = NEOQueryImageAttributes;
+
+    pPriv = (NEOPortPtr)overlayAdaptor->pPortPrivates[0].ptr;
+    pPriv->colorKey = nPtr->videoKey;
+    pPriv->interlace = nPtr->interlace;
+    pPriv->videoStatus = 0;
+    pPriv->brightness = 0;
+    REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+    nPtr->overlayAdaptor = overlayAdaptor;
+
+    xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+    xvColorKey = MAKE_ATOM("XV_COLORKEY");
+    xvInterlace = MAKE_ATOM("XV_INTERLACE");
+    
+    NEOResetVideo(pScrn);
+
+    return (overlayAdaptor);
+}
+
+void
+NEOResetVideo(ScrnInfoPtr pScrn)
+{
+    NEOPtr nPtr = NEOPTR(pScrn);
+    NEOPortPtr pPriv = (NEOPortPtr)nPtr->overlayAdaptor->pPortPrivates[0].ptr;
+    int r, g, b;
+    VGA_HWP(pScrn);
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOResetVideo\n");
+#endif
+    switch (pScrn->depth){
+    case 8:
+	OUTGR(0xc6, pPriv->colorKey & 0);
+	OUTGR(0xc5, pPriv->colorKey & 0xff);
+	OUTGR(0xc7, pPriv->colorKey & 0);
+	break;
+    default:
+	r = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red;
+	g = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green;
+	b = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
+	OUTGR(0xc5, r);
+	OUTGR(0xc6, g);
+	OUTGR(0xc7, b);
+	break;
+    }
+    OUTGR(0xc4, pPriv->brightness);
+}
+
+static int
+NEOPutVideo(ScrnInfoPtr pScrn, 
+	     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, pointer data)
+{
+    NEOPortPtr pPriv = (NEOPortPtr)data;
+    NEOPtr nPtr = NEOPTR(pScrn);
+    CARD32 src_pitch, offset;
+    int xscale, yscale;
+    BoxRec dstBox;
+    INT32 x1, y1, x2, y2;
+    int size, bpp;
+    unsigned char capctrl;
+    VGA_HWP(pScrn);
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: src: %d %d %d %d\n", 
+	       src_x, src_y, src_w, src_h);
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: drw: %d %d %d %d\n", 
+	       drw_x, drw_y, drw_w, drw_h);
+#endif
+    if (src_w > 720)
+	src_w = 720;
+    if (src_h > 576)
+        src_h = 576;
+    if (pPriv->interlace != 2)
+	src_h /= 2;
+    x1 = src_x;
+    y1 = src_y;
+    x2 = src_x + src_w;
+    y2 = src_y + src_h;
+
+    dstBox.x1 = drw_x;
+    dstBox.y1 = drw_y;
+    dstBox.x2 = drw_x + drw_w;
+    dstBox.y2 = drw_y + drw_h;
+
+    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2,
+			       clipBoxes, src_w, src_h)){
+	return(Success);
+    }
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: %d %d %d %d\n", 
+	       x1, y1, x2, y2);
+#endif
+
+    dstBox.x1 -= pScrn->frameX0;
+    dstBox.y1 -= pScrn->frameY0;
+    dstBox.x2 -= pScrn->frameX0;
+    dstBox.y2 -= pScrn->frameY0;
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: dstBox %d %d %d %d\n", 
+	       dstBox.x1, dstBox.y1, dstBox.x2, dstBox.y2);
+#endif
+
+    bpp = (pScrn->bitsPerPixel + 1) >> 3;
+    src_pitch = (src_w + 7) & ~7;
+
+    xscale = 0x1000;
+    if (src_w <= drw_w){
+	xscale = (src_w * 0x1000 / drw_w) & 0xffff;
+    }
+
+    yscale = 0x1000;
+    if (src_h <= drw_h){
+ 	yscale = (src_h * 0x1000 / drw_h) & 0xffff;
+    }
+
+    size = src_h * src_pitch * 2;
+
+    if (size > nPtr->overlay){
+	if ((pPriv->linear = NEOAllocateMemory(pScrn, pPriv->linear, size)) 
+	    == NULL){
+	    return (BadAlloc);
+	}
+    } else {
+	pPriv->linear = NULL;
+    }
+    
+    if (pPriv->linear == NULL){
+	offset = nPtr->overlay_offset;
+    } else {
+	offset = pPriv->linear->offset * bpp;
+    }
+    
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutVideo: offset=0x%x\n", offset);
+#endif
+     WAIT_ENGINE_IDLE();
+     memset(nPtr->NeoFbBase + offset, 0, size);
+
+    if (!RegionsEqual(&pPriv->clip, clipBoxes)){
+	REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+	xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey,
+			    clipBoxes);
+    }
+
+    x1 >>= 16;
+    y1 >>= 16;
+    x2 >>= 16;
+    y2 >>= 16;
+
+    switch (nPtr->NeoChipset) {
+    default:
+    case NM2160: 
+	offset/=2;
+	OUTGR(0xbc, 0x4f);
+ 	break;
+    case NM2200:
+    case NM2230:
+    case NM2360:
+    case NM2380:
+	OUTGR(0xbc, 0x2e);
+ 	break;
+    }
+ 
+
+    OUTGR(0xb1, (((dstBox.x2-1) >> 4) & 0xf0) | ((dstBox.x1 >> 8) & 0x0f));
+    OUTGR(0xb2, dstBox.x1);
+    OUTGR(0xb3, dstBox.x2 - 1);
+    OUTGR(0xb4, (((dstBox.y2 - 1) >> 4) & 0xf0) | ((dstBox.y1 >> 8) & 0x0f));
+    OUTGR(0xb5, dstBox.y1);
+    OUTGR(0xb6, dstBox.y2 - 1);
+    OUTGR(0xb7, offset >> 16);
+    OUTGR(0xb8, offset >> 8);
+    OUTGR(0xb9, offset );
+    OUTGR(0xba, src_pitch >> 8);
+    OUTGR(0xbb, src_pitch);
+
+    OUTGR(0xc0, xscale >> 8);
+    OUTGR(0xc1, xscale);
+    OUTGR(0xc2, yscale >> 8);
+    OUTGR(0xc3, yscale);
+    OUTGR(0xbf, 0x02);
+
+    OUTGR(0x0a, 0x21);
+
+    OUTSR(0x0c, offset );
+    OUTSR(0x0d, offset >> 8);
+    OUTSR(0x0e, offset >> 16);
+    OUTSR(0x1a, src_pitch);
+    OUTSR(0x1b, src_pitch>>8);
+
+    OUTSR(0x17, 0 + x1);
+    OUTSR(0x18, 0 + x2 -1);
+    OUTSR(0x19, (((0 + x2 - 1) >> 4) & 0xf0) | (((0 + x1) >> 8) & 0x0f));
+
+    OUTSR(0x14, 14 + y1);
+    OUTSR(0x15, 14 + y2 - 2);
+    OUTSR(0x16, (((14 + y2 - 1) >> 4) & 0xf0) | (((14 + y1) >> 8) & 0x0f));
+
+    OUTSR(0x1c, 0xfb);
+    OUTSR(0x1d, 0x00);
+    OUTSR(0x1e, 0xe2);
+    OUTSR(0x1f, 0x02);
+
+    OUTSR(0x09, 0x11);
+    OUTSR(0x0a, 0x00);
+
+    capctrl = 0x21;
+    switch (pPriv->interlace){
+    case 0: /* Combine 2 fields */
+	break;
+    case 1: /* one field only */
+	capctrl |= 0x80;
+	break;
+    case 2: /* Interlaced fields */
+	capctrl |= 0x40;
+	break;
+    }
+    OUTSR(0x08, capctrl);
+
+#if 0
+    OUTGR(0x0a, 0x01);
+#endif
+    OUTGR(0xb0, 0x03);
+
+    pPriv->videoStatus = CLIENT_VIDEO_ON;
+    return (Success);
+}
+
+static void
+NEOStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
+{
+    NEOPortPtr pPriv = (NEOPortPtr)data;
+    NEOPtr nPtr = NEOPTR(pScrn);
+    VGA_HWP(pScrn);
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOStopVideo\n");
+#endif
+    REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+
+    if (exit){
+	if (pPriv->videoStatus & CLIENT_VIDEO_ON){
+#ifdef DEBUG
+            xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOStopVideo: stop capture\n");
+#endif
+	    OUTGR(0xb0, 0x02);
+	    OUTGR(0x0a, 0x21);
+	    OUTSR(0x08, 0xa0);
+#if 0
+	    OUTGR(0x0a, 0x01);
+#endif
+	}
+	if (pPriv->linear != NULL){
+	    xf86FreeOffscreenLinear(pPriv->linear);
+	    pPriv->linear = NULL;
+	}
+	pPriv->videoStatus = 0;
+    } else {
+	if (pPriv->videoStatus & CLIENT_VIDEO_ON){
+	    OUTGR(0xb0, 0x02);
+	    OUTGR(0x0a, 0x21);
+	    OUTSR(0x08, 0xa0);
+#if 0
+	    OUTGR(0x0a, 0x01);
+#endif
+	    pPriv->videoStatus |= OFF_TIMER;
+	    pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+	}
+    }
+}
+
+static int
+NEOSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, 
+		    pointer data)
+{
+    NEOPortPtr pPriv = (NEOPortPtr)data;
+    NEOPtr nPtr = NEOPTR(pScrn);
+    VGA_HWP(pScrn);
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOSetPortAttribute\n");
+#endif
+    if (attribute == xvColorKey){
+	int r, g, b;
+
+	pPriv->colorKey = value;
+	switch (pScrn->depth){
+	case 8:
+	    OUTGR(0xc6, pPriv->colorKey & 0xff);
+	    OUTGR(0xc5, 0x00);
+	    OUTGR(0xc7, 0x00);
+	    break;
+	default:
+	    r = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red;
+	    g = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green;
+	    b = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
+	    OUTGR(0xc5, r);
+	    OUTGR(0xc6, g);
+	    OUTGR(0xc7, b);
+	}
+    } else if (attribute == xvBrightness){
+	if ((value < -128) || (value > 127)){
+	    return (BadValue);
+	}
+	pPriv->brightness = value;
+	OUTGR(0xc4, value);
+    } else if (attribute == xvInterlace){
+	if (value < 0  ||  value > 2){
+	    return (BadValue);
+	}
+	pPriv->interlace = value;
+    } else {
+	return (BadMatch);
+    }
+    return (Success);
+}
+
+static int
+NEOGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, 
+		    pointer data)
+{
+    NEOPortPtr pPriv = (NEOPortPtr)data;
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOGetPortAttribute\n");
+#endif
+    if (attribute == xvColorKey){
+	*value = pPriv->colorKey;
+    } else if (attribute == xvBrightness){
+	*value = pPriv->brightness;
+    } else if (attribute == xvInterlace){
+	*value = pPriv->interlace;
+    } else {
+	return (BadMatch);
+    }
+    return (Success);
+}
+
+static void
+NEOQueryBestSize(ScrnInfoPtr pScrn, Bool motion, 
+		 short vid_w, short vid_h, short drw_w, short drw_h,
+		 unsigned int *p_w, unsigned int *p_h,
+		 pointer data)
+{
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOQueryBestSize\n");
+#endif
+    *p_w = min(drw_w, 1024);
+    *p_h = min(drw_h, 1024);
+}
+
+static int
+NEOPutImage(ScrnInfoPtr pScrn, 
+	    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)
+{
+    NEOPtr nPtr = NEOPTR(pScrn);
+    NEOPortPtr pPriv = (NEOPortPtr)nPtr->overlayAdaptor->pPortPrivates[0].ptr;
+    INT32 x1, y1, x2, y2;
+    int bpp;
+    int srcPitch, srcPitch2 = 0, dstPitch, size;
+    BoxRec dstBox;
+    CARD32 offset, offset2 = 0, offset3 = 0, tmp;
+    int left, top, nPixels, nLines;
+    unsigned char *dstStart;
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOPutImage\n");
+#endif
+
+    x1 = src_x;
+    y1 = src_y;
+    x2 = src_x + src_w;
+    y2 = src_y + src_h;
+    
+    dstBox.x1 = drw_x;
+    dstBox.y1 = drw_y;
+    dstBox.x2 = drw_x + drw_w;
+    dstBox.y2 = drw_y + drw_h;
+
+    if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2,
+			       clipBoxes, width, height)){
+	return (Success);
+    }
+
+    dstBox.x1 -= pScrn->frameX0;
+    dstBox.y1 -= pScrn->frameY0;
+    dstBox.x2 -= pScrn->frameX0;
+    dstBox.y2 -= pScrn->frameY0;    
+    
+    bpp = ((pScrn->bitsPerPixel + 1) >> 3);
+    
+    switch (id){
+    case FOURCC_YV12:
+	srcPitch  = (width + 3) & ~3;
+	offset2   = srcPitch * height;
+	srcPitch2 = ((width >> 1) + 3) & ~3;
+	offset3   = offset2 + (srcPitch2 * (height >> 1));
+  	dstPitch  = ((width << 1) + 15) & ~15; 
+	break;
+    case FOURCC_I420:
+	srcPitch  = (width + 3) & ~3;
+	offset3   = srcPitch * height;
+	srcPitch2 = ((width >> 1) + 3) & ~3;
+	offset2   = offset3 + (srcPitch2 * (height >> 1));
+  	dstPitch  = ((width << 1) + 15) & ~15;
+	break;
+    case FOURCC_YUY2:
+    case FOURCC_RV15:
+    case FOURCC_RV16:
+    default:
+	srcPitch = width << 1;
+  	dstPitch = (srcPitch + 15) & ~15;
+	break;
+    }
+    
+    size = dstPitch * height;
+    if (size > nPtr->overlay){
+	if ((pPriv->linear = NEOAllocateMemory(pScrn, pPriv->linear, size)) 
+	    == NULL){
+	    return (BadAlloc);
+	}
+    } else {
+	pPriv->linear = NULL;
+    }
+
+    top = y1 >> 16;
+    left = (x1 >> 16) & ~1;
+    nPixels = ((((x2 + 0xFFFF) >> 16) + 1) & ~1) - left;
+    left <<= 1;
+
+    if (pPriv->linear == NULL){
+	offset = nPtr->overlay_offset;
+    } else {
+	offset =  pPriv->linear->offset * bpp;
+    }
+    
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"offset=%x\n", offset);
+#endif
+
+    dstStart = (unsigned char *)(nPtr->NeoFbBase + offset + left);
+    
+    switch (id){
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	top &= ~1;
+	tmp = ((top >> 1) * srcPitch2) + (left >> 2);
+	offset2 += tmp;
+	offset3 += tmp;
+	nLines = ((((y2 + 0xFFFF) >> 16) + 1) & ~1) - top;
+	NEOCopyYV12Data(buf + (top * srcPitch) + (left >> 1), buf + offset2, 
+			buf + offset3, dstStart, srcPitch, srcPitch2, 
+			dstPitch, nLines, nPixels);
+	break;
+    default:
+	buf += (top * srcPitch) + left;
+	nLines = ((y2 + 0xFFFF) >> 16) - top;
+	NEOCopyData(buf, dstStart, srcPitch, dstPitch, nLines, nPixels << 1);
+    }
+
+    if (!RegionsEqual(&pPriv->clip, clipBoxes)){
+	REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+        xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+    }
+	NEODisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1,
+			x2, y2,	&dstBox, src_w, src_h, drw_w, drw_h);
+    
+    pPriv->videoStatus = CLIENT_VIDEO_ON;
+    return (Success);
+	
+}
+
+static int
+NEOQueryImageAttributes(ScrnInfoPtr pScrn, int id, 
+			unsigned short *width, unsigned short *height,
+			int *pitches, int *offsets)
+{
+    int size, tmp;
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOQueryImageAttributes\n");
+#endif
+    if (*width > 1024){
+	*width = 1024;
+    }
+    if (*height > 1024){
+	*height = 1024;
+    }
+
+    *width = (*width + 1) & ~1;
+    if (offsets != NULL){
+	offsets[0] = 0;
+    }
+
+    switch (id){
+    case FOURCC_YV12:
+    case FOURCC_I420:
+	*height = (*height + 1) & ~1;
+	size = (*width + 3) & ~3;
+	if (pitches != NULL){
+	    pitches[0] = size;
+	}
+	size *= *height;
+	if (offsets != NULL){
+	    offsets[1] = size;
+	}
+	tmp = ((*width >> 1) + 3) & ~3;
+	if (pitches != NULL){
+	    pitches[1] = pitches[2] = tmp;
+	}
+	tmp *= (*height >> 1);
+	size += tmp;
+	if (offsets != NULL){
+	    offsets[2] = size;
+	}
+	size += tmp;
+	break;
+    case FOURCC_YUY2:
+    case FOURCC_RV15:
+    case FOURCC_RV16:
+    default:
+	size = *width * 2;
+	if (pitches != NULL){
+	    pitches[0] = size;
+	}
+	size *= *height;
+	break;
+    }
+    return (size);
+}
+
+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.y1 != B->extents.y1)
+	|| (A->extents.x2 != B->extents.x2)
+	|| (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);
+}
+
+static void
+NEODisplayVideo(ScrnInfoPtr pScrn, 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)
+{
+    NEOPtr nPtr = NEOPTR(pScrn);
+    int hstretch, vstretch, fmt;
+    VGA_HWP(pScrn);
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEODisplayVideo\n");
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEODisplayVideo src_w=%d, src_h=%d, pitch=%d, drw_w=%d, drw_h=%d\n", src_w, src_h, pitch, drw_w, drw_h);
+#endif
+#define WIDTH_THRESHOLD 160
+    if (dstBox->x2 >= pScrn->virtualX) {
+	/*
+	 * This is a hack to work around a problem when video is moved
+	 * accross the right border.
+	 */
+	int diff_s = (width - ((x2 - x1) >> 16)) & ~1;
+	int diff_d = (drw_w - dstBox->x2 + dstBox->x1) & ~1;
+
+	offset -= 2 * ((diff_s > diff_d) ? diff_d : diff_s);
+	dstBox->x1 -= diff_d;
+    } else if (dstBox->x2 - dstBox->x1 < WIDTH_THRESHOLD) {
+	/*
+	 * When the video window is less than about 160 pixel wide
+	 * it will be distoreted. We attempt to fix it by actually
+	 * making it wider and relying on the color key to prevent
+	 * it from appearing outside of the video.
+	 */
+	int pre, post;
+	int scale = 1;
+	
+	if (dstBox->x1 < WIDTH_THRESHOLD) {
+	    pre = dstBox->x1;
+	    post = 160 - pre;
+	} else {
+	    pre = 160;
+	    post = 0;
+	}
+	offset -= 2 * scale * pre;
+	dstBox->x1 -= pre;
+	dstBox->x2 += post;
+    }
+    if (nPtr->videoHZoom != 1.0) {
+	if ((dstBox->x2 += 5) > pScrn->virtualX)
+	    dstBox->x2 = pScrn->virtualX;
+	if (dstBox->x1 > 0) dstBox->x1 += 2;
+    }
+    
+    fmt = 0x00;
+    switch (id){
+    case FOURCC_YV12:
+    case FOURCC_I420:
+    case FOURCC_YUY2:
+	fmt = 0x00;
+	break;
+    case FOURCC_RV15:
+    case FOURCC_RV16:
+	fmt = 0x20;
+	break;
+    }
+
+    offset += (x1 >> 15) & ~0x03;
+    
+    switch (nPtr->NeoChipset) {
+    default:
+    case NM2160: 
+        offset/=2;
+	pitch/=2;
+        OUTGR(0xbc, 0x4f);
+	break;
+    case NM2200:
+    case NM2230:
+    case NM2360:
+    case NM2380:
+        OUTGR(0xbc, 0x2e);
+	break;
+    }
+
+    /* factor 4 for granularity */
+    hstretch = (double)0x1000 * 4 / (int)(nPtr->videoHZoom * 4);
+    if (drw_w > src_w)
+	hstretch = (((int)src_w) * hstretch) / (int) drw_w;
+    
+    vstretch = (double)0x1000 / nPtr->videoVZoom;
+    if (drw_h > src_h)
+	vstretch = (((int)src_h) * vstretch )/ (int) drw_h;
+
+    OUTGR(0xb1, (((dstBox->x2 - 1) >> 4) & 0xf0) | ((dstBox->x1 >> 8) & 0x0f));
+    OUTGR(0xb2, dstBox->x1);
+    OUTGR(0xb3, dstBox->x2 - 1);
+    OUTGR(0xb4, (((dstBox->y2 - 1) >> 4) & 0xf0) | ((dstBox->y1 >> 8) & 0x0f));
+    OUTGR(0xb5, dstBox->y1);
+    OUTGR(0xb6, dstBox->y2 - 1);
+    OUTGR(0xb7, offset >> 16);
+    OUTGR(0xb8, offset >> 8);
+    OUTGR(0xb9, offset );
+    OUTGR(0xba, pitch >> 8);
+    OUTGR(0xbb, pitch);
+     
+    OUTGR(0xbd, 0x02);
+    OUTGR(0xbe, 0x00);
+    OUTGR(0xbf, 0x02);
+
+    OUTGR(0xc0, hstretch >> 8);
+    OUTGR(0xc1, hstretch);
+    OUTGR(0xc2, vstretch >> 8);
+    OUTGR(0xc3, vstretch);
+
+    OUTGR(0xb0, fmt | 0x03);
+
+    OUTGR(0x0a, 0x21);
+    OUTSR(0x08, 0xa0);
+    OUTGR(0x0a, 0x01);
+}
+
+static void
+NEOInitOffscreenImages(ScreenPtr pScreen)
+{
+    XF86OffscreenImagePtr offscreenImages;
+
+#ifdef DEBUG
+    xf86DrvMsg(xf86Screens[pScreen->myNum]->scrnIndex,X_INFO,"NEOInitOffscreenImages\n");
+#endif
+    if ((offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))) == NULL){
+	return;
+    }
+
+    offscreenImages->image = NEOVideoImages;
+    offscreenImages->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+    offscreenImages->alloc_surface = NEOAllocSurface;
+    offscreenImages->free_surface = NEOFreeSurface;
+    offscreenImages->display = NEODisplaySurface;
+    offscreenImages->stop = NEOStopSurface;
+    offscreenImages->getAttribute = NEOGetSurfaceAttribute;
+    offscreenImages->setAttribute = NEOSetSurfaceAttribute;
+    offscreenImages->max_width = 1024;
+    offscreenImages->max_height = 1024;
+    offscreenImages->num_attributes = nElems(NEOVideoAttributes);
+    offscreenImages->attributes = NEOVideoAttributes;
+
+    xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
+}
+
+static FBLinearPtr
+NEOAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
+{
+    ScreenPtr pScreen;
+    FBLinearPtr new_linear;
+    int bytespp = pScrn->bitsPerPixel >> 3;
+
+    /* convert size in bytes into number of pixels */
+    size = (size + bytespp - 1) / bytespp;
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+	       "NEOAllocateMemory: linear=%x, size=%d\n", linear, size);
+#endif
+    if (linear){
+#ifdef DEBUG
+        xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+		   "NEOAllocateMemory: linear->size=%d\n", linear->size);
+#endif
+	if (linear->size >= size){
+	    return (linear);
+	}
+
+	if (xf86ResizeOffscreenLinear(linear, size)){
+	    return (linear);
+	}
+
+	xf86FreeOffscreenLinear(linear);
+    }
+
+
+    pScreen = screenInfo.screens[pScrn->scrnIndex];
+    if ((new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, NULL,
+						  NULL, NULL)) == NULL){
+	int max_size;
+
+	xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, 
+					PRIORITY_EXTREME);
+#ifdef DEBUG
+        xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+		   "NEOAllocateMemory: max_size=%d\n", max_size);
+#endif
+	if (max_size < size){
+	    return (NULL);
+	}
+
+	xf86PurgeUnlockedOffscreenAreas(pScreen);
+	new_linear = xf86AllocateOffscreenLinear(pScreen, 
+						 size, 16, NULL, NULL, NULL);
+    }
+    
+    return (new_linear);
+}
+
+static void
+NEOCopyData(unsigned char *src, unsigned char *dst, 
+	    int srcPitch, int dstPitch,
+	    int height, int width)
+{
+    while (height-- > 0){
+	memcpy(dst, src, width);
+	src += srcPitch;
+	dst += dstPitch;
+    }
+}
+
+static void
+NEOCopyYV12Data(unsigned char *src1, unsigned char *src2,
+		unsigned char *src3, unsigned char *dst,
+		int srcPitch1, int srcPitch2, int dstPitch,
+		int height, int width)
+{
+    CARD32 *pDst = (CARD32 *) dst;
+    int i;
+
+    width >>= 1;
+    height >>= 1;
+    dstPitch >>= 2;
+    while (--height >= 0){
+	for (i =0; i < width; i++){
+	    pDst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) |
+		(src3[i] << 8) | (src2[i] << 24);
+	}
+	pDst += dstPitch;
+	src1 += srcPitch1;
+
+	for (i =0; i < width; i++){
+	    pDst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) |
+		(src3[i] << 8) | (src2[i] << 24);
+	}
+	pDst += dstPitch;
+	src1 += srcPitch1;
+	    src2 += srcPitch2;
+	    src3 += srcPitch2;
+    }
+}
+
+static int
+NEOAllocSurface(ScrnInfoPtr pScrn, int id, 
+		unsigned short width, unsigned short height,
+		XF86SurfacePtr surface)
+{
+    int pitch, bpp, size;
+    NEOOffscreenPtr pPriv;
+    FBLinearPtr linear;
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOAllocSurface\n");
+#endif
+    if (width > 1024  || height > 1024){
+	return (BadAlloc);
+    }
+
+    width = (width + 1) & ~1;
+    bpp = ((pScrn->bitsPerPixel + 1) >> 3);
+    pitch = ((width << 1) + 15) & ~15;
+    size = pitch * height;
+
+    if ((linear = NEOAllocateMemory(pScrn, NULL, size)) == NULL){
+	return (BadAlloc);
+    }
+
+    surface->width = width;
+    surface->height = height;
+    if ((surface->pitches = xalloc(sizeof(int))) == NULL){
+	xf86FreeOffscreenLinear(linear);
+	return (BadAlloc);
+    }
+    if ((surface->offsets = xalloc(sizeof(int))) == NULL){
+	xfree(surface->pitches);
+	xf86FreeOffscreenLinear(linear);
+	return (BadAlloc);
+    }
+
+    if ((pPriv = xalloc(sizeof(NEOOffscreenRec))) == NULL){
+	xfree(surface->pitches);
+	xfree(surface->offsets);
+	xf86FreeOffscreenLinear(linear);
+	return (BadAlloc);
+    }
+
+    pPriv->linear = linear;
+    pPriv->isOn = FALSE;
+
+    surface->pScrn = pScrn;
+    surface->id = id;
+    surface->pitches[0] = pitch;
+    surface->offsets[0] = linear->offset << 1;
+    surface->devPrivate.ptr = (pointer)pPriv;
+    return (Success);
+}
+
+static int
+NEOFreeSurface(XF86SurfacePtr surface)
+{
+    NEOOffscreenPtr pPriv = (NEOOffscreenPtr)surface->devPrivate.ptr;
+
+#ifdef DEBUG
+    xf86DrvMsg(0,X_INFO,"NEOFreeSurface\n");
+#endif
+    if (pPriv->isOn)
+	NEOStopSurface(surface);
+
+    xf86FreeOffscreenLinear(pPriv->linear);
+    xfree(surface->pitches);
+    xfree(surface->offsets);
+    xfree(surface->devPrivate.ptr);
+    return (Success);
+}
+
+static int
+NEODisplaySurface(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)
+{
+    NEOOffscreenPtr pPriv = (NEOOffscreenPtr)surface->devPrivate.ptr;
+    NEOPtr nPtr = NEOPTR(surface->pScrn);
+    NEOPortPtr portPriv = nPtr->overlayAdaptor->pPortPrivates[0].ptr;
+    INT32 x1, y1, x2, y2;
+    BoxRec dstBox;
+
+#ifdef DEBUG
+    xf86DrvMsg(surface->pScrn->scrnIndex,X_INFO,"NEODisplaySurface\n");
+#endif
+    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 (!xf86XVClipVideoHelper( &dstBox, &x1, &x2, &y1, &y2,
+			       clipBoxes, surface->width, surface->height)){
+	return (Success);
+    }
+
+    dstBox.x1 -= surface->pScrn->frameX0;
+    dstBox.y1 -= surface->pScrn->frameY0;
+    dstBox.x2 -= surface->pScrn->frameX0;
+    dstBox.y2 -= surface->pScrn->frameY0;
+
+    xf86XVFillKeyHelper(surface->pScrn->pScreen, portPriv->colorKey,
+			clipBoxes);
+    NEOResetVideo(surface->pScrn);
+    NEODisplayVideo(surface->pScrn, 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(pScrn->pScreen, &portPriv->clip);
+	UpdateCurrentTime();
+	portPriv->videoStatus = FREE_TIMER;
+	portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+    }
+    return (Success);
+}
+
+static int
+NEOStopSurface(XF86SurfacePtr surface)
+{
+    NEOOffscreenPtr pPriv = (NEOOffscreenPtr)surface->devPrivate.ptr;
+
+#ifdef DEBUG
+    xf86DrvMsg(surface->pScrn->scrnIndex,X_INFO,"NEOStopSurface\n");
+#endif
+    if (pPriv->isOn){
+	NEOPtr nPtr = NEOPTR(surface->pScrn);
+	VGA_HWP(surface->pScrn);
+	OUTGR(0xb0, 0x02);
+	pPriv->isOn = FALSE;
+    }
+    return (Success);
+}
+
+static int
+NEOGetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 *value)
+{
+    NEOPtr nPtr = NEOPTR(pScrn);
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOGetSurfaceAttribute\n");
+#endif
+    return (NEOGetPortAttribute(pScrn, 
+            attr, value, (pointer)nPtr->overlayAdaptor->pPortPrivates[0].ptr));
+}
+
+static int
+NEOSetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 value)
+{
+    NEOPtr nPtr = NEOPTR(pScrn);
+
+#ifdef DEBUG
+    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"NEOSetSurfaceAttribute\n");
+#endif
+    return (NEOSetPortAttribute(pScrn, 
+            attr, value, (pointer)nPtr->overlayAdaptor->pPortPrivates[0].ptr));
+}
+
+#else /* XvExtension */
+
+void NEOInitVideo(ScreenPtr pScreen) {}
+void NEOResetVideo(ScreenPtr pScreen) {}
+
+#endif
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.h xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.h
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.h	1970-01-01 01:00:00.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.h	2002-07-01 04:25:58.000000000 +0200
@@ -0,0 +1,84 @@
+/**********************************************************************
+Copyright 2002 by Shigehiro Nomura.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Shigehiro Nomura not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  Shigehiro Nomura
+and its suppliers make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or 
+implied warranty.
+
+SHIGEHIRO NOMURA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL SHIGEHIRO NOMURA AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_video.h,v 1.2 2002/07/01 02:25:58 tsi Exp $ */
+
+#ifndef _NEO_VIDEO_H
+#define _NEO_VIDEO_H
+
+#define ACC_MMIO
+
+#include "vgaHW.h"
+#include "fourcc.h"
+#include "Xv.h"
+
+#define NEO_VIDEO_VIDEO		0
+#define NEO_VIDEO_IMAGE		1
+
+#define FOURCC_RV15			0x35315652
+#define FOURCC_RV16			0x36315652
+
+#define OFF_DELAY			200		/* milliseconds */
+#define FREE_DELAY			60000	/* milliseconds */
+
+#define OFF_TIMER			0x01
+#define FREE_TIMER			0x02
+#define CLIENT_VIDEO_ON		0x04
+#define TIMER_MASK			(OFF_TIMER | FREE_TIMER)
+
+typedef struct
+{
+    FBLinearPtr	linear;
+    RegionRec	clip;
+    CARD32	colorKey;
+    CARD32	interlace;
+    CARD32	brightness;
+    CARD32	videoStatus;
+    Time	offTime;
+    Time	freeTime;
+} NEOPortRec, *NEOPortPtr;
+
+typedef struct
+{
+    FBLinearPtr	linear;
+    Bool	isOn;
+} NEOOffscreenRec, *NEOOffscreenPtr;
+
+/* I/O Functions */
+# define OUTGR(idx,dat) \
+   if (nPtr->NeoMMIOBase2) \
+     (*(unsigned short *)(nPtr->NeoMMIOBase2+VGA_GRAPH_INDEX)\
+                                                     =(idx)|((dat)<<8));\
+   else \
+      VGAwGR((idx),(dat));
+
+#  define OUTSR(idx,dat) \
+if (nPtr->NeoMMIOBase2) \
+   (*(unsigned short *)(nPtr->NeoMMIOBase2+VGA_SEQ_INDEX)=(idx)|((dat)<<8));\
+else \
+   VGAwSR((idx),(dat));
+
+# define VGA_HWP(x)     vgaHWPtr hwp = VGAHWPTR(x)
+
+#endif /* _NEO_VIDEO_H */
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/NM-reg.txt xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/NM-reg.txt
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/NM-reg.txt	1970-01-01 01:00:00.000000000 +0100
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/NM-reg.txt	2002-04-04 16:05:44.000000000 +0200
@@ -0,0 +1,69 @@
+NM2160 Register GUESS  
+   --- Overlay and ZV capture ---
+
+2002,2.3.
+
+1. Overlay
+  GRB0  bit5    Format; 0:YUY2/1:RGB
+        bit1    1
+        bit0    Enable overlay ; 1:enable/0:disable
+  GRB1  bit7:4  X2[11:8]
+        bit3:0  X1[11:8]
+  GRB2          X1[7:0]
+  GRB3          X2[7:0]
+  GRB4  bit7:4  Y2[11:8]
+        bit3:0  Y1[11:8]
+  GRB5          Y1[7:0]
+  GRB6          Y2[7:0]
+  GRB7          VRAM offset[24:17]
+  GRB8          VRAM offset[16:9]
+  GRB9          VRAM offset[8:1]
+  GRBA          Width in byte[15:8]
+  GRBB          Width in byte[7:0]
+  GRBC          0x4f
+  GRBD          -
+  GRBE          -
+  GRBF  bit2    0:normal/1:mirror
+        bit1:0  b'10'
+  GRC0          X scale[15:8] ; x1.0 == 0x1000
+  GRC1          X scale[7:0]
+  GRC2          Y scale[15:8] ; x1.0 == 0x1000
+  GRC3          Y scale[7:0]
+  GRC4          brightness   ; -128 to +127
+  GRC5          Color key(R)
+  GRC6          Color key(G) / Color key(8bpp)
+  GRC7          Color key(B)
+
+2. ZV capture
+  GR0A  bit5    Enable extended SR reg. ; 1:enable/0:disable
+        bit0    1
+
+  SR08  bit7:1  b'1010000'
+        bit0    Enable capture ; 1:enable/0:disable
+  SR09          0x11
+  SR0A          0x00
+  SR0B          -
+  SR0C          VRAM offset[8:1]
+  SR0D          VRAM offset[16:9]
+  SR0E          VRAM offset[24:17]
+  SR0F          -
+  SR10          -
+  SR11          -
+  SR12          -
+  SR13          -
+  SR14          Y1[7:0]
+  SR15          Y2[7:0]
+  SR16  bit7:4  Y2[11:4]
+        bit3:0  Y1[11:4]
+  SR17          X1[7:0]
+  SR18          X2[7:0]
+  SR19  bit7:4  X2[11:8]
+        bit3:0  X1[11:8]
+  SR1A          Width in byte[7:0]
+  SR1B          Width in byte[15:8]
+  SR1C          0xfb
+  SR1D          0x00
+  SR1E          0xe2
+  SR1F          0x02
+
+s.nomura@mba.nifty.ne.jp
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/README xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/README
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/README	1999-04-17 09:06:15.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/README	1999-04-17 09:06:15.000000000 +0200
@@ -147,4 +147,4 @@
 
 
 
-$XFree86$
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/README,v 1.1 1999/04/17 07:06:15 dawes Exp $
diff -x CVS -x neo_bank.c -uNr xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/TODO
--- xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO	1999-04-17 09:06:16.000000000 +0200
+++ xc.cvs20021023/programs/Xserver/hw/xfree86/drivers/neomagic/TODO	1999-04-17 09:06:16.000000000 +0200
@@ -17,4 +17,4 @@
 
 
 
-$XFree86$
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO,v 1.1 1999/04/17 07:06:16 dawes Exp $
