xserver/hw/xorg/ramdac BT.c, NONE, 1.1 BT.h, NONE, 1.1 BTPriv.h, NONE, 1.1 IBM.c, NONE, 1.1 IBM.h, NONE, 1.1 IBMPriv.h, NONE, 1.1 Makefile.am, NONE, 1.1 TI.c, NONE, 1.1 TI.h, NONE, 1.1 TIPriv.h, NONE, 1.1 xf86Cursor.c, NONE, 1.1 xf86Cursor.h, NONE, 1.1 xf86CursorPriv.h, NONE, 1.1 xf86HWCurs.c, NONE, 1.1 xf86RamDac.c, NONE, 1.1 xf86RamDac.h, NONE, 1.1 xf86RamDacCmap.c, NONE, 1.1 xf86RamDacMod.c, NONE, 1.1 xf86RamDacPriv.h, NONE, 1.1

Daniel Stone xserver-commit at pdx.freedesktop.org
Sun Apr 25 23:52:25 EST 2004


Committed by: daniel

Update of /cvs/xserver/xserver/hw/xorg/ramdac
In directory pdx:/tmp/cvs-serv17025/hw/xorg/ramdac

Added Files:
	BT.c BT.h BTPriv.h IBM.c IBM.h IBMPriv.h Makefile.am TI.c TI.h 
	TIPriv.h xf86Cursor.c xf86Cursor.h xf86CursorPriv.h 
	xf86HWCurs.c xf86RamDac.c xf86RamDac.h xf86RamDacCmap.c 
	xf86RamDacMod.c xf86RamDacPriv.h 
Log Message:
Xizzle is dead, long live Xorg.

Re-import the DDX from X11R6.7, complete with automakey goodness, and do the
requisite configure.ac, et al, updates; also import the XKB extension from the
6.7 DIX.

Currently it'll link and then hang solid in RADEONInitAccel(), or the next
function if you enable NoAccel.


--- NEW FILE: BT.c ---
/*
 * 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 at fairlite.demon.co.uk>
 *
 * BT RAMDAC routines.
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/BT.c,v 1.7 2000/10/20 12:57:27 alanh Exp $ */

#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"

#define INIT_BT_RAMDAC_INFO
#include "BTPriv.h"
#include "xf86RamDacPriv.h"

void
BTramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
				    RamDacRegRecPtr ramdacReg)
{
	int i;

	/* Here we pass a short, so that we can evaluate a mask too */
	/* So that the mask is the high byte and the data the low byte */
	/* Just the command/status registers */
	for (i=0x06;i<0x0A;i++) 
	    (*ramdacPtr->WriteDAC)
	        (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8, 
						ramdacReg->DacRegs[i]);
}

void
BTramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 
				 RamDacRegRecPtr ramdacReg)
{
	int i;
	
	(*ramdacPtr->ReadAddress)(pScrn, 0); /* Start at index 0 */
	for (i=0;i<768;i++)
	    ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);

	/* Just the command/status registers */
	for (i=0x06;i<0x0A;i++)
	    ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC)(pScrn, i);
}

RamDacHelperRecPtr
BTramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs/*, RamDacRecPtr ramdacPtr*/)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
    Bool RamDacIsSupported = FALSE;
    RamDacHelperRecPtr ramdacHelperPtr = NULL;
    int BTramdac_ID = -1;
    int i, status, cmd0;

    /* Save COMMAND Register 0 */
    cmd0 = (*ramdacPtr->ReadDAC)(pScrn, BT_COMMAND_REG_0);
    /* Ensure were going to access the STATUS Register on next read */
    (*ramdacPtr->WriteDAC)(pScrn, BT_COMMAND_REG_0, 0x7F, 0x00);

    status = (*ramdacPtr->ReadDAC)(pScrn, BT_STATUS_REG);
    switch (status) {
	case 0x40:
		BTramdac_ID = ATT20C504_RAMDAC;
		break;
	case 0xD0:
		BTramdac_ID = ATT20C505_RAMDAC;
		break;
	default:
		xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
			   "Unknown BT RAMDAC type (0x%x), assuming BT485\n",
			   status);
	case 0x80:
	case 0x90:
	case 0xA0:
	case 0xB0:
	case 0x28: 	/* This is for the DEC TGA - Questionable ? */
		BTramdac_ID = BT485_RAMDAC;
		break;
    }

    /* Restore COMMAND Register 0 */
    (*ramdacPtr->WriteDAC)(pScrn, BT_COMMAND_REG_0, 0x00, cmd0);

    if (BTramdac_ID == -1) {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"Cannot determine BT RAMDAC type, aborting\n");
	return NULL;
    } else {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"Attached RAMDAC is %s\n", BTramdacDeviceInfo[BTramdac_ID&0xFFFF].DeviceName);
    }

    for (i=0;ramdacs[i].token != -1;i++) {
	if (ramdacs[i].token == BTramdac_ID)
	    RamDacIsSupported = TRUE;
    }

    if (!RamDacIsSupported) {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"This BT RAMDAC is NOT supported by this driver, aborting\n");
	return NULL;
    }

    ramdacHelperPtr = RamDacHelperCreateInfoRec();
    switch(BTramdac_ID) {
	case BT485_RAMDAC:
	    ramdacHelperPtr->SetBpp = BTramdacSetBpp;
	    break;
    }
    ramdacPtr->RamDacType = BTramdac_ID;
    ramdacHelperPtr->RamDacType = BTramdac_ID;
    ramdacHelperPtr->Save = BTramdacSave;
    ramdacHelperPtr->Restore = BTramdacRestore;
	
    return ramdacHelperPtr;
}

void
BTramdacSetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
{
    /* We need to deal with Direct Colour visuals for 8bpp and other
     * good stuff for colours */
    switch (pScrn->bitsPerPixel) {
	case 32:
	    ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x10;
	    break;
	case 24:
	    ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x10;
	    break;
	case 16:
	    ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x38;
	    break;
	case 15:
	    ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x30;
	    break;
	case 8:
	    ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x40;
	    break;
	case 4:
	    ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x60;
	    break;
    }
}

--- NEW FILE: BT.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/BT.h,v 1.2 1998/07/25 16:57:17 dawes Exp $ */

#include "xf86RamDac.h"

RamDacHelperRecPtr BTramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs);
void BTramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
void BTramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
void BTramdacSetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);

#define ATT20C504_RAMDAC 	(VENDOR_BT << 16) | 0x00
#define ATT20C505_RAMDAC 	(VENDOR_BT << 16) | 0x01
#define BT485_RAMDAC		(VENDOR_BT << 16) | 0x02

/*
 * BT registers
 */

#define BT_WRITE_ADDR		0x00
#define BT_RAMDAC_DATA		0x01	
#define BT_PIXEL_MASK		0x02
#define BT_READ_ADDR		0x03
#define BT_CURS_WR_ADDR		0x04
#define BT_CURS_DATA		0x05
#define BT_COMMAND_REG_0	0x06
#define BT_CURS_RD_ADDR		0x07
#define BT_COMMAND_REG_1	0x08
#define BT_COMMAND_REG_2	0x09
#define BT_STATUS_REG		0x0A
#define BT_CURS_RAM_DATA	0x0B
#define BT_CURS_X_LOW		0x0C
#define BT_CURS_X_HIGH		0x0D
#define BT_CURS_Y_LOW		0x0E
#define BT_CURS_Y_HIGH		0x0F

--- NEW FILE: BTPriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/BTPriv.h,v 1.1.2.1 1998/07/18 17:54:00 dawes Exp $ */

#include "BT.h"

typedef struct {
	char *DeviceName;
} xf86BTramdacInfo;

extern xf86BTramdacInfo BTramdacDeviceInfo[];

#ifdef INIT_BT_RAMDAC_INFO
xf86BTramdacInfo BTramdacDeviceInfo[] = {
	{"AT&T 20C504"},
	{"AT&T 20C505"},
	{"BT485/484"}
};
#endif

--- NEW FILE: IBM.c ---
/*
 * 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 at fairlite.demon.co.uk>
 *
 * IBM RAMDAC routines.
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/IBM.c,v 1.12 2003/02/17 16:08:29 dawes Exp $ */

#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"

#include "xf86Cursor.h"

#define INIT_IBM_RAMDAC_INFO
#include "IBMPriv.h"
#include "xf86RamDacPriv.h"

#define INITIALFREQERR 100000

unsigned long
IBMramdac640CalculateMNPCForClock(
    unsigned long RefClock,	/* In 100Hz units */
    unsigned long ReqClock,	/* In 100Hz units */
    char IsPixClock,	/* boolean, is this the pixel or the sys clock */
    unsigned long MinClock,	/* Min VCO rating */
    unsigned long MaxClock,	/* Max VCO rating */
    unsigned long *rM,	/* M Out */
    unsigned long *rN,	/* N Out */
    unsigned long *rP,	/* Min P In, P Out */
    unsigned long *rC	/* C Out */
)
{
  unsigned long   M, N, P, iP = *rP;
  unsigned long   IntRef, VCO, Clock;
  long            freqErr, lowestFreqErr = INITIALFREQERR;
  unsigned long   ActualClock = 0;

  for (N = 0; N <= 63; N++)
    {
      IntRef = RefClock / (N + 1);
      if (IntRef < 10000)
	break;			/* IntRef needs to be >= 1MHz */
      for (M = 2; M <= 127; M++)
	{
	  VCO = IntRef * (M + 1);
	  if ((VCO < MinClock) || (VCO > MaxClock))
	    continue;
	  for (P = iP; P <= 4; P++)
	    {
	      if (P != 0)
		Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P);
	      else
		Clock = (RefClock * (M + 1)) / (N + 1);

	      freqErr = (Clock - ReqClock);

	      if (freqErr < 0)
		{
		  /* PixelClock gets rounded up always so monitor reports
		     correct frequency. */
		  if (IsPixClock)
		    continue;
		  freqErr = -freqErr;
		}

	      if (freqErr < lowestFreqErr)
		{
		  *rM = M;
		  *rN = N;
		  *rP = P;
		  *rC = (VCO <= 1280000 ? 1 : 2);
		  ActualClock = Clock;

		  lowestFreqErr = freqErr;
		  /* Return if we found an exact match */
		  if (freqErr == 0)
		    return (ActualClock);
		}
	    }
	}
    }

  return (ActualClock);
}

unsigned long
IBMramdac526CalculateMNPCForClock(
    unsigned long RefClock,	/* In 100Hz units */
    unsigned long ReqClock,	/* In 100Hz units */
    char IsPixClock,	/* boolean, is this the pixel or the sys clock */
    unsigned long MinClock,	/* Min VCO rating */
    unsigned long MaxClock,	/* Max VCO rating */
    unsigned long *rM,	/* M Out */
    unsigned long *rN,	/* N Out */
    unsigned long *rP,	/* Min P In, P Out */
    unsigned long *rC	/* C Out */
)
{
  unsigned long   M, N, P, iP = *rP;
  unsigned long   IntRef, VCO, Clock;
  long            freqErr, lowestFreqErr = INITIALFREQERR;
  unsigned long   ActualClock = 0;

  for (N = 0; N <= 63; N++)
    {
      IntRef = RefClock / (N + 1);
      if (IntRef < 10000)
	break;			/* IntRef needs to be >= 1MHz */
      for (M = 0; M <= 63; M++)
	{
	  VCO = IntRef * (M + 1);
	  if ((VCO < MinClock) || (VCO > MaxClock))
	    continue;
	  for (P = iP; P <= 4; P++)
	    {
	      if (P)
		Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P);
	      else
		Clock = VCO;

	      freqErr = (Clock - ReqClock);

	      if (freqErr < 0)
		{
		  /* PixelClock gets rounded up always so monitor reports
		     correct frequency. */
		  if (IsPixClock)
		    continue;
		  freqErr = -freqErr;
		}

	      if (freqErr < lowestFreqErr)
		{
		  *rM = M;
		  *rN = N;
		  *rP = P;
		  *rC = (VCO <= 1280000 ? 1 : 2);
		  ActualClock = Clock;

		  lowestFreqErr = freqErr;
		  /* Return if we found an exact match */
		  if (freqErr == 0)
		    return (ActualClock);
		}
	    }
	}
    }

  return (ActualClock);
}

void
IBMramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
				    RamDacRegRecPtr ramdacReg)
{
	int i, maxreg, dacreg;

	switch (ramdacPtr->RamDacType) {
	    case IBM640_RAMDAC:
		maxreg = 0x300;
		dacreg = 1024;
		break;
	    default:
		maxreg = 0x100;
		dacreg = 768;
		break;
	}

	/* Here we pass a short, so that we can evaluate a mask too */
	/* So that the mask is the high byte and the data the low byte */
	for (i=0;i<maxreg;i++) 
	    (*ramdacPtr->WriteDAC)
	        (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8, 
						ramdacReg->DacRegs[i]);

	(*ramdacPtr->WriteAddress)(pScrn, 0);
	for (i=0;i<dacreg;i++)
	    	(*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]);
}

void
IBMramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 
				 RamDacRegRecPtr ramdacReg)
{
	int i, maxreg, dacreg;

	switch (ramdacPtr->RamDacType) {
	    case IBM640_RAMDAC:
		maxreg = 0x300;
		dacreg = 1024;
		break;
	    default:
		maxreg = 0x100;
		dacreg = 768;
		break;
	}
	
	(*ramdacPtr->ReadAddress)(pScrn, 0);
	for (i=0;i<dacreg;i++)
	    ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);

	for (i=0;i<maxreg;i++) 
	    ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC)(pScrn, i);
}

RamDacHelperRecPtr
IBMramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs/* , RamDacRecPtr ramdacPtr*/)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
    RamDacHelperRecPtr ramdacHelperPtr = NULL;
    Bool RamDacIsSupported = FALSE;
    int IBMramdac_ID = -1;
    int i;
    unsigned char id, rev, id2, rev2;

    /* read ID and revision */
    rev = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev);
    id = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id);

    /* check if ID and revision are read only */
    (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, IBMRGB_rev);
    (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, IBMRGB_id);
    rev2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev);
    id2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id);

    switch (id) {
	case 0x30:
		if (rev == 0xc0) IBMramdac_ID = IBM624_RAMDAC;
		if (rev == 0x80) IBMramdac_ID = IBM624DB_RAMDAC;
		break;
	case 0x12:
		if (rev == 0x1c) IBMramdac_ID = IBM640_RAMDAC;
		break;
	case 0x01:
		IBMramdac_ID = IBM525_RAMDAC;
		break;
	case 0x02:
		if (rev == 0xf0) IBMramdac_ID = IBM524_RAMDAC;
		if (rev == 0xe0) IBMramdac_ID = IBM524A_RAMDAC;
		if (rev == 0xc0) IBMramdac_ID = IBM526_RAMDAC;
		if (rev == 0x80) IBMramdac_ID = IBM526DB_RAMDAC;
		break;
    }

    if (id == 1 || id == 2) {
        if (id == id2 && rev == rev2) {		/* IBM RGB52x found */
	    /* check for 128bit VRAM -> RGB528 */
	    if (((*ramdacPtr->ReadDAC)(pScrn, IBMRGB_misc1) & 0x03) == 0x03) {
	        IBMramdac_ID = IBM528_RAMDAC;	/* 128bit DAC found */
	        if (rev == 0xe0)
		    IBMramdac_ID = IBM528A_RAMDAC;
	    }
        }
    }

    (*ramdacPtr->WriteDAC)(pScrn, rev, 0, IBMRGB_rev);
    (*ramdacPtr->WriteDAC)(pScrn, id, 0, IBMRGB_id);

    if (IBMramdac_ID == -1) {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"Cannot determine IBM RAMDAC type, aborting\n");
	return NULL;
    } else {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"Attached RAMDAC is %s\n", IBMramdacDeviceInfo[IBMramdac_ID&0xFFFF].DeviceName);
    }

    for (i=0;ramdacs[i].token != -1;i++) {
	if (ramdacs[i].token == IBMramdac_ID)
	    RamDacIsSupported = TRUE;
    }

    if (!RamDacIsSupported) {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"This IBM RAMDAC is NOT supported by this driver, aborting\n");
	return NULL;
    }

    ramdacHelperPtr = RamDacHelperCreateInfoRec();
    switch (IBMramdac_ID) {
	case IBM526_RAMDAC:
	case IBM526DB_RAMDAC:
 	    ramdacHelperPtr->SetBpp = IBMramdac526SetBpp;
    	    ramdacHelperPtr->HWCursorInit = IBMramdac526HWCursorInit;
	    break;
	case IBM640_RAMDAC:
 	    ramdacHelperPtr->SetBpp = IBMramdac640SetBpp;
    	    ramdacHelperPtr->HWCursorInit = IBMramdac640HWCursorInit;
	    break;
    }
    ramdacPtr->RamDacType = IBMramdac_ID;
    ramdacHelperPtr->RamDacType = IBMramdac_ID;
    ramdacHelperPtr->Save = IBMramdacSave;
    ramdacHelperPtr->Restore = IBMramdacRestore;

    return ramdacHelperPtr;
}

void
IBMramdac526SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
{
    ramdacReg->DacRegs[IBMRGB_key_control] = 0x00; /* Disable Chroma Key */

    switch (pScrn->bitsPerPixel) {
	case 32:
	    ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_32BPP;
	    ramdacReg->DacRegs[IBMRGB_32bpp] = B32_DCOL_DIRECT;
	    ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
	    if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
		ramdacReg->DacRegs[IBMRGB_key_control] = 0x01; /* Enable Key */
		ramdacReg->DacRegs[IBMRGB_key] = 0xFF; 
		ramdacReg->DacRegs[IBMRGB_key_mask] = 0xFF;
	    }
	    break;
	case 24:
	    ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_24BPP;
	    ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_24bpp] = B24_DCOL_DIRECT;
	    ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
	    break;
	case 16:
	    if (pScrn->depth == 16) {
	        ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP;
	        ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
	        ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
	        ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR |
					           B16_CONTIGUOUS | B16_565;
	        ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
	    } else {
	        ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP;
	        ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
	        ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
	        ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR |
					           B16_CONTIGUOUS | B16_555;
	        ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
	    }
	    break;
	case 8:
	    ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_8BPP;
	    ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_8bpp] = B8_DCOL_INDIRECT;
	    break;
	case 4:
	    ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_4BPP;
	    ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
	    ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
    }
}

void
IBMramdac640SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
{
    unsigned char bpp = 0x00;
    unsigned char overlaybpp = 0x00;
    unsigned char offset = 0x00;
    unsigned char dispcont = 0x44;

    ramdacReg->DacRegs[RGB640_SER_WID_03_00] = 0x00;
    ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x00;
    ramdacReg->DacRegs[RGB640_DIAGS] = 0x07;

    switch (pScrn->depth) {
	case 8:
	    ramdacReg->DacRegs[RGB640_SER_07_00] = 0x00; 
	    ramdacReg->DacRegs[RGB640_SER_15_08] = 0x00;
	    ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
	    ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
    	    ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_16_1; /*16:1 Mux*/
    	    ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
	    bpp = 0x03;
	    break;
	case 15:
	    ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10;
	    ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11;
	    ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
	    ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
    	    ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux*/
    	    ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
	    bpp = 0x0E;
	    break;
	case 16:
	    ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10;
	    ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11;
	    ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
	    ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
    	    ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux*/
    	    ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
	    bpp = 0x05;
	    break;
	case 24:
	    ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30; 
	    ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31;
	    ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32;
	    ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33;
    	    ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/
    	    ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
	    bpp = 0x09;
	    if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
		ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x04;
		ramdacReg->DacRegs[RGB640_CHROMA_KEY0] = 0xFF;
		ramdacReg->DacRegs[RGB640_CHROMA_MASK0] = 0xFF;
		offset = 0x04;
		overlaybpp = 0x04;
		dispcont = 0x48;
	    }
	    break;
	case 30: /* 10 bit dac */
	    ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30; 
	    ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31;
	    ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32;
	    ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33;
    	    ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/
    	    ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PSIZE10 | 
						   IBM640_PCLK_8; /* pll / 8 */
	    bpp = 0x0D;
	    break;
    }
	
    { 
	int i;
    	for (i=0x100;i<0x140;i+=4) {
	    /* Initialize FrameBuffer Window Attribute Table */
	    ramdacReg->DacRegs[i+0] = bpp;
	    ramdacReg->DacRegs[i+1] = offset;
	    ramdacReg->DacRegs[i+2] = 0x00;
	    ramdacReg->DacRegs[i+3] = 0x00;
	    /* Initialize Overlay Window Attribute Table */
	    ramdacReg->DacRegs[i+0x100] = overlaybpp;
	    ramdacReg->DacRegs[i+0x101] = 0x00;
	    ramdacReg->DacRegs[i+0x102] = 0x00;
	    ramdacReg->DacRegs[i+0x103] = dispcont;
        }
    }
}

static void 
IBMramdac526ShowCursor(ScrnInfoPtr pScrn)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

   /* Enable cursor - X11 mode */
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x07);
}

static void 
IBMramdac640ShowCursor(ScrnInfoPtr pScrn)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

   /* Enable cursor - mode2 (x11 mode) */
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x0B);
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CROSSHAIR_CONTROL, 0x00, 0x00);
}

static void
IBMramdac526HideCursor(ScrnInfoPtr pScrn)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

   /* Disable cursor - X11 mode */
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x24);
}

static void
IBMramdac640HideCursor(ScrnInfoPtr pScrn)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

   /* Disable cursor - mode2 (x11 mode) */
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x08);
}

static void
IBMramdac526SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

   x += 64;
   y += 64;

   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_x, 0x00, 0x3f);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_y, 0x00, 0x3f);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xl, 0x00, x & 0xff);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xh, 0x00, (x>>8) & 0xf);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yl, 0x00, y & 0xff);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yh, 0x00, (y>>8) & 0xf);
}

static void
IBMramdac640SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

   x += 64;
   y += 64;

   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETX, 0x00, 0x3f);
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETY, 0x00, 0x3f);
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_LOW, 0x00, x & 0xff);
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_HIGH, 0x00, (x>>8) & 0xf);
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_LOW, 0x00, y & 0xff);
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_HIGH, 0x00, (y>>8) & 0xf);
}

static void
IBMramdac526SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_r, 0x00, bg >> 16);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_g, 0x00, bg >> 8);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_b, 0x00, bg);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_r, 0x00, fg >> 16);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_g, 0x00, fg >> 8);
   (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_b, 0x00, fg);
}

static void
IBMramdac640SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
  
   (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_COL0, 0x00, 0);
   (*ramdacPtr->WriteData)(pScrn, fg>>16);
   (*ramdacPtr->WriteData)(pScrn, fg>>8);
   (*ramdacPtr->WriteData)(pScrn, fg);
   (*ramdacPtr->WriteData)(pScrn, bg>>16);
   (*ramdacPtr->WriteData)(pScrn, bg>>8);
   (*ramdacPtr->WriteData)(pScrn, bg);
   (*ramdacPtr->WriteData)(pScrn, fg>>16);
   (*ramdacPtr->WriteData)(pScrn, fg>>8);
   (*ramdacPtr->WriteData)(pScrn, fg);
   (*ramdacPtr->WriteData)(pScrn, bg>>16);
   (*ramdacPtr->WriteData)(pScrn, bg>>8);
   (*ramdacPtr->WriteData)(pScrn, bg);
}

static void 
IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
   int i;
   /* 
    * Output the cursor data.  The realize function has put the planes into
    * their correct order, so we can just blast this out.
    */
   for (i = 0; i < 1024; i++)
      (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_array + i, 0x00, (*src++));
}

static void 
IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
   RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
   int i;
   /* 
    * Output the cursor data.  The realize function has put the planes into
    * their correct order, so we can just blast this out.
    */
   for (i = 0; i < 1024; i++)
      (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_WRITE + i, 0x00, (*src++));
}

static Bool 
IBMramdac526UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
{
    return TRUE;
}

static Bool 
IBMramdac640UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
{
    return TRUE;
}

void
IBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr)
{
    infoPtr->MaxWidth = 64;
    infoPtr->MaxHeight = 64;
    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
		     HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
		     HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
    infoPtr->SetCursorColors = IBMramdac526SetCursorColors;
    infoPtr->SetCursorPosition = IBMramdac526SetCursorPosition;
    infoPtr->LoadCursorImage = IBMramdac526LoadCursorImage;
    infoPtr->HideCursor = IBMramdac526HideCursor;
    infoPtr->ShowCursor = IBMramdac526ShowCursor;
    infoPtr->UseHWCursor = IBMramdac526UseHWCursor;
}

void
IBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr)
{
    infoPtr->MaxWidth = 64;
    infoPtr->MaxHeight = 64;
    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
		     HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
		     HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
    infoPtr->SetCursorColors = IBMramdac640SetCursorColors;
    infoPtr->SetCursorPosition = IBMramdac640SetCursorPosition;
    infoPtr->LoadCursorImage = IBMramdac640LoadCursorImage;
    infoPtr->HideCursor = IBMramdac640HideCursor;
    infoPtr->ShowCursor = IBMramdac640ShowCursor;
    infoPtr->UseHWCursor = IBMramdac640UseHWCursor;
}

--- NEW FILE: IBM.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/IBM.h,v 1.7 1999/02/12 22:52:11 hohndel Exp $ */

#include <xf86RamDac.h>

RamDacHelperRecPtr IBMramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs);
void IBMramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
void IBMramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
void IBMramdac526SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
void IBMramdac640SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
unsigned long IBMramdac526CalculateMNPCForClock(unsigned long RefClock,
    unsigned long ReqClock, char IsPixClock, unsigned long MinClock,
    unsigned long MaxClock, unsigned long *rM, unsigned long *rN,
    unsigned long *rP, unsigned long *rC);
unsigned long IBMramdac640CalculateMNPCForClock(unsigned long RefClock,
    unsigned long ReqClock, char IsPixClock, unsigned long MinClock,
    unsigned long MaxClock, unsigned long *rM, unsigned long *rN,
    unsigned long *rP, unsigned long *rC);
void IBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr);
void IBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr);

#define IBM524_RAMDAC		((VENDOR_IBM << 16) | 0x00)
#define IBM524A_RAMDAC		((VENDOR_IBM << 16) | 0x01)
#define IBM525_RAMDAC		((VENDOR_IBM << 16) | 0x02)
#define IBM526_RAMDAC		((VENDOR_IBM << 16) | 0x03)
#define IBM526DB_RAMDAC		((VENDOR_IBM << 16) | 0x04)
#define IBM528_RAMDAC		((VENDOR_IBM << 16) | 0x05)
#define IBM528A_RAMDAC		((VENDOR_IBM << 16) | 0x06)
#define IBM624_RAMDAC		((VENDOR_IBM << 16) | 0x07)
#define IBM624DB_RAMDAC		((VENDOR_IBM << 16) | 0x08)
#define IBM640_RAMDAC		((VENDOR_IBM << 16) | 0x09)

/*
 * IBM Ramdac registers
 */

#define IBMRGB_REF_FREQ_1       14.31818
#define IBMRGB_REF_FREQ_2       50.00000

#define IBMRGB_rev		0x00
#define IBMRGB_id		0x01
#define IBMRGB_misc_clock	0x02
#define IBMRGB_sync		0x03
#define IBMRGB_hsync_pos	0x04
#define IBMRGB_pwr_mgmt		0x05
#define IBMRGB_dac_op		0x06
#define IBMRGB_pal_ctrl		0x07
#define IBMRGB_sysclk		0x08  /* not RGB525 */
#define IBMRGB_pix_fmt		0x0a
#define IBMRGB_8bpp		0x0b
#define IBMRGB_16bpp		0x0c
#define IBMRGB_24bpp		0x0d
#define IBMRGB_32bpp		0x0e
#define IBMRGB_pll_ctrl1	0x10
#define IBMRGB_pll_ctrl2	0x11
#define IBMRGB_pll_ref_div_fix	0x14
#define IBMRGB_sysclk_ref_div	0x15  /* not RGB525 */
#define IBMRGB_sysclk_vco_div	0x16  /* not RGB525 */
/* #define IBMRGB_f0		0x20 */

#define IBMRGB_sysclk_n		0x15
#define IBMRGB_sysclk_m		0x16
#define IBMRGB_sysclk_p		0x17
#define IBMRGB_sysclk_c		0x18

#define IBMRGB_m0		0x20
#define IBMRGB_n0		0x21
#define IBMRGB_p0		0x22
#define IBMRGB_c0		0x23
#define IBMRGB_m1		0x24
#define IBMRGB_n1		0x25
#define IBMRGB_p1		0x26
#define IBMRGB_c1		0x27
#define IBMRGB_m2		0x28
#define IBMRGB_n2		0x29
#define IBMRGB_p2		0x2a
#define IBMRGB_c2		0x2b
#define IBMRGB_m3		0x2c
#define IBMRGB_n3		0x2d
#define IBMRGB_p3		0x2e
#define IBMRGB_c3		0x2f

#define IBMRGB_curs		0x30
#define IBMRGB_curs_xl		0x31
#define IBMRGB_curs_xh		0x32
#define IBMRGB_curs_yl		0x33
#define IBMRGB_curs_yh		0x34
#define IBMRGB_curs_hot_x	0x35
#define IBMRGB_curs_hot_y	0x36
#define IBMRGB_curs_col1_r	0x40
#define IBMRGB_curs_col1_g	0x41
#define IBMRGB_curs_col1_b	0x42
#define IBMRGB_curs_col2_r	0x43
#define IBMRGB_curs_col2_g	0x44
#define IBMRGB_curs_col2_b	0x45
#define IBMRGB_curs_col3_r	0x46
#define IBMRGB_curs_col3_g	0x47
#define IBMRGB_curs_col3_b	0x48
#define IBMRGB_border_col_r	0x60
#define IBMRGB_border_col_g	0x61
#define IBMRGB_botder_col_b	0x62
#define IBMRGB_key		0x68
#define IBMRGB_key_mask		0x6C
#define IBMRGB_misc1		0x70
#define IBMRGB_misc2		0x71
#define IBMRGB_misc3		0x72
#define IBMRGB_misc4		0x73  /* not RGB525 */
#define IBMRGB_key_control	0x78
#define IBMRGB_dac_sense	0x82
#define IBMRGB_misr_r		0x84
#define IBMRGB_misr_g		0x86
#define IBMRGB_misr_b		0x88
#define IBMRGB_pll_vco_div_in	0x8e
#define IBMRGB_pll_ref_div_in	0x8f
#define IBMRGB_vram_mask_0	0x90
#define IBMRGB_vram_mask_1	0x91
#define IBMRGB_vram_mask_2	0x92
#define IBMRGB_vram_mask_3	0x93
#define IBMRGB_curs_array	0x100



/* Constants rgb525.h */  

/* RGB525_REVISION_LEVEL */
#define RGB525_PRODUCT_REV_LEVEL        0xf0

/* RGB525_ID */
#define RGB525_PRODUCT_ID               0x01

/* RGB525_MISC_CTRL_1 */
#define MISR_CNTL_ENABLE                0x80
#define VMSK_CNTL_ENABLE                0x40
#define PADR_RDMT_RDADDR                0x0
#define PADR_RDMT_PAL_STATE             0x20
#define SENS_DSAB_DISABLE               0x10
#define SENS_SEL_BIT3                   0x0
#define SENS_SEL_BIT7                   0x08
#define VRAM_SIZE_32                    0x0
#define VRAM_SIZE_64                    0x01

/* RGB525_MISC_CTRL_2 */
#define PCLK_SEL_LCLK                   0x0
#define PCLK_SEL_PLL                    0x40
#define PCLK_SEL_EXT                    0x80
#define INTL_MODE_ENABLE                0x20
#define BLANK_CNTL_ENABLE               0x10
#define COL_RES_6BIT                    0x0
#define COL_RES_8BIT                    0x04
#define PORT_SEL_VGA                    0x0
#define PORT_SEL_VRAM                   0x01

/* RGB525_MISC_CTRL_3 */
#define SWAP_RB                         0x80
#define SWAP_WORD_LOHI                  0x0
#define SWAP_WORD_HILO                  0x10
#define SWAP_NIB_HILO                   0x0
#define SWAP_NIB_LOHI                   0x02

/* RGB525_MISC_CLK_CTRL */
#define DDOT_CLK_ENABLE                 0x0
#define DDOT_CLK_DISABLE                0x80
#define SCLK_ENABLE                     0x0
#define SCLK_DISABLE                    0x40
#define B24P_DDOT_PLL                   0x0
#define B24P_DDOT_SCLK                  0x20
#define DDOT_DIV_PLL_1                  0x0
#define DDOT_DIV_PLL_2                  0x02
#define DDOT_DIV_PLL_4                  0x04
#define DDOT_DIV_PLL_8                  0x06
#define DDOT_DIV_PLL_16                 0x08
#define PLL_DISABLE                     0x0
#define PLL_ENABLE                      0x01

/* RGB525_SYNC_CTRL */
#define DLY_CNTL_ADD                    0x0
#define DLY_SYNC_NOADD                  0x80
#define CSYN_INVT_DISABLE               0x0
#define CSYN_INVT_ENABLE                0x40
#define VSYN_INVT_DISABLE               0x0
#define VSYN_INVT_ENABLE                0x20
#define HSYN_INVT_DISABLE               0x0
#define HSYN_INVT_ENABLE                0x10
#define VSYN_CNTL_NORMAL                0x0
#define VSYN_CNTL_HIGH                  0x04
#define VSYN_CNTL_LOW                   0x08
#define VSYN_CNTL_DISABLE               0x0C
#define HSYN_CNTL_NORMAL                0x0
#define HSYN_CNTL_HIGH                  0x01
#define HSYN_CNTL_LOW                   0x02
#define HSYN_CNTL_DISABLE               0x03

/* RGB525_HSYNC_CTRL */
#define HSYN_POS(n)                     (n)

/* RGB525_POWER_MANAGEMENT */
#define SCLK_PWR_NORMAL                 0x0
#define SCLK_PWR_DISABLE                0x10
#define DDOT_PWR_NORMAL                 0x0
#define DDOT_PWR_DISABLE                0x08
#define SYNC_PWR_NORMAL                 0x0
#define SYNC_PWR_DISABLE                0x04
#define ICLK_PWR_NORMAL                 0x0
#define ICLK_PWR_DISABLE                0x02
#define DAC_PWR_NORMAL                  0x0
#define DAC_PWR_DISABLE                 0x01

/* RGB525_DAC_OPERATION */
#define SOG_DISABLE                     0x0
#define SOG_ENABLE                      0x08
#define BRB_NORMAL                      0x0
#define BRB_ALWAYS                      0x04
#define DSR_DAC_SLOW                    0x02
#define DSR_DAC_FAST                    0x0
#define DPE_DISABLE                     0x0
#define DPE_ENABLE                      0x01

/* RGB525_PALETTE_CTRL */
#define SIXBIT_LINEAR_ENABLE            0x0
#define SIXBIT_LINEAR_DISABLE           0x80
#define PALETTE_PARITION(n)             (n)

/* RGB525_PIXEL_FORMAT */
#define PIXEL_FORMAT_4BPP               0x02
#define PIXEL_FORMAT_8BPP               0x03
#define PIXEL_FORMAT_16BPP              0x04
#define PIXEL_FORMAT_24BPP              0x05
#define PIXEL_FORMAT_32BPP              0x06

/* RGB525_8BPP_CTRL */
#define B8_DCOL_INDIRECT                0x0
#define B8_DCOL_DIRECT                  0x01

/* RGB525_16BPP_CTRL */
#define B16_DCOL_INDIRECT               0x0
#define B16_DCOL_DYNAMIC                0x40
#define B16_DCOL_DIRECT                 0xC0
#define B16_POL_FORCE_BYPASS            0x0
#define B16_POL_FORCE_LOOKUP            0x20
#define B16_ZIB                         0x0
#define B16_LINEAR                      0x04
#define B16_555                         0x0
#define B16_565                         0x02
#define B16_SPARSE                      0x0
#define B16_CONTIGUOUS                  0x01

/* RGB525_24BPP_CTRL */
#define B24_DCOL_INDIRECT               0x0
#define B24_DCOL_DIRECT                 0x01

/* RGB525_32BPP_CTRL */
#define B32_POL_FORCE_BYPASS            0x0
#define B32_POL_FORCE_LOOKUP            0x04
#define B32_DCOL_INDIRECT               0x0
#define B32_DCOL_DYNAMIC                0x01
#define B32_DCOL_DIRECT                 0x03

/* RGB525_PLL_CTRL_1 */
#define REF_SRC_REFCLK                  0x0
#define REF_SRC_EXTCLK                  0x10
#define PLL_EXT_FS_3_0                  0x0
#define PLL_EXT_FS_2_0                  0x01
#define PLL_CNTL2_3_0                   0x02
#define PLL_CNTL2_2_0                   0x03

/* RGB525_PLL_CTRL_2 */
#define PLL_INT_FS_3_0(n)               (n)
#define PLL_INT_FS_2_0(n)               (n)

/* RGB525_PLL_REF_DIV_COUNT */
#define REF_DIV_COUNT(n)                (n)

/* RGB525_F0 - RGB525_F15 */
#define VCO_DIV_COUNT(n)                (n)

/* RGB525_PLL_REFCLK values */
#define RGB525_PLL_REFCLK_MHz(n)        ((n)/2)

/* RGB525_CURSOR_CONTROL */
#define SMLC_PART_0                     0x0
#define SMLC_PART_1                     0x40
#define SMLC_PART_2                     0x80
#define SMLC_PART_3                     0xC0
#define PIX_ORDER_RL                    0x0
#define PIX_ORDER_LR                    0x20
#define LOC_READ_LAST                   0x0
#define LOC_READ_ACTUAL                 0x10
#define UPDT_CNTL_DELAYED               0x0
#define UPDT_CNTL_IMMEDIATE             0x08
#define CURSOR_SIZE_32                  0x0
#define CURSOR_SIZE_64                  0x40
#define CURSOR_MODE_OFF                 0x0
#define CURSOR_MODE_3_COLOR             0x01
#define CURSOR_MODE_2_COLOR_HL          0x02
#define CURSOR_MODE_2_COLOR             0x03

/* RGB525_REVISION_LEVEL */
#define REVISION_LEVEL                  0xF0    /* predefined */

/* RGB525_ID */
#define ID_CODE                         0x01    /* predefined */

/* MISR status */
#define RGB525_MISR_DONE                0x01

/* the IBMRGB640 is rather different from the rest of the RAMDACs,
   so we define a completely new set of register names for it */
#define RGB640_SER_07_00		0x02
#define RGB640_SER_15_08		0x03
#define RGB640_SER_23_16		0x04
#define RGB640_SER_31_24		0x05
#define RGB640_SER_WID_03_00		0x06
#define RGB640_SER_WID_07_04		0x07
#define RGB640_SER_MODE			0x08
#define		IBM640_SER_2_1	0x00
#define		IBM640_SER_4_1	0x01
#define		IBM640_SER_8_1	0x02
#define		IBM640_SER_16_1	0x03
#define		IBM640_SER_16_3	0x05
#define		IBM640_SER_5_1	0x06
#define RGB640_PIXEL_INTERLEAVE		0x09
#define RGB640_MISC_CONF		0x0a
#define		IBM640_PCLK		0x00
#define		IBM640_PCLK_2		0x40
#define		IBM640_PCLK_4		0x80
#define		IBM640_PCLK_8		0xc0
#define		IBM640_PSIZE10		0x10
#define		IBM640_LCI		0x08
#define		IBM640_WIDCTL_MASK	0x07
#define RGB640_VGA_CONTROL		0x0b
#define 	IBM640_RDBK	0x04
#define 	IBM640_PSIZE8	0x02
#define		IBM640_VRAM	0x01
#define RGB640_DAC_CONTROL		0x0d
#define		IBM640_MONO	0x08
#define		IBM640_DACENBL	0x04
#define		IBM640_SHUNT	0x02
#define		IBM640_SLOWSLEW	0x01
#define RGB640_OUTPUT_CONTROL		0x0e
#define		IBM640_RDAI	0x04
#define		IBM640_WDAI	0x02
#define		IBM640_WATCTL	0x01
#define RGB640_SYNC_CONTROL		0x0f
#define		IBM640_PWR	0x20
#define		IBM640_VSP	0x10
#define		IBM640_HSP	0x08
#define		IBM640_CSE	0x04
#define		IBM640_CSG	0x02
#define		IBM640_BPE	0x01
#define RGB640_PLL_N			0x10
#define RGB640_PLL_M			0x11
#define RGB640_PLL_P			0x12
#define RGB640_PLL_CTL			0x13
#define 	IBM640_PLL_EN	0x04
#define		IBM640_PLL_HIGH	0x10
#define		IBM640_PLL_LOW	0x01
#define RGB640_AUX_PLL_CTL		0x17
#define		IBM640_AUXPLL	0x04
#define		IBM640_AUX_HI	0x02
#define		IBM640_AUX_LO	0x01
#define RGB640_CHROMA_KEY0		0x20
#define RGB640_CHROMA_MASK0		0x21
#define RGB640_CURS_X_LOW		0x40
#define RGB640_CURS_X_HIGH		0x41
#define RGB640_CURS_Y_LOW		0x42
#define RGB640_CURS_Y_HIGH		0x43
#define RGB640_CURS_OFFSETX		0x44
#define RGB640_CURS_OFFSETY		0x45
#define RGB640_CURSOR_CONTROL		0x4B
#define		IBM640_CURS_OFF		0x00
#define		IBM640_CURS_MODE0	0x01
#define		IBM640_CURS_MODE1	0x02
#define		IBM640_CURS_MODE2	0x03
#define		IBM640_CURS_ADV		0x04
#define RGB640_CROSSHAIR_CONTROL	0x57
#define RGB640_VRAM_MASK0		0xf0
#define RGB640_VRAM_MASK1		0xf1
#define RGB640_VRAM_MASK2		0xf2
#define RGB640_DIAGS			0xfa
#define RGB640_CURS_WRITE		0x1000
#define RGB640_CURS_COL0		0x4800
#define RGB640_CURS_COL1		0x4801
#define RGB640_CURS_COL2		0x4802
#define RGB640_CURS_COL3		0x4803

--- NEW FILE: IBMPriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/IBMPriv.h,v 1.1.2.2 1998/07/18 17:54:01 dawes Exp $ */

#include "IBM.h"

typedef struct {
	char *DeviceName;
} xf86IBMramdacInfo;

extern xf86IBMramdacInfo IBMramdacDeviceInfo[];

#ifdef INIT_IBM_RAMDAC_INFO
xf86IBMramdacInfo IBMramdacDeviceInfo[] = {
	{"IBM 524"},
	{"IBM 524A"},
	{"IBM 525"},
	{"IBM 526"},
	{"IBM 526DB(DoubleBuffer)"},
	{"IBM 528"},
	{"IBM 528A"},
	{"IBM 624"},
	{"IBM 624DB(DoubleBuffer)"},
	{"IBM 640"}
};
#endif

--- NEW FILE: Makefile.am ---
INCLUDES = $(XORG_INCS)
AM_CFLAGS = $(XORG_CFLAGS) -DXAAReverseBitOrder=xf86ReverseBitOrder -DRAMDAC_MODULE

lib_LIBRARIES = libxorgramdac.a
libxorgramdac_a_SOURCES = xf86RamDacMod.c xf86RamDac.c xf86RamDacCmap.c \
                          xf86Cursor.c xf86HWCurs.c IBM.c BT.c TI.c \
			  $(srcdir)/../xaa/xaaBitOrder.c

sdk_INCLUDEDIR=$(includedir)/xorg
sdk_INCLUDES = BT.h IBM.h TI.h xf86Cursor.h xf86RamDac.h

--- NEW FILE: TI.c ---
/*
 * 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 at fairlite.demon.co.uk>
 *
 * Modified from IBM.c to support TI RAMDAC routines 
 *   by Jens Owen, <jens at tungstengraphics.com>.
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/TI.c,v 1.7 2003/02/17 16:08:29 dawes Exp $ */

#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"

#include "xf86Cursor.h"

#define INIT_TI_RAMDAC_INFO
#include "TIPriv.h"
#include "xf86RamDacPriv.h"

/* The following values are in kHz */
#define TI_MIN_VCO_FREQ  110000
#define TI_MAX_VCO_FREQ  220000

unsigned long
TIramdacCalculateMNPForClock(
    unsigned long RefClock,	/* In 100Hz units */
    unsigned long ReqClock,	/* In 100Hz units */
    char IsPixClock,	/* boolean, is this the pixel or the sys clock */
    unsigned long MinClock,	/* Min VCO rating */
    unsigned long MaxClock,	/* Max VCO rating */
    unsigned long *rM,	/* M Out */
    unsigned long *rN,	/* N Out */
    unsigned long *rP 	/* Min P In, P Out */
)
{
    unsigned long   n, p;
    unsigned long   best_m = 0, best_n = 0;
    double          VCO, IntRef = (double)RefClock;
    double          m_err, inc_m, calc_m;
    unsigned long   ActualClock;

    /* Make sure that MinClock <= ReqClock <= MaxClock */
    if ( ReqClock < MinClock)
	ReqClock = MinClock;
    if ( ReqClock > MaxClock )
	ReqClock = MaxClock;

    /*
     * ActualClock = VCO / 2 ^ p
     * Choose p so that TI_MIN_VCO_FREQ <= VCO <= TI_MAX_VCO_FREQ
     * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ
     * we don't have to bother checking for this maximum limit.
     */
    VCO = (double)ReqClock;
    for ( p = 0; p < 3 && VCO < TI_MIN_VCO_FREQ; ( p )++ )
	 VCO *= 2.0;

    /*
     * We avoid doing multiplications by ( 65 - n ),
     * and add an increment instead - this keeps any error small.
     */
    inc_m = VCO / ( IntRef * 8.0 );

    /* Initial value of calc_m for the loop */
    calc_m = inc_m + inc_m + inc_m;

    /* Initial amount of error for an integer - impossibly large */
    m_err = 2.0;

    /* Search for the closest INTEGER value of ( 65 - m ) */
    for ( n = 3; n <= 25; ( n )++, calc_m += inc_m ) {

	/* Ignore values of ( 65 - m ) which we can't use */
	if ( calc_m < 3.0 || calc_m > 64.0 )
	    continue;

	/*
	 * Pick the closest INTEGER (has smallest fractional part).
	 * The optimizer should clean this up for us.
	 */
	if (( calc_m - ( int ) calc_m ) < m_err ) {
	    m_err = calc_m - ( int ) calc_m;
	    best_m = ( int ) calc_m;
	    best_n = n;
	}
    }

    /* 65 - ( 65 - x ) = x */
    *rM = 65 - best_m;
    *rN = 65 - best_n;
    *rP = p;

    /* Now all the calculations can be completed */
    VCO = 8.0 * IntRef * best_m / best_n;
    ActualClock = VCO / ( 1 << p );

#ifdef DEBUG
    ErrorF( "f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
	    ActualClock, VCO, *rN, *rM, *rP);
#endif

    return (ActualClock);
}

void
TIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
				   RamDacRegRecPtr ramdacReg)
{
    int i;
    unsigned long status;

    /* Here we pass a short, so that we can evaluate a mask too
     * So that the mask is the high byte and the data the low byte
     * Order is important
     */
    TIRESTORE(TIDAC_latch_ctrl);
    TIRESTORE(TIDAC_true_color_ctrl);
    TIRESTORE(TIDAC_multiplex_ctrl);
    TIRESTORE(TIDAC_clock_select);
    TIRESTORE(TIDAC_palette_page);
    TIRESTORE(TIDAC_general_ctrl);
    TIRESTORE(TIDAC_misc_ctrl);
	    /* 0x2A & 0x2B are reserved */
    TIRESTORE(TIDAC_key_over_low);
    TIRESTORE(TIDAC_key_over_high);
    TIRESTORE(TIDAC_key_red_low);
    TIRESTORE(TIDAC_key_red_high);
    TIRESTORE(TIDAC_key_green_low);
    TIRESTORE(TIDAC_key_green_high);
    TIRESTORE(TIDAC_key_blue_low);
    TIRESTORE(TIDAC_key_blue_high);
    TIRESTORE(TIDAC_key_ctrl);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x30);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x38);
    TIRESTORE(TIDAC_clock_ctrl);
    TIRESTORE(TIDAC_sense_test);
    TIRESTORE(TIDAC_ind_curs_ctrl);

    /* only restore clocks if they were valid to begin with */

    if (ramdacReg->DacRegs[TIDAC_PIXEL_VALID]) {
    /* Reset pixel clock */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 0x3c);

    /* Restore N, M & P values for pixel clocks */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
					ramdacReg->DacRegs[TIDAC_PIXEL_N]);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
					ramdacReg->DacRegs[TIDAC_PIXEL_M]);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
					ramdacReg->DacRegs[TIDAC_PIXEL_P]);

    /* wait for pixel clock to lock */
    i = 1000000;
    do {
	status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
    } while ((!(status & 0x40)) && (--i));
    if (!(status & 0x40)) {
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
			"Pixel clock setup timed out\n");
	return;
    }
    }

    if (ramdacReg->DacRegs[TIDAC_LOOP_VALID]) {
    /* Reset loop clock */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 0x70);

    /* Restore N, M & P values for pixel clocks */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
					ramdacReg->DacRegs[TIDAC_LOOP_N]);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
					ramdacReg->DacRegs[TIDAC_LOOP_M]);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
					ramdacReg->DacRegs[TIDAC_LOOP_P]);

    /* wait for loop clock to lock */
    i = 1000000;
    do {
        status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
    } while ((!(status & 0x40)) && (--i));
    if (!(status & 0x40)) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
			"Loop clock setup timed out\n");
	    return;
    }
    }

    /* restore palette */
    (*ramdacPtr->WriteAddress)(pScrn, 0);
#ifndef NOT_DONE
    for (i=0;i<768;i++)
	(*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]);
#else
	(*ramdacPtr->WriteData)(pScrn, 0);
	(*ramdacPtr->WriteData)(pScrn, 0);
	(*ramdacPtr->WriteData)(pScrn, 0);
    for (i=0;i<765;i++)
	(*ramdacPtr->WriteData)(pScrn, 0xff);
#endif
}

void
TIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 
				RamDacRegRecPtr ramdacReg)
{
    int i;

    (*ramdacPtr->ReadAddress)(pScrn, 0);
    for (i=0;i<768;i++)
	ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);

    /* Read back N,M and P values for pixel clock */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
    ramdacReg->DacRegs[TIDAC_PIXEL_N] = 
			(*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
    ramdacReg->DacRegs[TIDAC_PIXEL_M] = 
		    	(*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
    ramdacReg->DacRegs[TIDAC_PIXEL_P] = 
		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);

    /* Read back N,M and P values for loop clock */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
    ramdacReg->DacRegs[TIDAC_LOOP_N] = 
		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
    ramdacReg->DacRegs[TIDAC_LOOP_M] = 
		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
    ramdacReg->DacRegs[TIDAC_LOOP_P] = 
		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);

    /* Order is important */
    TISAVE(TIDAC_latch_ctrl);
    TISAVE(TIDAC_true_color_ctrl);
    TISAVE(TIDAC_multiplex_ctrl);
    TISAVE(TIDAC_clock_select);
    TISAVE(TIDAC_palette_page);
    TISAVE(TIDAC_general_ctrl);
    TISAVE(TIDAC_misc_ctrl);
	    /* 0x2A & 0x2B are reserved */
    TISAVE(TIDAC_key_over_low);
    TISAVE(TIDAC_key_over_high);
    TISAVE(TIDAC_key_red_low);
    TISAVE(TIDAC_key_red_high);
    TISAVE(TIDAC_key_green_low);
    TISAVE(TIDAC_key_green_high);
    TISAVE(TIDAC_key_blue_low);
    TISAVE(TIDAC_key_blue_high);
    TISAVE(TIDAC_key_ctrl);
    TISAVE(TIDAC_clock_ctrl);
    TISAVE(TIDAC_sense_test);
    TISAVE(TIDAC_ind_curs_ctrl);
}

RamDacHelperRecPtr
TIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
    RamDacHelperRecPtr ramdacHelperPtr = NULL;
    Bool RamDacIsSupported = FALSE;
    int TIramdac_ID = -1;
    int i;
    unsigned char id, rev, rev2, id2;

    /* read ID and revision */
    rev = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
    id = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);

    /* check if ID and revision are read only */
    (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, TIDAC_rev);
    (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, TIDAC_id);
    rev2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
    id2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);

    switch (id) {
	case TIDAC_TVP_3030_ID:
		if (id == id2 && rev == rev2)  /* check for READ ONLY */
		    TIramdac_ID = TI3030_RAMDAC;
		break;
	case TIDAC_TVP_3026_ID:
		if (id == id2 && rev == rev2)  /* check for READ ONLY */
		    TIramdac_ID = TI3026_RAMDAC;
		break;
    }

    (*ramdacPtr->WriteDAC)(pScrn, rev, 0, TIDAC_rev);
    (*ramdacPtr->WriteDAC)(pScrn, id, 0, TIDAC_id);

    if (TIramdac_ID == -1) {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"Cannot determine TI RAMDAC type, aborting\n");
	return NULL;
    } else {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"Attached RAMDAC is %s\n", TIramdacDeviceInfo[TIramdac_ID&0xFFFF].DeviceName);
    }

    for (i=0;ramdacs[i].token != -1;i++) {
	if (ramdacs[i].token == TIramdac_ID)
	    RamDacIsSupported = TRUE;
    }

    if (!RamDacIsSupported) {
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
		"This TI RAMDAC is NOT supported by this driver, aborting\n");
	return NULL;
    }

    ramdacHelperPtr = RamDacHelperCreateInfoRec();
    switch (TIramdac_ID) {
	case TI3030_RAMDAC:
 	    ramdacHelperPtr->SetBpp = TIramdac3030SetBpp;
    	    ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
	    break;
	case TI3026_RAMDAC:
 	    ramdacHelperPtr->SetBpp = TIramdac3026SetBpp;
    	    ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
	    break;
    }
    ramdacPtr->RamDacType = TIramdac_ID;
    ramdacHelperPtr->RamDacType = TIramdac_ID;
    ramdacHelperPtr->Save = TIramdacSave;
    ramdacHelperPtr->Restore = TIramdacRestore;

    return ramdacHelperPtr;
}

void
TIramdac3026SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
{
    switch (pScrn->bitsPerPixel) {
    case 32:
	/* order is important */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5c;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
	    ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
	    ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
	}
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    case 24:
	/* order is important */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    case 16:
	/* order is important */
#if 0
	/* Matrox driver uses this */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
#else
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
#endif
	if (pScrn->depth == 16) {
	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
	} else {
	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
	}
#if 0
	/* Matrox driver uses this */
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
#else
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x54;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
#endif
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    case 8:
	/* order is important */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4c;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    }
}

void
TIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
{
    switch (pScrn->bitsPerPixel) {
    case 32:
	/* order is important */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5D;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
	    ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
	    ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
	}
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    case 24:
	/* order is important */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    case 16:
	/* order is important */
#if 0
	/* Matrox driver uses this */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
#else
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
#endif
	if (pScrn->depth == 16) {
	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
	} else {
	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
	}
#if 0
	/* Matrox driver uses this */
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
#else
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x55;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x85;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
#endif
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    case 8:
	/* order is important */
	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4d;
	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
	/* 0x2A & 0x2B are reserved */
	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
	break;
    }
}

static void 
TIramdacShowCursor(ScrnInfoPtr pScrn)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

    /* Enable cursor - X11 mode */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x03);
}

static void
TIramdacHideCursor(ScrnInfoPtr pScrn)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

    /* Disable cursor - X11 mode */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00);
}

static void
TIramdacSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

    x += 64;
    y += 64;

    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XLOW,  0, x & 0xff);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XHIGH, 0, (x >> 8) & 0x0f);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YLOW,  0, y & 0xff);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YHIGH, 0, (y >> 8) & 0x0f);
}

static void
TIramdacSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);

    /* Background color */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 1);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x00ff0000) >> 16));
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x0000ff00) >>  8));
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0,  (bg&0x000000ff)       );

    /* Foreground color */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 2);
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x00ff0000) >> 16));
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x0000ff00) >>  8));
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0,  (fg&0x000000ff)       );
}

static void 
TIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
    int i = 1024;

    /* reset A9,A8 */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00); 
    /* reset cursor RAM load address A7..A0 */
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_INDEX, 0x00, 0x00); 
 
    while(i--) {
	/* NOT_DONE: might need a delay here */
	(*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++));
    }
}

static Bool 
TIramdacUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
{
    return TRUE;
}

void
TIramdacHWCursorInit(xf86CursorInfoPtr infoPtr)
{
    infoPtr->MaxWidth = 64;
    infoPtr->MaxHeight = 64;
    infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
		     HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
		     HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
    infoPtr->SetCursorColors = TIramdacSetCursorColors;
    infoPtr->SetCursorPosition = TIramdacSetCursorPosition;
    infoPtr->LoadCursorImage = TIramdacLoadCursorImage;
    infoPtr->HideCursor = TIramdacHideCursor;
    infoPtr->ShowCursor = TIramdacShowCursor;
    infoPtr->UseHWCursor = TIramdacUseHWCursor;
}

void TIramdacLoadPalette(
    ScrnInfoPtr pScrn, 
    int numColors, 
    int *indices,
    LOCO *colors,
    VisualPtr pVisual
){
    RamDacRecPtr hwp = RAMDACSCRPTR(pScrn);
    int i, index, shift;

    if (pScrn->depth == 16) {
    for(i = 0; i < numColors; i++) {
	index = indices[i];
    	(*hwp->WriteAddress)(pScrn, index << 2);
	(*hwp->WriteData)(pScrn, colors[index >> 1].red);
	(*hwp->WriteData)(pScrn, colors[index].green);
	(*hwp->WriteData)(pScrn, colors[index >> 1].blue);

	if(index <= 31) {
	    (*hwp->WriteAddress)(pScrn, index << 3);
	    (*hwp->WriteData)(pScrn, colors[index].red);
	    (*hwp->WriteData)(pScrn, colors[(index << 1) + 1].green);
	    (*hwp->WriteData)(pScrn, colors[index].blue);
	}
    }
} else {
    shift = (pScrn->depth == 15) ? 3 : 0;

    for(i = 0; i < numColors; i++) {
	index = indices[i];
    	(*hwp->WriteAddress)(pScrn, index << shift);
	(*hwp->WriteData)(pScrn, colors[index].red);
	(*hwp->WriteData)(pScrn, colors[index].green);
	(*hwp->WriteData)(pScrn, colors[index].blue);
    }
}
}

--- NEW FILE: TI.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/TI.h,v 1.4 2000/05/02 21:04:46 alanh Exp $ */

#include <xf86RamDac.h>

unsigned long TIramdacCalculateMNPForClock(unsigned long RefClock,
    unsigned long ReqClock, char IsPixClock, unsigned long MinClock,
    unsigned long MaxClock, unsigned long *rM, unsigned long *rN,
    unsigned long *rP);
RamDacHelperRecPtr TIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs);
void TIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
void TIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
void TIramdac3026SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
void TIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
unsigned long TIramdac3030CalculateMNPForClock(unsigned long RefClock,
    unsigned long ReqClock, char IsPixClock, unsigned long MinClock,
    unsigned long MaxClock, unsigned long *rM, unsigned long *rN,
    unsigned long *rP);
void TIramdacHWCursorInit(xf86CursorInfoPtr infoPtr);
void TIramdacLoadPalette( ScrnInfoPtr pScrn, int numColors, int *indices,
    LOCO *colors, VisualPtr pVisual);


#define TI3030_RAMDAC		(VENDOR_TI << 16) | 0x00
#define TI3026_RAMDAC		(VENDOR_TI << 16) | 0x01

/*
 * TI Ramdac registers
 */

#define TIDAC_rev		0x01
#define TIDAC_ind_curs_ctrl	0x06
#define TIDAC_byte_router_ctrl	0x07
#define TIDAC_latch_ctrl	0x0f
#define TIDAC_true_color_ctrl	0x18
#define TIDAC_multiplex_ctrl	0x19
#define TIDAC_clock_select	0x1a
#define TIDAC_palette_page	0x1c
#define TIDAC_general_ctrl	0x1d
#define TIDAC_misc_ctrl		0x1e
#define TIDAC_pll_addr		0x2c
#define TIDAC_pll_pixel_data	0x2d
#define TIDAC_pll_memory_data	0x2e
#define TIDAC_pll_loop_data	0x2f
#define TIDAC_key_over_low	0x30
#define TIDAC_key_over_high	0x31
#define TIDAC_key_red_low	0x32
#define TIDAC_key_red_high	0x33
#define TIDAC_key_green_low	0x34
#define TIDAC_key_green_high	0x35
#define TIDAC_key_blue_low	0x36
#define TIDAC_key_blue_high	0x37
#define TIDAC_key_ctrl		0x38
#define TIDAC_clock_ctrl	0x39
#define TIDAC_sense_test	0x3a
#define TIDAC_test_mode_data	0x3b
#define TIDAC_crc_remain_lsb	0x3c
#define TIDAC_crc_remain_msb	0x3d
#define TIDAC_crc_bit_select	0x3e
#define TIDAC_id		0x3f

/* These are pll values that are accessed via TIDAC_pll_pixel_data */
#define TIDAC_PIXEL_N		0x80
#define TIDAC_PIXEL_M		0x81
#define TIDAC_PIXEL_P		0x82
#define TIDAC_PIXEL_VALID	0x83

/* These are pll values that are accessed via TIDAC_pll_loop_data */
#define TIDAC_LOOP_N		0x90
#define TIDAC_LOOP_M		0x91
#define TIDAC_LOOP_P		0x92
#define TIDAC_LOOP_VALID	0x93

/* Direct mapping addresses */
#define TIDAC_INDEX		0xa0
#define TIDAC_PALETTE_DATA	0xa1
#define TIDAC_READ_MASK		0xa2
#define TIDAC_READ_ADDR		0xa3
#define TIDAC_CURS_WRITE_ADDR	0xa4
#define TIDAC_CURS_COLOR	0xa5
#define TIDAC_CURS_READ_ADDR	0xa7
#define TIDAC_CURS_CTL		0xa9
#define TIDAC_INDEXED_DATA	0xaa
#define TIDAC_CURS_RAM_DATA	0xab
#define TIDAC_CURS_XLOW		0xac
#define TIDAC_CURS_XHIGH	0xad
#define TIDAC_CURS_YLOW		0xae
#define TIDAC_CURS_YHIGH	0xaf

#define TIDAC_sw_reset		0xff

/* Constants */  
#define TIDAC_TVP_3026_ID       0x26
#define TIDAC_TVP_3030_ID       0x30

--- NEW FILE: TIPriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/TIPriv.h,v 1.2 1998/07/25 16:57:19 dawes Exp $ */

#include "TI.h"

typedef struct {
	char *DeviceName;
} xf86TIramdacInfo;

extern xf86TIramdacInfo TIramdacDeviceInfo[];

#ifdef INIT_TI_RAMDAC_INFO
xf86TIramdacInfo TIramdacDeviceInfo[] = {
	{"TI TVP3030"},
	{"TI TVP3026"}
};
#endif

#define TISAVE(_reg) do { 						\
    ramdacReg->DacRegs[_reg] = (*ramdacPtr->ReadDAC)(pScrn, _reg);	\
} while (0)

#define TIRESTORE(_reg) do { 						\
    (*ramdacPtr->WriteDAC)(pScrn, _reg, 				\
	(ramdacReg->DacRegs[_reg] & 0xFF00) >> 8, 			\
	ramdacReg->DacRegs[_reg]);					\
} while (0)

--- NEW FILE: xf86Cursor.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.c,v 1.19tsi Exp $ */

#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86CursorPriv.h"
#include "colormapst.h"
#include "cursorstr.h"

int xf86CursorScreenIndex = -1;
static unsigned long xf86CursorGeneration = 0;

/* sprite functions */

static Bool xf86CursorRealizeCursor(ScreenPtr, CursorPtr);
static Bool xf86CursorUnrealizeCursor(ScreenPtr, CursorPtr);
static void xf86CursorSetCursor(ScreenPtr, CursorPtr, int, int);
static void xf86CursorMoveCursor(ScreenPtr, int, int);

static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
   xf86CursorRealizeCursor,
   xf86CursorUnrealizeCursor,
   xf86CursorSetCursor,
   xf86CursorMoveCursor
};

/* Screen functions */

static void xf86CursorInstallColormap(ColormapPtr);
static void xf86CursorRecolorCursor(ScreenPtr, CursorPtr, Bool);
static Bool xf86CursorCloseScreen(int, ScreenPtr);
static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
				    ScreenPtr);

/* ScrnInfoRec functions */

static Bool xf86CursorSwitchMode(int, DisplayModePtr,int);
static Bool xf86CursorEnterVT(int, int);
static void xf86CursorLeaveVT(int, int);
static int  xf86CursorSetDGAMode(int, int, DGADevicePtr);

Bool
xf86InitCursor(
   ScreenPtr pScreen,
   xf86CursorInfoPtr infoPtr
)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    xf86CursorScreenPtr ScreenPriv;
    miPointerScreenPtr PointPriv;

    if (xf86CursorGeneration != serverGeneration) {
	if ((xf86CursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
	    return FALSE;
	xf86CursorGeneration = serverGeneration;
    }

    if (!xf86InitHardwareCursor(pScreen, infoPtr))
	return FALSE;

    ScreenPriv = xcalloc(1, sizeof(xf86CursorScreenRec));
    if (!ScreenPriv)
	return FALSE;

    pScreen->devPrivates[xf86CursorScreenIndex].ptr = ScreenPriv;

    ScreenPriv->SWCursor = TRUE;
    ScreenPriv->isUp = FALSE;
    ScreenPriv->CurrentCursor = NULL;
    ScreenPriv->CursorInfoPtr = infoPtr;
    ScreenPriv->PalettedCursor = FALSE;
    ScreenPriv->pInstalledMap = NULL;

    ScreenPriv->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = xf86CursorCloseScreen;
    ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
    pScreen->QueryBestSize = xf86CursorQueryBestSize;
    ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
    pScreen->RecolorCursor = xf86CursorRecolorCursor;

    if ((infoPtr->pScrn->bitsPerPixel == 8) &&
	!(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
	ScreenPriv->InstallColormap = pScreen->InstallColormap;
	pScreen->InstallColormap = xf86CursorInstallColormap;
	ScreenPriv->PalettedCursor = TRUE;
    }

    PointPriv = pScreen->devPrivates[miPointerScreenIndex].ptr;

    ScreenPriv->showTransparent = PointPriv->showTransparent;
    if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT)
	PointPriv->showTransparent = TRUE;
    else
	PointPriv->showTransparent = FALSE;
    ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
    PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;

    ScreenPriv->SwitchMode = pScrn->SwitchMode;
    ScreenPriv->EnterVT = pScrn->EnterVT;
    ScreenPriv->LeaveVT = pScrn->LeaveVT;
    ScreenPriv->SetDGAMode = pScrn->SetDGAMode;
    
    ScreenPriv->ForceHWCursorCount = 0;
    ScreenPriv->HWCursorForced = FALSE;

    if (pScrn->SwitchMode)
	pScrn->SwitchMode = xf86CursorSwitchMode;
    pScrn->EnterVT = xf86CursorEnterVT;
    pScrn->LeaveVT = xf86CursorLeaveVT;
    pScrn->SetDGAMode = xf86CursorSetDGAMode;

    return TRUE;
}

/***** Screen functions *****/

static Bool
xf86CursorCloseScreen(int i, ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    miPointerScreenPtr PointPriv =
	pScreen->devPrivates[miPointerScreenIndex].ptr;
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    if (ScreenPriv->isUp && pScrn->vtSema)
	xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);

    pScreen->CloseScreen = ScreenPriv->CloseScreen;
    pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
    pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
    if (ScreenPriv->InstallColormap)
	pScreen->InstallColormap = ScreenPriv->InstallColormap;

    PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
    PointPriv->showTransparent = ScreenPriv->showTransparent;

    pScrn->SwitchMode = ScreenPriv->SwitchMode;
    pScrn->EnterVT = ScreenPriv->EnterVT;
    pScrn->LeaveVT = ScreenPriv->LeaveVT;
    pScrn->SetDGAMode = ScreenPriv->SetDGAMode;

    xfree(ScreenPriv->transparentData);
    xfree(ScreenPriv);

    return (*pScreen->CloseScreen)(i, pScreen);
}

static void
xf86CursorQueryBestSize(
   int class,
   unsigned short *width,
   unsigned short *height,
   ScreenPtr pScreen)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    if (class == CursorShape) {
	if(*width > ScreenPriv->CursorInfoPtr->MaxWidth)
	   *width = ScreenPriv->CursorInfoPtr->MaxWidth;
	if(*height > ScreenPriv->CursorInfoPtr->MaxHeight)
	   *height = ScreenPriv->CursorInfoPtr->MaxHeight;
    } else
	(*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
}

static void
xf86CursorInstallColormap(ColormapPtr pMap)
{
    xf86CursorScreenPtr ScreenPriv =
	pMap->pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    ScreenPriv->pInstalledMap = pMap;

    (*ScreenPriv->InstallColormap)(pMap);
}

static void
xf86CursorRecolorCursor(
    ScreenPtr pScreen,
    CursorPtr pCurs,
    Bool displayed)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    if (!displayed)
	return;

    if (ScreenPriv->SWCursor)
	(*ScreenPriv->RecolorCursor)(pScreen, pCurs, displayed);
    else
	xf86RecolorCursor(pScreen, pCurs, displayed);
}

/***** ScrnInfoRec functions *********/

static Bool
xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
{
    Bool ret;
    ScreenPtr pScreen = screenInfo.screens[index];
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;
    miPointerScreenPtr PointPriv =
	pScreen->devPrivates[miPointerScreenIndex].ptr;

    if (ScreenPriv->isUp) {
	xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
	ScreenPriv->isUp = FALSE;
    }

    ret = (*ScreenPriv->SwitchMode)(index, mode, flags);

    /*
     * Cannot restore cursor here because the new frame[XY][01] haven't been
     * calculated yet.  However, because the hardware cursor was removed above,
     * ensure the cursor is repainted by miPointerWarpCursor().
     */
    ScreenPriv->CursorToRestore = ScreenPriv->CurrentCursor;
    PointPriv->waitForUpdate = FALSE;	/* Force cursor repaint */

    return ret;
}

static Bool
xf86CursorEnterVT(int index, int flags)
{
    Bool ret;
    ScreenPtr pScreen = screenInfo.screens[index];
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    ret = (*ScreenPriv->EnterVT)(index, flags);

    if (ScreenPriv->CurrentCursor)
	xf86CursorSetCursor(pScreen, ScreenPriv->CurrentCursor,
			ScreenPriv->x, ScreenPriv->y);
    return ret;
}

static void
xf86CursorLeaveVT(int index, int flags)
{
    ScreenPtr pScreen = screenInfo.screens[index];
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    if (ScreenPriv->isUp) {
	xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
	ScreenPriv->isUp = FALSE;
    }
    ScreenPriv->SWCursor = TRUE;

    (*ScreenPriv->LeaveVT)(index, flags);
}

static int
xf86CursorSetDGAMode(int index, int num, DGADevicePtr devRet)
{
    ScreenPtr pScreen = screenInfo.screens[index];
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;
    int ret;

    if (num && ScreenPriv->isUp) {
	xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
	ScreenPriv->isUp = FALSE;
	ScreenPriv->SWCursor = TRUE;
    }

    ret = (*ScreenPriv->SetDGAMode)(index, num, devRet);

    if (ScreenPriv->CurrentCursor && (!num || (ret != Success))) {
	xf86CursorSetCursor(pScreen, ScreenPriv->CurrentCursor,
			ScreenPriv->x, ScreenPriv->y);
    }

    return ret;
}

/****** miPointerSpriteFunctions *******/

static Bool
xf86CursorRealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    if (pCurs->refcnt <= 1)
	pCurs->devPriv[pScreen->myNum] = NULL;

    return (*ScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCurs);
}

static Bool
xf86CursorUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    if (pCurs->refcnt <= 1) {
	xfree(pCurs->devPriv[pScreen->myNum]);
	pCurs->devPriv[pScreen->myNum] = NULL;
    }

    return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCurs);
}

static void
xf86CursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
    miPointerScreenPtr PointPriv;

    ScreenPriv->CurrentCursor = pCurs;
    ScreenPriv->x = x;
    ScreenPriv->y = y;
    ScreenPriv->CursorToRestore = NULL;

    if (pCurs == NullCursor) {	/* means we're supposed to remove the cursor */
	if (ScreenPriv->SWCursor)
	    (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, NullCursor, x, y);
	else if (ScreenPriv->isUp) {
	    xf86SetCursor(pScreen, NullCursor, x, y);
	    ScreenPriv->isUp = FALSE;
	}
	return;
    }

    ScreenPriv->HotX = pCurs->bits->xhot;
    ScreenPriv->HotY = pCurs->bits->yhot;

    PointPriv = pScreen->devPrivates[miPointerScreenIndex].ptr;

    if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
#ifdef ARGB_CURSOR
	pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
	 (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
	pCurs->bits->argb == 0 &&
#endif
	(pCurs->bits->height <= infoPtr->MaxHeight) &&
	(pCurs->bits->width <= infoPtr->MaxWidth) &&
	(!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
    {

	if (ScreenPriv->SWCursor)	/* remove the SW cursor */
	      (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, NullCursor, x, y);

	xf86SetCursor(pScreen, pCurs, x, y);
	ScreenPriv->SWCursor = FALSE;
	ScreenPriv->isUp = TRUE;
	PointPriv->waitForUpdate = !infoPtr->pScrn->silkenMouse;
	return;
    }

    PointPriv->waitForUpdate = TRUE;

    if (ScreenPriv->isUp) {
	/* Remove the HW cursor, or make it transparent */
	if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
	    xf86SetTransparentCursor(pScreen);
	} else {
	    xf86SetCursor(pScreen, NullCursor, x, y);
	    ScreenPriv->isUp = FALSE;
	}
    }

    ScreenPriv->SWCursor = TRUE;

    if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
	pCurs = NullCursor;
    (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCurs, x, y);
}

static void
xf86CursorMoveCursor(ScreenPtr pScreen, int x, int y)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    ScreenPriv->x = x;
    ScreenPriv->y = y;

    if (ScreenPriv->CursorToRestore)
	xf86CursorSetCursor(pScreen, ScreenPriv->CursorToRestore,
			    ScreenPriv->x, ScreenPriv->y);
    else if (ScreenPriv->SWCursor)
	(*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
    else if (ScreenPriv->isUp)
	xf86MoveCursor(pScreen, x, y);
}

void
xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;

    if (on)
    {
	if (ScreenPriv->ForceHWCursorCount++ == 0)
	{
	    if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor)
	    {
		ScreenPriv->HWCursorForced = TRUE;
		xf86CursorSetCursor (pScreen, ScreenPriv->CurrentCursor,
				     ScreenPriv->x, ScreenPriv->y);
	    }
	    else
		ScreenPriv->HWCursorForced = FALSE;
	}
    }
    else
    {
	if (--ScreenPriv->ForceHWCursorCount == 0)
	{
	    if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
		xf86CursorSetCursor (pScreen, ScreenPriv->CurrentCursor,
				     ScreenPriv->x, ScreenPriv->y);
	}
    }
}

xf86CursorInfoPtr
xf86CreateCursorInfoRec(void)
{
    return xcalloc(1, sizeof(xf86CursorInfoRec));
}

void
xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
{
    xfree(infoPtr);
}

--- NEW FILE: xf86Cursor.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.h,v 1.10tsi Exp $ */

#ifndef _XF86CURSOR_H
#define _XF86CURSOR_H

#include "xf86str.h"
#include "mipointer.h"

typedef struct _xf86CursorInfoRec {
    ScrnInfoPtr pScrn;
    int Flags;
    int MaxWidth;
    int MaxHeight;
    void (*SetCursorColors)(ScrnInfoPtr pScrn, int bg, int fg);
    void (*SetCursorPosition)(ScrnInfoPtr pScrn, int x, int y);
    void (*LoadCursorImage)(ScrnInfoPtr pScrn, unsigned char *bits);
    void (*HideCursor)(ScrnInfoPtr pScrn);
    void (*ShowCursor)(ScrnInfoPtr pScrn);
    unsigned char* (*RealizeCursor)(struct _xf86CursorInfoRec *, CursorPtr);
    Bool (*UseHWCursor)(ScreenPtr, CursorPtr);

#ifdef ARGB_CURSOR
    Bool (*UseHWCursorARGB) (ScreenPtr, CursorPtr);
    void (*LoadCursorARGB) (ScrnInfoPtr, CursorPtr);
#endif

} xf86CursorInfoRec, *xf86CursorInfoPtr;

Bool xf86InitCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr);
xf86CursorInfoPtr xf86CreateCursorInfoRec(void);
void xf86DestroyCursorInfoRec(xf86CursorInfoPtr);
void xf86ForceHWCursor (ScreenPtr pScreen, Bool on);

#define HARDWARE_CURSOR_INVERT_MASK 			0x00000001
#define HARDWARE_CURSOR_AND_SOURCE_WITH_MASK		0x00000002
#define HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK		0x00000004
#define HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED	0x00000008
#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1	0x00000010
#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8	0x00000020
#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16	0x00000040
#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32	0x00000080
#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64	0x00000100
#define HARDWARE_CURSOR_TRUECOLOR_AT_8BPP		0x00000200
#define HARDWARE_CURSOR_BIT_ORDER_MSBFIRST		0x00000400
#define HARDWARE_CURSOR_NIBBLE_SWAPPED			0x00000800
#define HARDWARE_CURSOR_SHOW_TRANSPARENT		0x00001000
#define HARDWARE_CURSOR_UPDATE_UNHIDDEN			0x00002000

#endif /* _XF86CURSOR_H */

--- NEW FILE: xf86CursorPriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86CursorPriv.h,v 1.4tsi Exp $ */

#ifndef _XF86CURSORPRIV_H
#define _XF86CURSORPRIV_H

#include "xf86Cursor.h"
#include "mipointrst.h"

typedef struct {
    Bool			SWCursor;
    Bool			isUp;
    Bool			showTransparent;
    short			HotX;
    short			HotY;
    short			x;
    short			y;
    CursorPtr			CurrentCursor, CursorToRestore;
    xf86CursorInfoPtr		CursorInfoPtr;
    CloseScreenProcPtr          CloseScreen;
    RecolorCursorProcPtr	RecolorCursor;
    InstallColormapProcPtr	InstallColormap;
    QueryBestSizeProcPtr	QueryBestSize;
    miPointerSpriteFuncPtr	spriteFuncs;
    Bool			PalettedCursor;
    ColormapPtr			pInstalledMap;
    Bool                	(*SwitchMode)(int, DisplayModePtr,int);
    Bool                	(*EnterVT)(int, int);
    void                	(*LeaveVT)(int, int);
    int				(*SetDGAMode)(int, int, DGADevicePtr);

    /* Number of requests to force HW cursor */
    int				ForceHWCursorCount;
    Bool			HWCursorForced;

    pointer			transparentData;
} xf86CursorScreenRec, *xf86CursorScreenPtr;

void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
void xf86SetTransparentCursor(ScreenPtr pScreen);
void xf86MoveCursor(ScreenPtr pScreen, int x, int y);
void xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed);
Bool xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr);

CARD32 xf86ReverseBitOrder(CARD32 data);

extern int xf86CursorScreenIndex;

#endif /* _XF86CURSORPRIV_H */

--- NEW FILE: xf86HWCurs.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c,v 1.12 2003/02/13 20:28:41 tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "cursorstr.h"
#include "mi.h"
#include "mipointer.h"
#include "xf86CursorPriv.h"

#include "servermd.h"

#if BITMAP_SCANLINE_PAD == 64

#if 1
/* Cursors might be only 32 wide. Give'em a chance */
#define SCANLINE CARD32
#define CUR_BITMAP_SCANLINE_PAD 32
#define CUR_LOG2_BITMAP_PAD 5
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
#else
#define SCANLINE CARD64
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
static CARD64 xf86CARD64ReverseBits(CARD64 w);

static CARD64
xf86CARD64ReverseBits(CARD64 w)
{
  unsigned char *p = (unsigned char *)&w;

  p[0] = byte_reversed[p[0]];
  p[1] = byte_reversed[p[1]];
  p[2] = byte_reversed[p[2]];
  p[3] = byte_reversed[p[3]];
  p[4] = byte_reversed[p[4]];
  p[5] = byte_reversed[p[5]];
  p[6] = byte_reversed[p[6]];
  p[7] = byte_reversed[p[7]];

  return w;
}
#endif

#else

#define SCANLINE CARD32
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)

#endif /* BITMAP_SCANLINE_PAD == 64 */

static unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
static unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
static unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
static unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
static unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);

Bool
xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
{
    if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
	return FALSE;

    /* These are required for now */
    if (!infoPtr->SetCursorPosition ||
	!infoPtr->LoadCursorImage ||
	!infoPtr->HideCursor ||
	!infoPtr->ShowCursor ||
	!infoPtr->SetCursorColors)
	return FALSE;

    if (infoPtr->RealizeCursor) {
	/* Don't overwrite a driver provided Realize Cursor function */
    } else
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
	infoPtr->RealizeCursor = RealizeCursorInterleave1;
    } else
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
	infoPtr->RealizeCursor = RealizeCursorInterleave8;
    } else
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
	infoPtr->RealizeCursor = RealizeCursorInterleave16;
    } else
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
	infoPtr->RealizeCursor = RealizeCursorInterleave32;
    } else
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
	infoPtr->RealizeCursor = RealizeCursorInterleave64;
    } else {    /* not interleaved */
	infoPtr->RealizeCursor = RealizeCursorInterleave0;
    }

    infoPtr->pScrn = xf86Screens[pScreen->myNum];

    return TRUE;
}

void
xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
    unsigned char *bits;

    if (pCurs == NullCursor) {
	(*infoPtr->HideCursor)(infoPtr->pScrn);
	return;
    }

    bits = pCurs->devPriv[pScreen->myNum];

    x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
    y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;

#ifdef ARGB_CURSOR
    if (!pCurs->bits->argb || !infoPtr->LoadCursorARGB)
#endif
    if (!bits) {
	bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
	pCurs->devPriv[pScreen->myNum] = bits;
    }

    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
	(*infoPtr->HideCursor)(infoPtr->pScrn);

#ifdef ARGB_CURSOR
    if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
	(*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
    else
#endif
    if (bits)
	(*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);

    xf86RecolorCursor(pScreen, pCurs, 1);

    (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);

    (*infoPtr->ShowCursor)(infoPtr->pScrn);
}

void
xf86SetTransparentCursor(ScreenPtr pScreen)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;

    if (!ScreenPriv->transparentData)
	ScreenPriv->transparentData =
	    (*infoPtr->RealizeCursor)(infoPtr, NullCursor);

    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
	(*infoPtr->HideCursor)(infoPtr->pScrn);

    if (ScreenPriv->transparentData)
	(*infoPtr->LoadCursorImage)(infoPtr->pScrn,
				    ScreenPriv->transparentData);

    (*infoPtr->ShowCursor)(infoPtr->pScrn);
}

void
xf86MoveCursor(ScreenPtr pScreen, int x, int y)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;

    x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
    y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;

    (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
}

void
xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
{
    xf86CursorScreenPtr ScreenPriv =
	pScreen->devPrivates[xf86CursorScreenIndex].ptr;
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;

#ifdef ARGB_CURSOR
    /* recoloring isn't applicable to ARGB cursors and drivers 
       shouldn't have to ignore SetCursorColors requests */
    if (pCurs->bits->argb)
        return;
#endif

    if (ScreenPriv->PalettedCursor) {
	xColorItem sourceColor, maskColor;
	ColormapPtr pmap = ScreenPriv->pInstalledMap;
	
	if (!pmap)
	    return;

	sourceColor.red = pCurs->foreRed;
	sourceColor.green = pCurs->foreGreen;
	sourceColor.blue = pCurs->foreBlue;
	FakeAllocColor(pmap, &sourceColor);
	maskColor.red = pCurs->backRed;
	maskColor.green = pCurs->backGreen;
	maskColor.blue = pCurs->backBlue;
	FakeAllocColor(pmap, &maskColor);
	FakeFreeColor(pmap, sourceColor.pixel);
	FakeFreeColor(pmap, maskColor.pixel);
	(*infoPtr->SetCursorColors)(infoPtr->pScrn,
		maskColor.pixel, sourceColor.pixel);
    } else {    /* Pass colors in 8-8-8 RGB format */
	(*infoPtr->SetCursorColors)(infoPtr->pScrn,
	    (pCurs->backBlue >> 8) |
	    ((pCurs->backGreen >> 8) << 8) |
	    ((pCurs->backRed >> 8) << 16),
	    (pCurs->foreBlue >> 8) |
	    ((pCurs->foreGreen >> 8) << 8) |
	    ((pCurs->foreRed >> 8) << 16)
	);
    }
}

/* These functions assume that MaxWidth is a multiple of 32 */
static unsigned char*
RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{

    SCANLINE *SrcS, *SrcM, *DstS, *DstM;
    SCANLINE *pSrc, *pMsk;
    unsigned char *mem;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    int SrcPitch, DstPitch, Pitch, y, x;
    /* how many words are in the source or mask */
    int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);


    if (!(mem = xcalloc(1, size)))
	return NULL;

    if (pCurs == NullCursor) {
	if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
	    DstM = (SCANLINE*)mem;
	    if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
		DstM += words;
	    (void)memset(DstM, -1, words * sizeof(SCANLINE));
	}
	return mem;
    }

    /* SrcPitch == the number of scanlines wide the cursor image is */
    SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
      CUR_LOG2_BITMAP_PAD;

    /* DstPitch is the width of the hw cursor in scanlines */
    DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
    Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;

    SrcS = (SCANLINE*)pCurs->bits->source;
    SrcM = (SCANLINE*)pCurs->bits->mask;
    DstS = (SCANLINE*)mem;
    DstM = DstS + words;

    if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
	SCANLINE *tmp;
	tmp = DstS; DstS = DstM; DstM = tmp;
    }

    if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
	for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
	    y--;
	    pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
	    for(x = 0; x < Pitch; x++) {
		pSrc[x] = SrcS[x] & SrcM[x];
		pMsk[x] = SrcM[x];
	    }
	}
    } else {
	for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
	    y--;
	    pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
	    for(x = 0; x < Pitch; x++) {
		pSrc[x] = SrcS[x];
		pMsk[x] = SrcM[x];
	    }
	}
    }

    if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
	int count = size;
	unsigned char* pntr1 = (unsigned char *)DstS;
	unsigned char* pntr2 = (unsigned char *)DstM;
	unsigned char a, b;
	while (count) {

	   a = *pntr1;
	   b = *pntr2;
	   *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
	   *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
	   pntr1++; pntr2++;
	   count-=2;
	}
    }

    /*
     * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
     * out entire source mask.
     */
    if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
	int count = words;
	SCANLINE* pntr = DstM;
	while (count--) {
	   *pntr = ~(*pntr);
	    pntr++;
	}
    }

    if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
	for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
	    y--;
	    pSrc+=DstPitch, pMsk+=DstPitch) {
	    for(x = 0; x < Pitch; x++) {
		pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
		pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
	    }
	}
    }

    return mem;
}

static unsigned char*
RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    unsigned char *DstS, *DstM;
    unsigned char *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
	return NULL;

    if (!(mem = xcalloc(1, size))) {
	xfree(mem2);
	return NULL;
    }

     /* 1 bit interleave */
    DstS = mem2;
    DstM = DstS + (size >> 1);
    pntr = mem;
    count = size;
    while (count) {
	*pntr++ = ((*DstS&0x01)     ) | ((*DstM&0x01) << 1) |
		  ((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
		  ((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
		  ((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
	*pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
		  ((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
		  ((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
		  ((*DstS&0x80) >> 1) | ((*DstM&0x80)     );
	DstS++;
	DstM++;
	count-=2;
    }

    /* Free the uninterleaved cursor */
    xfree(mem2);

    return mem;
}

static unsigned char*
RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    unsigned char *DstS, *DstM;
    unsigned char *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
	return NULL;

    if (!(mem = xcalloc(1, size))) {
	xfree(mem2);
	return NULL;
    }

    /* 8 bit interleave */
    DstS = mem2;
    DstM = DstS + (size >> 1);
    pntr = mem;
    count = size;
    while (count) {
	*pntr++ = *DstS++;
	*pntr++ = *DstM++;
	count-=2;
    }

    /* Free the uninterleaved cursor */
    xfree(mem2);

    return mem;
}

static unsigned char*
RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    unsigned short *DstS, *DstM;
    unsigned short *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
	return NULL;

    if (!(mem = xcalloc(1, size))) {
	xfree(mem2);
	return NULL;
    }

    /* 16 bit interleave */
    DstS = (pointer)mem2;
    DstM = DstS + (size >> 2);
    pntr = (pointer)mem;
    count = (size >> 1);
    while (count) {
	*pntr++ = *DstS++;
	*pntr++ = *DstM++;
	count-=2;
    }

    /* Free the uninterleaved cursor */
    xfree(mem2);

    return mem;
}

static unsigned char*
RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    CARD32 *DstS, *DstM;
    CARD32 *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
	return NULL;

    if (!(mem = xcalloc(1, size))) {
	xfree(mem2);
	return NULL;
    }

    /* 32 bit interleave */
    DstS = (pointer)mem2;
    DstM = DstS + (size >> 3);
    pntr = (pointer)mem;
    count = (size >> 2);
    while (count) {
	*pntr++ = *DstS++;
	*pntr++ = *DstM++;
	count-=2;
    }

    /* Free the uninterleaved cursor */
    xfree(mem2);

    return mem;
}

static unsigned char*
RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    CARD32 *DstS, *DstM;
    CARD32 *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
	return NULL;

    if (!(mem = xcalloc(1, size))) {
	xfree(mem2);
	return NULL;
    }

    /* 64 bit interleave */
    DstS = (pointer)mem2;
    DstM = DstS + (size >> 3);
    pntr = (pointer)mem;
    count = (size >> 2);
    while (count) {
	*pntr++ = *DstS++;
	*pntr++ = *DstS++;
	*pntr++ = *DstM++;
	*pntr++ = *DstM++;
	count-=4;
    }

    /* Free the uninterleaved cursor */
    xfree(mem2);

    return mem;
}

--- NEW FILE: xf86RamDac.c ---
/*
 * 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 at fairlite.demon.co.uk>
 *
 * Generic RAMDAC access routines.
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.c,v 1.6tsi Exp $ */

#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"

#include "xf86RamDacPriv.h"

int RamDacHWPrivateIndex = -1;
int RamDacScreenPrivateIndex = -1;

RamDacRecPtr
RamDacCreateInfoRec()
{
    RamDacRecPtr infoRec;

    infoRec = xcalloc(1, sizeof(RamDacRec));

    return infoRec;
}

RamDacHelperRecPtr
RamDacHelperCreateInfoRec()
{
    RamDacHelperRecPtr infoRec;

    infoRec = xcalloc(1, sizeof(RamDacHelperRec));

    return infoRec;
}

void 
RamDacDestroyInfoRec(RamDacRecPtr infoRec)
{
    xfree(infoRec);
}

void 
RamDacHelperDestroyInfoRec(RamDacHelperRecPtr infoRec)
{
    xfree(infoRec);
}

Bool
RamDacInit(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPriv)
{
    RamDacScreenRecPtr ramdacScrPtr;

    /*
     * make sure the RamDacRec is allocated
     */
    if (!RamDacGetRec(pScrn))
	return FALSE;
    ramdacScrPtr =
	((RamDacScreenRecPtr) (pScrn)->privates[RamDacGetScreenIndex()].ptr);
    ramdacScrPtr->RamDacRec = ramdacPriv;

    return(TRUE);
}

void
RamDacGetRecPrivate()
{
    if (RamDacHWPrivateIndex < 0)
	RamDacHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
    if (RamDacScreenPrivateIndex < 0)
	RamDacScreenPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
    return;
}

Bool
RamDacGetRec(ScrnInfoPtr scrp)
{
    RamDacGetRecPrivate();
    /*
     * New privates are always set to NULL, so we can check if the allocation
     * has already been done.
     */
    if (scrp->privates[RamDacHWPrivateIndex].ptr != NULL)
	return TRUE;
    if (scrp->privates[RamDacScreenPrivateIndex].ptr != NULL)
	return TRUE;

    scrp->privates[RamDacHWPrivateIndex].ptr = 
					xnfcalloc(sizeof(RamDacHWRec), 1);
    scrp->privates[RamDacScreenPrivateIndex].ptr = 
					xnfcalloc(sizeof(RamDacScreenRec), 1);
    
    return TRUE;
}

void
RamDacFreeRec(ScrnInfoPtr pScrn)
{
    RamDacHWRecPtr ramdacHWPtr;
    RamDacScreenRecPtr ramdacScrPtr;

    if (RamDacHWPrivateIndex < 0)
	return;

    if (RamDacScreenPrivateIndex < 0)
	return;

    ramdacHWPtr = RAMDACHWPTR(pScrn);
    ramdacScrPtr = ((RamDacScreenRecPtr)
				(pScrn)->privates[RamDacGetScreenIndex()].ptr);
    
    if (ramdacHWPtr)
	xfree(ramdacHWPtr);
    ramdacHWPtr = NULL;

    if (ramdacScrPtr)
	xfree(ramdacScrPtr);
    ramdacScrPtr = NULL;
}

int
RamDacGetHWIndex()
{
    return RamDacHWPrivateIndex;
}

int
RamDacGetScreenIndex()
{
    return RamDacScreenPrivateIndex;
}

--- NEW FILE: xf86RamDac.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.h,v 1.9 1999/03/28 15:33:02 dawes Exp $ */

#ifndef _XF86RAMDAC_H
#define _XF86RAMDAC_H 1

#include "colormapst.h"
#include "xf86Cursor.h"

/* Define unique vendor codes for RAMDAC's */
#define VENDOR_IBM	0x0000
#define VENDOR_BT	0x0001
#define VENDOR_TI	0x0002

typedef struct _RamDacRegRec {
/* This is probably the nastiest assumption, we allocate 1024 slots for
 * ramdac registers, should be enough. I've checked IBM and TVP series 
 * and they seem o.k 
 * Then we allocate 768 entries for the DAC too. IBM640 needs 1024 -FIXME
 */
    unsigned short DacRegs[0x400];	/* register set */
    unsigned char DAC[0x300];		/* colour map */
    Bool Overlay;
} RamDacRegRec, *RamDacRegRecPtr;

typedef struct _RamDacHWRegRec {
    RamDacRegRec	SavedReg;
    RamDacRegRec	ModeReg;
} RamDacHWRec, *RamDacHWRecPtr;

typedef struct _RamDacRec {
    CARD32 RamDacType;

    void (*LoadPalette)(
	ScrnInfoPtr pScrn, 
	int numColors, 
	int *indices, 
	LOCO *colors,
	VisualPtr pVisual
    );

    unsigned char (*ReadDAC)(
	ScrnInfoPtr pScrn,
	CARD32
    );

    void (*WriteDAC)(
	ScrnInfoPtr pScrn,
	CARD32,
	unsigned char,
	unsigned char
    );

    void (*WriteAddress)(
	ScrnInfoPtr pScrn,
	CARD32
    );

    void (*WriteData)(
	ScrnInfoPtr pScrn,
	unsigned char
    );

    void (*ReadAddress)(
	ScrnInfoPtr pScrn,
	CARD32
    );

    unsigned char (*ReadData)(
	ScrnInfoPtr pScrn
    );
} RamDacRec, *RamDacRecPtr;

typedef struct _RamDacHelperRec {
    CARD32 RamDacType;

    void (*Restore)(
	ScrnInfoPtr pScrn,
	RamDacRecPtr ramdacPtr,
	RamDacRegRecPtr ramdacReg
    );

    void (*Save)(
	ScrnInfoPtr pScrn,
	RamDacRecPtr ramdacPtr,
	RamDacRegRecPtr ramdacReg
    );

    void (*SetBpp)(
	ScrnInfoPtr pScrn,
	RamDacRegRecPtr ramdacReg
    );

    void (*HWCursorInit)(
	xf86CursorInfoPtr infoPtr
    );
} RamDacHelperRec, *RamDacHelperRecPtr;

#define RAMDACHWPTR(p) ((RamDacHWRecPtr)((p)->privates[RamDacGetHWIndex()].ptr))

typedef struct _RamdacScreenRec {
    RamDacRecPtr	RamDacRec;
} RamDacScreenRec, *RamDacScreenRecPtr;
#define RAMDACSCRPTR(p) ((RamDacScreenRecPtr)((p)->privates[RamDacGetScreenIndex()].ptr))->RamDacRec

extern int RamDacHWPrivateIndex;
extern int RamDacScreenPrivateIndex;

typedef struct {
    int		token;
} RamDacSupportedInfoRec, *RamDacSupportedInfoRecPtr;

RamDacRecPtr RamDacCreateInfoRec(void);
RamDacHelperRecPtr RamDacHelperCreateInfoRec(void);
void RamDacDestroyInfoRec(RamDacRecPtr RamDacRec);
void RamDacHelperDestroyInfoRec(RamDacHelperRecPtr RamDacRec);
Bool RamDacInit(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec);
void RamDacSetGamma(ScrnInfoPtr pScrn, Bool Real8BitDac);
void RamDacRestoreDACValues(ScrnInfoPtr pScrn);
Bool RamDacHandleColormaps(ScreenPtr pScreen, int maxColors, int sigRGBbits,
			   unsigned int flags);
void RamDacFreeRec(ScrnInfoPtr pScrn);
int  RamDacGetHWIndex(void);

#endif /* _XF86RAMDAC_H */

--- NEW FILE: xf86RamDacCmap.c ---
/*
 * 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 at fairlite.demon.co.uk>
 *
 * Generic RAMDAC access to colormaps.
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacCmap.c,v 1.6 2000/03/21 21:15:28 alanh Exp $ */

#include <X11/X.h>
#include <X11/Xproto.h>
#include "windowstr.h"
#include "mipointer.h"
#include "micmap.h"

#include "xf86.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "colormapst.h"
#include "xf86RamDacPriv.h"

#include "xf86PciInfo.h"
#include "xf86Pci.h"

void
RamDacLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
		 VisualPtr pVisual)
{
    RamDacRecPtr hwp = RAMDACSCRPTR(pScrn);
    int i, index;

    for (i = 0; i < numColors; i++) {
	index = indices[i];
	(*hwp->WriteAddress)(pScrn, index);
	(*hwp->WriteData)(pScrn, colors[index].red);
	(*hwp->WriteData)(pScrn, colors[index].green);
	(*hwp->WriteData)(pScrn, colors[index].blue);
    }
}

Bool
RamDacHandleColormaps(ScreenPtr pScreen, int maxColors, int sigRGBbits,
		      unsigned int flags)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    RamDacRecPtr hwp = RAMDACSCRPTR(pScrn);

    if (hwp->LoadPalette == NULL)
   	return xf86HandleColormaps(pScreen, maxColors, sigRGBbits,
			     RamDacLoadPalette, NULL, flags);
    else
    	return xf86HandleColormaps(pScreen, maxColors, sigRGBbits,
			     hwp->LoadPalette, NULL, flags);
}

--- NEW FILE: xf86RamDacMod.c ---
/*
 * 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 at fairlite.demon.co.uk>
 *
 * Generic RAMDAC module.
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacMod.c,v 1.5 1999/01/17 10:54:13 dawes Exp $ */

#include "xf86Module.h"


static XF86ModuleVersionInfo VersRec = {
	"ramdac",
	MODULEVENDORSTRING,
	MODINFOSTRING1,
	MODINFOSTRING2,
	XORG_VERSION_CURRENT,
	0, 1, 0,
	ABI_CLASS_VIDEODRV,
	ABI_VIDEODRV_VERSION,
	MOD_CLASS_NONE,
	{0, 0, 0, 0}
};

XF86ModuleData ramdacModuleData = { &VersRec, NULL, NULL };


--- NEW FILE: xf86RamDacPriv.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacPriv.h,v 1.3 1998/12/06 06:08:37 dawes Exp $ */

#include "xf86RamDac.h"
#include "xf86cmap.h"

void RamDacGetRecPrivate(void);
Bool RamDacGetRec(ScrnInfoPtr pScrn);
int  RamDacGetScreenIndex(void);
void RamDacLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
    			LOCO *colors, VisualPtr pVisual);




More information about the xserver-commit mailing list