summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
commit8cf2eff7ea90409df3f75a53080b45dd54acba17 (patch)
tree3f1ddbc3bd39caed9c18ff7b89fa8c2acd5ab004
Initial revisionXORG-STABLE
-rw-r--r--README.sgml62
-rw-r--r--man/cyrix.man75
-rw-r--r--src/cyrix.h532
-rw-r--r--src/cyrix_accel.c447
-rw-r--r--src/cyrix_bank.c72
-rw-r--r--src/cyrix_driver.c1516
-rw-r--r--src/cyrix_helper.c382
-rw-r--r--src/cyrix_shadow.c155
8 files changed, 3241 insertions, 0 deletions
diff --git a/README.sgml b/README.sgml
new file mode 100644
index 0000000..a0861c9
--- /dev/null
+++ b/README.sgml
@@ -0,0 +1,62 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+<title>Information for Cyrix Chipset Users
+<author>The XFree86 Project Inc.
+<date>7 March 2000
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/cyrix.sgml,v 1.3 2000/03/08 05:38:43 dawes Exp $
+</ident>
+<toc>
+
+<sect>Supported hardware <p>
+
+This driver
+supports a single chipset `mediagx' that should work on the following Cyrix
+CPUs with integrated graphics:
+
+<itemize>
+<item>MediaGX
+<item>MediaGXi
+<item>MediaGXm
+</itemize>
+
+<sect>Features <p>
+<itemize>
+<item>Rather sparse (color depth hardcoded to 8)
+</itemize>
+
+<sect>XF86Config Option <p>
+<descrip>
+<tag>Option "sw_cursor"</tag>
+disable the hardware cursor. (Code not verified yet!)
+<tag>Option "no_accel"</tag>
+completely disables acceleration. Usually not recommended.
+</descrip>
+
+<sect>Bugs and Limitations<p>
+<itemize>
+<item>As a first cut at the new design, known problems are everywhere.
+The console font is corrupted upon exit. The server seems stable if
+the virtual desktop and resolution size match. I found 1024x768 usable
+and that's why I released this version. Geeks can have fun with this
+but NEWBIES should use the 3.3.3.1 release instead!
+<item>On some older chipsets, the driver may trigger an illegal instruction
+just after probing for the ``scratchpad size''. If this is the case,
+email to <email>hecker@cat.dfrc.nasa.gov</email> with the output of
+<verb>
+XFree86 -probeonly -verbose
+</verb>
+and this will be fixed.
+</itemize>
+
+<sect>Authors<p>
+<itemize>
+<item>Richard Hecker <email>hecker@cat.dfrc.nasa.gov</email>
+</itemize>
+
+
+</article>
+
diff --git a/man/cyrix.man b/man/cyrix.man
new file mode 100644
index 0000000..f8fb670
--- /dev/null
+++ b/man/cyrix.man
@@ -0,0 +1,75 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix.man,v 1.3 2002/11/06 11:38:59 alanh Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH CYRIX __drivermansuffix__ __vendorversion__
+.SH NAME
+cyrix \- Cyrix video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qcyrix\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B cyrix
+is an XFree86 driver for the Cyrix MediaGX (now Natsemi Geode) series of
+processors when using the built in video.
+.SH SUPPORTED HARDWARE
+The
+.B cyrix
+driver supports the MediaGX, MediaGXi and MediaGXm processors, as well as
+the Natsemi 'Geode' branded processors. It supports the CS5510, CS5520,
+CS5530 and CS5530A companion chips. The driver supports 4, 8, 15 and 16 bit
+deep displays with video compression and acceleration.
+.PP
+The MediaGX run length compresses its shared framebuffer, for the best
+performance on a MediaGX machine pick backgrounds that compress well
+horizonally.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The following driver
+.B options
+are supported
+.TP
+.BI "Option \*qNoAccel\*q \*q" boolean \*q
+Disable or enable acceleration. Default: acceleration is enabled.
+.TP
+.BI "Option \*qSWCursor\*q \*q" boolean \*q
+Disable or enable software cursor. Default software cursor is enabled and a
+hardware cursor is used.
+.TP
+.BI "Option \*qHWCursor\*q \*q" boolean \*q
+Disable or enable hardware cursor. Default hardware cursor is disabled.
+.TP
+.BI "Option \*qShadowFB\*q \*q" boolean \*q
+Disable or enable shadow frame buffer. The shadow buffer is normally only
+used when rotating the screen. The default is false.
+.TP
+.BI "Option \*qRotate\*q \*qCW\*q"
+.TP
+.BI "Option \*qRotate\*q \*qCCW\*q"
+.PP
+Rotate the display clockwise or counterclockwise for use on Cyrix based
+tablet PC systems. This mode is currently unaccelerated.
+.SH "BUGS"
+This driver has not been tested on the original 5510 hardware for some
+considerable time.
+.PP
+8bit mode does not currently work on the CS5510 with external RAMDAC.
+.PP
+The 5530A video overlay facility is not currently supported.
+.PP
+XFree86 uses the MediaGX 'SoftVGA' interface. On a small number of boards
+this is buggy and may result in strange illegal instruction traps.
+.PP
+Hardware cursors are not currently supported.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
+.SH AUTHORS
+Authors include: Richard Hecker, Annius Groenink, Dirk Hohndel, The GGI
+Project, Alan Cox.
diff --git a/src/cyrix.h b/src/cyrix.h
new file mode 100644
index 0000000..c75c222
--- /dev/null
+++ b/src/cyrix.h
@@ -0,0 +1,532 @@
+/*
+ * Copyright 2000 by Richard A. Hecker, California, United States
+ * Copyright 2002 by Red Hat Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov
+ * Re-written for XFree86 v4.0
+ * Chunks re-written again for XFree86 v4.2
+ * Alan Cox <alan@redhat.com>
+ * Previous driver (pre-XFree86 v4.0) 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix.h,v 1.4 2002/11/06 11:38:59 alanh Exp $ */
+
+#ifndef _CYRIX_H_
+#define _CYRIX_H_
+
+#include "xaa.h"
+#include "xf86Cursor.h"
+#include "vgaHW.h"
+
+/* 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
+ GGI's permission under the XFree86 license.
+*/
+
+/* XFree86 macros */
+#define CYRIXPTR(p) ((CYRIXPrvPtr)((p)->driverPrivate))
+
+
+/* Driver specific structures */
+typedef struct {
+ unsigned char cyrixRegs3x4[0x100];
+ unsigned char cyrixRegs3CE[0x100];
+ unsigned char cyrixRegs3C4[0x100];
+ unsigned char cyrixRegsDAC[0x01];
+ unsigned char cyrixRegsClock[0x03];
+ unsigned char DacRegs[0x300];
+ unsigned int Colormap[0x100]; /* Actually 18bit values */
+} CYRIXRegRec, *CYRIXRegPtr;
+
+typedef struct {
+ /* extended SoftVGA registers */
+ unsigned char VerticalTimingExtension;
+ unsigned char ExtendedAddressControl;
+ unsigned char ExtendedOffset;
+ unsigned char Offset;
+ 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];
+} prevExt;
+
+typedef struct {
+ /* struct for the server */
+ CARD32 IOAccelAddress;
+ CARD32 FbAddress;
+ char* GXregisters;
+ int CYRIXcursorAddress; /* relative to fb base */
+ int CYRIXbltBuf0Address;/*relative to GXregisters*/
+ int CYRIXbltBuf1Address;
+ int CYRIXbltBufSize;
+ EntityInfoPtr pEnt;
+ unsigned char * FbBase;
+ pciVideoPtr PciInfo;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ int HwBpp;
+ int MinClock;
+ int MaxClock;
+ int Chipset;
+ int ChipRev;
+ int RamDac;
+ long FbMapSize;
+ short EngineOperation;
+ CYRIXRegRec SavedReg;
+ CYRIXRegRec ModeReg;
+ vgaHWRec std;
+ prevExt PrevExt;
+ Bool HWCursor;
+/* Bool IsCyber;
+ Bool NewClockCode;*/
+ Bool NoAccel;
+ Bool NoCompress;
+ Bool ShadowFB;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ int Rotate;
+ void (*PointerMoved)(int index, int x, int y);
+ OptionInfoPtr Options;
+ /* accel stuff */
+ int bltBufWidth;
+ int blitMode;
+ int vectorMode;
+ int transMode;
+ int copyXdir;
+ int setBlitModeOnSync;
+
+} CYRIXPrivate, *CYRIXPrvPtr;
+
+typedef struct {
+ vgaHWRec std; /* IBM VGA */
+ prevExt ext;
+} CYRIXRec, *CYRIXPtr;
+
+/* Helper routines */
+extern void Cyrix1bppColorMap(ScrnInfoPtr pScrn);
+extern int CyrixHWCursor(ScreenPtr pScr);
+extern int CyrixInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+extern void CyrixRestore(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg);
+extern void * CyrixSave(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg);
+
+/* Shadow routines */
+extern void CYRIXRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+extern void CYRIXPointerMoved(int index, int x, int y);
+extern void CYRIXRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+extern void CYRIXRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+
+extern void CYRIXsetBlitBuffers(void);
+extern void CYRIXsetBlitBuffersOnOldChip(void);
+
+/* 32 bit access to GX registers */
+#define GX_REG(a) (*(volatile CARD32*)(pCyrix->GXregisters + (a)))
+
+
+/* externs in cyrix_accel.c */
+extern void CYRIXAccelInit(ScreenPtr);
+
+/* A minor Sync() function that only waits for the graphics pipeline
+ registers to be flushed so we can define a new operation */
+#define CYRIXsetupSync() \
+ while (GX_REG(GP_BLIT_STATUS) & BS_BLIT_PENDING)
+
+
+/* access macros to the graphics pipeline registers */
+#define CYRIXsetSrcXY(x, y) \
+ GX_REG(GP_SRC_XCOOR) = (((y) << 16) | (x))
+
+#define CYRIXsetDstXY(x, y) \
+ GX_REG(GP_DST_XCOOR) = (((y) << 16) | (x))
+
+#define CYRIXsetWH(w, h) \
+ GX_REG(GP_WIDTH) = (((h) << 16) | (w))
+
+#define CYRIXsetSourceColors01(p, col0, col1) \
+ CYRIXsetColors01((p), GP_SRC_COLOR_0, (col0), (col1))
+
+#define CYRIXsetPatColors01(p, col0, col1) \
+ CYRIXsetColors01((p), GP_PAT_COLOR_0, (col0), (col1))
+
+#define CYRIXsetPatColors23(p, col2, col3) \
+ CYRIXsetColors01((p), GP_PAT_COLOR_2, (col2), (col3))
+
+#define CYRIXsetPatData(data0, data1) \
+ GX_REG(GP_PAT_DATA_0) = (data0); \
+ GX_REG(GP_PAT_DATA_1) = (data1)
+
+#define CYRIXsetPatMode(xrop, pm) \
+ GX_REG(GP_RASTER_MODE) = ((pm) | windowsROPpatMask[(xrop)])
+
+#define CYRIXsetPatModeX(xrop, pm) \
+ GX_REG(GP_RASTER_MODE) = ((pm) | windowsROPsrcMask[(xrop)])
+
+#define CYRIXsetPatModeTrans(pm) \
+ GX_REG(GP_RASTER_MODE) = ((pm) | RM_CLIP_ENABLE | 0xC6);
+
+#define CYRIXsetBlitMode() \
+ GX_REG(GP_BLIT_MODE) = (pCyrix->blitMode)
+
+#define CYRIXsetVectorMode() \
+ GX_REG(GP_VECTOR_MODE) = (pCyrix->vectorMode)
+
+#define IfDest(rop, planemask, val) \
+ (( (((rop) & 0x5) ^ (((rop) & 0xA) >> 1)) \
+ || (~((planemask) & 0xFF)) \
+ ) ? (val) : 0)
+
+/* Generic MediaGX hardware register and value definitions */
+
+#define GX_IOPORT_INDEX 0x22
+#define GX_IOPORT_DATA 0x23
+
+/* I/O REGISTERS INDEX DEFINITIONS */
+
+#define GX_IOIDX_PCR 0x20
+#define GX_IOIDX_CCR1 0xC1
+#define GX_IOIDX_CCR2 0xC2
+#define GX_IOIDX_CCR3 0xC3
+#define GX_IOIDX_CCR4 0xE8
+#define GX_IOIDX_DIR0 0xFE
+#define GX_IOIDX_DIR1 0xFF
+#define GX_IOIDX_SMAR0 0xCD
+#define GX_IOIDX_SMAR1 0xCE
+#define GX_IOIDX_SMAR2 0xCF
+#define GX_IOIDX_SMHR0 0xB0
+#define GX_IOIDX_SMHR1 0xB1
+#define GX_IOIDX_SMHR2 0xB2
+#define GX_IOIDX_SMHR3 0xB3
+#define GX_IOIDX_GCR 0xB8
+#define GX_IOIDX_VGACTL 0xB9
+#define GX_IOIDX_VGAM0 0xBA
+#define GX_IOIDX_VGAM1 0xBB
+#define GX_IOIDX_VGAM2 0xBC
+#define GX_IOIDX_VGAM3 0xBD
+
+/* BUS CONTROLLER REGISTER DEFINITIONS */
+
+#define BC_DRAM_TOP 0x8000
+#define BC_XMAP_1 0x8004
+#define BC_XMAP_2 0x8008
+#define BC_XMAP_3 0x800C
+
+/* 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 */
+#define RM_CLIP_ENABLE 0x1000 /* enables clipping */
+
+/* "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_FLUSH 0x0080 /* flush pipeline requests */
+#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 */
+
+/* DISPLAY CONTROLLER REGISTER DEFINITIONS */
+
+#define DC_UNLOCK 0x8300 /* lock register */
+#define DC_GENERAL_CFG 0x8304 /* config registers... */
+#define DC_TIMING_CFG 0x8308
+#define DC_OUTPUT_CFG 0x830C
+
+#define DC_FB_ST_OFFSET 0x8310 /* framebuffer start offset */
+#define DC_CB_ST_OFFSET 0x8314 /* compression start offset */
+#define DC_CURS_ST_OFFSET 0x8318 /* cursor start offset*/
+#define DC_ICON_ST_OFFSET 0x831C /* icon start offset */
+#define DC_VID_ST_OFFSET 0x8320 /* video start offset */
+#define DC_LINE_DELTA 0x8324 /* fb and cb skip counts */
+#define DC_BUF_SIZE 0x8328 /* fb and cb line size */
+
+#define DC_H_TIMING_1 0x8330 /* horizontal timing... */
+#define DC_H_TIMING_2 0x8334
+#define DC_H_TIMING_3 0x8338
+#define DC_FP_H_TIMING 0x833C
+
+#define DC_V_TIMING_1 0x8340 /* vertical timing... */
+#define DC_V_TIMING_2 0x8344
+#define DC_V_TIMING_3 0x8348
+#define DC_FP_V_TIMING 0x834C
+
+#define DC_CURSOR_X 0x8350 /* cursor x position */
+#define DC_ICON_X 0x8354 /* HACK - 1.3 definition */
+#define DC_V_LINE_CNT 0x8354 /* vertical line counter */
+#define DC_CURSOR_Y 0x8358 /* cursor y position */
+#define DC_ICON_Y 0x835C /* HACK - 1.3 definition */
+#define DC_SS_LINE_COMPARE 0x835C /* line compare value */
+
+#define DC_CURSOR_COLOR 0x8360 /* cursor colors */
+#define DC_ICON_COLOR 0x8364 /* icon colors */
+#define DC_BORDER_COLOR 0x8368 /* border color */
+
+#define DC_PAL_ADDRESS 0x8370 /* palette address */
+#define DC_PAL_DATA 0x8374 /* palette data */
+
+/* PALETTE ADDRESS DEFINITIONS */
+
+#define PAL_CURSOR_COLOR_0 0x100
+#define PAL_CURSOR_COLOR_1 0x101
+#define PAL_ICON_COLOR_0 0x102
+#define PAL_ICON_COLOR_1 0x103
+#define PAL_OVERSCAN_COLOR 0x104
+
+/* DC BIT DEFINITIONS */
+
+#define DC_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */
+
+#define DC_GCFG_DFLE 0x00000001 /* display FIFO load enable */
+#define DC_GCFG_CURE 0x00000002 /* cursor enable */
+#define DC_GCFG_ICNE 0x00000004 /* HACK - 1.3 definition */
+#define DC_GCFG_PLNO 0x00000004 /* planar offset LSB */
+#define DC_GCFG_VIDE 0x00000008 /* HACK - 1.3 definition */
+#define DC_GCFG_PPC 0x00000008 /* pixel pan compatibility */
+#define DC_GCFG_CMPE 0x00000010 /* compression enable */
+#define DC_GCFG_DECE 0x00000020 /* decompression enable */
+#define DC_GCFG_DCLK_MASK 0x000000C0 /* dotclock multiplier */
+#define DC_GCFG_DCLK_POS 6 /* dotclock multiplier */
+#define DC_GCFG_DFHPSL_MASK 0x00000F00 /* FIFO high-priority start */
+#define DC_GCFG_DFHPSL_POS 8 /* FIFO high-priority start */
+#define DC_GCFG_DFHPEL_MASK 0x0000F000 /* FIFO high-priority end */
+#define DC_GCFG_DFHPEL_POS 12 /* FIFO high-priority end */
+#define DC_GCFG_CIM_MASK 0x00030000 /* compressor insert mode */
+#define DC_GCFG_CIM_POS 16 /* compressor insert mode */
+#define DC_GCFG_FDTY 0x00040000 /* frame dirty mode */
+#define DC_GCFG_RTPM 0x00080000 /* real-time perf. monitor */
+#define DC_GCFG_DAC_RS_MASK 0x00700000 /* DAC register selects */
+#define DC_GCFG_DAC_RS_POS 20 /* DAC register selects */
+#define DC_GCFG_CKWR 0x00800000 /* clock write */
+#define DC_GCFG_LDBL 0x01000000 /* line double */
+#define DC_GCFG_DIAG 0x02000000 /* FIFO diagnostic mode */
+#define DC_GCFG_CH4S 0x04000000 /* sparse refresh mode */
+#define DC_GCFG_SSLC 0x08000000 /* enable line compare */
+#define DC_GCFG_FBLC 0x10000000 /* enable fb offset compare */
+#define DC_GCFG_DFCK 0x20000000 /* divide flat-panel clock */
+#define DC_GCFG_DPCK 0x40000000 /* divide pixel clock */
+#define DC_GCFG_DDCK 0x80000000 /* divide dot clock */
+
+#define DC_TCFG_FPPE 0x00000001 /* flat-panel power enable */
+#define DC_TCFG_HSYE 0x00000002 /* horizontal sync enable */
+#define DC_TCFG_VSYE 0x00000004 /* vertical sync enable */
+#define DC_TCFG_BLKE 0x00000008 /* blank enable */
+#define DC_TCFG_DDCK 0x00000010 /* DDC clock */
+#define DC_TCFG_TGEN 0x00000020 /* timing generator enable */
+#define DC_TCFG_VIEN 0x00000040 /* vertical interrupt enable */
+#define DC_TCFG_BLNK 0x00000080 /* blink enable */
+#define DC_TCFG_CHSP 0x00000100 /* horizontal sync polarity */
+#define DC_TCFG_CVSP 0x00000200 /* vertical sync polarity */
+#define DC_TCFG_FHSP 0x00000400 /* panel horz sync polarity */
+#define DC_TCFG_FVSP 0x00000800 /* panel vert sync polarity */
+#define DC_TCFG_FCEN 0x00001000 /* flat-panel centering */
+#define DC_TCFG_CDCE 0x00002000 /* HACK - 1.3 definition */
+#define DC_TCFG_PLNR 0x00002000 /* planar mode enable */
+#define DC_TCFG_INTL 0x00004000 /* interlace scan */
+#define DC_TCFG_PXDB 0x00008000 /* pixel double */
+#define DC_TCFG_BKRT 0x00010000 /* blink rate */
+#define DC_TCFG_PSD_MASK 0x000E0000 /* power sequence delay */
+#define DC_TCFG_PSD_POS 17 /* power sequence delay */
+#define DC_TCFG_DDCI 0x08000000 /* DDC input (RO) */
+#define DC_TCFG_SENS 0x10000000 /* monitor sense (RO) */
+#define DC_TCFG_DNA 0x20000000 /* display not active (RO) */
+#define DC_TCFG_VNA 0x40000000 /* vertical not active (RO) */
+#define DC_TCFG_VINT 0x80000000 /* vertical interrupt (RO) */
+
+#define DC_OCFG_8BPP 0x00000001 /* 8/16 bpp select */
+#define DC_OCFG_555 0x00000002 /* 16 bpp format */
+#define DC_OCFG_PCKE 0x00000004 /* PCLK enable */
+#define DC_OCFG_FRME 0x00000008 /* frame rate mod enable */
+#define DC_OCFG_DITE 0x00000010 /* dither enable */
+#define DC_OCFG_2PXE 0x00000020 /* 2 pixel enable */
+#define DC_OCFG_2XCK 0x00000040 /* 2 x pixel clock */
+#define DC_OCFG_2IND 0x00000080 /* 2 index enable */
+#define DC_OCFG_34ADD 0x00000100 /* 3- or 4-bit add */
+#define DC_OCFG_FRMS 0x00000200 /* frame rate mod select */
+#define DC_OCFG_CKSL 0x00000400 /* clock select */
+#define DC_OCFG_PRMP 0x00000800 /* palette re-map */
+#define DC_OCFG_PDEL 0x00001000 /* panel data enable low */
+#define DC_OCFG_PDEH 0x00002000 /* panel data enable high */
+#define DC_OCFG_CFRW 0x00004000 /* comp line buffer r/w sel */
+#define DC_OCFG_DIAG 0x00008000 /* comp line buffer diag */
+
+/* MC REGISTER DEFINITIONS */
+
+#define MC_GBASE_ADD 0x8414 /* Graphics mem base address */
+#define MC_DR_ADD 0x8418 /* Dirty RAM address index */
+#define MC_DR_ACC 0x841C /* Dirty RAM memory access */
+#define MC_RAMDAC_ACC 0x8420 /* RAMDAC register access */
+
+/* CPU REGISTER REGISTER DEFINITIONS */
+
+#define BB0_BASE 0xFFFFFF0C /* Blit buffer 0 base */
+#define BB1_BASE 0xFFFFFF1C /* Blit buffer 1 base */
+
+
+
+/* SoftVGA CRTC register indices and bit definitions */
+
+#define CrtcExtendedRegisterLock 0x30
+#define CrtcGraphicsMemorySize 0x3E
+#define CrtcModeSwitchControl 0x3F
+#define CrtcVerticalTimingExtension 0x41
+#define CrtcExtendedAddressControl 0x43
+#define CrtcExtendedStartAddress 0x44
+#define CrtcExtendedOffset 0x45
+#define CrtcExtendedColorControl 0x46
+#define CrtcWriteMemoryAperture 0x47
+#define CrtcReadMemoryAperture 0x48
+#define CrtcDisplayCompression 0x49
+#define CrtcDriverControl 0x4A
+#define CrtcDACControl 0x4B
+#define CrtcClockControl 0x4C
+#define CrtcClockFrequency 0x4D
+#define CrtcClockFrequencyFraction 0x4E
+#define CrtcRefreshRate 0x4F
+
+/* ExtendedAddressControl bit definitions */
+#define EAC_PIXEL_DOUBLE 0x04
+#define EAC_DIRECT_FRAME_BUFFER 0x02
+#define EAC_PACKED_CHAIN4 0x01
+
+/* ExtendedColorControl bit definitions */
+#define ECC_32BPP 0x04 /* MXi only */
+#define ECC_555_FORMAT 0x02
+#define ECC_565_FORMAT 0x00
+#define ECC_16BPP 0x01
+#define ECC_8BPP 0x00
+
+/* DriverControl bit definitions */
+#define DRVCT_DISPLAY_DRIVER_ACTIVE 0x01
+
+/* DACControl bit definitions */
+#define DACCT_HALF_PIXEL_PER_CLOCK 0x08
+#define DACCT_TWO_PIXELS_PER_CLOCK 0x04
+#define DACCT_ENABLE_16BIT_BUS 0x02
+
+/* ClockControl bit definitions */
+#define CLKCT_EXT_CLOCK_MODE 0x80
+#define CLKCT_HALVE_DOT_CLOCK 0x20
+#define CLKCT_DOUBLE_DOT_CLOCK 0x10
+#define CLKCT_GENDAC_ICS5342 0x00
+#define CLKCT_GENDAC_MASK 0x07
+
+#endif /* _CYRIX_H_ */
diff --git a/src/cyrix_accel.c b/src/cyrix_accel.c
new file mode 100644
index 0000000..652c1d8
--- /dev/null
+++ b/src/cyrix_accel.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2000 by Richard A. Hecker, California, United States
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Richard Hecker not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Richard Hecker makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov
+ * Re-written for XFree86 v4.0
+ * Previous driver (pre-XFree86 v4.0) 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_accel.c,v 1.5 2002/11/06 11:38:59 alanh Exp $ */
+
+#include "vgaHW.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xaalocal.h"
+#include "cyrix.h"
+#include "miline.h"
+#include "xf86_libc.h"
+#include "compiler.h"
+
+/* size of color expand source area (embedded in frame buffer) */
+#define CYRIXexpandSize 32768
+
+/* Raster operations are converted in such a way that we can use them to
+ do planemask operations: lower nybble is NOP (pattern=planemask),
+ 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. */
+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 };
+
+/* Forward declaration of functions used in the driver */
+void CYRIXAccelSync(ScrnInfoPtr pScrn);
+void CYRIXSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+void CYRIXSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+void CYRIXSetupForScreenToScreenCopy(ScrnInfoPtr, int xdir, int ydir,
+ int rop, unsigned int planemask, int transparency_color);
+void CYRIXSubsequentScreenToScreenCopy(ScrnInfoPtr, int x1, int y1, int x2,
+ int y2, int w, int h);
+void CYRIXSubsequentBresenhamLine(ScrnInfoPtr pScrn,int x1, int y1,
+ int e1, int e2, int err, int length,
+ int octant);
+void CYRIXSetupForColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
+ int patterny, int rop, unsigned int planemask, int transparency_color);
+void CYRIXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
+ int patterny, int x, int y, int w, int h);
+void CYRIXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+void CYRIXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+void InitPixmapCache(ScreenPtr pScreen, RegionPtr areas, pointer data);
+/* Info Rec for all these routines to use */
+
+/* Acceleration init function, sets up pointers to our accelerated functions */
+void
+CYRIXAccelInit(ScreenPtr pScreen)
+{ /* General acceleration flags */
+
+ CYRIXPrvPtr pCyrix;
+ ScrnInfoPtr pScrn;
+ XAAInfoRecPtr localRecPtr;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pCyrix = CYRIXPTR(pScrn);
+ pCyrix->AccelInfoRec = localRecPtr = XAACreateInfoRec();
+ localRecPtr->Flags = PIXMAP_CACHE
+ | PW_BACKGROUND
+#if 0
+ | HARDWARE_PATTERN_MONO_TRANSPARENCY
+#endif
+ | HARDWARE_PATTERN_SCREEN_ORIGIN
+ | BIT_ORDER_IN_BYTE_MSBFIRST
+ | HARDWARE_PATTERN_PROGRAMMED_BITS;
+
+ /* Sync */
+ localRecPtr->Sync = CYRIXAccelSync;
+
+ /* Filled rectangles */
+ localRecPtr->SetupForSolidFill =
+ CYRIXSetupForSolidFill;
+ localRecPtr->SubsequentSolidFillRect =
+ CYRIXSubsequentSolidFillRect;
+ pCyrix->AccelInfoRec->PolyFillRectSolidFlags = NO_PLANEMASK;
+
+ /* ScreenToScreen copies */
+ localRecPtr->SetupForScreenToScreenCopy =
+ CYRIXSetupForScreenToScreenCopy;
+ localRecPtr->SubsequentScreenToScreenCopy =
+ CYRIXSubsequentScreenToScreenCopy;
+
+ pCyrix->AccelInfoRec->CopyAreaFlags = NO_PLANEMASK | GXCOPY_ONLY;
+
+#if 0
+ /* Bresenham lines - disable because of minor display errors */
+ localRecPtr->SubsequentBresenhamLine =
+ CYRIXSubsequentBresenhamLine;
+ localRecPtr->ErrorTermBits = 15;
+#endif
+
+ /* 8x8 color-expanded patterns */
+ localRecPtr->SetupForColor8x8PatternFill =
+ CYRIXSetupForColor8x8PatternFillRect;
+ localRecPtr->SubsequentColor8x8PatternFillRect =
+ CYRIXSubsequentColor8x8PatternFillRect;
+
+ /* Color expansion */
+ localRecPtr->Color8x8PatternFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | NO_PLANEMASK |
+ TRANSPARENCY_GXCOPY_ONLY | SCANLINE_PAD_DWORD;
+
+ /* Use two blit buffers in a row for text expansion
+ (this is an undefendable fix to a text display distortion
+ bug if we don't give XAA enough room, but the only thing that
+ seems to make it work properly) */
+ localRecPtr->ColorExpandBase =
+ (unsigned char*)(pCyrix->GXregisters + pCyrix->CYRIXbltBuf0Address);
+ localRecPtr->ColorExpandRange =
+ pCyrix->CYRIXbltBufSize * 2;
+
+ localRecPtr->SetupForCPUToScreenColorExpandFill =
+ CYRIXSetupForCPUToScreenColorExpandFill;
+ localRecPtr->SubsequentCPUToScreenColorExpandFill =
+ CYRIXSubsequentCPUToScreenColorExpandFill;
+
+ /* calculate the pixel width of a blit buffer for convenience */
+ pCyrix->bltBufWidth = pCyrix->CYRIXbltBufSize / (pScrn->bitsPerPixel / 8);
+}
+
+
+/* set colors - called through access macros in cyrix.h */
+static __inline__ void CYRIXsetColors01(ScrnInfoPtr pScrn, int reg,
+ int col0, int col1) {
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+
+ if (pScrn->bitsPerPixel == 16)
+ GX_REG(reg) = ((col1 & 0xFFFF) << 16) | (col0 & 0xFFFF);
+ else
+ { col0 &= 0xFF;
+ col1 &= 0xFF;
+ GX_REG(reg) = (col1 << 24) | (col1 << 16) | (col0 << 8) | col0;
+} }
+
+
+/* The generic Sync() function that waits for everything to
+ be completed (e.g. before writing to the frame buffer
+ directly). */
+void
+CYRIXAccelSync(ScrnInfoPtr pScrn)
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+
+ if (pCyrix->setBlitModeOnSync)
+ { pCyrix->setBlitModeOnSync = 0;
+ CYRIXsetupSync();
+ CYRIXsetBlitMode();
+ }
+ while (GX_REG(GP_BLIT_STATUS) &
+ (BS_BLIT_BUSY|BS_PIPELINE_BUSY|BS_BLIT_PENDING));
+}
+
+
+/* Solid rectangles */
+void
+CYRIXSetupForSolidFill(pScrn, color, rop, planemask)
+ScrnInfoPtr pScrn;
+int color, rop;
+unsigned int planemask;
+{
+ CYRIXPrvPtr pCyrix;
+
+ pCyrix = CYRIXPTR(pScrn);
+ if (pCyrix->AccelInfoRec->PolyFillRectSolidFlags & GXCOPY_ONLY)
+ rop = GXcopy;
+ if (pCyrix->AccelInfoRec->PolyFillRectSolidFlags & NO_PLANEMASK)
+ planemask = 0xFFFF;
+ CYRIXsetupSync();
+ CYRIXsetSourceColors01(pScrn, color, color);
+ CYRIXsetPatColors01(pScrn, planemask, 0);
+ CYRIXsetPatMode(rop, RM_PAT_DISABLE);
+ pCyrix->blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND
+ | IfDest(rop, planemask, BM_READ_DST_FB0);
+ pCyrix->vectorMode = IfDest(rop, planemask, VM_READ_DST_FB);
+}
+
+
+void
+CYRIXSubsequentSolidFillRect(pScrn, x, y, w, h)
+ScrnInfoPtr pScrn;
+int x, y, w, h;
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+
+ /* divide the operation into columns if required; use twice the
+ blit buffer width because buffer 0 will overflow into buffer 1 */
+ while (w > 2 * pCyrix->bltBufWidth)
+ { CYRIXSubsequentSolidFillRect(pScrn, x, y,
+ 2 * pCyrix->bltBufWidth, h);
+ x += 2 * pCyrix->bltBufWidth;
+ w -= 2 * pCyrix->bltBufWidth;
+ }
+ CYRIXsetupSync();
+ CYRIXsetDstXY(x, y);
+ CYRIXsetWH(w, h);
+ CYRIXsetBlitMode();
+}
+
+
+/* Screen to screen copies */
+void
+CYRIXSetupForScreenToScreenCopy(pScrn, xdir, ydir, rop,
+ planemask, transparency_color)
+ScrnInfoPtr pScrn;
+int xdir, ydir;
+int rop;
+unsigned int planemask;
+int transparency_color;
+{
+ CYRIXPrvPtr pCyrix;
+
+ pCyrix = CYRIXPTR(pScrn);
+ if (pCyrix->AccelInfoRec->CopyAreaFlags & NO_PLANEMASK)
+ planemask = 0xFFFF;
+ if (pCyrix->AccelInfoRec->CopyAreaFlags & GXCOPY_ONLY)
+ rop = GXcopy;
+ if (pCyrix->AccelInfoRec->CopyAreaFlags & NO_TRANSPARENCY)
+ transparency_color = -1;
+
+ CYRIXsetupSync();
+ CYRIXsetPatColors01(pScrn, planemask, 0);
+
+ if (transparency_color == -1)
+ { CYRIXsetPatMode(rop, RM_PAT_DISABLE);
+ pCyrix->transMode = 0;
+ }
+ else
+ { CYRIXsetPatModeTrans(RM_PAT_DISABLE);
+ pCyrix->transMode = 1;
+
+ if (pCyrix->AccelInfoRec->CopyAreaFlags &
+ TRANSPARENCY_GXCOPY_ONLY)
+ rop = GXcopy;
+
+ /* fill blit buffer 1 with the transparency color */
+ if (pScrn->bitsPerPixel == 16)
+ { int k = pCyrix->CYRIXbltBufSize / 4;
+ CARD32 val = (transparency_color << 16) |
+ transparency_color;
+ volatile CARD32* buf = &(GX_REG(pCyrix->CYRIXbltBuf1Address));
+
+ while (--k >= 0) buf[k] = val;
+ }
+ else
+ memset(pCyrix->GXregisters + pCyrix->CYRIXbltBuf1Address,
+ transparency_color, pCyrix->CYRIXbltBufSize);
+ }
+
+ pCyrix->blitMode = BM_READ_SRC_FB | BM_WRITE_FB | BM_SOURCE_COLOR
+ | (pCyrix->transMode ? BM_READ_DST_NONE : IfDest(rop, planemask, BM_READ_DST_FB1))
+ | (ydir < 0 ? BM_REVERSE_Y : 0);
+
+ pCyrix->copyXdir = xdir;
+}
+
+void
+CYRIXSubsequentScreenToScreenCopy(pScrn, x1, y1, x2, y2, w, h)
+ScrnInfoPtr pScrn;
+int x1, y1, x2, y2, w, h;
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ int up = (pCyrix->blitMode & BM_REVERSE_Y);
+
+ /* divide the operation into columns when necessary */
+ if (pCyrix->copyXdir < 0)
+ { int x_offset = w - pCyrix->bltBufWidth;
+
+ while (x_offset > 0)
+ { CYRIXSubsequentScreenToScreenCopy(pScrn, x1 + x_offset, y1,
+ x2 + x_offset, y2,
+ pCyrix->bltBufWidth, h);
+ x_offset -= pCyrix->bltBufWidth;
+ w -= pCyrix->bltBufWidth;
+ } }
+ else while (w > pCyrix->bltBufWidth)
+ { CYRIXSubsequentScreenToScreenCopy(pScrn, x1, y1, x2, y2,
+ pCyrix->bltBufWidth, h);
+ x1 += pCyrix->bltBufWidth;
+ x2 += pCyrix->bltBufWidth;
+ w -= pCyrix->bltBufWidth;
+ }
+
+ 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 (pCyrix->transMode)
+ { pCyrix->blitMode |= BM_READ_DST_BB1;
+ CYRIXsetWH(w, 1);
+ CYRIXsetBlitMode();
+ h--;
+ if (!h) return;
+ if (up) { y1--; y2--; }
+ else { y1++; y2++; }
+ CYRIXsetupSync();
+ pCyrix->blitMode &= ~(BM_READ_DST_BB1);
+ }
+ CYRIXsetWH(w, h);
+ CYRIXsetBlitMode();
+}
+
+
+/* Bresenham lines */
+void
+CYRIXSubsequentBresenhamLine(pScrn, x1, y1, e1, e2, err, length, octant)
+ScrnInfoPtr pScrn; int x1, y1, octant, err, e1, e2, length;
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+
+ if (octant & YMAJOR) {
+ pCyrix->vectorMode = (pCyrix->vectorMode & VM_READ_DST_FB) | VM_Y_MAJOR;
+ if (!(octant & XDECREASING)) pCyrix->vectorMode |= VM_MINOR_INC;
+ if (!(octant & YDECREASING)) pCyrix->vectorMode |= VM_MAJOR_INC;
+ } else {
+ pCyrix->vectorMode = (pCyrix->vectorMode & VM_READ_DST_FB) | VM_X_MAJOR;
+ if (!(octant & XDECREASING)) pCyrix->vectorMode |= VM_MAJOR_INC;
+ if (!(octant & YDECREASING)) pCyrix->vectorMode |= VM_MINOR_INC;
+ }
+
+ CYRIXsetupSync();
+ CYRIXsetDstXY(x1, y1);
+ CYRIXsetWH(length, (err & 0xFFFF));
+ CYRIXsetSrcXY((e1 & 0xFFFF), (e2 & 0xFFFF));
+ CYRIXsetVectorMode();
+}
+
+
+/* 8x8 pattern color expand */
+void CYRIXSetupForColor8x8PatternFillRect(pScrn, patternx, patterny,
+ rop, planemask, transparency_color)
+ScrnInfoPtr pScrn;
+int patternx, patterny;
+int rop, transparency_color;
+unsigned int planemask;
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ XAAInfoRecPtr localRecPtr = pCyrix->AccelInfoRec;
+
+ if (localRecPtr->Color8x8PatternFillFlags & NO_PLANEMASK)
+ planemask = 0xFFFF;
+ if ((transparency_color == -1) && (localRecPtr->Color8x8PatternFillFlags &
+ TRANSPARENCY_GXCOPY_ONLY))
+ rop = GXcopy;
+
+ CYRIXsetupSync();
+ CYRIXsetPatColors01(pScrn, (transparency_color == -1) ?
+ 0 : transparency_color, planemask);
+ CYRIXsetPatData(patternx, patterny);
+ CYRIXsetPatModeX(rop, RM_PAT_MONO | ((transparency_color == -1) ?
+ RM_PAT_TRANSPARENT : 0));
+
+ pCyrix->blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND |
+ ((transparency_color == -1) ?
+ IfDest(rop, planemask, BM_READ_DST_FB0) : BM_READ_DST_NONE);
+}
+
+void CYRIXSubsequentColor8x8PatternFillRect(pScrn, patternx, patterny, x, y, w, h)
+ScrnInfoPtr pScrn;
+int patternx, patterny;
+int x, y, w, h;
+{ CYRIXSubsequentSolidFillRect(pScrn, x, y, w, h);
+}
+
+
+/* CPU-to-screen color expansion */
+void CYRIXSetupForCPUToScreenColorExpandFill(pScrn, fg, bg, rop, planemask)
+ScrnInfoPtr pScrn;
+int bg, fg, rop;
+unsigned int planemask;
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ XAAInfoRecPtr localRecPtr = pCyrix->AccelInfoRec;
+
+ int trans = (bg == -1);
+
+ if (trans && (localRecPtr->CPUToScreenColorExpandFillFlags &
+ TRANSPARENCY_GXCOPY_ONLY))
+ rop = GXcopy;
+
+ CYRIXsetupSync();
+ CYRIXsetSourceColors01(pScrn, trans ? 0 : bg, fg);
+ CYRIXsetPatColors01(pScrn, 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. */
+ pCyrix->blitMode = BM_READ_SRC_BB0 | BM_WRITE_FB | BM_SOURCE_EXPAND
+ | (trans ? IfDest(rop, planemask, BM_READ_DST_FB1) : BM_READ_DST_NONE);
+}
+
+void CYRIXSubsequentCPUToScreenColorExpandFill(pScrn, x, y, w, h, skipleft)
+ScrnInfoPtr pScrn;
+int x, y, w, h;
+int skipleft;
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ CYRIXsetupSync();
+ CYRIXsetSrcXY(0, 0);
+ CYRIXsetDstXY(x, y);
+ CYRIXsetWH(w, h);
+
+ CYRIXAccelSync(pScrn);
+ pCyrix->setBlitModeOnSync = 1;
+}
+
diff --git a/src/cyrix_bank.c b/src/cyrix_bank.c
new file mode 100644
index 0000000..e06d6dd
--- /dev/null
+++ b/src/cyrix_bank.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000 by Richard A. Hecker, California, United States
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Richard Hecker not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Richard Hecker makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov
+ * Re-written for XFree86 v4.0
+ * Previous driver (pre-XFree86 v4.0) 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_bank.c,v 1.3 2002/11/06 11:38:59 alanh Exp $ */
+
+#define PSZ 8
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* Driver specific headers */
+#include "cyrix.h"
+
+int
+CYRIXSetRead(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ return 0;
+}
+
+
+int
+CYRIXSetWrite(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+ return 0;
+}
+
+
+int
+CYRIXSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+ return 0;
+}
diff --git a/src/cyrix_driver.c b/src/cyrix_driver.c
new file mode 100644
index 0000000..9908478
--- /dev/null
+++ b/src/cyrix_driver.c
@@ -0,0 +1,1516 @@
+/*
+ * Copyright 2000 by Richard A. Hecker, California, United States
+ * Copyright 2002 by Red Hat Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Richard Hecker not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Richard Hecker makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov
+ * Re-written for XFree86 v4.0
+ *
+ * Chunks re-written again for XFree86 v4.2
+ * Alan Cox <alan@redhat.com>
+ * - Fixed cursor handling
+ * - Rewrote parts of the broken mode switch code
+ * - Added proper PCI detection
+ * - Added ShadowFB support
+ * - Added rotate support
+ * - Fixed palette loading/restore
+ * - Added "Nocompression" option
+ * - Fixed line length loading
+ * - Fixed panning logic
+ *
+ * Previous driver (pre-XFree86 v4.0) 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.
+ * (note that most of the data books have been released by
+ * NatSemi and are downloadable for free as pdf files)
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_driver.c,v 1.26 2003/01/07 00:05:13 alanh Exp $ */
+
+#include "fb.h"
+#include "mibank.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "shadowfb.h"
+#include "vgaHW.h"
+#include "xf86DDC.h"
+#include "xf86RAC.h"
+#include "xf86Resources.h"
+#include "compiler.h"
+#include "xf86int10.h"
+#include "vbe.h"
+
+#include "cyrix.h"
+
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+
+#include "opaque.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+
+static const OptionInfoRec * CYRIXAvailableOptions(int chip, int busid);
+static void CYRIXIdentify(int flags);
+static Bool CYRIXProbe(DriverPtr drv, int flags);
+static Bool CYRIXPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool CYRIXScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool CYRIXEnterVT(int scrnIndex, int flags);
+static void CYRIXLeaveVT(int scrnIndex, int flags);
+static Bool CYRIXCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool CYRIXSaveScreen(ScreenPtr pScreen, int mode);
+
+/* Required if the driver supports mode switching */
+static Bool CYRIXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+static void CYRIXAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void CYRIXFreeScreen(int scrnIndex, int flags);
+static int CYRIXFindIsaDevice(GDevPtr dev);
+static int CYRIXValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static void CYRIXSave(ScrnInfoPtr pScrn);
+static void CYRIXRestore(ScrnInfoPtr pScrn);
+static Bool CYRIXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void CYRIXRestorePalette(ScrnInfoPtr pScrn);
+static void CYRIXSavePalette(ScrnInfoPtr pScrn);
+
+/* Misc additional routines */
+void CYRIXSetRead(int bank);
+void CYRIXSetWrite(int bank);
+void CYRIXSetReadWrite(int bank);
+
+#define VERSION 4000
+#define CYRIX_NAME "CYRIX"
+#define CYRIX_DRIVER_NAME "cyrix"
+#define CYRIX_MAJOR_VERSION 1
+#define CYRIX_MINOR_VERSION 0
+#define CYRIX_PATCHLEVEL 0
+#define VGA_REGION 2
+
+enum GenericTypes {
+ CHIP_CYRIXmediagx
+};
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the moduleSetup
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec CYRIX = {
+ VERSION,
+ CYRIX_DRIVER_NAME,
+ CYRIXIdentify,
+ CYRIXProbe,
+ CYRIXAvailableOptions,
+ NULL,
+ 0
+};
+
+static SymTabRec CYRIXChipsets[] = {
+ { CHIP_CYRIXmediagx, "mediagx" },
+ { -1, NULL }
+};
+
+static IsaChipsets CYRIXISAChipsets[] = {
+ { CHIP_CYRIXmediagx, RES_EXCLUSIVE_VGA },
+ { -1, 0 }
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_NOACCEL,
+ OPTION_NOCOMPRESS,
+ OPTION_SHADOW_FB,
+ OPTION_ROTATE
+} CYRIXOpts;
+
+static const OptionInfoRec CYRIXOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOCOMPRESS, "NoCompression",OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWHandleColormaps",
+ "vgaHWInit",
+ "vgaHWLock",
+ "vgaHWMapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbScreenInit",
+ "fbPictureInit",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ "vbeFree",
+ NULL
+};
+
+/* access to the MediaGX video hardware registers */
+
+
+/* DEBUG variables & flags */
+#define ENTER TRUE
+#define LEAVE FALSE
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(cyrixSetup);
+
+static XF86ModuleVersionInfo cyrixVersRec =
+{
+ "cyrix",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ CYRIX_MAJOR_VERSION, CYRIX_MINOR_VERSION, CYRIX_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData cyrixModuleData = { &cyrixVersRec, cyrixSetup, NULL };
+
+pointer
+cyrixSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&CYRIX, module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, vbeSymbols, shadowSymbols, NULL);
+ return (pointer)TRUE;
+ }
+
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+CYRIXGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate a CYRIXRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(CYRIXPrivate), 1);
+ if (pScrn->driverPrivate == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+CYRIXFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static void
+CYRIXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ unsigned char DPMSCont, PMCont, temp;
+ outb(0x3C4, 0x0E);
+ temp = inb(0x3C5);
+ outb(0x3C5, 0xC2);
+ outb(0x83C8, 0x04); /* Read DPMS Control */
+ PMCont = inb(0x83C6) & 0xFC;
+ outb(0x3CE, 0x23);
+ DPMSCont = inb(0x3CF) & 0xFC;
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On, HSync: On, VSync: On */
+ PMCont |= 0x03;
+ DPMSCont |= 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off, HSync: Off, VSync: On */
+ PMCont |= 0x02;
+ DPMSCont |= 0x01;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off, HSync: On, VSync: Off */
+ PMCont |= 0x02;
+ DPMSCont |= 0x02;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off, HSync: Off, VSync: Off */
+ PMCont |= 0x00;
+ DPMSCont |= 0x03;
+ break;
+ }
+ outb(0x3CF, DPMSCont);
+ outb(0x83C8, 0x04);
+ outb(0x83C6, PMCont);
+ outw(0x3C4, (temp<<8) | 0x0E);
+}
+
+/* Mandatory */
+static void
+CYRIXIdentify(int flags)
+{
+ xf86PrintChipsets(CYRIX_NAME, "driver for Cyrix MediaGX Processors", CYRIXChipsets);
+}
+
+static const OptionInfoRec *
+CYRIXAvailableOptions(int chip, int busid)
+{
+ return CYRIXOptions;
+}
+
+#define PCI_CHIP_CYRIX5510 0x0000
+#define PCI_CHIP_CYRIX5520 0x0002
+#define PCI_CHIP_CYRIX5530 0x0104
+
+/* Conversion PCI ID to chipset name */
+static PciChipsets CYRIXPCIchipsets[] = {
+ { CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5510, RES_EXCLUSIVE_VGA },
+ { CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5520, RES_EXCLUSIVE_VGA },
+ { CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5530, RES_EXCLUSIVE_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+/* Mandatory */
+static Bool
+CYRIXProbe(DriverPtr drv, int flags)
+{
+ int i, numDevSections, numUsed, *usedChips;
+ GDevPtr *devSections;
+ ScrnInfoPtr pScrn;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ */
+
+ /*
+ * Look for config file Device sections with this driver specified.
+ */
+ if ((numDevSections = xf86MatchDevice(CYRIX_DRIVER_NAME,
+ &devSections)) <= 0) {
+#ifdef DEBUG
+ xf86ErrorFVerb(3,"%s: No Device section found.\n",CYRIX_NAME);
+#endif
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+#ifdef DEBUG
+ xf86ErrorFVerb(3,"%s: Device Sections found: %d\n",CYRIX_NAME, numDevSections);
+#endif
+
+ /* Should look like an ISA device */
+
+ /* PCI BUS */
+ if (xf86GetPciVideoInfo() ) {
+ numUsed = xf86MatchPciInstances(CYRIX_NAME, PCI_VENDOR_CYRIX,
+ CYRIXChipsets, CYRIXPCIchipsets,
+ devSections,numDevSections,
+ drv, &usedChips);
+
+ if (numUsed > 0) {
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ /* Allocate a ScrnInfoRec and claim the slot */
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ CYRIXPCIchipsets,NULL, NULL,
+ NULL, NULL, NULL))) {
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = CYRIX_DRIVER_NAME;
+ pScrn->name = CYRIX_NAME;
+ pScrn->Probe = CYRIXProbe;
+ pScrn->PreInit = CYRIXPreInit;
+ pScrn->ScreenInit = CYRIXScreenInit;
+ pScrn->SwitchMode = CYRIXSwitchMode;
+ pScrn->AdjustFrame = CYRIXAdjustFrame;
+ pScrn->LeaveVT = CYRIXLeaveVT;
+ pScrn->EnterVT = CYRIXEnterVT;
+ pScrn->FreeScreen = CYRIXFreeScreen;
+ pScrn->ValidMode = CYRIXValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ xfree(usedChips);
+ }
+ }
+
+
+ numUsed = xf86MatchIsaInstances(CYRIX_NAME,CYRIXChipsets,
+ CYRIXISAChipsets,drv,
+ CYRIXFindIsaDevice,devSections,
+ numDevSections,&usedChips);
+ if(numUsed > 0) {
+ foundScreen = TRUE;
+
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+
+ if (!(flags & PROBE_DETECT)) {
+ for (i=0; i < numUsed; i++) {
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn = NULL;
+ if ((pScrn = xf86ConfigIsaEntity(pScrn, 0, usedChips[i],
+ CYRIXISAChipsets, NULL,
+ NULL, NULL, NULL, NULL))){
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = CYRIX_DRIVER_NAME;
+ pScrn->name = CYRIX_NAME;
+ pScrn->Probe = CYRIXProbe;
+ pScrn->PreInit = CYRIXPreInit;
+ pScrn->ScreenInit = CYRIXScreenInit;
+ pScrn->SwitchMode = CYRIXSwitchMode;
+ pScrn->AdjustFrame = CYRIXAdjustFrame;
+ pScrn->LeaveVT = CYRIXLeaveVT;
+ pScrn->EnterVT = CYRIXEnterVT;
+ pScrn->FreeScreen = CYRIXFreeScreen;
+ pScrn->ValidMode = CYRIXValidMode;
+ }
+ }
+ }
+ }
+ xfree(usedChips);
+ return (foundScreen);
+}
+
+static int
+CYRIXFindIsaDevice(GDevPtr dev)
+{
+ CARD32 CurrentValue, TestValue;
+ unsigned char gcr;
+
+ /* No need to unlock VGA CRTC registers here */
+
+ /* VGA has one more read/write attribute register than EGA */
+ /* use register probing to decide whether the chip is
+ * `suitable' for us.
+ */
+ int vgaIOBase = VGAHW_GET_IOBASE();
+
+ (void) inb(vgaIOBase + 0x0AU); /* Reset flip-flop */
+ outb(0x3C0, 0x14 | 0x20);
+ CurrentValue = inb(0x3C1);
+ outb(0x3C0, CurrentValue ^ 0x0F);
+ outb(0x3C0, 0x14 | 0x20);
+ TestValue = inb(0x3C1);
+ outb(0x3C0, CurrentValue);
+
+ /* Quit now if no VGA is present */
+ if ((CurrentValue ^ 0x0F) != TestValue)
+ return -1;
+
+ /* the lock register should read 0xFF after we have
+ written 0x00 to lock */
+ outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
+ outb(vgaIOBase + 5, 0x00);
+
+ if (inb(vgaIOBase + 5) != 0xFF) return -1;
+
+ /* the lock register should read 0x00 after we have
+ written the magic word 'WL' to unlock */
+ outb(vgaIOBase + 5, 0x57);
+ outb(vgaIOBase + 5, 0x4C);
+
+ /* GGI's idea to do two comparisons */
+ if (inb(vgaIOBase + 5) != 0x00) goto fail;
+ if (inb(vgaIOBase + 5) != 0x00) goto fail;
+
+ /* OK, it's most likely a MediaGX. Now check the scratchpad
+ * size. If it is zero, we're not using the MediaGX graphics
+ * facilities.
+ */
+ outb(GX_IOPORT_INDEX, GX_IOIDX_DIR0); /* doesn't work w/o that */
+ outb(GX_IOPORT_INDEX, GX_IOIDX_GCR);
+ gcr = inb(GX_IOPORT_DATA);
+
+ /* end GGI MediaGX driver based code */
+ if (!(gcr & 12)) goto fail;
+
+ /* Unprotect MediaGX extended registers */
+ outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
+ outb(vgaIOBase + 5, 0x00);
+
+ return (int)CHIP_CYRIXmediagx;
+
+ fail:
+ /* Protect MediaGX extended registers */
+ outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
+ outb(vgaIOBase + 5, 0x00);
+ return -1;
+}
+
+static void
+CYRIXProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,index);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+}
+
+/* Mandatory */
+static Bool
+CYRIXPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ MessageType from;
+ CYRIXPrvPtr pCyrix;
+ int videoram;
+ int i;
+ ClockRangePtr clockRanges;
+ CARD32 physbase, padsize;
+ int CYRIXisOldChipRevision;
+ int device_step, device_revision;
+ int vgaIOBase;
+ unsigned char gcr;
+ static int accelWidths[3]= {2,1024, 2048};
+ const char *s;
+
+ /* Allocate the CYRIXRec driverPrivate */
+ if (!CYRIXGetRec(pScrn)) return FALSE;
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+ pCyrix = CYRIXPTR(pScrn);
+
+ pCyrix->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ if (pCyrix->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ if (flags & PROBE_DETECT) {
+ CYRIXProbeDDC(pScrn, pCyrix->pEnt->index);
+ return TRUE;
+ }
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+
+ /* Unprotect MediaGX extended registers */
+ outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
+ outb(vgaIOBase + 5, 0x57);
+ outb(vgaIOBase + 5, 0x4C);
+
+ outb(GX_IOPORT_INDEX, GX_IOIDX_DIR0); /* doesn't work w/o that */
+ outb(GX_IOPORT_INDEX, GX_IOIDX_GCR);
+ gcr = inb(GX_IOPORT_DATA);
+
+ physbase = (gcr & 3) << 30;
+ padsize = (gcr & 12) ? (((gcr & 12) >> 2) + 1) : 0;
+
+ /* end GGI MediaGX driver based code */
+ if (padsize == 0) return (FALSE);
+
+ xf86ErrorF("%s: GX_BASE: 0x%x\n",CYRIX_NAME, physbase);
+ xf86ErrorF("%s: Scratchpad size: %d kbytes\n",CYRIX_NAME, padsize);
+
+ /* Probe for the MediaGX processor version details. Older versions
+ * use different op-codes for setting the organization of the
+ * blit buffers within the scratch padarea. We currently
+ * also use this version ID to guess whether the chipset has
+ * an external DAC (in which case we treat the colour maps
+ * in a slightly different fashion)
+ */
+ outb(0x22, 0xFF);
+ device_step = device_revision = inb(0x23);
+ device_step >>= 8;
+ device_revision &= 0xFF;
+ xf86ErrorF("%s: MediaGX processor ID %d revision %d\n",
+ CYRIX_NAME, device_step, device_revision);
+
+ CYRIXisOldChipRevision = (device_step == 0 && device_revision < 40);
+
+ /* Some MediaGX systems have different blit buffer offsets than
+ * is indicated by the scratchpad size. Make sure that we have
+ * the right offsets by writing them into the corresponding CPU
+ * registers. The op-codes to use depend on the processor
+ * revision. The value `40' is a guess (awaiting details from Cyrix).
+ */
+ pCyrix->CYRIXbltBufSize = (padsize == 4) ? 1840 : (padsize == 3) ? 1328 : 816;
+ pCyrix->CYRIXbltBuf1Address = 0x0E60 - pCyrix->CYRIXbltBufSize;
+ pCyrix->CYRIXbltBuf0Address = pCyrix->CYRIXbltBuf1Address - pCyrix->CYRIXbltBufSize;
+
+ /* map the entire area from GX_BASE (scratchpad area)
+ up to the end of the control registers */
+ pCyrix->GXregisters = (char*)xf86MapVidMem(pScrn->scrnIndex,
+ VGA_REGION, (int )physbase, 0x9000);
+ if (!pCyrix->GXregisters) {
+ ErrorF("%s: Cannot map hardware registers\n", CYRIX_NAME);
+ return FALSE;
+ }
+
+ /* This is the general case */
+ for (i = 0; i<pScrn->numEntities; i++) {
+ pCyrix->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ if (pCyrix->pEnt->resources) return FALSE;
+ pCyrix->Chipset = pCyrix->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(CYRIXChipsets,
+ pCyrix->pEnt->chipset);
+ }
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 0, 0, Support24bppFb)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /*
+ * The new cmap layer needs this to be initialised.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* We use a programmable clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the CYRIXRec driverPrivate */
+ if (!CYRIXGetRec(pScrn)) {
+ return FALSE;
+ }
+ pCyrix = CYRIXPTR(pScrn);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if (!(pCyrix->Options = xalloc(sizeof(CYRIXOptions))))
+ return FALSE;
+ memcpy(pCyrix->Options, CYRIXOptions, sizeof(CYRIXOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCyrix->Options);
+
+ /* Set the bits per RGB for 8bpp mode */
+ pScrn->rgbBits = 6;
+
+ from = X_DEFAULT;
+ pCyrix->HWCursor = FALSE;
+ if (xf86IsOptionSet(pCyrix->Options, OPTION_HW_CURSOR)) {
+ from = X_CONFIG;
+ pCyrix->HWCursor = TRUE;
+ }
+ if (xf86IsOptionSet(pCyrix->Options, OPTION_SW_CURSOR)) {
+ from = X_CONFIG;
+ pCyrix->HWCursor = FALSE;
+ }
+ if (pCyrix->HWCursor == TRUE)
+ xf86DrvMsg(pScrn->scrnIndex, from, "Hardware cursor is disabled in this release\n");
+
+ if (xf86ReturnOptValBool(pCyrix->Options, OPTION_SHADOW_FB, FALSE)) {
+ pCyrix->ShadowFB = TRUE;
+ pCyrix->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ pCyrix->Rotate = 0;
+ if ((s = xf86GetOptValString(pCyrix->Options, OPTION_ROTATE))) {
+ if(!xf86NameCmp(s, "CW")) {
+ pCyrix->ShadowFB = TRUE;
+ pCyrix->NoAccel = TRUE;
+ pCyrix->HWCursor = FALSE;
+ pCyrix->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise - acceleration disabled\n");
+ } else
+ if(!xf86NameCmp(s, "CCW")) {
+ pCyrix->ShadowFB = TRUE;
+ pCyrix->NoAccel = TRUE;
+ pCyrix->HWCursor = FALSE;
+ pCyrix->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen counter clockwise - acceleration disabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid options are \"CW\" or \"CCW\"\n");
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pCyrix->HWCursor ? "HW" : "SW");
+ if (xf86IsOptionSet(pCyrix->Options, OPTION_NOACCEL)) {
+ pCyrix->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ pCyrix->NoCompress = FALSE;
+ if (xf86IsOptionSet(pCyrix->Options, OPTION_NOCOMPRESS)) {
+ pCyrix->NoCompress = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Compression disabled\n");
+ }
+
+ pCyrix->PciInfo = NULL;
+ pCyrix->RamDac = -1;
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * CYRIXProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pCyrix->Chipset);
+ return FALSE;
+ }
+ if (pCyrix->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+
+ pCyrix->EngineOperation = 0x00;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", pScrn->chipset);
+
+ if (pCyrix->pEnt->device->MemBase != 0) {
+ pCyrix->FbAddress = pCyrix->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ from = X_PROBED;
+ pCyrix->FbAddress = 0x40800000; /* Hard coded for 1st try */
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pCyrix->FbAddress);
+
+ if (pCyrix->pEnt->device->IOBase != 0) {
+ pCyrix->IOAccelAddress = pCyrix->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ from = X_PROBED;
+ pCyrix->IOAccelAddress = 0x40008100; /* Hard coded for 1st try */
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from,"IO registers at 0x%x\n",pCyrix->IOAccelAddress);
+
+ /* HW bpp matches reported bpp */
+ pCyrix->HwBpp = pScrn->bitsPerPixel;
+
+ if (pCyrix->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pCyrix->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ from = X_PROBED;
+ outb(vgaIOBase + 4, CrtcGraphicsMemorySize);
+ videoram = (inb(vgaIOBase + 5) * 64);
+ pScrn->videoRam = videoram & 0xFFFFFC00; /* mask out the part we want */
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pCyrix->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Set the min pixel clock */
+ pCyrix->MinClock = 16250; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pCyrix->MinClock / 1000);
+
+ pCyrix->MaxClock = 135000;
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Max pixel clock is %d MHz\n",
+ pCyrix->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = pCyrix->MinClock;
+ clockRanges->maxClock = pCyrix->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our CYRIXValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+ /*
+ * XXX Assuming min pitch 256, max 2048
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ accelWidths, 256, 2048,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pCyrix->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ CYRIXFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ CYRIXFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ pCyrix->EngineOperation |= 0x00;
+ break;
+ case 16:
+ pCyrix->EngineOperation |= 0x01;
+ break;
+ }
+
+ /* Load fb module */
+ if (xf86LoadSubModule(pScrn, "fb") == NULL) {
+ CYRIXFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ /* Load XAA if needed */
+ if (!pCyrix->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ CYRIXFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+
+ switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
+ case 512:
+ pCyrix->EngineOperation |= 0x00;
+ break;
+ case 1024:
+ pCyrix->EngineOperation |= 0x04;
+ break;
+ case 2048:
+ pCyrix->EngineOperation |= 0x08;
+ break;
+ }
+ }
+
+ /* Load shadowfb if needed */
+ if (pCyrix->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ CYRIXFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+CYRIXSave(ScrnInfoPtr pScrn)
+{
+ vgaRegPtr vgaReg;
+ CYRIXPrvPtr pCyrix;
+ CYRIXRegPtr cyrixReg;
+
+ pCyrix = CYRIXPTR(pScrn);
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ cyrixReg = &pCyrix->SavedReg;
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+ CyrixSave(pScrn, cyrixReg);
+ CYRIXSavePalette(pScrn);
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+CYRIXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int ret = -1;
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ CYRIXPrvPtr pCyrix;
+ CYRIXRegPtr cyrixReg;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWUnlock(hwp);
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ pCyrix = CYRIXPTR(pScrn);
+
+ /* Do the guts of this work */
+ ret = CyrixInit(pScrn, mode);
+
+ if (!ret)
+ return FALSE;
+
+ /* Program the registers */
+ vgaReg = &hwp->ModeReg;
+ cyrixReg = &pCyrix->ModeReg;
+
+ CyrixRestore(pScrn, cyrixReg);
+/* vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);*/
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+CYRIXRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ CYRIXPrvPtr pCyrix;
+ CYRIXRegPtr cyrixReg;
+
+ hwp = VGAHWPTR(pScrn);
+ pCyrix = CYRIXPTR(pScrn);
+ vgaReg = &hwp->SavedReg;
+ cyrixReg = &pCyrix->SavedReg;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ /*CyrixRestore(pScrn, cyrixReg);*/
+ CYRIXRestorePalette(pScrn);
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+
+ vgaHWProtect(pScrn, FALSE);
+}
+
+/* Needed because we are not VGA enough in all cases (eg 5530 LCD) */
+
+static void
+CYRIXLoadPalette(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indices,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ int i;
+ unsigned int locked;
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+
+ switch(pScrn->depth) {
+ case 15:
+ case 16:
+ return;
+ }
+
+ locked = GX_REG(DC_UNLOCK);
+ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+
+ for(i = 0; i < numColors; i++) {
+ unsigned int red, green, blue;
+ int index = indices[i];
+
+ red = colors[index].red;
+ green = colors[index].green;
+ blue = colors[index].blue;;
+
+ GX_REG(DC_PAL_ADDRESS) = index;
+ GX_REG(DC_PAL_DATA) = (red << 12) | (green << 6) | blue;
+ }
+ GX_REG(DC_UNLOCK) = locked;
+}
+
+static void CYRIXSavePalette(ScrnInfoPtr pScrn)
+{
+ int i;
+ unsigned int locked;
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+
+ locked = GX_REG(DC_UNLOCK);
+ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+
+ for(i = 0; i < 256; i++) {
+ GX_REG(DC_PAL_ADDRESS) = i;
+ pCyrix->SavedReg.Colormap[i] = GX_REG(DC_PAL_DATA);
+ }
+ GX_REG(DC_UNLOCK) = locked;
+}
+
+static void CYRIXRestorePalette(ScrnInfoPtr pScrn)
+{
+ int i;
+ unsigned int locked;
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+
+ locked = GX_REG(DC_UNLOCK);
+ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+
+ for(i = 0; i < 256; i++) {
+ GX_REG(DC_PAL_ADDRESS) = i;
+ GX_REG(DC_PAL_DATA) = pCyrix->SavedReg.Colormap[i];
+ }
+ GX_REG(DC_UNLOCK) = locked;
+}
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+CYRIXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* The vgaHW references will disappear one day */
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ CYRIXPrvPtr pCyrix;
+ int ret;
+ VisualPtr visual;
+ int width, height, displayWidth;
+ unsigned char *FBStart;
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ hwp = VGAHWPTR(pScrn);
+
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+
+ pCyrix = CYRIXPTR(pScrn);
+
+ /* Map the VGA memory, frambuffer, and get the VGA IO base */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ vgaHWGetIOBase(hwp);
+ pCyrix->FbBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ (unsigned long)pCyrix->FbAddress, pCyrix->FbMapSize);
+
+ /* Save the current state */
+ CYRIXSave(pScrn);
+
+ /* Initialise the first mode */
+ CYRIXModeInit(pScrn, pScrn->currentMode);
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ CYRIXSaveScreen(pScreen, SCREEN_SAVER_ON);
+ CYRIXAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ /* XXX Fill the screen with black */
+#if 0
+ CYRIXSaveScreen(pScreen, SCREEN_SAVER_OFF);
+#endif
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ */
+
+ /*
+ * Reset visual list.
+ */
+ if (pScrn->bitsPerPixel >= 8) miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!xf86SetDefaultVisual(pScrn, -1))
+ return FALSE;
+
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ miSetPixmapDepths ();
+
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ displayWidth = pScrn->displayWidth;
+
+
+ if(pCyrix->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ }
+
+ if(pCyrix->ShadowFB) {
+ pCyrix->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pCyrix->ShadowPtr = xalloc(pCyrix->ShadowPitch * height);
+ displayWidth = pCyrix->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pCyrix->ShadowPtr;
+ } else {
+ pCyrix->ShadowPtr = NULL;
+ FBStart = pCyrix->FbBase;
+ }
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ case 16:
+ ret = fbScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth, pScrn->bitsPerPixel);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in CYRIXScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ } else if (pScrn->depth == 1) {
+ Cyrix1bppColorMap(pScrn);
+ }
+
+ /* must be after RGB ordering fixed */
+ fbPictureInit (pScreen, 0, 0);
+
+ if (pScrn->depth < 8) {
+ miBankInfoPtr pBankInfo;
+
+ /* Setup the vga banking variables */
+ pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1);
+ if (pBankInfo == NULL)
+ return FALSE;
+
+ pBankInfo->pBankA = hwp->Base;
+ pBankInfo->pBankB = hwp->Base;
+ pBankInfo->BankSize = 0x10000;
+ pBankInfo->nBankDepth = pScrn->depth;
+ xf86EnableAccess(pScrn);
+
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CYRIXSetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CYRIXSetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CYRIXSetReadWrite;
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo)) {
+ xfree(pBankInfo);
+ pBankInfo = NULL;
+ return FALSE;
+ }
+ }
+
+ if (!pCyrix->NoAccel)
+ CYRIXAccelInit(pScreen);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ xf86SetSilkenMouse(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
+ CYRIXLoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)CYRIXDisplayPowerManagementSet, 0);
+
+ pScrn->memPhysBase = pCyrix->FbAddress;
+ pScrn->fbOffset = 0;
+
+ if(pCyrix->ShadowFB) {
+ RefreshAreaFuncPtr refreshArea = CYRIXRefreshArea;
+
+ if(pCyrix->Rotate) {
+ if (!pCyrix->PointerMoved) {
+ pCyrix->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = CYRIXPointerMoved;
+ }
+
+ switch(pScrn->bitsPerPixel) {
+ case 8: refreshArea = CYRIXRefreshArea8; break;
+ case 16: refreshArea = CYRIXRefreshArea16; break;
+ }
+ }
+
+ ShadowFBInit(pScreen, refreshArea);
+ }
+
+ pCyrix->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = CYRIXCloseScreen;
+ pScreen->SaveScreen = CYRIXSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+static Bool
+CYRIXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return CYRIXModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/* Usually mandatory */
+static void
+CYRIXAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp;
+ CYRIXPrvPtr pCyrix;
+ int base = y * pScrn->displayWidth + x;
+ unsigned char temp;
+ int vgaIOBase;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaIOBase = hwp->IOBase;
+ pCyrix = CYRIXPTR(pScrn);
+
+ switch (pScrn->bitsPerPixel) {
+ case 4:
+/* base /= 2; */
+ base = base >> 4;
+ break;
+ case 8:
+ base = (base & 0xFFFFFFF8) >> 2;
+ break;
+ case 16:
+/* base *= (pScrn->bitsPerPixel / 8); */
+ base /= 2;
+ break;
+ }
+
+ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+
+ /* If you switch to poking FB_ST_OFFSET directly it expects to be
+ fed different values to the SoftVGA emulation code */
+
+ /*GX_REG(DC_FB_ST_OFFSET) = base; */
+ /* CRT bits 0-15 */
+ outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
+ outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
+ /* CRT bit 16 */
+ outb(vgaIOBase + 4, 0x1E); temp = inb(vgaIOBase + 5) & 0xDF;
+ outb(vgaIOBase + 5, temp | (base & 0x10000) >> 11);
+ GX_REG(DC_UNLOCK) = 0;
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+CYRIXEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ /* Should we re-save the text mode on each VT enter? */
+ if (!CYRIXModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+CYRIXLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ CYRIXRestore(pScrn);
+ vgaHWLock(hwp);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ */
+
+/* Mandatory */
+static Bool
+CYRIXCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CYRIXPrvPtr pCyrix;
+
+ if (pScrn->vtSema) {
+ CYRIXRestore(pScrn);
+ vgaHWLock(hwp);
+ }
+ pCyrix = CYRIXPTR(pScrn);
+ if(pCyrix->AccelInfoRec)
+ XAADestroyInfoRec(pCyrix->AccelInfoRec);
+ if (pCyrix->ShadowPtr)
+ xfree(pCyrix->ShadowPtr);
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pCyrix->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+CYRIXFreeScreen(int scrnIndex, int flags)
+{
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ CYRIXFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+CYRIXValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ return(MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+CYRIXSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
diff --git a/src/cyrix_helper.c b/src/cyrix_helper.c
new file mode 100644
index 0000000..22c46a2
--- /dev/null
+++ b/src/cyrix_helper.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2000 by Richard A. Hecker, California, United States
+ * Copyright 2002 by Red Hat Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Richard Hecker not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Richard Hecker makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * RICHARD HECKER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RICHARD HECKER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Richard Hecker, hecker@cat.dfrc.nasa.gov
+ * Re-written for XFree86 v4.0
+ *
+ * Chunks re-written again for XFree86 v4.2
+ * Alan Cox <alan@redhat.com>
+ *
+ * Previous driver (pre-XFree86 v4.0) 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_helper.c,v 1.4 2002/11/06 11:38:59 alanh Exp $ */
+
+#include "cyrix.h"
+#include "vgaHW.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#define CYRIXmarkLinesDirty { \
+ int k = 0; \
+ while (k < 1024) { \
+ GX_REG(MC_DR_ADD) = k++; \
+ GX_REG(MC_DR_ACC) = 0; \
+ } \
+ }
+
+static void CYRIXresetVGA(ScrnInfoPtr pScrn, unsigned long vgaIOBase);
+
+void Cyrix1bppColorMap(ScrnInfoPtr pScrn)
+{ /* use dedicated color map routines on new chipsets in 8bpp */
+ ErrorF("%s: Cyrix 1BPP is only a stub for now.\n", X_PROBED);
+ return;
+}
+
+
+int CyrixHWCursor(ScreenPtr pScreen)
+{
+ return 1024;
+}
+
+void CyrixRestore(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg)
+{
+ unsigned char temp;
+ CYRIXPrvPtr pCyrix;
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ unsigned long vgaIOBase;
+
+ vgaHWProtect(pScrn, TRUE); /* Blank the screen */
+ pCyrix = CYRIXPTR(pScrn);
+/* vgaReg = &VGAHWPTR(pScrn)->SavedReg; */
+ hwp = VGAHWPTR(pScrn);
+ vgaHWUnlock(hwp);
+ vgaReg = &hwp->ModeReg;
+
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* restore standard VGA portion */
+ outb(vgaIOBase + 4, CrtcModeSwitchControl);
+ outb(vgaIOBase + 5, 0x01);
+ CYRIXresetVGA(pScrn,vgaIOBase);
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+
+ vgaHWProtect(pScrn, TRUE); /* Blank the screen */
+
+ CYRIXmarkLinesDirty;
+
+ /* restore miscellaneous output registers */
+ outb(0x3C2, vgaReg->MiscOutReg);
+
+ /* restore SoftVGA extended registers */
+ outb(vgaIOBase + 4, CrtcDriverControl);
+ temp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, (pCyrix->PrevExt.DriverControl & 0x01)
+ | (temp & 0xfe));
+
+ outb(vgaIOBase + 4, CrtcVerticalTimingExtension);
+ temp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, (pCyrix->PrevExt.VerticalTimingExtension & 0x55)
+ | (temp & 0xaa));
+
+ outb(vgaIOBase + 4, CrtcExtendedAddressControl);
+ temp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, (pCyrix->PrevExt.ExtendedAddressControl & 0x07)
+ | (temp & 0xf8));
+
+ outb(vgaIOBase + 4, 19);
+ outb(vgaIOBase + 5, pCyrix->PrevExt.Offset);
+
+ outb(vgaIOBase + 4, CrtcExtendedOffset);
+ temp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, ((pCyrix->PrevExt.ExtendedOffset) & 0x03)
+ | (temp & 0xfc));
+
+ outb(vgaIOBase + 4, CrtcExtendedColorControl);
+ temp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, (pCyrix->PrevExt.ExtendedColorControl & 0x07)
+ | (temp & 0xf8));
+
+ outb(vgaIOBase + 4, CrtcDisplayCompression);
+ temp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, (pCyrix->PrevExt.DisplayCompression & 0x0f)
+ | (temp & 0xf0));
+
+ outb(vgaIOBase + 4, CrtcDACControl);
+ temp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, (pCyrix->PrevExt.DACControl & 0x0e)
+ | (temp & 0xf1));
+
+ outb(vgaIOBase + 4, CrtcModeSwitchControl);
+ outb(vgaIOBase + 5, 0x00);
+
+ /* 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 | DC_GCFG_FBLC | DC_GCFG_CURE)
+#define GPBS_MASK (BC_16BPP | BC_FB_WIDTH_2048)
+
+ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+
+ GX_REG(DC_CURS_ST_OFFSET) = pCyrix->PrevExt.DcCursStOffset;
+ GX_REG(DC_CB_ST_OFFSET) = pCyrix->PrevExt.DcCbStOffset;
+ GX_REG(DC_LINE_DELTA) = (GX_REG(DC_LINE_DELTA) & 0xFFC00FFF)
+ | (pCyrix->PrevExt.DcLineDelta & 0x003FF000);
+ GX_REG(DC_BUF_SIZE) = (GX_REG(DC_BUF_SIZE) & 0xFFFF01FF)
+ | (pCyrix->PrevExt.DcBufSize & 0x0000FE00);
+ GX_REG(DC_CURSOR_X) = pCyrix->PrevExt.DcCursorX;
+ GX_REG(DC_CURSOR_Y) = pCyrix->PrevExt.DcCursorY;
+ GX_REG(DC_CURSOR_COLOR) = pCyrix->PrevExt.DcCursorColor;
+
+ GX_REG(DC_GENERAL_CFG) = (GX_REG(DC_GENERAL_CFG) & (~DCFG_MASK))
+ | (pCyrix->PrevExt.DcGeneralCfg & DCFG_MASK);
+
+ GX_REG(DC_UNLOCK) = 0;
+
+ GX_REG(GP_BLIT_STATUS) = (GX_REG(GP_BLIT_STATUS) & (~GPBS_MASK))
+ | (pCyrix->PrevExt.GpBlitStatus & GPBS_MASK);
+
+#endif
+
+ vgaHWProtect(pScrn, FALSE); /* Turn on screen */
+}
+
+void *
+CyrixSave(ScrnInfoPtr pScrn, CYRIXRegPtr cyrixReg)
+{
+ CYRIXPrvPtr pCyrix;
+ vgaRegPtr vgaReg;
+ unsigned long vgaIOBase;
+
+#ifndef MONOVGA
+ /* If we don't turn on the screen we end up restoring a
+ blanked display on some boxes whose APM is a bit too smart.
+ Save the display turned -on- therefore */
+
+ vgaHWProtect(pScrn, FALSE); /* Turn on screen */
+
+ /* save graphics pipeline registers */
+ pCyrix = CYRIXPTR(pScrn);
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ pCyrix->PrevExt.GpBlitStatus = GX_REG(GP_BLIT_STATUS);
+
+ /* save miscellaneous output registers */
+ vgaReg->MiscOutReg = inb(0x3CC);
+
+ /* save graphics pipeline registers */
+ GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
+ pCyrix->PrevExt.DcGeneralCfg = GX_REG(DC_GENERAL_CFG);
+ pCyrix->PrevExt.DcCursStOffset = GX_REG(DC_CURS_ST_OFFSET);
+ pCyrix->PrevExt.DcCbStOffset = GX_REG(DC_CB_ST_OFFSET);
+ pCyrix->PrevExt.DcLineDelta = GX_REG(DC_LINE_DELTA);
+ pCyrix->PrevExt.DcBufSize = GX_REG(DC_BUF_SIZE);
+ pCyrix->PrevExt.DcCursorX = GX_REG(DC_CURSOR_X);
+ pCyrix->PrevExt.DcCursorY = GX_REG(DC_CURSOR_Y);
+ pCyrix->PrevExt.DcCursorColor = GX_REG(DC_CURSOR_COLOR);
+ GX_REG(DC_UNLOCK) = 0;
+
+#endif
+
+ /* save SoftVGA pCyrix->PrevExt.nded registers */
+ outb(vgaIOBase + 4, CrtcVerticalTimingExtension);
+ pCyrix->PrevExt.VerticalTimingExtension = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcExtendedAddressControl);
+ pCyrix->PrevExt.ExtendedAddressControl = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, 19);
+ pCyrix->PrevExt.Offset = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcExtendedOffset);
+ pCyrix->PrevExt.ExtendedOffset = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcExtendedColorControl);
+ pCyrix->PrevExt.ExtendedColorControl = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcDisplayCompression);
+ pCyrix->PrevExt.DisplayCompression = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcDriverControl);
+ pCyrix->PrevExt.DriverControl = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcDACControl);
+ pCyrix->PrevExt.DACControl = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcClockControl);
+ pCyrix->PrevExt.ClockControl = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcClockFrequency);
+ pCyrix->PrevExt.CrtClockFrequency = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcClockFrequencyFraction);
+ pCyrix->PrevExt.CrtClockFrequencyFraction = inb(vgaIOBase + 5);
+
+ outb(vgaIOBase + 4, CrtcRefreshRate);
+ pCyrix->PrevExt.RefreshRate = inb(vgaIOBase + 5);
+
+ /* save standard VGA portion */
+ CYRIXresetVGA(pScrn,vgaIOBase);
+
+ return((void *)vgaIOBase);
+}
+
+
+Bool
+CyrixInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ CYRIXPrvPtr pCyrix;
+ int offset_shift = (pScrn->bitsPerPixel == 16) ? 2 :
+ (pScrn->bitsPerPixel == 8) ? 3 : 4;
+ int line_offset = pScrn->displayWidth >> offset_shift;
+
+ pCyrix = CYRIXPTR(pScrn);
+
+ /* initialize standard VGA portion */
+ if (!vgaHWInit(pScrn, mode))
+ return(FALSE);
+
+ /* initialize SoftVGA extended registers */
+ pCyrix->PrevExt.VerticalTimingExtension =
+ ((mode->CrtcVSyncStart & 0x400) >> 4) |
+ (((mode->CrtcVDisplay - 1) & 0x400) >> 8) |
+ (((mode->CrtcVTotal - 2) & 0x400) >> 10) |
+ ((mode->CrtcVSyncStart & 0x400) >> 6);
+
+ if (pScrn->bitsPerPixel < 8)
+ pCyrix->PrevExt.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER;
+ else
+ pCyrix->PrevExt.ExtendedAddressControl = EAC_DIRECT_FRAME_BUFFER |
+ EAC_PACKED_CHAIN4;
+
+ pCyrix->PrevExt.ExtendedOffset = ((line_offset >> 8) & 0x03);
+ pCyrix->PrevExt.Offset = line_offset;
+
+ pCyrix->PrevExt.ExtendedColorControl = (pScrn->bitsPerPixel == 16)
+ ? ECC_16BPP | ECC_565_FORMAT
+ : ECC_8BPP;
+
+ /* display compression is set using the DC registers */
+ pCyrix->PrevExt.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 (pScrn->bitsPerPixel < 8)
+ pCyrix->PrevExt.DriverControl = 0x00;
+ else
+ pCyrix->PrevExt.DriverControl = DRVCT_DISPLAY_DRIVER_ACTIVE;
+
+ /* set `16 bit bus' or else compression will hang the
+ system in 16bpp mode */
+ if (pScrn->bitsPerPixel == 16)
+ pCyrix->PrevExt.DACControl = DACCT_ENABLE_16BIT_BUS;
+ else
+ pCyrix->PrevExt.DACControl = 0;
+
+
+#ifndef MONOVGA
+ /* initialize masked contents of display controller
+ hardware registers. */
+ pCyrix->PrevExt.DcCursStOffset = pCyrix->CYRIXcursorAddress;
+ pCyrix->PrevExt.DcLineDelta = 0 << 12;
+ pCyrix->PrevExt.DcBufSize = 0x41 << 9;
+ pCyrix->PrevExt.DcCursorX = 0;
+ pCyrix->PrevExt.DcCursorY = 0;
+ pCyrix->PrevExt.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 (pCyrix->NoCompress == FALSE &&
+ mode->CrtcVDisplay == pScrn->virtualY &&
+ mode->CrtcHDisplay == pScrn->virtualX &&
+ 0 == GX_REG(DC_FB_ST_OFFSET))
+ {
+ pCyrix->PrevExt.DcGeneralCfg = DC_GCFG_DECE | DC_GCFG_CMPE;
+ if (/* pScrn->bitsPerPixel != 8 || -- this is OK now */
+ (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) & 0x03FF)
+ pCyrix->PrevExt.DcGeneralCfg |= DC_GCFG_FDTY;
+ }
+ else
+ pCyrix->PrevExt.DcGeneralCfg = 0;
+
+
+ /* initialize the graphics pipeline registers */
+ pCyrix->PrevExt.GpBlitStatus = ((pScrn->displayWidth == 2048) ?
+ BC_FB_WIDTH_2048 : BC_FB_WIDTH_1024) |
+ ((pScrn->bitsPerPixel == 16) ?
+ BC_16BPP : BC_8BPP);
+#endif
+
+ return(TRUE);
+}
+
+
+static void
+CYRIXresetVGA(ScrnInfoPtr pScrn, unsigned long vgaIOBase)
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ 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 */
+ 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);
+}
diff --git a/src/cyrix_shadow.c b/src/cyrix_shadow.c
new file mode 100644
index 0000000..479ad36
--- /dev/null
+++ b/src/cyrix_shadow.c
@@ -0,0 +1,155 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_shadow.c,v 1.1 2002/11/06 11:38:59 alanh Exp $ */
+
+/*
+ Copyright (c) 1999, The XFree86 Project Inc.
+ Written by Mark Vojkovich <markv@valinux.com>
+*/
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "cyrix.h"
+#include "shadowfb.h"
+#include "servermd.h"
+
+
+
+void
+CYRIXRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pCyrix->ShadowPtr + (pbox->y1 * pCyrix->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pCyrix->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pCyrix->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+CYRIXPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ int newX, newY;
+
+ if(pCyrix->Rotate == 1) {
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ }
+
+ (*pCyrix->PointerMoved)(index, newX, newY);
+}
+
+void
+CYRIXRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pCyrix->Rotate * pCyrix->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(pCyrix->Rotate == 1) {
+ dstPtr = pCyrix->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = pCyrix->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = pCyrix->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = pCyrix->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[srcPitch * 3] << 24);
+ src += srcPitch * 4;
+ }
+ srcPtr += pCyrix->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+CYRIXRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pCyrix->Rotate * pCyrix->ShadowPitch >> 1;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~1;
+ y2 = (pbox->y2 + 1) & ~1;
+ height = (y2 - y1) >> 1; /* in dwords */
+
+ if(pCyrix->Rotate == 1) {
+ dstPtr = (CARD16*)pCyrix->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)pCyrix->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)pCyrix->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)pCyrix->ShadowPtr +
+ (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 16);
+ src += srcPitch * 2;
+ }
+ srcPtr += pCyrix->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+