#include "vgaHW.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xaalocal.h"
#include "cyrix.h"
#include "miline.h"
#include "xf86_libc.h"
#include "compiler.h"
#define CYRIXexpandSize 32768
static const int windowsROPpatMask[16] = { 0x0A, 0x8A, 0x4A, 0xCA,
0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA,
0x3A, 0xBA, 0x7A, 0xFA };
static const int windowsROPsrcMask[16] = { 0x22, 0xA2, 0x62, 0xE2,
0x2A, 0xAA, 0x6A, 0xEA,
0x26, 0xA6, 0x66, 0xE6,
0x2E, 0xAE, 0x6E, 0xEE };
void CYRIXAccelSync(ScrnInfoPtr pScrn);
void CYRIXSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask);
void CYRIXSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
int w, int h);
void CYRIXSetupForScreenToScreenCopy(ScrnInfoPtr, int xdir, int ydir,
int rop, unsigned int planemask, int transparency_color);
void CYRIXSubsequentScreenToScreenCopy(ScrnInfoPtr, int x1, int y1, int x2,
int y2, int w, int h);
void CYRIXSubsequentBresenhamLine(ScrnInfoPtr pScrn,int x1, int y1,
int e1, int e2, int err, int length,
int octant);
void CYRIXSetupForColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
int patterny, int rop, unsigned int planemask, int transparency_color);
void CYRIXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
int patterny, int x, int y, int w, int h);
void CYRIXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
int bg, int rop, unsigned int planemask);
void CYRIXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
int y, int w, int h, int skipleft);
void InitPixmapCache(ScreenPtr pScreen, RegionPtr areas, pointer data);
void
CYRIXAccelInit(ScreenPtr pScreen)
{
CYRIXPrvPtr pCyrix;
ScrnInfoPtr pScrn;
XAAInfoRecPtr localRecPtr;
pScrn = xf86Screens[pScreen->myNum];
pCyrix = CYRIXPTR(pScrn);
pCyrix->AccelInfoRec = localRecPtr = XAACreateInfoRec();
localRecPtr->Flags = PIXMAP_CACHE
| PW_BACKGROUND
#if 0
| HARDWARE_PATTERN_MONO_TRANSPARENCY
#endif
| HARDWARE_PATTERN_SCREEN_ORIGIN
| BIT_ORDER_IN_BYTE_MSBFIRST
| HARDWARE_PATTERN_PROGRAMMED_BITS;
localRecPtr->Sync = CYRIXAccelSync;
localRecPtr->SetupForSolidFill =
CYRIXSetupForSolidFill;
localRecPtr->SubsequentSolidFillRect =
CYRIXSubsequentSolidFillRect;
pCyrix->AccelInfoRec->PolyFillRectSolidFlags = NO_PLANEMASK;
localRecPtr->SetupForScreenToScreenCopy =
CYRIXSetupForScreenToScreenCopy;
localRecPtr->SubsequentScreenToScreenCopy =
CYRIXSubsequentScreenToScreenCopy;
pCyrix->AccelInfoRec->CopyAreaFlags = NO_PLANEMASK | GXCOPY_ONLY;
#if 0
localRecPtr->SubsequentBresenhamLine =
CYRIXSubsequentBresenhamLine;
localRecPtr->ErrorTermBits = 15;
#endif
localRecPtr->SetupForColor8x8PatternFill =
CYRIXSetupForColor8x8PatternFillRect;
localRecPtr->SubsequentColor8x8PatternFillRect =
CYRIXSubsequentColor8x8PatternFillRect;
localRecPtr->Color8x8PatternFillFlags =
BIT_ORDER_IN_BYTE_MSBFIRST | NO_PLANEMASK |
TRANSPARENCY_GXCOPY_ONLY | SCANLINE_PAD_DWORD;
localRecPtr->ColorExpandBase =
(unsigned char*)(pCyrix->GXregisters + pCyrix->CYRIXbltBuf0Address);
localRecPtr->ColorExpandRange =
pCyrix->CYRIXbltBufSize * 2;
localRecPtr->SetupForCPUToScreenColorExpandFill =
CYRIXSetupForCPUToScreenColorExpandFill;
localRecPtr->SubsequentCPUToScreenColorExpandFill =
CYRIXSubsequentCPUToScreenColorExpandFill;
pCyrix->bltBufWidth = pCyrix->CYRIXbltBufSize / (pScrn->bitsPerPixel / 8);
}
static __inline__ void CYRIXsetColors01(ScrnInfoPtr pScrn, int reg,
int col0, int col1) {
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
if (pScrn->bitsPerPixel == 16)
GX_REG(reg) = ((col1 & 0xFFFF) << 16) | (col0 & 0xFFFF);
else
{ col0 &= 0xFF;
col1 &= 0xFF;
GX_REG(reg) = (col1 << 24) | (col1 << 16) | (col0 << 8) | col0;
} }
void
CYRIXAccelSync(ScrnInfoPtr pScrn)
{
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
if (pCyrix->setBlitModeOnSync)
{ pCyrix->setBlitModeOnSync = 0;
CYRIXsetupSync();
CYRIXsetBlitMode();
}
while (GX_REG(GP_BLIT_STATUS) &
(BS_BLIT_BUSY|BS_PIPELINE_BUSY|BS_BLIT_PENDING));
}
void
CYRIXSetupForSolidFill(pScrn, color, rop, planemask)
ScrnInfoPtr pScrn;
int color, rop;
unsigned int planemask;
{
CYRIXPrvPtr pCyrix;
pCyrix = CYRIXPTR(pScrn);
if (pCyrix->AccelInfoRec->PolyFillRectSolidFlags & GXCOPY_ONLY)
rop = GXcopy;
if (pCyrix->AccelInfoRec->PolyFillRectSolidFlags & NO_PLANEMASK)
planemask = 0xFFFF;
CYRIXsetupSync();
CYRIXsetSourceColors01(pScrn, color, color);
CYRIXsetPatColors01(pScrn, planemask, 0);
CYRIXsetPatMode(rop, RM_PAT_DISABLE);
pCyrix->blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND
| IfDest(rop, planemask, BM_READ_DST_FB0);
pCyrix->vectorMode = IfDest(rop, planemask, VM_READ_DST_FB);
}
void
CYRIXSubsequentSolidFillRect(pScrn, x, y, w, h)
ScrnInfoPtr pScrn;
int x, y, w, h;
{
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
while (w > 2 * pCyrix->bltBufWidth)
{ CYRIXSubsequentSolidFillRect(pScrn, x, y,
2 * pCyrix->bltBufWidth, h);
x += 2 * pCyrix->bltBufWidth;
w -= 2 * pCyrix->bltBufWidth;
}
CYRIXsetupSync();
CYRIXsetDstXY(x, y);
CYRIXsetWH(w, h);
CYRIXsetBlitMode();
}
void
CYRIXSetupForScreenToScreenCopy(pScrn, xdir, ydir, rop,
planemask, transparency_color)
ScrnInfoPtr pScrn;
int xdir, ydir;
int rop;
unsigned int planemask;
int transparency_color;
{
CYRIXPrvPtr pCyrix;
pCyrix = CYRIXPTR(pScrn);
if (pCyrix->AccelInfoRec->CopyAreaFlags & NO_PLANEMASK)
planemask = 0xFFFF;
if (pCyrix->AccelInfoRec->CopyAreaFlags & GXCOPY_ONLY)
rop = GXcopy;
if (pCyrix->AccelInfoRec->CopyAreaFlags & NO_TRANSPARENCY)
transparency_color = -1;
CYRIXsetupSync();
CYRIXsetPatColors01(pScrn, planemask, 0);
if (transparency_color == -1)
{ CYRIXsetPatMode(rop, RM_PAT_DISABLE);
pCyrix->transMode = 0;
}
else
{ CYRIXsetPatModeTrans(RM_PAT_DISABLE);
pCyrix->transMode = 1;
if (pCyrix->AccelInfoRec->CopyAreaFlags &
TRANSPARENCY_GXCOPY_ONLY)
rop = GXcopy;
if (pScrn->bitsPerPixel == 16)
{ int k = pCyrix->CYRIXbltBufSize / 4;
CARD32 val = (transparency_color << 16) |
transparency_color;
volatile CARD32* buf = &(GX_REG(pCyrix->CYRIXbltBuf1Address));
while (--k >= 0) buf[k] = val;
}
else
memset(pCyrix->GXregisters + pCyrix->CYRIXbltBuf1Address,
transparency_color, pCyrix->CYRIXbltBufSize);
}
pCyrix->blitMode = BM_READ_SRC_FB | BM_WRITE_FB | BM_SOURCE_COLOR
| (pCyrix->transMode ? BM_READ_DST_NONE : IfDest(rop, planemask, BM_READ_DST_FB1))
| (ydir < 0 ? BM_REVERSE_Y : 0);
pCyrix->copyXdir = xdir;
}
void
CYRIXSubsequentScreenToScreenCopy(pScrn, x1, y1, x2, y2, w, h)
ScrnInfoPtr pScrn;
int x1, y1, x2, y2, w, h;
{
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
int up = (pCyrix->blitMode & BM_REVERSE_Y);
if (pCyrix->copyXdir < 0)
{ int x_offset = w - pCyrix->bltBufWidth;
while (x_offset > 0)
{ CYRIXSubsequentScreenToScreenCopy(pScrn, x1 + x_offset, y1,
x2 + x_offset, y2,
pCyrix->bltBufWidth, h);
x_offset -= pCyrix->bltBufWidth;
w -= pCyrix->bltBufWidth;
} }
else while (w > pCyrix->bltBufWidth)
{ CYRIXSubsequentScreenToScreenCopy(pScrn, x1, y1, x2, y2,
pCyrix->bltBufWidth, h);
x1 += pCyrix->bltBufWidth;
x2 += pCyrix->bltBufWidth;
w -= pCyrix->bltBufWidth;
}
CYRIXsetupSync();
CYRIXsetSrcXY(x1, (up ? (y1 + h - 1) : y1));
CYRIXsetDstXY(x2, (up ? (y2 + h - 1) : y2));
if (pCyrix->transMode)
{ pCyrix->blitMode |= BM_READ_DST_BB1;
CYRIXsetWH(w, 1);
CYRIXsetBlitMode();
h--;
if (!h) return;
if (up) { y1--; y2--; }
else { y1++; y2++; }
CYRIXsetupSync();
pCyrix->blitMode &= ~(BM_READ_DST_BB1);
}
CYRIXsetWH(w, h);
CYRIXsetBlitMode();
}
void
CYRIXSubsequentBresenhamLine(pScrn, x1, y1, e1, e2, err, length, octant)
ScrnInfoPtr pScrn; int x1, y1, octant, err, e1, e2, length;
{
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
if (octant & YMAJOR) {
pCyrix->vectorMode = (pCyrix->vectorMode & VM_READ_DST_FB) | VM_Y_MAJOR;
if (!(octant & XDECREASING)) pCyrix->vectorMode |= VM_MINOR_INC;
if (!(octant & YDECREASING)) pCyrix->vectorMode |= VM_MAJOR_INC;
} else {
pCyrix->vectorMode = (pCyrix->vectorMode & VM_READ_DST_FB) | VM_X_MAJOR;
if (!(octant & XDECREASING)) pCyrix->vectorMode |= VM_MAJOR_INC;
if (!(octant & YDECREASING)) pCyrix->vectorMode |= VM_MINOR_INC;
}
CYRIXsetupSync();
CYRIXsetDstXY(x1, y1);
CYRIXsetWH(length, (err & 0xFFFF));
CYRIXsetSrcXY((e1 & 0xFFFF), (e2 & 0xFFFF));
CYRIXsetVectorMode();
}
void CYRIXSetupForColor8x8PatternFillRect(pScrn, patternx, patterny,
rop, planemask, transparency_color)
ScrnInfoPtr pScrn;
int patternx, patterny;
int rop, transparency_color;
unsigned int planemask;
{
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
XAAInfoRecPtr localRecPtr = pCyrix->AccelInfoRec;
if (localRecPtr->Color8x8PatternFillFlags & NO_PLANEMASK)
planemask = 0xFFFF;
if ((transparency_color == -1) && (localRecPtr->Color8x8PatternFillFlags &
TRANSPARENCY_GXCOPY_ONLY))
rop = GXcopy;
CYRIXsetupSync();
CYRIXsetPatColors01(pScrn, (transparency_color == -1) ?
0 : transparency_color, planemask);
CYRIXsetPatData(patternx, patterny);
CYRIXsetPatModeX(rop, RM_PAT_MONO | ((transparency_color == -1) ?
RM_PAT_TRANSPARENT : 0));
pCyrix->blitMode = BM_READ_SRC_NONE | BM_WRITE_FB | BM_SOURCE_EXPAND |
((transparency_color == -1) ?
IfDest(rop, planemask, BM_READ_DST_FB0) : BM_READ_DST_NONE);
}
void CYRIXSubsequentColor8x8PatternFillRect(pScrn, patternx, patterny, x, y, w, h)
ScrnInfoPtr pScrn;
int patternx, patterny;
int x, y, w, h;
{ CYRIXSubsequentSolidFillRect(pScrn, x, y, w, h);
}
void CYRIXSetupForCPUToScreenColorExpandFill(pScrn, fg, bg, rop, planemask)
ScrnInfoPtr pScrn;
int bg, fg, rop;
unsigned int planemask;
{
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
XAAInfoRecPtr localRecPtr = pCyrix->AccelInfoRec;
int trans = (bg == -1);
if (trans && (localRecPtr->CPUToScreenColorExpandFillFlags &
TRANSPARENCY_GXCOPY_ONLY))
rop = GXcopy;
CYRIXsetupSync();
CYRIXsetSourceColors01(pScrn, trans ? 0 : bg, fg);
CYRIXsetPatColors01(pScrn, planemask, 0);
CYRIXsetPatMode(rop, RM_PAT_DISABLE | (trans ? RM_SRC_TRANSPARENT : 0));
pCyrix->blitMode = BM_READ_SRC_BB0 | BM_WRITE_FB | BM_SOURCE_EXPAND
| (trans ? IfDest(rop, planemask, BM_READ_DST_FB1) : BM_READ_DST_NONE);
}
void CYRIXSubsequentCPUToScreenColorExpandFill(pScrn, x, y, w, h, skipleft)
ScrnInfoPtr pScrn;
int x, y, w, h;
int skipleft;
{
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
CYRIXsetupSync();
CYRIXsetSrcXY(0, 0);
CYRIXsetDstXY(x, y);
CYRIXsetWH(w, h);
CYRIXAccelSync(pScrn);
pCyrix->setBlitModeOnSync = 1;
}