--- /dev/null
+diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile
+--- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile Wed Jun 23 08:37:21 1999
++++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile Sat Oct 24 03:54:44 1998
+@@ -1,4 +1,4 @@
+-XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile,v 1.1.2.9 1999/06/23 12:37:21 hohndel Exp $
++XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/Imakefile,v 1.1.2.8 1998/10/22 04:31:05 hohndel Exp $
+ XCOMM
+ XCOMM This is an Imakefile for the cyrix driver.
+ XCOMM
+@@ -6,10 +6,10 @@
+ #include <Server.tmpl>
+
+ SRCS = cyrix_driver.c cyrix_accel.c cyrix_cursor.c cyrix_cmap.c cyrix_bank.s \
+- cyrix_asm.s gxrender.c
++ cyrix_asm.s
+
+ OBJS = cyrix_driver.o cyrix_accel.o cyrix_cursor.o cyrix_cmap.o cyrix_bank.o \
+- cyrix_asm.o gxrender.o
++ cyrix_asm.o
+
+ DEFINES = -DPSZ=8
+
+@@ -61,7 +61,6 @@
+ InstallLinkKitNonExecFile(cyrix_driver.c,$(LINKKITDIR)/drivers/vga256/cyrix)
+ InstallLinkKitNonExecFile(cyrix_bank.s,$(LINKKITDIR)/drivers/vga256/cyrix)
+ InstallLinkKitNonExecFile(cyrix_asm.s,$(LINKKITDIR)/drivers/vga256/cyrix)
+-InstallLinkKitNonExecFile(gxrender.c,$(LINKKITDIR)/drivers/vga256/cyrix)
+ InstallLinkKitNonExecFile(Imakefile,$(LINKKITDIR)/drivers/vga256/cyrix)
+
+ XCOMM
+@@ -82,4 +81,3 @@
+ XCOMM Install Link Kit Non Exec File(Imakefile,$(LINKKITDIR)/drivers/vga16/cyrix)
+
+ DependTarget()
+-
+diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h
+--- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h Tue Dec 22 02:49:58 1998
++++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h Fri Nov 6 11:41:51 1998
+@@ -1,5 +1,5 @@
+
+-/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h,v 1.1.2.6 1998/12/22 07:49:58 hohndel Exp $ */
++/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix.h,v 1.1.2.5 1998/11/06 09:47:02 hohndel Exp $ */
+
+ /* this code is partly based on the MediaGX sources from the GGI project
+ based on CYRIX example code (gxvideo.c) and included with CYRIX and
+@@ -88,10 +88,9 @@
+ #define CYRIXsetVectorMode() \
+ GX_REG(GP_VECTOR_MODE) = (vectorMode)
+
+-#define IfDest(rop, planemask, val) \
+- (( (((rop) & 0x5) ^ (((rop) & 0xA) >> 1)) \
+- || (~((planemask) & 0xFF)) \
+- ) ? (val) : 0)
++#define IfDest(xrop, val) ((((xrop) & 0x5) ^ (((xrop) & 0xA) >> 1)) ? (val) : 0)
++
++
+
+ /* Generic MediaGX hardware register and value definitions */
+
+diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c
+--- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c Wed Jun 23 08:37:21 1999
++++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c Fri Nov 6 11:41:51 1998
+@@ -1,7 +1,6 @@
+-/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c,v 1.1.2.6 1999/06/23 12:37:21 hohndel Exp $ */
++/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_accel.c,v 1.1.2.3 1998/11/06 09:47:04 hohndel Exp $ */
+
+ /*
+- * Copyright 1999 by Brian Falardeau.
+ * Copyright 1998 by Annius Groenink, Amsterdam.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+@@ -33,6 +32,7 @@
+ #include "cyrix.h"
+ #include "miline.h"
+
++
+ /* size of color expand source area (embedded in frame buffer) */
+ #define CYRIXexpandSize 32768
+
+@@ -41,64 +41,17 @@
+ upper nybble inverted X raster operation (bits 0 - 3 correspond to
+ bits 3 - 0 and 7 - 4 in Windows style ROP). In some routines,
+ the role of source and pattern is inverted. */
+-
+-/* The following ROPs only use pattern and destination data. */
+-/* They are used when the planemask specifies all planes (no mask). */
+-
+-static const int windowsROPpat[16] = {
+- 0x00, /* GXclear = 0 */
+- 0xA0, /* GXand = pat AND dst */
+- 0x50, /* GXandReverse = pat AND NOT dst */
+- 0xF0, /* GXcopy = pat */
+- 0x0A, /* GXandInverted = NOT pat AND dst */
+- 0xAA, /* GXnoop = dst */
+- 0x5A, /* GXxor = pat XOR dst */
+- 0xFA, /* GXor = pat OR dst */
+- 0x05, /* GXnor = NOT pat AND NOT dst */
+- 0xA5, /* GXequiv = NOT pat XOR dst */
+- 0x55, /* GXinvert = NOT dst */
+- 0xF5, /* GXorReverse = pat OR NOT dst */
+- 0x0F, /* GXcopyInverted = NOT pat */
+- 0xAF, /* GXorInverted = NOT pat OR dst */
+- 0x5F, /* GXnand = NOT pat OR NOT dst */
+- 0xFF, /* GXset = 1 */
+-};
+-
+-/* The following ROPs use source data to specify a planemask. */
+-/* If the planemask (src) is one, then the result is the appropriate */
+-/* combination of pattern and destination data. If the planemask (src) */
+-/* is zero, then the result is always just destination data. */
+-
+-static const int windowsROPsrcMask[16] = {
+- 0x22, /* GXclear => 0 if src = 1, dst if src = 0 */
+- 0xA2, /* GXand = pat AND dst if src = 1, dst if src = 0 */
+- 0x62, /* GXandReverse = pat AND NOT dst if src = 1, dst if src = 0 */
+- 0xE2, /* GXcopy = pat if src = 1, dst if src = 0 */
+- 0x2A, /* GXandInverted = NOT pat AND dst if src = 1, dst if src = 0 */
+- 0xAA, /* GXnoop = dst if src = 1, dst if src = 0 */
+- 0x6A, /* GXxor = pat XOR dst if src = 1, dst if src = 0 */
+- 0xEA, /* GXor = pat OR dst if src = 1, dst if src = 0 */
+- 0x26, /* GXnor = NOT pat AND NOT dst if src = 1, dst if src = 0 */
+- 0xA6, /* GXequiv = NOT pat XOR dst if src = 1, dst if src = 0 */
+- 0x66, /* GXinvert = NOT dst if src = 1, dst if src = 0 */
+- 0xE6, /* GXorReverse = pat OR NOT dst if src = 1, dst if src = 0 */
+- 0x2E, /* GXcopyInverted = NOT pat if src = 1, dst if src = 0 */
+- 0xAE, /* GXorInverted = NOT pat OR dst if src = 1, dst if src = 0 */
+- 0x6E, /* GXnand = NOT pat OR NOT dst if src = 1, dst if src = 0 */
+- 0xEE, /* GXset = 1 if src = 1, dst if src = 0 */
+-};
+-
+-/* The following ROPs use pattern data to specify a planemask. */
+-/* If the planemask (pat) is one, then the result is the appropriate */
+-/* combination of source and destination data. If the planemask (pat) */
+-/* is zero, then the result is always just destination data. */
+-
+ static const int windowsROPpatMask[16] = { 0x0A, 0x8A, 0x4A, 0xCA,
+ 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA,
+ 0x3A, 0xBA, 0x7A, 0xFA };
+
++static const int windowsROPsrcMask[16] = { 0x22, 0xA2, 0x62, 0xE2,
++ 0x2A, 0xAA, 0x6A, 0xEA,
++ 0x26, 0xA6, 0x66, 0xE6,
++ 0x2E, 0xAE, 0x6E, 0xEE };
+
++static int bltBufWidth;
+
+ static int blitMode;
+ static int vectorMode;
+@@ -106,85 +59,25 @@
+ static int copyXdir;
+ static int setBlitModeOnSync = 0;
+
+-/* STATIC VARIABLES FOR THIS FILE */
+-/* Used to maintain state between setup and rendering calls. */
+-
+-static int CYRIXsavedROP;
+-static int CYRIXtransparent;
+-static int CYRIXtransColor;
+-static int CYRIXstartMonoExpand = 0;
+-
+-static unsigned short CYRIXsaveX, CYRIXsaveY, CYRIXsaveW, CYRIXsaveH;
+
+ /* Forward declaration of functions used in the driver */
+-
+ void CYRIXAccelSync();
+ void CYRIXAccelInit();
+ void CYRIXSetupForFillRectSolid();
+ void CYRIXSubsequentFillRectSolid();
+-void CYRIXSetupFor8x8PatternColorExpand();
+-void CYRIXSubsequent8x8PatternColorExpand();
+ void CYRIXSetupForScreenToScreenCopy();
+ void CYRIXSubsequentScreenToScreenCopy();
+-
+ void CYRIXSubsequentBresenhamLine();
++void CYRIXSetupFor8x8PatternColorExpand();
++void CYRIXSubsequent8x8PatternColorExpand();
+ void CYRIXSetupForCPUToScreenColorExpand();
+ void CYRIXSubsequentCPUToScreenColorExpand();
+
+-/* Routines in GXRENDER.C */
+-
+-void gxr_initialize(unsigned char *regptr, unsigned short bpp,
+- unsigned short BB0base, unsigned short BB1base,
+- unsigned short BBwidthPixels);
+-
+-void gxr_wait_until_idle(void);
+-
+-void gxr_load_solid_source(unsigned short color);
+-
+-void gxr_load_mono_source(unsigned short bgcolor, unsigned short fgcolor,
+- unsigned short transparent);
+-
+-void gxr_load_solid_pattern(unsigned short color);
+-
+-void gxr_load_mono_pattern(unsigned short bgcolor, unsigned short fgcolor,
+- unsigned long data0, unsigned long data1, unsigned char transparency);
+-
+-void gxr_load_raster_operation(unsigned char rop);
+-
+-void gxr_pattern_fill(unsigned short x, unsigned short y,
+- unsigned short width, unsigned short height);
+-
+-void gxr_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height);
+-
+-void gxr_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height, unsigned short color);
+-
+-void gxr_text_glyph(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height, unsigned char *data, unsigned short pitch);
+-
+-void gxr_bresenham_line(unsigned short x, unsigned short y,
+- unsigned short length, unsigned short initerr,
+- unsigned short axialerr, unsigned short diagerr,
+- unsigned short flags);
+-
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXAccelInit
+-//
+-// This routine hooks the acceleration routines and sets appropriate flags.
+-//---------------------------------------------------------------------------
+-*/
+
++/* Acceleration init function, sets up pointers to our accelerated functions */
+ void
+ CYRIXAccelInit()
+-{
+- int bltBufWidth;
+-
+- /* General acceleration flags */
++{ /* General acceleration flags */
+ xf86AccelInfoRec.Flags = PIXMAP_CACHE
+ | BACKGROUND_OPERATIONS
+ | HARDWARE_PATTERN_SCREEN_ORIGIN
+@@ -245,344 +138,232 @@
+
+ /* calculate the pixel width of a blit buffer for convenience */
+ bltBufWidth = CYRIXbltBufSize / (vgaBitsPerPixel / 8);
++}
+
+- /* pass parameters to GXRENDER.C file */
+
+- gxr_initialize((unsigned char *) GXregisters,
+- (unsigned short) vgaBitsPerPixel,
+- (unsigned short) CYRIXbltBuf0Address,
+- (unsigned short) CYRIXbltBuf1Address,
+- (unsigned short) bltBufWidth);
+-}
++/* set colors - called through access macros in cyrix.h */
++static __inline__ void CYRIXsetColors01(reg, col0, col1)
++int reg;
++int col0;
++int col1;
++{ if (vgaBitsPerPixel == 16)
++ GX_REG(reg) = ((col1 & 0xFFFF) << 16) | (col0 & 0xFFFF);
++ else
++ { col0 &= 0xFF;
++ col1 &= 0xFF;
++ GX_REG(reg) = (col1 << 24) | (col1 << 16) | (col0 << 8) | col0;
++} }
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXAccelSync
+-//
+-// This routine is called before accessing the frame buffer directly to
+-// make sure that the graphics pipeline is idle. It is also called after
+-// loading the monochrome data into BB0 for bitmap to screen BLTs.
+-//---------------------------------------------------------------------------
+-*/
+
++/* The generic Sync() function that waits for everything to
++ be completed (e.g. before writing to the frame buffer
++ directly). */
+ void
+ CYRIXAccelSync()
+-{
+- /* CHECK IF END TO CPU TO SCREEN EXPAND BLT */
+-
+- if (CYRIXstartMonoExpand)
+- {
+- /* START CPU TO SCREEN EXPAND BLT */
+- /* Data has already been loaded into BB0, so use NULL pointer. */
+-
+- /* this is formally incorrect: XAA may use both BB0 and BB1
+- for the text source bitmap, so READ_DST_FB1 should not be
+- used. So far, this problem has not manifested itself in
+- practice. */
+-
+- CYRIXstartMonoExpand = 0;
+- gxr_text_glyph(0, 0, CYRIXsaveX, CYRIXsaveY, CYRIXsaveW,
+- CYRIXsaveH, 0, 0);
++{ if (setBlitModeOnSync)
++ { setBlitModeOnSync = 0;
++ CYRIXsetupSync();
++ CYRIXsetBlitMode();
+ }
+-
+- /* WAIT UNTIL IDLE */
+-
+- gxr_wait_until_idle();
++ while (GX_REG(GP_BLIT_STATUS) &
++ (BS_BLIT_BUSY|BS_PIPELINE_BUSY|BS_BLIT_PENDING));
+ }
+
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSetupForFillRectSolid
+-//
+-// This routine is called to setup the solid pattern color for future
+-// rectangular fills or vectors.
+-//---------------------------------------------------------------------------
+-*/
+-
++/* Solid rectangles */
+ void
+ CYRIXSetupForFillRectSolid(color, rop, planemask)
+ int color, rop;
+ unsigned int planemask;
+-{
+- /* LOAD THE SOLID PATTERN COLOR */
+-
+- gxr_load_solid_pattern((unsigned short) color);
+-
+- /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */
+-
+- if (planemask == (unsigned int) -1)
+- {
+- /* use normal pattern ROPs if all planes are enabled */
+-
+- gxr_load_raster_operation(windowsROPpat[rop & 0x0F]);
+- }
+- else
+- {
+- /* select ROP that uses planemask in src data */
+-
+- gxr_load_solid_source((unsigned short) planemask);
+- gxr_load_raster_operation(windowsROPsrcMask[rop & 0x0F]);
+- }
++{ CYRIXsetupSync();
++ CYRIXsetSourceColors01(color, color);
++ CYRIXsetPatColors01(planemask, 0);
++ CYRIXsetPatMode(rop, RM_PAT_DISABLE);
++ blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND
++ | IfDest(rop, BM_READ_DST_FB0);
++ vectorMode = IfDest(rop, VM_READ_DST_FB);
+ }
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSubsequentFillRectSolid
+-//
+-// This routine is called to fill a rectangular region using the previously
+-// specified solid pattern and raster operation.
+-//
+-// Sample application uses:
+-// - Window backgrounds.
+-// - x11perf: rectangle tests (-rect500).
+-// - x11perf: fill trapezoid tests (-trap100).
+-// - x11perf: horizontal line segments (-hseg500).
+-//---------------------------------------------------------------------------
+-*/
+
+ void
+ CYRIXSubsequentFillRectSolid(x, y, w, h)
+ int x, y, w, h;
+-{
+- /* call routine to fill rectangular region */
+-
+- gxr_pattern_fill((unsigned short) x, (unsigned short) y,
+- (unsigned short) w, (unsigned short) h);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSetupFor8x8PatternColorExpand
+-//
+-// This routine is called to setup the monochrome pattern (8x8) and raster
+-// operation for future rectangular fills.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void CYRIXSetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, rop, planemask)
+-int patternx, patterny;
+-int bg, fg, rop;
+-unsigned int planemask;
+-{ int trans = (bg == -1);
+-
+- /* LOAD PATTERN COLORS AND DATA */
+-
+- gxr_load_mono_pattern((unsigned short) bg, (unsigned short) fg,
+- (unsigned long) patternx, (unsigned long) patterny,
+- (unsigned char) trans);
+-
+- /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */
+-
+- if (planemask == (unsigned int) -1)
+- {
+- /* use normal pattern ROPs if all planes are enabled */
+-
+- gxr_load_raster_operation(windowsROPpat[rop & 0x0F]);
+- }
+- else
+- {
+- /* select ROP that uses planemask in src data */
+-
+- gxr_load_solid_source((unsigned short) planemask);
+- gxr_load_raster_operation(windowsROPsrcMask[rop & 0x0F]);
++{ /* divide the operation into columns if required; use twice the
++ blit buffer width because buffer 0 will overflow into buffer 1 */
++ while (w > 2 * bltBufWidth)
++ { CYRIXSubsequentFillRectSolid(x, y, 2 * bltBufWidth, h);
++ x += 2 * bltBufWidth;
++ w -= 2 * bltBufWidth;
+ }
++ CYRIXsetupSync();
++ CYRIXsetDstXY(x, y);
++ CYRIXsetWH(w, h);
++ CYRIXsetBlitMode();
+ }
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSubsequent8x8PatternColorExpand
+-//
+-// This routine is called to fill a rectangular region using the previously
+-// specified monochrome pattern (8x8) and raster operation.
+-//
+-// Sample application uses:
+-// - Patterned desktops
+-// - x11perf: stippled rectangle tests (-srect500).
+-// - x11perf: opaque stippled rectangle tests (-osrect500).
+-//---------------------------------------------------------------------------
+-*/
+-
+-void CYRIXSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h)
+-int patternx, patterny;
+-int x, y, w, h;
+-{
+- /* call routine to fill rectangular region */
+-
+- gxr_pattern_fill((unsigned short) x, (unsigned short) y,
+- (unsigned short) w, (unsigned short) h);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSetupForScreenToScreenCopy
+-//
+-// This routine is called to setup the planemask and raster operation
+-// for future screen to screen BLTs.
+-//---------------------------------------------------------------------------
+-*/
+
++/* Screen to screen copies */
+ void
+ CYRIXSetupForScreenToScreenCopy(xdir, ydir, rop, planemask, transparency_color)
+ int xdir, ydir;
+ int rop;
+ unsigned int planemask;
+ int transparency_color;
+-{
+- /* LOAD PLANEMASK INTO PATTERN DATA */
++{ CYRIXsetupSync();
++ CYRIXsetPatColors01(planemask, 0);
+
+- gxr_load_solid_pattern((unsigned short) planemask);
+-
+- /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */
++ if (transparency_color == -1)
++ { CYRIXsetPatMode(rop, RM_PAT_DISABLE);
++ transMode = 0;
++ }
++ else
++ { CYRIXsetPatModeTrans(RM_PAT_DISABLE);
++ transMode = 1;
+
+- gxr_load_raster_operation(windowsROPpatMask[rop & 0x0F]);
++ /* fill blit buffer 1 with the transparency color */
++ if (vgaBitsPerPixel == 16)
++ { int k = CYRIXbltBufSize / 4;
++ CARD32 val = (transparency_color << 16) |
++ transparency_color;
++ volatile CARD32* buf = &(GX_REG(CYRIXbltBuf1Address));
++
++ while (--k >= 0) buf[k] = val;
++ }
++ else
++ memset(GXregisters + CYRIXbltBuf1Address,
++ transparency_color, CYRIXbltBufSize);
++ }
+
+- /* SAVE TRANSPARENCY FLAG */
++ blitMode = BM_READ_SRC_FB | BM_WRITE_FB | BM_SOURCE_COLOR
++ | (transMode ? IfDest(rop, BM_READ_DST_FB1) : BM_READ_DST_NONE)
++ | (ydir < 0 ? BM_REVERSE_Y : 0);
+
+- CYRIXtransparent = (transparency_color == -1) ? 0 : 1;
+- CYRIXtransColor = transparency_color;
++ copyXdir = xdir;
+ }
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSubsequentScreenToScreenCopy
+-//
+-// This routine is called to perform a screen to screen BLT using the
+-// previously specified planemask, raster operation, and transparency flag.
+-//
+-// Sample application uses (non-transparent):
+-// - Moving windows.
+-// - x11perf: scroll tests (-scroll500).
+-// - x11perf: copy from window to window (-copywinwin500).
+-//
+-// No application found using transparency.
+-//---------------------------------------------------------------------------
+-*/
+-
+ void
+ CYRIXSubsequentScreenToScreenCopy(x1, y1, x2, y2, w, h)
+ int x1, y1, x2, y2, w, h;
+-{
+- if (CYRIXtransparent)
+- {
+- /* CALL ROUTINE FOR TRANSPARENT SCREEN TO SCREEN BLT */
+- /* Should only be called for the "copy" raster operation. */
+-
+- gxr_screen_to_screen_xblt(
+- (unsigned short) x1, (unsigned short) y1,
+- (unsigned short) x2, (unsigned short) y2,
+- (unsigned short) w, (unsigned short) h,
+- (unsigned short) CYRIXtransColor);
++{ int up = (blitMode & BM_REVERSE_Y);
++
++ /* divide the operation into columns when necessary */
++ if (copyXdir < 0)
++ { int x_offset = w - bltBufWidth;
++
++ while (x_offset > 0)
++ { CYRIXSubsequentScreenToScreenCopy(x1 + x_offset, y1,
++ x2 + x_offset, y2,
++ bltBufWidth, h);
++ x_offset -= bltBufWidth;
++ w -= bltBufWidth;
++ } }
++ else while (w > bltBufWidth)
++ { CYRIXSubsequentScreenToScreenCopy(x1, y1, x2, y2,
++ bltBufWidth, h);
++ x1 += bltBufWidth;
++ x2 += bltBufWidth;
++ w -= bltBufWidth;
+ }
+- else
+- {
+- /* CALL ROUTINE FOR NORMAL SCREEN TO SCREEN BLT */
+
+- gxr_screen_to_screen_blt(
+- (unsigned short) x1, (unsigned short) y1,
+- (unsigned short) x2, (unsigned short) y2,
+- (unsigned short) w, (unsigned short) h);
++ CYRIXsetupSync();
++ CYRIXsetSrcXY(x1, (up ? (y1 + h - 1) : y1));
++ CYRIXsetDstXY(x2, (up ? (y2 + h - 1) : y2));
++
++ /* in transparent mode, one line reads the transparency color
++ into a processor-internal register, and the remaining lines
++ can be done in a single second pass */
++ if (transMode)
++ { blitMode |= BM_READ_DST_BB1;
++ CYRIXsetWH(w, 1);
++ CYRIXsetBlitMode();
++ h--;
++ if (!h) return;
++ if (up) { y1--; y2--; }
++ else { y1++; y2++; }
++ CYRIXsetupSync();
++ blitMode &= ~(BM_READ_DST_BB1);
+ }
++ CYRIXsetWH(w, h);
++ CYRIXsetBlitMode();
+ }
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSubsequentBresenhamLine
+-//
+-// This routine is called to render a vector using the specified Bresenham
+-// parameters.
+-//
+-// Sample application uses:
+-// - Window outlines on window move.
+-// - x11perf: line segments (-seg500).
+-//---------------------------------------------------------------------------
+-*/
+
++/* Bresenham lines */
+ void
+ CYRIXSubsequentBresenhamLine(x1, y1, octant, err, e1, e2, length)
+ int x1, y1, octant, err, e1, e2, length;
+-{
+- unsigned short flags;
+-
+- /* DETERMINE YMAJOR AND DIRECTION FLAGS */
+-
+- if (octant & YMAJOR)
+- { flags = VM_Y_MAJOR;
+- if (!(octant & XDECREASING)) flags |= VM_MINOR_INC;
+- if (!(octant & YDECREASING)) flags |= VM_MAJOR_INC;
++{ if (octant & YMAJOR)
++ { vectorMode = (vectorMode & VM_READ_DST_FB) | VM_Y_MAJOR;
++ if (!(octant & XDECREASING)) vectorMode |= VM_MINOR_INC;
++ if (!(octant & YDECREASING)) vectorMode |= VM_MAJOR_INC;
+ }
+ else
+- { flags = VM_X_MAJOR;
+- if (!(octant & XDECREASING)) flags |= VM_MAJOR_INC;
+- if (!(octant & YDECREASING)) flags |= VM_MINOR_INC;
++ { vectorMode = (vectorMode & VM_READ_DST_FB) | VM_X_MAJOR;
++ if (!(octant & XDECREASING)) vectorMode |= VM_MAJOR_INC;
++ if (!(octant & YDECREASING)) vectorMode |= VM_MINOR_INC;
+ }
+
+- /* CALL ROUTINE TO DRAW VECTOR */
+-
+- gxr_bresenham_line((unsigned short) x1, (unsigned short) y1,
+- (unsigned short) length, (unsigned short) err,
+- (unsigned short) e1, (unsigned short) e2, (unsigned short) flags);
++ CYRIXsetupSync();
++ CYRIXsetDstXY(x1, y1);
++ CYRIXsetWH(length, (err & 0xFFFF));
++ CYRIXsetSrcXY((e1 & 0xFFFF), (e2 & 0xFFFF));
++ CYRIXsetVectorMode();
+ }
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSetupForCPUToScreenColorExpand
+-//
+-// This routine is called to setup the planemask, colors, and raster
+-// operation for future monocrome bitmap to screen BLTs.
+-//---------------------------------------------------------------------------
+-*/
+
+-void CYRIXSetupForCPUToScreenColorExpand(bg, fg, rop, planemask)
++/* 8x8 pattern color expand */
++void CYRIXSetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, rop, planemask)
++int patternx, patterny;
+ int bg, fg, rop;
+ unsigned int planemask;
+ { int trans = (bg == -1);
+
+- /* LOAD SOURCE COLORS */
++ CYRIXsetupSync();
++ CYRIXsetSourceColors01(planemask, planemask);
++ CYRIXsetPatColors01(trans ? 0 : bg, fg);
++ CYRIXsetPatData(patternx, patterny);
++ CYRIXsetPatModeX(rop, RM_PAT_MONO | (trans ? RM_PAT_TRANSPARENT : 0));
+
+- gxr_load_mono_source((unsigned short) bg, (unsigned short) fg,
+- (unsigned short) trans);
++ blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND
++ | (trans ? IfDest(rop, BM_READ_DST_FB0) : BM_READ_DST_NONE);
++}
+
+- /* LOAD PLANEMASK INTO PATTERN DATA */
++void CYRIXSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h)
++int patternx, patterny;
++int x, y, w, h;
++{ CYRIXSubsequentFillRectSolid(x, y, w, h);
++}
+
+- gxr_load_solid_pattern((unsigned short) planemask);
+-
+- /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */
+
+- gxr_load_raster_operation(windowsROPpatMask[rop & 0x0F]);
+-}
++/* CPU-to-screen color expansion */
++void CYRIXSetupForCPUToScreenColorExpand(bg, fg, rop, planemask)
++int bg, fg, rop;
++unsigned int planemask;
++{ int trans = (bg == -1);
+
+-/*
+-//---------------------------------------------------------------------------
+-// CYRIXSubsequentCPUToScreenColorExpand
+-//
+-// This routine is called to render expanded monocrome bitmap data to the
+-// screen using the previously specified colors and raster operation. Since
+-// the server loads the monochrome data into BB0, not the driver, this
+-// routine just sets a flag and saves the parameters to use when the server
+-// is done loading the data and calls the CYRIXAccelSync function.
+-//
+-// Sample application uses:
+-// - Text in windows.
+-// - x11perf: text (-ftext, -f8text, -f9text, ...).
+-//---------------------------------------------------------------------------
+-*/
++ CYRIXsetupSync();
++ CYRIXsetSourceColors01(trans ? 0 : bg, fg);
++ CYRIXsetPatColors01(planemask, 0);
++
++ CYRIXsetPatMode(rop, RM_PAT_DISABLE | (trans ? RM_SRC_TRANSPARENT : 0));
++
++ /* this is formally incorrect: XAA may use both BB0 and BB1
++ for the text source bitmap, so READ_DST_FB1 should not be
++ used. So far, this problem has not manifested itself in
++ practice. */
++ blitMode = BM_READ_SRC_BB0 | BM_WRITE_FB | BM_SOURCE_EXPAND
++ | (trans ? IfDest(rop, BM_READ_DST_FB1) : BM_READ_DST_NONE);
++}
+
+ void CYRIXSubsequentCPUToScreenColorExpand(x, y, w, h, skipleft)
+ int x, y, w, h;
+ int skipleft;
+-{
+- CYRIXstartMonoExpand = 1;
+- CYRIXsaveX = x;
+- CYRIXsaveY = y;
+- CYRIXsaveW = w;
+- CYRIXsaveH = h;
+-
+- /* WAIT UNTIL IDLE BEFORE ALLOWING WRITES TO BLT BUFFERS */
+- /* Server will load the monochrome data into BB0 after this. */
++{ CYRIXsetupSync();
++ CYRIXsetSrcXY(0, 0);
++ CYRIXsetDstXY(x, y);
++ CYRIXsetWH(w, h);
+
+- gxr_wait_until_idle();
++ CYRIXAccelSync();
++ setBlitModeOnSync = 1;
+ }
+-
+-/* END OF FILE */
+
+diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c
+--- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c Wed Jun 23 08:37:22 1999
++++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c Fri Nov 6 11:41:51 1998
+@@ -1,12 +1,9 @@
+-/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c,v 1.1.2.7 1999/06/23 12:37:22 hohndel Exp $ */
++/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/cyrix_driver.c,v 1.1.2.6 1998/11/06 09:47:08 hohndel Exp $ */
+ /*
+- * Copyright 1999 by Brian Falardeau
+ * Copyright 1998 by Annius V. Groenink (A.V.Groenink@zfc.nl, avg@cwi.nl),
+ * Dirk H. Hohndel (hohndel@suse.de),
+ * Portions: the GGI project & confidential CYRIX databooks.
+ *
+- * Substitute Brian Falardeau into a copy of the following legal jargon...
+- *
+ * 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
+@@ -25,17 +22,13 @@
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
++/* $XConsortium: $ */
+
+ /*************************************************************************/
+
+ /*
+ Log for the cyrix driver source as a whole
+
+- May 1999, Brian Falardeau:
+- - Fixed interaction with SoftVGA for setting 2K pitch at 1280x1024.
+- - Added CRTC tables for 60 Hz and 75 Hz modes.
+- - Removed enabling display compression directly for VSA1.
+-
+ 5th Nov 1998 avg - Fixed blit buffer organization using CPU_WRITE
+ instruction. Support for older chipsets (color
+ treatment and different CPU_WRITE opcode).
+@@ -115,35 +108,50 @@
+ #include "extensions/xf86dgastr.h"
+ #endif
+
++#ifdef XF86VGA16
++#define MONOVGA
++#endif
+
++#if !defined(MONOVGA) && !defined(XF86VGA16)
+ #include "vga256.h"
++#endif
++
+ #include "cyrix.h"
+
+ pciTagRec CyrixPciTag;
+ extern vgaHWCursorRec vgaHWCursor;
+
+-#define NUM_STD_CRTC_REGS 25
+-#define NUM_EXT_CRTC_REGS 16
+-
+ typedef struct {
+ vgaHWRec std; /* IBM VGA */
+ struct vgaCYRIXext
+- {
+- /* override of miscellaneous output register value */
+-
+- unsigned char miscOutput;
+-
+- /* override of standard CRTC register values */
+-
+- unsigned char stdCRTCregs[NUM_STD_CRTC_REGS];
+-
+- /* extended CRTC register values (specific to MediaGX) */
+-
+- unsigned char extCRTCregs[NUM_EXT_CRTC_REGS];
++ { /* extended SoftVGA registers */
++ unsigned char VerticalTimingExtension;
++ unsigned char ExtendedAddressControl;
++ unsigned char ExtendedOffset;
++ unsigned char ExtendedColorControl;
++ unsigned char DisplayCompression;
++ unsigned char DriverControl;
++ unsigned char DACControl;
++ unsigned char ClockControl;
++ unsigned char CrtClockFrequency;
++ unsigned char CrtClockFrequencyFraction;
++ unsigned char RefreshRate;
++
++ /* display controller hardware registers */
++ CARD32 DcGeneralCfg;
++ CARD32 DcCursStOffset;
++ CARD32 DcCbStOffset;
++ CARD32 DcLineDelta;
++ CARD32 DcBufSize;
++ CARD32 DcCursorX;
++ CARD32 DcCursorY;
++ CARD32 DcCursorColor;
+
+ /* graphics pipeline registers */
+-
+ CARD32 GpBlitStatus;
++
++ /* save area for cursor image */
++ char cursorPattern[256];
+ } ext;
+ } vgaCYRIXRec, *vgaCYRIXPtr;
+
+@@ -158,9 +166,11 @@
+ static void CYRIXRestore();
+ static void CYRIXAdjust();
+
++#ifndef MONOVGA
+ static void CYRIXFbInit();
+ static Bool CYRIXScreenInit();
+ static Bool CYRIXPitchAdjust();
++#endif
+
+ void CYRIXSetRead();
+ void CYRIXSetWrite();
+@@ -177,7 +187,11 @@
+ CYRIXAdjust,
+ vgaHWSaveScreen,
+ (void (*)())NoopDDA, /* CYRIXGetMode */
++#ifndef MONOVGA
+ CYRIXFbInit,
++#else
++ (void (*)())NoopDDA, /* CYRIXFbInit */
++#endif
+ CYRIXSetRead,
+ CYRIXSetWrite,
+ CYRIXSetReadWrite,
+@@ -191,9 +205,9 @@
+ VGA_NO_DIVIDE_VERT, /* ChipInterlaceType */
+ {0,}, /* ChipOptionFlags */
+ 8, /* ChipRounding */
+- TRUE, /* ChipUseLinearAddressing */
+- 0x40800000, /* ChipLinearBase */
+- 0x001FFFFF, /* ChipLinearSize */
++ FALSE, /* ChipUseLinearAddressing */
++ 0, /* ChipLinearBase */
++ 0, /* ChipLinearSize */
+ TRUE, /* ChipHas16bpp */
+ FALSE, /* ChipHas24bpp */
+ FALSE, /* ChipHas32bpp */
+@@ -207,10 +221,6 @@
+
+ char* GXregisters;
+
+-int CYRIXvsaversion; /* VSA version */
+-#define CYRIX_VSA1 1
+-#define CYRIX_VSA2 2
+-
+ int CYRIXcbufferAddress; /* relative to video base */
+ int CYRIXoffscreenAddress;
+ int CYRIXcursorAddress;
+@@ -225,94 +235,6 @@
+
+ #define newstate ((vgaCYRIXPtr)vgaNewVideoState)
+
+-typedef struct {
+- int xsize;
+- int ysize;
+- int clock;
+- unsigned char miscOutput;
+- unsigned char stdCRTCregs[NUM_STD_CRTC_REGS];
+- unsigned char extCRTCregs[NUM_EXT_CRTC_REGS];
+-} vgaCYRIXmode;
+-
+-vgaCYRIXmode CYRIXmodes[] =
+-{
+-/*------------------------------------------------------------------------------*/
+- { 640, 480, /* 640x480 */
+- 25, /* 25 MHz clock = 60 Hz refresh rate */
+- 0xE3, /* miscOutput register */
+- { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, /* standard CRTC */
+- 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF },
+- { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+- { 800, 600, /* 800x600 */
+- 40, /* 40 MHz clock = 60 Hz refresh rate */
+- 0x23, /* miscOutput register */
+- { 0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0, /* standard CRTC */
+- 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF },
+- { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0xA0, 0x50, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+- { 1024, 768, /* 1024x768 */
+- 65, /* 65 MHz clock = 60 Hz refresh rate */
+- 0xE3, /* miscOutput register */
+- { 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5, /* standard CRTC */
+- 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF },
+- { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0x80, 0x41, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+- { 1280, 1024, /* 1280x1024 */
+- 108, /* 108 MHz clock = 60 Hz refresh rate */
+- 0x23, /* miscOutput register */
+- { 0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52, /* standard CRTC */
+- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF },
+- { 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0x80, 0x6C, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+- { 640, 480, /* 640x480 */
+- 31, /* 31.5 MHz clock = 75 Hz refresh rate */
+- 0xE3, /* miscOutput register */
+- { 0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F, /* standard CRTC */
+- 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF },
+- { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0xA0, 0x3F, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+- { 800, 600, /* 800x600 */
+- 99, /* 99 MHz clock = 75 Hz refresh rate */
+- 0x23, /* miscOutput register */
+- { 0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0, /* standard CRTC */
+- 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF },
+- { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0xA0, 0x63, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+- { 1024, 768, /* 1024x768 */
+- 79, /* 79 MHz clock = 75 Hz refresh rate */
+- 0xE3, /* miscOutput register */
+- { 0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5, /* standard CRTC */
+- 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF },
+- { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0x80, 0x4F, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+- { 1280, 1024, /* 1280x1024 */
+- 135, /* 135 MHz clock = 75 Hz refresh rate */
+- 0x23, /* miscOutput register */
+- { 0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52, /* standard CRTC */
+- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF },
+- { 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
+- 0x00, 0x00, 0x01, 0x03, 0x80, 0x87, 0x00, 0x00 } },
+-/*------------------------------------------------------------------------------*/
+-};
+-
+-#define NUM_CYRIX_MODES sizeof(CYRIXmodes)/sizeof(vgaCYRIXmode)
+-
+ static char *
+ CYRIXIdent(n)
+ int n;
+@@ -478,6 +400,7 @@
+ vga256InfoRec.bankedMono = TRUE;
+ OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &vga256InfoRec.clockOptions);
+
++#ifndef MONOVGA
+ /* define option set valid for the driver */
+ OFLG_SET(OPTION_SW_CURSOR, &CYRIX.ChipOptionFlags);
+ OFLG_SET(OPTION_HW_CURSOR, &CYRIX.ChipOptionFlags);
+@@ -496,12 +419,13 @@
+ CYRIX.ChipLinearSize = (1024 * vga256InfoRec.videoRam);
+
+ CYRIX.ChipUseLinearAddressing = TRUE;
++#endif
+
+ /* map the entire area from GX_BASE (scratchpad area)
+ up to the end of the control registers */
+ GXregisters = (char*)xf86MapVidMem(vga256InfoRec.scrnIndex,
+ EXTENDED_REGION,
+- (void*)physbase, 0x20000);
++ (void*)physbase, 0x9000);
+
+ if (!GXregisters)
+ { ErrorF("%s %s: Cannot map hardware registers\n",
+@@ -509,80 +433,27 @@
+ goto probeFailed;
+ }
+
+- /* check VSA version */
+- /* VSA2 contains a "CX" signature at registers 0x35 and 0x36. */
+- /* The SoftVGA interface changed slightly for VSA2. Originally, */
+- /* VSA2 was intended for MXi only, but it may someday be */
+- /* provided for MediaGX systems as well. */
+-
+- CYRIXvsaversion = CYRIX_VSA2;
+- outb(vgaIOBase + 4, 0x35);
+- if (inb(vgaIOBase + 5) != 'C') CYRIXvsaversion = CYRIX_VSA1;
+- outb(vgaIOBase + 4, 0x36);
+- if (inb(vgaIOBase + 5) != 'X') CYRIXvsaversion = CYRIX_VSA1;
+- if (CYRIXvsaversion == CYRIX_VSA1)
+- {
+- ErrorF("%s %s: VSA1 detected\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- }
+- else
+- {
+- ErrorF("%s %s: VSA2 detected\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- }
+ return(TRUE);
+ }
+
+-/*------------------------------------------------------------------------*\
+-** FbInit()
+-**
+-** From README file: "The FbInit() function is required for drivers with
+-** accelerated graphics support. It is used to replace default cfb.banked
+-** functions with accelerated chip-specific versions.
+-**
+-** For the Cyrix driver, this routine is also used to allocate video
+-** memory. This is more complicated than it needs to be...
+-**
+-** For VSA1, SoftVGA manages all of graphics memory, including the
+-** compression buffer, cursor buffer, and offscreen memory. The driver
+-** should not allocate memory itself. For offscreen memory it reads
+-** registers 0x3C and 0x3D. For the cursor buffer it reads the hardware
+-** register after validating a mode. For compression, it just sets bit 0
+-** of register 0x49 if it wants to use compression, and SoftVGA will
+-** enable it if memory has been allocated.
+-**
+-** This model, however, breaks down for this driver. There is a bug in
+-** SoftVGA that keeps the 0x3C register from working properly. This bug
+-** also prevents compression from being enabled when using a virtual
+-** desktop. This driver also cannot use the memory past 2 Meg, which
+-** effects the memory calculation.
+-**
+-** Therefore, this driver does what it is not supposed to and allocates
+-** video memory itself. But, this is required due to bugs in SoftVGA and,
+-** as it turns out, works out fine (with limiting compression use).
+-**
+-** For VSA2, the driver is supposed to do this allocation itself.
+-\*------------------------------------------------------------------------*/
+
++#ifndef MONOVGA
+ static void
+ CYRIXFbInit()
+ { int lineDelta = vga256InfoRec.displayWidth * (vgaBitsPerPixel / 8);
+ int virtualDelta = vga256InfoRec.virtualX * (vgaBitsPerPixel / 8);
+- int base;
+
+ vgaSetScreenInitHook(CYRIXScreenInit);
+
+- /* always put the cursor at the end of video memory. */
+-
+- CYRIXcursorAddress = CYRIX.ChipLinearSize - 256;
+-
+ /* offscreen memory is, normally, right after the frame buffer;
++ always put the cursor at the end of video memory.
++
+ (It would be nice to use the ignored 64KB block at the end of
+ the video memory (2112 - 2048) for the hardware cursor, but
+ it is not mapped. This will not be a problem in Xfree 3.9 */
+-
+ CYRIXoffscreenAddress = (lineDelta * vga256InfoRec.virtualY);
+- CYRIXoffscreenSize = CYRIXcursorAddress - CYRIXoffscreenAddress;
++ CYRIXcursorAddress = CYRIX.ChipLinearSize - 256;
++ CYRIXoffscreenSize = CYRIXcursorAddress - CYRIXoffscreenAddress;
+
+ /* if there is enough room between lines, put the compression
+ buffer there */
+@@ -591,7 +462,7 @@
+ CYRIXcbLineDelta = (lineDelta >> 2);
+ if (xf86Verbose > 1)
+ ErrorF("%s %s: Interleaving frame buffer and compression buffer\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
++ XCONFIG_PROBED, vga256InfoRec.name);
+ }
+ /* otherwise, put it directly after the virtual frame */
+ else
+@@ -600,7 +471,7 @@
+ if (cbuffer_size > CYRIXoffscreenSize)
+ { CYRIXcbLineDelta = 0;
+ ErrorF("%s %s: No room for the compression buffer\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
++ XCONFIG_PROBED, vga256InfoRec.name);
+ }
+ else
+ { CYRIXcbufferAddress = CYRIXoffscreenAddress;
+@@ -609,43 +480,25 @@
+ CYRIXoffscreenSize -= cbuffer_size;
+ } }
+
+- /* print results of offscreen memory configuration */
+-
+- if (CYRIXoffscreenSize <= 0)
+- {
+- ErrorF("%s %s: No offscreen memory available.\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- }
+- else
+- {
+- ErrorF("%s %s: Offscreen memory from 0x%8.8X-0x%8.8X\n",
+- XCONFIG_PROBED, vga256InfoRec.name,
+- CYRIXoffscreenAddress,
+- CYRIXoffscreenAddress+CYRIXoffscreenSize-1);
+- }
+-
+- /* call CYRIXAccelInit to setup the XAA accelerated functions */
+-
++ /* call CYRIXAccelInit to setup the XAA accelerated functions */
+ if (!OFLG_ISSET(OPTION_NOACCEL, &vga256InfoRec.options))
+ CYRIXAccelInit();
+
+ /* install hardware cursor routines */
+-
+ if (OFLG_ISSET(OPTION_HW_CURSOR, &vga256InfoRec.options))
+- { if (CYRIXoffscreenSize > 0)
++ { if (CYRIXoffscreenSize >= 0)
+ { vgaHWCursor.Initialized = TRUE;
+ vgaHWCursor.Init = CYRIXCursorInit;
+ vgaHWCursor.Restore = CYRIXRestoreCursor;
+ vgaHWCursor.Warp = CYRIXWarpCursor;
+ vgaHWCursor.QueryBestSize = CYRIXQueryBestSize;
+- ErrorF("%s %s: Using hardware cursor at %8.8X\n",
+- XCONFIG_PROBED, vga256InfoRec.name, CYRIXcursorAddress);
++ if (xf86Verbose)
++ ErrorF("%s %s: Using hardware cursor\n",
++ XCONFIG_PROBED, vga256InfoRec.name);
+ }
+ else
+- {
+ ErrorF("%s %s: No room for hardware cursor\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- }
++ XCONFIG_PROBED, vga256InfoRec.name);
+ }
+ }
+
+@@ -696,6 +549,7 @@
+
+ return pitch;
+ }
++#endif /* not MONOVGA */
+
+
+ static void
+@@ -747,121 +601,210 @@
+
+ static void
+ CYRIXresetVGA()
+-{
+- int i;
++{ unsigned char temp;
++ /* switch off compression and cursor the hard way */
++ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
++ GX_REG(DC_GENERAL_CFG) &= ~(DC_GCFG_CMPE | DC_GCFG_DECE | DC_GCFG_FDTY | DC_GCFG_CURE);
++ GX_REG(DC_UNLOCK) = 0;
++ CYRIXmarkLinesDirty();
+
+ /* reset SoftVGA extensions to standard VGA behaviour */
+-
+- for (i = 0; i < NUM_EXT_CRTC_REGS; i++)
+- {
+- outb(vgaIOBase + 4, 0x40 + i);
+- outb(vgaIOBase + 5, 0x00);
+- }
++ outb(vgaIOBase + 4, CrtcExtendedAddressControl);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, temp & 0xf8);
++ outb(vgaIOBase + 4, CrtcExtendedStartAddress);
++ outb(vgaIOBase + 5, 0x00);
++ outb(vgaIOBase + 4, CrtcWriteMemoryAperture);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, temp & 0xe0);
++ outb(vgaIOBase + 4, CrtcReadMemoryAperture);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, temp & 0xe0);
++ outb(vgaIOBase + 4, CrtcDriverControl);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, temp & 0xfe);
++ outb(vgaIOBase + 4, CrtcDisplayCompression);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, temp & 0xf0);
+ }
+
+ static void
+ CYRIXRestore(restore)
+ vgaCYRIXPtr restore;
+-{ unsigned char i, temp, temp2;
+- unsigned long value;
+-
+- /* unlock extended CRTC registers */
+-
+- outb(vgaIOBase + 4, 0x30);
+- outb(vgaIOBase + 5, 0x57);
+- outb(vgaIOBase + 5, 0x4C);
++{ unsigned char temp;
++ vgaProtect(TRUE); /* Blank the screen */
+
+- /* SIGNAL THE BEGINNING OF THE MODE SWITCH
+- SoftVGA will hold off validating the back end hardware. */
+-
+- outb(vgaIOBase + 4, CrtcModeSwitchControl);
+- outb(vgaIOBase + 5, 0x01);
++ /* it would be ideal to be able to use the ModeSwitchControl
++ register to protect SoftVGA from reading the configuration
++ before all registers have been written. But that bit must be
++ set somewhere in the middle of vgaHWRestore (after restoring
++ the font). Luckily things seem to work without it. */
+
+ /* restore standard VGA portion */
+-
+ CYRIXresetVGA();
+ vgaHWRestore((vgaHWPtr)restore);
++ CYRIXmarkLinesDirty();
+
+- /* override restored miscellaneous output regiter value */
+-
+- outb(0x3C2, restore->ext.miscOutput);
+-
+- /* override restored standard CRTC register values */
+-
+- outb(vgaIOBase + 4, 0x11);
+- outb(vgaIOBase + 5, 0x00);
+- for (i = 0; i < NUM_STD_CRTC_REGS; i++)
+- {
+- outb(vgaIOBase + 4, i);
+- outb(vgaIOBase + 5, restore->ext.stdCRTCregs[i]);
+- }
+-
+ /* restore SoftVGA extended registers */
++ outb(vgaIOBase + 4, CrtcDriverControl);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.DriverControl & 0x01)
++ | (temp & 0xfe));
++
++ outb(vgaIOBase + 4, CrtcVerticalTimingExtension);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.VerticalTimingExtension & 0x55)
++ | (temp & 0xaa));
++
++ outb(vgaIOBase + 4, CrtcExtendedAddressControl);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.ExtendedAddressControl & 0x07)
++ | (temp & 0xf8));
++
++ outb(vgaIOBase + 4, CrtcExtendedOffset);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.ExtendedOffset & 0x03)
++ | (temp & 0xfc));
++
++ outb(vgaIOBase + 4, CrtcExtendedColorControl);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.ExtendedColorControl & 0x07)
++ | (temp & 0xf8));
++
++ outb(vgaIOBase + 4, CrtcDisplayCompression);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.DisplayCompression & 0x0f)
++ | (temp & 0xf0));
++
++ outb(vgaIOBase + 4, CrtcDACControl);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.DACControl & 0x0e)
++ | (temp & 0xf1));
++
++ if (restore->std.NoClock >= 0)
++ { outb(vgaIOBase + 4, CrtcClockControl);
++ temp = inb(vgaIOBase + 5);
++ outb(vgaIOBase + 5, (restore->ext.ClockControl & 0xb0)
++ | (temp & 0x4f));
++
++ outb(vgaIOBase + 4, CrtcClockFrequency);
++ outb(vgaIOBase + 5, restore->ext.CrtClockFrequency);
++
++ outb(vgaIOBase + 4, CrtcClockFrequencyFraction);
++ outb(vgaIOBase + 5, restore->ext.CrtClockFrequencyFraction);
++
++ outb(vgaIOBase + 4, CrtcRefreshRate);
++ outb(vgaIOBase + 5, restore->ext.RefreshRate);
++ }
++
++ /* let SoftVGA programming settle before we access DC registers,
++ but don't wait too long */
++ usleep(1000);
++ CYRIXmarkLinesDirty();
++
++ /* restore display controller hardware registers */
++#ifndef MONOVGA
++#define DCFG_MASK (DC_GCFG_FDTY | DC_GCFG_DECE | DC_GCFG_CMPE)
++#define GPBS_MASK (BC_16BPP | BC_FB_WIDTH_2048)
+
+- for (i = 0; i < NUM_EXT_CRTC_REGS; i++)
+- {
+- outb(vgaIOBase + 4, 0x40+i);
+- outb(vgaIOBase + 5, restore->ext.extCRTCregs[i]);
+- }
++ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+
+- /* signal the end of the mode switch */
++ GX_REG(DC_CURS_ST_OFFSET) = restore->ext.DcCursStOffset;
++ GX_REG(DC_CB_ST_OFFSET) = restore->ext.DcCbStOffset;
++ GX_REG(DC_LINE_DELTA) = (GX_REG(DC_LINE_DELTA) & 0xFFC00FFF)
++ | (restore->ext.DcLineDelta & 0x003FF000);
++ GX_REG(DC_BUF_SIZE) = (GX_REG(DC_BUF_SIZE) & 0xFFFF01FF)
++ | (restore->ext.DcBufSize & 0x0000FE00);
++ GX_REG(DC_CURSOR_X) = restore->ext.DcCursorX;
++ GX_REG(DC_CURSOR_Y) = restore->ext.DcCursorY;
++ GX_REG(DC_CURSOR_COLOR) = restore->ext.DcCursorColor;
+
+- outb(vgaIOBase + 4, CrtcModeSwitchControl);
+- outb(vgaIOBase + 5, 0x00);
++ GX_REG(DC_GENERAL_CFG) = (GX_REG(DC_GENERAL_CFG) & (~DCFG_MASK))
++ | (restore->ext.DcGeneralCfg & DCFG_MASK);
+
+- /* wait until SoftVGA has validated the mode.
+- This is for VSA1 only, where SoftVGA waits until the next
+- vertical blank to recalculate the hardware state. For VSA2
+- the hardware us updated immediately, so this is not needed.
+- THIS MUST BE DONE FOR VSA1 before loading the GP_BLT_STATUS
+- register, otherwise SoftVGA will override the value. */
++ GX_REG(DC_UNLOCK) = 0;
+
+- if (CYRIXvsaversion == CYRIX_VSA1)
+- {
+- outb(vgaIOBase + 4, 0x33);
+- while(inb(vgaIOBase + 5) & 0x80);
+- }
++ GX_REG(GP_BLIT_STATUS) = (GX_REG(GP_BLIT_STATUS) & (~GPBS_MASK))
++ | (restore->ext.GpBlitStatus & GPBS_MASK);
+
+- /* overrite what SoftVGA may have stored into GP_BLIT_STATUS */
++ /* restore cursor pattern */
++ if (restore->ext.DcCursStOffset < 1024 * vga256InfoRec.videoRam)
++ memcpy((char*)vgaLinearBase + restore->ext.DcCursStOffset,
++ restore->ext.cursorPattern, 256);
++#endif
+
+- GX_REG(GP_BLIT_STATUS) = restore->ext.GpBlitStatus;
++ vgaProtect(FALSE); /* Turn on screen */
+ }
+
+ static void *
+ CYRIXSave(save)
+ vgaCYRIXPtr save;
+-{ unsigned char i;
+- struct vgaCYRIXext ext;
++{ struct vgaCYRIXext ext;
+
+- /* save miscellaneous output register */
++#ifndef MONOVGA
++ /* save graphics pipeline registers */
++ ext.GpBlitStatus = GX_REG(GP_BLIT_STATUS);
+
+- ext.miscOutput = inb(0x3CC);
++ /* save display controller hardware registers */
++ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
++ ext.DcGeneralCfg = GX_REG(DC_GENERAL_CFG);
++ ext.DcCursStOffset = GX_REG(DC_CURS_ST_OFFSET);
++ ext.DcCbStOffset = GX_REG(DC_CB_ST_OFFSET);
++ ext.DcLineDelta = GX_REG(DC_LINE_DELTA);
++ ext.DcBufSize = GX_REG(DC_BUF_SIZE);
++ ext.DcCursorX = GX_REG(DC_CURSOR_X);
++ ext.DcCursorY = GX_REG(DC_CURSOR_Y);
++ ext.DcCursorColor = GX_REG(DC_CURSOR_COLOR);
++ GX_REG(DC_UNLOCK) = 0;
++
++ /* save cursor pattern.
++ In the 3.3.1 solution, we don't need to do this
++ if it is in the extra 64KB block of frame buffer memory
++ that we ignore (and is not mapped anyway) */
++ if (ext.DcCursStOffset < 1024 * vga256InfoRec.videoRam)
++ memcpy(ext.cursorPattern,
++ (char*)vgaLinearBase + ext.DcCursStOffset, 256);
++#endif
+
+- /* save standard CRTC registers */
++ /* save SoftVGA extended registers */
++ outb(vgaIOBase + 4, CrtcVerticalTimingExtension);
++ ext.VerticalTimingExtension = inb(vgaIOBase + 5);
+
+- for (i = 0; i < NUM_STD_CRTC_REGS; i++)
+- {
+- outb(vgaIOBase + 4, i);
+- ext.stdCRTCregs[i] = inb(vgaIOBase + 5);
+- }
++ outb(vgaIOBase + 4, CrtcExtendedAddressControl);
++ ext.ExtendedAddressControl = inb(vgaIOBase + 5);
+
+- /* save extended CRTC registers */
++ outb(vgaIOBase + 4, CrtcExtendedOffset);
++ ext.ExtendedOffset = inb(vgaIOBase + 5);
+
+- for (i = 0; i < NUM_EXT_CRTC_REGS; i++)
+- {
+- outb(vgaIOBase + 4, 0x40+i);
+- ext.extCRTCregs[i] = inb(vgaIOBase + 5);
+- }
++ outb(vgaIOBase + 4, CrtcExtendedColorControl);
++ ext.ExtendedColorControl = inb(vgaIOBase + 5);
+
+- /* save graphics pipeline registers */
++ outb(vgaIOBase + 4, CrtcDisplayCompression);
++ ext.DisplayCompression = inb(vgaIOBase + 5);
+
+- ext.GpBlitStatus = GX_REG(GP_BLIT_STATUS);
++ outb(vgaIOBase + 4, CrtcDriverControl);
++ ext.DriverControl = inb(vgaIOBase + 5);
+
+- /* save standard VGA portion */
++ outb(vgaIOBase + 4, CrtcDACControl);
++ ext.DACControl = inb(vgaIOBase + 5);
++
++ outb(vgaIOBase + 4, CrtcClockControl);
++ ext.ClockControl = inb(vgaIOBase + 5);
++
++ outb(vgaIOBase + 4, CrtcClockFrequency);
++ ext.CrtClockFrequency = inb(vgaIOBase + 5);
+
++ outb(vgaIOBase + 4, CrtcClockFrequencyFraction);
++ ext.CrtClockFrequencyFraction = inb(vgaIOBase + 5);
++
++ outb(vgaIOBase + 4, CrtcRefreshRate);
++ ext.RefreshRate = inb(vgaIOBase + 5);
++
++ /* save standard VGA portion */
+ CYRIXresetVGA();
+ save = (vgaCYRIXPtr)vgaHWSave((vgaHWPtr)save, sizeof(vgaCYRIXRec));
+ save->ext = ext;
++
+ return ((void *) save);
+ }
+
+@@ -869,108 +812,101 @@
+ static Bool
+ CYRIXInit(mode)
+ DisplayModePtr mode;
+-{ int i, mode_index;
+- int clock = vga256InfoRec.clock[mode->Clock] / 1000;
+- int min, diff;
+- int offset_shift = (vgaBitsPerPixel == 16) ? 2 :
++{ int offset_shift = (vgaBitsPerPixel == 16) ? 2 :
+ (vgaBitsPerPixel == 8) ? 3 : 4;
+ int line_offset = vga256InfoRec.displayWidth >> offset_shift;
+
+ /* initialize standard VGA portion */
+-
+ if (!vgaHWInit(mode,sizeof(vgaCYRIXRec)))
+ return(FALSE);
+
+- /* search for specified mode in the table */
+- /* Need to find the entry with the closest dot clock value */
+- /* Assume within at least 200 MHz and then maintain closest natch. */
+-
+- mode_index = 0;
+- min = 200;
+- for (i = 0; i < NUM_CYRIX_MODES; i++)
+- {
+- diff = clock - CYRIXmodes[i].clock;
+- if (diff < 0) diff = -diff;
+- if ((mode->CrtcHDisplay == CYRIXmodes[i].xsize) &&
+- (mode->CrtcVDisplay == CYRIXmodes[i].ysize) &&
+- (diff < min))
+- {
+- mode_index = i;
+- min = diff;
+- }
+- }
+-
+- /* override standard miscOutput register value */
+-
+- newstate->ext.miscOutput = CYRIXmodes[mode_index].miscOutput;
++ newstate->std.CRTC[19] = line_offset;
+
+- /* override standard CRTC register values */
++ /* initialize SoftVGA extended registers */
++ newstate->ext.VerticalTimingExtension =
++ ((mode->CrtcVSyncStart & 0x400) >> 4) |
++ (((mode->CrtcVDisplay - 1) & 0x400) >> 8) |
++ (((mode->CrtcVTotal - 2) & 0x400) >> 10) |
++ ((mode->CrtcVSyncStart & 0x400) >> 6);
+
+- for (i = 0; i < NUM_STD_CRTC_REGS; i++)
+- {
+- newstate->ext.stdCRTCregs[i] =
+- CYRIXmodes[mode_index].stdCRTCregs[i];
+- }
+-
+- /* set extended CRTC registers */
+-
+- for (i = 0; i < NUM_EXT_CRTC_REGS; i++)
+- {
+- newstate->ext.extCRTCregs[i] =
+- CYRIXmodes[mode_index].extCRTCregs[i];
+- }
+-
+- /* override pitch from the mode tables */
+- /* (same tables are used for 8BPP and 16BPP) */
++ if (vgaBitsPerPixel < 8)
++ newstate->ext.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER;
++ else
++ newstate->ext.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER |
++ EAC_PACKED_CHAIN4;
+
+- newstate->ext.stdCRTCregs[19] = line_offset;
+- newstate->ext.extCRTCregs[5] = ((line_offset >> 8) & 0x03);
++ newstate->ext.ExtendedOffset = ((line_offset >> 8) & 0x03);
+
+- /* override color control from the mode tables */
+- /* (same tables are used for 8BPP and 16BPP) */
++ newstate->ext.ExtendedColorControl = (vgaBitsPerPixel == 16)
++ ? ECC_16BPP | ECC_565_FORMAT
++ : ECC_8BPP;
++
++ /* display compression is set using the DC registers */
++ newstate->ext.DisplayCompression = 0x00;
++
++ /* we drive the palette through the display controller (in new
++ chipsets only) in 8bpp and 16bpp (that is, whenever the
++ hardware cursor is used). */
++ if (vgaBitsPerPixel < 8)
++ newstate->ext.DriverControl = 0x00;
++ else
++ newstate->ext.DriverControl = DRVCT_DISPLAY_DRIVER_ACTIVE;
+
+- newstate->ext.extCRTCregs[6] = (vgaBitsPerPixel == 16)
+- ? ECC_16BPP | ECC_565_FORMAT : ECC_8BPP;
++ /* set `16 bit bus' or else compression will hang the
++ system in 16bpp mode */
++ if (vgaBitsPerPixel == 16)
++ newstate->ext.DACControl = DACCT_ENABLE_16BIT_BUS;
++ else
++ newstate->ext.DACControl = 0;
+
+- /* enable display compression when appropriate */
+
+- if (CYRIXvsaversion == CYRIX_VSA1)
+- {
+- /* For VSA1, SoftVGA manages the compression buffer. */
+- /* Enabling compression directly causes unpredictable results. */
+- /* Only enable if not panning (there is a bug in SoftVGA that */
+- /* will put the compression buffer in the wrong place when */
+- /* using a virtual desktop. */
+- /* By setting bit 0 of register 0x49, SoftVGA will enable */
+- /* compression whenever possible, based on memory available */
+- /* and starting address of memory. */
+-
+- if ((mode->CrtcVDisplay == vga256InfoRec.virtualY) &&
+- (mode->CrtcHDisplay == vga256InfoRec.virtualX))
+- {
+- newstate->ext.extCRTCregs[9] = 0x01;
+- ErrorF("%s %s: Display compression enabled.\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- }
+- else
+- {
+- ErrorF("%s %s: Display compression disabled.\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- }
++ if (newstate->std.NoClock >= 0)
++ { int entier_clock = (vga256InfoRec.clock[mode->Clock] / 1000);
++ int clock_fraction = (vga256InfoRec.clock[mode->Clock] / 100)
++ - (entier_clock * 10);
++
++ newstate->ext.ClockControl = CLKCT_EXT_CLOCK_MODE;
++ newstate->ext.CrtClockFrequency = entier_clock;
++ newstate->ext.CrtClockFrequencyFraction = clock_fraction;
++ newstate->ext.RefreshRate = 0 /* relevant to VGA BIOS only */;
++ }
++
++#ifndef MONOVGA
++ /* initialize masked contents of display controller
++ hardware registers. */
++ newstate->ext.DcCursStOffset = CYRIXcursorAddress;
++ newstate->ext.DcCbStOffset = CYRIXcbufferAddress;
++ newstate->ext.DcLineDelta = CYRIXcbLineDelta << 12;
++ newstate->ext.DcBufSize = 0x41 << 9;
++ newstate->ext.DcCursorX = 0;
++ newstate->ext.DcCursorY = 0;
++ newstate->ext.DcCursorColor = 0;
++
++ /* Compression is enabled only when a buffer was allocated by
++ FbInit and provided that the displayed screen is the virtual
++ screen. If the line delta is not 1024 or 2048, entire frames
++ will be flagged dirty as opposed to lines. Problems with 16bpp
++ and line-dirty flagging seem to have been solved now. */
++ if (CYRIXcbLineDelta != 0 &&
++ mode->CrtcVDisplay == vga256InfoRec.virtualY &&
++ mode->CrtcHDisplay == vga256InfoRec.virtualX)
++ { newstate->ext.DcGeneralCfg = DC_GCFG_DECE
++ | DC_GCFG_CMPE;
++ if (/* vgaBitsPerPixel != 8 || -- this is OK now */
++ (vga256InfoRec.displayWidth * (vgaBitsPerPixel / 8)) & 0x03FF)
++ newstate->ext.DcGeneralCfg |= DC_GCFG_FDTY;
+ }
+ else
+- {
+- /* ### TO DO ### */
+- /* Enable display compression directly for VSA2. */
+- /* For VSA2, the display driver manages all graphics memory. */
+- }
++ newstate->ext.DcGeneralCfg = 0;
+
+- /* initialize the graphics pipeline registers */
+
++ /* initialize the graphics pipeline registers */
+ newstate->ext.GpBlitStatus = ((vga256InfoRec.displayWidth == 2048) ?
+ BC_FB_WIDTH_2048 : BC_FB_WIDTH_1024) |
+ ((vgaBitsPerPixel == 16) ?
+ BC_16BPP : BC_8BPP);
++#endif
++
+ return(TRUE);
+ }
+
+@@ -978,68 +914,31 @@
+ CYRIXAdjust(x, y)
+ int x, y;
+ { int Base = (y * vga256InfoRec.displayWidth + x);
+- unsigned long active, sync, count1, count2;
+
+ if (vgaBitsPerPixel > 8) Base *= (vgaBitsPerPixel / 8);
+ if (vgaBitsPerPixel < 8) Base /= 2;
+
+- /* wait until out of active display area */
+-
+- active = GX_REG(DC_V_TIMING_1) & 0x07FF;
+- sync = GX_REG(DC_V_TIMING_3) & 0x07FF;
+-
+- do
+- {
+- /* read twice to avoid transition values */
+-
+- count1 = GX_REG(DC_V_LINE_CNT) & 0x07FF;
+- count2 = GX_REG(DC_V_LINE_CNT) & 0x07FF;
+- } while ((count1 != count2) || (count1 < active) || (count1 >= sync));
+-
+- /* load the start address directly */
+-
++ /* doing this using the SoftVGA registers does not work reliably */
+ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+ GX_REG(DC_FB_ST_OFFSET) = Base;
+ GX_REG(DC_UNLOCK) = 0;
+ }
+
+-/*------------------------------------------------------------------------*\
+-** ValidMode()
+-**
+-** From README file: "The ValidMode() function is required. It is used to
+-** check for any chipset dependent reasons why a graphics mode might not be
+-** valid. It gets called by higher levels of the code after the Probe()
+-** stage. In many cases no special checking will be required and this
+-** function will simply return TRUE always."
+-**
+-** For the Cyrix driver, this routine loops through modes provided in a
+-** table at the beginning of this file and returns OK if it finds a match.
+-** These tables were required to make the standard VESA 60 Hz and 75 Hz
+-** modes work correctly. Doing this, however, takes away the flexibility
+-** of adding different resolutions or different refresh rates to the
+-** XF86Config file.
+-\*------------------------------------------------------------------------*/
+-
+ static int
+ CYRIXValidMode(mode, verbose, flag)
+ DisplayModePtr mode;
+ Bool verbose;
+ int flag;
+-{
+- int i;
+-
+- /* loop through table of modes */
+-
+- for (i = 0; i < NUM_CYRIX_MODES; i++)
+- {
+- if ((mode->CrtcHDisplay == CYRIXmodes[i].xsize) &&
+- (mode->CrtcVDisplay == CYRIXmodes[i].ysize))
+- {
+- return MODE_OK;
+- }
++{ /* note (avg): there seems to be a lot more to this if you look
++ at the GGI code (adjustment). */
++ if (mode->CrtcHSyncStart - mode->CrtcHDisplay >= 24 ||
++ mode->CrtcHSyncStart - mode->CrtcHDisplay <= 8)
++ { if (verbose)
++ ErrorF("%s %s: mode %s: horizontal sync out of range (sync - display should be between 8 and 24)\n",
++ XCONFIG_PROBED, vga256InfoRec.name, mode->name
++ );
++ return MODE_HSYNC;
+ }
+- return MODE_BAD;
++ return(MODE_OK);
+ }
+-
+-/* END OF FILE */
+
+diff -ruN XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c
+--- XFree86-3.3.5/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c Thu Jun 24 01:59:41 1999
++++ XFree86-3.3.3.1/xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c Wed Dec 31 19:00:00 1969
+@@ -1,1237 +0,0 @@
+-/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cyrix/gxrender.c,v 1.1.2.1 1999/06/24 05:59:41 hohndel Exp $ */
+-/*
+-//---------------------------------------------------------------------------
+-// gxrender.c
+-//
+-// This file gives examples of using the MediaGX graphics unit to provide
+-// acceleration for 2D display drivers. It is intended to provide an
+-// absraction layer for new display driver development. This code handles
+-// the quirks of the MediaGX graphics unit to allow faster developemt times
+-// for new drivers.
+-//---------------------------------------------------------------------------
+-*/
+-
+-/* GRAPHICS PIPELINE REGISTER DEFINITIONS */
+-
+-#define GP_DST_XCOOR 0x8100 /* x destination origin */
+-#define GP_DST_YCOOR 0x8102 /* y destination origin */
+-#define GP_WIDTH 0x8104 /* pixel width */
+-#define GP_HEIGHT 0x8106 /* pixel height */
+-#define GP_SRC_XCOOR 0x8108 /* x source origin */
+-#define GP_SRC_YCOOR 0x810A /* y source origin */
+-
+-#define GP_VECTOR_LENGTH 0x8104 /* vector length */
+-#define GP_INIT_ERROR 0x8106 /* vector initial error */
+-#define GP_AXIAL_ERROR 0x8108 /* axial error increment */
+-#define GP_DIAG_ERROR 0x810A /* diagonal error increment */
+-
+-#define GP_SRC_COLOR_0 0x810C /* source color 0 */
+-#define GP_SRC_COLOR_1 0x810E /* source color 1 */
+-#define GP_PAT_COLOR_0 0x8110 /* pattern color 0 */
+-#define GP_PAT_COLOR_1 0x8112 /* pattern color 1 */
+-#define GP_PAT_COLOR_2 0x8114 /* pattern color 2 */
+-#define GP_PAT_COLOR_3 0x8116 /* pattern color 3 */
+-#define GP_PAT_DATA_0 0x8120 /* bits 31:0 of pattern */
+-#define GP_PAT_DATA_1 0x8124 /* bits 63:32 of pattern */
+-#define GP_PAT_DATA_2 0x8128 /* bits 95:64 of pattern */
+-#define GP_PAT_DATA_3 0x812C /* bits 127:96 of pattern */
+-
+-#define GP_RASTER_MODE 0x8200 /* raster operation */
+-#define GP_VECTOR_MODE 0x8204 /* vector mode register */
+-#define GP_BLIT_MODE 0x8208 /* blit mode register */
+-#define GP_BLIT_STATUS 0x820C /* blit status register */
+-
+-/* "GP_VECTOR_MODE" BIT DEFINITIONS */
+-
+-#define VM_X_MAJOR 0x0000 /* X major vector */
+-#define VM_Y_MAJOR 0x0001 /* Y major vector */
+-#define VM_MAJOR_INC 0x0002 /* positive major axis step */
+-#define VM_MINOR_INC 0x0004 /* positive minor axis step */
+-#define VM_READ_DST_FB 0x0008 /* read destination data */
+-
+-/* "GP_RASTER_MODE" BIT DEFINITIONS */
+-
+-#define RM_PAT_DISABLE 0x0000 /* pattern is disabled */
+-#define RM_PAT_MONO 0x0100 /* 1BPP pattern expansion */
+-#define RM_PAT_DITHER 0x0200 /* 2BPP pattern expansion */
+-#define RM_PAT_COLOR 0x0300 /* 8BPP or 16BPP pattern */
+-#define RM_PAT_MASK 0x0300 /* mask for pattern mode */
+-#define RM_PAT_TRANSPARENT 0x0400 /* transparent 1BPP pattern */
+-#define RM_SRC_TRANSPARENT 0x0800 /* transparent 1BPP source */
+-
+-/* "GP_BLIT_STATUS" BIT DEFINITIONS */
+-
+-#define BS_BLIT_BUSY 0x0001 /* blit engine is busy */
+-#define BS_PIPELINE_BUSY 0x0002 /* graphics pipeline is bus */
+-#define BS_BLIT_PENDING 0x0004 /* blit pending */
+-#define BC_8BPP 0x0000 /* 8BPP mode */
+-#define BC_16BPP 0x0100 /* 16BPP mode */
+-#define BC_FB_WIDTH_1024 0x0000 /* framebuffer width = 1024 */
+-#define BC_FB_WIDTH_2048 0x0200 /* framebuffer width = 2048 */
+-
+-/* "GP_BLIT_MODE" BIT DEFINITIONS */
+-
+-#define BM_READ_SRC_NONE 0x0000 /* source foreground color */
+-#define BM_READ_SRC_FB 0x0001 /* read source from FB */
+-#define BM_READ_SRC_BB0 0x0002 /* read source from BB0 */
+-#define BM_READ_SRC_BB1 0x0003 /* read source from BB1 */
+-#define BM_READ_SRC_MASK 0x0003 /* read source mask */
+-
+-#define BM_READ_DST_NONE 0x0000 /* no destination data */
+-#define BM_READ_DST_BB0 0x0008 /* destination from BB0 */
+-#define BM_READ_DST_BB1 0x000C /* destination from BB1 */
+-#define BM_READ_DST_FB0 0x0010 /* dest from FB (store BB0) */
+-#define BM_READ_DST_FB1 0x0014 /* dest from FB (store BB1)*/
+-#define BM_READ_DST_MASK 0x001C /* read destination mask */
+-
+-#define BM_WRITE_FB 0x0000 /* write to framebuffer */
+-#define BM_WRITE_MEM 0x0020 /* write to memory */
+-#define BM_WRITE_MASK 0x0020 /* write mask */
+-
+-#define BM_SOURCE_COLOR 0x0000 /* source is 8BPP or 16BPP */
+-#define BM_SOURCE_EXPAND 0x0040 /* source is 1BPP */
+-#define BM_SOURCE_TEXT 0x00C0 /* source is 1BPP text */
+-#define BM_SOURCE_MASK 0x00C0 /* source mask */
+-
+-#define BM_REVERSE_Y 0x0100 /* reverse Y direction */
+-
+-/* THE DRIVER NEEDS TO MAINTAIN THE SIZE AND LOCATION OF THE BLT BUFFERS
+-// These constants will work with 2K or 3K config, 8 or 16 BPP. The driver
+-// should set them, however, to optimize for the current config. Otherwise
+-// screen to screen BLTs, for example, may be visibly split into two vertical
+-// sections when they do not need to be.
+-*/
+-
+-/* STATIC VARIABLES FOR GXRENDER.C FILE */
+-
+-unsigned char *GXRregptr;
+-unsigned short GXRbpp;
+-unsigned short GXRbb0Base;
+-unsigned short GXRbb1Base;
+-unsigned short GXRbufferWidthPixels;
+-
+-unsigned short GXRpatternFlags;
+-unsigned short GXRsourceFlags;
+-unsigned short GXRsavedColor;
+-unsigned short GXRsavedRop;
+-unsigned short GXRusesDstData;
+-
+-/* MACROS FOR REGISTER ACCESS
+-// These macros asssume that a pointer was specified during initialization.
+-// They also assume 32-bit access is possible (16-bit access such as for
+-// Windows 98 display drivers would require different macros).
+-*/
+-
+-#define WRITE_REG8(offset, value) \
+- (*(volatile unsigned char *)(GXRregptr + (offset))) = (value)
+-
+-#define WRITE_REG16(offset, value) \
+- (*(volatile unsigned short *)(GXRregptr + (offset))) = (value)
+-
+-#define WRITE_REG32(offset, value) \
+- (*(volatile unsigned long *)(GXRregptr + (offset))) = (value)
+-
+-#define READ_REG16(offset) \
+- (*(volatile unsigned short *)(GXRregptr + (offset)))
+-
+-#define READ_REG32(offset) \
+- (*(volatile unsigned long *)(GXRregptr + (offset)))
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_INITIALIZE
+-//
+-// This routine initializes the parameters for the current configuration.
+-//
+-// REGPTR pointer to GX memory mapped registers
+-// BPP bits per pixel (8 pr 16)
+-//
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_initialize(unsigned char *regptr, unsigned short bpp,
+- unsigned short BB0base, unsigned short BB1base,
+- unsigned short BBwidthPixels)
+-{
+- GXRregptr = regptr;
+- GXRbpp = bpp;
+- GXRbb0Base = BB0base;
+- GXRbb1Base = BB1base;
+- GXRbufferWidthPixels = BBwidthPixels;
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_WAIT_UNTIL_IDLE
+-//
+-// This routine waits until the graphics engine is idle.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_wait_until_idle(void)
+-{
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_LOAD_SOLID_SOURCE
+-//
+-// This routine is used to specify a solid source color. For the Xfree96
+-// display driver, the source color is used to specify a planemask and the
+-// ROP is adjusted accordingly.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_load_solid_source(unsigned short color)
+-{
+- /* CLEAR TRANSPARENCY FLAG */
+-
+- GXRsourceFlags = 0;
+-
+- /* FORMAT 8 BPP COLOR */
+- /* GX requires 8BPP color data be duplicated into bits [15:8]. */
+-
+- if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP))
+- {
+- color &= 0x00FF;
+- color |= (color << 8);
+- }
+-
+- /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_SRC_COLOR_0, color);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_LOAD_MONO_SOURCE
+-//
+-// This routine is used to specify the monochrome source colors.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_load_mono_source(unsigned short bgcolor, unsigned short fgcolor,
+- unsigned short transparent)
+-{
+- /* SET TRANSPARENCY FLAG */
+-
+- GXRsourceFlags = transparent ? RM_SRC_TRANSPARENT : 0;
+-
+- /* FORMAT 8 BPP COLOR */
+- /* GX requires 8BPP color data be duplicated into bits [15:8]. */
+-
+- if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP))
+- {
+- bgcolor &= 0x00FF;
+- bgcolor |= (bgcolor << 8);
+- fgcolor &= 0x00FF;
+- fgcolor |= (fgcolor << 8);
+- }
+-
+- /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_SRC_COLOR_0, bgcolor);
+- WRITE_REG16(GP_SRC_COLOR_1, fgcolor);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_LOAD_SOLID_PATTERN
+-//
+-// This routine is used to specify a solid pattern color. It is called
+-// before performing solid rectangle fills or more complicated BLTs that
+-// use a solid pattern color.
+-//
+-// The driver should always call "gxr_load_raster_operation" after a call
+-// to this routine to make sure that the pattern flags are set appropriately.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_load_solid_pattern(unsigned short color)
+-{
+- /* SET PATTERN FLAGS */
+-
+- GXRpatternFlags = 0;
+-
+- /* FORMAT 8 BPP COLOR */
+- /* GX requires 8BPP color data be duplicated into bits [15:8]. */
+-
+- if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP))
+- {
+- color &= 0x00FF;
+- color |= (color << 8);
+- }
+-
+- /* SAVE THE REFORMATTED COLOR FOR LATER */
+- /* Used to call the "gxr_solid_fill" routine for special cases. */
+-
+- GXRsavedColor = color;
+-
+- /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_PAT_COLOR_0, color);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_LOAD_MONO_PATTERN
+-//
+-// This routine is used to specify a monochrome pattern.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_load_mono_pattern(unsigned short bgcolor, unsigned short fgcolor,
+- unsigned long data0, unsigned long data1, unsigned char transparent)
+-{
+- /* SET PATTERN FLAGS */
+-
+- GXRpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT :
+- RM_PAT_MONO;
+-
+- /* FORMAT 8 BPP COLOR */
+- /* GX requires 8BPP color data be duplicated into bits [15:8]. */
+-
+- if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP))
+- {
+- bgcolor &= 0x00FF;
+- bgcolor |= (bgcolor << 8);
+- fgcolor &= 0x00FF;
+- fgcolor |= (fgcolor << 8);
+- }
+-
+- /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_PAT_COLOR_0, bgcolor);
+- WRITE_REG16(GP_PAT_COLOR_1, fgcolor);
+- WRITE_REG32(GP_PAT_DATA_0, data0);
+- WRITE_REG32(GP_PAT_DATA_1, data1);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_LOAD_RASTER_OPERATION
+-//
+-// This routine loads the specified raster operation. It sets the pattern
+-// flags appropriately.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_load_raster_operation(unsigned char rop)
+-{
+- unsigned short rop16;
+-
+- /* GENERATE 16-BIT VERSION OF ROP WITH PATTERN FLAGS */
+-
+- rop16 = (unsigned short) rop | GXRpatternFlags;
+- if ((rop & 0x33) ^ ((rop >> 2) & 0x33))
+- rop16 |= GXRsourceFlags;
+-
+- /* SAVE ROP FOR LATER COMPARISONS */
+- /* Need to have the pattern flags included */
+-
+- GXRsavedRop = rop16;
+-
+- /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */
+- /* True if even bits (0:2:4:6) do not equal the correspinding */
+- /* even bits (1:3:5:7). */
+-
+- GXRusesDstData = ((rop & 0x55) ^ ((rop >> 1) & 0x55));
+-
+- /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
+- /* Only one operation can be pending at a time. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_RASTER_MODE, rop16);
+-}
+-
+-/*
+-//---------------------------------------------------------------------------
+-// GXR_SOLID_FILL
+-//
+-// This routine MUST be used when performing a solid rectangle fill with
+-// the ROPs of PATCOPY (0xF0), BLACKNESS (0x00), WHITENESS (0xFF), or
+-// PATINVERT (0x0F). There is a bug in GXm for these cases that requires a
+-// workaround.
+-//
+-// For BLACKNESS (ROP = 0x00), set the color to 0x0000.
+-// For WHITENESS (ROP = 0xFF), set the color to 0xFFFF.
+-// For PATINVERT (ROP = 0x0F), invert the desired color.
+-//
+-// X screen X position (left)
+-// Y screen Y position (top)
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-// COLOR fill color
+-//
+-// THIS ROUTINE SHOULD NOT BE DIRECTLY CALLED FROM THE DRIVER. The driver
+-// should always use gxr_pattern_fill and let that routine call this one
+-// when approipriate. This is to hide quirks specific to MediaGX hardware.
+-//---------------------------------------------------------------------------
+-*/
+-
+-void gxr_solid_fill(unsigned short x, unsigned short y,
+- unsigned short width, unsigned short height, unsigned short color)
+-{
+- unsigned short section;
+-
+- /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+- /* Only one operation can be pending at a time. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+-
+- /* SET REGISTERS TO DRAW RECTANGLE */
+-
+- WRITE_REG16(GP_DST_XCOOR, x);
+- WRITE_REG16(GP_DST_YCOOR, y);
+- WRITE_REG16(GP_HEIGHT, height);
+- WRITE_REG16(GP_RASTER_MODE, 0x00F0); /* PATCOPY */
+- WRITE_REG16(GP_PAT_COLOR_0, color);
+-
+- /* CHECK WIDTH FOR GX BUG WORKAROUND */
+-
+- if (width <= 16)
+- {
+- /* OK TO DRAW SMALL RECTANGLE IN ONE PASS */
+-
+- WRITE_REG16(GP_WIDTH, width);
+- WRITE_REG16(GP_BLIT_MODE, 0);
+- }
+- else
+- {
+- /* DRAW FIRST PART OF RECTANGLE */
+- /* Get to a 16 pixel boundary. */
+-
+- section = 0x10 - (x & 0x0F);
+- WRITE_REG16(GP_WIDTH, section);
+- WRITE_REG16(GP_BLIT_MODE, 0);
+-
+- /* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_DST_XCOOR, x + section);
+- WRITE_REG16(GP_DST_YCOOR, y);
+- WRITE_REG16(GP_WIDTH, width - section);
+- WRITE_REG16(GP_BLIT_MODE, 0);
+- }
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// GXR_PATTERN_FILL
+-//
+-// This routine is used to fill a rectangular region. The pattern must
+-// be previously loaded using one of gxr_load_*_pattern routines. Also, the
+-// raster operation must be previously specified using the
+-// "gxr_load_raster_operation" routine.
+-//
+-// X screen X position (left)
+-// Y screen Y position (top)
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_pattern_fill(unsigned short x, unsigned short y,
+- unsigned short width, unsigned short height)
+-{
+- unsigned short section, buffer_width, blit_mode;
+-
+- /* CHECK IF OPTIMIZED SOLID CASES */
+- /* Check all 16 bits of the ROP to include solid pattern flags. */
+-
+- switch(GXRsavedRop)
+- {
+- /* CHECK FOR SPECIAL CASES WITHOUT DESTINATION DATA */
+- /* Need hardware workaround for fast "burst write" cases. */
+-
+- case 0x00F0:
+- gxr_solid_fill(x, y, width, height, GXRsavedColor);
+- break;
+- case 0x000F:
+- gxr_solid_fill(x, y, width, height, ~GXRsavedColor);
+- break;
+- case 0x0000:
+- gxr_solid_fill(x, y, width, height, 0x0000);
+- break;
+- case 0x00FF:
+- gxr_solid_fill(x, y, width, height, 0xFFFF);
+- break;
+-
+- /* REMAINING CASES REQUIRE DESTINATION DATA OR NOT SOLID COLOR */
+-
+- default:
+-
+- /* DETERMINE BLT MODE VALUE */
+- /* Still here for non-solid patterns without destination data. */
+-
+- blit_mode = GXRusesDstData ? BM_READ_DST_FB0 : 0;
+-
+- /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+- /* Write the registers that do not change for each section. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_HEIGHT, height);
+-
+- /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */
+- /* Therefore, width available = BLT buffer width * 2. */
+-
+- buffer_width = GXRbufferWidthPixels << 1;
+-
+- /* REPEAT UNTIL FINISHED WITH RECTANGLE */
+- /* Perform BLT in vertical sections, as wide as the BLT buffer */
+- /* allows. Hardware does not split the operations, so */
+- /* software must do it to avoid large scanlines that would */
+- /* overflow the BLT buffers. */
+-
+- while(width > 0)
+- {
+- /* DETERMINE WIDTH OF SECTION */
+-
+- if (width > buffer_width) section = buffer_width;
+- else section = width;
+-
+- /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_DST_XCOOR, x);
+- WRITE_REG16(GP_DST_YCOOR, y);
+- WRITE_REG16(GP_WIDTH, section);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+-
+- /* ADJUST PARAMETERS FOR NEXT SECTION */
+-
+- width -= section;
+- x += section;
+- }
+- break;
+- }
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// SCREEN TO SCREEN BLT
+-//
+-// This routine should be used to perform a screen to screen BLT when the
+-// ROP does not require destination data.
+-//
+-// SRCX screen X position to copy from
+-// SRCY screen Y position to copy from
+-// DSTX screen X position to copy to
+-// DSTY screen Y position to copy to
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height)
+-{
+- unsigned short section, buffer_width;
+- unsigned short blit_mode;
+-
+- /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */
+-
+- blit_mode = GXRusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB :
+- BM_READ_SRC_FB;
+-
+- /* CHECK Y DIRECTION */
+- /* Hardware has support for negative Y direction. */
+-
+- if (dsty > srcy)
+- {
+- blit_mode |= BM_REVERSE_Y;
+- srcy += height - 1;
+- dsty += height - 1;
+- }
+-
+- /* CHECK X DIRECTION */
+- /* Hardware does not support negative X direction since at the time */
+- /* of development all supported resolutions could fit a scanline of */
+- /* data at once into the BLT buffers (using both BB0 and BB1). This */
+- /* code is more generic to allow for any size BLT buffer. */
+-
+- if (dstx > srcx)
+- {
+- srcx += width;
+- dstx += width;
+- }
+-
+- /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+- /* Write the registers that do not change for each section. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_HEIGHT, height);
+-
+- /* CHECK AVAILABLE BLT BUFFER SIZE */
+- /* Can use both BLT buffers if no destination data is required. */
+-
+- buffer_width = GXRusesDstData ? GXRbufferWidthPixels :
+- GXRbufferWidthPixels << 1;
+-
+- /* REPEAT UNTIL FINISHED WITH RECTANGLE */
+- /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */
+- /* Hardware does not split the operations, so software must do it to */
+- /* avoid large scanlines that would overflow the BLT buffers. */
+-
+- while(width > 0)
+- {
+- /* CHECK WIDTH OF CURRENT SECTION */
+-
+- if (width > buffer_width) section = buffer_width;
+- else section = width;
+-
+- /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_SRC_YCOOR, srcy);
+- WRITE_REG16(GP_DST_YCOOR, dsty);
+- WRITE_REG16(GP_WIDTH, section);
+-
+- /* CHECK X DIRECTION */
+-
+- if (dstx > srcx)
+- {
+- /* NEGATIVE X DIRECTION */
+- /* Still positive X direction within the section. */
+-
+- srcx -= section;
+- dstx -= section;
+- WRITE_REG16(GP_SRC_XCOOR, srcx);
+- WRITE_REG16(GP_DST_XCOOR, dstx);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+- }
+- else
+- {
+- /* POSITIVE X DIRECTION */
+-
+- WRITE_REG16(GP_SRC_XCOOR, srcx);
+- WRITE_REG16(GP_DST_XCOOR, dstx);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+- dstx += section;
+- srcx += section;
+- }
+- width -= section;
+- }
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// SCREEN TO SCREEN TRANSPARENT BLT
+-//
+-// This routine should be used to perform a screen to screen BLT when a
+-// specified color should by transparent. The only supported ROP is SRCCOPY.
+-//
+-// SRCX screen X position to copy from
+-// SRCY screen Y position to copy from
+-// DSTX screen X position to copy to
+-// DSTY screen Y position to copy to
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-// COLOR transparent color
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height, unsigned short color)
+-{
+- unsigned short section, buffer_width;
+- unsigned short blit_mode = BM_READ_SRC_FB;
+- unsigned short i;
+-
+- /* CHECK Y DIRECTION */
+- /* Hardware has support for negative Y direction. */
+-
+- if (dsty > srcy)
+- {
+- blit_mode |= BM_REVERSE_Y;
+- srcy += height - 1;
+- dsty += height - 1;
+- }
+-
+- /* CHECK X DIRECTION */
+- /* Hardware does not support negative X direction since at the time */
+- /* of development all supported resolutions could fit a scanline of */
+- /* data at once into the BLT buffers (using both BB0 and BB1). This */
+- /* code is more generic to allow for any size BLT buffer. */
+-
+- if (dstx > srcx)
+- {
+- srcx += width;
+- dstx += width;
+- }
+-
+- /* CALCULATE BLT BUFFER SIZE */
+- /* Need to use BB1 to store the BLT buffer data. */
+-
+- buffer_width = GXRbufferWidthPixels;
+-
+- /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */
+-
+- if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP))
+- {
+- color &= 0x00FF;
+- color |= (color << 8);
+- }
+-
+- /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */
+- /* Need to make sure any previous BLT using BB1 is complete. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY);
+- for (i = 0; i < 16; i+=2)
+- {
+- WRITE_REG16(GXRbb1Base+i, color);
+- }
+-
+- /* DO BOGUS BLT TO LATCH DATA FROM BB1 */
+- /* Already know graphics pipeline is idle. */
+-
+- WRITE_REG32(GP_DST_XCOOR, 0);
+- WRITE_REG32(GP_SRC_XCOOR, 0);
+- WRITE_REG16(GP_WIDTH, 16);
+- WRITE_REG16(GP_HEIGHT, 1);
+- WRITE_REG16(GP_RASTER_MODE, 0x00CC);
+- WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1);
+-
+- /* WRITE REGISTERS FOR REAL SCREEN TO SCREEN BLT */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_HEIGHT, height);
+- WRITE_REG16(GP_RASTER_MODE, 0x10C6);
+- WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF);
+-
+- /* REPEAT UNTIL FINISHED WITH RECTANGLE */
+- /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */
+- /* Hardware does not split the operations, so software must do it to */
+- /* avoid large scanlines that would overflow the BLT buffers. */
+-
+- while(width > 0)
+- {
+- /* CHECK WIDTH OF CURRENT SECTION */
+-
+- if (width > buffer_width) section = buffer_width;
+- else section = width;
+-
+- /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_SRC_YCOOR, srcy);
+- WRITE_REG16(GP_DST_YCOOR, dsty);
+- WRITE_REG16(GP_WIDTH, section);
+-
+- /* CHECK X DIRECTION */
+- /* Again, this must be done in software, and can be removed if the */
+- /* display driver knows that the BLT buffers will always be large */
+- /* enough to contain an entire scanline of a screen to screen BLT. */
+-
+- if (dstx > srcx)
+- {
+- /* NEGATIVE X DIRECTION */
+- /* Still positive X direction within the section. */
+-
+- srcx -= section;
+- dstx -= section;
+- WRITE_REG16(GP_SRC_XCOOR, srcx);
+- WRITE_REG16(GP_DST_XCOOR, dstx);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+- }
+- else
+- {
+- /* POSITIVE X DIRECTION */
+-
+- WRITE_REG16(GP_SRC_XCOOR, srcx);
+- WRITE_REG16(GP_DST_XCOOR, dstx);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+- dstx += section;
+- srcx += section;
+- }
+- width -= section;
+- }
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// COLOR BITMAP TO SCREEN BLT
+-//
+-// This routine transfers color bitmap data to the screen. For most cases,
+-// when the ROP is SRCCOPY, it may be faster to write a separate routine that
+-// copies the data to the frame buffer directly. This routine should be
+-// used when the ROP requires destination data.
+-//
+-// Transparency is handled by another routine.
+-//
+-// SRCX X offset within source bitmap
+-// SRCY Y offset within source bitmap
+-// DSTX screen X position to render data
+-// DSTY screen Y position to render data
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-// *DATA pointer to bitmap data
+-// PITCH pitch of bitmap data (bytes between scanlines)
+-// ROP ternary raster operation (0x00-0xFF).
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height, unsigned char *data, unsigned short pitch,
+- unsigned char rop)
+-{
+- unsigned short section, buffer_width;
+- unsigned short blit_mode = BM_READ_SRC_BB0;
+- unsigned short line_srcx, line_dstx, line_width;
+- unsigned short offset, i;
+-
+- /* CHECK IF ROP REQUIRES DESTINATION DATA */
+- /* Even bits (0:2:4:6) do not equal corresponding odd bits (1:3:5:7). */
+-
+- if ((rop & 0x55) ^ ((rop >> 1) & 0x55))
+- blit_mode |= BM_READ_DST_FB1;
+-
+- /* CHECK SIZE OF BLT BUFFER */
+-
+- buffer_width = GXRbufferWidthPixels;
+-
+- /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+- /* Write the registers that do not change for each section. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_HEIGHT, 1);
+- WRITE_REG16(GP_RASTER_MODE, (unsigned short) rop & 0x00FF);
+-
+- /* REPEAT FOR EACH SCANLINE */
+-
+- offset = srcy * pitch;
+-
+- while(height > 0)
+- {
+- line_width = width;
+- line_srcx = srcx;
+- line_dstx = dstx;
+-
+- while(line_width > 0)
+- {
+- /* CHECK WIDTH OF CURRENT SECTION */
+-
+- if (line_width > buffer_width) section = buffer_width;
+- else section = line_width;
+-
+- /* TRANSFER SCANLINE OF BITMAP DATA TO BLT BUFFER 0 */
+- /* Need to wait for BS_PIPELINE_BUSY to make sure that the */
+- /* data in BB0 for the previous scanline is no longer used. */
+- /* This can be heavily optimized to not do a byte at a time. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY);
+- if (READ_REG16(GP_BLIT_STATUS) & BC_16BPP)
+- {
+- for (i = 0; i < section; i++)
+- {
+- WRITE_REG16(GXRbb0Base+i, data[offset+((line_srcx+i)<<1)]);
+- }
+- }
+- else
+- {
+- for (i = 0; i < section; i++)
+- {
+- WRITE_REG8(GXRbb0Base+i, data[line_srcx+offset+i]);
+- }
+- }
+-
+- /* RENDER FROM BB0 TO FRAME BUFFER */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_DST_XCOOR, line_dstx);
+- WRITE_REG16(GP_DST_YCOOR, dsty);
+- WRITE_REG16(GP_WIDTH, section);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+-
+- line_width -= section;
+- line_dstx += section;
+- line_srcx += section;
+- }
+- height--;
+- dsty++;
+- offset += pitch;
+- }
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// COLOR BITMAP TO SCREEN TRANSPARENT BLT
+-//
+-// This routine transfers color bitmap data to the screen with transparency.
+-// The transparent color is specified. The only supported ROP is SRCCOPY,
+-// meaning that transparency cannot be applied if the ROP requires
+-// destination data (this is a hardware restriction).
+-//
+-// SRCX X offset within source bitmap
+-// SRCY Y offset within source bitmap
+-// DSTX screen X position to render data
+-// DSTY screen Y position to render data
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-// *DATA pointer to bitmap data
+-// PITCH pitch of bitmap data (bytes between scanlines)
+-// COLOR transparent color
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height, unsigned char *data, unsigned short pitch,
+- unsigned short color)
+-{
+- unsigned short section, buffer_width;
+- unsigned short blit_mode = BM_READ_SRC_BB0;
+- unsigned short line_srcx, line_dstx, line_width;
+- unsigned short offset, i, first_blt = 1;
+-
+- /* CHECK SIZE OF BLT BUFFER */
+-
+- buffer_width = GXRbufferWidthPixels;
+-
+- /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+- /* Write the registers that do not change for each section. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_HEIGHT, 1);
+- WRITE_REG16(GP_RASTER_MODE, 0x10C6);
+- WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF);
+-
+- /* CALCULATE OFFSET INTO BITMAP DATA */
+-
+- offset = srcy * pitch;
+-
+- /* REPEAT FOR EACH SCANLINE */
+-
+- while(height > 0)
+- {
+- line_width = width;
+- line_srcx = srcx;
+- line_dstx = dstx;
+-
+- while(line_width > 0)
+- {
+- /* CHECK WIDTH OF CURRENT SECTION */
+-
+- if (line_width > buffer_width) section = buffer_width;
+- else section = line_width;
+-
+- /* TRANSFER SCANLINE OF BITMAP DATA TO BLT BUFFER 0 */
+- /* Need to wait for BS_PIPELINE_BUSY to make sure that the */
+- /* data in BB0 for the previous scanline is no longer used. */
+- /* This can be heavily optimized to not do a byte at a time. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY);
+- if (READ_REG16(GP_BLIT_STATUS) & BC_16BPP)
+- {
+- for (i = 0; i < section; i++)
+- {
+- WRITE_REG16(GXRbb0Base+i, data[offset+((line_srcx+i)<<1)]);
+- }
+- }
+- else
+- {
+- for (i = 0; i < section; i++)
+- {
+- WRITE_REG8(GXRbb0Base+i, data[line_srcx+offset+i]);
+- }
+- }
+-
+- /* RENDER FROM BB0 TO FRAME BUFFER */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_DST_XCOOR, line_dstx);
+- WRITE_REG16(GP_DST_YCOOR, dsty);
+- WRITE_REG16(GP_WIDTH, section);
+-
+- /* NEED TO DO EXTRA WORK FOR THE FIRST BLT */
+-
+- if (first_blt)
+- {
+- /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */
+- /* This can be heavily optimized to not do 16-bits at a time. */
+-
+- if (READ_REG16(GP_BLIT_STATUS) & BC_16BPP)
+- {
+- for (i = 0; i < section; i++)
+- {
+- WRITE_REG16(GXRbb1Base+i*2, color);
+- }
+- }
+- else
+- {
+- for (i = 0; i < section; i++)
+- {
+- WRITE_REG8(GXRbb1Base+i, (unsigned char) color);
+- }
+- }
+- WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_READ_DST_BB1);
+- first_blt = 0;
+- }
+- else
+- {
+- /* AFTER FIRST BLT, THE TRANSPARENCY DATA IS LATCHED */
+- /* Save time by not reading data from BB1. */
+-
+- WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0);
+- }
+- line_width -= section;
+- line_dstx += section;
+- line_srcx += section;
+- }
+- height--;
+- dsty++;
+- offset += pitch;
+- }
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// MONOCHROME BITMAP TO SCREEN BLT
+-//
+-// This routine transfers monochrome bitmap data to the screen.
+-//
+-// SRCX X offset within source bitmap
+-// SRCY Y offset within source bitmap
+-// DSTX screen X position to render data
+-// DSTY screen Y position to render data
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-// *DATA pointer to bitmap data
+-// PITCH pitch of bitmap data (bytes between scanlines)
+-// FGCOLOR color for bits = 1
+-// BGCOLOR color for bits = 0
+-// ROP ternary raster operation (0x00-0xFF).
+-// TRANSPARENT zero for opaque, otherwise transparent
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height, unsigned char *data, unsigned short pitch,
+- unsigned short fgcolor, unsigned short bgcolor, unsigned char rop,
+- unsigned char transparent)
+-{
+- unsigned short section, buffer_width;
+- unsigned short blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND;
+- unsigned short line_srcx, line_dstx, line_width;
+- unsigned short offset, i, bytes, raster_mode;
+-
+- /* FORMAT 8BPP COLOR */
+- /* GX requires that 8BPP color data be duplicated into bits [15:8]. */
+-
+- if (!(READ_REG16(GP_BLIT_STATUS) & BC_16BPP))
+- {
+- fgcolor &= 0x00FF;
+- fgcolor |= (fgcolor << 8);
+- bgcolor &= 0x00FF;
+- bgcolor |= (bgcolor << 8);
+- }
+-
+- /* CHECK IF ROP REQUIRES DESTINATION DATA */
+- /* Even bits (0:2:4:6) do not equal corresponding odd bits (1:3:5:7). */
+-
+- if ((rop & 0x55) ^ ((rop >> 1) & 0x55))
+- blit_mode |= BM_READ_DST_FB1;
+-
+- /* CALCULATE RASTER MODE */
+- /* Set mono flag. Transparency set based on input parameter. */
+-
+- raster_mode = ((unsigned short) rop & 0x00FF);
+- if (transparent) raster_mode |= RM_SRC_TRANSPARENT;
+-
+- /* CHECK SIZE OF BLT BUFFER */
+-
+- buffer_width = GXRbufferWidthPixels;
+-
+- /* CALCULATE OFFSET INTO BITMAP DATA */
+-
+- offset = srcy * pitch;
+-
+- /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+- /* Write the registers that do not change for each section. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_HEIGHT, 1);
+- WRITE_REG16(GP_RASTER_MODE, raster_mode);
+- WRITE_REG16(GP_SRC_COLOR_0, bgcolor);
+- WRITE_REG16(GP_SRC_COLOR_1, fgcolor);
+-
+- /* REPEAT FOR EACH SCANLINE */
+-
+- while(height > 0)
+- {
+- line_width = width;
+- line_srcx = srcx;
+- line_dstx = dstx;
+-
+- while(line_width > 0)
+- {
+- /* CHECK WIDTH OF CURRENT SECTION */
+- /* Only divide into sections if reading destination data. */
+- /* Since the source data is monochrome, it will always fit. */
+-
+- section = line_width;
+- if ((line_width > buffer_width) && (blit_mode & BM_READ_DST_FB1))
+- section = buffer_width;
+-
+- /* BYTES TO TRANSFER */
+- /* Add two bytes to handle truncating and alignment. */
+-
+- bytes = (section >> 3) + 2;
+-
+- /* TRANSFER SCANLINE OF BITMAP DATA TO BLT BUFFER 0 */
+- /* Need to wait for BS_PIPELINE_BUSY to make sure that the */
+- /* data in BB0 for the previous scanline is no longer used. */
+- /* This can be heavily optimized to not do a byte at a time. */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY);
+- for (i = 0; i < bytes; i++)
+- {
+- WRITE_REG8(GXRbb0Base+i, data[(line_srcx >> 3)+offset+i]);
+- }
+-
+- /* RENDER FROM BB0 TO FRAME BUFFER */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_DST_XCOOR, line_dstx);
+- WRITE_REG16(GP_DST_YCOOR, dsty);
+- WRITE_REG16(GP_SRC_XCOOR, line_srcx & 7);
+- WRITE_REG16(GP_WIDTH, section);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+-
+- line_width -= section;
+- line_dstx += section;
+- line_srcx += section;
+- }
+- height--;
+- dsty++;
+- offset += pitch;
+- }
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// TEXT GLYPH
+-//
+-// This routine draws a single character of text. It can only be used for
+-// characters that are less than or equal to 64x64 in size, since it
+-// transfers the entire data into the BLT buffers at once. Larger characters
+-// should use the monochrome bitmap to screen routine. The only supported
+-// ROP is SRCCOPY, again since the BLT buffer size is limited.
+-//
+-// SRCX X offset within source bitmap
+-// SRCY Y offset within source bitmap
+-// DSTX screen X position to render data
+-// DSTY screen Y position to render data
+-// WIDTH width of rectangle, in pixels
+-// HEIGHT height of rectangle, in scanlines
+-// *DATA pointer to bitmap data (NULL if already loaded)
+-// PITCH pitch of bitmap data (bytes between scanlines)
+-//
+-// For the Xfree86 display driver, the OS is given a pointer to BB0.
+-// Therefore, the data is already loaded when the driver is called, so the
+-// driver simply passes a NULL pointer to this routine.
+-//
+-// This same type of routine could be developed for "icons", or small
+-// color bitmaps that can fit entirely in the BLT buffer.
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_text_glyph(unsigned short srcx, unsigned short srcy,
+- unsigned short dstx, unsigned short dsty, unsigned short width,
+- unsigned short height, unsigned char *data, unsigned short pitch)
+-{
+- unsigned short offset, i, j, buffer_offset, bytes, blit_mode;
+-
+- blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND;
+- if (GXRusesDstData) blit_mode |= BM_READ_DST_FB1;
+-
+- /* CHECK IF DATA NEEDS TO BE TRANSFERRED */
+-
+- if (data != 0)
+- {
+- /* TRANSFER ENTIRE BITMAP DATA TO BLT BUFFER 0 */
+- /* Need to wait for BS_PIPELINE_BUSY to make sure that the */
+- /* data in BB0 for any previous BLT is no longer used. */
+- /* This data transfer has lots of room for performance optimization. */
+-
+- buffer_offset = 0;
+- offset = srcy * pitch + (srcx >> 3);
+- bytes = ((width + (srcx & 7) + 7) >> 3);
+- while(READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY);
+- for (j = 0; j < height; j++)
+- {
+- for (i = 0; i < bytes; i++)
+- {
+- WRITE_REG8(GXRbb0Base+buffer_offset, data[offset+i]);
+- buffer_offset++;
+- }
+- offset += pitch;
+- }
+- }
+-
+- /* RENDER FROM BB0 TO FRAME BUFFER */
+- /* Already know that the pipeline is idle from loading data. */
+-
+- WRITE_REG16(GP_DST_XCOOR, dstx);
+- WRITE_REG16(GP_DST_YCOOR, dsty);
+- WRITE_REG16(GP_SRC_XCOOR, srcx & 7);
+- WRITE_REG16(GP_WIDTH, width);
+- WRITE_REG16(GP_HEIGHT, height);
+- WRITE_REG16(GP_BLIT_MODE, blit_mode);
+-}
+-
+-/*
+-//----------------------------------------------------------------------------
+-// 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.
+-//
+-// X screen X position to start vector
+-// Y screen Y position to start vector
+-// LENGTH length of the vector, in pixels
+-// INITERR Bresenham initial error term
+-// AXIALERR Bresenham axial error term
+-// DIAGERR Bresenham diagonal error term
+-// FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC
+-//----------------------------------------------------------------------------
+-*/
+-
+-void gxr_bresenham_line(unsigned short x, unsigned short y,
+- unsigned short length, unsigned short initerr,
+- unsigned short axialerr, unsigned short diagerr,
+- unsigned short flags)
+-{
+- unsigned short vector_mode = flags;
+- if (GXRusesDstData) vector_mode |= VM_READ_DST_FB;
+-
+- /* CHECK NULL LENGTH */
+-
+- if (!length) return;
+-
+- /* LOAD THE REGISTERS FOR THE VECTOR */
+-
+- while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING);
+- WRITE_REG16(GP_DST_XCOOR, x);
+- WRITE_REG16(GP_DST_YCOOR, y);
+- WRITE_REG16(GP_VECTOR_LENGTH, length);
+- WRITE_REG16(GP_INIT_ERROR, initerr);
+- WRITE_REG16(GP_AXIAL_ERROR, axialerr);
+- WRITE_REG16(GP_DIAG_ERROR, diagerr);
+- WRITE_REG16(GP_VECTOR_MODE, vector_mode);
+-}
+-
+-/* END OF FILE */
+-
--- /dev/null
+--- XFree86-3.3.6/xc/config/cf/xfree86.cf.810 Tue Mar 14 23:08:19 2000
++++ XFree86-3.3.6/xc/config/cf/xfree86.cf Tue Mar 14 23:08:19 2000
+@@ -437,7 +437,7 @@ XCOMM $XConsortium: xfree86.cf /main/34
+ cirrus ncr77c22 compaq mga oak al2101 \
+ ali cl64xx video7 ark mx realtek s3_savage s3v apm \
+ s3_svga neo chips cyrix rendition p9x00 \
+- spc8110 i740 tdfx smi generic
++ spc8110 i740 tdfx i810 smi generic
+ # else
+ # define XF86SvgaDrivers nv et4000 et3000 pvga1 gvga r128 ati sis tvga8900 \
+ cirrus ncr77c22 compaq mga oak al2101 \
+--- XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/doc/Imakefile.810 Fri Dec 3 01:42:28 1999
++++ XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/doc/Imakefile Tue Mar 14 23:08:19 2000
+@@ -90,7 +90,7 @@ HWREADME = README.ati README.trident RE
+ README.I128 README.Mach32 \
+ README.Mach64 README.ark README.MGA README.NVIDIA README.mouse \
+ README.neo README.rendition README.3DLabs README.cyrix \
+- README.i740 README.r128
++ README.i740 README.r128 README.i810
+
+ MAINDOCS = COPYRIGHT README README.Config BUILD RELNOTES
+
+--- XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_memory.c.810 Thu Nov 18 11:22:48 1999
++++ XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_memory.c Wed Mar 15 10:16:12 2000
+@@ -54,343 +54,192 @@ extern vgaPCIInformation *vgaPCIInfo;
+ #include "i810.h"
+ #include "i810_reg.h"
+
+-#include <agpgart.h>
++#include <linux/agpgart.h>
+
+ /* DcachePtr will be set up, but not used.
+ */
+ I810MemRange I810DcacheMem = { 0, 0, 0 };
+ I810MemRange I810SysMem = { 0, 0, 0 };
+-I810MemRange *I810DisplayPtr = &I810SysMem;
+-
+-
+-#define gtt_None 0
+-#define gtt_Local 1
+-#define gtt_Kernel 2
+-
+-
+-/* Used in fallback GTT:
+- */
+-static int I810GttType = 0;
+-static unsigned long I810Physical = 0;
+-static unsigned long I810GttSize = 0;
+-static unsigned long I810GttPhysical = 0;
+-static unsigned long I810ScratchPageLocal = 0;
+
++unsigned long I810TopOfMem = 0;
+
+ /* Used to determine which watermarks to use:
+ */
+ int I810LmFreqSel = 0;
+
+-
+-/* Communications with the kernel module:
++/* Work out the real top of physical memory (not just what it says in
++ * /proc/meminfo). Figure out the position and size of the
++ * preallocated (stolen) video ram segment. For now, this is all the
++ * memory we will use.
+ */
+-static int gartfd;
+-static struct gart_info gartinf;
+-static struct gart_pge_info gart_pg_inf;
+-
+-static int I810AllocateGARTMemory( void )
++Bool I810CharacterizeSystemRam( pciConfigPtr pcr )
+ {
+- int size = 4 * 1024 * 1024;
+- int i, j, pages = size / 4096;
+- struct stat sb;
+-
+- /* We can only fallback if there is no agpgart module active -
+- * otherwise the fallback to system ram screws up the other gart
+- * client(s).
++ pciTagRec tag = pcibusTag(pcr->_bus, pcr->_cardnum, pcr->_func);
++ unsigned long whtcfg_pamr_drp;
++ int pages = 4 * 1024 * 1024 / 4096;
++
++ /* Communications with the kernel module:
+ */
+- if (stat("/dev/agpgart", &sb) != 0) {
+- ErrorF("%s %s: Stat failed on /dev/agpgart: %s\n",
+- XCONFIG_PROBED, vga256InfoRec.name,
+- sys_errlist[errno]);
++ int gartfd;
++ agp_info agpinf;
++ agp_bind bind;
++ agp_allocate alloc;
++
++ /* Physical page reserved for hardware curcor. It is at the top of
++ the frame buffer. */
++ int hw_cursor_page;
+
+- /* Fallback - we'll manage the GTT ourselves.
+- */
+- return -1;
+- }
++ /* Need to do read longs, because read word returns rubbish...
++ */
++ whtcfg_pamr_drp = pciReadLong( tag, WHTCFG_PAMR_DRP );
++
++ /* Need this for choosing watermarks.
++ */
++ if ((whtcfg_pamr_drp & LM_FREQ_MASK) == LM_FREQ_133)
++ I810LmFreqSel = 133;
++ else
++ I810LmFreqSel = 100;
+
+ gartfd = open("/dev/agpgart", O_RDWR);
+ if (gartfd == -1) {
+ ErrorF("%s %s: unable to open /dev/agpgart: %s\n",
+- XCONFIG_PROBED, vga256InfoRec.name,
++ XCONFIG_PROBED, vga256InfoRec.name,
+ sys_errlist[errno]);
+ FatalError("Aborting");
+ }
+
+- if (ioctl(gartfd, GARTIOCINFO, &gartinf) != 0) {
+- ErrorF("%s %s: error doing ioctl(GARTIOCINFO): %s\n",
+- XCONFIG_PROBED, vga256InfoRec.name,
++ if (ioctl(gartfd, AGPIOC_ACQUIRE) != 0) {
++ ErrorF("%s %s: error doing ioctl(AGPIOC_ACQUIRE): %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name,
+ sys_errlist[errno]);
+ FatalError("Aborting");
+ }
+
++ if (ioctl(gartfd, AGPIOC_INFO, &agpinf) != 0) {
++ ErrorF("%s %s: error doing ioctl(AGPIOC_INFO): %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name,
++ sys_errlist[errno]);
++ FatalError("Aborting");
++ }
+
+- /* Dcache - half the speed of normal ram, so not really useful for
+- * a 2d server. Don't bother reporting its presence.
+- */
+- if (gartinf.num_dcache_slots) {
+- I810DcacheMem.Start = gartinf.num_of_slots * 4096;
+- I810DcacheMem.Size = gartinf.num_dcache_slots * 4096;
+- I810DcacheMem.End = I810DcacheMem.Start + I810DcacheMem.Size;
++ if (agpinf.version.major != 0 ||
++ agpinf.version.minor != 99) {
++ ErrorF("%s %s: Agp kernel driver version not correct\n",
++ XCONFIG_PROBED, vga256InfoRec.name);
++ FatalError("Aborting");
+ }
+-
++
++ /* Reserve a page for hardware cursor. */
++ hw_cursor_page = OFLG_ISSET(OPTION_SW_CURSOR, &vga256InfoRec.options)
++ ? 0 : 1;
+
+ /* Treat the gart like video memory - we assume we own all that is
+ * there, so ignore EBUSY errors. Don't try to remove it on
+ * failure, either.
+ */
+- for (i = 0; i < pages; i++)
+- if (ioctl(gartfd, GARTIOCINSERT, &i) != 0) {
+- if (errno != EBUSY)
+- {
+- perror("gart insert");
+- ErrorF("%s %s: GART: allocation of %d pages failed at page %d\n",
+- XCONFIG_PROBED, vga256InfoRec.name, pages, i);
+- FatalError("Aborting");
+- }
+- }
++ alloc.pg_count = pages - hw_cursor_page;
++ alloc.type = 0;
+
+- ErrorF("%s %s: GART: allocated %dK system ram\n",
+- XCONFIG_PROBED, vga256InfoRec.name, pages * 4);
+-
+- I810SysMem.Start = 0;
+- I810SysMem.End = pages * 4096;
+- I810SysMem.Size = pages * 4096;
+- I810GttType = gtt_Kernel;
+-
+- vga256InfoRec.videoRam = I810SysMem.Size / 1024;
++ if (ioctl(gartfd, AGPIOC_ALLOCATE, &alloc) && errno != EBUSY) {
++ ErrorF("%s %s: GART: allocation of %d pages: %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name, alloc.pg_count,
++ sys_errlist[errno]);
++ FatalError("Aborting");
++ }
+
+- return 0;
+-}
++ bind.pg_start = I810TopOfMem / 4096;
++ bind.key = alloc.key;
++ if (ioctl(gartfd, AGPIOC_BIND, &bind) && errno != EBUSY) {
++ ErrorF("%s %s: GART: bind of %d pages: %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name, alloc.pg_count,
++ sys_errlist[errno]);
++ FatalError("Aborting");
++ }
+
++ I810SysMem.Start = I810TopOfMem;
++ I810SysMem.End = alloc.pg_count * 4096;
++ I810SysMem.Size = I810SysMem.End - I810SysMem.Start;
++ I810TopOfMem = I810SysMem.End;
+
+-static void I810SetupFallbackGTT()
+-{
+- unsigned int off, pte;
++ if (hw_cursor_page) {
++ /* Mouse cursor -- The i810 (crazy) needs a physical address in
++ * system memory from which to upload the cursor. We get this
++ * from the agpgart module using a special memory type.
++ */
++ alloc.pg_count = hw_cursor_page;
++ alloc.type = 2;
+
+- OUTREG(PGETBL_CTL, (I810GttPhysical | PGETBL_ENABLED));
++ if (ioctl(gartfd, AGPIOC_ALLOCATE, &alloc) != 0) {
++ ErrorF("%s %s: GART: allocation of %d pages for mouse: %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name, alloc.pg_count,
++ sys_errlist[errno]);
++ }
++ else {
++ bind.pg_start = I810TopOfMem / 4096;
++ bind.key = alloc.key;
++
++ if (ioctl(gartfd, AGPIOC_BIND, &bind) != 0) {
++ ErrorF("%s %s: GART: bind of %d pages for mouse: %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name, alloc.pg_count,
++ sys_errlist[errno]);
++ ioctl(gartfd, AGPIOC_DEALLOCATE, &alloc);
++ }
++ else {
++ I810CursorPhysical = alloc.physical;
++ I810CursorStart = I810TopOfMem;
+
+- /* - load GTT entries via the MMIO aperture
+- * - Use a dedicated scratch page.
+- */
+- for (off = 0, pte = 0 ;
+- pte < (I810GttSize * 1024) ;
+- off += 4096, pte += 4)
+- {
+- if (off < I810DcacheMem.End) {
+- OUTREG_(PTE_BASE + pte, off | PTE_LOCAL | PTE_VALID);
+- } else if (off < I810SysMem.End) {
+- OUTREG_(PTE_BASE + pte,
+- (I810Physical + off - I810DcacheMem.End)
+- | PTE_MAIN_UNCACHED | PTE_VALID);
+- } else {
+- OUTREG_(PTE_BASE + pte,
+- (I810Physical + I810ScratchPageLocal)
+- | PTE_MAIN_UNCACHED | PTE_VALID);
++ I810TopOfMem += alloc.pg_count * 4096;
++ }
+ }
+ }
+-}
+
+-
+-/* Work out the real top of physical memory (not just what it says in
+- * /proc/meminfo). Figure out the position and size of the
+- * preallocated (stolen) video ram segment. For now, this is all the
+- * memory we will use.
+- */
+-Bool I810CharacterizeSystemRam( pciConfigPtr pcr )
+-{
+- pciTagRec tag = pcibusTag(pcr->_bus, pcr->_cardnum, pcr->_func);
+- unsigned long mb = 0;
+- unsigned long foo;
+- unsigned long whtcfg_pamr_drp;
+- unsigned long smram_miscc;
+- int i;
+-
+- /* Need to do read longs, because read word returns rubbish...
+- */
+- whtcfg_pamr_drp = pciReadLong( tag, WHTCFG_PAMR_DRP );
+- smram_miscc = pciReadLong( tag, SMRAM_MISCC );
+-
+- /* Need this for choosing watermarks.
++ /* Dcache - half the speed of normal ram, so not really useful for
++ * a 2d server. Don't bother reporting its presence. This is
++ * mapped in addition to the requested amount of system ram.
+ */
+- if ((whtcfg_pamr_drp & LM_FREQ_MASK) == LM_FREQ_133)
+- I810LmFreqSel = 133;
+- else
+- I810LmFreqSel = 100;
+-
+-
+- if (I810AllocateGARTMemory() == 0)
+- return TRUE;
+- else if (getenv("I810_UNSUPPORTED_GTT_FALLBACK"))
+- ErrorF("%s %s: No kernel GTT support detected - trying to fall back\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- else
+- FatalError("Couldn't get memory from gart module,\n"
+- "and I810_UNSUPPORTED_GTT_FALLBACK not set.");
+-
++ alloc.pg_count = 1024;
++ alloc.type = 1;
+
+- /* Fallback is useful for debugging, or if someone is unable to
+- * compile the kernel module (eg. a 1.2.x kernel, or a non-linux
+- * operating system). However there are real drawbacks - there has
+- * been little thought given to synchronization between two X
+- * servers running on the same hardware, non-X users of the gart
+- * (eg svga, fbdev, ggi), and when direct-rendering 3d clients
+- * become available the same problems will arise there, too.
+- *
+- * Additionally, the X server is unable to allocate system memory,
+- * so must cram everything into whatever 'stolen' memory was
+- * reserved by the chipset at startup. This is sneaky - the memory
+- * isn't guarenteed to be present, and is not guarenteed to be
+- * stable, either.
+- *
+- * Thus this should never be considered anything but a stopgap
+- * measure, or tool for special circumstances where a kernel module
+- * is unavailable.
++ /* Keep it 512K aligned for the sake of tiled regions.
+ */
+- if ((smram_miscc & GFX_MEM_WIN_SIZE) == GFX_MEM_WIN_32M)
+- I810GttSize = 32;
+- else
+- I810GttSize = 64;
++ I810TopOfMem += 0x7ffff;
++ I810TopOfMem &= ~0x7ffff;
+
+- ErrorF("%s %s: GTT window size: %ld mb\n",
+- XCONFIG_PROBED, vga256InfoRec.name, I810GttSize);
+-
+- for ( i = 0 ; i < 2 ; i++ ) {
+- char drp;
+- int row = 0;
+-
+- switch (i) {
+- case 0: drp = whtcfg_pamr_drp >> SYS_DRAM_ROW_0_SHIFT; break;
+- case 1: drp = whtcfg_pamr_drp >> SYS_DRAM_ROW_1_SHIFT; break;
++ if (ioctl(gartfd, AGPIOC_ALLOCATE, &alloc) != 0) {
++ ErrorF("%s %s: GART: %d pages for DCACHE: %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name, alloc.pg_count,
++ sys_errlist[errno]);
++ }
++ else {
++ bind.pg_start = I810TopOfMem / 4096;
++ bind.key = alloc.key;
++
++ if (ioctl(gartfd, AGPIOC_BIND, &bind) != 0) {
++ ErrorF("%s %s: GART: bind of %d pages for DCACHE: %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name, alloc.pg_count,
++ sys_errlist[errno]);
++ ioctl(gartfd, AGPIOC_DEALLOCATE, &alloc);
+ }
+-
+- switch (drp & DRAM_MASK) {
+- case 0x0: row = DRAM_VALUE_0; break;
+- case 0x1: row = DRAM_VALUE_1; break;
+- /* no 0x2 value defined */
+- case 0x3: row = DRAM_VALUE_3; break;
+- case 0x4: row = DRAM_VALUE_4; break;
+- case 0x5: row = DRAM_VALUE_5; break;
+- case 0x6: row = DRAM_VALUE_6; break;
+- case 0x7: row = DRAM_VALUE_7; break;
+- case 0x8: row = DRAM_VALUE_8; break;
+- case 0x9: row = DRAM_VALUE_9; break;
+- case 0xa: row = DRAM_VALUE_A; break;
+- case 0xb: row = DRAM_VALUE_B; break;
+- case 0xc: row = DRAM_VALUE_C; break;
+- case 0xd: row = DRAM_VALUE_D; break;
+- case 0xe: row = DRAM_VALUE_E; break;
+- case 0xf: row = DRAM_VALUE_F; break;
+- default:
+- FatalError("%s %s: Unrecognized system dram row size\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- break;
++ else {
++ I810DcacheMem.Start = I810TopOfMem;
++ I810DcacheMem.Size = alloc.pg_count * 4096;
++ I810DcacheMem.End = I810DcacheMem.Start + I810DcacheMem.Size;
++ I810TopOfMem = I810DcacheMem.End;
+ }
+-
+- mb += row;
+-
+- ErrorF("%s %s: System dram row %d, size %d mb\n",
+- XCONFIG_PROBED, vga256InfoRec.name, i, row );
+- }
+-
+- ErrorF("%s %s: Installed mainboard ram: %d mb\n",
+- XCONFIG_PROBED, vga256InfoRec.name, mb);
+-
+- mb *= 1024*1024;
+-
+- /* Take into account memory reserved for TSEG, whatever that is.
+- */
+- switch (smram_miscc & USMM) {
+- case USMM_TSEG_512K: mb -= 512 * 1024; break;
+- case USMM_TSEG_1M: mb -= 1024 * 1024; break;
+- default: break;
+- }
+-
+- switch (smram_miscc & GMS) {
+- case GMS_DISABLE:
+- ErrorF("i810 is disabled\n");
+- return 0;
+- case GMS_ENABLE_BARE:
+- ErrorF("\nNo system ram reserved for i810, and no kernel GTT\n");
+- return 0;
+- case GMS_ENABLE_512K:
+- I810SysMem.End = 512 * 1024;
+- I810Physical = mb - 512 * 1024;
+- ErrorF("%s %s: Only 512k system ram available for i810\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- break;
+- case GMS_ENABLE_1M:
+- I810SysMem.End = 1024 * 1024;
+- I810Physical = mb - 1024 * 1024;
+- ErrorF("%s %s: Only 1024k system ram available for i810\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+- break;
+ }
+
+- /* Reserve space for the GTT and scratch page.
+- */
+- I810SysMem.End -= I810GttSize * 1024;
+- I810GttPhysical = I810Physical + I810SysMem.End;
+- I810SysMem.End -= 4096;
+- I810ScratchPageLocal = I810SysMem.End;
+- I810SysMem.Size = I810SysMem.End - I810SysMem.Start;
+-
+-
+- /* Breifly map IO registers to virtual address space. */
+- I810MMIOBase = xf86MapVidMem(vga256InfoRec.scrnIndex, MMIO_REGION,
+- (pointer)(I810MMIOAddr), 0x80000);
+-
+- if (!I810MMIOBase)
+- FatalError("Couldn't map MMIO region");
+-
+- /* Dcache is too slow for normal use, but it's a way to get a
+- * fullsized framebuffer in the fallback mode.
+- */
+- if ((INREG8(DRAM_ROW_TYPE) & DRAM_ROW_0) == DRAM_ROW_0_SDRAM)
+- {
+- ErrorF("%s %s: Detected 4MB dedicated video ram\n",
+- XCONFIG_PROBED, vga256InfoRec.name);
+-
+- I810DcacheMem.Start = 0;
+- I810DcacheMem.End = 4 * 1024 * 1024;
+- I810DcacheMem.Size = I810DcacheMem.End;
+- I810SysMem.Start += I810DcacheMem.Size;
+- I810SysMem.End += I810DcacheMem.Size;
+- I810DisplayPtr = &I810DcacheMem;
++ if (ioctl(gartfd, AGPIOC_RELEASE) != 0) {
++ ErrorF("%s %s: error doing ioctl(AGPIOC_RELEASE): %s\n",
++ XCONFIG_PROBED, vga256InfoRec.name,
++ sys_errlist[errno]);
+ }
+
+- vga256InfoRec.videoRam = (I810SysMem.End - I810DcacheMem.Start) / 1024;
+- I810GttType = gtt_Local;
++ ErrorF("%s %s: GART: allocated %dK system ram\n",
++ XCONFIG_PROBED, vga256InfoRec.name, pages * 4);
+
+- I810SetupFallbackGTT();
++ vga256InfoRec.videoRam = (pages * 4096) / 1024;
+
+- /* Unmap them again. */
+- xf86UnMapVidMem(vga256InfoRec.scrnIndex, MMIO_REGION,
+- (pointer)(I810MMIOAddr), 0x80000);
+ return TRUE;
+-}
+-
+-
+-unsigned long I810LocalToPhysical( unsigned long local )
+-{
+- switch (I810GttType) {
+- case gtt_Local:
+- if (I810DisplayPtr == &I810SysMem)
+- return I810Physical + local;
+- else
+- return I810Physical + local - 4 * 1024 * 1024;
+- break;
+- case gtt_Kernel:
+- gart_pg_inf.index = (local + 4095) / 4096;
+- if (ioctl(gartfd, GARTIOCPGINFO, &gart_pg_inf) != 0) {
+- ErrorF("%s %s: error doing ioctl(GARTIOCINFO, %x): %s\n",
+- XCONFIG_PROBED, vga256InfoRec.name, gart_pg_inf.index,
+- sys_errlist[errno]);
+- return 0;
+- }
+- return gart_pg_inf.physical + (local & 4095);
+- default:
+- return 0;
+- }
+ }
+
+ int I810AllocLow( I810MemRange *result, I810MemRange *pool, int size )
+--- XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_driver.c.810 Thu Nov 18 11:22:48 1999
++++ XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_driver.c Wed Mar 15 08:36:05 2000
+@@ -126,6 +126,7 @@ int I810LinearAddr = 0;
+ int I810MMIOAddr = 0;
+
+ unsigned long I810CursorPhysical = 0;
++unsigned long I810CursorStart = 0;
+ int I810CursorOffset = 0;
+
+ I810RingBuffer I810LpRing;
+@@ -196,13 +197,13 @@ vgaVideoChipRec I810 = {
+ (void (*)())NoopDDA, /* I810SetWrite, */
+ (void (*)())NoopDDA, /* I810SetReadWrite, */
+
+- 0x10000, /* banked mode stuff */
+- 0x10000, /* */
+- 16, /* */
+- 0xFFFF, /* */
+- 0x00000, 0x10000, /* */
+- 0x00000, 0x10000, /* */
+- FALSE, /* banked mode stuff */
++ 0x10000, /* ChipMapSize */
++ 0x10000, /* ChipSegmentSize */
++ 16, /* ChipSegmentShift */
++ 0xFFFF, /* ChipSegmentMask */
++ 0x00000, 0x10000, /* ChipReadBottom, ChipReadTop */
++ 0x00000, 0x10000, /* ChipUse2Banks, ChipWriteTop */
++ FALSE, /* ChipUse2Banks */
+ VGA_NO_DIVIDE_VERT,
+ {0,},
+ 8, /* scanline padding - replace pitchadjust? */
+@@ -1304,7 +1305,7 @@ I810FbInit()
+ /* Allocate the framebuffer.
+ */
+ if (!I810AllocLow( &I810FrameBuffer,
+- I810DisplayPtr,
++ &I810SysMem,
+ (vga256InfoRec.virtualY *
+ vga256InfoRec.displayWidth *
+ vgaBytesPerPixel) ))
+@@ -1318,26 +1319,15 @@ I810FbInit()
+
+ if (!OFLG_ISSET(OPTION_SW_CURSOR, &vga256InfoRec.options))
+ {
+- if (!I810AllocHigh( &I810Cursor, &I810SysMem, 4096 )) {
+- ErrorF("%s %s: %s: Warning: "
+- "Cannot allocate memory in framebuffer for cursor image\n",
+- (OFLG_ISSET(OPTION_HW_CURSOR, &vga256InfoRec.options) ?
+- XCONFIG_GIVEN : XCONFIG_PROBED),
+- vga256InfoRec.name,
+- vga256InfoRec.chipset);
+- }
+- else {
+- /* Translate to a physical system memory address - this is the
+- * only thing for which the hardware will not use the GTT...
+- */
+- I810CursorPhysical = I810LocalToPhysical( I810Cursor.Start );
+-
+- if (I810_DEBUG & DEBUG_VERBOSE_MEMORY)
+- fprintf(stderr, "cursor local %x phys %x\n",
+- I810Cursor.Start, I810CursorPhysical);
+-
+- if (I810CursorPhysical)
+- I810CursorInit();
++ if (I810_DEBUG & DEBUG_VERBOSE_MEMORY)
++ fprintf(stderr, "cursor local %x phys %x\n",
++ I810CursorStart, I810CursorPhysical);
++
++ if (I810CursorPhysical) {
++ I810Cursor.Start = I810CursorStart;
++ I810Cursor.Size = 4096;
++ I810Cursor.End = I810Cursor.Start + I810Cursor.Size;
++ I810CursorInit();
+ }
+ }
+
+--- XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810.h.810 Thu Nov 18 11:22:47 1999
++++ XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810.h Tue Mar 14 23:08:19 2000
+@@ -47,6 +47,7 @@ extern Bool I810CharacterizeSy
+ /* Globals */
+ extern unsigned char *I810MMIOBase;
+ extern unsigned long I810CursorPhysical;
++extern unsigned long I810CursorStart;
+ extern int I810CursorOffset;
+ extern int I810Chipset;
+
+@@ -61,8 +62,6 @@ typedef struct {
+
+ extern int I810AllocHigh( I810MemRange *result, I810MemRange *pool, int size );
+ extern int I810AllocLow( I810MemRange *result, I810MemRange *pool, int size );
+-extern unsigned long I810LocalToPhysical( unsigned long local );
+-
+ /*
+ */
+ typedef struct {
+@@ -80,7 +79,7 @@ extern I810RingBuffer I810LpRing;
+ extern int I810FrameBufferLocked;
+ extern int I810LmFreqSel;
+
+-extern I810MemRange I810SysMem, I810DcacheMem, *I810DisplayPtr;
++extern I810MemRange I810SysMem, I810DcacheMem;
+ extern I810MemRange I810Mprotect;
+ extern I810MemRange I810Cursor;
+
+--- XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_wmark.c.810 Thu Nov 18 11:22:48 1999
++++ XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_wmark.c Tue Mar 14 23:08:19 2000
+@@ -320,19 +320,5 @@ unsigned int I810CalcWatermark( double f
+ ErrorF("%s %s: chose watermark 0x%x: (tab.freq %.1f)\n",
+ XCONFIG_PROBED, vga256InfoRec.name, tab[i].wm, tab[i].freq);
+
+- /* None of these values (sourced from intel) have watermarks for
+- * the dcache memory. Fake it for now by using the same watermark
+- * for both...
+- *
+- * Update: this is probably because dcache isn't real useful as
+- * framebuffer memory, so intel's drivers don't need watermarks
+- * for that memory because they never use it to feed the ramdacs.
+- * We do use it in the fallback mode, so keep the watermarks for
+- * now.
+- */
+- if (I810DisplayPtr == &I810DcacheMem)
+- return (tab[i].wm & ~0xffffff) | ((tab[i].wm>>12) & 0xfff);
+- else
+- return tab[i].wm;
++ return tab[i].wm;
+ }
+-
+--- XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_accel.c.810 Thu Nov 18 11:22:48 1999
++++ XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/vga256/drivers/i810/i810_accel.c Tue Mar 14 23:08:19 2000
+@@ -257,7 +257,7 @@ I810AccelInit()
+ if (pix_cache.Size > I810SysMem.Size)
+ pix_cache.Size = I810SysMem.Size;
+
+- if (I810AllocLow( &pix_cache, I810DisplayPtr, pix_cache.Size ))
++ if (I810AllocLow( &pix_cache, &I810SysMem, pix_cache.Size ))
+ {
+ xf86AccelInfoRec.PixmapCacheMemoryStart = pix_cache.Start;
+ xf86AccelInfoRec.PixmapCacheMemoryEnd = pix_cache.End;
+--- XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/xf86config/Cards.810 Tue Mar 14 23:08:19 2000
++++ XFree86-3.3.6/xc/programs/Xserver/hw/xfree86/xf86config/Cards Tue Mar 14 23:08:19 2000
+@@ -3093,6 +3093,11 @@ SEE Intel 740 (generic)
+ NAME Winfast S900 i740 AGP 8MB
+ SEE Intel 740 (generic)
+
++NAME Intel 810
++CHIPSET Intel 810
++SERVER SVGA
++NOCLOCKPROBE
++
+ NAME Voodoo Banshee (generic)
+ CHIPSET Voodoo Banshee
+ SERVER SVGA
--- /dev/null
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/accel/mach64/ativga.c devel/xc/programs/Xserver/hw/xfree86/accel/mach64/ativga.c
+*** base/xc/programs/Xserver/hw/xfree86/accel/mach64/ativga.c Wed Feb 9 20:05:48 2000
+--- devel/xc/programs/Xserver/hw/xfree86/accel/mach64/ativga.c Fri Feb 4 09:13:42 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/ativga.c,v 3.7.2.1 1998/10/18 20:42:04 hohndel Exp $ */
+ /***************************************************************************
+ * Start of VGA font saving and restoration code.
+ * Created: Sun Jun 27 12:50:09 1993 by faith@cs.unc.edu
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/ativga.c,v 3.7.2.1tsi Exp $ */
+ /***************************************************************************
+ * Start of VGA font saving and restoration code.
+ * Created: Sun Jun 27 12:50:09 1993 by faith@cs.unc.edu
+***************
+*** 55,60 ****
+--- 55,61 ----
+
+ typedef struct {
+ vgaHWRec std;
++ unsigned char shadow_crtc[25];
+ unsigned char ATIExtRegBank[11]; /* ATI Registers B0,B1,B2,B3,
+ B5, B6,B8,B9, BE,A6,A7 */
+ } SaveBlock;
+***************
+*** 104,111 ****
+--- 105,114 ----
+ void mach64SaveVGAInfo(screen_idx)
+ int screen_idx;
+ {
++ unsigned long saved_lcd_gen_ctrl = 0, lcd_gen_ctrl = 0;
+ unsigned char b2_save;
+ unsigned char b8_save;
++ int i;
+
+ if (!vgaBase) {
+ vgaBase = xf86MapVidMem(screen_idx, VGA_REGION, (pointer)0xa0000,
+***************
+*** 114,123 ****
+
+ vgaIOBase = (inb(0x3cc) & 0x01) ? 0x3D0 : 0x3B0;
+
+- /* This part is copied from ATISave() in
+- * xf86/vga256/drivers/ati/driver.c
+- */
+-
+ if (!mach64IntegratedController) {
+ /* Unlock ATI specials */
+ outw(ATIExtReg, (((b8_save = inATI(0xb8)) & 0xC0) << 8) | 0xb8);
+--- 117,122 ----
+***************
+*** 126,132 ****
+--- 125,172 ----
+ outw(ATIExtReg, 0x00b2); /* segment select 0 */
+ }
+
++ if (mach64LCDPanelID >= 0) {
++ if (mach64ChipType == MACH64_LG_ID) {
++ saved_lcd_gen_ctrl = regr(LCD_GEN_CTRL);
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ regw(LCD_GEN_CTRL, lcd_gen_ctrl);
++ } else {
++ outb(ioLCD_INDEX, LCD_GEN_CNTL);
++ saved_lcd_gen_ctrl = inl(ioLCD_DATA);
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ outl(ioLCD_DATA, lcd_gen_ctrl);
++ }
++ }
++
+ vgaNewVideoState = vgaHWSave(vgaNewVideoState, sizeof(SaveBlock));
++ /* Unlock VGA CRTC */
++ outw(vgaIOBase + 4, ((save->std.CRTC[17] & 0x7F) << 8) | 17);
++
++ if (mach64LCDPanelID >= 0) {
++ lcd_gen_ctrl |= SHADOW_EN | SHADOW_RW_EN;
++ if (mach64ChipType == MACH64_LG_ID) {
++ regw(LCD_GEN_CTRL, lcd_gen_ctrl);
++ } else {
++ outb(ioLCD_INDEX, LCD_GEN_CNTL);
++ outl(ioLCD_DATA, lcd_gen_ctrl);
++ }
++
++ for (i=0; i<25; i++) {
++ outb(vgaIOBase + 4, i);
++ save->shadow_crtc[i] = inb(vgaIOBase + 5);
++ }
++ /* Unlock shadow VGA CRTC */
++ outw(vgaIOBase + 4, ((save->shadow_crtc[17] & 0x7F) << 8) | 17);
++
++ if (mach64ChipType == MACH64_LG_ID) {
++ regw(LCD_GEN_CTRL, saved_lcd_gen_ctrl);
++ } else {
++ outb(ioLCD_INDEX, LCD_GEN_CNTL);
++ outl(ioLCD_DATA, saved_lcd_gen_ctrl);
++ }
++ }
+
+ if (!mach64IntegratedController) {
+ save->ATIReg0 = inATI(0xb0);
+***************
+*** 155,163 ****
+
+ void mach64RestoreVGAInfo()
+ {
+! /* This routine is mostly from ATIRestore() in
+! * xf86/vga256/drivers/ati/driver.c
+! */
+
+ if (!mach64IntegratedController) {
+ /* Unlock ATI specials */
+--- 195,202 ----
+
+ void mach64RestoreVGAInfo()
+ {
+! unsigned long saved_lcd_gen_ctrl = 0, lcd_gen_ctrl = 0;
+! int i;
+
+ if (!mach64IntegratedController) {
+ /* Unlock ATI specials */
+***************
+*** 182,191 ****
+--- 221,265 ----
+ outw(ATIExtReg, (save->ATIReg8 << 8) | 0xb8);
+ }
+
++ if (mach64LCDPanelID >= 0) {
++ if (mach64ChipType == MACH64_LG_ID) {
++ saved_lcd_gen_ctrl = regr(LCD_GEN_CTRL);
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ regw(LCD_GEN_CTRL, lcd_gen_ctrl);
++ } else {
++ outb(ioLCD_INDEX, LCD_GEN_CNTL);
++ saved_lcd_gen_ctrl = inl(ioLCD_DATA);
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ outl(ioLCD_DATA, lcd_gen_ctrl);
++ }
++ }
++
+ /*
+ * Restore the generic vga registers
+ */
+ vgaHWRestore((vgaHWPtr)save);
++
++ if (mach64LCDPanelID >= 0) {
++ lcd_gen_ctrl |= SHADOW_EN | SHADOW_RW_EN;
++ if (mach64ChipType == MACH64_LG_ID) {
++ regw(LCD_GEN_CTRL, lcd_gen_ctrl);
++ } else {
++ outb(ioLCD_INDEX, LCD_GEN_CNTL);
++ outl(ioLCD_DATA, lcd_gen_ctrl);
++ }
++
++ outw(vgaIOBase + 4, ((save->shadow_crtc[17] & 0x7F) << 8) | 17);
++ for (i=0; i<25; i++) outw(vgaIOBase + 4, (save->shadow_crtc[i] << 8) | i);
++
++ if (mach64ChipType == MACH64_LG_ID) {
++ regw(LCD_GEN_CTRL, saved_lcd_gen_ctrl);
++ } else {
++ outb(ioLCD_INDEX, LCD_GEN_CNTL);
++ outl(ioLCD_DATA, saved_lcd_gen_ctrl);
++ }
++ }
+ }
+
+ /*
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.c devel/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.c
+*** base/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.c Wed Feb 9 20:05:49 2000
+--- devel/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.c Mon Feb 14 09:27:30 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.c,v 3.62.2.20 1999/10/12 17:18:42 hohndel Exp $ */
+ /*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ * Copyright 1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.c,v 3.62.2.20tsi Exp $ */
+ /*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ * Copyright 1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
+***************
+*** 417,422 ****
+--- 417,423 ----
+ int mach64MemClk;
+ int mach64DRAMMemClk;
+ int mach64VRAMMemClk;
++ int mach64XCLK;
+ int mach64MemCycle;
+ Bool mach64IntegratedController;
+ Bool mach64HasDSP;
+***************
+*** 1540,1545 ****
+--- 1541,1565 ----
+ mach64CXClk = 7; /* Use IBM RGB514 PLL */
+ else
+ mach64CXClk = info->CXClk;
++ if (mach64HasDSP) {
++ /* Calculate XCLK */
++ outb(ioCLOCK_CNTL + 1, MCLK_FB_DIV << 2);
++ mach64XCLK =
++ inb(ioCLOCK_CNTL + 2) * 4 * mach64RefFreq / mach64RefDivider;
++ outb(ioCLOCK_CNTL + 1, PLL_XCLK_CNTL << 2);
++ i = inb(ioCLOCK_CNTL + 2);
++ if (!(i & MFB_TIMES_4_2))
++ mach64XCLK >>= 1;
++ i = i & XCLK_SRC_SEL;
++ switch (i) {
++ case 0: break;
++ case 1: case 2: case 3: mach64XCLK >>= i; break;
++ case 4: mach64XCLK /= 3; break;
++ default:
++ ErrorF("Unsupported XCLK source: %d!\n", i);
++ return FALSE;
++ }
++ }
+
+ #ifdef DEBUG
+ ErrorF("MinFreq = %d, MaxFreq = %d, RefFreq = %d, RefDivider = %d\n",
+***************
+*** 1561,1567 ****
+
+ mach64LCDHorizontal = info->LCDHorizontal;
+ mach64LCDVertical = info->LCDVertical;
+! mach64LCDClock = mach64GetCTClock(0);
+ ErrorF("%s %s: %dx%d panel (ID %d) detected; clock %.2f MHz\n",
+ XCONFIG_PROBED, mach64InfoRec.name,
+ mach64LCDHorizontal, mach64LCDVertical, mach64LCDPanelID,
+--- 1581,1587 ----
+
+ mach64LCDHorizontal = info->LCDHorizontal;
+ mach64LCDVertical = info->LCDVertical;
+! mach64LCDClock = mach64GetCTClock((inb(0x3cc) >> 2) & 3);
+ ErrorF("%s %s: %dx%d panel (ID %d) detected; clock %.2f MHz\n",
+ XCONFIG_PROBED, mach64InfoRec.name,
+ mach64LCDHorizontal, mach64LCDVertical, mach64LCDPanelID,
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.h devel/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.h
+*** base/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.h Wed Feb 9 20:05:49 2000
+--- devel/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.h Mon Feb 14 08:52:16 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.h,v 3.14.2.6 1999/07/23 13:22:36 hohndel Exp $ */
+ /*
+ * Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
+ *
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.h,v 3.14.2.6tsi Exp $ */
+ /*
+ * Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
+ *
+***************
+*** 29,35 ****
+ #ifndef MACH64_H
+ #define MACH64_H
+
+! #define MACH64_PATCHLEVEL "0"
+
+ #define MACH64_CURSBYTES 1024
+ #define MACH64_CURSMAX 64
+--- 29,35 ----
+ #ifndef MACH64_H
+ #define MACH64_H
+
+! #define MACH64_PATCHLEVEL "1"
+
+ #define MACH64_CURSBYTES 1024
+ #define MACH64_CURSMAX 64
+***************
+*** 85,90 ****
+--- 85,91 ----
+ extern int mach64MemClk;
+ extern int mach64DRAMMemClk;
+ extern int mach64VRAMMemClk;
++ extern int mach64XCLK;
+ extern int mach64MemCycle;
+
+ extern int mach64LCDPanelID;
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64init.c devel/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64init.c
+*** base/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64init.c Wed Feb 9 20:05:53 2000
+--- devel/xc/programs/Xserver/hw/xfree86/accel/mach64/mach64init.c Mon Feb 14 09:25:05 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64init.c,v 3.24.2.11 1999/10/12 17:18:43 hohndel Exp $ */
+ /*
+ * Written by Jake Richter
+ * Copyright (c) 1989, 1990 Panacea Inc., Londonderry, NH - All Rights Reserved
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64init.c,v 3.24.2.11tsi Exp $ */
+ /*
+ * Written by Jake Richter
+ * Copyright (c) 1989, 1990 Panacea Inc., Londonderry, NH - All Rights Reserved
+***************
+*** 1120,1126 ****
+ default: bpp = 4; break;
+ }
+
+! x = ((double)mach64VRAMMemClk * 64.0) / (current_dot_clock * (double)bpp);
+ if (mach64LCDPanelID >= 0) /* Compensate for horizontal stretching */
+ x *= (double)mach64LCDHorizontal / (double)current_hdisplay;
+ bx = ceil(log(floor(x))/log(2));
+--- 1120,1126 ----
+ default: bpp = 4; break;
+ }
+
+! x = ((double)mach64XCLK * 64.0) / (current_dot_clock * (double)bpp);
+ if (mach64LCDPanelID >= 0) /* Compensate for horizontal stretching */
+ x *= (double)mach64LCDHorizontal / (double)current_hdisplay;
+ bx = ceil(log(floor(x))/log(2));
+***************
+*** 1275,1281 ****
+ ErrorF("dsp_on = %d, ron = %d, rloop = %d\n", dsp_on, ron, rloop);
+ ErrorF("dsp_off = %d, roff = %d\n", dsp_off, roff);
+ ErrorF("dsp_xclks_per_qw = %d\n", dsp_xclks_per_qw);
+! ErrorF("mach64VRAMMemClk = %d, ", mach64VRAMMemClk);
+ ErrorF("dot_clock = %.3lf, ", current_dot_clock);
+ ErrorF("bpp = %d\n", bpp);
+ ErrorF("trp = %d, ", trp);
+--- 1275,1281 ----
+ ErrorF("dsp_on = %d, ron = %d, rloop = %d\n", dsp_on, ron, rloop);
+ ErrorF("dsp_off = %d, roff = %d\n", dsp_off, roff);
+ ErrorF("dsp_xclks_per_qw = %d\n", dsp_xclks_per_qw);
+! ErrorF("mach64XCLK = %d, ", mach64XCLK);
+ ErrorF("dot_clock = %.3lf, ", current_dot_clock);
+ ErrorF("bpp = %d\n", bpp);
+ ErrorF("trp = %d, ", trp);
+***************
+*** 2899,2906 ****
+ outl(ioLCD_DATA, old_POWER_MANAGEMENT);
+ if ((mach64ChipType != MACH64_LB_ID) &&
+ (mach64ChipType != MACH64_LD_ID) &&
+! (mach64ChipType != MACH64_LR_ID) &&
+! (mach64ChipType != MACH64_LS_ID)) {
+ outb(ioLCD_INDEX, LCD_POWER_MANAGEMENT_2);
+ outl(ioLCD_DATA, old_POWER_MANAGEMENT_2);
+ }
+--- 2899,2906 ----
+ outl(ioLCD_DATA, old_POWER_MANAGEMENT);
+ if ((mach64ChipType != MACH64_LB_ID) &&
+ (mach64ChipType != MACH64_LD_ID) &&
+! (mach64ChipType != MACH64_LI_ID) &&
+! (mach64ChipType != MACH64_LP_ID)) {
+ outb(ioLCD_INDEX, LCD_POWER_MANAGEMENT_2);
+ outl(ioLCD_DATA, old_POWER_MANAGEMENT_2);
+ }
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/accel/mach64/regmach64.h devel/xc/programs/Xserver/hw/xfree86/accel/mach64/regmach64.h
+*** base/xc/programs/Xserver/hw/xfree86/accel/mach64/regmach64.h Wed Feb 9 20:05:54 2000
+--- devel/xc/programs/Xserver/hw/xfree86/accel/mach64/regmach64.h Mon Feb 14 09:16:35 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/regmach64.h,v 3.15.2.8 1999/10/12 17:18:44 hohndel Exp $ */
+ /*
+ * Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
+ *
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/regmach64.h,v 3.15.2.8tsi Exp $ */
+ /*
+ * Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
+ *
+***************
+*** 353,358 ****
+--- 353,360 ----
+ #define VCLK1_POST 0x0C
+ #define VCLK2_POST 0x30
+ #define VCLK3_POST 0xC0
++ #define XCLK_SRC_SEL 0x07
++ #define MFB_TIMES_4_2 0x08
+
+ /* LCD_INDEX register mapping */
+ #define LCD_REG_INDEX 0x0000000f
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticlock.c devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticlock.c
+*** base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticlock.c Wed Feb 9 20:09:29 2000
+--- devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticlock.c Wed Feb 2 09:56:02 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticlock.c,v 1.1.2.3 1999/10/12 17:18:52 hohndel Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticlock.c,v 1.1.2.3tsi Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+***************
+*** 534,539 ****
+--- 534,544 ----
+ for (; Clock_Line[++Clock_Chip_Index]; )
+ {
+ int Maximum_Gap = 0, Clock_Count = 0, Clock_Index = 0;
++
++ /* Only Mach64's and Rage128's can have programmable clocks */
++ if ((Clock_Chip_Index >= ATI_CLOCK_MACH64A) &&
++ (ATIAdapter < ATI_ADAPTER_MACH64))
++ break;
+
+ for (; Clock_Index < Number_Of_Clocks; Clock_Index++)
+ {
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticonsole.c devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticonsole.c
+*** base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticonsole.c Wed Feb 9 20:09:29 2000
+--- devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticonsole.c Wed Feb 2 19:20:42 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticonsole.c,v 1.1.2.2 1999/10/12 17:18:52 hohndel Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/aticonsole.c,v 1.1.2.2tsi Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+***************
+*** 54,60 ****
+ saved_crtc_int_cntl, saved_lcd_index;
+
+ static Bool entered = LEAVE;
+! CARD32 tmp;
+
+ # ifdef XFreeXDGA
+ if ((enter == LEAVE) && !ATIUsing1bppModes &&
+--- 54,60 ----
+ saved_crtc_int_cntl, saved_lcd_index;
+
+ static Bool entered = LEAVE;
+! CARD32 tmp, lcd_gen_ctrl = 0, saved_lcd_gen_ctrl = 0;
+
+ # ifdef XFreeXDGA
+ if ((enter == LEAVE) && !ATIUsing1bppModes &&
+***************
+*** 139,149 ****
+ outl(ATIIOPortCRTC_GEN_CNTL, tmp | CRTC_EN);
+ outl(ATIIOPortCRTC_GEN_CNTL, tmp);
+ outl(ATIIOPortCRTC_GEN_CNTL, tmp | CRTC_EN);
+! if (ATIChip >= ATI_CHIP_264XL)
+ {
+ saved_lcd_index = inl(ATIIOPortLCD_INDEX);
+! outl(ATIIOPortLCD_INDEX,
+! saved_lcd_index & ~(LCD_MONDET_INT_EN | LCD_MONDET_INT));
+ }
+
+ /* Ensure VGA aperture is enabled */
+--- 139,150 ----
+ outl(ATIIOPortCRTC_GEN_CNTL, tmp | CRTC_EN);
+ outl(ATIIOPortCRTC_GEN_CNTL, tmp);
+ outl(ATIIOPortCRTC_GEN_CNTL, tmp | CRTC_EN);
+! if (ATILCDPanelID >= 0)
+ {
+ saved_lcd_index = inl(ATIIOPortLCD_INDEX);
+! if (ATIChip >= ATI_CHIP_264XL)
+! outl(ATIIOPortLCD_INDEX, saved_lcd_index &
+! ~(LCD_MONDET_INT_EN | LCD_MONDET_INT));
+ }
+
+ /* Ensure VGA aperture is enabled */
+***************
+*** 191,196 ****
+--- 192,222 ----
+ }
+ }
+
++ if (ATILCDPanelID >= 0)
++ {
++ if (ATIChip == ATI_CHIP_264LT)
++ {
++ saved_lcd_gen_ctrl = inl(ATIIOPortLCD_GEN_CTRL);
++
++ /* Setup to unlock non-shadow registers */
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ outl(ATIIOPortLCD_GEN_CTRL, lcd_gen_ctrl);
++ }
++ else /* if ((ATIChip == ATI_CHIP_264LTPRO) ||
++ (ATIChip == ATI_CHIP_264XL) ||
++ (ATIChip == ATI_CHIP_MOBILITY)) */
++ {
++ saved_lcd_gen_ctrl = ATIGetLTProLCDReg(LCD_GEN_CNTL);
++
++ /* Setup to unlock shadow registers */
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
++ }
++ }
++
++ UnlockShadowVGA:
+ ATISetVGAIOBase(inb(R_GENMO));
+
+ /*
+***************
+*** 241,258 ****
+--- 267,371 ----
+ VSyncEnd = VBlankEnd - 1;
+ PutReg(CRTX(vgaIOBase), 0x11U, (VSyncEnd & 0x0FU) | 0x20U);
+ }
++
++ if (ATILCDPanelID >= 0)
++ {
++ Bool DoShadow = TRUE;
++
++ lcd_gen_ctrl ^= (SHADOW_EN | SHADOW_RW_EN);
++ if (!(lcd_gen_ctrl & (SHADOW_EN | SHADOW_RW_EN)))
++ {
++ DoShadow = FALSE;
++ lcd_gen_ctrl = saved_lcd_gen_ctrl;
++ }
++
++ /*
++ * Setup to unlock shadow registers or restore previous
++ * selection.
++ */
++ if (ATIChip == ATI_CHIP_264LT)
++ outl(ATIIOPortLCD_GEN_CTRL, lcd_gen_ctrl);
++ else /* if ((ATIChip == ATI_CHIP_264LTPRO) ||
++ (ATIChip == ATI_CHIP_264XL) ||
++ (ATIChip == ATI_CHIP_MOBILITY)) */
++ {
++ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
++
++ /* Restore LCD index */
++ outb(ATIIOPortLCD_INDEX, GetByte(saved_lcd_index, 0));
++ }
++
++ if (DoShadow)
++ goto UnlockShadowVGA; /* Unlock shadow registers */
++ }
+ }
+ }
+ else
+ {
+ if (ATIVGAAdapter != ATI_ADAPTER_NONE)
+ {
++ if (ATILCDPanelID >= 0)
++ {
++ if (ATIChip == ATI_CHIP_264LT)
++ {
++ saved_lcd_gen_ctrl = inl(ATIIOPortLCD_GEN_CTRL);
++
++ /* Setup to lock non-shadow registers */
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ outl(ATIIOPortLCD_GEN_CTRL, lcd_gen_ctrl);
++ }
++ else /* if ((ATIChip == ATI_CHIP_264LTPRO) ||
++ (ATIChip == ATI_CHIP_264XL) ||
++ (ATIChip == ATI_CHIP_MOBILITY)) */
++ {
++ saved_lcd_gen_ctrl = ATIGetLTProLCDReg(LCD_GEN_CNTL);
++
++ /* Setup to lock shadow registers */
++ lcd_gen_ctrl = saved_lcd_gen_ctrl &
++ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN);
++ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
++ }
++ }
++
++ LockShadowVGA:
+ ATISetVGAIOBase(inb(R_GENMO));
+
+ /* Protect CRTC[0-7] */
+ tmp = GetReg(CRTX(vgaIOBase), 0x11U);
+ outb(CRTD(vgaIOBase), tmp | 0x80U);
+
++ if (ATILCDPanelID >= 0)
++ {
++ Bool DoShadow = TRUE;
++
++ lcd_gen_ctrl ^= (SHADOW_EN | SHADOW_RW_EN);
++ if (!(lcd_gen_ctrl & (SHADOW_EN | SHADOW_RW_EN)))
++ {
++ DoShadow = FALSE;
++ lcd_gen_ctrl = saved_lcd_gen_ctrl;
++ }
++
++ /*
++ * Setup to lock shadow registers or restore previous
++ * selection.
++ */
++ if (ATIChip == ATI_CHIP_264LT)
++ outl(ATIIOPortLCD_GEN_CTRL, lcd_gen_ctrl);
++ else /* if ((ATIChip == ATI_CHIP_264LTPRO) ||
++ (ATIChip == ATI_CHIP_264XL) ||
++ (ATIChip == ATI_CHIP_MOBILITY)) */
++ {
++ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
++
++ /* Restore LCD index */
++ outb(ATIIOPortLCD_INDEX, GetByte(saved_lcd_index, 0));
++ }
++
++ if (DoShadow)
++ goto LockShadowVGA; /* Lock shadow registers */
++ }
++
+ if (ATIChipHasVGAWonder)
+ {
+ /*
+***************
+*** 315,321 ****
+ outl(ATIIOPortDAC_CNTL, saved_dac_cntl);
+ if (ATIChip < ATI_CHIP_264CT)
+ outl(ATIIOPortMEM_INFO, saved_mem_info);
+! else if (ATIChip >= ATI_CHIP_264XL)
+ outl(ATIIOPortLCD_INDEX, saved_lcd_index);
+ }
+
+--- 428,434 ----
+ outl(ATIIOPortDAC_CNTL, saved_dac_cntl);
+ if (ATIChip < ATI_CHIP_264CT)
+ outl(ATIIOPortMEM_INFO, saved_mem_info);
+! else if (ATILCDPanelID >= 0)
+ outl(ATIIOPortLCD_INDEX, saved_lcd_index);
+ }
+
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/atiprobe.c devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/atiprobe.c
+*** base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/atiprobe.c Wed Feb 9 20:09:32 2000
+--- devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/atiprobe.c Tue Feb 1 10:27:18 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/atiprobe.c,v 1.1.2.8 1999/10/13 14:32:32 hohndel Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/atiprobe.c,v 1.1.2.8tsi Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+***************
+*** 1184,1200 ****
+ ATILCDHorizontal = BIOSWord(LCDPanelInfo + 0x19U);
+ ATILCDVertical = BIOSWord(LCDPanelInfo + 0x1BU);
+
+! /* Assume clock 0 */
+! ATILCDClock = 2 * ATIGetMach64PLLReg(PLL_VCLK0_FB_DIV);
+ ATILCDClock *= ATIReferenceNumerator;
+ ATILCDClock /= ATIClockDescriptor->MinM;
+ ATILCDClock /= ATIReferenceDenominator;
+! Index =
+! GetBits(ATIGetMach64PLLReg(PLL_XCLK_CNTL), PLL_VCLK0_XDIV);
+! Index *= MaxBits(PLL_VCLK0_POST_DIV) + 1;
+! Index |= GetBits(ATIGetMach64PLLReg(PLL_VCLK_POST_DIV),
+! PLL_VCLK0_POST_DIV);
+! ATILCDClock /= ATIClockDescriptor->PostDividers[Index];
+ }
+ }
+
+--- 1184,1202 ----
+ ATILCDHorizontal = BIOSWord(LCDPanelInfo + 0x19U);
+ ATILCDVertical = BIOSWord(LCDPanelInfo + 0x1BU);
+
+! /* Compute panel clock */
+! Index = GetBits(inb(R_GENMO), 0x0C);
+! ATILCDClock = 2 * ATIGetMach64PLLReg(PLL_VCLK0_FB_DIV + Index);
+ ATILCDClock *= ATIReferenceNumerator;
+ ATILCDClock /= ATIClockDescriptor->MinM;
+ ATILCDClock /= ATIReferenceDenominator;
+! Index2 =
+! GetBits(ATIGetMach64PLLReg(PLL_XCLK_CNTL),
+! PLL_VCLK0_XDIV << Index);
+! Index2 *= MaxBits(PLL_VCLK0_POST_DIV) + 1;
+! Index2 |= GetBits(ATIGetMach64PLLReg(PLL_VCLK_POST_DIV),
+! PLL_VCLK0_POST_DIV << (2 * Index));
+! ATILCDClock /= ATIClockDescriptor->PostDividers[Index2];
+ }
+ }
+
+diff -cENRr -x CVS -x test base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/ativersion.h devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/ativersion.h
+*** base/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/ativersion.h Wed Feb 9 20:09:34 2000
+--- devel/xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/ativersion.h Wed Feb 9 11:01:02 2000
+***************
+*** 1,4 ****
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/ativersion.h,v 1.1.2.5 1999/10/12 17:18:57 hohndel Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+--- 1,4 ----
+! /* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/ati/ativersion.h,v 1.1.2.5tsi Exp $ */
+ /*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+***************
+*** 24,33 ****
+ #ifndef ___ATIVERSION_H___
+ #define ___ATIVERSION_H___ 1
+
+! #define ATI_VERSION_NAME "4.6"
+
+ #define ATI_VERSION_MAJOR 4
+! #define ATI_VERSION_MINOR 6
+
+ #define ATI_VERSION_CURRENT ((ATI_VERSION_MAJOR << 16) | ATI_VERSION_MINOR)
+
+--- 24,33 ----
+ #ifndef ___ATIVERSION_H___
+ #define ___ATIVERSION_H___ 1
+
+! #define ATI_VERSION_NAME "4.7"
+
+ #define ATI_VERSION_MAJOR 4
+! #define ATI_VERSION_MINOR 7
+
+ #define ATI_VERSION_CURRENT ((ATI_VERSION_MAJOR << 16) | ATI_VERSION_MINOR)
+