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
commit677304545d45d78574e4252fa1c572e7861f1a73 (patch)
treeb0f632cd4ffdf05d02c187f60981fddda17a5390
parentb077108c744cf66a1276f896513180f53573035c (diff)
Initial revisionXORG-STABLE
-rw-r--r--src/BT463ramdac.c140
-rw-r--r--src/BTramdac.c178
-rw-r--r--src/IBM561ramdac.c735
-rw-r--r--src/ICS1562.c114
-rw-r--r--src/tga.h219
-rw-r--r--src/tga_accel.c1569
-rw-r--r--src/tga_cursor.c185
-rw-r--r--src/tga_dac.c846
-rw-r--r--src/tga_driver.c1766
-rw-r--r--src/tga_line.c629
-rw-r--r--src/tga_regs.h217
11 files changed, 6598 insertions, 0 deletions
diff --git a/src/BT463ramdac.c b/src/BT463ramdac.c
new file mode 100644
index 0000000..44d1f24
--- /dev/null
+++ b/src/BT463ramdac.c
@@ -0,0 +1,140 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/BT463ramdac.c,v 1.1 1998/08/29 05:43:34 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "BT.h"
+#include "tga_regs.h"
+#include "tga.h"
+
+
+#define BT463_LOAD_ADDR(a) \
+ TGA_WRITE_REG(BT463_ADDR_LO<<2, TGA_RAMDAC_SETUP_REG); \
+ TGA_WRITE_REG((BT463_ADDR_LO<<10)|((a)&0xff), TGA_RAMDAC_REG); \
+ TGA_WRITE_REG(BT463_ADDR_HI<<2, TGA_RAMDAC_SETUP_REG); \
+ TGA_WRITE_REG((BT463_ADDR_HI<<10)|(((a)>>8)&0xff), TGA_RAMDAC_REG);
+
+#define BT463_WRITE(m,a,v) \
+ BT463_LOAD_ADDR((a)); \
+ TGA_WRITE_REG(((m)<<2),TGA_RAMDAC_SETUP_REG); \
+ TGA_WRITE_REG(((m)<<10)|((v)&0xff),TGA_RAMDAC_REG);
+
+/*
+ * useful defines for managing the BT463 on the 24-plane TGAs
+ */
+#define BT463_READ_BIT 0x2
+
+#define BT463_ADDR_LO 0x0
+#define BT463_ADDR_HI 0x1
+#define BT463_REG_ACC 0x2
+#define BT463_PALETTE 0x3
+
+#define BT463_CUR_CLR_0 0x0100
+#define BT463_CUR_CLR_1 0x0101
+
+#define BT463_CMD_REG_0 0x0201
+#define BT463_CMD_REG_1 0x0202
+#define BT463_CMD_REG_2 0x0203
+
+#define BT463_READ_MASK_0 0x0205
+#define BT463_READ_MASK_1 0x0206
+#define BT463_READ_MASK_2 0x0207
+#define BT463_READ_MASK_3 0x0208
+
+#define BT463_BLINK_MASK_0 0x0209
+#define BT463_BLINK_MASK_1 0x020a
+#define BT463_BLINK_MASK_2 0x020b
+#define BT463_BLINK_MASK_3 0x020c
+
+#define BT463_WINDOW_TYPE_BASE 0x0300
+
+
+static unsigned
+BT463_READ(TGAPtr pTga, unsigned m, unsigned a)
+{
+ unsigned val;
+
+ BT463_LOAD_ADDR(a);
+ TGA_WRITE_REG((m<<2)|0x2, TGA_RAMDAC_SETUP_REG);
+ val = TGA_READ_REG(TGA_RAMDAC_REG);
+ val = (val >> 16) & 0xff;
+ return val;
+}
+
+
+void
+BT463ramdacSave(ScrnInfoPtr pScrn, unsigned char *Bt463)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ int i, j;
+
+ Bt463[0] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_0);
+ Bt463[1] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_1);
+ Bt463[2] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_2);
+
+ Bt463[3] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_0);
+ Bt463[4] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_1);
+ Bt463[5] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_2);
+ Bt463[6] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_3);
+
+ Bt463[7] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_0);
+ Bt463[8] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_1);
+ Bt463[9] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_2);
+ Bt463[10] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_3);
+
+ BT463_LOAD_ADDR(BT463_WINDOW_TYPE_BASE);
+ TGA_WRITE_REG((BT463_REG_ACC<<2)|0x2, TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0, j = 11; i < 16; i++) {
+ Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ }
+
+/*
+ fprintf(stderr, "BT463ramdacSave (%p)\n", Bt463);
+ for (i=0; i<58; i++)
+ fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Bt463[i]);
+*/
+}
+
+
+void
+BT463ramdacRestore(ScrnInfoPtr pScrn, unsigned char *Bt463)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ int i, j;
+
+ BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_0, Bt463[0]);
+ BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_1, Bt463[1]);
+ BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_2, Bt463[2]);
+
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_0, Bt463[3]);
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_1, Bt463[4]);
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_2, Bt463[5]);
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_3, Bt463[6]);
+
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_0, Bt463[7]);
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_1, Bt463[8]);
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_2, Bt463[9]);
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_3, Bt463[10]);
+
+ BT463_LOAD_ADDR(BT463_WINDOW_TYPE_BASE);
+ TGA_WRITE_REG((BT463_REG_ACC<<2), TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0, j = 11; i < 16; i++) {
+ TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+ }
+
+/*
+ fprintf(stderr, "BT463ramdacRestore (%p)\n", Bt463);
+ for (i=0; i<58; i++)
+ fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Bt463[i]);
+*/
+}
diff --git a/src/BTramdac.c b/src/BTramdac.c
new file mode 100644
index 0000000..c2aa06a
--- /dev/null
+++ b/src/BTramdac.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * 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.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * tgaBTOutIndReg() and tgaBTInIndReg() are used to access
+ * the indirect TGA BT RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/BTramdac.c,v 1.5 2000/10/20 12:57:26 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "tga_regs.h"
+#include "BT.h"
+#include "tga.h"
+
+void
+tgaBTOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data)
+{
+ TGAPtr pTga;
+ unsigned char tmp = 0x00;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(reg << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG);
+
+ if (mask != 0x00)
+ tmp = (TGA_READ_REG(TGA_RAMDAC_REG)>>16) & mask;
+
+ TGA_WRITE_REG(reg << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+
+ TGA_WRITE_REG ((tmp | data) | (reg<<9), TGA_RAMDAC_REG);
+}
+
+unsigned char
+tgaBTInIndReg (ScrnInfoPtr pScrn, CARD32 reg)
+{
+ TGAPtr pTga;
+ unsigned char ret;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(reg << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG);
+ ret = TGA_READ_REG (TGA_RAMDAC_REG)>>16;
+
+ return (ret);
+}
+
+void
+tgaBTWriteAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(BT_WRITE_ADDR << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(index | (BT_WRITE_ADDR<<9), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(BT_RAMDAC_DATA << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+}
+
+void
+tgaBTWriteData (ScrnInfoPtr pScrn, unsigned char data)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(data | (BT_RAMDAC_DATA << 9), TGA_RAMDAC_REG);
+}
+
+void
+tgaBTReadAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(BT_PIXEL_MASK << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(0xFF | (BT_PIXEL_MASK<<9), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(BT_READ_ADDR << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(index | (BT_READ_ADDR<<9), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(BT_RAMDAC_DATA << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG);
+}
+
+unsigned char
+tgaBTReadData (ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ return(TGA_READ_REG(TGA_RAMDAC_REG)>>16);
+}
+
+/********************* TGA2 stuff below here ********************/
+
+void
+tga2BTOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data)
+{
+ TGAPtr pTga;
+ unsigned char tmp = 0x00;
+ unsigned int addr = 0xe000U | (reg << 8);
+
+ pTga = TGAPTR(pScrn);
+
+ if (mask != 0x00)
+ tmp = TGA2_READ_RAMDAC_REG(addr) & mask;
+
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "tga2OutIndReg: reg 0x%x data 0x%x\n",
+ reg, tmp|data);
+#endif
+ TGA2_WRITE_RAMDAC_REG ((tmp | data), addr);
+}
+
+unsigned char
+tga2BTInIndReg (ScrnInfoPtr pScrn, CARD32 reg)
+{
+ TGAPtr pTga;
+ unsigned char ret;
+ unsigned int addr = 0xe000U | (reg << 8);
+
+ pTga = TGAPTR(pScrn);
+
+ ret = TGA2_READ_RAMDAC_REG(addr);
+
+ return (ret);
+}
+
+void
+tga2BTWriteAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ tga2BTOutIndReg(pScrn, BT_WRITE_ADDR, 0, index);
+}
+
+void
+tga2BTWriteData (ScrnInfoPtr pScrn, unsigned char data)
+{
+ tga2BTOutIndReg(pScrn, BT_RAMDAC_DATA, 0, data);
+}
+
+void
+tga2BTReadAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ tga2BTOutIndReg(pScrn, BT_PIXEL_MASK, 0, 0xff);
+ tga2BTOutIndReg(pScrn, BT_READ_ADDR, 0, index);
+}
+
+unsigned char
+tga2BTReadData (ScrnInfoPtr pScrn)
+{
+ return tga2BTInIndReg(pScrn, BT_RAMDAC_DATA);
+}
diff --git a/src/IBM561ramdac.c b/src/IBM561ramdac.c
new file mode 100644
index 0000000..2ddfb08
--- /dev/null
+++ b/src/IBM561ramdac.c
@@ -0,0 +1,735 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/IBM561ramdac.c,v 1.3 2001/02/15 11:03:58 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "tga_regs.h"
+#include "tga.h"
+
+/*
+ * useful defines for managing the IBM561 on the 24-plane TGA2s
+ */
+
+#define IBM561_HEAD_MASK 0x01
+#define IBM561_READ 0x02
+#define IBM561_WRITE 0x00
+
+#define RAMDAC_ONE_BYTE 0x0E000
+#define RAMDAC_TWO_BYTES 0x0c000
+#define RAMDAC_THREE_BYTES 0x08000
+#define RAMDAC_FOUR_BYTES 0x00000
+
+#define IBM561_ADDR_LOW 0x0000
+#define IBM561_ADDR_HIGH 0x0100
+#define IBM561_CMD_REGS 0x0200
+
+#define IBM561_CMD_CURS_PIX 0x0200
+#define IBM561_CMD_CURS_LUT 0x0300
+#define IBM561_CMD_FB_WAT 0x0300
+#define IBM561_CMD_AUXFB_WAT 0x0200
+#define IBM561_CMD_OL_WAT 0x0300
+#define IBM561_CMD_AUXOL_WAT 0x0200
+#define IBM561_CMD_GAMMA 0x0300
+#define IBM561_CMD_CMAP 0x0300
+
+#define IBM561_ADDR_EPSR_SHIFT 0
+#define IBM561_ADDR_EPDR_SHIFT 8
+
+#define IBM561_CONFIG_REG_1 0x0001
+#define IBM561_CONFIG_REG_2 0x0002
+#define IBM561_CONFIG_REG_1 0x0001
+#define IBM561_CONFIG_REG_2 0x0002
+#define IBM561_CONFIG_REG_3 0x0003
+#define IBM561_CONFIG_REG_4 0x0004
+#define IBM561_WAT_SEG_REG 0x0006
+#define IBM561_OL_SEG_REG 0x0007
+#define IBM561_CHROMA_KEY_REG0 0x0010
+#define IBM561_CHROMA_KEY_REG1 0x0011
+#define IBM561_CHROMA_MASK_REG0 0x0012
+#define IBM561_CHROMA_MASK_REG1 0x0013
+#define IBM561_SYNC_CONTROL 0x0020
+#define IBM561_PLL_VCO_DIV_REG 0x0021
+#define IBM561_PLL_REF_REG 0x0022
+#define IBM561_CURSOR_CTRL_REG 0x0030
+#define IBM561_CURSOR_HS_REG 0x0034
+#define IBM561_VRAM_MASK_REG 0x0050
+#define IBM561_DAC_CTRL 0x005f
+#define IBM561_DIV_DOT_CLK_REG 0x0082
+
+#define IBM561_READ_MASK 0x0205
+#define IBM561_BLINK_MASK 0x0209
+#define IBM561_FB_WINDOW_TYPE_TABLE 0x1000
+#define IBM561_AUXFB_WINDOW_TYPE_TABLE 0x0E00
+#define IBM561_OL_WINDOW_TYPE_TABLE 0x1400
+#define IBM561_AUXOL_WINDOW_TYPE_TABLE 0x0F00
+#define IBM561_RED_GAMMA_TABLE 0x3000
+#define IBM561_GREEN_GAMMA_TABLE 0x3400
+#define IBM561_BLUE_GAMMA_TABLE 0x3800
+#define IBM561_COLOR_LOOKUP_TABLE 0x4000
+#define IBM561_CURSOR_LOOKUP_TABLE 0x0a11
+#define IBM561_CURSOR_BLINK_TABLE 0x0a15
+#define IBM561_CROSS_LOOKUP_TABLE 0x0a19
+#define IBM561_CROSS_BLINK_TABLE 0x0a1d
+#define IBM561_CURSOR_PIXMAP 0x2000
+#define IBM561_CURSOR_X_LOW 0x0036
+#define IBM561_CURSOR_X_HIGH 0x0037
+#define IBM561_CURSOR_Y_LOW 0x0038
+#define IBM561_CURSOR_Y_HIGH 0x0039
+
+#define LO_ADDR (IBM561_ADDR_LOW | RAMDAC_ONE_BYTE)
+#define HI_ADDR (IBM561_ADDR_HIGH | RAMDAC_ONE_BYTE)
+
+#define REGS_ADDR (IBM561_CMD_REGS | RAMDAC_ONE_BYTE)
+#define FBWAT_ADDR (IBM561_CMD_FB_WAT | RAMDAC_ONE_BYTE)
+#define AUXFBWAT_ADDR (IBM561_CMD_AUXFB_WAT | RAMDAC_ONE_BYTE)
+#define OLWAT_ADDR (IBM561_CMD_OL_WAT | RAMDAC_ONE_BYTE)
+#define AUXOLWAT_ADDR (IBM561_CMD_AUXOL_WAT | RAMDAC_ONE_BYTE)
+#define CMAP_ADDR (IBM561_CMD_CMAP | RAMDAC_ONE_BYTE)
+#define GAMMA_ADDR (IBM561_CMD_GAMMA | RAMDAC_ONE_BYTE)
+
+#define IBM561LoadAddr(reg) \
+do { \
+ TGA2_WRITE_RAMDAC_REG((reg), LO_ADDR); \
+ TGA2_WRITE_RAMDAC_REG((reg) >> 8, HI_ADDR); \
+} while (0)
+
+unsigned char
+IBM561ReadReg(ScrnInfoPtr pScrn, CARD32 reg)
+{
+ TGAPtr pTga;
+ unsigned char ret;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA2_WRITE_RAMDAC_REG(reg, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(reg >> 8, HI_ADDR);
+
+ ret = TGA2_READ_RAMDAC_REG(REGS_ADDR);
+
+#if 1
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "IBM561ReadReg: reg 0x%x data 0x%x\n",
+ reg, ret);
+#endif
+ return (ret);
+}
+
+void
+IBM561WriteReg(ScrnInfoPtr pScrn, CARD32 reg,
+#if 0
+ unsigned char mask, unsigned char data)
+#else
+ unsigned char data)
+#endif
+{
+ TGAPtr pTga;
+ unsigned char tmp = 0x00;
+
+ pTga = TGAPTR(pScrn);
+
+#if 0
+ if (mask != 0x00) {
+ TGA2_WRITE_RAMDAC_REG(reg, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(reg >> 8, HI_ADDR);
+ tmp = TGA2_READ_RAMDAC_REG(REGS_ADDR) & mask;
+ }
+#endif
+
+#if 1
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "IBM561WriteReg: reg 0x%x data 0x%x\n",
+ reg, tmp | data);
+#endif
+
+ TGA2_WRITE_RAMDAC_REG(reg, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(reg >> 8, HI_ADDR);
+ TGA2_WRITE_RAMDAC_REG ((tmp | data), REGS_ADDR);
+}
+
+void
+IBM561ramdacSave(ScrnInfoPtr pScrn, unsigned char *Ibm561)
+{
+#if 0
+ TGAPtr pTga = TGAPTR(pScrn);
+ int i, j;
+
+ /* ?? FIXME OR NOT this is from BT463ramdacSave ?? */
+ Ibm561[0] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_CMD_REG_0);
+ Ibm561[1] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_CMD_REG_1);
+ Ibm561[2] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_CMD_REG_2);
+
+ Ibm561[3] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_0);
+ Ibm561[4] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_1);
+ Ibm561[5] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_2);
+ Ibm561[6] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_3);
+
+ Ibm561[7] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_0);
+ Ibm561[8] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_1);
+ Ibm561[9] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_2);
+ Ibm561[10] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_3);
+
+ IBM561_LOAD_ADDR(IBM561_WINDOW_TYPE_BASE);
+ TGA_WRITE_REG((IBM561_REG_ACC<<2)|0x2, TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0, j = 11; i < 16; i++) {
+ Ibm561[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ Ibm561[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ Ibm561[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ }
+#endif
+
+/*
+ fprintf(stderr, "IBM561ramdacSave (%p)\n", Ibm561);
+ for (i=0; i<58; i++)
+ fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Ibm561[i]);
+*/
+}
+
+static void
+IBM561WindowTagsInit(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ unsigned char low, high;
+ int i;
+
+/*
+ tga.h defines fb_wid_cell_t as a structure containing two bytes,
+ low and high in order. The 561 has 10 bit window tags so only
+ part of the high byte is used (actually only 2 bits). Pixel C for
+ 8-plane indexes uses 16bpp indexing per IBM's application notes
+ which describe quad bufering. Note, this array is arranged as
+ low byte followed by high byte which will apppear backwards
+ relative to the 561 spec( a value of 0x01 in the high byte
+ really represents a color table starting address of 256).
+ ex (entry 4):
+ {0x28, 0x01}, *4 8-plane index (PIXEL C 561 H/W screw-up) *
+ low byte = 0x28
+ high byte = 0x01
+ wat entry = 0x0128
+
+ from the spec: 8 in the low nibble selects buffer 1
+ 2 in the next nibble selects pixformat of 16 bpp
+ 1 in the next nibble indicates a start addr of 256
+*/
+typedef struct {
+ unsigned char low_byte;
+ unsigned char high_byte;
+}fb_wid_cell_t;
+
+typedef struct {
+ unsigned char aux_fbwat;
+} aux_fb_wid_cell_t;
+
+typedef struct {
+ unsigned char low_byte;
+ unsigned char high_byte;
+} ol_wid_cell_t;
+
+typedef struct {
+ unsigned char aux_olwat;
+} aux_ol_wid_cell_t;
+
+/*
+ * There are actually 256 window tag entries in the FB and OL WAT tables.
+ * We will use only 16 for compatability with the BT463 and more importantly
+ * to implement the virtual ramdac interface. This requires us to only
+ * report the smallest WAT table size, in this case its the auxillary wat
+ * tables which are 16 entries.
+ */
+
+#define TGA_RAMDAC_561_FB_WINDOW_TAG_COUNT 256
+#define TGA_RAMDAC_561_FB_WINDOW_TAG_MAX_COUNT 16
+#define TGA_RAMDAC_561_AUXFB_WINDOW_TAG_COUNT 16
+#define TGA_RAMDAC_561_OL_WINDOW_TAG_COUNT 256
+#define TGA_RAMDAC_561_OL_WINDOW_TAG_MAX_COUNT 16
+#define TGA_RAMDAC_561_AUXOL_WINDOW_TAG_COUNT 16
+#define TGA_RAMDAC_561_CMAP_ENTRY_COUNT 1024
+#define TGA_RAMDAC_561_GAM_ENTRY_COUNT 256
+
+ static fb_wid_cell_t
+ fb_wids_561[TGA_RAMDAC_561_FB_WINDOW_TAG_COUNT] = {
+#if 0
+ {0x28, 0x00}, /*0 8-plane index (PIXEL C 561 H/W screw-up) */
+#else
+ {0x36, 0x00}, /*c 24-plane true */
+#endif
+ {0x08, 0x00}, /*1 8-plane index (PIXEL B) */
+ {0x00, 0x00}, /*2 8-plane index (PIXEL A) */
+ {0x34, 0x00}, /*3 24-plane direct, cmap 0 */
+ {0x28, 0x01}, /*4 8-plane index (PIXEL C 561 H/W screw-up) */
+ {0x08, 0x01}, /*5 8-plane index (PIXEL B) */
+ {0x00, 0x01}, /*6 8-plane index (PIXLE A) */
+ {0x34, 0x01}, /*7 24-plane direct, cmap 1 */
+ {0x1e, 0x00}, /*8 12-plane true */
+ /*{0x16, 0x00}, 9 12-plane true */
+ {0x14, 0x00}, /*9 12-plane true(direct) */
+ {0x1e, 0x01}, /*a 12-plane true */
+ {0x16, 0x01}, /*b 12-plane true */
+ {0x36, 0x00}, /*c 24-plane true */
+ {0x36, 0x00}, /*d 24-plane true */
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0}
+ };
+
+ static aux_fb_wid_cell_t
+ auxfb_wids_561[TGA_RAMDAC_561_AUXFB_WINDOW_TAG_COUNT] = {
+ {0x04}, /*0 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*1 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*2 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*3 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*4 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*5 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*6 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*7 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*8 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*9 GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*a GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*b GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*c GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*d GMA=bypass, XH=disable, PT=dc */
+ {0x04}, /*e old cursor colors for 463 don't use*/
+ {0x04}, /*f old cursor colors for 463 don't use*/
+ };
+
+ static ol_wid_cell_t
+ ol_wids_561[TGA_RAMDAC_561_OL_WINDOW_TAG_COUNT] = {
+ {0x31, 0x02}, /*0 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*1 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*2 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*3 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*4 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*5 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*6 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*7 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*8 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*9 PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*a PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*b PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*c PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*d PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*e PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0x31, 0x02}, /*f PX=4bpp, BS=0, MODE=index, TR=OPAQ */
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}
+ };
+
+ static aux_ol_wid_cell_t
+ auxol_wids_561[TGA_RAMDAC_561_AUXOL_WINDOW_TAG_COUNT] = {
+ {0x0c}, /*0 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */
+ {0x0c}, /*1 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */
+ {0x0c}, /*2 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */
+ {0x0c}, /*3 CK/OT=dc, UL=disabled, OL=enabled, GB=use */
+ {0x0c}, /*4 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */
+ {0x0c}, /*5 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */
+ {0x0c}, /*6 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */
+ {0x0c}, /*7 CK/OT=dc, UL=disabled, OL=enabled, GB=use */
+ {0x0c}, /*8 CK/OT=dc, UL=disabled, OL=disabled, GB=use */
+ {0x0c}, /*9 CK/OT=dc, UL=disabled, OL=enabled, GB=use */
+ {0x0c}, /*a CK/OT=dc, UL=disabled, OL=enabled, GB=use */
+ {0x0c}, /*b CK/OT=dc, UL=disabled, OL=enabled, GB=use */
+ {0x0c}, /*c CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */
+ {0x0c}, /*d CK/OT=dc, UL=disabled, OL=disabled, GB=bypass */
+ {0x0c}, /*e old cursor color for 463, don't use */
+ {0x0c}, /*f old cursor color for 463, don't use */
+ };
+
+ /* ibm561 so init the window tags's via interrupt. It must be
+ * done either during the vsync interrupt or by blanking, We will
+ * actually do both. ???????
+ */
+
+ IBM561LoadAddr(IBM561_FB_WINDOW_TYPE_TABLE);
+ for ( i = 0; i < TGA_RAMDAC_561_FB_WINDOW_TAG_COUNT; i++ ) {
+ low = ((fb_wids_561[i].low_byte & 0xfc) >> 2);
+ high =((fb_wids_561[i].high_byte & 0x03) << 6) & 0xff;
+ TGA2_WRITE_RAMDAC_REG (low | high, FBWAT_ADDR);
+
+ low = (fb_wids_561[i].low_byte & 0x03) << 6;
+ TGA2_WRITE_RAMDAC_REG (low, FBWAT_ADDR);
+ }
+
+ IBM561LoadAddr(IBM561_AUXFB_WINDOW_TYPE_TABLE);
+ for ( i = 0; i < TGA_RAMDAC_561_AUXFB_WINDOW_TAG_COUNT; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (auxfb_wids_561[i].aux_fbwat, AUXFBWAT_ADDR);
+ }
+
+
+ IBM561LoadAddr(IBM561_OL_WINDOW_TYPE_TABLE);
+ for ( i = 0; i < TGA_RAMDAC_561_OL_WINDOW_TAG_COUNT; i++ ) {
+ low = ((ol_wids_561[i].low_byte & 0xfc) >> 2);
+ high =((ol_wids_561[i].high_byte & 0x03) << 6) & 0xff;
+ TGA2_WRITE_RAMDAC_REG (low | high, OLWAT_ADDR);
+
+ low = (ol_wids_561[i].low_byte & 0x03) << 6;
+ TGA2_WRITE_RAMDAC_REG (low, OLWAT_ADDR);
+ }
+
+
+ IBM561LoadAddr(IBM561_AUXOL_WINDOW_TYPE_TABLE);
+ for ( i = 0; i < TGA_RAMDAC_561_AUXOL_WINDOW_TAG_COUNT; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (auxol_wids_561[i].aux_olwat, AUXOLWAT_ADDR);
+ }
+}
+
+/*
+ * ibm561_init_color_map
+ *
+ * Initialize color map in 561. Note the entire
+ * color map is initialized, both the 8-bit and the 24-bit
+ * portions.
+ */
+static int
+IBM561InitColormap(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+#if 0
+ tga_ibm561_info_t *bti = (tga_ibm561_info_t *) closure;
+ tga_info_t *tgap = tga_softc[bti->unit];
+#endif
+ int i;
+
+ TGA2_WRITE_RAMDAC_REG(IBM561_COLOR_LOOKUP_TABLE, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_COLOR_LOOKUP_TABLE >> 8, HI_ADDR);
+
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+
+ for ( i = 1; i <256; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ }
+
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+
+ for ( i = 1; i <256; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ }
+
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+
+ for ( i = 1; i <256; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ }
+
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR);
+
+ for ( i = 1; i <256; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR);
+ }
+
+ /*
+ * The ddx layer views the gamma table as an extension of the
+ * color pallettes, therefore the gamma table is initialized here.
+ * Note, each entry in the table is 10 bits, requiring two writes
+ * per entry!! The table are initialized the same way as color tables,
+ * a zero entry followed by mulitple ff's. NOTE, the gamma tables are
+ * loaded in a strange manner, DO NOT use this code as a guide (we are
+ * writing all zero's or all ones). See the tga_ibm561_load_color_map
+ * _entry code above.
+ */
+
+ TGA2_WRITE_RAMDAC_REG(IBM561_RED_GAMMA_TABLE, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_RED_GAMMA_TABLE >> 8, HI_ADDR);
+
+ TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR);
+
+ for ( i = 1; i <256; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR);
+ }
+
+ TGA2_WRITE_RAMDAC_REG(IBM561_GREEN_GAMMA_TABLE, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_GREEN_GAMMA_TABLE >> 8, HI_ADDR);
+
+ TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR);
+
+ for ( i = 1; i <256; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR);
+ }
+
+ TGA2_WRITE_RAMDAC_REG(IBM561_BLUE_GAMMA_TABLE, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_BLUE_GAMMA_TABLE >> 8, HI_ADDR);
+
+ TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR);
+
+ for ( i = 1; i <256; i++ ) {
+ TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR);
+ TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR);
+ }
+
+
+#if 0
+ /* ?? no cursor support yet */
+ bti->cursor_fg.red = bti->cursor_fg.green = bti->cursor_fg.blue
+ = 0xffff;
+ bti->cursor_bg.red = bti->cursor_bg.green = bti->cursor_bg.blue
+ = 0x0000;
+ tga_ibm561_restore_cursor_color( closure, 0 );
+#endif
+
+ return 0;
+}
+
+void
+IBM561ramdacHWInit(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ unsigned int temp1[6] = {0,0,0,0,0,0};
+
+ /*
+ * Set-up av9110 to 14.3 Mhz as reference for 561's PLL
+ */
+ temp1[0] = 0x00000101;
+ temp1[1] = 0x01000000;
+ temp1[2] = 0x00000001;
+ temp1[3] = 0x00010000;
+ temp1[4] = 0x01010100;
+ temp1[5] = 0x01000000;
+
+ write_av9110(pScrn, temp1);
+
+ /*
+ * Initialize IBM561 RAMDAC
+ */
+ IBM561WriteReg(pScrn, IBM561_CONFIG_REG_1, 0x2a );
+ IBM561WriteReg(pScrn, IBM561_CONFIG_REG_3, 0x41 );
+ IBM561WriteReg(pScrn, IBM561_CONFIG_REG_4, 0x20 );
+
+/* IBM561WriteReg(pScrn, IBM561_PLL_VCO_DIV_REG, 0xc8 ); */
+ IBM561WriteReg(pScrn, IBM561_PLL_VCO_DIV_REG, tga_c_table->ibm561_vco_div);
+
+/* IBM561WriteReg(pScrn, IBM561_PLL_REF_REG, 0x08 ); */
+ IBM561WriteReg(pScrn, IBM561_PLL_REF_REG, tga_c_table->ibm561_ref );
+
+ IBM561WriteReg(pScrn, IBM561_DIV_DOT_CLK_REG, 0xb0 );
+
+ IBM561WriteReg(pScrn, IBM561_SYNC_CONTROL, 0x01 );
+
+ IBM561WriteReg(pScrn, IBM561_CONFIG_REG_2, 0x19 );
+
+ TGA_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+
+ /* Configure the RAMDAC, note registers not set either depend on the
+ * previous setting (ie what firmaware programmed to be) or what the
+ * X-server will set them to
+ */
+
+
+ /*
+ * Config Register 1: MUX=4:1 BASIC, OVLY=8 bits, WID=8 bits (bits 4-7 of the
+ * overlay and window ID's are tied to ground in the hardware).
+ */
+ IBM561WriteReg(pScrn, IBM561_CONFIG_REG_1, 0x2a );
+
+ /* SKIP Config Register 2-3 (use Diag settings at least for now) */
+
+ /*
+ * Config Register 4: FB_WID=4 bits, SWE=Common, AOW=LSB, AFW=LSB
+ */
+ IBM561WriteReg(pScrn, IBM561_CONFIG_REG_4, 0x20 );
+
+ /*
+ * SKIP Interleave Register (use Diag settings at least for now)
+ */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /*
+ * WAT/OL Segement Registers
+ */
+ /* ?? we setup the address registers first, then stream the data out ?? */
+ TGA2_WRITE_RAMDAC_REG(IBM561_WAT_SEG_REG, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_WAT_SEG_REG >> 8, HI_ADDR);
+
+ /* WAT Segment Register */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* OL Segment Register */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* AUX WAT Segment Register */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* AUX OL Segment Register */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /*
+ * Chroma Key Registers and Masks
+ */
+ /* ?? we setup the address registers first, then stream the data out ?? */
+ TGA2_WRITE_RAMDAC_REG(IBM561_CHROMA_KEY_REG0, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_CHROMA_KEY_REG0 >> 8, HI_ADDR);
+
+ /* Chroma key register 0 */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* Chroma key register 1 */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* Chroma key mask register 0 */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* Chroma key mask register 1 */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /*
+ * Cursor Control Register
+ */
+ IBM561WriteReg(pScrn, IBM561_CURSOR_CTRL_REG, /*pScrn->cursor_on_off*/0);
+
+ /*
+ * Cursor Hot Spot X/Y Registers
+ */
+ TGA2_WRITE_RAMDAC_REG(IBM561_CURSOR_HS_REG, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_CURSOR_HS_REG >> 8, HI_ADDR);
+
+ /* Cursor "x" Hot Spot Register */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* Cursor "y" Hot Spot Register */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* Cursor "x" Location Register (low byte) */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* Cursor "x" Location Register (high byte) */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /* Cursor "y" Location Register (low byte) */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* Cursor "y" Location Register (high byte) */
+ TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR);
+
+ /*
+ * VRAM Mask regs (used for diag purposes, reset them just in case)
+ */
+ TGA2_WRITE_RAMDAC_REG(IBM561_VRAM_MASK_REG, LO_ADDR);
+ TGA2_WRITE_RAMDAC_REG(IBM561_VRAM_MASK_REG >> 8, HI_ADDR);
+
+ /* VRAM mask register 1 */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* VRAM mask register 2 */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* VRAM mask register 3 */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* VRAM mask register 4 */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* VRAM mask register 5 */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* VRAM mask register 6 */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* VRAM mask register 7 */
+ TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR);
+
+ /* Finally, do colormaps and windowtags */
+ IBM561InitColormap(pScrn);
+ IBM561WindowTagsInit(pScrn);
+}
+
+void
+IBM561ramdacRestore(ScrnInfoPtr pScrn, unsigned char *Ibm561)
+{
+#if 0
+ TGAPtr pTga = TGAPTR(pScrn);
+#endif
+
+#if 0
+ /* ?? finally the stock stuff ?? */
+ int i, j;
+ /* ?? FIXME OR NOT this is currently copied from the BT463 */
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_CMD_REG_0, Ibm561[0]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_CMD_REG_1, Ibm561[1]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_CMD_REG_2, Ibm561[2]);
+
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_0, Ibm561[3]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_1, Ibm561[4]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_2, Ibm561[5]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_3, Ibm561[6]);
+
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_0, Ibm561[7]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_1, Ibm561[8]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_2, Ibm561[9]);
+ IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_3, Ibm561[10]);
+
+ IBM561_LOAD_ADDR(IBM561_WINDOW_TYPE_BASE);
+ TGA_WRITE_REG((IBM561_REG_ACC<<2), TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0, j = 11; i < 16; i++) {
+ TGA_WRITE_REG(Ibm561[j++]|(IBM561_REG_ACC<<10), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(Ibm561[j++]|(IBM561_REG_ACC<<10), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(Ibm561[j++]|(IBM561_REG_ACC<<10), TGA_RAMDAC_REG);
+ }
+#endif
+
+/*
+ fprintf(stderr, "IBM561ramdacRestore (%p)\n", Ibm561);
+ for (i=0; i<58; i++)
+ fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Ibm561[i]);
+*/
+
+}
+
diff --git a/src/ICS1562.c b/src/ICS1562.c
new file mode 100644
index 0000000..ac72b24
--- /dev/null
+++ b/src/ICS1562.c
@@ -0,0 +1,114 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c,v 1.3 1999/04/17 07:06:56 dawes Exp $ */
+
+#define BASE_FREQ 14.31818
+#define MAX_FREQ 230000
+
+#define reorder(a) ( \
+ (a & 0x80) >> 7 | \
+ (a & 0x40) >> 5 | \
+ (a & 0x20) >> 3 | \
+ (a & 0x10) >> 1 | \
+ (a & 0x08) << 1 | \
+ (a & 0x04) << 3 | \
+ (a & 0x02) << 5 | \
+ (a & 0x01) << 7 )
+
+#define CHECK_MIN(m,a,r,n) do { \
+ diff = f - (BASE_FREQ * 1e3 * (n)) / (r << p); \
+ if (diff < 0) diff = -diff; \
+ if (diff < min_diff) { \
+ min_diff = diff; \
+ best_m = m; \
+ best_a = a; \
+ best_r = r; \
+ } \
+ } while(0)
+
+
+static void Set_1562_PLL(int f, int p, int m, int a, int r, unsigned char *bits)
+{
+ bits[0] = 0x80; /* N1 = 4, not used for PLL */
+ bits[1] = reorder(p) >> 4;
+ bits[2] = 0x00; /* N2 = 1 */
+ if (f <= 120000)
+ bits[3] = 0x20; /* V = 100 */
+ else if (f <= 200000)
+ bits[3] = 0xa0; /* V = 101 */
+ else
+ bits[3] = 0x60; /* V = 110 */
+ bits[3] |= 0x05; /* P = 10, phase detector on */
+ bits[4] = reorder(m);
+ bits[5] = reorder(a);
+ bits[6] = reorder(r);
+
+#ifdef DEBUG
+ {
+ int i;
+ for(i=0; i<7; i++)
+ ErrorF("%02x ", bits[i]);
+ ErrorF("\n");
+ }
+#endif
+}
+
+void ICS1562_CalcClockBits(long f, unsigned char *bits);
+
+void ICS1562_CalcClockBits(long f, unsigned char *bits)
+{
+ int n,r, a,m, p, r0,r1,n0,n1;
+ int best_m=34, best_a=1, best_r=30;
+ double diff, min_diff;
+ double ff, ffp;
+
+ if (f > MAX_FREQ)
+ f = MAX_FREQ;
+
+ if (f >= MAX_FREQ/2)
+ p=0;
+ else if (f >= MAX_FREQ/4)
+ p=1;
+ else
+ p=2;
+
+ ff = f / 1e3 / BASE_FREQ;
+ ffp = ff * (1 << p);
+ min_diff = 999999999;
+
+ r0 = (int)(7/ffp);
+ if (r0 < 1) r0 = 1;
+ r1 = (int)(449/ffp);
+ if (r1 > 0x7f+1) r1 = 0x7f+1;
+ if (r1 < r0) r1 = r0;
+
+ for (r=r0; r<r1; r++) {
+ n0 = (int)(ffp * r);
+ if (n0 < 7) n0 = 7;
+ n1 = (int)(ffp * (r+1));
+ if (n1 > 448) n1 = 448;
+ for (n=n0; n<n1; n++) {
+ m = ((n+3)/7) - 1;
+ if (m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7);
+ if (++m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7);
+ m = (n/6) - 1;
+ a = n - (m+1)*6;
+ if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a);
+ m++;
+ a = n - (m+1)*6;
+ if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a);
+ }
+ }
+
+ if (best_a) n = (best_m+1)*6+best_a;
+ else n = (best_m+1)*7;
+
+#ifdef DEBUG
+ ErrorF("%8.3f %f %f p=%d m=%d a=%d r=%d %d/%d\n"
+ ,f/1e3
+ ,min_diff,(BASE_FREQ * (n)) / (best_r << p)
+ ,p ,best_m, best_a, best_r-1
+ ,n,best_r
+ );
+#endif
+
+ Set_1562_PLL(f, p, best_m, best_a, best_r-1, bits);
+}
diff --git a/src/tga.h b/src/tga.h
new file mode 100644
index 0000000..7246511
--- /dev/null
+++ b/src/tga.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * 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.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga.h,v 1.18 2001/11/21 22:32:58 alanh Exp $ */
+
+#ifndef _TGA_H_
+#define _TGA_H_
+
+#include "xaa.h"
+#include "xf86RamDac.h"
+
+typedef struct {
+ unsigned long tgaRegs[0x100];
+} TGARegRec, *TGARegPtr;
+
+
+#define TGAPTR(p) ((TGAPtr)((p)->driverPrivate))
+
+typedef struct {
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int Chipset;
+ RamDacHelperRecPtr RamDac;
+ int ChipRev;
+ int HwBpp;
+ int BppShift;
+ int pprod;
+ CARD32 CardAddress;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ unsigned char * FbBase;
+ unsigned char * IOBase;
+ unsigned char * ClkBase; /* TGA2 */
+ unsigned char * DACBase; /* TGA2 */
+ unsigned char * HACKBase; /* TGA2 */
+ long FbMapSize;
+ unsigned long regOffset;
+ Bool NoAccel;
+ Bool NoXaaPolySegment;
+ Bool Dac6Bit;
+ Bool SyncOnGreen;
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ int MinClock;
+ int MaxClock;
+ TGARegRec SavedReg;
+ TGARegRec ModeReg;
+ CARD32 AccelFlags;
+ RamDacRecPtr RamDacRec;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ int CardType;
+ unsigned char Bt463modeReg[59];
+ unsigned char Bt463saveReg[59];
+ unsigned char Ibm561modeReg[59];
+ unsigned char Ibm561saveReg[59];
+ EntityInfoPtr pEnt;
+ CARD32 *buffers[1];
+ unsigned int current_rop;
+ unsigned int current_planemask;
+ int transparent_pattern_p;
+ int blitdir;
+ int block_or_opaque_p;
+ int ce_height;
+ int ce_width;
+ int ce_x;
+ int ce_y;
+ int ce_skipleft;
+ int line_pattern_length;
+ CARD16 line_pattern; /* for dashed lines */
+ int Bpp; /* bytes per pixel */
+ int depthflag; /* either BPP8PACKED or BPP24 */
+ OptionInfoPtr Options;
+} TGARec, *TGAPtr;
+
+/* ?? this is a hack for initial TGA2 support */
+struct monitor_data {
+ unsigned int max_rows; /* Monitor setup */
+ unsigned int max_cols;
+ unsigned int pixel_freq;
+ unsigned int refresh_rate;
+ unsigned int vert_slines;
+ unsigned int vert_fp;
+ unsigned int vert_sync;
+ unsigned int vert_bp;
+ unsigned int horz_pix;
+ unsigned int horz_fp;
+ unsigned int horz_sync;
+ unsigned int horz_bp;
+ unsigned int vco_div; /* ICS setup */
+ unsigned int ref_div;
+ unsigned int vco_pre;
+ unsigned int clk_div;
+ unsigned int vco_out_div;
+ unsigned int clk_out_en;
+ unsigned int clk_out_enX;
+ unsigned int res0;
+ unsigned int clk_sel;
+ unsigned int res1;
+ unsigned int ibm561_vco_div; /* IBM561 PLL setup */
+ unsigned int ibm561_ref;
+};
+
+extern struct monitor_data tga_crystal_table[];
+extern int tga_crystal_table_entries;
+extern struct monitor_data *tga_c_table;
+
+/* Prototypes */
+
+/* tga_dac.c */
+void DEC21030Restore(ScrnInfoPtr pScrn,/* vgaRegPtr vgaReg,*/
+ TGARegPtr tgaReg/*, Bool restoreFonts*/);
+void DEC21030Save(ScrnInfoPtr pScrn, /*vgaRegPtr vgaReg,*/ TGARegPtr tgaReg/*,
+ Bool saveFonts*/);
+Bool DEC21030Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void write_av9110(ScrnInfoPtr pScrn, unsigned int *);
+void TGA2SetupMode(ScrnInfoPtr pScrn);
+void Ibm561Init(TGAPtr pTga);
+void Bt463Init(TGAPtr pTga);
+
+/* tga_accel.c */
+Bool DEC21030AccelInit(ScreenPtr pScreen);
+
+/* BTramdac.c */
+void tgaBTOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data);
+unsigned char tgaBTInIndReg(ScrnInfoPtr pScrn, CARD32 reg);
+void tgaBTWriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void tgaBTReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void tgaBTWriteData(ScrnInfoPtr pScrn, unsigned char data);
+unsigned char tgaBTReadData(ScrnInfoPtr pScrn);
+
+void tga2BTOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data);
+unsigned char tga2BTInIndReg(ScrnInfoPtr pScrn, CARD32 reg);
+void tga2BTWriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void tga2BTReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void tga2BTWriteData(ScrnInfoPtr pScrn, unsigned char data);
+unsigned char tga2BTReadData(ScrnInfoPtr pScrn);
+
+/* BT463ramdac.c */
+void BT463ramdacSave(ScrnInfoPtr pScrn, unsigned char *data);
+void BT463ramdacRestore(ScrnInfoPtr pScrn, unsigned char *data);
+
+/* IBM561ramdac.c */
+void IBM561ramdacSave(ScrnInfoPtr pScrn, unsigned char *data);
+void IBM561ramdacHWInit(ScrnInfoPtr pScrn);
+void IBM561ramdacRestore(ScrnInfoPtr pScrn, unsigned char *data);
+unsigned char IBM561ReadReg(ScrnInfoPtr pScrn, CARD32 reg);
+void IBM561WriteReg(ScrnInfoPtr pScrn, CARD32 reg, unsigned char data);
+
+/* tga_cursor.c */
+Bool TGAHWCursorInit(ScreenPtr pScreen);
+
+/* tga_line.c */
+
+void TGAPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+void TGAPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+void TGAPolySegmentDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+void TGAPolyLinesDashed(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+
+/* line functions */
+void
+TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+void
+TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
+ int dir);
+void
+TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant, int flags);
+void
+TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant);
+void
+TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
+ int err);
+
+void
+TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length,
+ unsigned char *pattern);
+void
+TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant, int flags, int phase);
+void
+TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
+ int err, int phase);
+
+
+
+
+#endif /* _TGA_H_ */
+
diff --git a/src/tga_accel.c b/src/tga_accel.c
new file mode 100644
index 0000000..b00596d
--- /dev/null
+++ b/src/tga_accel.c
@@ -0,0 +1,1569 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c,v 1.15 2001/11/21 22:32:59 alanh Exp $ */
+
+/*
+ * Copyright 1996,1997 by Alan Hourihane, Wigan, England.
+ *
+ * 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.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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: Alan Hourihane, alanh@fairlite.demon.co.uk
+ *
+ * DEC TGA accelerated options.
+ */
+
+#include "fb.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "mipointer.h"
+
+#include "mibstore.h"
+#include "miline.h"
+
+#include "tga_regs.h"
+#include "BT.h"
+#include "tga.h"
+
+/* defines */
+
+#define BLIT_FORWARDS 0
+#define BLIT_BACKWARDS 1
+#define USE_BLOCK_FILL 2
+#define USE_OPAQUE_FILL 3
+#define MIX_SRC 0x03
+
+#define CE_BUFSIZE 256
+
+#define FB_OFFSET(x, y) (((long)(y) * pScrn->displayWidth * (pTga->Bpp)) + (long)(x) * pTga->Bpp)
+
+/* prototypes */
+
+static void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w);
+static void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w);
+extern void TGASync(ScrnInfoPtr pScrn);
+static void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h);
+static void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color);
+static void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h);
+static void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y, int w,
+ int h);
+static void TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask);
+
+static void
+TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w,
+ int h, int skipleft);
+static void
+TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+
+
+/*
+ * The following function sets up the supported acceleration. Call it
+ * from the FbInit() function in the SVGA driver.
+ */
+Bool
+DEC21030AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr TGA_AccelInfoRec;
+ BoxRec AvailFBArea;
+ ScrnInfoPtr pScrn;
+ TGAPtr pTga;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pTga = TGAPTR(pScrn);
+
+ /* ErrorF("DEC21030AccelInit called!"); */
+
+ /* first, create the XAAInfoRec */
+ TGA_AccelInfoRec = XAACreateInfoRec();
+
+ /* ErrorF("XAACreateInfoRec called"); */
+
+ if(pScrn->depth == 8) {
+ pTga->depthflag = BPP8PACKED;
+ pTga->Bpp = 1;
+ } else {
+ pTga->depthflag = BPP24;
+ pTga->Bpp = 4;
+ }
+
+ TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ TGA_AccelInfoRec->Sync = TGASync;
+
+ /* solid fill */
+
+ TGA_AccelInfoRec->SolidFillFlags = 0;
+ TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill;
+ TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect;
+
+ /* screen to screen copy */
+ TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
+ TGA_AccelInfoRec->SetupForScreenToScreenCopy =
+ TGASetupForScreenToScreenCopy;
+ TGA_AccelInfoRec->SubsequentScreenToScreenCopy =
+ TGASubsequentScreenToScreenCopy;
+
+ /* mono 8x8 pattern fill */
+
+ TGA_AccelInfoRec->Mono8x8PatternFillFlags =
+ HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_LSBFIRST;
+ TGA_AccelInfoRec->SetupForMono8x8PatternFill =
+ TGASetupForMono8x8PatternFill;
+ TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect =
+ TGASubsequentMono8x8PatternFillRect;
+
+ /* color expand */
+ /* does not work for 32bpp (yet) */
+ TGA_AccelInfoRec->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+
+ TGA_AccelInfoRec->NumScanlineColorExpandBuffers = 1;
+ pTga->buffers[0] = (CARD32 *)xnfalloc(CE_BUFSIZE);
+ TGA_AccelInfoRec->ScanlineColorExpandBuffers =
+ (unsigned char **)pTga->buffers;
+ TGA_AccelInfoRec->SetupForScanlineCPUToScreenColorExpandFill =
+ TGASetupForScanlineCPUToScreenColorExpandFill;
+ TGA_AccelInfoRec->SubsequentScanlineCPUToScreenColorExpandFill =
+ TGASubsequentScanlineCPUToScreenColorExpandFill;
+ TGA_AccelInfoRec->SubsequentColorExpandScanline =
+ TGASubsequentColorExpandScanline;
+
+ /* lines */
+
+ TGA_AccelInfoRec->PolylinesThinSolid = TGAPolyLines;
+ if(pTga->NoXaaPolySegment == FALSE)
+ TGA_AccelInfoRec->PolySegmentThinSolid = TGAPolySegment;
+ TGA_AccelInfoRec->PolylinesThinSolidFlags = 0x0;
+ TGA_AccelInfoRec->PolySegmentThinSolidFlags = 0x0;
+
+ TGA_AccelInfoRec->PolylinesThinDashed = TGAPolyLinesDashed;
+ if(pTga->NoXaaPolySegment == FALSE)
+ TGA_AccelInfoRec->PolySegmentThinDashed = TGAPolySegmentDashed;
+ TGA_AccelInfoRec->PolylinesThinDashedFlags = 0x0;
+ TGA_AccelInfoRec->PolySegmentThinDashedFlags = 0x0;
+ TGA_AccelInfoRec->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED;
+ TGA_AccelInfoRec->DashPatternMaxLength = 16;
+
+ /* initialize the pixmap cache */
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0; /* these gotta be 0 */
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth *
+ pTga->Bpp);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ TGA_AccelInfoRec->PixmapCacheFlags = 0;
+
+ /* initialize XAA */
+ return(XAAInit(pScreen, TGA_AccelInfoRec));
+}
+
+static void
+TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga = NULL;
+ unsigned int fgcolor = 0, bgcolor = 0, pmask = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASetupForScanlineCPUToScreenColorExpandFill called\n"); */
+ if(pTga->depthflag == BPP8PACKED) {
+ fgcolor = (fg | (fg << 8) | (fg << 16) | (fg << 24));
+ bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24);
+ pmask = planemask | (planemask << 8) | (planemask << 16)
+ | (planemask << 24);
+ }
+ else {
+ bgcolor = bg;
+ fgcolor = fg;
+ pmask = planemask;
+ }
+ pTga->current_rop = rop | pTga->depthflag;
+
+ if(bg == -1) {
+ pTga->transparent_pattern_p = 1;
+ if(rop == MIX_SRC) {
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG);
+ if(pTga->depthflag == BPP24) {
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG);
+ }
+ }
+ else {
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+ TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG);
+ }
+ }
+ else {
+ pTga->transparent_pattern_p = 0;
+ TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG);
+ }
+ TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); /* we know when to
+ reset this */
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+static void
+TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w,
+ int h, int skipleft)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASubsequentScanlineCPUToScreenColorExpandFill called\n"); */
+/* ErrorF("w = %d, h = %d\n", w, h); */
+
+ pTga->ce_height = h;
+ pTga->ce_width = w;
+ pTga->ce_x = x;
+ pTga->ce_y = y;
+ pTga->ce_skipleft = skipleft;
+/* ErrorF("skipleft is %d\n", skipleft); */
+
+ if(pTga->transparent_pattern_p) {
+ if(pTga->block_or_opaque_p == USE_BLOCK_FILL)
+ TGA_FAST_WRITE_REG(BLOCKSTIPPLE | X11 | pTga->depthflag,
+ TGA_MODE_REG);
+ else
+ TGA_FAST_WRITE_REG(TRANSPARENTSTIPPLE | X11 | pTga->depthflag,
+ TGA_MODE_REG);
+/* ErrorF("transparent stipple with x = %d, y = %d, w = %d, h = %d\n", */
+/* x, y, w, h); */
+ }
+ else
+ TGA_FAST_WRITE_REG(OPAQUESTIPPLE | X11 | pTga->depthflag,
+ TGA_MODE_REG);
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+static void
+TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+ unsigned char *p = NULL;
+ int width = 0;
+ unsigned int addr;
+ unsigned int pixelmask = 0;
+ unsigned int stipple;
+ unsigned int align_mask;
+ int align = 0;
+ int skipleft;
+
+ CARD32 c = 0, d = 0;
+ CARD32 *e = NULL;
+ int i = 0, num_dwords = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ align_mask = (pTga->depthflag == BPP24) ? 0x0f : 0x03;
+
+#if 0
+ ErrorF("TGASubsequentColorExpandScanline called\n");
+ if(pTga->transparent_pattern_p)
+ ErrorF("transparent color expand\n");
+#endif
+
+ p = (unsigned char *)pTga->buffers[0];
+ addr = FB_OFFSET(pTga->ce_x, pTga->ce_y);
+ width = pTga->ce_width;
+ skipleft = pTga->ce_skipleft;
+
+ while(width > 0) {
+ if(!pTga->transparent_pattern_p)
+ pixelmask = 0xFFFFFFFF;
+
+ align = (addr & align_mask) / pTga->Bpp; /* no. pixels out of align */
+ if (align) {
+ if (!pTga->transparent_pattern_p)
+ pixelmask <<= align;
+/* ErrorF("alignment is %d\n", align); */
+ addr -= align * pTga->Bpp;
+ width += align;
+
+ e = (CARD32 *)p;
+ num_dwords = (width / 32) + 1;
+ if(num_dwords > (CE_BUFSIZE / 4)) { /* shouldn't happen */
+ ErrorF("TGASubsequentColorExpandScanline passed scanline %d bytes long, truncating\n", num_dwords * 4);
+ num_dwords = CE_BUFSIZE / 4;
+ }
+ for(i = 0; i < num_dwords; i++) {
+ c = e[i];
+ if(i == 0)
+ e[i] = c << align;
+ else
+ e[i] = (d >> (32 - align)) | (c << align);
+ d = c;
+ }
+ }
+
+ if (!pTga->transparent_pattern_p) {
+ if (skipleft) {
+ pixelmask <<= skipleft;
+ skipleft = 0;
+ }
+ if (width < 32) {
+ pixelmask &= (0xFFFFFFFF >> (32 - width));
+ }
+ TGA_FAST_WRITE_REG(pixelmask, TGA_PIXELMASK_REG);
+ }
+ else {
+ unsigned int *i = NULL;
+
+/* ErrorF("transparent scanline with x = %d, y = %d, w = %d, h = %d\n", pTga->ce_x, pTga->ce_y, pTga->ce_width, pTga->ce_height); */
+ if (skipleft) {
+ i = (unsigned int *)p;
+ *i &= (0xFFFFFFFF << skipleft);
+ skipleft = 0;
+ }
+ if (width < 32) {
+ i = (unsigned int *)p;
+ *i &= (0xFFFFFFFF >> (32 - width));
+ }
+ }
+
+ stipple = *((unsigned int *)p);
+ switch (pTga->Chipset) {
+ case PCI_CHIP_TGA2:
+ *(unsigned int *)(pTga->FbBase + addr) = stipple; WMB;
+ break;
+ case PCI_CHIP_DEC21030:
+ TGA_FAST_WRITE_REG(addr, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(stipple, TGA_CONTINUE_REG);
+ }
+ addr += 32 * pTga->Bpp;
+ p += 4;
+ width -= 32;
+ }
+ pTga->ce_height--;
+ if(pTga->ce_height == 0) {
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag,
+ TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+ }
+ else
+ pTga->ce_y += 1;
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+/* Block Fill mode is faster, but only works for certain rops. So we will
+ have to implement Opaque Fill anyway, so we will do that first, then
+ do Block Fill for the special cases
+*/
+void
+TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+ unsigned int fgcolor = 0, pmask = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+ /* ErrorF("TGASetupForSolidFill called"); */
+
+ if(pTga->depthflag == BPP8PACKED) {
+ fgcolor = color | (color << 8) | (color << 16) | (color << 24);
+ pmask = planemask | (planemask << 8) | (planemask << 16) |
+ (planemask << 24);
+ }
+ else {
+ fgcolor = color;
+ pmask = planemask;
+ }
+
+
+ if(rop == MIX_SRC) { /* we can just do a block copy */
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG);
+ if(pTga->depthflag == BPP24) {
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG);
+ }
+ }
+ else {
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+ pTga->current_rop = rop | pTga->depthflag;
+ TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG);
+/* ErrorF("opaque fill called\n"); */
+ }
+
+ pTga->current_planemask = pmask;
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_DATA_REG);
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ unsigned int mode_reg = 0;
+ int i = 0;
+ unsigned int pixel_count = 0; /* the actual # of pixels to be written */
+ unsigned int write_data = 0; /* the actual data written */
+ int a1 = 0;
+#ifdef PROFILE
+ unsigned int stop, start;
+#endif
+ TGAPtr pTga;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ /* ErrorF("TGASubsequentFillRectSolid called\n"); */
+
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) {
+ mode_reg = OPAQUEFILL | X11 | pTga->depthflag;
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+ /* we have to set this to GXCOPY every time before we exit */
+ }
+ else
+ mode_reg = BLOCKFILL | X11 | pTga->depthflag;
+
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+
+ if(w > 2048) {
+ ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n");
+ w = 2048;
+ }
+ pixel_count = w - 1;
+
+ for(i = 0; i < h; i++) {
+ a1 = FB_OFFSET(x, y + i);
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
+ write_data = pixel_count;
+ TGA_FAST_WRITE_REG(a1, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(write_data, TGA_CONTINUE_REG);
+ }
+
+ mode_reg = SIMPLE | X11 | pTga->depthflag;
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag,
+ TGA_RASTEROP_REG); /* GXCOPY */
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+/* we only need to calculate the direction of a move once per move,
+ so we do it in the setup function and leave it */
+
+void
+TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color)
+ /* xdir 1 = left-to-right, -1 = right to left
+ ydir 1 = top-to-bottom, -1 = bottom to top
+ */
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+ unsigned int pmask = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ /* see section 6.2.9 */
+
+ if (pTga->depthflag == BPP8PACKED) {
+ pmask = planemask | (planemask << 8) | (planemask << 16) |
+ (planemask << 24);
+ }
+ else
+ pmask = planemask;
+
+ pTga->current_planemask = pmask;
+ TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG);
+
+ pTga->current_rop = rop | pTga->depthflag;
+
+ /* do we copy a rectangle from top to bottom or bottom to top? */
+ if (ydir == -1) {
+ pTga->blitdir = BLIT_FORWARDS;
+ }
+ else {
+ pTga->blitdir = BLIT_BACKWARDS;
+ }
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+/*
+ * This is the implementation of the SubsequentForScreenToScreenCopy
+ * that sends commands to the coprocessor to perform a screen-to-screen
+ * copy of the specified areas, with the parameters from the SetUp call.
+ */
+void
+TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w, int h)
+{
+ /* x1, y1 = source coords
+ x2, y2 = destination coords
+ w = width
+ h = height
+ */
+
+ int i = 0;
+ void (*copy_func)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w);
+#ifdef PROFILE
+ unsigned int stop, start;
+#endif
+ TGAPtr pTga;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+#if 0
+ ErrorF("TGASubsequentScreenToScreenCopy(,%d,%d,%d,%d,%d,%d):"
+ " COPY %s BLIT %s\n",
+ x1, y1, x2, y2, w, h, (x2 > x1 && (x1 + w) > x2)?"BWD":"FWD",
+ (pTga->blitdir == BLIT_FORWARDS)?"FWD":"BWD");
+#endif
+ TGASync(pScrn); /* ?? */
+
+ TGA_FAST_WRITE_REG(COPY | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+
+ if(x2 > x1 && (x1 + w) > x2)
+ copy_func = TGACopyLineBackwards;
+ else
+ copy_func = TGACopyLineForwards;
+
+ TGA_SAVE_OFFSET();
+ if(pTga->blitdir == BLIT_FORWARDS) {
+ for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */
+ (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w);
+ }
+ }
+ else {
+ for(i = 0; i < h; i++) {
+ (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w);
+ }
+ }
+
+ TGASync(pScrn); /* ?? */
+
+ TGA_GET_OFFSET();
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+
+void
+TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w)
+{
+ /* copy a line of width w from x1,y1 to x2,y2 using copy mode */
+ int read;
+ unsigned long source_address, destination_address;
+ unsigned int mask_source, mask_destination;
+ int cando;
+ unsigned int cando_mask;
+ int source_align, destination_align;
+ int pixel_shift;
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ cando = 32;
+ cando_mask = 0xFFFFFFFFU;
+ if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) {
+ cando = 16;
+ cando_mask = 0x0000FFFFU;
+ }
+
+ source_address = FB_OFFSET(x1, y1);
+ destination_address = FB_OFFSET(x2, y2);
+#if 0
+ ErrorF("CPY-FWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx\n",
+ x1, y1, x2, y2, w, source_address, destination_address);
+#endif
+ read = 0;
+ while (read < w) {
+
+ mask_source = cando_mask;
+ if ((w - read) >= cando)
+ mask_destination = cando_mask;
+ else
+ mask_destination = cando_mask >> (cando - (w - read));
+
+ source_align = source_address & 0x07;
+ source_address -= source_align;
+ mask_source <<= source_align / pTga->Bpp;
+ /* mask_source &= cando_mask; */
+
+ destination_align = destination_address & 0x07;
+ destination_address -= destination_align;
+ mask_destination <<= destination_align / pTga->Bpp;
+ /* mask_destination &= cando_mask; */
+
+ if (destination_align >= source_align)
+ pixel_shift = destination_align - source_align;
+ else {
+ pixel_shift = 8 - (source_align - destination_align);
+ /* we need to prime the residue register in this case */
+ destination_address -= 8;
+ mask_destination <<= 8 / pTga->Bpp;
+ mask_destination &= cando_mask;/* ?? */
+ }
+
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ switch (pTga->Chipset) {
+ case PCI_CHIP_TGA2:
+ *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB;
+ *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB;
+ break;
+ case PCI_CHIP_DEC21030:
+ /* use GADR and GCTR */
+ TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG);
+ break;
+ }
+
+ source_address += (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp;
+ destination_address += cando * pTga->Bpp;
+
+ read += cando;
+ read -= destination_align / pTga->Bpp; /* "read" is perhaps better
+ called "written"... */
+ if (destination_align < source_align) {
+ read -= 8 / pTga->Bpp;
+ }
+ }
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+
+void
+TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w)
+ /* x1, y1 = source
+ x2, y2 = destination
+ w = width
+ */
+{
+ unsigned long a1, a2;
+ unsigned long source_address, destination_address;
+ unsigned int mask_source, mask_destination;
+ int cando;
+ unsigned int cando_mask;
+ int source_align, destination_align;
+ int pixel_shift;
+ int read;
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ cando = 32;
+ cando_mask = 0xFFFFFFFFU;
+ if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) {
+ cando = 16;
+ cando_mask = 0x0000FFFFU;
+ }
+
+ a1 = FB_OFFSET(x1, y1);
+ a2 = FB_OFFSET(x2, y2);
+
+ source_address = FB_OFFSET((x1 + w) - cando, y1);
+ destination_address = FB_OFFSET((x2 + w) - cando, y2);
+
+#if 0
+ ErrorF("CPY-BWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx"
+ " a1 0x%lx a2 0x%lx\n",
+ x1, y1, x2, y2, w, source_address, destination_address, a1, a2);
+#endif
+
+ read = 0;
+ while (read < w) {
+ mask_source = cando_mask;
+ if ((w - read) >= cando)
+ mask_destination = cando_mask;
+ else {
+ mask_destination = ((unsigned int)cando_mask) << (cando - (w - read));
+ mask_destination &= cando_mask; /* esp. for cando==16 */
+ }
+
+ source_align = source_address & 0x07;
+ destination_align = destination_address & 0x07;
+
+ if (read == 0 && destination_align &&
+ (source_align > destination_align)) {
+ /* we want to take out all the destination_align pixels in one
+ little copy first, then move on to the main stuff */
+ unsigned long tmp_src, tmp_dest;
+ unsigned int tmp_src_mask, tmp_dest_mask;
+
+ tmp_src = a1 + (w - (source_align / pTga->Bpp)) * pTga->Bpp;
+ tmp_dest = a2 + (w - (destination_align / pTga->Bpp) - (8 / pTga->Bpp)) * pTga->Bpp;
+ tmp_src_mask = cando_mask;
+ tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align) / pTga->Bpp;
+ tmp_dest_mask <<= 8 / pTga->Bpp;
+ pixel_shift = (8 - source_align) + destination_align;
+#if 0
+ ErrorF("CPY-BWD - preliminary copy: sa = %d, da = %d, ps =%d\n",
+ source_align, destination_align, pixel_shift);
+#endif
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_TGA2:
+ *(unsigned int *)(pTga->FbBase + tmp_src) = tmp_src_mask; WMB;
+ *(unsigned int *)(pTga->FbBase + tmp_dest) = tmp_dest_mask; WMB;
+ break;
+ case PCI_CHIP_DEC21030:
+ /* use GADR and GCTR */
+ TGA_FAST_WRITE_REG(tmp_src, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(tmp_src_mask, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(tmp_dest, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(tmp_dest_mask, TGA_CONTINUE_REG);
+ break;
+ }
+
+ source_address += (8 - source_align);
+ mask_source >>= (8 - source_align) / pTga->Bpp;
+ mask_source >>= destination_align / pTga->Bpp;
+ mask_destination >>= destination_align / pTga->Bpp;
+ }
+ else if (read == 0 && (source_align != destination_align)) {
+ source_address += (8 - source_align);
+ /* mask_source >>= (8 - source_align); */
+ /* if we uncomment this, it breaks...TGA tries to
+ optimize away a read of our last pixels... */
+ }
+ else if (source_align) {
+ source_address += (8 - source_align);
+ mask_source >>= (8 - source_align) / pTga->Bpp;
+ }
+
+ if (destination_align) {
+ destination_address += (8 - destination_align);
+ mask_destination >>= (8 - destination_align) / pTga->Bpp;
+ }
+
+ if (destination_align >= source_align)
+ pixel_shift = destination_align - source_align;
+ else {
+ pixel_shift = (8 - source_align) + destination_align;
+ if (destination_align) {
+ source_address += 8;
+ mask_source >>= 8 / pTga->Bpp;
+ }
+ }
+
+#if 0
+ ErrorF("CPY-BWD - normal: sadr 0x%lx sm 0x%x dadr 0x%lx dm 0x%x"
+ " sa %d da %d ps %d read %d\n",
+ source_address, mask_source,
+ destination_address, mask_destination,
+ source_align, destination_align, pixel_shift, read);
+#endif
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ switch (pTga->Chipset) {
+ case PCI_CHIP_TGA2:
+ *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB;
+ *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB;
+ break;
+ case PCI_CHIP_DEC21030:
+ /* use GADR and GCTR */
+ TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG);
+ break;
+ }
+
+/* if(read == 0) */
+/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */
+/* pixel_shift); */
+
+ if (destination_align > source_align) {
+ source_address -= cando * pTga->Bpp - 8;
+ destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp;
+ if (read == 0)
+ read += (cando - 8 / pTga->Bpp) + source_align / pTga->Bpp;
+ else
+ read += cando - 8 / pTga->Bpp;
+ }
+ else if (destination_align == source_align) {
+ source_address -= cando * pTga->Bpp;
+ destination_address -= cando * pTga->Bpp;
+ if (read == 0 && destination_align)
+ read += (cando - (8 - destination_align) / pTga->Bpp);
+ else
+ read += cando;
+ }
+ else if (source_align > destination_align) {
+ source_address -= cando * pTga->Bpp - 8;
+ destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp;
+ /* only happens when read == 0 */
+ if (destination_align)
+ read += (cando - 16 / pTga->Bpp) + source_align / pTga->Bpp;
+ else
+ read += cando - pixel_shift / pTga->Bpp;
+ }
+ }
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+ unsigned int fgcolor = 0, bgcolor = 0, pmask = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */
+/* patx, paty, fg, bg, rop, planemask); */
+
+ if(bg == -1) /* we are transparent */
+ pTga->transparent_pattern_p = 1;
+ else
+ pTga->transparent_pattern_p = 0;
+
+ if(rop == MIX_SRC)
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ else
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+
+ if(pTga->depthflag == BPP8PACKED) {
+ fgcolor = fg | (fg << 8) | (fg << 16) | (fg << 24);
+ bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24);
+ pmask = planemask | (planemask << 8) | (planemask << 16) |
+ (planemask << 24);
+ }
+ else {
+ fgcolor = fg;
+ bgcolor = bg;
+ pmask = planemask;
+ }
+
+
+ if(pTga->transparent_pattern_p &&
+ pTga->block_or_opaque_p == USE_BLOCK_FILL) {
+ /* we can use block fill mode to draw a transparent stipple */
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG);
+ if(pTga->depthflag == BPP24) {
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG);
+ }
+ }
+ else if(pTga->transparent_pattern_p) {
+ TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG);
+ }
+ else {
+ TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG);
+ TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
+ }
+ pTga->current_rop = rop;
+ pTga->current_planemask = pmask;
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+/* patx and paty = first & second dwords of pattern to be rendered, packed */
+{
+ TGAPtr pTga;
+ int i, j;
+ unsigned int stipple_mask[8], align, tmp;
+#ifdef PROFILE
+ register unsigned int stop, start;
+#endif
+ TGA_DECL();
+
+
+/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); */
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ if(w > 2048)
+ ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n");
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+ if(pTga->depthflag == BPP8PACKED)
+ align = FB_OFFSET(x, y) % 4;
+ else
+ align = x % 4;
+
+ for(i = 0; i < 4; i++) {
+ tmp = (patx >> (i * 8)) & 0xFF;
+ stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24));
+ }
+ for(i = 4; i < 8; i++) {
+ tmp = (paty >> ((i - 4) * 8)) & 0xFF;
+ stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24));
+ }
+ if(align) { /* stipples must be aligned to four bytes */
+ for(i = 0; i < 8; i++) {
+ stipple_mask[i] = (stipple_mask[i] << align) |
+ ((stipple_mask[i] & 0xFF000000) >> (32 - align));
+ }
+ }
+
+ if((pTga->block_or_opaque_p == USE_BLOCK_FILL) && pTga->transparent_pattern_p) {
+ /* use block fill */
+ TGA_FAST_WRITE_REG(BLOCKFILL | X11 | pTga->depthflag, TGA_MODE_REG);
+
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+ else if(pTga->transparent_pattern_p) {
+ /* if we can't use block fill, we'll use transparent fill */
+ TGA_FAST_WRITE_REG(TRANSPARENTFILL | X11 | pTga->depthflag, TGA_MODE_REG);
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+ else { /* use opaque fill mode */
+/* ErrorF("Using opaque fill mode\n"); */
+ TGA_FAST_WRITE_REG(OPAQUEFILL | X11 | pTga->depthflag, TGA_MODE_REG);
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+void
+TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga = NULL;
+ unsigned int fgcolor = 0, pmask = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+/* ErrorF("TGASetupForSolidLine called\n"); */
+
+ if(pTga->depthflag == BPP8PACKED) {
+ fgcolor = color | (color << 8) | (color << 16) | (color << 24);
+ pmask = planemask | (planemask << 8) | (planemask << 16) |
+ (planemask << 24);
+ }
+ else {
+ fgcolor = color;
+ pmask = planemask;
+ }
+
+
+ pTga->current_rop = rop | pTga->depthflag;
+ TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG);
+ pTga->current_planemask = pmask;
+ TGA_FAST_WRITE_REG(0xFFFF, TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG);
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+void
+TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
+ int dir)
+{
+ if(dir == DEGREES_0) /* line is to the right */
+ TGASubsequentSolidLine(pScrn, x, y, x + len, y, 0x0, OMIT_LAST);
+ else if(dir == DEGREES_270) /* line is down */
+ TGASubsequentSolidLine(pScrn, x, y, x, y + len, YMAJOR, OMIT_LAST);
+ else
+ ErrorF("TGASubsequentSolidHorVertLine passed dir %d!\n", dir);
+
+ return;
+}
+
+void
+TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant, int flags)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga = NULL;
+ CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0;
+ int length = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+/* ErrorF("TGASubsequentSolidLine called\n"); */
+
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag |
+ ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+
+ address = FB_OFFSET(x1, y1);
+ TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG);
+ abs_dx = abs(x2 - x1);
+ abs_dy = abs(y2 - y1);
+ if(octant & YMAJOR)
+ length = abs_dy;
+ else
+ length = abs_dx;
+
+ if(octant & YMAJOR) {
+ if(octant & YDECREASING) {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE0_REG;
+ else
+ octant_reg = TGA_SLOPE2_REG;
+ }
+ else {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE1_REG;
+ else
+ octant_reg = TGA_SLOPE3_REG;
+ }
+ }
+ else {
+ if(octant & YDECREASING) {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE4_REG;
+ else
+ octant_reg = TGA_SLOPE6_REG;
+ }
+ else {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE5_REG;
+ else
+ octant_reg = TGA_SLOPE7_REG;
+ }
+ }
+
+ TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg);
+ if(length > 16 && length % 16)
+ length -= length % 16;
+ else
+ length -= 16;
+
+ while(length > 0) {
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG);
+ length -= 16;
+ }
+
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+void
+TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga = NULL;
+ CARD32 abs_dx = 0, abs_dy = 0, octant_reg = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+/* ErrorF("TGASetupForClippedLine called\n"); */
+
+/* TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG); */
+/* TGA_FAST_WRITE_REG(OPAQUELINE | X11 | BPP8PACKED, TGA_MODE_REG); */
+
+ abs_dx = abs(x2 - x1);
+ abs_dy = abs(y2 - y1);
+
+ if(octant & YMAJOR) {
+ if(octant & YDECREASING) {
+ if(octant & XDECREASING)
+ octant_reg = TGA_NOSLOPE0_REG;
+ else
+ octant_reg = TGA_NOSLOPE2_REG;
+ }
+ else {
+ if(octant & XDECREASING)
+ octant_reg = TGA_NOSLOPE1_REG;
+ else
+ octant_reg = TGA_NOSLOPE3_REG;
+ }
+ }
+ else {
+ if(octant & YDECREASING) {
+ if(octant & XDECREASING)
+ octant_reg = TGA_NOSLOPE4_REG;
+ else
+ octant_reg = TGA_NOSLOPE6_REG;
+ }
+ else {
+ if(octant & XDECREASING)
+ octant_reg = TGA_NOSLOPE5_REG;
+ else
+ octant_reg = TGA_NOSLOPE7_REG;
+ }
+ }
+
+ TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg);
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
+ int err)
+ /* we are already in line mode, now we need to
+ 1) write starting pixel address to gaddr
+ 2) write initial error and line length to bresenham 3
+ 3) write the gctr to draw the line, and repeat for lines > 16 pixels
+ 4) set mode back to simple mode
+ */
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga = NULL;
+ CARD32 address = 0;
+ int length = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+/* ErrorF("TGASubsequentClippedSolidLine called\n"); */
+
+ address = FB_OFFSET(x1, y1);
+ TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG);
+
+ TGA_FAST_WRITE_REG(pTga->current_rop | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+
+ length = len;
+ TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG);
+
+ while(length > 0) {
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG);
+ if(length > 16 && length % 16)
+ length -= length % 16;
+ else
+ length -= 16;
+ }
+
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+
+}
+
+void
+TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length,
+ unsigned char *pattern)
+{
+#ifdef PROFILE
+ unsigned int start = 0, stop = 0;
+#endif
+ TGAPtr pTga = NULL;
+ unsigned int color1 = 0, color2 = 0, pmask = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+/* ErrorF("TGASetupForDashedLine called\n"); */
+
+ if(pTga->depthflag == BPP8PACKED) {
+ color1 = fg | (fg << 8) | (fg << 16) | (fg << 24);
+ color2 = bg | (bg << 8) | (bg << 16) | (bg << 24);
+ pmask = planemask | (planemask << 8) | (planemask << 16)
+ | (planemask << 24);
+ }
+ else {
+ color1 = fg;
+ color2 = fg;
+ pmask = planemask;
+ }
+
+ pTga->current_rop = rop | pTga->depthflag;
+ TGA_FAST_WRITE_REG(color1, TGA_FOREGROUND_REG);
+ pTga->current_planemask = pmask;
+ if(bg == -1) /* transparent line */
+ pTga->transparent_pattern_p = 1;
+ else {
+ pTga->transparent_pattern_p = 0;
+ TGA_FAST_WRITE_REG(color2, TGA_BACKGROUND_REG);
+ }
+
+ pTga->line_pattern = pattern[0] | (pattern[1] << 8);
+ pTga->line_pattern_length = length;
+
+ TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG);
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+void
+TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int octant, int flags, int phase)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga = NULL;
+ CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0;
+ int length = 0;
+ CARD16 line_mask = 0;
+ int pattern_overflow = 0;
+ int l = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+/* ErrorF("TGASubsequentDashedLine called\n"); */
+
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+ if(pTga->transparent_pattern_p)
+ TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag |
+ ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS),
+ TGA_MODE_REG);
+ else
+ TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag |
+ ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS),
+ TGA_MODE_REG);
+
+ address = FB_OFFSET(x1, y1);
+ TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG);
+ abs_dx = abs(x2 - x1);
+ abs_dy = abs(y2 - y1);
+ if(abs_dx > abs_dy)
+ length = abs_dx;
+ else
+ length = abs_dy;
+
+ if(octant & YMAJOR) {
+ if(octant & YDECREASING) {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE0_REG;
+ else
+ octant_reg = TGA_SLOPE2_REG;
+ }
+ else {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE1_REG;
+ else
+ octant_reg = TGA_SLOPE3_REG;
+ }
+ }
+ else {
+ if(octant & YDECREASING) {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE4_REG;
+ else
+ octant_reg = TGA_SLOPE6_REG;
+ }
+ else {
+ if(octant & XDECREASING)
+ octant_reg = TGA_SLOPE5_REG;
+ else
+ octant_reg = TGA_SLOPE7_REG;
+ }
+ }
+ /* set up our first pattern with phase. Keep track of if we overflow the
+ pattern by pattern_overflow, and correct on the next write */
+
+ if(phase) {
+ line_mask = pTga->line_pattern >> phase;
+ l = (pTga->line_pattern_length - phase);
+ }
+ else {
+ line_mask = pTga->line_pattern;
+ l = pTga->line_pattern_length;
+ }
+
+ while(l < 16) {
+ line_mask |= pTga->line_pattern << l;
+ l += pTga->line_pattern_length;
+ }
+ pattern_overflow = l - 16;
+
+ TGA_FAST_WRITE_REG(line_mask, TGA_DATA_REG);
+
+ TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg);
+
+ if(length > 16 && length % 16)
+ length -= length % 16;
+ else
+ length -= 16;
+
+ while(length > 0) {
+
+ if(pattern_overflow) {
+ line_mask = pTga->line_pattern >> (pTga->line_pattern_length -
+ pattern_overflow);
+ l = pattern_overflow;
+ }
+ else {
+ line_mask = pTga->line_pattern;
+ l = pTga->line_pattern_length;
+ }
+ while(l < 16) {
+ line_mask |= (pTga->line_pattern << l);
+ l += pTga->line_pattern_length;
+ }
+ pattern_overflow = l - 16;
+
+ TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG);
+ length -= 16;
+ }
+
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+void
+TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
+ int err, int phase)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga = NULL;
+ CARD32 address = 0;
+ int length = 0;
+ CARD16 line_mask = 0;
+ int pattern_overflow = 0;
+ int l = 0;
+ TGA_DECL();
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+ /* ErrorF("TGASubsequentClippedDashedLine called\n"); */
+
+ address = FB_OFFSET(x1, y1);
+ TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG);
+
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG);
+
+ if(pTga->transparent_pattern_p)
+ TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag, TGA_MODE_REG);
+ else
+ TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG);
+
+ length = len;
+ TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG);
+
+
+ if(phase) {
+ line_mask = pTga->line_pattern >> phase;
+ l = (pTga->line_pattern_length - phase);
+ }
+ else {
+ line_mask = pTga->line_pattern;
+ l = pTga->line_pattern_length;
+ }
+
+ while(l < 16) {
+ line_mask |= pTga->line_pattern << l;
+ l += pTga->line_pattern_length;
+ }
+ pattern_overflow = l - 16;
+
+
+ while(length > 0) {
+ TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG);
+
+ if(pattern_overflow) {
+ line_mask = pTga->line_pattern >> (pTga->line_pattern_length -
+ pattern_overflow);
+ l = pattern_overflow;
+ }
+ else {
+ line_mask = pTga->line_pattern;
+ l = pTga->line_pattern_length;
+ }
+ while(l < 16) {
+ line_mask |= (pTga->line_pattern << l);
+ l += pTga->line_pattern_length;
+ }
+ pattern_overflow = l - 16;
+
+ if(length > 16 && length % 16)
+ length -= length % 16;
+ else
+ length -= 16;
+ }
+
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
diff --git a/src/tga_cursor.c b/src/tga_cursor.c
new file mode 100644
index 0000000..1c2d359
--- /dev/null
+++ b/src/tga_cursor.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright 1999 by Matthew Grossman, Seattle, USA.
+ *
+ * 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 Matthew
+ * Grossman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Matthew Grossman makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MATTHEW GROSSMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MATTHEW GROSSMAN 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: Matthew Grossman, mattg@oz.net
+ *
+ * DEC TGA hardware cursor using BT485 ramdac
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c,v 1.2 2000/10/20 12:57:26 alanh Exp $ */
+
+
+/* tga_cursor.c */
+
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "BT.h"
+
+#include "tga.h"
+#include "tga_regs.h"
+
+/* defines */
+/* BT485 also supports 32 bit cursor, but why use it? */
+#define CURSOR_SIZE 64
+
+/* protos */
+
+static void TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
+static void TGAShowCursor(ScrnInfoPtr pScrn);
+static void TGAHideCursor(ScrnInfoPtr pScrn);
+static void TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+
+static void
+TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ int i;
+
+ /* set 64 bit cursor */
+ pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04);
+
+ /* first write address reg @ 0x0, then write 0xb with the data (for 32 bit
+ cursor) */
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
+
+ for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
+
+ for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
+
+/* pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); */
+
+ return;
+}
+
+
+static void
+TGAShowCursor(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ /* enable BT485 X11 cursor */
+ pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x03);
+
+ return;
+}
+
+
+static void
+TGAHideCursor(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x00);
+
+ return;
+}
+
+static void
+TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ unsigned int tmp_x, tmp_y;
+
+ /* translate x && y to BT485 cursor addresses */
+
+ tmp_x = x + CURSOR_SIZE;
+ tmp_x &= 0x0FFF;
+
+ tmp_y = y + CURSOR_SIZE;
+ tmp_y &= 0x0FFF;
+
+ /* write out the addresses */
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, (tmp_x & 0xFF));
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, (tmp_x >> 8));
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, (tmp_y & 0xFF));
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, (tmp_y >> 8));
+
+ return;
+}
+
+
+static void
+TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+ /* set pScrn->cursor_fg and pScrn->cursor_bg */
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ /* first, load address register at 0x4 with 0x1, then write 3 color
+ octets RGB to 0x5 (background), then write three octets to 0x5
+ (foreground), then write to address register 0xFC */
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
+
+ /* we don't seem to support the 6 bit DAC option as of 4.0, and why
+ would we? */
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x00FF0000) >> 16);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x0000FF00) >> 8);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x000000FF));
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x00FF0000) >> 16);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x0000FF00) >> 8);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x000000FF));
+
+/* pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x00); */
+
+ return;
+}
+
+
+Bool
+TGAHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TGAPtr pTga;
+ xf86CursorInfoPtr infoPtr;
+
+ pTga = TGAPTR(pScrn);
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pTga->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = CURSOR_SIZE;
+ infoPtr->MaxHeight = CURSOR_SIZE;
+ infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
+
+ infoPtr->SetCursorColors = TGASetCursorColors;
+ infoPtr->SetCursorPosition = TGASetCursorPosition;
+ infoPtr->LoadCursorImage = TGALoadCursorImage;
+ infoPtr->HideCursor = TGAHideCursor;
+ infoPtr->ShowCursor = TGAShowCursor;
+ infoPtr->UseHWCursor = NULL;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
diff --git a/src/tga_dac.c b/src/tga_dac.c
new file mode 100644
index 0000000..ec5f866
--- /dev/null
+++ b/src/tga_dac.c
@@ -0,0 +1,846 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * 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.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_dac.c,v 1.14 2001/10/28 03:33:50 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "BT.h"
+#include "tga_regs.h"
+#include "tga.h"
+
+static void ICS1562ClockSelect(ScrnInfoPtr pScrn, int freq);
+static void ICS9110ClockSelect(ScrnInfoPtr pScrn, int freq);
+extern void ICS1562_CalcClockBits(long f, unsigned char *bits);
+
+static void
+ICS1562ClockSelect(ScrnInfoPtr pScrn, int freq)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ unsigned char pll_bits[7];
+ unsigned long temp;
+ int i, j;
+
+ /* There lies an ICS1562 Clock Generator. */
+ ICS1562_CalcClockBits(freq, pll_bits);
+
+ /*
+ * For the DEC 21030 TGA:
+ * This requires the 55 clock bits be written in a serial manner to
+ * bit 0 of the CLOCK register and on the 56th bit set the hold flag.
+ */
+ for (i = 0;i <= 6; i++) {
+ for (j = 0; j <= 7; j++) {
+ temp = (pll_bits[i] >> (7-j)) & 1;
+ if (i == 6 && j == 7)
+ temp |= 2;
+ TGA_WRITE_REG(temp, TGA_CLOCK_REG);
+ }
+ }
+}
+
+struct monitor_data tga_crystal_table[] = {
+{
+/* Option 0 Monitor Info 130.8 */
+1024, /* rows */
+1280, /* columns */
+130, /* 130.8 Mhz */
+72, /* refresh rate */
+1024, /* v scanlines */
+3, /* v front porch */
+3, /* v sync */
+33, /* v back porch */
+1280, /* h pixels */
+32, /* h front porch */
+160, /* h sync */
+232, /* h back porch */
+/* AV9110 clock serial load information 130.808 */
+0x40, /* 0:6 VCO frequency divider N */
+0x7, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* IBM561 PLL setup data 130.808 */
+0xC8, /* VCO Div: PFR=0x3, M-65=49 */
+0x8 /* REF: N=0x8 */
+},
+{
+/* Option 3 Monitor Info 104.00 Mhz */
+900, /* rows */
+1152, /* columns */
+104, /* 104 Mhz */
+72, /* refresh rate */
+900, /* v scanlines */
+6, /* v front porch */
+10, /* v sync */
+44, /* v back porch */
+1152, /* h pixels */
+64, /* h front porch */
+112, /* h sync */
+176, /* h back porch */
+/* 103.994 MHz av9110 clock serial load information */
+0x6d, /* 0:6 VCO frequency divider N */
+0xf, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 104.00 MHz IBM561 PLL setup data */
+0x96, /* VCO Div: PFR=2, M=57 */
+0x6 /* REF: N=6 */
+},
+#if 1
+{
+/* Option 6 Monitor Info 74.00 Mhz */
+768, /* rows */
+1024, /* columns */
+74, /* 74 Mhz */
+72, /* refresh rate */
+768, /* v scanlines */
+1, /* v front porch */
+6, /* v sync */
+22, /* v back porch */
+1024, /* h pixels */
+16, /* h front porch */
+128, /* h sync */
+128, /* h back porch */
+/* 74.00 MHz AV9110 clock serial load information */
+0x2a, /* 0:6 VCO frequency divider N */
+0x41, /* 7:13 Reference frequency divide M */
+0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 74.00 MHz IBM561 PLL setup data */
+0x9C, /* VCO Div: PFR=2, M=0x5D*/
+0x9 /* REF: N=0x9 */
+},
+#else
+{
+/* Option 5 Monitor Info 75.00 Mhz */
+768, /* rows */
+1024, /* columns */
+75, /* 74 Mhz */
+70, /* refresh rate */
+768, /* v scanlines */
+3, /* v front porch */
+6, /* v sync */
+29, /* v back porch */
+1024, /* h pixels */
+24, /* h front porch */
+136, /* h sync */
+144, /* h back porch */
+/* 75.00 MHz AV9110 clock serial load information */
+0x6e, /* 0:6 VCO frequency divider N */
+0x15, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 75.00 MHz IBM561 PLL setup data */
+0x93, /* VCO Div: PFR=2, M=0x54 */
+0x8 /* REF: N=0x8 */
+},
+#endif
+{
+/* Option 9 Monitor Info 50 Mhz ergo SVGA */
+600, /* rows */
+800, /* columns */
+50, /* 50 Mhz */
+72, /* refresh rate */
+600, /* v scanlines */
+37, /*(31 tga)v front porch */
+6, /* v sync */
+23, /*(29 tga)v back porch */
+800, /* h pixels */
+56, /* h front porch */
+120, /* h sync */
+64, /* h back porch */
+/*50.00 Mhz AV9110 clock serial load information */
+0x37, /* 0:6 VCO frequency divider N */
+0x3f, /* 7:13 Reference frequency divide M */
+0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 50.00 MHz IBM561 PLL setup data */
+0x45, /* VCO Div: PFR=1, M=46*/
+0x5 /* REF: N=5 */
+},
+{
+/* Option B Monitor Info 31.5 Mhz ergo VGA */
+480, /* rows */
+640, /* columns */
+32, /* 32 Mhz */
+72, /* refresh rate */
+480, /* v scanlines */
+9, /* v front porch */
+3, /* v sync */
+28, /* v back porch */
+640, /* h pixels */
+24, /* h front porch */
+40, /* h sync */
+128, /* h back porch */
+/* 31.50 MHz AV9110 clock serial load information */
+0x16, /* 0:6 VCO frequency divider N */
+0x05, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 31.50 MHz IBM561 PLL setup data */
+0x17, /* VCO Div: PFR=0, M=0x58 */
+0x5 /* REF: N=0x5 */
+},
+#ifdef ALLOW_LT_72_HZ
+{
+/* Option 1 Monitor Info 119.84 Mhz */
+1024, /* rows */
+1280, /* columns */
+119, /* 119 Mhz */
+66, /* refresh rate */
+1024, /* v scanlines */
+3, /* v front porch */
+3, /* v sync */
+33, /* v back porch */
+1280, /* h pixels */
+32, /* h front porch */
+160, /* h sync */
+232, /* h back porch */
+/* 119.84MHz AV9110 clock serial load information */
+0x2d, /* 0:6 VCO frequency divider N */
+0x2b, /* 7:13 Reference frequency divide M */
+0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* IBM561 PLL setup data 119.84 */
+0x82, /* VCO Div: PFR=0x2, M=0x43 */
+0x4 /* REF: N=0x4 */
+},
+{
+/* Option 2 Monitor Info 108.18 Mhz */
+1024, /* rows */
+1280, /* columns */
+108, /* 108 Mhz */
+60, /* refresh rate */
+1024, /* v scanlines */
+3, /* v front porch */
+3, /* v sync */
+26, /* v back porch */
+1280, /* h pixels */
+44, /* h front porch */
+184, /* h sync */
+200, /* h back porch */
+/* 108.18 MHz av9110 Clk serial load information */
+0x11, /* 0:6 VCO frequency divider N */
+0x9, /* 7:13 Reference frequency divide M */
+0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 108.18 MHz IBM561 PLL setup data */
+0xB8, /* VCO Div: PFR=2, M=79 */
+0x8 /* REF: N=0x8 */
+},
+{
+/* Option 5 Monitor Info 75.00 Mhz */
+768, /* rows */
+1024, /* columns */
+75, /* 74 Mhz */
+70, /* refresh rate */
+768, /* v scanlines */
+3, /* v front porch */
+6, /* v sync */
+29, /* v back porch */
+1024, /* h pixels */
+24, /* h front porch */
+136, /* h sync */
+144, /* h back porch */
+/* 75.00 MHz AV9110 clock serial load information */
+0x6e, /* 0:6 VCO frequency divider N */
+0x15, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 75.00 MHz IBM561 PLL setup data */
+0x93, /* VCO Div: PFR=2, M=0x54 */
+0x8 /* REF: N=0x8 */
+},
+{
+/* Option 7 Monitor Info 69 Mhz DEC 72 Hz */
+864, /* rows */
+1024, /* columns */
+69, /* 69.x Mhz */
+60, /* refresh rate */
+864, /* v scanlines */
+0, /* v front porch */
+3, /* v sync */
+34, /* v back porch */
+1024, /* h pixels */
+12, /* h front porch */
+128, /* h sync */
+116, /* h back porch */
+/* 69.00 Mhz AV9110 clock serial load information */
+0x35, /* 0:6 VCO frequency divider N */
+0xb, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 69.00 MHz IBM561 PLL setup data */
+0xA9, /* VCO Div: PFR=2, M=0x6A */
+0xB /* REF: N=0xB */
+},
+{
+/* Option 8 Monitor Info 65 Mhz */
+768, /* rows */
+1024, /* columns */
+65, /* 65 Mhz */
+60, /* refresh rate */
+768, /* v scanlines */
+7, /* v front porch */
+9, /* v sync */
+26, /* v back porch */
+1024, /* h pixels */
+56, /* h front porch */
+64, /* h sync */
+200, /* h back porch */
+/* 65.00 MHz AV9110 clock serial load information */
+0x6d, /* 0:6 VCO frequency divider N */
+0x0c, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 65.00 MHz IBM561 PLL setup data */
+0xAC, /* VCO Div: PFR=2, M=0x6D */
+0xC /* REF: N=0xC */
+},
+{
+/* Option A Monitor Info 40 Mhz SVGA */
+600, /* rows */
+800, /* columns */
+40, /* 40 Mhz */
+60, /* refresh rate */
+600, /* v scanlines */
+1, /* v front porch */
+4, /* v sync */
+23, /* v back porch */
+800, /* h pixels */
+40, /* h front porch */
+128, /* h sync */
+88, /* h back porch */
+/* 40.00 MHz AV9110 clock serial load information */
+0x5f, /* 0:6 VCO frequency divider N */
+0x11, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 40.00 MHz IBM561 PLL setup data */
+0x42, /* VCO Div: PFR=1, M=43 */
+0x6 /* REF: N=0x6 */
+},
+{
+/* Option C Monitor Info 25.175 Mhz VGA */
+480, /* rows */
+640, /* columns */
+25, /* 25.175 Mhz */
+60, /* refresh rate */
+480, /* v scanlines */
+10, /* v front porch */
+2, /* v sync */
+33, /* v back porch */
+640, /* h pixels */
+16, /* h front porch */
+96, /* h sync */
+48, /* h back porch */
+/* 25.175 MHz AV9110 clock serial load information */
+0x66, /* 0:6 VCO frequency divider N */
+0x1d, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 25.175 MHz IBM561 PLL setup data */
+0x3E, /* VCO Div: PFR=0, M=0x7F */
+0x9 /* REF: N=0x9 */
+},
+{
+/* Option E Monitor Info 110 Mhz */
+1024, /* rows */
+1280, /* columns */
+110,
+60, /* refresh rate */
+1024, /* v scanlines */
+6, /* v front porch */
+7, /* v sync */
+44, /* v back porch */
+1280, /* h pixels */
+19, /* h front porch */
+163, /* h sync */
+234, /* h back porch */
+/* 110.0 MHz AV9110 clock serial load information */
+0x60, /* 0:6 VCO frequency divider N */
+0x32, /* 7:13 Reference frequency divide M */
+0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 110.0 MHz IBM561 PLL setup data */
+0xBA, /* VCO Div: PFR=0x2, M=0x7B */
+0x8 /* REF: N=0x8 */
+},
+#endif /* ALLOW_LT_72_HZ */
+#ifdef ALLOW_GT_72_HZ
+{
+/* Option D Monitor Info 135 Mhz */
+1024, /* rows */
+1280, /* columns */
+135, /* 135 Mhz */
+75, /* refresh rate */
+1024, /* v scanlines */
+1, /* v front porch */
+3, /* v sync */
+38, /* v back porch */
+1280, /* h pixels */
+16, /* h front porch */
+144, /* h sync */
+248, /* h back porch */
+/* 135.0 MHz AV9110 clock serial load information */
+0x42, /* 0:6 VCO frequency divider N */
+0x07, /* 7:13 Reference frequency divide M */
+0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 135.0 MHz IBM561 PLL setup data */
+0xC1, /* VCO Div: PFR=0x3, M=0x42 */
+0x7 /* REF: N=0x7 */
+},
+#ifdef ALLOW_GT_1280x1024
+{
+/* Option 4 Monitor Info 175.5 Mhz (8-plane) */
+1200, /* rows */
+1600, /* columns */
+175, /* clock */
+65, /* refresh rate */
+1200, /* v scanlines */
+1, /* v front porch */
+3, /* v sync */
+46, /* v back porch */
+1600, /* h pixels */
+32, /* h front porch */
+192, /* h sync */
+336, /* h back porch */
+/* 110.0 MHz AV9110 clock serial load information */
+0x5F, /* 0:6 VCO frequency divider N */
+0x3E, /* 7:13 Reference frequency divide M */
+0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8)
+*/
+0x1, /* 15:16 CLK/X output divide X */
+0x1, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 110.0 MHz IBM561 PLL setup data */
+0xE1, /* VCO Div: PFR=0x3, M-65=0x21 */
+0x8 /* REF: N=0x8 */
+},
+{
+/* Option F Monitor Info (24-plane) */
+1200, /* rows */
+1600, /* columns */
+202.5, /* 130.8 Mhz */
+75, /* refresh rate */
+1200, /* v scanlines */
+1, /* v front porch */
+3, /* v sync */
+46, /* v back porch */
+1600, /* h pixels */
+32, /* h front porch */
+192, /* h sync */
+336, /* h back porch */
+/* AV9110 clock serial load information 130.808 */
+0x60, /* 0:6 VCO frequency divider N */
+0x32, /* 7:13 Reference frequency divide M */
+0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */
+0x1, /* 15:16 CLK/X output divide X */
+0x2, /* 17:18 VCO output divide R */
+1, /* 19 CLK Output enable. */
+1, /* 20 CLK/X Output enable */
+0, /* reserved, should be set to 0 */
+0, /* Reference clock select on CLK 1=ref */
+1, /* reserved, should be set to 1 */
+/* 110.0 MHz IBM561 PLL setup data */
+0xE2, /* bogus VCO Div: PFR=0x2, M=0x7B */
+0x7 /* bogus REF: N=0x8 */
+}
+#endif /* ALLOW_GT_1280x1024 */
+#endif /* ALLOW_GT_72_HZ */
+};
+
+int tga_crystal_table_entries = sizeof(tga_crystal_table)/sizeof(struct monitor_data);
+
+struct monitor_data *tga_c_table;
+
+/* ICS av9110 is only used on TGA2 */
+
+void
+write_av9110(ScrnInfoPtr pScrn, unsigned int *temp)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ /* the following is based on write_av9110() from the
+ TRU64 kernel TGA driver */
+
+ TGA2_WRITE_CLOCK_REG(0x0, 0xf800);
+ TGA2_WRITE_CLOCK_REG(0x0, 0xf000);
+
+ TGA2_WRITE_CLOCK_REG(temp[0], 0x0000);
+ TGA2_WRITE_CLOCK_REG(temp[1], 0x0000);
+ TGA2_WRITE_CLOCK_REG(temp[2], 0x0000);
+ TGA2_WRITE_CLOCK_REG(temp[3], 0x0000);
+ TGA2_WRITE_CLOCK_REG(temp[4], 0x0000);
+ TGA2_WRITE_CLOCK_REG(temp[5], 0x0000);
+
+ TGA2_WRITE_CLOCK_REG(0x0, 0xf800);
+}
+
+void TGA2SetupMode(ScrnInfoPtr pScrn)
+{
+ int i;
+
+ /*
+ * HACK HACK HACK
+ *
+ * We do not know how to generate arbitrary clocks, so we search
+ * the crystal_table above for a match. Sigh...
+ */
+ tga_c_table = tga_crystal_table;
+ for (i = 0; i < tga_crystal_table_entries; i++, tga_c_table++) {
+ if ((tga_c_table->max_rows == pScrn->currentMode->VDisplay) &&
+ (tga_c_table->max_cols == pScrn->currentMode->HDisplay)) {
+ ErrorF("Found a matching mode (%d)!\n", i);
+ break;
+ }
+ }
+ if (i == tga_crystal_table_entries) {
+#ifdef FOR_NOW
+ FatalError("Unable to find a workable mode");
+#else
+ ErrorF("Unable to find a matching mode!\n");
+ /* tga_c_table = &tga_crystal_table[4]; *//* 640x480 @ 72 */
+ tga_c_table = &tga_crystal_table[2]; /* 1024x768 @ 72 */
+#endif
+ }
+ return;
+}
+
+static void
+ICS9110ClockSelect(ScrnInfoPtr pScrn, int freq)
+{
+ unsigned int temp, temp1[6];
+
+ /* There lies an ICS9110 Clock Generator. */
+ /* ICS9110_CalcClockBits(freq, pll_bits); */
+
+ /* the following is based on munge_ics() from the
+ TRU64 kernel TGA driver */
+
+ temp = (unsigned int)(tga_c_table->vco_div |
+ (tga_c_table->ref_div << 7) |
+ (tga_c_table->vco_pre << 14) |
+ (tga_c_table->clk_div << 15) |
+ (tga_c_table->vco_out_div << 17) |
+ (tga_c_table->clk_out_en << 19) |
+ (tga_c_table->clk_out_enX << 20) |
+ (tga_c_table->res0 << 21) |
+ (tga_c_table->clk_sel << 22) |
+ (tga_c_table->res1 << 23));
+
+ temp1[0] = (temp & 0x00000001) | ((temp & 0x00000002) << 7) |
+ ((temp & 0x00000004) << 14) | ((temp & 0x00000008) << 21);
+
+ temp1[1] = ((temp & 0x00000010) >> 4) | ((temp & 0x00000020) << 3) |
+ ((temp & 0x00000040) << 10) | ((temp & 0x00000080) << 17);
+
+ temp1[2] = ((temp & 0x00000100) >> 8) | ((temp & 0x00000200) >> 1) |
+ ((temp & 0x00000400) << 6) | ((temp & 0x00000800) << 13);
+
+ temp1[3] = ((temp & 0x00001000) >> 12) | ((temp & 0x00002000) >> 5) |
+ ((temp & 0x00004000) << 2) | ((temp & 0x00008000) << 9);
+
+ temp1[4] = ((temp & 0x00010000) >> 16) | ((temp & 0x00020000) >> 9) |
+ ((temp & 0x00040000) >> 2) | ((temp & 0x00080000) << 5);
+
+ temp1[5] = ((temp & 0x00100000) >> 20) | ((temp & 0x00200000) >> 13) |
+ ((temp & 0x00400000) >> 6) | ((temp & 0x00800000) << 1);
+
+ write_av9110(pScrn, temp1);
+
+}
+
+void
+Ibm561Init(TGAPtr pTga)
+{
+ unsigned char *Ibm561 = pTga->Ibm561modeReg;
+ int i, j;
+
+/* ?? FIXME FIXME FIXME FIXME */
+
+ /* Command registers */
+ Ibm561[0] = 0x40; Ibm561[1] = 0x08;
+ Ibm561[2] = (pTga->SyncOnGreen ? 0x80 : 0x00);
+
+ /* Read mask */
+ Ibm561[3] = 0xff; Ibm561[4] = 0xff; Ibm561[5] = 0xff; Ibm561[6] = 0x0f;
+
+ /* Blink mask */
+ Ibm561[7] = 0x00; Ibm561[8] = 0x00; Ibm561[9] = 0x00; Ibm561[10] = 0x00;
+
+ /* Window attributes */
+ for (i = 0, j=11; i < 16; i++) {
+ Ibm561[j++] = 0x00; Ibm561[j++] = 0x01; Ibm561[j++] = 0x80;
+ }
+}
+
+void
+Bt463Init(TGAPtr pTga)
+{
+ unsigned char *Bt463 = pTga->Bt463modeReg;
+ int i, j;
+
+ /* Command registers */
+ Bt463[0] = 0x40; Bt463[1] = 0x08;
+ Bt463[2] = (pTga->SyncOnGreen ? 0x80 : 0x00);
+
+ /* Read mask */
+ Bt463[3] = 0xff; Bt463[4] = 0xff; Bt463[5] = 0xff; Bt463[6] = 0x0f;
+
+ /* Blink mask */
+ Bt463[7] = 0x00; Bt463[8] = 0x00; Bt463[9] = 0x00; Bt463[10] = 0x00;
+
+ /* Window attributes */
+ for (i = 0, j=11; i < 16; i++) {
+ Bt463[j++] = 0x00; Bt463[j++] = 0x01; Bt463[j++] = 0x80;
+ }
+}
+
+Bool
+DEC21030Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ TGARegPtr pReg = &pTga->ModeReg;
+
+ if (pTga->RamDac != NULL) { /* this really means 8-bit and BT485 */
+ RamDacHWRecPtr pBT = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr ramdacReg = &pBT->ModeReg;
+
+ ramdacReg->DacRegs[BT_COMMAND_REG_0] = 0xA0 |
+ (!pTga->Dac6Bit ? 0x2 : 0x0) | (pTga->SyncOnGreen ? 0x8 : 0x0);
+#if 1
+ ramdacReg->DacRegs[BT_COMMAND_REG_2] = 0x20;
+#else
+ ramdacReg->DacRegs[BT_COMMAND_REG_2] = 0x27; /* ?? was 0x20 */
+#endif
+ ramdacReg->DacRegs[BT_STATUS_REG] = 0x14;
+ (*pTga->RamDac->SetBpp)(pScrn, ramdacReg);
+
+ } else {
+ switch (pTga->Chipset) {
+ case PCI_CHIP_DEC21030: /* always BT463 */
+ Bt463Init(pTga);
+ break;
+ case PCI_CHIP_TGA2: /* always IBM 561 */
+ Ibm561Init(pTga);
+ break;
+ }
+ }
+
+ pReg->tgaRegs[0x00] = mode->CrtcHDisplay;
+ pReg->tgaRegs[0x01] = mode->CrtcHSyncStart - mode->CrtcHDisplay;
+ pReg->tgaRegs[0x02] = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 4;
+ pReg->tgaRegs[0x03] = (mode->CrtcHTotal - mode->CrtcHSyncEnd) / 4;
+ pReg->tgaRegs[0x04] = mode->CrtcVDisplay;
+ pReg->tgaRegs[0x05] = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ pReg->tgaRegs[0x06] = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ pReg->tgaRegs[0x07] = mode->CrtcVTotal - mode->CrtcVSyncEnd;
+
+ /*
+ * We do polarity the Step B way of the 21030
+ * Tell me how I can detect a Step A, and I'll support that too.
+ * But I think that the Step B's are most common
+ */
+ if (mode->Flags & V_PHSYNC)
+ pReg->tgaRegs[0x08] = 1; /* Horizontal Polarity */
+ else
+ pReg->tgaRegs[0x08] = 0;
+
+ if (mode->Flags & V_PVSYNC)
+ pReg->tgaRegs[0x09] = 1; /* Vertical Polarity */
+ else
+ pReg->tgaRegs[0x09] = 0;
+
+ pReg->tgaRegs[0x0A] = mode->Clock;
+
+ pReg->tgaRegs[0x10] = (((pReg->tgaRegs[0x00]) / 4) & 0x1FF) |
+ ((((pReg->tgaRegs[0x00]) / 4) & 0x600) << 19) |
+ (((pReg->tgaRegs[0x01]) / 4) << 9) |
+ (pReg->tgaRegs[0x02] << 14) |
+ (pReg->tgaRegs[0x03] << 21) |
+#if 0
+ (1 << 31) | /* ?? */
+#endif
+ (pReg->tgaRegs[0x08] << 30);
+ pReg->tgaRegs[0x11] = pReg->tgaRegs[0x04] |
+ (pReg->tgaRegs[0x05] << 11) |
+ (pReg->tgaRegs[0x06] << 16) |
+ (pReg->tgaRegs[0x07] << 22) |
+ (pReg->tgaRegs[0x09] << 30);
+
+ pReg->tgaRegs[0x12] = 0x01;
+
+ pReg->tgaRegs[0x13] = 0x0000;
+ return TRUE;
+}
+
+void
+DEC21030Save(ScrnInfoPtr pScrn, TGARegPtr tgaReg)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ tgaReg->tgaRegs[0x10] = TGA_READ_REG(TGA_HORIZ_REG);
+ tgaReg->tgaRegs[0x11] = TGA_READ_REG(TGA_VERT_REG);
+ tgaReg->tgaRegs[0x12] = TGA_READ_REG(TGA_VALID_REG);
+ tgaReg->tgaRegs[0x13] = TGA_READ_REG(TGA_BASE_ADDR_REG);
+
+ return;
+}
+
+void
+DEC21030Restore(ScrnInfoPtr pScrn, TGARegPtr tgaReg)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(0x00, TGA_VALID_REG); /* Disable Video */
+
+ switch (pTga->Chipset) {
+ case PCI_CHIP_DEC21030:
+ ICS1562ClockSelect(pScrn, tgaReg->tgaRegs[0x0A]);
+ break;
+ case PCI_CHIP_TGA2:
+ ICS9110ClockSelect(pScrn, tgaReg->tgaRegs[0x0A]);
+ break;
+ }
+
+ TGA_WRITE_REG(tgaReg->tgaRegs[0x10], TGA_HORIZ_REG);
+ TGA_WRITE_REG(tgaReg->tgaRegs[0x11], TGA_VERT_REG);
+ TGA_WRITE_REG(tgaReg->tgaRegs[0x13], TGA_BASE_ADDR_REG);
+
+ TGA_WRITE_REG(tgaReg->tgaRegs[0x12], TGA_VALID_REG); /* Re-enable Video */
+
+ return;
+}
diff --git a/src/tga_driver.c b/src/tga_driver.c
new file mode 100644
index 0000000..3822dc9
--- /dev/null
+++ b/src/tga_driver.c
@@ -0,0 +1,1766 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * 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.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Matthew Grossman, <mattg@oz.net> - acceleration and misc fixes
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c,v 1.58 2001/11/21 22:33:00 alanh Exp $ */
+
+/* everybody includes these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* PCI headers */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+/* module versioning */
+#include "xf86Version.h"
+
+/* RAC stuff */
+#include "xf86Resources.h"
+
+/* #include "vgaHW.h" */
+
+/* software cursor */
+#include "mipointer.h"
+/* backing store */
+#include "mibstore.h"
+
+/* #include "mibank.h" */
+/* colormap manipulation */
+#include "micmap.h"
+
+#include "fb.h"
+
+/* more RAC stuff */
+#include "xf86RAC.h"
+
+/* Gamma Correction? */
+#include "xf86cmap.h"
+
+#include "tga_regs.h"
+#include "BT.h"
+#include "tga.h"
+
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#include "Xv.h"
+#endif
+
+static const OptionInfoRec * TGAAvailableOptions(int chipid, int busid);
+static void TGAIdentify(int flags);
+static Bool TGAProbe(DriverPtr drv, int flags);
+static Bool TGAPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool TGAScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool TGAEnterVT(int scrnIndex, int flags);
+static void TGALeaveVT(int scrnIndex, int flags);
+static Bool TGACloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool TGASaveScreen(ScreenPtr pScreen, int mode);
+
+/* Required if the driver supports mode switching */
+static Bool TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+static void TGAAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void TGAFreeScreen(int scrnIndex, int flags);
+static int TGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static Bool TGAMapMem(ScrnInfoPtr pScrn);
+static Bool TGAUnmapMem(ScrnInfoPtr pScrn);
+static void TGASave(ScrnInfoPtr pScrn);
+static void TGARestore(ScrnInfoPtr pScrn);
+static Bool TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+static void TGARestoreHWCursor(ScrnInfoPtr pScrn);
+
+static void TGADisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+
+void TGASync(ScrnInfoPtr pScrn);
+
+#define VERSION 4000
+#define TGA_NAME "TGA"
+#define TGA_DRIVER_NAME "tga"
+#define TGA_MAJOR_VERSION 1
+#define TGA_MINOR_VERSION 0
+#define TGA_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * 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 TGA = {
+ VERSION,
+ TGA_DRIVER_NAME,
+ TGAIdentify,
+ TGAProbe,
+ TGAAvailableOptions,
+ NULL,
+ 0
+};
+
+static SymTabRec TGAChipsets[] = {
+ { PCI_CHIP_DEC21030, "tga" },
+ { PCI_CHIP_TGA2, "tga2" },
+ { -1, NULL }
+};
+
+static PciChipsets TGAPciChipsets[] = {
+ { PCI_CHIP_DEC21030, PCI_CHIP_DEC21030, NULL },
+ { PCI_CHIP_TGA2, PCI_CHIP_TGA2, NULL },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_RGB_BITS,
+ OPTION_NOACCEL,
+ OPTION_SYNC_ON_GREEN,
+ OPTION_DAC_6_BIT,
+ OPTION_NOXAAPOLYSEGMENT
+} TGAOpts;
+
+static const OptionInfoRec TGAOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_DAC_6_BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOXAAPOLYSEGMENT, "NoXaaPolySegment",OPTV_BOOLEAN,{0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static RamDacSupportedInfoRec BTramdacs[] = {
+ { BT485_RAMDAC },
+ { -1 }
+};
+
+static const char *ramdacSymbols[] = {
+ "BTramdacProbe",
+ "RamDacCreateInfoRec",
+ "RamDacDestroyInfoRec",
+ "RamDacFreeRec",
+ "RamDacGetHWIndex",
+ "RamDacHandleColormaps",
+ "RamDacInit",
+ "xf86CreateCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAGCIndex",
+ "XAAInit",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(tgaSetup);
+
+static XF86ModuleVersionInfo tgaVersRec =
+{
+ "tga",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ TGA_MAJOR_VERSION, TGA_MINOR_VERSION, TGA_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData tgaModuleData = { &tgaVersRec, tgaSetup, NULL };
+
+pointer
+tgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&TGA, module, 0);
+
+ /*
+ * Modules that this driver always requires can be loaded here
+ * by calling LoadSubModule().
+ */
+
+ LoaderRefSymLists(ramdacSymbols, fbSymbols, xaaSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+static unsigned int fb_offset_presets[4] = {
+ TGA_8PLANE_FB_OFFSET,
+ TGA_24PLANE_FB_OFFSET,
+ 0xffffffff,
+ TGA_24PLUSZ_FB_OFFSET
+};
+
+static char *tga_cardnames[4] = {
+ "TGA 8 Plane",
+ "TGA 24 Plane",
+ NULL,
+ "TGA 24 Plane 3D"
+};
+
+static Bool
+TGAGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an TGARec, 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(TGARec), 1);
+ /* Initialise it */
+
+
+ return TRUE;
+}
+
+static void
+TGAFreeRec(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ if (pScrn->driverPrivate == NULL)
+ return;
+
+ pTga = TGAPTR(pScrn);
+
+ if(pTga->buffers[0])
+ free(pTga->buffers[0]);
+
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+
+ return;
+}
+
+static const OptionInfoRec *
+TGAAvailableOptions(int chipid, int busid)
+{
+ return TGAOptions;
+}
+
+/* Mandatory */
+static void
+TGAIdentify(int flags)
+{
+ xf86PrintChipsets(TGA_NAME, "driver for Digital chipsets", TGAChipsets);
+ return;
+}
+
+
+/* Mandatory */
+static Bool
+TGAProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ 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.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(TGA_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(TGA_NAME, PCI_VENDOR_DIGITAL,
+ TGAChipsets, TGAPciChipsets, devSections, numDevSections,
+ drv, &usedChips);
+
+ xfree(devSections);
+ if (numUsed <= 0)
+ return FALSE;
+
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
+ /*
+ * Check that nothing else has claimed the slots.
+ */
+ ScrnInfoPtr pScrn = NULL;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ TGAPciChipsets, NULL, NULL,
+ NULL, NULL, NULL))) {
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = TGA_DRIVER_NAME;
+ pScrn->name = TGA_NAME;
+ pScrn->Probe = TGAProbe;
+ pScrn->PreInit = TGAPreInit;
+ pScrn->ScreenInit = TGAScreenInit;
+ pScrn->SwitchMode = TGASwitchMode;
+ pScrn->AdjustFrame = TGAAdjustFrame;
+ pScrn->EnterVT = TGAEnterVT;
+ pScrn->LeaveVT = TGALeaveVT;
+ pScrn->FreeScreen = TGAFreeScreen;
+ pScrn->ValidMode = TGAValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ xfree(usedChips);
+ return foundScreen;
+}
+
+#if 0
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ int *linePitches = NULL;
+ int i, n = 0;
+ int *linep = NULL;
+ /* TGAPtr pTga = TGAPTR(pScrn); */
+
+ for (i = 0; linep[i] != 0; i++) {
+ if (linep[i] != -1) {
+ n++;
+ linePitches = xnfrealloc(linePitches, n * sizeof(int));
+ linePitches[n - 1] = i << 5;
+ }
+ }
+
+ /* Mark the end of the list */
+ if (n > 0) {
+ linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
+ linePitches[n] = 0;
+ }
+ return linePitches;
+}
+#endif /* 0 */
+
+/* Mandatory */
+static Bool
+TGAPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ pciVideoPtr pciPtr;
+ TGAPtr pTga;
+ MessageType from;
+ int i;
+ ClockRangePtr clockRanges;
+ pointer Base;
+
+ if (flags & PROBE_DETECT) 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.
+ */
+
+ /* The ramdac module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+
+ /* Allocate the TGARec driverPrivate */
+ if (!TGAGetRec(pScrn)) {
+ return FALSE;
+ }
+ pTga = TGAPTR(pScrn);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*********************
+ Handle pci and chipset stuff
+ *********************/
+
+
+ /* This driver doesn't expect more than one entity per screen */
+ if (pScrn->numEntities > 1)
+ return FALSE;
+ /* This is the general case */
+ for (i = 0; i < pScrn->numEntities; i++) {
+ pTga->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ if (pTga->pEnt->resources) return FALSE;
+ pTga->Chipset = pTga->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(TGAChipsets,
+ pTga->pEnt->chipset);
+
+ /* TGA is purely PCI */
+ if (pTga->pEnt->location.type == BUS_PCI) {
+ pciPtr = xf86GetPciInfoForEntity(pTga->pEnt->index);
+ pTga->PciInfo = pciPtr;
+ pTga->PciTag = pciTag(pTga->PciInfo->bus,
+ pTga->PciInfo->device,
+ pTga->PciInfo->func);
+ }
+ else
+ return FALSE;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * TGAProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pTga->Chipset);
+ return FALSE;
+ }
+ if (pTga->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ from = X_PROBED;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ pTga->PciTag = pciTag(pTga->PciInfo->bus, pTga->PciInfo->device,
+ pTga->PciInfo->func);
+
+
+
+ /*********************
+ deal with depth and framebuffer size
+ *********************/
+
+ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* we can do option processing now */
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+ /* Process the options */
+ if (!(pTga->Options = xalloc(sizeof(TGAOptions))))
+ return FALSE;
+ memcpy(pTga->Options, TGAOptions, sizeof(TGAOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTga->Options);
+ if (xf86ReturnOptValBool(pTga->Options, OPTION_PCI_RETRY, FALSE)) {
+ pTga->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+
+ if(xf86ReturnOptValBool(pTga->Options, OPTION_SYNC_ON_GREEN, FALSE)) {
+ pTga->SyncOnGreen = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");
+ }
+
+ if(xf86ReturnOptValBool(pTga->Options, OPTION_DAC_6_BIT, FALSE)) {
+ pTga->Dac6Bit = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "6 bit DAC enabled\n");
+ }
+
+ if(xf86ReturnOptValBool(pTga->Options, OPTION_NOXAAPOLYSEGMENT, FALSE)) {
+ pTga->NoXaaPolySegment = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XAA PolySegment() disabled\n");
+ }
+
+ /* end option processing */
+
+ /*
+ * 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 */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * The new cmap code requires this to be initialised.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* Default to 8 */
+ pScrn->rgbBits = 8;
+ if(pTga->Dac6Bit)
+ pScrn->rgbBits = 6;
+ }
+ from = X_DEFAULT;
+
+ /* determine whether we use hardware or software cursor */
+
+ pTga->HWCursor = TRUE;
+ if (xf86GetOptValBool(pTga->Options, OPTION_HW_CURSOR, &pTga->HWCursor))
+ from = X_CONFIG;
+ if (xf86ReturnOptValBool(pTga->Options, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pTga->HWCursor = FALSE;
+ }
+
+ if(pScrn->depth != 8) {
+ pTga->HWCursor = FALSE;
+ from = X_WARNING;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Hardware cursor currently only works with BT485 ramdac\n");
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pTga->HWCursor ? "HW" : "SW");
+
+ if (xf86ReturnOptValBool(pTga->Options, OPTION_NOACCEL, FALSE)) {
+ pTga->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ if (pTga->pEnt->device->MemBase != 0) {
+ pTga->CardAddress = pTga->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ pTga->CardAddress = pTga->PciInfo->memBase[0] & 0xFFC00000;/*??*/
+ }
+
+ pTga->FbAddress = pTga->CardAddress;
+ /* Adjust MMIO region */
+ pTga->IOAddress = pTga->CardAddress + TGA_REGS_OFFSET;
+
+
+ /*********************
+ determine what sort of TGA card we have -- the only differences are
+ framebuffer size and ramdac type, all TGA cards use 21030 chips
+ *********************/
+
+ /* check what the user has specified in XF86Config */
+ if(pTga->pEnt->device->videoRam) {
+ switch(pTga->pEnt->device->videoRam) {
+ case 2048:
+ pTga->CardType = TYPE_TGA_8PLANE;
+ break;
+ case 8192:
+ pTga->CardType = TYPE_TGA_24PLANE;
+ break;
+ case 16384:
+ pTga->CardType = TYPE_TGA_24PLUSZ;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "%d KB video RAM specified, driver only supports 2048, 8192, or 16384 KB cards\n",
+ pTga->pEnt->device->videoRam);
+ return FALSE;
+ }
+ }
+ else { /* try to divine the amount of RAM */
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_TGA2:
+ Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
+ pTga->PciTag, pTga->IOAddress, 0x1000);
+ pTga->CardType = (*(unsigned int *)((char *)Base+TGA_REVISION_REG) >> 21) & 0x3;
+ pTga->CardType ^= (pTga->CardType == 1) ? 0 : 3;
+ xf86UnMapVidMem(pScrn->scrnIndex, Base, 0x1000);
+ break;
+ case PCI_CHIP_DEC21030:
+ Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
+ pTga->PciTag, pTga->FbAddress, 4);
+ pTga->CardType = (*(unsigned int *)Base >> 12) & 0xf;
+ xf86UnMapVidMem(pScrn->scrnIndex, Base, 4);
+ break;
+ }
+ }
+
+ switch (pTga->CardType) {
+ case TYPE_TGA_8PLANE:
+ case TYPE_TGA_24PLANE:
+ case TYPE_TGA_24PLUSZ:
+ xf86DrvMsg(pScrn->scrnIndex, from, "Card Name: \"%s\"\n",
+ tga_cardnames[pTga->CardType]);
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Card \"0x%02x\" is not recognised\n", pTga->CardType);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Assuming 8 plane TGA with 2MB frame buffer\n");
+ pTga->CardType = TYPE_TGA_8PLANE;
+ break;
+ }
+
+ /* Adjust framebuffer for card type */
+ pTga->FbAddress += fb_offset_presets[pTga->CardType];
+
+ if (!(((pScrn->depth == 8) && (pTga->CardType == TYPE_TGA_8PLANE)) ||
+ ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLANE)) ||
+ ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLUSZ)))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this card\n",
+ pScrn->depth);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pTga->FbAddress);
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pTga->IOAddress);
+
+ /* RAC stuff: we don't have any resources we need to reserve,
+ but we should do this here anyway */
+ if (xf86RegisterResources(pTga->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+
+
+ /* HW bpp matches reported bpp */
+ pTga->HwBpp = pScrn->bitsPerPixel;
+
+ if (pTga->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pTga->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ switch (pTga->CardType) {
+ case TYPE_TGA_8PLANE:
+ pScrn->videoRam = 2*1024;
+ break;
+ case TYPE_TGA_24PLANE:
+ pScrn->videoRam = 8*1024;
+ break;
+ case TYPE_TGA_24PLUSZ:
+ pScrn->videoRam = 16*1024;
+ break;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pTga->FbMapSize = pScrn->videoRam * 1024;
+
+ if (xf86LoadSubModule(pScrn, "fb") == NULL) {
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ /* Load XAA if needed */
+ if (!pTga->NoAccel || pTga->HWCursor) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+
+ /*********************
+ Let's check what type of DAC we have and reject if necessary
+ *********************/
+
+ pTga->RamDac = NULL;
+
+ if (pTga->CardType != TYPE_TGA_8PLANE) {
+ pTga->RamDacRec = NULL;
+ pTga->RamDac = NULL;
+ } else {
+
+ pTga->RamDacRec = RamDacCreateInfoRec();
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_DEC21030:
+ pTga->RamDacRec->ReadDAC = tgaBTInIndReg;
+ pTga->RamDacRec->WriteDAC = tgaBTOutIndReg;
+ pTga->RamDacRec->ReadAddress = tgaBTReadAddress;
+ pTga->RamDacRec->WriteAddress = tgaBTWriteAddress;
+ pTga->RamDacRec->ReadData = tgaBTReadData;
+ pTga->RamDacRec->WriteData = tgaBTWriteData;
+ break;
+ case PCI_CHIP_TGA2:
+ pTga->RamDacRec->ReadDAC = tga2BTInIndReg;
+ pTga->RamDacRec->WriteDAC = tga2BTOutIndReg;
+ pTga->RamDacRec->ReadAddress = tga2BTReadAddress;
+ pTga->RamDacRec->WriteAddress = tga2BTWriteAddress;
+ pTga->RamDacRec->ReadData = tga2BTReadData;
+ pTga->RamDacRec->WriteData = tga2BTWriteData;
+ break;
+ }
+
+ if (!RamDacInit(pScrn, pTga->RamDacRec)) {
+ RamDacDestroyInfoRec(pTga->RamDacRec);
+ return FALSE;
+ }
+
+ TGAMapMem(pScrn);
+
+ pTga->RamDac = BTramdacProbe(pScrn, BTramdacs);
+
+ TGAUnmapMem(pScrn);
+
+ if (pTga->RamDac == NULL)
+ return FALSE;
+ }
+
+ /*********************
+ set up clock and mode stuff
+ *********************/
+
+ pScrn->progClock = TRUE;
+
+ /* Set the min pixel clock */
+ pTga->MinClock = 16250; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pTga->MinClock / 1000);
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pTga->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pTga->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 32:
+ speed = pTga->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pTga->MaxClock = pTga->pEnt->device->dacSpeeds[0];
+ else
+ pTga->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ switch (pTga->Chipset) {
+ case PCI_CHIP_DEC21030:
+ pTga->MaxClock = 135000;
+ break;
+ case PCI_CHIP_TGA2:
+ pTga->MaxClock = 170000;
+ break;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pTga->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = pTga->MinClock;
+ clockRanges->maxClock = pTga->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+
+ if(pScrn->display->virtualX || pScrn->display->virtualY) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "TGA does not support a virtual desktop\n");
+ pScrn->display->virtualX = 0;
+ pScrn->display->virtualY = 0;
+ }
+
+ /*
+ * 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 TGAValidMode() 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,
+ NULL, 256, 2048,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pTga->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ TGAFreeRec(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");
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if(i > 1) {
+ DisplayModePtr mp1 = NULL, mp2 = NULL;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "TGA only supports one mode, using first mode.\n");
+ mp1 = pScrn->modes->next;
+ mp2 = mp1;
+ while(mp1 && mp1->next != mp1) {
+ mp1 = mp1->next;
+ xf86DeleteMode(&(pScrn->modes), mp2);
+ mp2 = mp1;
+ }
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /*
+ This is a bit of a hack; we seem to have to init
+ the TGA2 chipset knowing what the mode is, so we
+ do this now as soon as we know it...
+ */
+ if (pTga->Chipset == PCI_CHIP_TGA2) {
+ TGA2SetupMode(pScrn);
+ }
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+TGAMapMem(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+
+ /* TGA doesn't need a sparse memory mapping, because all register
+ accesses are doublewords */
+
+ pTga->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
+ pTga->PciTag,
+ pTga->IOAddress, 0x100000);
+ if (pTga->IOBase == NULL)
+ return FALSE;
+
+ pTga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pTga->PciTag,
+ (unsigned long)pTga->FbAddress,
+ pTga->FbMapSize);
+ if (pTga->FbBase == NULL)
+ return FALSE;
+
+ if (pTga->Chipset == PCI_CHIP_DEC21030)
+ return TRUE;
+
+ pTga->ClkBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
+ pTga->PciTag,
+ (unsigned long)pTga->CardAddress + TGA2_CLOCK_OFFSET,
+ 0x10000);
+ if (pTga->ClkBase == NULL)
+ return FALSE;
+
+ pTga->DACBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
+ pTga->PciTag,
+ (unsigned long)pTga->CardAddress + TGA2_RAMDAC_OFFSET,
+ 0x10000);
+ if (pTga->DACBase == NULL)
+ return FALSE;
+
+ /*
+ * This is a hack specifically for the TGA2 code, as it sometimes
+ * calculates/uses addresses in TGA2 memory which are NOT mmapped
+ * by the normal framebuffer code above. This most frequently occurs
+ * when displaying something close to the top-left corner (in the
+ * routines CopyLine{Forwards,Backwards}.
+ *
+ * This could most likely also be fixed by further modifying the
+ * code, but it (the code) is ugly enough already... ;-}
+ *
+ * So, the workaround is to simply mmap an additional PAGE of
+ * framebuffer memory in front of the normal mmap to prevent
+ * SEGVs from happening.
+ */
+ pTga->HACKBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pTga->PciTag,
+ (unsigned long)pTga->FbAddress - getpagesize(),
+ getpagesize());
+ if (pTga->HACKBase == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+TGAUnmapMem(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->IOBase, 0x100000);
+ pTga->IOBase = NULL;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->FbBase, pTga->FbMapSize);
+ pTga->FbBase = NULL;
+
+ if (pTga->Chipset == PCI_CHIP_DEC21030)
+ return TRUE;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->ClkBase, 0x10000);
+ pTga->ClkBase = NULL;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->DACBase, 0x10000);
+ pTga->DACBase = NULL;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->HACKBase, getpagesize());
+ pTga->HACKBase = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+TGASave(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+ TGARegPtr tgaReg;
+ RamDacHWRecPtr pBT;
+ RamDacRegRecPtr BTreg;
+
+ pTga = TGAPTR(pScrn);
+ tgaReg = &pTga->SavedReg;
+
+ DEC21030Save(pScrn, tgaReg);
+ if (pTga->RamDac) { /* must be BT485... */
+ pBT = RAMDACHWPTR(pScrn);
+ BTreg = &pBT->SavedReg;
+ (*pTga->RamDac->Save)(pScrn, pTga->RamDacRec, BTreg);
+ } else switch (pTga->Chipset)
+ {
+ case PCI_CHIP_TGA2:
+ IBM561ramdacSave(pScrn, pTga->Ibm561saveReg);
+ break;
+ case PCI_CHIP_DEC21030:
+ BT463ramdacSave(pScrn, pTga->Bt463saveReg);
+ break;
+ }
+}
+
+
+/*
+ * 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
+TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int ret = -1;
+ TGAPtr pTga;
+ TGARegPtr tgaReg;
+ RamDacHWRecPtr pBT;
+ RamDacRegRecPtr BTreg;
+
+ pTga = TGAPTR(pScrn);
+
+ pScrn->vtSema = TRUE;
+
+ ret = DEC21030Init(pScrn, mode);
+
+ if (pTga->Chipset == PCI_CHIP_TGA2 && pTga->RamDac == NULL)
+ IBM561ramdacHWInit(pScrn);
+
+ if (!ret)
+ return FALSE;
+
+ /* Program the registers */
+ tgaReg = &pTga->ModeReg;
+
+ DEC21030Restore(pScrn, tgaReg);
+
+ if (pTga->RamDac != NULL) {
+ pBT = RAMDACHWPTR(pScrn);
+ BTreg = &pBT->ModeReg;
+ (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
+ if (pTga->Chipset == PCI_CHIP_TGA2) {
+ pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x0c);
+ }
+ pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff);
+ } else {
+ switch (pTga->Chipset) {
+ case PCI_CHIP_TGA2:
+ IBM561ramdacRestore(pScrn, pTga->Ibm561modeReg);
+ break;
+ case PCI_CHIP_DEC21030:
+ BT463ramdacRestore(pScrn, pTga->Bt463modeReg);
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+TGARestore(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+ TGARegPtr tgaReg;
+ RamDacHWRecPtr pBT;
+ RamDacRegRecPtr BTreg;
+
+ pTga = TGAPTR(pScrn);
+ tgaReg = &pTga->SavedReg;
+
+ /* Initial Text mode clock */
+ tgaReg->tgaRegs[0x0A] = 25175;
+
+ DEC21030Restore(pScrn, tgaReg);
+
+ if (pTga->RamDac != NULL) {
+ pBT = RAMDACHWPTR(pScrn);
+ BTreg = &pBT->SavedReg;
+ (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
+ if (pTga->Chipset == PCI_CHIP_TGA2) {
+ pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x00);
+ }
+ pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff);
+ } else switch (pTga->Chipset) {
+ case PCI_CHIP_TGA2:
+ IBM561ramdacRestore(pScrn, pTga->Ibm561saveReg);
+ break;
+ case PCI_CHIP_DEC21030:
+ BT463ramdacRestore(pScrn, pTga->Bt463saveReg);
+ break;
+ }
+
+ if (pTga->HWCursor)
+ TGARestoreHWCursor(pScrn);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+TGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ TGAPtr pTga;
+ int ret;
+ VisualPtr visual;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+ pTga = TGAPTR(pScrn);
+
+ /* Map the TGA memory and MMIO areas */
+ if (!TGAMapMem(pScrn))
+ return FALSE;
+
+#if 1
+ /* dump original register contents */
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MODE 0x%x\n",
+ TGA_READ_REG(TGA_MODE_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VALID 0x%x\n",
+ TGA_READ_REG(TGA_VALID_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DEEP 0x%x\n",
+ TGA_READ_REG(TGA_DEEP_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXSH 0x%x\n",
+ TGA_READ_REG(TGA_PIXELSHIFT_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ROP 0x%x\n",
+ TGA_READ_REG(TGA_RASTEROP_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HORIZ 0x%x\n",
+ TGA_READ_REG(TGA_HORIZ_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VERT 0x%x\n",
+ TGA_READ_REG(TGA_VERT_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXMSK 0x%x\n",
+ TGA_READ_REG(TGA_PIXELMASK_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "REV 0x%x\n",
+ TGA_READ_REG(TGA_REVISION_REG));
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VADDR 0x%x\n",
+ TGA_READ_REG(TGA_BASE_ADDR_REG));
+#endif
+
+ /* Save the current state */
+ TGASave(pScrn);
+
+ /* Initialise the first mode */
+ TGAModeInit(pScrn, pScrn->currentMode);
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ TGASaveScreen(pScreen, SCREEN_SAVER_ON);
+
+ /*
+ * 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.
+ *
+ * For most PC hardware at depths >= 8, the defaults that fb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes for each visual supported.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ miSetPixmapDepths ();
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ case 32:
+ ret = fbScreenInit(pScreen, pTga->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth, pScrn->bitsPerPixel);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in TGAScrnInit\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;
+ }
+ }
+ }
+
+ /* must be after RGB ordering fixed */
+
+ fbPictureInit (pScreen, 0, 0);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+ /* we should ALWAYS do this */
+ if (pScrn->bitsPerPixel == 8) {
+ TGA_WRITE_REG(SIMPLE | X11 | BPP8PACKED, TGA_MODE_REG);
+ TGA_WRITE_REG(0x3 | BPP8PACKED, TGA_RASTEROP_REG);
+ if (pTga->Chipset == PCI_CHIP_TGA2)
+ TGA_WRITE_REG(2 << 28, TGA_DEEP_REG);
+ } else {
+ TGA_WRITE_REG(SIMPLE | X11 | BPP24, TGA_MODE_REG);
+ TGA_WRITE_REG(0x3 | BPP24, TGA_RASTEROP_REG);
+ if (pTga->Chipset == PCI_CHIP_TGA2)
+ TGA_WRITE_REG((7 << 2) | 1 | (2 << 28), TGA_DEEP_REG);
+ }
+ TGA_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
+ TGA_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
+
+ if (!pTga->NoAccel) {
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_TGA2:
+ case PCI_CHIP_DEC21030:
+ if(DEC21030AccelInit(pScreen) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "XAA Initialization failed\n");
+ return(FALSE);
+ }
+ break;
+ }
+ }
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialize HW cursor layer.
+ Must follow software cursor initialization*/
+ if (pTga->HWCursor) {
+ if(!TGAHWCursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ return(FALSE);
+ }
+ }
+
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if ((pScrn->bitsPerPixel==8) &&
+ (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits,
+ CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)))
+ return FALSE;
+
+ pTga->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = TGACloseScreen;
+ pScreen->SaveScreen = TGASaveScreen;
+
+ if(xf86DPMSInit(pScreen, TGADisplayPowerManagementSet, 0) == FALSE)
+ ErrorF("DPMS initialization failed!\n");
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ pScrn->memPhysBase = pTga->FbAddress;
+ pScrn->fbOffset = 0;
+
+ n = xf86XVListGenericAdaptors(pScrn,&ptr);
+
+ if(n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+
+ }
+#endif
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* unblank the screen */
+ TGASaveScreen(pScreen, SCREEN_SAVER_OFF);
+
+ /* Done */
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+static Bool
+TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return TGAModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+static void
+TGAAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ /* we don't support virtual desktops, because TGA doesn't have the
+ ability to set the start of the visible framebuffer at an arbitrary
+ pixel */
+ return;
+}
+
+/*
+ * 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
+TGAEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ /* Should we re-save the text mode on each VT enter? */
+ if (!TGAModeInit(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
+TGALeaveVT(int scrnIndex, int flags)
+{
+ TGAPtr pTga;
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ pTga = TGAPTR(pScrn);
+ TGARestore(pScrn);
+
+ /* no longer necessary with new VT switching code */
+/* memset(pTga->FbBase, 0, pTga->FbMapSize); */
+ return;
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode.
+ */
+
+/* Mandatory */
+static Bool
+TGACloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ TGARestore(pScrn);
+ /* memset(pTga->FbBase, 0, pScrn->videoRam * 1024); */
+ TGASync(pScrn);
+ TGAUnmapMem(pScrn);
+
+ if(pTga->AccelInfoRec)
+ XAADestroyInfoRec(pTga->AccelInfoRec);
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pTga->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+TGAFreeScreen(int scrnIndex, int flags)
+{
+ RamDacFreeRec(xf86Screens[scrnIndex]);
+ TGAFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+TGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ if (mode->Flags & V_INTERLACE)
+ return(MODE_BAD);
+
+ return(MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+TGASaveScreen(ScreenPtr pScreen, int mode)
+ /* this function should blank the screen when unblank is FALSE and
+ unblank it when unblank is TRUE -- it doesn't actually seem to be
+ used for much though */
+{
+ TGAPtr pTga;
+ ScrnInfoPtr pScrn;
+ int valid_reg = 0;
+ Bool unblank;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pTga = TGAPTR(pScrn);
+ valid_reg = TGA_READ_REG(TGA_VALID_REG);
+ valid_reg &= 0xFFFFFFFC;
+
+ unblank = xf86IsUnblank(mode);
+
+ if(unblank == FALSE)
+ valid_reg |= 0x3;
+ else /* this function is sometimes called w/1 || 2 as TRUE */
+ valid_reg |= 0x1;
+
+ TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
+
+/* ErrorF("TGASaveScreen called\n"); */
+
+ return TRUE;
+}
+
+
+/*
+ * TGADisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+static void
+TGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ TGAPtr pTga;
+ int valid_reg = 0;
+
+ pTga = TGAPTR(pScrn);
+ valid_reg = TGA_READ_REG(TGA_VALID_REG);
+ valid_reg &= 0xFFFFFFFC;
+
+ switch(PowerManagementMode) {
+ case DPMSModeOn:
+ /* HSync: On, VSync: On */
+ valid_reg |= 0x1;
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ /* TGA gives us a function to blank the screen while maintaining sync...
+ I guess we can just use that here... */
+ valid_reg |= 0x3;
+ break;
+ case DPMSModeOff:
+ valid_reg |= 0x2;
+ break;
+ default:
+ ErrorF("Invalid PowerManagementMode %d passed to TGADisplayPowerManagementSet\n", PowerManagementMode);
+ break;
+ }
+
+ TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
+ return;
+}
+
+static void
+TGARestoreHWCursor(ScrnInfoPtr pScrn)
+ /*
+ from tga.c in the linux kernel...may not work for BSD...
+ when the cursor is restored, it is one line down from where it should
+ be...this is disconcerting, but purely cosmetic. Unfortunately reading
+ in the cursor framebuffer doesn't seem to work, I get a bunch of junk
+ at the beginning...other than that, see tga_cursor.c
+ I believe this to be a problem with the linux kernel code.
+ Hmm...this seems to be a 2.0.* problem, 2.2 works ok
+ */
+{
+ unsigned char *p = NULL;
+ int i = 0;
+ TGAPtr pTga;
+
+ /* Making this static prevents EGCS from compiling memset code
+ to initialize it, which was causing a problem. */
+ static const CARD32 tga_cursor_source[128] = {
+ 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
+ 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
+ 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
+ 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
+ 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
+ 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
+ 0x000000ff, 0x00000000,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ };
+
+ /* this is the linux console hw cursor...what about the bsd console? */
+ /* what about tgafb? */
+ pTga = TGAPTR(pScrn);
+
+ /* we want to move the cursor off the screen before we do anything with it
+ otherwise, there is a "ghost cursor" that shows up */
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, 0);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, 0);
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, 0);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, 0);
+
+
+ /* set a windows cursor -- oddly, this doesn't seem necessary */
+ pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x02);
+
+ /* set a 64 bit cursor */
+/* pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80); */
+/* pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); */
+/* pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04); */
+
+ /* set the colors */
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
+
+
+ /* load the console cursor */
+ pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
+ p = (unsigned char *)tga_cursor_source;
+ for(i = 0; i < 512; i++)
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *p++);
+ for(i = 0; i < 512; i++)
+ pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, 0xff);
+
+ return;
+}
+
+
+/*
+ * This is the implementation of the Sync() function.
+ */
+void
+TGASync(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ unsigned int stat;
+
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_TGA2:
+ /* This code is weird, but then so is TGA2... ;-} */
+ mem_barrier();
+ while((stat = TGA_READ_REG(TGA_CMD_STAT_REG))) {
+ if (((stat >> 8) & 0xff) == ((stat >> 16) & 0xff)) {
+ TGA_WRITE_REG(0, TGA_CMD_STAT_REG);
+ mem_barrier();
+#if 0
+ErrorF("TGASync: writing CMD_STATUS\n");
+#endif
+ }
+ usleep(1000);
+ }
+ break;
+
+ case PCI_CHIP_DEC21030:
+#if 0
+ /* I'm experiencing lockups which could be due to this function.
+ We don't seem to need it anyway...
+ */
+ while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01);
+#endif
+ break;
+ }
+
+ return;
+}
+
diff --git a/src/tga_line.c b/src/tga_line.c
new file mode 100644
index 0000000..b1a510c
--- /dev/null
+++ b/src/tga_line.c
@@ -0,0 +1,629 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_line.c,v 1.2 1999/12/16 02:26:30 robin Exp $ */
+
+/*
+ * Copyright 1999 by Matthew Grossman, Seattle, USA.
+ *
+ * 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 Matthew
+ * Grossman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Matthew Grossman makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MATTHEW GROSSMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MATTHEW GROSSMAN 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: Matthew Grossman, mattg@oz.net
+ *
+ */
+
+/* tga_line.c */
+/* accelerated solid and dashed lines */
+/* adapted from xaa/xaaLine.c */
+
+#include "X.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+/* #include "tga.h" */
+#include "tga_regs.h"
+
+/* line functions */
+extern void
+TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+extern void
+TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
+ int dir);
+extern void
+TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant, int flags);
+extern void
+TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant);
+extern void
+TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
+ int err);
+
+extern void
+TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length,
+ unsigned char *pattern);
+extern void
+TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int octant, int flags, int phase);
+extern void
+TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
+ int err, int phase);
+
+
+extern void
+TGASync(ScrnInfoPtr pScrn);
+
+void TGAPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+void TGAPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+void TGAPolySegmentDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+void TGAPolyLinesDashed(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+
+
+void
+#ifdef POLYSEGMENT
+TGAPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+#else
+ TGAPolyLines(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit
+#endif
+ ){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
+ int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ int nbox;
+ BoxPtr pbox;
+#ifndef POLYSEGMENT
+ DDXPointPtr ppt;
+#endif
+ int x1, x2, y1, y2, tmp, len;
+
+#ifdef POLYSEGMENT
+/* ErrorF("TGAPolySegment called!\n"); */
+#else
+/* ErrorF("TGAPolyLines called\n"); */
+#endif
+
+ if(!nboxInit)
+ return;
+ /****************/
+ /* TGA FUNCTION */
+ /****************/
+ TGASetupForSolidLine(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2) { /* vertical line */
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2) {
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast) y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast) y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while(nbox && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ /* stop when lower edge of box is beyond end of line */
+ while(nbox && (y2 >= pbox->y1)) {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2)) {
+ tmp = max(y1, pbox->y1);
+ len = min(y2, pbox->y2) - tmp;
+ if (len)
+ TGASubsequentSolidHorVertLine(infoRec->pScrn, x1, tmp,
+ len, DEGREES_270);
+ }
+ nbox--;
+ pbox++;
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ } else if (y1 == y2) { /* horizontal line */
+ /* force line from left to right, keeping endpoint semantics */
+ if (x1 > x2) {
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast) x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast) x2++;
+#endif
+
+ /* find the correct band */
+ while(nbox && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if (nbox && (pbox->y1 <= y1)) {
+ int orig_y = pbox->y1;
+ /* when we leave this band, we're done */
+ while(nbox && (orig_y == pbox->y1)) {
+ if (pbox->x2 <= x1) {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2) {
+ nbox = 0;
+ break;
+ }
+
+ tmp = max(x1, pbox->x1);
+ len = min(x2, pbox->x2) - tmp;
+ if (len)
+ TGASubsequentSolidHorVertLine(infoRec->pScrn, tmp,
+ y1, len, DEGREES_0);
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ } else{ /* sloped line */
+ unsigned int oc1, oc2;
+ int dmin, dmaj, e, octant;
+
+
+ if((dmaj = x2 - x1) < 0) {
+ dmaj = -dmaj;
+ octant = XDECREASING;
+ } else octant = 0;
+
+ if((dmin = y2 - y1) < 0) {
+ dmin = -dmin;
+ octant |= YDECREASING;
+ }
+
+ if(dmin >= dmaj){
+ tmp = dmin; dmin = dmaj; dmaj = tmp;
+ octant |= YMAJOR;
+ }
+
+ e = -dmaj - ((bias >> octant) & 1);
+ len = dmaj;
+ dmin *= 2;
+ dmaj *= 2;
+
+
+ while(nbox--) {
+ oc1 = oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if (!(oc1 | oc2)) { /* unclipped */
+ TGASubsequentSolidLine(infoRec->pScrn, x1, y1, x2, y2,
+ octant,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST
+ );
+ break;
+ } else if (oc1 & oc2) { /* completely clipped */
+ pbox++;
+
+ } else { /* partially clipped */
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int err, adx, ady;
+
+ if(octant & YMAJOR) {
+ ady = dmaj /= 2;
+ adx = dmin /= 2;
+ } else {
+ ady = dmin /= 2;
+ adx = dmaj /= 2;
+ }
+
+ if (miZeroClipLine(pbox->x1, pbox->y1,
+ pbox->x2 - 1, pbox->y2 - 1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (octant & YMAJOR)
+ len = abs(new_y2 - new_y1);
+ else
+ len = abs(new_x2 - new_x1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) { /* we have a real line */
+ int abserr, clipdx, clipdy;
+
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+
+ if (octant & YMAJOR)
+ err = e + clipdy*dmin - clipdx*dmaj;
+ else
+ err = e + clipdx*dmin - clipdy*dmaj;
+ } else
+ err = e;
+
+#define range infoRec->SolidBresenhamLineErrorTermBits
+ abserr = abs(err);
+ while((abserr & range) ||
+ (dmaj & range) ||
+ (dmin & range)) {
+ dmin /= 2;
+ dmaj /= 2;
+ abserr /= 2;
+ err /= 2;
+ }
+ TGASetupForClippedLine(infoRec->pScrn, x1, y1, x2,
+ y2, octant);
+ TGASubsequentClippedSolidLine(infoRec->pScrn,
+ new_x1, new_y1, len,
+ err);
+
+
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) && (y2 < pbox->y2))
+ {
+ TGASubsequentSolidHorVertLine(infoRec->pScrn, x2, y2, 1,
+ DEGREES_0);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+
+ TGASync(infoRec->pScrn);
+ return;
+}
+
+#undef range
+
+ void
+#ifdef POLYSEGMENT
+ TGAPolySegmentDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+#else
+ TGAPolyLinesDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit
+#endif
+ ){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
+ BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
+ int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ int nbox;
+ BoxPtr pbox;
+#ifndef POLYSEGMENT
+ DDXPointPtr ppt;
+#endif
+ unsigned int oc1, oc2;
+ int dmin, dmaj, e, octant;
+ int x1, x2, y1, y2, tmp, len, offset;
+ int PatternLength, PatternOffset;
+
+#ifdef POLYSEGMENT
+/* ErrorF("TGAPolySegmentDashed called\n"); */
+#else
+/* ErrorF("TGAPolyLinesDashed called\n"); */
+#endif
+
+ if(!nboxInit)
+ return;
+
+ PatternLength = pGCPriv->DashLength;
+ PatternOffset = pGC->dashOffset % PatternLength;
+
+ TGASetupForDashedLine(infoRec->pScrn, pGC->fgPixel,
+ (pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1,
+ pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern);
+
+
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+
+
+ if((dmaj = x2 - x1) < 0) {
+ dmaj = -dmaj;
+ octant = XDECREASING;
+ } else octant = 0;
+
+ if((dmin = y2 - y1) < 0) {
+ dmin = -dmin;
+ octant |= YDECREASING;
+ }
+
+ if(dmin >= dmaj){
+ tmp = dmin; dmin = dmaj; dmaj = tmp;
+ octant |= YMAJOR;
+ }
+
+ e = -dmaj - ((bias >> octant) & 1);
+ len = dmaj;
+ dmin <<= 1;
+ dmaj <<= 1;
+
+
+ while(nbox--) {
+ oc1 = oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if (!(oc1 | oc2)) { /* unclipped */
+ TGASubsequentDashedLine(infoRec->pScrn, x1, y1, x2, y2,
+ octant,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST, PatternOffset);
+ break;
+ } else if (oc1 & oc2) { /* completely clipped */
+ pbox++;
+ } else { /* partially clipped */
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int err, adx, ady;
+
+ if(octant & YMAJOR) {
+ ady = dmaj >> 1;
+ adx = dmin >> 1;
+ } else {
+ ady = dmin >> 1;
+ adx = dmaj >> 1;
+ }
+
+ if (miZeroClipLine(pbox->x1, pbox->y1,
+ pbox->x2 - 1, pbox->y2 - 1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (octant & YMAJOR)
+ len = abs(new_y2 - new_y1);
+ else
+ len = abs(new_x2 - new_x1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) {
+ int abserr, clipdx, clipdy;
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+
+ if (octant & YMAJOR)
+ err = e + clipdy*dmin - clipdx*dmaj;
+ else
+ err = e + clipdx*dmin - clipdy*dmaj;
+ } else
+ err = e;
+
+#define range infoRec->DashedBresenhamLineErrorTermBits
+ abserr = abs(err);
+ while((abserr & range) ||
+ (dmaj & range) ||
+ (dmin & range)) {
+ dmin >>= 1;
+ dmaj >>= 1;
+ abserr >>= 1;
+ err /= 2;
+ }
+
+ if(octant & YMAJOR)
+ offset = abs(new_y1 - y1);
+ else
+ offset = abs(new_x1 - x1);
+
+ offset += PatternOffset;
+ offset %= PatternLength;
+
+ TGASetupForClippedLine(infoRec->pScrn, x1, x2, y1, y2,
+ octant);
+ TGASubsequentClippedDashedLine(infoRec->pScrn, new_x1,
+ new_y1, len, err,
+ PatternOffset);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ len = abs(y2 - y1);
+ tmp = abs(x2 - x1);
+ PatternOffset += (len > tmp) ? len : tmp;
+ PatternOffset %= PatternLength;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--) {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) && (y2 < pbox->y2))
+ {
+ TGASubsequentDashedLine(infoRec->pScrn, x2, y2, x2, y2, 0, 0,
+ PatternOffset);
+ break;
+ } else
+ pbox++;
+ }
+ }
+#endif
+
+ TGASync(infoRec->pScrn);
+ return;
+}
+
+
diff --git a/src/tga_regs.h b/src/tga_regs.h
new file mode 100644
index 0000000..4bda04a
--- /dev/null
+++ b/src/tga_regs.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * 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.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h,v 1.12 2002/05/13 05:22:37 keithp Exp $ */
+
+/* TGA hardware description (minimal)
+ *
+ * Offsets within Memory Space
+ *
+ * Portions taken from linux's own tga driver...
+ * Courtesy of Jay Estabrook.
+ */
+
+#ifndef TGA_REGS_H
+#define TGA_REGS_H
+
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#define TYPE_TGA_8PLANE 0
+#define TYPE_TGA_24PLANE 1
+#define TYPE_TGA_24PLUSZ 3
+
+#if 1
+#define WMB mem_barrier()
+#else
+#define WMB write_mem_barrier()
+#endif
+
+#define TGA_WRITE_REG(v,r) \
+ do {\
+ *(unsigned int *)((char*)(pTga->IOBase)+(r)) = (v);\
+ WMB;\
+ } while (0)
+
+#define TGA_READ_REG(r) \
+ ( *(unsigned int *)((char*)(pTga->IOBase)+(r)))
+
+#define TGA2_WRITE_CLOCK_REG(v,r) \
+ do {\
+ *(unsigned int *)((char*)(pTga->ClkBase)+(r)) = (v);\
+ WMB;\
+ } while (0)
+
+#define TGA2_WRITE_RAMDAC_REG(v,r) \
+ do {\
+ *(unsigned int *)((char*)(pTga->DACBase)+(r)) = (v);\
+ WMB;\
+ } while (0)
+
+#define TGA2_READ_RAMDAC_REG(r) \
+ ( *(unsigned int *)((char*)(pTga->DACBase)+(r)))
+
+#if defined(__alpha__) && 0 /* ?? disable this for now ?? */
+/* we can avoid an mb() if we write to an alternate register space each time */
+
+#define MAX_OFFSET 8192
+#define OFFSET_INC 1024
+
+#define TGA_DECL() register unsigned long iobase, offset
+#define TGA_GET_IOBASE() iobase = (unsigned long)pTga->IOBase;
+#define TGA_GET_OFFSET() offset = pTga->regOffset;
+#define TGA_SAVE_OFFSET() pTga->regOffset = offset;
+
+/* #define PROFILE */
+#undef PROFILE
+
+#ifdef PROFILE
+static __inline__ unsigned int realcc()
+{
+ u_long cc;
+ __asm__ volatile("rpcc %0" : "=r"(cc) : : "memory");
+ return cc;
+}
+
+#define TGA_FAST_WRITE_REG(v,r) \
+do {\
+start = realcc();\
+ *(unsigned int *)(iobase + offset + (r)) = v;\
+ offset += OFFSET_INC;\
+ if(offset > MAX_OFFSET) (offset = 0);\
+ stop = realcc();\
+ ErrorF("TGA_FAST_WRITE_REG = %d\n", stop - start);\
+} while (0)
+
+#else /* PROFILE */
+
+#define TGA_FAST_WRITE_REG(v,r) \
+do {\
+ *(unsigned int *)(iobase + offset + (r)) = v;\
+ offset += OFFSET_INC;\
+ if(offset > MAX_OFFSET) (offset = 0);\
+} while (0)
+#endif /* PROFILE */
+
+#else /* __alpha__ */
+
+#define TGA_DECL()
+#define TGA_GET_IOBASE() ;
+#define TGA_GET_OFFSET() ;
+#define TGA_SAVE_OFFSET() ;
+#define TGA_FAST_WRITE_REG(v,r) TGA_WRITE_REG(v,r)
+
+#endif /* __alpha__ */
+
+#define TGA_ROM_OFFSET 0x00000000
+#define TGA2_CLOCK_OFFSET 0x00060000
+#define TGA2_RAMDAC_OFFSET 0x00080000
+#define TGA_REGS_OFFSET 0x00100000
+#define TGA_8PLANE_FB_OFFSET 0x00200000
+#define TGA_24PLANE_FB_OFFSET 0x00800000
+#define TGA_24PLUSZ_FB_OFFSET 0x01000000
+
+#define TGA_FOREGROUND_REG 0x0020
+#define TGA_BACKGROUND_REG 0x0024
+#define TGA_PLANEMASK_REG 0x0028
+#define TGA_MODE_REG 0x0030
+#define SIMPLE 0x00
+#define Z3D 0x10
+#define OPAQUESTIPPLE 0x01
+#define FILL 0x20
+#define TRANSPARENTSTIPPLE 0x05
+#define BLOCKSTIPPLE 0x0D
+#define BLOCKFILL 0x2D
+#define OPAQUELINE 0x02
+#define TRANSPARENTLINE 0x06
+#define BPP8PACKED (0x00 << 8)
+#define BPP8UNPACK (0x01 << 8)
+#define BPP12LOW (0x02 << 8)
+#define BPP12HIGH (0x06 << 8)
+#define BPP24 (0x03 << 8)
+#define CAP_ENDS 0x8000
+#define X11 0x0000
+#define MODE_WIN32 0x2000
+ /* copy mode */
+#define COPY 0x07
+ /* opaque fill mode */
+#define OPAQUEFILL 0x21
+#define TRANSPARENTFILL 0x45
+#define TGA_RASTEROP_REG 0x0034
+#define TGA_PIXELSHIFT_REG 0x0038
+#define TGA_ADDRESS_REG 0x003c
+#define TGA_CONTINUE_REG 0x004c
+#define TGA_DEEP_REG 0x0050
+#define TGA_REVISION_REG 0x0054 /* TGA2 */
+#define TGA_PIXELMASK_REG 0x002c
+#define TGA_PIXELMASK_PERS_REG 0x005c
+#define TGA_CURSOR_BASE_REG 0x0060
+#define TGA_HORIZ_REG 0x0064
+#define TGA_VERT_REG 0x0068
+#define TGA_BASE_ADDR_REG 0x006c
+#define TGA_VALID_REG 0x0070
+#define TGA_CURSOR_XY_REG 0x0074
+#define TGA_INTR_STAT_REG 0x007c
+ /* GDAR */
+#define TGA_DATA_REG 0x0080
+#define TGA_WIDTH_REG 0x009c
+#define TGA_SPAN_REG 0x00bc
+#define TGA_RAMDAC_SETUP_REG 0x00c0
+
+#define TGA_NOSLOPE7_REG 0x011C
+#define TGA_NOSLOPE6_REG 0x0118
+#define TGA_NOSLOPE5_REG 0x0114
+#define TGA_NOSLOPE4_REG 0x0110
+#define TGA_NOSLOPE3_REG 0x010C
+#define TGA_NOSLOPE2_REG 0x0108
+#define TGA_NOSLOPE1_REG 0x0104
+#define TGA_NOSLOPE0_REG 0x0100
+
+#define TGA_SLOPE0_REG 0x0120
+#define TGA_SLOPE1_REG 0x0124
+#define TGA_SLOPE2_REG 0x0128
+#define TGA_SLOPE3_REG 0x012C
+#define TGA_SLOPE4_REG 0x0130
+#define TGA_SLOPE5_REG 0x0134
+#define TGA_SLOPE6_REG 0x0138
+#define TGA_SLOPE7_REG 0x013C
+#define TGA_BRES3_REG 0x0048
+#define TGA_BRES2_REG 0x0044
+#define TGA_BRES1_REG 0x0040
+
+#define TGA_BLOCK_COLOR0_REG 0x0140
+#define TGA_BLOCK_COLOR1_REG 0x0144
+#define TGA_BLOCK_COLOR2_REG 0x0148
+#define TGA_BLOCK_COLOR3_REG 0x014c
+#define TGA_BLOCK_COLOR4_REG 0x0150
+#define TGA_BLOCK_COLOR5_REG 0x0154
+#define TGA_BLOCK_COLOR6_REG 0x0158
+#define TGA_BLOCK_COLOR7_REG 0x015c
+#define TGA_CLOCK_REG 0x01e8
+#define TGA_RAMDAC_REG 0x01f0
+#define TGA_CMD_STAT_REG 0x01f8
+
+#define BT485_READ_BIT 0x01
+#define BT485_WRITE_BIT 0x00
+
+#endif