#include "tseng.h"
#include "tseng_acl.h"
#include "tseng_inline.h"
void TsengSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg, int rop, unsigned int planemask);
void TsengSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int srcx, int srcy, int skipleft);
void TsengSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft);
void TsengSubsequentColorExpandScanline(ScrnInfoPtr pScrn,
int bufno);
void TsengSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg, int rop, unsigned int planemask);
void TsengSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft);
void TsengSubsequentColorExpandScanline_8bpp(ScrnInfoPtr pScrn, int bufno);
void TsengSubsequentColorExpandScanline_16bpp(ScrnInfoPtr pScrn, int bufno);
void TsengSubsequentColorExpandScanline_24bpp(ScrnInfoPtr pScrn, int bufno);
void TsengSubsequentColorExpandScanline_32bpp(ScrnInfoPtr pScrn, int bufno);
Bool
TsengXAAInit_Colexp(ScrnInfoPtr pScrn)
{
int i, j, r;
TsengPtr pTseng = TsengPTR(pScrn);
XAAInfoRecPtr pXAAInfo = pTseng->AccelInfoRec;
PDEBUG(" TsengXAAInit_Colexp\n");
#ifdef TODO
if (OFLG_ISSET(OPTION_XAA_NO_COL_EXP, &vga256InfoRec.options))
return;
#endif
pXAAInfo->ScreenToScreenColorExpandFillFlags =
BIT_ORDER_IN_BYTE_LSBFIRST |
SCANLINE_PAD_DWORD |
LEFT_EDGE_CLIPPING |
NO_PLANEMASK;
#if 1
if (Is_ET6K || (Is_W32p && (pScrn->bitsPerPixel == 8))) {
pXAAInfo->SetupForScreenToScreenColorExpandFill =
TsengSetupForScreenToScreenColorExpandFill;
pXAAInfo->SubsequentScreenToScreenColorExpandFill =
TsengSubsequentScreenToScreenColorExpandFill;
}
#endif
pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags =
BIT_ORDER_IN_BYTE_LSBFIRST |
SCANLINE_PAD_DWORD |
NO_PLANEMASK;
#if 1
if (!Is_ET6K) {
pTseng->XAAScanlineColorExpandBuffers[0] =
xnfalloc(((pScrn->virtualX + 31)/32) * 4 * pTseng->Bytesperpixel);
if (pTseng->XAAScanlineColorExpandBuffers[0] == NULL) {
xf86Msg(X_ERROR, "Could not malloc color expansion scanline buffer.\n");
return FALSE;
}
pXAAInfo->NumScanlineColorExpandBuffers = 1;
pXAAInfo->ScanlineColorExpandBuffers = pTseng->XAAScanlineColorExpandBuffers;
pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
TsengSetupForCPUToScreenColorExpandFill;
pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
TsengSubsequentScanlineCPUToScreenColorExpandFill;
switch (pScrn->bitsPerPixel) {
case 8:
pXAAInfo->SubsequentColorExpandScanline =
TsengSubsequentColorExpandScanline_8bpp;
break;
case 15:
case 16:
pXAAInfo->SubsequentColorExpandScanline =
TsengSubsequentColorExpandScanline_16bpp;
break;
case 24:
pXAAInfo->SubsequentColorExpandScanline =
TsengSubsequentColorExpandScanline_24bpp;
break;
case 32:
pXAAInfo->SubsequentColorExpandScanline =
TsengSubsequentColorExpandScanline_32bpp;
break;
}
pTseng->ColExpLUT = xnfalloc(sizeof(CARD32)*256);
if (pTseng->ColExpLUT == NULL) {
xf86Msg(X_ERROR, "Could not malloc color expansion tables.\n");
return FALSE;
}
for (i = 0; i < 256; i++) {
r = 0;
for (j = 7; j >= 0; j--) {
r <<= pTseng->Bytesperpixel;
if ((i >> j) & 1)
r |= (1 << pTseng->Bytesperpixel) - 1;
}
pTseng->ColExpLUT[i] = r;
}
}
#endif
#if 1
if (Is_ET6K) {
pXAAInfo->NumScanlineColorExpandBuffers = 3;
pXAAInfo->ScanlineColorExpandBuffers =
pTseng->XAAColorExpandBuffers;
pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
TsengSetupForScreenToScreenColorExpandFill;
pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
TsengSubsequentScanlineCPUToScreenColorExpandFill;
pXAAInfo->SubsequentColorExpandScanline =
TsengSubsequentColorExpandScanline;
for (i = 0; i < pXAAInfo->NumScanlineColorExpandBuffers; i++) {
pTseng->XAAColorExpandBuffers[i] =
pTseng->FbBase + pTseng->AccelColorExpandBufferOffsets[i];
}
if (!pTseng->UseLinMem) {
for (i = 0; i < pXAAInfo->NumScanlineColorExpandBuffers; i++) {
pTseng->XAAColorExpandBuffers[i] =
pTseng->XAAColorExpandBuffers[i]
- pTseng->AccelColorExpandBufferOffsets[0]
+ 0x18000 + 48;
}
}
pXAAInfo->ScanlineColorExpandBuffers = pTseng->XAAColorExpandBuffers;
}
#endif
#ifdef TSENG_CPU_TO_SCREEN_COLOREXPAND
pXAAInfo->CPUToScreenColorExpandFillFlags =
BIT_ORDER_IN_BYTE_LSBFIRST |
SCANLINE_PAD_DWORD |
CPU_TRANSFER_PAD_DWORD |
NO_PLANEMASK;
if (Is_W32_any && (pScrn->bitsPerPixel == 8)) {
pXAAInfo->SetupForCPUToScreenColorExpandFill =
TsengSetupForCPUToScreenColorExpandFill;
pXAAInfo->SubsequentCPUToScreenColorExpandFill =
TsengSubsequentCPUToScreenColorExpandFill;
pXAAInfo->ColorExpandBase = (CARD8 *)pTseng->tsengCPU2ACLBase;
pXAAInfo->ColorExpandRange = 8192;
}
#endif
return TRUE;
}
#define SET_FUNCTION_COLOREXPAND \
if (Is_ET6K) \
ACL_MIX_CONTROL(0x32); \
else \
ACL_ROUTING_CONTROL(0x08);
#define SET_FUNCTION_COLOREXPAND_CPU \
ACL_ROUTING_CONTROL(0x02);
void
TsengSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft)
{
TsengPtr pTseng = TsengPTR(pScrn);
if (!Is_ET6K) {
pTseng->acl_colexp_width_dwords = (MULBPP(pTseng, w) + 31) >> 5;
pTseng->acl_colexp_width_bytes = (MULBPP(pTseng, w) + 7) >> 3;
}
pTseng->acl_ColorExpandDst = FBADDR(pTseng, x, y);
pTseng->acl_skipleft = skipleft;
wait_acl_queue(pTseng);
#if 0
ACL_MIX_Y_OFFSET(w - 1);
ErrorF(" W=%d", w);
#endif
SET_XY(pTseng, w, 1);
}
void
TsengSubsequentColorExpandScanline(ScrnInfoPtr pScrn,
int bufno)
{
TsengPtr pTseng = TsengPTR(pScrn);
wait_acl_queue(pTseng);
ACL_MIX_ADDRESS((pTseng->AccelColorExpandBufferOffsets[bufno] << 3) + pTseng->acl_skipleft);
START_ACL(pTseng, pTseng->acl_ColorExpandDst);
pTseng->acl_ColorExpandDst += pTseng->line_width;
}
void TsengSubsequentColorExpandScanline_8bpp(ScrnInfoPtr pScrn, int bufno)
{
TsengPtr pTseng = TsengPTR(pScrn);
pointer dest = pTseng->tsengCPU2ACLBase;
int i,j;
CARD8 *bufptr;
i = pTseng->acl_colexp_width_bytes;
bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
wait_acl_queue(pTseng);
START_ACL (pTseng, pTseng->acl_ColorExpandDst);
j = 0;
while (i--) {
MMIO_OUT8(dest,j++, *bufptr++);
}
pTseng->acl_ColorExpandDst += pTseng->line_width;
}
void TsengSubsequentColorExpandScanline_16bpp(ScrnInfoPtr pScrn, int bufno)
{
TsengPtr pTseng = TsengPTR(pScrn);
pointer dest = pTseng->tsengCPU2ACLBase;
int i,j;
CARD8 *bufptr;
register CARD32 bits16;
i = pTseng->acl_colexp_width_dwords * 2;
bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
wait_acl_queue(pTseng);
START_ACL(pTseng, pTseng->acl_ColorExpandDst);
j = 0;
while (i--) {
bits16 = pTseng->ColExpLUT[*bufptr++];
MMIO_OUT8(dest,j++,bits16 & 0xFF);
MMIO_OUT8(dest,j++,(bits16 >> 8) & 0xFF);
}
pTseng->acl_ColorExpandDst += pTseng->line_width;
}
void TsengSubsequentColorExpandScanline_24bpp(ScrnInfoPtr pScrn, int bufno)
{
TsengPtr pTseng = TsengPTR(pScrn);
pointer dest = pTseng->tsengCPU2ACLBase;
int i, k, j = -1;
CARD8 *bufptr;
register CARD32 bits24;
i = pTseng->acl_colexp_width_dwords * 4;
bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
wait_acl_queue(pTseng);
START_ACL(pTseng, pTseng->acl_ColorExpandDst);
bits24 = pTseng->ColExpLUT[*bufptr++];
k = 0;
while (i--) {
if ((j++) == 2) {
j = 0;
bits24 = pTseng->ColExpLUT[*bufptr++];
}
MMIO_OUT8(dest,k++,bits24 & 0xFF);
bits24 >>= 8;
}
pTseng->acl_ColorExpandDst += pTseng->line_width;
}
void TsengSubsequentColorExpandScanline_32bpp(ScrnInfoPtr pScrn, int bufno)
{
TsengPtr pTseng = TsengPTR(pScrn);
pointer dest = pTseng->tsengCPU2ACLBase;
int i,j;
CARD8 *bufptr;
register CARD32 bits32;
i = pTseng->acl_colexp_width_dwords;
bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
wait_acl_queue(pTseng);
START_ACL(pTseng, pTseng->acl_ColorExpandDst);
j = 0;
while (i--) {
bits32 = pTseng->ColExpLUT[*bufptr++];
MMIO_OUT8(dest,j++,bits32 & 0xFF);
MMIO_OUT8(dest,j++,(bits32 >> 8) & 0xFF);
MMIO_OUT8(dest,j++,(bits32 >> 16) & 0xFF);
MMIO_OUT8(dest,j++,(bits32 >> 24) & 0xFF);
}
pTseng->acl_ColorExpandDst += pTseng->line_width;
}
void TsengSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg, int rop, unsigned int planemask)
{
TsengPtr pTseng = TsengPTR(pScrn);
PINGPONG(pTseng);
wait_acl_queue(pTseng);
SET_FG_ROP(rop);
SET_BG_ROP_TR(rop, bg);
SET_XYDIR(0);
SET_FG_BG_COLOR(pTseng, fg, bg);
SET_FUNCTION_COLOREXPAND_CPU;
ACL_MIX_ADDRESS(0);
}
void TsengSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft)
{
TsengPtr pTseng = TsengPTR(pScrn);
int destaddr = FBADDR(pTseng, x, y);
if (skipleft)
ErrorF("Can't do: Skipleft = %d\n", skipleft);
ErrorF("=========WAIT FIXME!\n");
WAIT_INTERFACE;
ACL_MIX_Y_OFFSET(w - 1);
SET_XY(pTseng, w, h);
START_ACL(pTseng, destaddr);
}
void
TsengSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg, int rop, unsigned int planemask)
{
TsengPtr pTseng = TsengPTR(pScrn);
PINGPONG(pTseng);
wait_acl_queue(pTseng);
SET_FG_ROP(rop);
SET_BG_ROP_TR(rop, bg);
SET_FG_BG_COLOR(pTseng, fg, bg);
SET_FUNCTION_COLOREXPAND;
SET_XYDIR(0);
}
void
TsengSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int srcx, int srcy, int skipleft)
{
TsengPtr pTseng = TsengPTR(pScrn);
int destaddr = FBADDR(pTseng, x, y);
wait_acl_queue(pTseng);
SET_XY(pTseng, w, h);
ACL_MIX_ADDRESS(
(((srcy * pScrn->displayWidth) + srcx) * pScrn->bitsPerPixel) + skipleft);
ACL_MIX_Y_OFFSET(pTseng->line_width << 3);
START_ACL(pTseng, destaddr);
}