summaryrefslogtreecommitdiff
path: root/hw/kdrive
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@fairlite.demon.co.uk>2001-05-23 08:56:09 +0000
committerAlan Hourihane <alanh@fairlite.demon.co.uk>2001-05-23 08:56:09 +0000
commit85d827f5329fa93dea1125788457fac6835cd134 (patch)
treed383a6b9972216d3164e319876693874155ef547 /hw/kdrive
parentf9104754cda1212cf48d6d24a0a586c5368d7549 (diff)
Add PCMCIA server for HP VGA Out PC Card and the Voyager VGA Card. Use on
the Compaq IPAQ. Use -listmodes to see supported modes. Hack the touchscreen driver to work as a mouse pad for the VGA screen. Fixup key bindings so xmodmap can remap IPAQ's buttons as mouse buttons.
Diffstat (limited to 'hw/kdrive')
-rw-r--r--hw/kdrive/Imakefile6
-rw-r--r--hw/kdrive/fbdev/Imakefile6
-rw-r--r--hw/kdrive/fbdev/fbdev.c6
-rw-r--r--hw/kdrive/fbdev/fbinit.c4
-rw-r--r--hw/kdrive/linux/ts.c37
-rw-r--r--hw/kdrive/pcmcia/Imakefile13
-rw-r--r--hw/kdrive/pcmcia/modes.h66
-rw-r--r--hw/kdrive/pcmcia/pcmcia.c929
-rw-r--r--hw/kdrive/pcmcia/pcmcia.h262
-rw-r--r--hw/kdrive/pcmcia/pcmciacurs.c449
-rw-r--r--hw/kdrive/pcmcia/pcmciashadow.c191
-rw-r--r--hw/kdrive/pcmcia/pcmciastub.c54
-rw-r--r--hw/kdrive/src/kinput.c31
-rw-r--r--hw/kdrive/src/kmap.c6
14 files changed, 2044 insertions, 16 deletions
diff --git a/hw/kdrive/Imakefile b/hw/kdrive/Imakefile
index 874e16196..1b91011ba 100644
--- a/hw/kdrive/Imakefile
+++ b/hw/kdrive/Imakefile
@@ -1,5 +1,5 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
-XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Imakefile,v 1.5 2000/12/01 00:01:30 keithp Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Imakefile,v 1.6 2001/03/30 02:15:19 keithp Exp $
KDRIVE=.
#include "Kdrive.tmpl"
@@ -13,6 +13,10 @@ XVSRCS=kxv.c
XVOBJS=kxv.o
#endif
+#if XipaqServer
+DEFINES = -DXIPAQ
+#endif
+
SRCS = kcmap.c kcolor.c kdrive.c kinfo.c kinput.c kmap.c knoop.c ktest.c \
vga.c kasync.c kmode.c kcurscol.c kshadow.c $(RENDERSRCS) $(XVSRCS)
diff --git a/hw/kdrive/fbdev/Imakefile b/hw/kdrive/fbdev/Imakefile
index 783effb08..5a8eb248e 100644
--- a/hw/kdrive/fbdev/Imakefile
+++ b/hw/kdrive/fbdev/Imakefile
@@ -1,8 +1,12 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
-XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/Imakefile,v 1.2 2000/09/03 05:11:17 keithp Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/Imakefile,v 1.3 2000/12/01 00:01:31 keithp Exp $
KDRIVE=..
#include "../Kdrive.tmpl"
+#ifdef XipaqServer
+DEFINES = -DXIPAQ
+#endif
+
SRCS = fbdev.c fbinit.c
OBJS = fbdev.o fbinit.o
diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c
index 9cab4cfb8..baac67168 100644
--- a/hw/kdrive/fbdev/fbdev.c
+++ b/hw/kdrive/fbdev/fbdev.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.10 2000/10/03 17:22:14 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.11 2001/03/30 02:15:20 keithp Exp $ */
#include "fbdev.h"
@@ -295,6 +295,8 @@ fbdevUpdateFake24 (ScreenPtr pScreen,
}
#endif /* FAKE24_ON_16 */
+int TsFbdev = -1;
+
Bool
fbdevInitScreen (ScreenPtr pScreen)
{
@@ -304,6 +306,8 @@ fbdevInitScreen (ScreenPtr pScreen)
ShadowUpdateProc update;
ShadowWindowProc window;
+ TsFbdev = pScreen->myNum;
+
if (scrpriv->shadow)
{
window = fbdevWindowLinear;
diff --git a/hw/kdrive/fbdev/fbinit.c b/hw/kdrive/fbdev/fbinit.c
index f2f5a6b16..744f7d6bb 100644
--- a/hw/kdrive/fbdev/fbinit.c
+++ b/hw/kdrive/fbdev/fbinit.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.4 2000/09/22 06:25:08 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.6 2000/09/28 20:58:21 keithp Exp $ */
#include <fbdev.h>
@@ -53,6 +53,7 @@ KdCardFuncs fbdevFuncs = {
fbdevPutColors, /* putColors */
};
+#ifndef XIPAQ
void
InitCard (char *name)
{
@@ -85,3 +86,4 @@ ddxProcessArgument (int argc, char **argv, int i)
{
return KdProcessArgument (argc, argv, i);
}
+#endif
diff --git a/hw/kdrive/linux/ts.c b/hw/kdrive/linux/ts.c
index 6342c4b95..e130dc557 100644
--- a/hw/kdrive/linux/ts.c
+++ b/hw/kdrive/linux/ts.c
@@ -1,5 +1,5 @@
/*
- * $XFree86$
+ * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ts.c,v 1.2 2000/09/26 15:57:04 tsi Exp $
*
* Derived from ps2.c by Jim Gettys
*
@@ -35,6 +35,10 @@
#include <sys/ioctl.h>
#include <linux/h3600_ts.h> /* touch screen events */
+static long lastx = 0, lasty = 0;
+int TsScreen;
+extern int TsFbdev;
+
void
TsRead (int tsPort)
{
@@ -52,20 +56,39 @@ TsRead (int tsPort)
{
if (event.pressure)
{
- flags = KD_BUTTON_1;
- x = event.x;
- y = event.y;
- }
- else {
+ /*
+ * HACK ATTACK. (static global variables used !)
+ * Here we test for the touch screen driver actually being on the
+ * touch screen, if it is we send absolute coordinates. If not,
+ * then we send delta's so that we can track the entire vga screen.
+ */
+ if (TsScreen == TsFbdev) {
+ flags = KD_BUTTON_1;
+ x = event.x;
+ y = event.y;
+ } else {
+ flags = /* KD_BUTTON_1 |*/ KD_MOUSE_DELTA;
+ if ((lastx == 0) || (lasty == 0)) {
+ x = 0;
+ y = 0;
+ } else {
+ x = event.x - lastx;
+ y = event.y - lasty;
+ }
+ lastx = event.x;
+ lasty = event.y;
+ }
+ } else {
flags = KD_MOUSE_DELTA;
x = 0;
y = 0;
+ lastx = 0;
+ lasty = 0;
}
KdEnqueueMouseEvent (flags, x, y);
}
}
-
char *TsNames[] = {
"/dev/ts",
"/dev/h3600_ts" /* temporary name; note this code can try
diff --git a/hw/kdrive/pcmcia/Imakefile b/hw/kdrive/pcmcia/Imakefile
new file mode 100644
index 000000000..14ae72466
--- /dev/null
+++ b/hw/kdrive/pcmcia/Imakefile
@@ -0,0 +1,13 @@
+XCOMM $XFree86$
+KDRIVE=..
+#include "../Kdrive.tmpl"
+
+SRCS = pcmcia.c pcmciacurs.c pcmciastub.c pcmciashadow.c
+
+OBJS = pcmcia.o pcmciacurs.o pcmciastub.o pcmciashadow.o
+
+INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/fbdev
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(pcmcia,$(OBJS))
+DependTarget()
diff --git a/hw/kdrive/pcmcia/modes.h b/hw/kdrive/pcmcia/modes.h
new file mode 100644
index 000000000..34c7f653a
--- /dev/null
+++ b/hw/kdrive/pcmcia/modes.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, 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$ */
+
+#define V_NHSYNC 0x01
+#define V_NVSYNC 0x02
+#define V_PHSYNC 0x04
+#define V_PVSYNC 0x08
+#define V_INTERLACE 0x10
+
+pcmciaDisplayModeRec pcmciaDefaultModes [] = {
+/* 640x400 @ 70Hz (VGA) hsync: 37.9kHz */
+ {640, 400, 70 ,31500, 640,672,736,832,0, 400,401,404,445,0, V_NHSYNC | V_PVSYNC},
+/* 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz */
+ {640, 480, 60 ,25200, 640,656,752,800,0, 480,490,492,525,0, V_NHSYNC | V_NVSYNC},
+/* 640x480 @ 72Hz (VESA) hsync: 37.9kHz */
+ {640, 480, 72 ,31500, 640,664,704,832,0, 480,489,491,520,0, V_NHSYNC | V_NVSYNC},
+/* 640x480 @ 75Hz (VESA) hsync: 37.5kHz */
+ {640, 480, 75 ,31500, 640,656,720,840,0, 480,481,484,500,0, V_NHSYNC | V_NVSYNC},
+/* 640x480 @ 85Hz (VESA) hsync: 43.3kHz */
+ {640, 480, 85 ,36000, 640,696,752,832,0, 480,481,484,509,0, V_NHSYNC | V_NVSYNC},
+/* 800x600 @ 56Hz (VESA) hsync: 35.2kHz */
+ {800, 600, 56 ,36000, 800,824,896,1024,0, 600,601,603,625,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 60Hz (VESA) hsync: 37.9kHz */
+ {800, 600, 60 ,40000, 800,840,968,1056,0, 600,601,605,628,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 72Hz (VESA) hsync: 48.1kHz */
+ {800, 600, 72 ,50000, 800,856,976,1040,0, 600,637,643,666,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 75Hz (VESA) hsync: 46.9kHz */
+ {800, 600, 75 ,49500, 800,816,896,1056,0, 600,601,604,625,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 85Hz (VESA) hsync: 53.7kHz */
+ {800, 600, 85 ,56300, 800,832,896,1048,0, 600,601,604,631,0, V_PHSYNC | V_PVSYNC},
+/* 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz */
+ {1024, 768, 43 ,44900, 1024,1032,1208,1264,0, 768,768,776,817,0, V_PHSYNC | V_PVSYNC | V_INTERLACE},
+/* 1024x768 @ 60Hz (VESA) hsync: 48.4kHz */
+ {1024, 768, 60 ,65000, 1024,1048,1184,1344,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC},
+/* 1024x768 @ 70Hz (VESA) hsync: 56.5kHz */
+ {1024, 768, 70 ,75000, 1024,1048,1184,1328,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC},
+/* 1024x768 @ 75Hz (VESA) hsync: 60.0kHz */
+ {1024, 768, 75 ,78800, 1024,1040,1136,1312,0, 768,769,772,800,0, V_PHSYNC | V_PVSYNC},
+/* 1024x768 @ 85Hz (VESA) hsync: 68.7kHz */
+ {1024, 768, 85 ,94500, 1024,1072,1168,1376,0, 768,769,772,808,0, V_PHSYNC | V_PVSYNC},
+/* 1152x864 @ 75Hz (VESA) hsync: 67.5kHz */
+ {1152, 864, 75 ,108000, 1152,1216,1344,1600,0, 864,865,868,900,0, V_PHSYNC | V_PVSYNC},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+};
diff --git a/hw/kdrive/pcmcia/pcmcia.c b/hw/kdrive/pcmcia/pcmcia.c
new file mode 100644
index 000000000..a38686ebb
--- /dev/null
+++ b/hw/kdrive/pcmcia/pcmcia.c
@@ -0,0 +1,929 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, 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>
+ *
+ * A driver for the following PCMCIA cards...
+ * Hewlett Packards HP VGA Out (Model F1252A)
+ * Colorgraphics Voyager VGA
+ *
+ * Tested running under a Compaq IPAQ Pocket PC running Linux
+ */
+/* $XFree86$ */
+
+#include "pcmcia.h"
+#define extern
+#include <asm/io.h>
+#undef extern
+
+#define CLOCK 14318 /* KHz */
+#define CLK_N(a,b) (a & 0xff)
+#define CLK_M(a,b) ((b) & 0x3f)
+#define CLK_K(a,b) (((b) >> 6) & 3)
+#define CLK_FREQ(a,b) (((CLK_N(a,b) + 8) * CLOCK) / ((CLK_M(a,b)+2) << CLK_K(a,b)))
+
+#include "modes.h"
+
+extern void
+tridentUpdatePacked (ScreenPtr pScreen,
+ PixmapPtr pShadow,
+ RegionPtr damage);
+extern void
+cirrusUpdatePacked (ScreenPtr pScreen,
+ PixmapPtr pShadow,
+ RegionPtr damage);
+
+Bool
+pcmciaCardInit (KdCardInfo *card)
+{
+ pcmciaCardInfo *pcmciac;
+ CARD8 r9;
+
+ pcmciac = (pcmciaCardInfo *) xalloc (sizeof (pcmciaCardInfo));
+ if (!pcmciac)
+ return FALSE;
+
+ pcmciac->cop_base = (CARD8 *) KdMapDevice (PCMCIA_COP_BASE(card),
+ PCMCIA_COP_SIZE(card));
+
+ r9 = pcmciaReadIndex (pcmciac, 0x3c4, 0x09);
+ /*
+ * Crude detection....
+ * The trident chip has a read only register at 0x09, which returns 0x4.
+ * If it's not that, we assume the cirrus chip.
+ * BREAKAGE.! If we have an anonymous PCMCIA card inserted, we could
+ * potentially smash something here. FIXME !
+ */
+ if (r9 == 0x04) {
+ ErrorF("PCMCIA: Found HP VGA card\n");
+ pcmciac->HP = TRUE; /* Select HP VGA Out Card */
+ } else {
+ ErrorF("PCMCIA: Found Voyager VGA card\n");
+ pcmciac->HP = FALSE; /* Select Voyager VGA Card */
+ }
+
+ if (pcmciac->HP) {
+ /* needed by the accelerator - later */
+ pcmciac->cop = (Cop *) (pcmciac->cop_base + TRIDENT_COP_OFF(card));
+ }
+
+ /*
+ * Map frame buffer
+ */
+ if (pcmciac->HP)
+ pcmciac->fb = KdMapDevice (0x2ce00000, 0x80000);
+ else
+ pcmciac->fb = KdMapDevice (0x2c0a0000, 0x10000); /*64K bank switched*/
+
+ if (!pcmciac->fb)
+ return FALSE;
+
+ pcmciac->window = 0;
+
+ card->driver = pcmciac;
+
+ return TRUE;
+}
+
+Bool
+pcmciaScreenInit (KdScreenInfo *screen)
+{
+ pcmciaCardInfo *pcmciac = screen->card->driver;
+ pcmciaScreenInfo *pcmcias;
+ int screen_size, memory;
+ int i;
+
+ pcmcias = (pcmciaScreenInfo *) xalloc (sizeof (pcmciaScreenInfo));
+ if (!pcmcias)
+ return FALSE;
+ memset (pcmcias, '\0', sizeof (pcmciaScreenInfo));
+
+ /* if (!pcmciac->cop) */
+ screen->dumb = TRUE;
+
+ /* default to 8bpp */
+ if (!screen->fb[0].depth)
+ screen->fb[0].depth = 8;
+
+ /* default to 60Hz refresh */
+ if (!screen->rate)
+ screen->rate = 60;
+
+ i = 0;
+ pcmcias->Mode = -1;
+ while (pcmciaDefaultModes[i].Width != 0) {
+ if ( (screen->width == pcmciaDefaultModes[i].Width) &&
+ (screen->height == pcmciaDefaultModes[i].Height) &&
+ (screen->rate == pcmciaDefaultModes[i].Refresh) ) {
+ pcmcias->Mode = i;
+ break;
+ }
+ i++;
+ }
+
+ if ( pcmcias->Mode == -1 ) {
+ ErrorF("PCMCIA: no matching vesa mode for screen selection, aborting.\n");
+ ErrorF("PCMCIA: use -listmodes to check for supported list of modes.\n");
+ return FALSE; /* end of list */
+ }
+
+ memory = 512 * 1024;
+ pcmcias->screen = pcmciac->fb;
+
+ if (pcmciac->HP && !screen->softCursor && screen->fb[0].depth == 8) {
+ /* Let's do hw cursor for the HP card, only in 8bit mode though */
+ pcmcias->cursor_base = pcmcias->screen + memory - 4096;
+ memory -= 4096;
+ }
+
+ if (screen->fb[0].depth == 4) {
+ ErrorF("PCMCIA: depth 4 isn't supported.\n");
+ return FALSE; /* screen->fb[0].bitsPerPixel = 4; need fb to support it*/
+ } else
+ if (screen->fb[0].depth == 8)
+ screen->fb[0].bitsPerPixel = 8;
+ else
+ if (screen->fb[0].depth == 15 ||
+ screen->fb[0].depth == 16)
+ screen->fb[0].bitsPerPixel = 16;
+
+ if ( (screen->width * screen->height *
+ (screen->fb[0].bitsPerPixel / 8)) > memory) {
+ ErrorF("PCMCIA: Not enough memory for resolution requested, aborting.\n");
+ return FALSE;
+ }
+
+ screen->fb[0].pixelStride = screen->width;
+ screen->fb[0].byteStride = screen->width * (screen->fb[0].bitsPerPixel >>3);
+
+ screen->fb[0].frameBuffer = pcmciac->fb;
+ switch (screen->fb[0].depth) {
+ case 4:
+ screen->fb[0].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor));
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
+ break;
+ case 8:
+ screen->fb[0].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
+ break;
+ case 15:
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x03e0;
+ screen->fb[0].redMask = 0x7c00;
+ break;
+ case 16:
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x07e0;
+ screen->fb[0].redMask = 0xf800;
+ break;
+ }
+ screen_size = screen->fb[0].byteStride * screen->height;
+
+ screen->driver = pcmcias;
+
+ return KdShadowScreenInit(screen);
+}
+
+void *
+tridentWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ *size = pScreenPriv->screen->fb[0].byteStride;
+ return (CARD8 *) pcmciac->fb + row * pScreenPriv->screen->fb[0].byteStride + offset;
+}
+
+void *
+cirrusWindowWindowed (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ int bank, boffset;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ bank = (row * pScreenPriv->screen->fb[0].byteStride) / 0x1000;
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0B, 8);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x09, bank);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0A, bank);
+ *size = pScreenPriv->screen->fb[0].byteStride;
+ return (CARD8 *) pcmciac->fb + (row * pScreenPriv->screen->fb[0].byteStride) - (bank * 0x1000) + offset;
+}
+
+Bool
+pcmciaInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ ShadowUpdateProc update;
+ ShadowWindowProc window;
+
+ if (pcmciac->HP) {
+ update = tridentUpdatePacked;
+ window = tridentWindowLinear;
+ } else {
+ update = cirrusUpdatePacked;
+ window = cirrusWindowWindowed;
+ }
+ return KdShadowInitScreen (pScreen, update, window);
+}
+
+CARD8
+pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index)
+{
+ CARD8 value;
+
+ pcmciac->cop_base[port] = index;
+ value = pcmciac->cop_base[port+1];
+ return value;
+}
+
+void
+pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value)
+{
+ pcmciac->cop_base[port] = index;
+ pcmciac->cop_base[port+1] = value;
+}
+
+CARD8
+pcmciaReadReg (pcmciaCardInfo *pcmciac, CARD16 port)
+{
+ CARD8 value;
+
+ value = pcmciac->cop_base[port];
+
+ return value;
+}
+
+void
+pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value)
+{
+ pcmciac->cop_base[port] = value;
+}
+
+
+void
+pcmciaPause ()
+{
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 50 * 1000;
+ select (1, 0, 0, 0, &tv);
+}
+
+void
+pcmciaPreserve (KdCardInfo *card)
+{
+}
+
+/* CLOCK_FACTOR is double the osc freq in kHz (osc = 14.31818 MHz) */
+#define CLOCK_FACTOR 28636
+
+/* stability constraints for internal VCO -- MAX_VCO also determines the maximum Video pixel clock */
+#define MIN_VCO CLOCK_FACTOR
+#define MAX_VCO 111000
+
+/* clock in kHz is (numer * CLOCK_FACTOR / (denom & 0x3E)) >> (denom & 1) */
+#define VCOVAL(n, d) \
+ ((((n) & 0x7F) * CLOCK_FACTOR / ((d) & 0x3E)) )
+
+#define CLOCKVAL(n, d) \
+ (VCOVAL(n, d) >> ((d) & 1))
+
+int CirrusFindClock(freq, max_clock, num_out, den_out)
+ int freq;
+ int max_clock;
+ int *num_out;
+ int *den_out;
+{
+ int n;
+ int num = 0, den = 0;
+ int mindiff;
+
+ /*
+ * If max_clock is greater than the MAX_VCO default, ignore
+ * MAX_VCO. On the other hand, if MAX_VCO is higher than max_clock,
+ * make use of the higher MAX_VCO value.
+ */
+ if (MAX_VCO > max_clock)
+ max_clock = MAX_VCO;
+
+ mindiff = freq;
+ for (n = 0x10; n < 0x7f; n++) {
+ int d;
+ for (d = 0x14; d < 0x3f; d++) {
+ int c, diff;
+ /* Avoid combinations that can be unstable. */
+ if ((VCOVAL(n, d) < MIN_VCO) || (VCOVAL(n, d) > max_clock))
+ continue;
+ c = CLOCKVAL(n, d);
+ diff = abs(c - freq);
+ if (diff < mindiff) {
+ mindiff = diff;
+ num = n;
+ den = d;
+ }
+ }
+ }
+
+ *num_out = num;
+ *den_out = den;
+
+ return 0;
+}
+
+
+void
+tridentSetCLK(int clock, CARD8 *a, CARD8 *b)
+{
+ int powerup[4] = { 1,2,4,8 };
+ int clock_diff = 750;
+ int freq, ffreq;
+ int m, n, k;
+ int p, q, r, s;
+ int startn, endn;
+ int endm, endk;
+
+ p = q = r = s = 0;
+
+ startn = 0;
+ endn = 121;
+ endm = 31;
+ endk = 1;
+
+ freq = clock;
+
+ for (k=0;k<=endk;k++)
+ for (n=startn;n<=endn;n++)
+ for (m=1;m<=endm;m++)
+ {
+ ffreq = ( ( ((n + 8) * CLOCK) / ((m + 2) * powerup[k]) ));
+ if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
+ {
+ clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
+ p = n; q = m; r = k; s = ffreq;
+ }
+ }
+
+#if 0
+ ErrorF ("ffreq %d clock %d\n", s, clock);
+#endif
+ if (s == 0)
+ {
+ FatalError("Unable to set programmable clock.\n"
+ "Frequency %d is not a valid clock.\n"
+ "Please modify XF86Config for a new clock.\n",
+ freq);
+ }
+
+ /* N is first 7bits, first M bit is 8th bit */
+ *a = ((1 & q) << 7) | p;
+ /* first 4bits are rest of M, 1bit for K value */
+ *b = (((q & 0xFE) >> 1) | (r << 4));
+}
+
+Bool
+pcmciaEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+ int i,j;
+ unsigned char Sequencer[6];
+ unsigned char CRTC[31];
+ unsigned char Graphics[9];
+ unsigned char Attribute[21];
+ unsigned char MiscOutReg;
+ pcmciaDisplayModeRec mode = pcmciaDefaultModes[pcmcias->Mode];
+
+ /*
+ * compute correct Hsync & Vsync polarity
+ */
+ if ((mode.Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode.Flags & (V_PVSYNC | V_NVSYNC)))
+ {
+ MiscOutReg = 0x23;
+ if (mode.Flags & V_NHSYNC) MiscOutReg |= 0x40;
+ if (mode.Flags & V_NVSYNC) MiscOutReg |= 0x80;
+ }
+ else
+ {
+ int VDisplay = mode.VDisplay;
+ if (VDisplay < 400)
+ MiscOutReg = 0xA3; /* +hsync -vsync */
+ else if (VDisplay < 480)
+ MiscOutReg = 0x63; /* -hsync +vsync */
+ else if (VDisplay < 768)
+ MiscOutReg = 0xE3; /* -hsync -vsync */
+ else
+ MiscOutReg = 0x23; /* +hsync +vsync */
+ }
+
+ /*
+ * Time Sequencer
+ */
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ Sequencer[0] = 0x02;
+ else
+ Sequencer[0] = 0x00;
+ Sequencer[1] = 0x01;
+ Sequencer[2] = 0x0F;
+ Sequencer[3] = 0x00; /* Font select */
+ if (pScreenPriv->screen->fb[0].depth < 8)
+ Sequencer[4] = 0x06; /* Misc */
+ else
+ Sequencer[4] = 0x0E; /* Misc */
+ Sequencer[5] = 0x00;
+
+ /*
+ * CRTC Controller
+ */
+ CRTC[0] = (mode.HTotal >> 3) - 5;
+ CRTC[1] = (mode.HDisplay >> 3) - 1;
+ CRTC[2] = ((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1;
+ CRTC[3] = ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F) | 0x80;
+ i = (((mode.HSkew << 2) + 0x10) & ~0x1F);
+ if (i < 0x80)
+ CRTC[3] |= i;
+ CRTC[4] = (mode.HSyncStart >> 3);
+ CRTC[5] = (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2)
+ | (((mode.HSyncEnd >> 3)) & 0x1F);
+ CRTC[6] = (mode.VTotal - 2) & 0xFF;
+ CRTC[7] = (((mode.VTotal - 2) & 0x100) >> 8)
+ | (((mode.VDisplay - 1) & 0x100) >> 7)
+ | ((mode.VSyncStart & 0x100) >> 6)
+ | ((((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0x100) >> 5)
+ | 0x10
+ | (((mode.VTotal - 2) & 0x200) >> 4)
+ | (((mode.VDisplay - 1) & 0x200) >> 3)
+ | ((mode.VSyncStart & 0x200) >> 2);
+ CRTC[8] = 0x00;
+ CRTC[9] = ((((min(mode.VSyncStart,mode.VDisplay))-1) & 0x200) >> 4) | 0x40;
+ CRTC[10] = 0x00;
+ CRTC[11] = 0x00;
+ CRTC[12] = 0x00;
+ CRTC[13] = 0x00;
+ CRTC[14] = 0x00;
+ CRTC[15] = 0x00;
+ CRTC[16] = mode.VSyncStart & 0xFF;
+ CRTC[17] = (mode.VSyncEnd & 0x0F) | 0x20;
+ CRTC[18] = (mode.VDisplay - 1) & 0xFF;
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 4;
+ else
+ if (pScreenPriv->screen->fb[0].depth == 8)
+ CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 3;
+ else
+ if (pScreenPriv->screen->fb[0].depth == 16 ||
+ pScreenPriv->screen->fb[0].depth == 15)
+ CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 2;
+ CRTC[20] = 0x00;
+ CRTC[21] = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF;
+ CRTC[22] = ((min(mode.VSyncEnd,mode.VDisplay)) - 1) & 0xFF;
+ if (pScreenPriv->screen->fb[0].depth < 8)
+ CRTC[23] = 0xE3;
+ else
+ CRTC[23] = 0xC3;
+ CRTC[24] = 0xFF;
+ CRTC[25] = 0x00;
+ CRTC[26] = 0x00;
+ if (!pcmciac->HP)
+ if (mode.Flags & V_INTERLACE) CRTC[26] |= 0x01;
+ if (pcmciac->HP)
+ CRTC[27] = 0x00;
+ else
+ CRTC[27] = 0x22;
+ CRTC[28] = 0x00;
+ CRTC[29] = 0x00;
+ CRTC[30] = 0x80;
+ if (pcmciac->HP)
+ if (mode.Flags & V_INTERLACE) CRTC[30] |= 0x04;
+
+{
+ int nExtBits = 0;
+ CARD32 ExtBits;
+ CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
+
+ CRTC[3] = (CRTC[3] & ~0x1F)
+ | ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F);
+ CRTC[5] = (CRTC[5] & ~0x80)
+ | (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2);
+ ExtBits = (((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & ExtBitMask;
+
+ /* First the horizontal case */
+ if ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) == (mode.HTotal >> 3)))
+ {
+ int i = (CRTC[3] & 0x1F)
+ | ((CRTC[5] & 0x80) >> 2)
+ | ExtBits;
+ if ((i-- > ((((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1)
+ & (0x3F | ExtBitMask)))
+ && ((min(mode.HSyncEnd,mode.HTotal)) == mode.HTotal))
+ i = 0;
+ CRTC[3] = (CRTC[3] & ~0x1F) | (i & 0x1F);
+ CRTC[5] = (CRTC[5] & ~0x80) | ((i << 2) & 0x80);
+ ExtBits = i & ExtBitMask;
+ }
+}
+{
+ CARD32 ExtBits;
+ CARD32 ExtBitMask = 0;
+ /* If width is not known nBits should be 0. In this
+ * case BitMask is set to 0 so we can check for it. */
+ CARD32 BitMask = 0;
+ int VBlankStart = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF;
+ CRTC[22] = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & 0xFF;
+ ExtBits = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & ExtBitMask;
+
+ if ((min(mode.VSyncEnd,mode.VTotal)) == mode.VTotal)
+ /* Null top overscan */
+ {
+ int i = CRTC[22] | ExtBits;
+ if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask)))
+ || ((i > VBlankStart) && /* 8-bit case */
+ ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */
+ !(CRTC[9] & 0x9F)) /* 1 scanline/row */
+ i = 0;
+ else
+ i = (i - 1);
+ CRTC[22] = i & 0xFF;
+ ExtBits = i & 0xFF00;
+ }
+}
+
+ /*
+ * Graphics Display Controller
+ */
+ Graphics[0] = 0x00;
+ Graphics[1] = 0x00;
+ Graphics[2] = 0x00;
+ Graphics[3] = 0x00;
+ Graphics[4] = 0x00;
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ Graphics[5] = 0x02;
+ else
+ Graphics[5] = 0x40;
+ Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
+ Graphics[7] = 0x0F;
+ Graphics[8] = 0xFF;
+
+ Attribute[0] = 0x00; /* standard colormap translation */
+ Attribute[1] = 0x01;
+ Attribute[2] = 0x02;
+ Attribute[3] = 0x03;
+ Attribute[4] = 0x04;
+ Attribute[5] = 0x05;
+ Attribute[6] = 0x06;
+ Attribute[7] = 0x07;
+ Attribute[8] = 0x08;
+ Attribute[9] = 0x09;
+ Attribute[10] = 0x0A;
+ Attribute[11] = 0x0B;
+ Attribute[12] = 0x0C;
+ Attribute[13] = 0x0D;
+ Attribute[14] = 0x0E;
+ Attribute[15] = 0x0F;
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ Attribute[16] = 0x81;
+ else
+ Attribute[16] = 0x41;
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
+ Attribute[17] = 0x00;
+ else
+ Attribute[17] = 0xFF;
+ Attribute[18] = 0x0F;
+ Attribute[19] = 0x00;
+ Attribute[20] = 0x00;
+
+ /* Wake up the card */
+ if (pcmciac->HP) {
+ pcmciaWriteReg(pcmciac, 0x3c3, 0x1);
+ pcmciaWriteReg(pcmciac, 0x46e8, 0x10);
+ } else {
+ pcmciaWriteReg(pcmciac, 0x105, 0x1);
+ pcmciaWriteReg(pcmciac, 0x46e8, 0x1f);
+ pcmciaWriteReg(pcmciac, 0x102, 0x1);
+ pcmciaWriteReg(pcmciac, 0x46e8, 0xf);
+ pcmciaWriteReg(pcmciac, 0x3c3, 0x1);
+ }
+
+ if (pcmciac->HP) {
+ /* unlock */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x11, 0x92);
+ j = pcmciaReadIndex(pcmciac, 0x3c4, 0xb);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0xe, 0xc2);
+
+ /* switch on dac */
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x29, 0x24);
+ /* switch on the accelerator */
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x36, 0x80);
+
+ /* bump up memory clk */
+ pcmciaWriteReg(pcmciac, 0x43c6, 0x65);
+ pcmciaWriteReg(pcmciac, 0x43c7, 0x00);
+ } else {
+ /* unlock */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x06, 0x12);
+ pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg);
+ }
+
+ /* synchronous reset */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0);
+
+ pcmciaWriteReg(pcmciac, 0x3da, 0x10);
+
+ for (i=0;i<6;i++)
+ pcmciaWriteIndex(pcmciac, 0x3c4, i, Sequencer[i]);
+
+ if (pcmciac->HP) {
+ /* Stick chip into color mode */
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x2f, 0x06);
+ /* Switch on Linear addressing */
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x21, 0x2e);
+ } else {
+ /* Stick chip into 8bit access mode - ugh! */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x0F, 0x20); /* 0x26 ? */
+ /* reset mclk */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x1F, 0);
+ }
+
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0x3);
+
+ for (i=0;i<31;i++)
+ pcmciaWriteIndex(pcmciac, 0x3d4, i, CRTC[i]);
+
+ for (i=0;i<9;i++)
+ pcmciaWriteIndex(pcmciac, 0x3ce, i, Graphics[i]);
+
+ j = pcmciaReadReg(pcmciac, 0x3da);
+
+ for (i=0;i<21;i++) {
+ pcmciaWriteReg(pcmciac, 0x3c0, i);
+ pcmciaWriteReg(pcmciac, 0x3c0, Attribute[i]);
+ }
+
+ j = pcmciaReadReg(pcmciac, 0x3da);
+ pcmciaWriteReg(pcmciac, 0x3c0, 0x20);
+
+ j = pcmciaReadReg(pcmciac, 0x3c8);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ switch (pScreenPriv->screen->fb[0].depth) {
+ /* This is here for completeness, when/if we ever do 4bpp */
+ case 4:
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x0);
+ if (pcmciac->HP) {
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x90);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00);
+ } else
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x00);
+ break;
+ case 8:
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x0);
+ if (pcmciac->HP) {
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x92);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00);
+ } else
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x01);
+ break;
+ case 15:
+ if (pcmciac->HP) {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x10);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04);
+ } else {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0xC0);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03);
+ }
+ break;
+ case 16:
+ if (pcmciac->HP) {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x30);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04);
+ } else {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0xC1);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03);
+ }
+ break;
+ }
+ j = pcmciaReadReg(pcmciac, 0x3c8);
+
+ pcmciaWriteReg(pcmciac, 0x3c6, 0xff);
+
+ for (i=0;i<256;i++) {
+ pcmciaWriteReg(pcmciac, 0x3c8, i);
+ pcmciaWriteReg(pcmciac, 0x3c9, i);
+ pcmciaWriteReg(pcmciac, 0x3c9, i);
+ pcmciaWriteReg(pcmciac, 0x3c9, i);
+ }
+
+ /* Set the Clock */
+ if (pcmciac->HP) {
+ CARD8 a,b;
+ int clock = mode.Clock;
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
+ clock *= 2;
+ tridentSetCLK(clock, &a, &b);
+ pcmciaWriteReg(pcmciac, 0x43c8, a);
+ pcmciaWriteReg(pcmciac, 0x43c9, b);
+ } else {
+ int num, den;
+ unsigned char tmp;
+ int clock = mode.Clock;
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
+ clock *= 2;
+
+ CirrusFindClock(clock, MAX_VCO, &num, &den);
+
+ tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x0d);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x0d, (tmp & 0x80) | num);
+ tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x1d);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x1d, (tmp & 0xc0) | den);
+ }
+ pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg | 0x08);
+
+#if 0 /* for debugging */
+ for (i=1;i<0x3f;i++)
+ ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3c4, i));
+
+ ErrorF("\n");
+
+ for (i=0;i<0x3f;i++)
+ ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3ce, i));
+
+ ErrorF("\n");
+
+ for (i=0;i<0x3f;i++)
+ ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3d4, i));
+#endif
+
+ return TRUE;
+}
+
+void
+pcmciaDisable (ScreenPtr pScreen)
+{
+}
+
+const CARD8 tridentDPMSModes[4] = {
+ 0x00, /* KD_DPMS_NORMAL */
+ 0x01, /* KD_DPMS_STANDBY */
+ 0x02, /* KD_DPMS_SUSPEND */
+ 0x03, /* KD_DPMS_POWERDOWN */
+};
+
+Bool
+pcmciaDPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ if (pcmciac->HP) {
+ pcmciaWriteIndex (pcmciac, 0x3ce, 0x23, tridentDPMSModes[mode]);
+ pcmciaPause ();
+ } else {
+ /* Voyager */
+ }
+
+ return TRUE;
+}
+
+void
+pcmciaRestore (KdCardInfo *card)
+{
+}
+
+void
+pcmciaScreenFini (KdScreenInfo *screen)
+{
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) screen->driver;
+
+ xfree (pcmcias);
+ screen->driver = 0;
+}
+
+void
+pcmciaCardFini (KdCardInfo *card)
+{
+ pcmciaCardInfo *pcmciac = card->driver;
+
+ if (pcmciac->cop_base)
+ KdUnmapDevice ((void *) pcmciac->cop_base, PCMCIA_COP_SIZE(card));
+}
+
+void
+pcmciaGetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ while (ndef--)
+ {
+ pcmciaWriteReg (pcmciac, 0x3C7, pdefs->pixel);
+ pdefs->red = pcmciaReadReg (pcmciac, 0x3C9) << 10;
+ pdefs->green = pcmciaReadReg (pcmciac, 0x3C9) << 10;
+ pdefs->blue = pcmciaReadReg (pcmciac, 0x3C9) << 10;
+ pdefs++;
+ }
+}
+
+void
+pcmciaPutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ while (ndef--)
+ {
+ pcmciaWriteReg (pcmciac, 0x3C8, pdefs->pixel);
+ pcmciaWriteReg (pcmciac, 0x3C9, pdefs->red >> 10);
+ pcmciaWriteReg (pcmciac, 0x3C9, pdefs->green >> 10);
+ pcmciaWriteReg (pcmciac, 0x3C9, pdefs->blue >> 10);
+ pdefs++;
+ }
+}
+
+
+KdCardFuncs pcmciaFuncs = {
+ pcmciaCardInit, /* cardinit */
+ pcmciaScreenInit, /* scrinit */
+ pcmciaInitScreen, /* initScreen */
+ pcmciaPreserve, /* preserve */
+ pcmciaEnable, /* enable */
+ pcmciaDPMS, /* dpms */
+ pcmciaDisable, /* disable */
+ pcmciaRestore, /* restore */
+ pcmciaScreenFini, /* scrfini */
+ pcmciaCardFini, /* cardfini */
+
+ pcmciaCursorInit, /* initCursor */
+ pcmciaCursorEnable, /* enableCursor */
+ pcmciaCursorDisable, /* disableCursor */
+ pcmciaCursorFini, /* finiCursor */
+ pcmciaRecolorCursor, /* recolorCursor */
+
+#if 0 /* not yet */
+ pcmciaDrawInit, /* initAccel */
+ pcmciaDrawEnable, /* enableAccel */
+ pcmciaDrawSync, /* syncAccel */
+ pcmciaDrawDisable, /* disableAccel */
+ pcmciaDrawFini, /* finiAccel */
+#else
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#endif
+
+ pcmciaGetColors, /* getColors */
+ pcmciaPutColors, /* putColors */
+};
diff --git a/hw/kdrive/pcmcia/pcmcia.h b/hw/kdrive/pcmcia/pcmcia.h
new file mode 100644
index 000000000..9e26dc282
--- /dev/null
+++ b/hw/kdrive/pcmcia/pcmcia.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, 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$ */
+
+#ifndef _PCMCIA_H_
+#define _PCMCIA_H_
+
+#include <fbdev.h>
+
+/*
+ * offset from ioport beginning
+ */
+
+#define PCMCIA_COP_BASE(c) 0x20000000
+#define PCMCIA_COP_SIZE(c) 0x10000
+#define TRIDENT_COP_OFF(c) 0x2100
+
+typedef volatile CARD8 VOL8;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD32 VOL32;
+
+typedef struct _cop {
+ VOL32 src_start_xy; /* 0x00 */
+ VOL32 src_end_xy; /* 0x04 */
+ VOL32 dst_start_xy; /* 0x08 */
+ VOL32 dst_end_xy; /* 0x0c */
+ VOL32 alpha; /* 0x10 */
+ CARD8 pad14[0xc]; /* 0x14 */
+ VOL32 multi; /* 0x20 */
+
+#define COP_MULTI_CLIP_TOP_LEFT 0x10000000
+#define COP_MULTI_DEPTH 0x40000000
+#define COP_MULTI_COLOR_KEY 0x70000000
+#define COP_MULTI_STYLE 0x50000000
+#define COP_MULTI_PATTERN 0x80000000
+#define COP_MULTI_ROP 0x90000000
+#define COP_MULTI_STRIDE 0x60000000
+#define COP_MULTI_Z 0xa0000000
+#define COP_MULTI_ALPHA 0xb0000000
+#define COP_MULTI_TEXTURE 0xd0000000
+#define COP_MULTI_TEXTURE_BOUND 0xe0000000
+#define COP_MULTI_TEXTURE_ADVANCED 0x20000000
+#define COP_MULTI_MASK 0xf0000000
+
+#define COP_DEPTH_8 0x00000000
+#define COP_DEPTH_16 0x00000001
+#define COP_DEPTH_24_32 0x00000002
+#define COP_DEPTH_15 0x00000005
+#define COP_DEPTH_DITHER_DISABLE 0x00000008
+
+
+#define COP_ALPHA_SRC_BLEND_0 0x00000000
+#define COP_ALPHA_SRC_BLEND_1 0x00000001
+#define COP_ALPHA_SRC_BLEND_SRC_C 0x00000002
+#define COP_ALPHA_SRC_BLEND_1_SRC_C 0x00000003
+#define COP_ALPHA_SRC_BLEND_SRC_A 0x00000004
+#define COP_ALPHA_SRC_BLEND_1_SRC_A 0x00000005
+#define COP_ALPHA_SRC_BLEND_DST_A 0x00000006
+#define COP_ALPHA_SRC_BLEND_1_DST_A 0x00000007
+#define COP_ALPHA_SRC_BLEND_DST_C 0x00000008
+#define COP_ALPHA_SRC_BLEND_1_DST_C 0x00000009
+#define COP_ALPHA_SRC_BLEND_SAT 0x0000000A
+#define COP_ALPHA_SRC_BLEND_BG 0x0000000B
+
+#define COP_ALPHA_DST_BLEND_0 0x00000000
+#define COP_ALPHA_DST_BLEND_1 0x00000010
+#define COP_ALPHA_DST_BLEND_SRC_C 0x00000020
+#define COP_ALPHA_DST_BLEND_1_SRC_C 0x00000030
+#define COP_ALPHA_DST_BLEND_SRC_A 0x00000040
+#define COP_ALPHA_DST_BLEND_1_SRC_A 0x00000050
+#define COP_ALPHA_DST_BLEND_DST_A 0x00000060
+#define COP_ALPHA_DST_BLEND_1_DST_A 0x00000070
+#define COP_ALPHA_DST_BLEND_DST_C 0x00000080
+#define COP_ALPHA_DST_BLEND_1_DST_C 0x00000090
+#define COP_ALPHA_DST_BLEND_OTHER 0x000000A0
+
+#define COP_ALPHA_RESULT_ALPHA 0x00100000
+#define COP_ALPHA_DEST_ALPHA 0x00200000
+#define COP_ALPHA_SOURCE_ALPHA 0x00400000
+#define COP_ALPHA_WRITE_ENABLE 0x00800000
+#define COP_ALPHA_TEST_ENABLE 0x01000000
+#define COP_ALPHA_BLEND_ENABLE 0x02000000
+#define COP_ALPHA_DEST_VALUE 0x04000000
+#define COP_ALPHA_SOURCE_VALUE 0x08000000
+
+ VOL32 command; /* 0x24 */
+#define COP_OP_NULL 0x00000000
+#define COP_OP_LINE 0x20000000
+#define COP_OP_BLT 0x80000000
+#define COP_OP_TEXT 0x90000000
+#define COP_OP_POLY 0xb0000000
+#define COP_OP_POLY2 0xe0000000
+#define COP_SCL_EXPAND 0x00800000
+#define COP_SCL_OPAQUE 0x00400000
+#define COP_SCL_REVERSE 0x00200000
+#define COP_SCL_MONO_OFF 0x001c0000
+#define COP_LIT_TEXTURE 0x00004000
+#define COP_BILINEAR 0x00002000
+#define COP_OP_ZBUF 0x00000800
+#define COP_OP_ROP 0x00000400
+#define COP_OP_FG 0x00000200
+#define COP_OP_FB 0x00000080
+#define COP_X_REVERSE 0x00000004
+#define COP_CLIP 0x00000001
+ VOL32 texture_format; /* 0x28 */
+ CARD8 pad2c[0x4]; /* 0x2c */
+
+ VOL32 clip_bottom_right; /* 0x30 */
+ VOL32 dataIII; /* 0x34 */
+ VOL32 dataIV; /* 0x38 */
+ CARD8 pad3c[0x8]; /* 0x3c */
+
+ VOL32 fg; /* 0x44 */
+ VOL32 bg; /* 0x48 */
+ CARD8 pad4c[0x4]; /* 0x4c */
+
+ VOL32 pattern_fg; /* 0x50 */
+ VOL32 pattern_bg; /* 0x54 */
+ CARD8 pad58[0xc]; /* 0x58 */
+
+ VOL32 status; /* 0x64 */
+#define COP_STATUS_BE_BUSY 0x80000000
+#define COP_STATUS_DPE_BUSY 0x20000000
+#define COP_STATUS_MI_BUSY 0x10000000
+#define COP_STATUS_FIFO_BUSY 0x08000000
+#define COP_STATUS_WB_BUSY 0x00800000
+#define COP_STATUS_Z_FAILED 0x00400000
+#define COP_STATUS_EFFECTIVE 0x00200000
+#define COP_STATUS_LEFT_VIEW 0x00080000
+
+ CARD8 pad68[0x4]; /* 0x68 */
+
+ VOL32 src_offset; /* 0x6c */
+ VOL32 z_offset; /* 0x70 */
+ CARD8 pad74[0x4]; /* 0x74 */
+
+ VOL32 display_offset; /* 0x78 */
+ VOL32 dst_offset; /* 0x7c */
+ CARD8 pad80[0x34]; /* 0x80 */
+
+ VOL32 semaphore; /* 0xb4 */
+} Cop;
+
+#define TRI_XY(x,y) ((y) << 16 | (x))
+
+typedef struct _pcmciaCardInfo {
+ CARD8 *fb;
+ Bool HP;
+ CARD8 *cop_base;
+ Cop *cop;
+ CARD32 *window;
+ CARD32 cop_depth;
+ CARD32 cop_stride;
+} pcmciaCardInfo;
+
+#define getpcmciaCardInfo(kd) ((pcmciaCardInfo *) ((kd)->card->driver))
+#define pcmciaCardInfo(kd) pcmciaCardInfo *pcmciac = getpcmciaCardInfo(kd)
+
+typedef struct _pcmciaCursor {
+ int width, height;
+ int xhot, yhot;
+ Bool has_cursor;
+ CursorPtr pCursor;
+ Pixel source, mask;
+} pcmciaCursor;
+
+#define PCMCIA_CURSOR_WIDTH 64
+#define PCMCIA_CURSOR_HEIGHT 64
+
+typedef struct _pcmciaScreenInfo {
+ int Mode;
+ CARD8 *cursor_base;
+ CARD8 *screen;
+ CARD8 *off_screen;
+ int off_screen_size;
+ pcmciaCursor cursor;
+} pcmciaScreenInfo;
+
+#define getpcmciaScreenInfo(kd) ((pcmciaScreenInfo *) ((kd)->screen->driver))
+#define pcmciaScreenInfo(kd) pcmciaScreenInfo *pcmcias = getpcmciaScreenInfo(kd)
+
+Bool
+pcmciaDrawInit (ScreenPtr pScreen);
+
+void
+pcmciaDrawEnable (ScreenPtr pScreen);
+
+void
+pcmciaDrawSync (ScreenPtr pScreen);
+
+void
+pcmciaDrawDisable (ScreenPtr pScreen);
+
+void
+pcmciaDrawFini (ScreenPtr pScreen);
+
+CARD8
+pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index);
+
+void
+pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value);
+
+void
+pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value);
+
+Bool
+pcmciaCursorInit (ScreenPtr pScreen);
+
+void
+pcmciaCursorEnable (ScreenPtr pScreen);
+
+void
+pcmciaCursorDisable (ScreenPtr pScreen);
+
+void
+pcmciaCursorFini (ScreenPtr pScreen);
+
+void
+pcmciaRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef);
+
+typedef struct _pcmciaDisplayModeRec {
+ int Width;
+ int Height;
+ int Refresh;
+ int Clock; /* pixel clock freq */
+ int HDisplay; /* horizontal timing */
+ int HSyncStart;
+ int HSyncEnd;
+ int HTotal;
+ int HSkew;
+ int VDisplay; /* vertical timing */
+ int VSyncStart;
+ int VSyncEnd;
+ int VTotal;
+ int VScan;
+ int Flags;
+} pcmciaDisplayModeRec, *pcmciaDisplayModePtr;
+
+extern KdCardFuncs pcmciaFuncs;
+
+#endif /* _PCMCIA_H_ */
diff --git a/hw/kdrive/pcmcia/pcmciacurs.c b/hw/kdrive/pcmcia/pcmciacurs.c
new file mode 100644
index 000000000..38612ae32
--- /dev/null
+++ b/hw/kdrive/pcmcia/pcmciacurs.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, 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$ */
+
+#include "pcmcia.h"
+#include "cursorstr.h"
+
+#define SetupCursor(s) KdScreenPriv(s); \
+ pcmciaCardInfo(pScreenPriv); \
+ pcmciaScreenInfo(pScreenPriv); \
+ pcmciaCursor *pCurPriv = &pcmcias->cursor
+
+static void
+_pcmciaMoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CARD8 xlow, xhigh, ylow, yhigh;
+ CARD8 xoff, yoff;
+
+ x -= pCurPriv->xhot;
+ xoff = 0;
+ if (x < 0)
+ {
+ xoff = -x;
+ x = 0;
+ }
+ y -= pCurPriv->yhot;
+ yoff = 0;
+ if (y < 0)
+ {
+ yoff = -y;
+ y = 0;
+ }
+
+ /* This is the recommended order to move the cursor */
+ if (pcmciac->HP) {
+ xlow = (CARD8) x;
+ xhigh = (CARD8) (x >> 8);
+ ylow = (CARD8) y;
+ yhigh = (CARD8) (y >> 8);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x40, xlow);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x41, xhigh);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x42, ylow);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x43, yhigh);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x46, xoff);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x47, yoff);
+ } else {
+ x >>= 3;
+ y >>= 3;
+ xlow = (CARD8) x;
+ xhigh = (CARD8) (x >> 8);
+ ylow = (CARD8) y;
+ yhigh = (CARD8) (y >> 8);
+ /* Don't be alarmed, yes the upper 3bits of the index are correct */
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x10 | xhigh << 5, xlow);
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x11 | yhigh << 5, ylow);
+ }
+}
+
+static void
+pcmciaMoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor (pScreen);
+
+ if (!pCurPriv->has_cursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ _pcmciaMoveCursor (pScreen, x, y);
+}
+
+static void
+pcmciaAllocCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+
+ KdAllocateCursorPixels (pScreen, 0, pCursor,
+ &pCurPriv->source, &pCurPriv->mask);
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 4:
+ pCurPriv->source |= pCurPriv->source << 4;
+ pCurPriv->mask |= pCurPriv->mask << 4;
+ case 8:
+ pCurPriv->source |= pCurPriv->source << 8;
+ pCurPriv->mask |= pCurPriv->mask << 8;
+ case 16:
+ pCurPriv->source |= pCurPriv->source << 16;
+ pCurPriv->mask |= pCurPriv->mask << 16;
+ }
+}
+
+static void
+pcmciaSetCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CARD32 fg, bg;
+
+ fg = pCurPriv->source;
+ bg = pCurPriv->mask;
+
+ if (pcmciac->HP) {
+ /*
+ * This trident chip uses the palette for it's cursor colors - ouch!
+ * We enforce it to always stay the black/white colors as we don't
+ * want it to muck with the overscan color. Tough. Use softCursor
+ * if you want to change cursor colors.
+ */
+ pcmciaWriteReg (pcmciac, 0x3c8, 0xff); /* DAC 0 */
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
+ pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 255 */
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
+ } else {
+ CARD8 temp;
+ temp = pcmciaReadIndex(pcmciac, 0x3c4, 0x12);
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, (temp & 0xFE) | 0x02);
+
+ pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 256 */
+ pcmciaWriteReg (pcmciac, 0x3c9, fg);
+ pcmciaWriteReg (pcmciac, 0x3c9, fg >> 8);
+ pcmciaWriteReg (pcmciac, 0x3c9, fg >> 16);
+ pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 257 */
+ pcmciaWriteReg (pcmciac, 0x3c9, bg);
+ pcmciaWriteReg (pcmciac, 0x3c9, bg >> 8);
+ pcmciaWriteReg (pcmciac, 0x3c9, bg >> 16);
+
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, temp);
+ }
+}
+
+void
+pcmciaRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ xColorItem sourceColor, maskColor;
+
+ if (!pCurPriv->has_cursor || !pCursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pdef)
+ {
+ while (ndef)
+ {
+ if (pdef->pixel == pCurPriv->source ||
+ pdef->pixel == pCurPriv->mask)
+ break;
+ ndef--;
+ }
+ if (!ndef)
+ return;
+ }
+ pcmciaAllocCursorColors (pScreen);
+ pcmciaSetCursorColors (pScreen);
+}
+
+#define InvertBits32(v) { \
+ v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
+ v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
+ v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
+}
+
+static void
+pcmciaLoadCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CursorBitsPtr bits = pCursor->bits;
+ int w, h;
+ CARD8 *ram;
+ CARD32 *msk, *mskLine, *src, *srcLine;
+ int i, j;
+ int cursor_address;
+ int lwsrc;
+ unsigned char ramdac_control_;
+ CARD32 offset;
+
+ /*
+ * Allocate new colors
+ */
+ pcmciaAllocCursorColors (pScreen);
+
+ pCurPriv->pCursor = pCursor;
+ pCurPriv->xhot = pCursor->bits->xhot;
+ pCurPriv->yhot = pCursor->bits->yhot;
+
+ /*
+ * Stick new image into cursor memory
+ */
+ if (pcmciac->HP) {
+ ram = (CARD8 *) pcmcias->cursor_base;
+ } else {
+ /* The last bank */
+ ram = (CARD8 *) pcmciac->fb;
+ pcmciaWriteIndex (pcmciac, 0x3ce, 0x09, 0x7f);
+ pcmciaWriteIndex (pcmciac, 0x3ce, 0x0A, 0x7f);
+ }
+
+ mskLine = (CARD32 *) bits->mask;
+ srcLine = (CARD32 *) bits->source;
+
+ h = bits->height;
+ if (h > PCMCIA_CURSOR_HEIGHT)
+ h = PCMCIA_CURSOR_HEIGHT;
+
+ lwsrc = BitmapBytePad(bits->width) / 4;
+
+ for (i = 0; i < PCMCIA_CURSOR_HEIGHT; i++) {
+ msk = mskLine;
+ src = srcLine;
+ mskLine += lwsrc;
+ srcLine += lwsrc;
+ for (j = 0; j < PCMCIA_CURSOR_WIDTH / 32; j++) {
+
+ CARD32 m, s;
+
+ if (i < h && j < lwsrc)
+ {
+ m = *msk++;
+ s = *src++;
+ InvertBits32(m);
+ InvertBits32(s);
+ }
+ else
+ {
+ m = 0;
+ s = 0;
+ }
+
+ /* Do 8bit access */
+ *ram++ = (m & 0xff);
+ *ram++ = (m & 0xff00) >> 8;
+ *ram++ = (m & 0xff0000) >> 16;
+ *ram++ = (m & 0xff000000) >> 24;
+ *ram++ = (s & 0xff);
+ *ram++ = (s & 0xff00) >> 8;
+ *ram++ = (s & 0xff0000) >> 16;
+ *ram++ = (s & 0xff000000) >> 24;
+ }
+ }
+
+ /* Set address for cursor bits */
+ if (pcmciac->HP) {
+ offset = pcmcias->cursor_base - (CARD8 *) pcmcias->screen;
+ offset >>= 10;
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x44, (CARD8) (offset & 0xff));
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x45, (CARD8) (offset >> 8));
+ } else {
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x13, 15); /* ?? */
+ }
+
+ /* Set new color */
+ pcmciaSetCursorColors (pScreen);
+
+ /* Enable the cursor */
+ if (pcmciac->HP)
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0xc1);
+ else
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0x05);
+
+ /* Move to new position */
+ pcmciaMoveCursor (pScreen, x, y);
+}
+
+static void
+pcmciaUnloadCursor (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ /* Disable cursor */
+ if (pcmciac->HP)
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0);
+ else
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0);
+}
+
+static Bool
+pcmciaRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ SetupCursor(pScreen);
+
+ if (!pScreenPriv->enabled)
+ return TRUE;
+
+ /* miRecolorCursor does this */
+ if (pCurPriv->pCursor == pCursor)
+ {
+ if (pCursor)
+ {
+ int x, y;
+
+ miPointerPosition (&x, &y);
+ pcmciaLoadCursor (pScreen, x, y);
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+pcmciaUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+pcmciaSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ SetupCursor(pScreen);
+
+ pCurPriv->pCursor = pCursor;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCursor)
+ pcmciaLoadCursor (pScreen, x, y);
+ else
+ pcmciaUnloadCursor (pScreen);
+}
+
+miPointerSpriteFuncRec pcmciaPointerSpriteFuncs = {
+ pcmciaRealizeCursor,
+ pcmciaUnrealizeCursor,
+ pcmciaSetCursor,
+ pcmciaMoveCursor,
+};
+
+static void
+pcmciaQueryBestSize (int class,
+ unsigned short *pwidth, unsigned short *pheight,
+ ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ switch (class)
+ {
+ case CursorShape:
+ if (*pwidth > pCurPriv->width)
+ *pwidth = pCurPriv->width;
+ if (*pheight > pCurPriv->height)
+ *pheight = pCurPriv->height;
+ if (*pwidth > pScreen->width)
+ *pwidth = pScreen->width;
+ if (*pheight > pScreen->height)
+ *pheight = pScreen->height;
+ break;
+ default:
+ fbQueryBestSize (class, pwidth, pheight, pScreen);
+ break;
+ }
+}
+
+Bool
+pcmciaCursorInit (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pcmcias->cursor_base)
+ {
+ pCurPriv->has_cursor = FALSE;
+ return FALSE;
+ }
+
+ pCurPriv->width = PCMCIA_CURSOR_WIDTH;
+ pCurPriv->height= PCMCIA_CURSOR_HEIGHT;
+ pScreen->QueryBestSize = pcmciaQueryBestSize;
+ miPointerInitialize (pScreen,
+ &pcmciaPointerSpriteFuncs,
+ &kdPointerScreenFuncs,
+ FALSE);
+ pCurPriv->has_cursor = TRUE;
+ pCurPriv->pCursor = NULL;
+ return TRUE;
+}
+
+void
+pcmciaCursorEnable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ int x, y;
+
+ miPointerPosition (&x, &y);
+ pcmciaLoadCursor (pScreen, x, y);
+ }
+ else
+ pcmciaUnloadCursor (pScreen);
+ }
+}
+
+void
+pcmciaCursorDisable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ pcmciaUnloadCursor (pScreen);
+ }
+ }
+}
+
+void
+pcmciaCursorFini (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ pCurPriv->pCursor = NULL;
+}
diff --git a/hw/kdrive/pcmcia/pcmciashadow.c b/hw/kdrive/pcmcia/pcmciashadow.c
new file mode 100644
index 000000000..a64e54fd7
--- /dev/null
+++ b/hw/kdrive/pcmcia/pcmciashadow.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, 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$ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+void
+tridentUpdatePacked (ScreenPtr pScreen,
+ PixmapPtr pShadow,
+ RegionPtr damage)
+{
+ shadowScrPriv(pScreen);
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase, *win;
+ CARD32 winSize;
+
+ fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp);
+ while (nbox--)
+ {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--)
+ {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (FbBits *) (*pScrPriv->window) (pScreen,
+ y,
+ scr * sizeof (FbBits),
+ SHADOW_WINDOW_WRITE,
+ &winSize);
+ if(!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof (FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+ {
+ CARD16 *sha16 = (CARD16*)sha;
+ CARD16 *win16 = (CARD16*)win;
+ while (i--)
+ {
+ *win16++ = *sha16++;
+ *win16++ = *sha16++;
+ }
+ }
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
+
+void
+cirrusUpdatePacked (ScreenPtr pScreen,
+ PixmapPtr pShadow,
+ RegionPtr damage)
+{
+ shadowScrPriv(pScreen);
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase, *win;
+ CARD32 winSize;
+
+ fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp);
+ while (nbox--)
+ {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--)
+ {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (FbBits *) (*pScrPriv->window) (pScreen,
+ y,
+ scr * sizeof (FbBits),
+ SHADOW_WINDOW_WRITE,
+ &winSize);
+ if(!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof (FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+ {
+ CARD8 *sha8 = (CARD8*)sha;
+ CARD8 *win8 = (CARD8*)win;
+ while (i--)
+ {
+ *win8++ = *sha8++;
+ *win8++ = *sha8++;
+ *win8++ = *sha8++;
+ *win8++ = *sha8++;
+ }
+ }
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
diff --git a/hw/kdrive/pcmcia/pcmciastub.c b/hw/kdrive/pcmcia/pcmciastub.c
new file mode 100644
index 000000000..e30881633
--- /dev/null
+++ b/hw/kdrive/pcmcia/pcmciastub.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, 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$ */
+
+#include "pcmcia.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ KdCardInfoAdd (&pcmciaFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+extern pcmciaDisplayModeRec pcmciaDefaultModes[];
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 00a757674..2636b8c11 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.12 2001/01/23 06:25:05 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.13 2001/03/30 02:15:20 keithp Exp $ */
#include "kdrive.h"
#include "inputstr.h"
@@ -992,7 +992,7 @@ extern int nClients;
void
KdCheckSpecialKeys(xEvent *xE)
{
- KeySym sym;
+ KeySym sym = KEYCOL1(xE->u.u.detail);
if (!pKdKeyboard) return;
@@ -1001,7 +1001,25 @@ KdCheckSpecialKeys(xEvent *xE)
*/
if (xE->u.u.type == KeyRelease) return;
-
+
+#ifdef XIPAQ
+ /*
+ * Check for buttons 1, 2 and 3 on the iPAQ
+ */
+ if (sym == XK_Pointer_Button1) {
+ KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_1, 0, 0);
+ return;
+ }
+ if (sym == XK_Pointer_Button2) {
+ KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_2, 0, 0);
+ return;
+ }
+ if (sym == XK_Pointer_Button3) {
+ KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_3, 0, 0);
+ return;
+ }
+#endif
+
/*
* Check for control/alt pressed
*/
@@ -1009,7 +1027,6 @@ KdCheckSpecialKeys(xEvent *xE)
(ControlMask|Mod1Mask))
return;
- sym = KEYCOL1(xE->u.u.detail);
/*
* Let OS function see keysym first
@@ -1428,16 +1445,22 @@ KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
static void
KdCrossScreen(ScreenPtr pScreen, Bool entering)
{
+#ifndef XIPAQ
if (entering)
KdEnableScreen (pScreen);
else
KdDisableScreen (pScreen);
+#endif
}
+/* HACK! */
+extern int TsScreen;
+
static void
KdWarpCursor (ScreenPtr pScreen, int x, int y)
{
KdBlockSigio ();
+ TsScreen = pScreen->myNum;
miPointerWarpCursor (pScreen, x, y);
KdUnblockSigio ();
}
diff --git a/hw/kdrive/src/kmap.c b/hw/kdrive/src/kmap.c
index 7238eaa2a..bf3991370 100644
--- a/hw/kdrive/src/kmap.c
+++ b/hw/kdrive/src/kmap.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kmap.c,v 1.6 2000/12/13 18:06:54 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kmap.c,v 1.7 2001/03/30 02:15:20 keithp Exp $ */
#include "kdrive.h"
@@ -67,7 +67,11 @@ KdMapDevice (CARD32 addr, CARD32 size)
void *a;
int fd;
+#ifdef __arm__
+ fd = open ("/dev/mem", O_RDWR|O_SYNC);
+#else
fd = open ("/dev/mem", O_RDWR);
+#endif
if (fd < 0)
FatalError ("KdMapDevice: failed to open /dev/mem (%s)\n",
strerror (errno));