static void 
XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 
					   int patternx, int patterny, 
					   int fg, int bg, int rop,
					   unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = 0;

    REPLICATE(fg);
    MMIO_OUT32(pTrident->IOBase, 0x2158, fg);

    if (bg == -1) {
	drawflag |= 1<<12;
   	MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg);
    } else {
    	REPLICATE(bg);
   	MMIO_OUT32(pTrident->IOBase, 0x215C, bg);
    }

    drawflag |= 7<<18;
    TGUI_DRAWFLAG(PATMONO | drawflag);
    MMIO_OUT32(pTrident->IOBase, 0x2180, patternx);
    MMIO_OUT32(pTrident->IOBase, 0x2184, patterny);
    TGUI_FMIX(XAAPatternROP[rop]);
}
static void
TridentClearSync(ScrnInfoPtr pScrn)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int count = 0, timeout = 0;
    int busy;

    for (;;) {
	BLTBUSY(busy);
	if (busy != GE_BUSY) {
	    return;
	}
	count++;
	if (count == 10000000) {
	    ErrorF("Trident: BitBLT engine time-out.\n");
	    count = 9990000;
	    timeout++;
	    if (timeout == 8) {
		/* Reset BitBLT Engine */
		TGUI_STATUS(0x00);
		return;
	    }
	}
    }
}
static void
TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 
				int xdir, int ydir, int rop,
				unsigned int planemask, int transparency_color)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int dst = 0;

    pTrident->BltScanDirection = 0;
    if (xdir < 0) pTrident->BltScanDirection |= XNEG;
    if (ydir < 0) pTrident->BltScanDirection |= YNEG;

    REPLICATE(transparency_color);
    if (transparency_color != -1) {
	if (pTrident->Chipset == PROVIDIA9685 ||
	    pTrident->Chipset == CYBER9388) {
	    dst |= 1<<16;
	} else {
    	    TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
	}
	TGUI_CKEY(transparency_color);
    }

    TGUI_DRAWFLAG(pTrident->DrawFlag | pTrident->BltScanDirection | SCR2SCR | dst);
    TGUI_FMIX(XAAGetCopyROP(rop));
}
static void
XPInitializeAccelerator(ScrnInfoPtr pScrn)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int shift;

    /* This forces updating the clipper */
    pTrident->Clipping = TRUE;

    CHECKCLIPPING;

    BLADE_XP_OPERMODE(pTrident->EngineOperation);
    pTrident->EngineOperation |= 0x40;
    switch (pScrn->bitsPerPixel) {
	case 8:
	default:		/* Muffle compiler */
		shift = 18;
		break;
	case 16:
		shift = 19;
		break;
	case 32:
		shift = 20;
		break;
    }
    MMIO_OUT32(pTrident->IOBase, 0x2154, (pScrn->displayWidth) << shift);
    MMIO_OUT32(pTrident->IOBase, 0x2150, (pScrn->displayWidth) << shift);
    MMIO_OUT8(pTrident->IOBase, 0x2126, 3);
}
static void
XPSync(ScrnInfoPtr pScrn)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int count = 0, timeout = 0;
    int busy;

    BLADE_XP_OPERMODE(pTrident->EngineOperation);

    for (;;) {
	BLTBUSY(busy);
	if (busy != GE_BUSY) {
	    return;
	}
	count++;
	if (count == 10000000) {
	    ErrorF("XP: BitBLT engine time-out.\n");
	    count = 9990000;
	    timeout++;
	    if (timeout == 8) {
		/* Reset BitBLT Engine */
		TGUI_STATUS(0x00);
		return;
	    }
	}
    }
}
static void
XP4SetupForCPUToScreenColorExpandFill(
	ScrnInfoPtr pScrn,
	int fg, int bg, 
	int rop, 
	unsigned int planemask
){
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    ropcode = XAAGetCopyROP(rop);
#if 0
    TGUI_FMIX(XAACopyROP[rop]);
#endif
    if (bg == -1) {
    TGUI_DRAWFLAG(SRCMONO | 1<<12);
    	REPLICATE(fg);
	TGUI_FCOLOUR(fg);
    } else { 
    TGUI_DRAWFLAG(SRCMONO);
    	REPLICATE(fg);
    	REPLICATE(bg);
	TGUI_FCOLOUR(fg);
	TGUI_BCOLOUR(bg);
    }
}
static void 
TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, 
					   int patternx, int patterny, 
					   int rop,
					   unsigned int planemask,
					   int transparency_color)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = 0;

    REPLICATE(transparency_color);
    if (transparency_color != -1) {
    	if (pTrident->Chipset == PROVIDIA9685 ||
            pTrident->Chipset == CYBER9388) {
	    drawflag |= 1<<16;
	} else {
    	    TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
	}
	TGUI_CKEY(transparency_color);
    }

    TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | drawflag);
    TGUI_PATLOC(((patterny * pTrident->PatternLocation) +
		 (patternx * pScrn->bitsPerPixel / 8)) >> 6);
    TGUI_FMIX(XAAGetPatternROP(rop));
}
static void smbus_write(ScrnInfoPtr pScrn, unsigned char bData, unsigned char bIndex, unsigned char devAdr)
{
    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
    unsigned short i;

    /* clear host status */
    OUTB(SMBUS_BASE, 0xFF);

    /* check SMBUS ready */
    for ( i = 0; i < 0xFFFF; i++ )
        if ( (INB(SMBUS_BASE) & 0x01) == 0 )
           break;

    OUTB(SMBUS_BASE+2, 0x08);

    /* set host command */
    OUTB(SMBUS_BASE+3, bIndex);

    /* set slave address */
    OUTB(SMBUS_BASE+4, devAdr & 0xFE);

    OUTB(SMBUS_BASE+5, bData);

    /* start */
    OUTB(SMBUS_BASE+2, 0x48);

    /* SMBUS Wait Ready */
    for ( i = 0; i < 0xFFFF; i++ )
    if ( (INB(SMBUS_BASE) & 0x01) == 0 )
       break;
}
static unsigned char smbus_read(ScrnInfoPtr pScrn, unsigned char bIndex, unsigned char devAdr)
{
    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
    unsigned short i;
    unsigned char  bData;

    /* clear host status */
    OUTB(SMBUS_BASE, 0xFF);

    /* check SMBUS ready */
    for ( i = 0; i < 0xFFFF; i++ )
        if ( (INB(SMBUS_BASE) & 0x01) == 0 )
            break;

    /* set host command */
    OUTB(SMBUS_BASE+3, bIndex);

    /* set slave address */
    OUTB(SMBUS_BASE+4, devAdr | 0x01);

    /* start */
    OUTB(SMBUS_BASE+2, 0x48);

    /* SMBUS Wait Ready */
    for ( i = 0; i < 0xFFFF; i++ )
        if ( (INB(SMBUS_BASE) & 0x01) == 0 )
            break;
    bData=INB(SMBUS_BASE+5);

    return bData;

}
static void
TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    TGUI_DIM_XY(w,h);
    TGUI_DEST_XY(x,y);
    TGUI_COMMAND(GE_BLT);
    TridentSync(pScrn);
}
static void
XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    
    MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y);
    MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h);
    XP4Sync(pScrn);
    MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetPatternROP(ropcode) << 24 | bpp << 8 | 2);
}
static void
XPSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, 
				    int rop, unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    REPLICATE(color);
    TGUI_FMIX(XAAPatternROP[rop]);
    MMIO_OUT32(pTrident->IOBase, 0x2158, color);
    TGUI_DRAWFLAG(SOLIDFILL);
}
static void
XP4SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, 
				    int rop, unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
    ropcode = rop;

    REPLICATE(color);
    MMIO_OUT32(pTrident->IOBase, 0x2158, color);
    MMIO_OUT32(pTrident->IOBase, 0x2128, 1<<14);
}
static void 
TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, 	
				   int patternx, int patterny,
				   int x, int y,
				   int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
  
    TGUI_DEST_XY(x,y);
    TGUI_DIM_XY(w,h);
    TGUI_COMMAND(GE_BLT);
    TridentClearSync(pScrn);
}
static void
XP4SubsequentCPUToScreenColorExpandFill(
	ScrnInfoPtr pScrn,
	int x, int y, int w, int h,
	int skipleft
){
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y);
    MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h);
    XP4Sync(pScrn);
    MMIO_OUT32(pTrident->IOBase, 0x2124, ropcode << 24 | bpp << 8 | 2);
}
static void
XPSubsequentScanlineCPUToScreenColorExpandFill(
	ScrnInfoPtr pScrn,
	int x, int y, int w, int h,
	int skipleft
){
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    pTrident->dwords = (w + 31) >> 5;
    pTrident->h = h;

    XP_DEST_XY(x,y);
    XP_DIM_XY(w>>1,h);
    TGUI_COMMAND(GE_BLT);
}
static void
XPSetupForSolidLine(ScrnInfoPtr pScrn, int color,
					 int rop, unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    pTrident->BltScanDirection = 0;
    REPLICATE(color);
    TGUI_FMIX(XAAPatternROP[rop]);
    if (pTrident->Chipset >= PROVIDIA9685) {
    	TGUI_FPATCOL(color);
    } else {
    	TGUI_FCOLOUR(color);
    }
}
static void
XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    XAAInfoRecPtr infoRec;
    infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    MoveDWORDS_FixedBase((CARD32 *)pTrident->IOBase + 0x2160,
		(CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0], 
			pTrident->dwords);

    pTrident->h--;
    if (pTrident->h)
    	XPSync(pScrn);
}
static void
TridentSubsequentScanlineCPUToScreenColorExpandFill(
	ScrnInfoPtr pScrn,
	int x, int y, int w, int h,
	int skipleft
){
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    pTrident->dwords = (w + 31) >> 5;
    pTrident->h = h;
    pTrident->y = y;
    pTrident->x = x;
    pTrident->w = w;

    TGUI_DEST_XY(x,pTrident->y++);
    TGUI_DIM_XY(w,1);
    TGUI_COMMAND(GE_BLT);
}
static void 
TridentSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
        int x, int y, int dmaj, int dmin, int e, int len, int octant)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int tmp = pTrident->BltScanDirection;

    if (octant & YMAJOR) tmp |= YMAJ;
    if (octant & XDECREASING) tmp |= XNEG;
    if (octant & YDECREASING) tmp |= YNEG;
    TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | STENCIL | tmp);
    TGUI_SRC_XY(dmin-dmaj,dmin);
    TGUI_DEST_XY(x,y);
    TGUI_DIM_XY(dmin+e,len);
    TGUI_COMMAND(GE_BRESLINE);
    TridentSync(pScrn);
}
static void
TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, 
				    int rop, unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = 0;

    REPLICATE(color);
    TGUI_FMIX(XAAGetPatternROP(rop));
    if (pTrident->Chipset == PROVIDIA9685 ||
        pTrident->Chipset == CYBER9388) {
    	TGUI_FPATCOL(color);
    } else {
    	drawflag |= PATMONO;
    	TGUI_FCOLOUR(color);
    }
    TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | drawflag);
}
void
TridentSetupForDashedLine(
    ScrnInfoPtr pScrn, 
    int fg, int bg, int rop,
    unsigned int planemask,
    int length,
    unsigned char *pattern
){
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    CARD32 *DashPattern = (CARD32*)pattern;
    CARD32 NiceDashPattern = DashPattern[0];

    NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1);
    switch(length) {
	case 2:	NiceDashPattern |= NiceDashPattern << 2;
	case 4:	NiceDashPattern |= NiceDashPattern << 4;
	case 8:	NiceDashPattern |= NiceDashPattern << 8;
    }
    pTrident->BltScanDirection = 0;
    REPLICATE(fg);
    if (pTrident->Chipset == PROVIDIA9685 ||
        pTrident->Chipset == CYBER9388) {
	TGUI_FPATCOL(fg);
    	if (bg == -1) {
	    pTrident->BltScanDirection |= 1<<12;
    	    TGUI_BPATCOL(~fg);
    	} else {
    	    REPLICATE(bg);
    	    TGUI_BPATCOL(bg);
    	}
    } else {
    	TGUI_FCOLOUR(fg);
    	if (bg == -1) {
	    pTrident->BltScanDirection |= 1<<12;
    	    TGUI_BCOLOUR(~fg);
    	} else {
    	    REPLICATE(bg);
    	    TGUI_BCOLOUR(bg);
    	}
    }
    TGUI_FMIX(XAAGetPatternROP(rop));
    pTrident->LinePattern = NiceDashPattern;
}
static void 
TridentSubsequentSolidHorVertLine(
    ScrnInfoPtr pScrn,
    int x, int y, 
    int len, int dir
){
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL);
    if (dir == DEGREES_0) {
    	TGUI_DIM_XY(len,1);
    	TGUI_DEST_XY(x,y);
    } else {
    	TGUI_DIM_XY(1,len);
    	TGUI_DEST_XY(x,y);
    }
    TGUI_COMMAND(GE_BLT);
    TridentSync(pScrn);
}
static void
TridentInitializeAccelerator(ScrnInfoPtr pScrn)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    /* This forces updating the clipper */
    pTrident->Clipping = TRUE;

    CHECKCLIPPING;

    if ( (pTrident->Chipset == PROVIDIA9682) ||
         (pTrident->Chipset == CYBER9385) ||
         (pTrident->Chipset == CYBER9382) ) 
    	pTrident->EngineOperation |= 0x100; /* Disable Clipping */

    TGUI_OPERMODE(pTrident->EngineOperation);

    pTrident->PatternLocation = pScrn->displayWidth*pScrn->bitsPerPixel/8;
}
static void
TridentSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    XAAInfoRecPtr infoRec;
    infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    MoveDWORDS((CARD32 *)pTrident->FbBase, 
		(CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0], 
			pTrident->dwords);

    pTrident->h--;
    TridentSync(pScrn);
    if (pTrident->h) {
    	TGUI_DEST_XY(pTrident->x,pTrident->y++);
    	TGUI_DIM_XY(pTrident->w,1);
    	TGUI_COMMAND(GE_BLT);
    }
}
static void
XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
					int x2, int y2, int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    if (pTrident->BltScanDirection & YNEG) {
        y1 = y1 + h - 1;
	y2 = y2 + h - 1;
    }
    if (pTrident->BltScanDirection & XNEG) {
	x1 = x1 + w - 1;
	x2 = x2 + w - 1;
    }
    MMIO_OUT32(pTrident->IOBase, 0x2138, x2<<16 | y2);
    MMIO_OUT32(pTrident->IOBase, 0x213C, x1<<16 | y1);
    MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h);
    XP4Sync(pScrn);
    MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetCopyROP(ropcode) << 24 | bpp << 8 | 1);
}
static void
TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
					int x2, int y2, int w, int h)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);

    if (pTrident->BltScanDirection & YNEG) {
        y1 = y1 + h - 1;
	y2 = y2 + h - 1;
    }
    if (pTrident->BltScanDirection & XNEG) {
	x1 = x1 + w - 1;
	x2 = x2 + w - 1;
    }
    TGUI_SRC_XY(x1,y1);
    TGUI_DEST_XY(x2,y2);
    TGUI_DIM_XY(w,h);
    TGUI_COMMAND(GE_BLT);
    TridentClearSync(pScrn);
}
void
TridentSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
        int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int tmp = pTrident->BltScanDirection;

    if (octant & YMAJOR) tmp |= YMAJ;
    if (octant & XDECREASING) tmp |= XNEG;
    if (octant & YDECREASING) tmp |= YNEG;

    TGUI_STYLE(((pTrident->LinePattern >> phase) | 
		(pTrident->LinePattern << (16-phase))) & 0x0000FFFF);
    TGUI_DRAWFLAG(pTrident->DrawFlag | STENCIL | tmp);
    TGUI_SRC_XY(dmin-dmaj,dmin);
    TGUI_DEST_XY(x,y);
    TGUI_DIM_XY(e+dmin,len);
    TGUI_COMMAND(GE_BRESLINE);
    TridentSync(pScrn);
}
static void 
TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 
					   int patternx, int patterny, 
					   int fg, int bg, int rop,
					   unsigned int planemask)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int drawflag = 0;

    REPLICATE(fg);
    if (pTrident->Chipset == PROVIDIA9685 ||
        pTrident->Chipset == CYBER9388)
    	TGUI_FPATCOL(fg);
    else
    	TGUI_FCOLOUR(fg);

    if (bg == -1) {
	drawflag |= 1<<12;
    	if (pTrident->Chipset == PROVIDIA9685 ||
            pTrident->Chipset == CYBER9388) 
    	    TGUI_BPATCOL(~fg);
	else
    	    TGUI_BCOLOUR(~fg);
    } else {
    	REPLICATE(bg);
    	if (pTrident->Chipset == PROVIDIA9685 ||
            pTrident->Chipset == CYBER9388) 
    	    TGUI_BPATCOL(bg);
	else
    	    TGUI_BCOLOUR(bg);
    }

    if (pTrident->Chipset == PROVIDIA9685 ||
        pTrident->Chipset == CYBER9388) {
	drawflag |= 7<<18;
    }
    TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | PATMONO | drawflag);
    TGUI_PATLOC(((patterny * pTrident->PatternLocation) +
		 (patternx * pScrn->bitsPerPixel / 8)) >> 6);
    TGUI_FMIX(XAAGetPatternROP(rop));
}
static void
XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 
				int xdir, int ydir, int rop,
				unsigned int planemask, int transparency_color)
{
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    int dst = 0;

    pTrident->BltScanDirection = 0;
    if (xdir < 0) pTrident->BltScanDirection |= XNEG;
    if (ydir < 0) pTrident->BltScanDirection |= YNEG;

    REPLICATE(transparency_color);
    if (transparency_color != -1) {
	dst |= 3<<16;
    	MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color);
    }

    TGUI_DRAWFLAG(pTrident->BltScanDirection | SCR2SCR | dst);
    TGUI_FMIX(XAACopyROP[rop]);
}