117a48c7cSmrg 217a48c7cSmrg#ifdef HAVE_CONFIG_H 317a48c7cSmrg#include "config.h" 417a48c7cSmrg#endif 517a48c7cSmrg 617a48c7cSmrg#define FASTER 717a48c7cSmrg#ifndef PSZ 817a48c7cSmrg#define PSZ 8 917a48c7cSmrg#endif 100dd80ee0Smrg 1117a48c7cSmrg#if PSZ == 24 1217a48c7cSmrg# define APM_SUFF_24 "24" 130dd80ee0Smrg# define A(s) Apm##s##24 1417a48c7cSmrg#else 1517a48c7cSmrg# define APM_SUFF_24 "" 160dd80ee0Smrg# define A(s) Apm##s 1717a48c7cSmrg#endif 180dd80ee0Smrg#define DPRINTNAME(s) do { xf86DrvMsgVerb(pScrn->pScreen->myNum, X_NOTICE, 6, "Apm" #s APM_SUFF_24 "\n"); } while (0) 1917a48c7cSmrg 2017a48c7cSmrg#if PSZ == 24 2117a48c7cSmrg#undef SETSOURCEXY 2217a48c7cSmrg#undef SETDESTXY 2317a48c7cSmrg#undef SETWIDTH 2417a48c7cSmrg#undef SETWIDTHHEIGHT 2517a48c7cSmrg#undef UPDATEDEST 2617a48c7cSmrg#define SETSOURCEXY(x,y) do { int off = ((((y) & 0xFFFF) * pApm->CurrentLayout.displayWidth + ((x) & 0x3FFF)) * 3); SETSOURCEOFF(((off & 0xFFF000) << 4) | (off & 0xFFF)); break;} while(1) 2717a48c7cSmrg#define SETDESTXY(x,y) do { int off = ((((y) & 0xFFFF) * pApm->CurrentLayout.displayWidth + ((x) & 0x3FFF)) * 3); SETDESTOFF(((off & 0xFFF000) << 4) | (off & 0xFFF)); break;} while(1) 2817a48c7cSmrg#define SETWIDTH(w) WRXW(0x58, ((w) & 0x3FFF) * 3) 2917a48c7cSmrg#define SETWIDTHHEIGHT(w,h) WRXL(0x58, ((h) << 16) | (((w) & 0x3FFF) * 3)) 3017a48c7cSmrg#define UPDATEDEST(x,y) (void)(curr32[0x54 / 4] = ((((y) & 0xFFFF) * pApm->CurrentLayout.displayWidth + ((x) & 0xFFFF)) * 3)) 3117a48c7cSmrg#endif 3217a48c7cSmrg 3317a48c7cSmrg/* Defines */ 3417a48c7cSmrg#define MAXLOOP 1000000 3517a48c7cSmrg 3617a48c7cSmrg 3717a48c7cSmrg/* Local functions */ 3817a48c7cSmrgstatic void A(Sync)(ScrnInfoPtr pScrn); 3917a48c7cSmrgstatic void A(SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop, 4017a48c7cSmrg unsigned int planemask); 4117a48c7cSmrgstatic void A(SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, 4217a48c7cSmrg int w, int h); 4317a48c7cSmrgstatic void A(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir, 4417a48c7cSmrg int rop, unsigned int planemask, 4517a48c7cSmrg int transparency_color); 4617a48c7cSmrgstatic void A(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int x1, int y1, 4717a48c7cSmrg int x2, int y2, int w, int h); 4817a48c7cSmrg#if PSZ != 24 4917a48c7cSmrgstatic void A(Sync6422)(ScrnInfoPtr pScrn); 5017a48c7cSmrgstatic void A(WriteBitmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h, 5117a48c7cSmrg unsigned char *src, int srcwidth, int skipleft, 5217a48c7cSmrg int fg, int bg, int rop, unsigned int planemask); 5317a48c7cSmrgstatic void A(TEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int w, int h, 5417a48c7cSmrg int skipleft, int startline, 5517a48c7cSmrg unsigned int **glyphs, int glyphWidth, 5617a48c7cSmrg int fg, int bg, int rop, unsigned planemask); 5717a48c7cSmrgstatic void A(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty, 5817a48c7cSmrg int fg, int bg, int rop, 5917a48c7cSmrg unsigned int planemask); 6017a48c7cSmrgstatic void A(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx, 6117a48c7cSmrg int paty, int x, int y, 6217a48c7cSmrg int w, int h); 6317a48c7cSmrg#if 0 6417a48c7cSmrgstatic void A(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int bg, int fg, int rop, unsigned int planemask); 6517a48c7cSmrgstatic void A(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); 6617a48c7cSmrg#endif 6717a48c7cSmrgstatic void A(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn, 6817a48c7cSmrg int fg, int bg, int rop, 6917a48c7cSmrg unsigned int planemask); 7017a48c7cSmrgstatic void A(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop, 7117a48c7cSmrg unsigned int planemask, int trans_color, 7217a48c7cSmrg int bpp, int depth); 7317a48c7cSmrgstatic void A(SubsequentImageWriteRect)(ScrnInfoPtr pScrn, int x, int y, 7417a48c7cSmrg int w, int h, int skipleft); 7517a48c7cSmrgstatic void A(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn, 7617a48c7cSmrg int x, int y, 7717a48c7cSmrg int w, int h, 7817a48c7cSmrg int srcx, int srcy, 7917a48c7cSmrg int offset); 8017a48c7cSmrgstatic void A(SubsequentSolidBresenhamLine)(ScrnInfoPtr pScrn, int x1, int y1, int octant, int err, int e1, int e2, int length); 8117a48c7cSmrgstatic void A(SubsequentSolidBresenhamLine6422)(ScrnInfoPtr pScrn, int x1, int y1, int octant, int err, int e1, int e2, int length); 8217a48c7cSmrgstatic void A(SetClippingRectangle)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2); 8317a48c7cSmrgstatic void A(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h, 8417a48c7cSmrg unsigned char *src, int srcwidth, int rop, 8517a48c7cSmrg unsigned int planemask, int trans, int bpp, 8617a48c7cSmrg int depth); 8717a48c7cSmrgstatic void A(FillImageWriteRects)(ScrnInfoPtr pScrn, int rop, 8817a48c7cSmrg unsigned int planemask, 8917a48c7cSmrg int nBox, BoxPtr pBox, int xorg, int yorg, 9017a48c7cSmrg PixmapPtr pPix); 9117a48c7cSmrgstatic void A(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn,int patx,int paty, 9217a48c7cSmrg int rop, unsigned int planemask, 9317a48c7cSmrg int transparency_color); 9417a48c7cSmrgstatic void A(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx, 9517a48c7cSmrg int paty, int x, int y, 9617a48c7cSmrg int w, int h); 9717a48c7cSmrg#endif 9817a48c7cSmrg 9917a48c7cSmrg/* Inline functions */ 10017a48c7cSmrgstatic __inline__ void 10117a48c7cSmrgA(WaitForFifo)(ApmPtr pApm, int slots) 10217a48c7cSmrg{ 10317a48c7cSmrg if (!pApm->UsePCIRetry) { 10417a48c7cSmrg volatile int i; 10517a48c7cSmrg 10617a48c7cSmrg for(i = 0; i < MAXLOOP; i++) { 10717a48c7cSmrg if ((STATUS() & STATUS_FIFO) >= slots) 10817a48c7cSmrg break; 10917a48c7cSmrg } 11017a48c7cSmrg if (i == MAXLOOP) { 11117a48c7cSmrg unsigned int status = STATUS(); 11217a48c7cSmrg 11317a48c7cSmrg WRXB(0x1FF, 0); 11417a48c7cSmrg if (!xf86ServerIsExiting()) 11517a48c7cSmrg FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", status); 11617a48c7cSmrg } 11717a48c7cSmrg } 11817a48c7cSmrg} 11917a48c7cSmrg 12017a48c7cSmrg 12117a48c7cSmrgstatic void 12217a48c7cSmrgA(SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop, 12317a48c7cSmrg unsigned int planemask) 12417a48c7cSmrg{ 12517a48c7cSmrg APMDECL(pScrn); 12617a48c7cSmrg 12717a48c7cSmrg DPRINTNAME(SetupForSolidFill); 12817a48c7cSmrg#ifdef FASTER 12917a48c7cSmrg A(WaitForFifo)(pApm, 3 + pApm->apmClip); 13017a48c7cSmrg SETDEC(DEC_QUICKSTART_ONDIMX | DEC_OP_RECT | DEC_DEST_UPD_TRCORNER | 13117a48c7cSmrg pApm->CurrentLayout.Setup_DEC); 13217a48c7cSmrg#else 13317a48c7cSmrg A(WaitForFifo)(pApm, 2 + pApm->apmClip); 13417a48c7cSmrg#endif 13517a48c7cSmrg#if PSZ == 2 13617a48c7cSmrg pApm->color = ((color & 0xFF0000) << 8) | ((color & 0xFF0000) >> 16) | 13717a48c7cSmrg ((color & 0xFF00) << 8) | ((color & 0xFF) << 16); 13817a48c7cSmrg#else 13917a48c7cSmrg SETFOREGROUNDCOLOR(color); 14017a48c7cSmrg#endif 14117a48c7cSmrg 14217a48c7cSmrg if (pApm->apmClip) { 14317a48c7cSmrg SETCLIP_CTRL(0); 14417a48c7cSmrg pApm->apmClip = FALSE; 14517a48c7cSmrg } 14617a48c7cSmrg 14717a48c7cSmrg SETROP(apmROP[rop]); 14817a48c7cSmrg} 14917a48c7cSmrg 15017a48c7cSmrgstatic void 15117a48c7cSmrgA(SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h) 15217a48c7cSmrg{ 15317a48c7cSmrg APMDECL(pScrn); 15417a48c7cSmrg 15517a48c7cSmrg DPRINTNAME(SubsequentSolidFillRect); 15617a48c7cSmrg#if PSZ == 24 15717a48c7cSmrg# ifndef FASTER 15817a48c7cSmrg A(WaitForFifo)(pApm, 5); 15917a48c7cSmrg# else 16017a48c7cSmrg A(WaitForFifo)(pApm, 4); 16117a48c7cSmrg# endif 16217a48c7cSmrg SETOFFSET(3*(pApm->CurrentLayout.displayWidth - w)); 16317a48c7cSmrg#if 0 16417a48c7cSmrg switch ((((y * pApm->CurrentLayout.displayWidth + x)* 3) / 8) % 3) { 16517a48c7cSmrg case 0: 16617a48c7cSmrg SETFOREGROUNDCOLOR(pApm->color); 16717a48c7cSmrg break; 16817a48c7cSmrg case 1: 16917a48c7cSmrg SETFOREGROUNDCOLOR((pApm->color << 8) | (pApm->color >> 16)); 17017a48c7cSmrg break; 17117a48c7cSmrg case 2: 17217a48c7cSmrg SETFOREGROUNDCOLOR(pApm->color >> 8); 17317a48c7cSmrg break; 17417a48c7cSmrg } 17517a48c7cSmrg#endif 17617a48c7cSmrg#else 17717a48c7cSmrg# ifndef FASTER 17817a48c7cSmrg A(WaitForFifo)(pApm, 3); 17917a48c7cSmrg# else 18017a48c7cSmrg A(WaitForFifo)(pApm, 2); 18117a48c7cSmrg# endif 18217a48c7cSmrg#endif 18317a48c7cSmrg SETDESTXY(x, y); 18417a48c7cSmrg SETWIDTHHEIGHT(w, h); 18517a48c7cSmrg UPDATEDEST(x + w + 1, y); 18617a48c7cSmrg#ifndef FASTER 18717a48c7cSmrg SETDEC(DEC_START | DEC_OP_RECT | DEC_DEST_UPD_TRCORNER | pApm->CurrentLayout.Setup_DEC); 18817a48c7cSmrg#endif 18917a48c7cSmrg} 19017a48c7cSmrg 19117a48c7cSmrgstatic void 19217a48c7cSmrgA(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, 19317a48c7cSmrg unsigned int planemask, int transparency_color) 19417a48c7cSmrg{ 19517a48c7cSmrg unsigned char tmp; 19617a48c7cSmrg 19717a48c7cSmrg APMDECL(pScrn); 19817a48c7cSmrg 19917a48c7cSmrg DPRINTNAME(SetupForScreenToScreenCopy); 20017a48c7cSmrg 20117a48c7cSmrg if (pApm->apmLock) { 20217a48c7cSmrg /* 20317a48c7cSmrg * This is just an attempt, because Daryll is tampering with MY registers. 20417a48c7cSmrg */ 20517a48c7cSmrg tmp = (RDXB(0xDB) & 0xF4) | 0x0A; 20617a48c7cSmrg WRXB(0xDB, tmp); 20717a48c7cSmrg ApmWriteSeq(0x1B, 0x20); 20817a48c7cSmrg ApmWriteSeq(0x1C, 0x2F); 20917a48c7cSmrg pApm->apmLock = FALSE; 21017a48c7cSmrg } 21117a48c7cSmrg 21217a48c7cSmrg pApm->blitxdir = xdir; 21317a48c7cSmrg pApm->blitydir = ydir; 21417a48c7cSmrg 21517a48c7cSmrg pApm->apmTransparency = (transparency_color != -1); 21617a48c7cSmrg 21717a48c7cSmrg#ifdef FASTER 21817a48c7cSmrg A(WaitForFifo)(pApm, 2 + (transparency_color != -1)); 21917a48c7cSmrg SETDEC(DEC_QUICKSTART_ONDIMX | DEC_OP_BLT | DEC_DEST_UPD_TRCORNER | 22017a48c7cSmrg (pApm->apmTransparency ? DEC_SOURCE_TRANSPARENCY : 0) | pApm->CurrentLayout.Setup_DEC | 22117a48c7cSmrg ((xdir < 0) ? DEC_DIR_X_NEG : DEC_DIR_X_POS) | 22217a48c7cSmrg ((ydir < 0) ? DEC_DIR_Y_NEG : DEC_DIR_Y_POS)); 22317a48c7cSmrg#else 22417a48c7cSmrg A(WaitForFifo)(pApm, 1 + (transparency_color != -1)); 22517a48c7cSmrg#endif 22617a48c7cSmrg 22717a48c7cSmrg if (transparency_color != -1) 22817a48c7cSmrg SETBACKGROUNDCOLOR(transparency_color); 22917a48c7cSmrg 23017a48c7cSmrg SETROP(apmROP[rop]); 23117a48c7cSmrg} 23217a48c7cSmrg 23317a48c7cSmrgstatic void 23417a48c7cSmrgA(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int x1, int y1, 23517a48c7cSmrg int x2, int y2, int w, int h) 23617a48c7cSmrg{ 23717a48c7cSmrg APMDECL(pScrn); 23817a48c7cSmrg#ifndef FASTER 23917a48c7cSmrg u32 c = pApm->apmTransparency ? DEC_SOURCE_TRANSPARENCY : 0; 24017a48c7cSmrg#endif 24117a48c7cSmrg u32 sx, dx, sy, dy; 24217a48c7cSmrg int i = y1 / pApm->CurrentLayout.Scanlines; 24317a48c7cSmrg 24417a48c7cSmrg DPRINTNAME(SubsequentScreenToScreenCopy); 24517a48c7cSmrg if (i && pApm->pixelStride) { 24617a48c7cSmrg#ifdef FASTER 24717a48c7cSmrg A(WaitForFifo)(pApm, 1); 24817a48c7cSmrg SETDEC(curr32[0x40 / 4] | (DEC_SOURCE_CONTIG | DEC_SOURCE_LINEAR)); 24917a48c7cSmrg#else 25017a48c7cSmrg c |= DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG; 25117a48c7cSmrg#endif 25217a48c7cSmrg pApm->apmClip = TRUE; 25317a48c7cSmrg A(WaitForFifo)(pApm, 3); 25417a48c7cSmrg SETCLIP_LEFTTOP(x2, y2); 25517a48c7cSmrg SETCLIP_RIGHTBOT(x2 + w - 1, y2 + h - 1); 25617a48c7cSmrg SETCLIP_CTRL(1); 25717a48c7cSmrg w = (pApm->pixelStride * 8) / pApm->CurrentLayout.bitsPerPixel; 25817a48c7cSmrg } 25917a48c7cSmrg else { 26017a48c7cSmrg#ifdef FASTER 26117a48c7cSmrg A(WaitForFifo)(pApm, 1 + pApm->apmClip); 26217a48c7cSmrg SETDEC(curr32[0x40 / 4] & ~(DEC_SOURCE_CONTIG | DEC_SOURCE_LINEAR)); 26317a48c7cSmrg if (pApm->apmClip) 26417a48c7cSmrg SETCLIP_CTRL(0); 26517a48c7cSmrg pApm->apmClip = FALSE; 26617a48c7cSmrg#else 26717a48c7cSmrg if (pApm->apmClip) { 26817a48c7cSmrg A(WaitForFifo)(pApm, 1); 26917a48c7cSmrg SETCLIP_CTRL(0); 27017a48c7cSmrg pApm->apmClip = FALSE; 27117a48c7cSmrg } 27217a48c7cSmrg#endif 27317a48c7cSmrg } 27417a48c7cSmrg if (i) { 27517a48c7cSmrg if (pApm->pixelStride) { 27617a48c7cSmrg x1 += (((y1 % pApm->CurrentLayout.Scanlines) - pApm->RushY[i - 1]) * pApm->pixelStride * 8) / pApm->CurrentLayout.bitsPerPixel; 27717a48c7cSmrg y1 = pApm->RushY[i - 1]; 27817a48c7cSmrg } 27917a48c7cSmrg else 28017a48c7cSmrg y1 -= i * pApm->CurrentLayout.Scanlines; 28117a48c7cSmrg } 28217a48c7cSmrg if (pApm->blitxdir < 0) 28317a48c7cSmrg { 28417a48c7cSmrg#ifndef FASTER 28517a48c7cSmrg c |= DEC_DIR_X_NEG; 28617a48c7cSmrg#endif 28717a48c7cSmrg sx = x1+w-1; 28817a48c7cSmrg dx = x2+w-1; 28917a48c7cSmrg } 29017a48c7cSmrg else 29117a48c7cSmrg { 29217a48c7cSmrg#ifndef FASTER 29317a48c7cSmrg c |= DEC_DIR_X_POS; 29417a48c7cSmrg#endif 29517a48c7cSmrg sx = x1; 29617a48c7cSmrg dx = x2; 29717a48c7cSmrg } 29817a48c7cSmrg 29917a48c7cSmrg if (pApm->blitydir < 0) 30017a48c7cSmrg { 30117a48c7cSmrg#ifndef FASTER 30217a48c7cSmrg c |= DEC_DIR_Y_NEG | DEC_START | DEC_OP_BLT | DEC_DEST_UPD_TRCORNER | 30317a48c7cSmrg pApm->CurrentLayout.Setup_DEC; 30417a48c7cSmrg#endif 30517a48c7cSmrg sy = y1+h-1; 30617a48c7cSmrg dy = y2+h-1; 30717a48c7cSmrg } 30817a48c7cSmrg else 30917a48c7cSmrg { 31017a48c7cSmrg#ifndef FASTER 31117a48c7cSmrg c |= DEC_DIR_Y_POS | DEC_START | DEC_OP_BLT | DEC_DEST_UPD_TRCORNER | 31217a48c7cSmrg pApm->CurrentLayout.Setup_DEC; 31317a48c7cSmrg#endif 31417a48c7cSmrg sy = y1; 31517a48c7cSmrg dy = y2; 31617a48c7cSmrg } 31717a48c7cSmrg 31817a48c7cSmrg#if PSZ == 24 31917a48c7cSmrg# ifndef FASTER 32017a48c7cSmrg A(WaitForFifo)(pApm, 5); 32117a48c7cSmrg# else 32217a48c7cSmrg A(WaitForFifo)(pApm, 4); 32317a48c7cSmrg# endif 32417a48c7cSmrg if (pApm->blitxdir == pApm->blitydir) 32517a48c7cSmrg SETOFFSET(3 * (pApm->CurrentLayout.displayWidth - w)); 32617a48c7cSmrg else 32717a48c7cSmrg SETOFFSET(3 * (pApm->CurrentLayout.displayWidth + w)); 32817a48c7cSmrg#else 32917a48c7cSmrg# ifndef FASTER 33017a48c7cSmrg A(WaitForFifo)(pApm, 4); 33117a48c7cSmrg# else 33217a48c7cSmrg A(WaitForFifo)(pApm, 3); 33317a48c7cSmrg# endif 33417a48c7cSmrg#endif 33517a48c7cSmrg 33617a48c7cSmrg if (i && pApm->pixelStride) { 33717a48c7cSmrg register unsigned int off = sx + sy * pApm->CurrentLayout.displayWidth; 33817a48c7cSmrg 33917a48c7cSmrg SETSOURCEOFF(((off & 0xFFF000) << 4) | (off & 0xFFF)); 34017a48c7cSmrg } 34117a48c7cSmrg else 34217a48c7cSmrg SETSOURCEXY(sx,sy); 34317a48c7cSmrg SETDESTXY(dx,dy); 34417a48c7cSmrg SETWIDTHHEIGHT(w,h); 34517a48c7cSmrg UPDATEDEST(dx + (w + 1)*pApm->blitxdir, dy); 34617a48c7cSmrg 34717a48c7cSmrg#ifndef FASTER 34817a48c7cSmrg SETDEC(c); 34917a48c7cSmrg#endif 35017a48c7cSmrg if (i) A(Sync)(pScrn); /* Only for AT3D */ 35117a48c7cSmrg} 35217a48c7cSmrg 35317a48c7cSmrg 35417a48c7cSmrg#if PSZ != 24 35517a48c7cSmrgstatic void 35617a48c7cSmrgA(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg, int bg, 35717a48c7cSmrg int rop, unsigned int planemask) 35817a48c7cSmrg{ 35917a48c7cSmrg APMDECL(pScrn); 36017a48c7cSmrg 36117a48c7cSmrg DPRINTNAME(SetupForScreenToScreenColorExpandFill); 36217a48c7cSmrg A(WaitForFifo)(pApm, 3 + pApm->apmClip); 36317a48c7cSmrg if (bg == -1) 36417a48c7cSmrg { 36517a48c7cSmrg SETFOREGROUNDCOLOR(fg); 36617a48c7cSmrg SETBACKGROUNDCOLOR(fg+1); 36717a48c7cSmrg pApm->apmTransparency = TRUE; 36817a48c7cSmrg } 36917a48c7cSmrg else 37017a48c7cSmrg { 37117a48c7cSmrg SETFOREGROUNDCOLOR(fg); 37217a48c7cSmrg SETBACKGROUNDCOLOR(bg); 37317a48c7cSmrg pApm->apmTransparency = FALSE; 37417a48c7cSmrg } 37517a48c7cSmrg 37617a48c7cSmrg SETROP(apmROP[rop]); 37717a48c7cSmrg} 37817a48c7cSmrg 37917a48c7cSmrgstatic void 38017a48c7cSmrgA(WriteBitmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h, 38117a48c7cSmrg unsigned char *src, int srcwidth, int skipleft, 38217a48c7cSmrg int fg, int bg, int rop, unsigned int planemask) 38317a48c7cSmrg{ 38417a48c7cSmrg APMDECL(pScrn); 38517a48c7cSmrg Bool beCareful, apmClip = FALSE; 38617a48c7cSmrg int wc, n, nc, wr, wrd; 38717a48c7cSmrg CARD32 *dstPtr; 38817a48c7cSmrg#ifndef FASTER 38917a48c7cSmrg int c; 39017a48c7cSmrg#endif 39117a48c7cSmrg 39217a48c7cSmrg DPRINTNAME(WriteBitmap); 39317a48c7cSmrg 39417a48c7cSmrg if (w <= 0 && h <= 0) 39517a48c7cSmrg return; 39617a48c7cSmrg 39717a48c7cSmrg /* 39817a48c7cSmrg * The function is a bit long, but the spirit is simple : put the monochrome 39917a48c7cSmrg * data in scratch memory and color-expand it using the 40017a48c7cSmrg * ScreenToScreenColorExpand techniques. 40117a48c7cSmrg */ 40217a48c7cSmrg 40317a48c7cSmrg w += skipleft; 40417a48c7cSmrg x -= skipleft; 40517a48c7cSmrg wc = pApm->ScratchMemSize * 8; 40617a48c7cSmrg wrd = (w + 31) >> 5; 40717a48c7cSmrg wr = wrd << 5; 40817a48c7cSmrg nc = wc / wr; 40917a48c7cSmrg if (nc > h) 41017a48c7cSmrg nc = h; 41117a48c7cSmrg if (wr / 8 > srcwidth) 41217a48c7cSmrg beCareful = TRUE; 41317a48c7cSmrg else 41417a48c7cSmrg beCareful = FALSE; 41517a48c7cSmrg srcwidth -= wr / 8; 41617a48c7cSmrg 41717a48c7cSmrg if (skipleft || w != wr) { 41817a48c7cSmrg apmClip = TRUE; 41917a48c7cSmrg A(WaitForFifo)(pApm, 3); 42017a48c7cSmrg SETCLIP_LEFTTOP(x + skipleft, y); 42117a48c7cSmrg SETCLIP_RIGHTBOT(x + w - 1, y + h - 1); 42217a48c7cSmrg SETCLIP_CTRL(1); 42317a48c7cSmrg } 42417a48c7cSmrg else if (pApm->apmClip) { 42517a48c7cSmrg A(WaitForFifo)(pApm, 1); 42617a48c7cSmrg SETCLIP_CTRL(0); 42717a48c7cSmrg } 42817a48c7cSmrg pApm->apmClip = FALSE; 42917a48c7cSmrg 43017a48c7cSmrg A(SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask); 43117a48c7cSmrg#ifdef FASTER 43217a48c7cSmrg A(WaitForFifo)(pApm, 2); 43317a48c7cSmrg if (pApm->apmTransparency) 43417a48c7cSmrg SETDEC(DEC_OP_BLT | DEC_DIR_X_POS | DEC_DIR_Y_POS | DEC_SOURCE_MONOCHROME | 43517a48c7cSmrg DEC_QUICKSTART_ONDIMX | DEC_DEST_UPD_BLCORNER | DEC_SOURCE_LINEAR | 43617a48c7cSmrg DEC_SOURCE_CONTIG | DEC_SOURCE_TRANSPARENCY | pApm->CurrentLayout.Setup_DEC); 43717a48c7cSmrg else 43817a48c7cSmrg SETDEC(DEC_OP_BLT | DEC_DIR_X_POS | DEC_DIR_Y_POS | DEC_SOURCE_MONOCHROME | 43917a48c7cSmrg DEC_QUICKSTART_ONDIMX | DEC_DEST_UPD_BLCORNER | DEC_SOURCE_LINEAR | 44017a48c7cSmrg DEC_SOURCE_CONTIG | pApm->CurrentLayout.Setup_DEC); 44117a48c7cSmrg#else 44217a48c7cSmrg A(WaitForFifo)(pApm, 1); 44317a48c7cSmrg c = DEC_OP_BLT | DEC_DIR_X_POS | DEC_DIR_Y_POS | DEC_SOURCE_MONOCHROME | 44417a48c7cSmrg DEC_START | DEC_DEST_UPD_BLCORNER | DEC_SOURCE_LINEAR | 44517a48c7cSmrg DEC_SOURCE_CONTIG | pApm->CurrentLayout.Setup_DEC; 44617a48c7cSmrg if (pApm->apmTransparency) 44717a48c7cSmrg c |= DEC_SOURCE_TRANSPARENCY; 44817a48c7cSmrg#endif 44917a48c7cSmrg 45017a48c7cSmrg SETDESTXY(x, y); 45117a48c7cSmrg 45217a48c7cSmrg if (!beCareful || h % nc > 3 || (w > 16 && h % nc)) { 45317a48c7cSmrg#ifndef FASTER 45417a48c7cSmrg if (h / nc) 45517a48c7cSmrg SETWIDTHHEIGHT(wr, nc); 45617a48c7cSmrg#endif 45717a48c7cSmrg for (n = h / nc; n-- > 0; ) { 45817a48c7cSmrg int i, j; 45917a48c7cSmrg 46017a48c7cSmrg if (pApm->ScratchMemPtr + nc * wrd * 4 < pApm->ScratchMemEnd) { 46117a48c7cSmrg#define d ((memType)dstPtr - (memType)pApm->FbBase) 46217a48c7cSmrg A(WaitForFifo)(pApm, 1); 46317a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemPtr; 46417a48c7cSmrg switch(pApm->CurrentLayout.bitsPerPixel) { 46517a48c7cSmrg case 8: case 24: 46617a48c7cSmrg SETSOURCEOFF((d & 0xFFF000) << 4 | 46717a48c7cSmrg (d & 0xFFF)); 46817a48c7cSmrg break; 46917a48c7cSmrg case 16: 47017a48c7cSmrg SETSOURCEOFF((d & 0xFFE000) << 3 | 47117a48c7cSmrg ((d & 0x1FFE) >> 1)); 47217a48c7cSmrg break; 47317a48c7cSmrg case 32: 47417a48c7cSmrg SETSOURCEOFF((d & 0xFFC000) << 2 | 47517a48c7cSmrg ((d & 0x3FFC) >> 2)); 47617a48c7cSmrg break; 47717a48c7cSmrg } 47817a48c7cSmrg#undef d 47917a48c7cSmrg } 48017a48c7cSmrg else { 48117a48c7cSmrg (*pApm->AccelInfoRec->Sync)(pScrn); 48217a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemOffset; 48317a48c7cSmrg SETSOURCEOFF(pApm->ScratchMem); 48417a48c7cSmrg } 48517a48c7cSmrg pApm->ScratchMemPtr = ((memType)(dstPtr + wrd * nc) + 4) 48617a48c7cSmrg & ~(memType)7; 48717a48c7cSmrg for (i = nc; i-- > 0; ) { 48817a48c7cSmrg for (j = wrd; j-- > 0; ) { 48917a48c7cSmrg *dstPtr++ = XAAReverseBitOrder(*(CARD32 *)src); 49017a48c7cSmrg src += 4; 49117a48c7cSmrg } 49217a48c7cSmrg src += srcwidth; 49317a48c7cSmrg } 49417a48c7cSmrg A(WaitForFifo)(pApm, 1); 49517a48c7cSmrg#ifdef FASTER 49617a48c7cSmrg SETWIDTHHEIGHT(wr, nc); 49717a48c7cSmrg#else 49817a48c7cSmrg SETDEC(c); 49917a48c7cSmrg#endif 50017a48c7cSmrg } 50117a48c7cSmrg } 50217a48c7cSmrg else { 50317a48c7cSmrg#ifndef FASTER 50417a48c7cSmrg if (h / nc) 50517a48c7cSmrg SETWIDTHHEIGHT(wr, nc); 50617a48c7cSmrg#endif 50717a48c7cSmrg for (n = h / nc; n-- > 0; ) { 50817a48c7cSmrg int i, j; 50917a48c7cSmrg 51017a48c7cSmrg if (pApm->ScratchMemPtr + nc * wrd * 4 < pApm->ScratchMemEnd) { 51117a48c7cSmrg#define d ((memType)dstPtr - (memType)pApm->FbBase) 51217a48c7cSmrg A(WaitForFifo)(pApm, 1); 51317a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemPtr; 51417a48c7cSmrg switch(pApm->CurrentLayout.bitsPerPixel) { 51517a48c7cSmrg case 8: case 24: 51617a48c7cSmrg SETSOURCEOFF((d & 0xFFF000) << 4 | 51717a48c7cSmrg (d & 0xFFF)); 51817a48c7cSmrg break; 51917a48c7cSmrg case 16: 52017a48c7cSmrg SETSOURCEOFF((d & 0xFFE000) << 3 | 52117a48c7cSmrg ((d & 0x1FFE) >> 1)); 52217a48c7cSmrg break; 52317a48c7cSmrg case 32: 52417a48c7cSmrg SETSOURCEOFF((d & 0xFFC000) << 2 | 52517a48c7cSmrg ((d & 0x3FFC) >> 2)); 52617a48c7cSmrg break; 52717a48c7cSmrg } 52817a48c7cSmrg#undef d 52917a48c7cSmrg } 53017a48c7cSmrg else { 53117a48c7cSmrg (*pApm->AccelInfoRec->Sync)(pScrn); 53217a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemOffset; 53317a48c7cSmrg SETSOURCEOFF(pApm->ScratchMem); 53417a48c7cSmrg } 53517a48c7cSmrg pApm->ScratchMemPtr = ((memType)(dstPtr + wrd * nc * 4) + 4) & ~7; 53617a48c7cSmrg for (i = nc; i-- > 0; ) { 53717a48c7cSmrg for (j = wrd; j-- > 0; ) { 53817a48c7cSmrg if (i || j || n) 53917a48c7cSmrg *dstPtr++ = XAAReverseBitOrder(*(CARD32 *)src); 54017a48c7cSmrg else if (srcwidth > -8) { 54117a48c7cSmrg ((CARD8 *)dstPtr)[0] = byte_reversed[((CARD8 *)src)[2]]; 54217a48c7cSmrg ((CARD8 *)dstPtr)[1] = byte_reversed[((CARD8 *)src)[1]]; 54317a48c7cSmrg ((CARD8 *)dstPtr)[2] = byte_reversed[((CARD8 *)src)[0]]; 54417a48c7cSmrg dstPtr = (CARD32 *)(3 + (CARD8 *)dstPtr); 54517a48c7cSmrg } 54617a48c7cSmrg else if (srcwidth > -16) { 54717a48c7cSmrg ((CARD8 *)dstPtr)[0] = byte_reversed[((CARD8 *)src)[1]]; 54817a48c7cSmrg ((CARD8 *)dstPtr)[1] = byte_reversed[((CARD8 *)src)[0]]; 54917a48c7cSmrg dstPtr = (CARD32 *)(2 + (CARD8 *)dstPtr); 55017a48c7cSmrg } 55117a48c7cSmrg else { 55217a48c7cSmrg *(CARD8 *)dstPtr = byte_reversed[*(CARD8 *)src]; 55317a48c7cSmrg dstPtr = (CARD32 *)(1 + (CARD8 *)dstPtr); 55417a48c7cSmrg } 55517a48c7cSmrg src += 4; 55617a48c7cSmrg } 55717a48c7cSmrg src += srcwidth; 55817a48c7cSmrg } 55917a48c7cSmrg A(WaitForFifo)(pApm, 1); 56017a48c7cSmrg#ifdef FASTER 56117a48c7cSmrg SETWIDTHHEIGHT(wr, nc); 56217a48c7cSmrg#else 56317a48c7cSmrg SETDEC(c); 56417a48c7cSmrg#endif 56517a48c7cSmrg } 56617a48c7cSmrg } 56717a48c7cSmrg 56817a48c7cSmrg /* 56917a48c7cSmrg * Same thing for the remnant 57017a48c7cSmrg */ 57117a48c7cSmrg UPDATEDEST(x, y + h + 1); 57217a48c7cSmrg h %= nc; 57317a48c7cSmrg if (h) { 57417a48c7cSmrg if (!beCareful) { 57517a48c7cSmrg int i, j; 57617a48c7cSmrg 57717a48c7cSmrg#ifndef FASTER 57817a48c7cSmrg SETWIDTHHEIGHT(wr, h); 57917a48c7cSmrg#endif 58017a48c7cSmrg if (pApm->ScratchMemPtr + h * wrd * 4 < pApm->ScratchMemEnd) { 58117a48c7cSmrg#define d ((memType)dstPtr - (memType)pApm->FbBase) 58217a48c7cSmrg A(WaitForFifo)(pApm, 1); 58317a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemPtr; 58417a48c7cSmrg switch(pApm->CurrentLayout.bitsPerPixel) { 58517a48c7cSmrg case 8: case 24: 58617a48c7cSmrg SETSOURCEOFF((d & 0xFFF000) << 4 | 58717a48c7cSmrg (d & 0xFFF)); 58817a48c7cSmrg break; 58917a48c7cSmrg case 16: 59017a48c7cSmrg SETSOURCEOFF((d & 0xFFE000) << 3 | 59117a48c7cSmrg ((d & 0x1FFE) >> 1)); 59217a48c7cSmrg break; 59317a48c7cSmrg case 32: 59417a48c7cSmrg SETSOURCEOFF((d & 0xFFC000) << 2 | 59517a48c7cSmrg ((d & 0x3FFC) >> 2)); 59617a48c7cSmrg break; 59717a48c7cSmrg } 59817a48c7cSmrg#undef d 59917a48c7cSmrg } 60017a48c7cSmrg else { 60117a48c7cSmrg (*pApm->AccelInfoRec->Sync)(pScrn); 60217a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemOffset; 60317a48c7cSmrg SETSOURCEOFF(pApm->ScratchMem); 60417a48c7cSmrg } 60517a48c7cSmrg pApm->ScratchMemPtr = ((memType)(dstPtr + wrd * h) + 4) & ~7; 60617a48c7cSmrg for (i = h; i-- > 0; ) { 60717a48c7cSmrg for (j = wrd; j-- > 0; ) { 60817a48c7cSmrg *dstPtr++ = XAAReverseBitOrder(*(CARD32 *)src); 60917a48c7cSmrg src += 4; 61017a48c7cSmrg } 61117a48c7cSmrg src += srcwidth; 61217a48c7cSmrg } 61317a48c7cSmrg A(WaitForFifo)(pApm, 1); 61417a48c7cSmrg#ifdef FASTER 61517a48c7cSmrg SETWIDTHHEIGHT(wr, h); 61617a48c7cSmrg#else 61717a48c7cSmrg SETDEC(c); 61817a48c7cSmrg#endif 61917a48c7cSmrg } 62017a48c7cSmrg else { 62117a48c7cSmrg int i, j; 62217a48c7cSmrg 62317a48c7cSmrg#ifndef FASTER 62417a48c7cSmrg SETWIDTHHEIGHT(w, h); 62517a48c7cSmrg#endif 62617a48c7cSmrg if (pApm->ScratchMemPtr + h * wrd * 4 < pApm->ScratchMemEnd) { 62717a48c7cSmrg#define d ((memType)dstPtr - (memType)pApm->FbBase) 62817a48c7cSmrg A(WaitForFifo)(pApm, 1); 62917a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemPtr; 63017a48c7cSmrg switch(pApm->CurrentLayout.bitsPerPixel) { 63117a48c7cSmrg case 8: case 24: 63217a48c7cSmrg SETSOURCEOFF((d & 0xFFF000) << 4 | 63317a48c7cSmrg (d & 0xFFF)); 63417a48c7cSmrg break; 63517a48c7cSmrg case 16: 63617a48c7cSmrg SETSOURCEOFF((d & 0xFFE000) << 3 | 63717a48c7cSmrg ((d & 0x1FFE) >> 1)); 63817a48c7cSmrg break; 63917a48c7cSmrg case 32: 64017a48c7cSmrg SETSOURCEOFF((d & 0xFFC000) << 2 | 64117a48c7cSmrg ((d & 0x3FFC) >> 2)); 64217a48c7cSmrg break; 64317a48c7cSmrg } 64417a48c7cSmrg#undef d 64517a48c7cSmrg } 64617a48c7cSmrg else { 64717a48c7cSmrg (*pApm->AccelInfoRec->Sync)(pScrn); 64817a48c7cSmrg dstPtr = (CARD32 *)pApm->ScratchMemOffset; 64917a48c7cSmrg SETSOURCEOFF(pApm->ScratchMem); 65017a48c7cSmrg } 65117a48c7cSmrg pApm->ScratchMemPtr = ((memType)(dstPtr + wrd * h) + 4) & ~7; 65217a48c7cSmrg for (i = h; i-- > 0; ) { 65317a48c7cSmrg for (j = wrd; j-- > 0; ) { 65417a48c7cSmrg if (i || j) 65517a48c7cSmrg *dstPtr++ = XAAReverseBitOrder(*(CARD32 *)src); 65617a48c7cSmrg else if (srcwidth > -8) { 65717a48c7cSmrg ((CARD8 *)dstPtr)[0] = byte_reversed[((CARD8 *)src)[2]]; 65817a48c7cSmrg ((CARD8 *)dstPtr)[1] = byte_reversed[((CARD8 *)src)[1]]; 65917a48c7cSmrg ((CARD8 *)dstPtr)[2] = byte_reversed[((CARD8 *)src)[0]]; 66017a48c7cSmrg dstPtr = (CARD32 *)(3 + (CARD8 *)dstPtr); 66117a48c7cSmrg } 66217a48c7cSmrg else if (srcwidth > -16) { 66317a48c7cSmrg ((CARD8 *)dstPtr)[0] = byte_reversed[((CARD8 *)src)[1]]; 66417a48c7cSmrg ((CARD8 *)dstPtr)[1] = byte_reversed[((CARD8 *)src)[0]]; 66517a48c7cSmrg dstPtr = (CARD32 *)(2 + (CARD8 *)dstPtr); 66617a48c7cSmrg } 66717a48c7cSmrg else { 66817a48c7cSmrg *(CARD8 *)dstPtr = byte_reversed[*(CARD8 *)src]; 66917a48c7cSmrg dstPtr = (CARD32 *)(1 + (CARD8 *)dstPtr); 67017a48c7cSmrg } 67117a48c7cSmrg src += 4; 67217a48c7cSmrg } 67317a48c7cSmrg src += srcwidth; 67417a48c7cSmrg } 67517a48c7cSmrg A(WaitForFifo)(pApm, 1); 67617a48c7cSmrg#ifdef FASTER 67717a48c7cSmrg SETWIDTHHEIGHT(w, h); 67817a48c7cSmrg#else 67917a48c7cSmrg SETDEC(c); 68017a48c7cSmrg#endif 68117a48c7cSmrg } 68217a48c7cSmrg } 68317a48c7cSmrg pApm->apmClip = apmClip; 68417a48c7cSmrg} 68517a48c7cSmrg 68617a48c7cSmrgstatic void 68717a48c7cSmrgA(TEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int w, int h, 68817a48c7cSmrg int skipleft, int startline, 68917a48c7cSmrg unsigned int **glyphs, int glyphWidth, 69017a48c7cSmrg int fg, int bg, int rop, unsigned planemask) 69117a48c7cSmrg{ 69217a48c7cSmrg CARD32 *base, *base0; 69317a48c7cSmrg GlyphScanlineFuncPtr GlyphFunc; 69417a48c7cSmrg static GlyphScanlineFuncPtr *GlyphTab = NULL; 69517a48c7cSmrg int w2, h2, dwords; 69617a48c7cSmrg 69717a48c7cSmrg if (!GlyphTab) GlyphTab = XAAGetGlyphScanlineFuncLSBFirst(); 69817a48c7cSmrg GlyphFunc = GlyphTab[glyphWidth - 1]; 69917a48c7cSmrg 70017a48c7cSmrg w2 = w + skipleft; 70117a48c7cSmrg h2 = h; 70217a48c7cSmrg dwords = (w2 + 31) >> 5; 70317a48c7cSmrg dwords <<= 2; 70417a48c7cSmrg 7050dd80ee0Smrg base0 = base = malloc(dwords * h); 70617a48c7cSmrg if (!base) 70717a48c7cSmrg return; /* Should not happen : it's rather small... */ 70817a48c7cSmrg 70917a48c7cSmrg while(h--) { 71017a48c7cSmrg base = (*GlyphFunc)(base, glyphs, startline++, w2, glyphWidth); 71117a48c7cSmrg } 71217a48c7cSmrg 71317a48c7cSmrg A(WriteBitmap)(pScrn, x, y, w, h2, (unsigned char *)base0, dwords, 71417a48c7cSmrg skipleft, fg, bg, rop, planemask); 71517a48c7cSmrg 7160dd80ee0Smrg free(base0); 71717a48c7cSmrg} 71817a48c7cSmrg 71917a48c7cSmrgstatic void A(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty, 72017a48c7cSmrg int fg, int bg, int rop, 72117a48c7cSmrg unsigned int planemask) 72217a48c7cSmrg{ 72317a48c7cSmrg APMDECL(pScrn); 72417a48c7cSmrg 72517a48c7cSmrg DPRINTNAME(SetupForMono8x8PatternFill); 72617a48c7cSmrg pApm->apmTransparency = (pApm->Chipset >= AT3D) && (bg == -1); 72717a48c7cSmrg pApm->Bg8x8 = bg; 72817a48c7cSmrg pApm->Fg8x8 = fg; 72917a48c7cSmrg pApm->rop = apmROP[rop]; 73017a48c7cSmrg A(WaitForFifo)(pApm, 3 + pApm->apmClip); 73117a48c7cSmrg if (bg == -1) 73217a48c7cSmrg SETBACKGROUNDCOLOR(fg + 1); 73317a48c7cSmrg else 73417a48c7cSmrg SETBACKGROUNDCOLOR(bg); 73517a48c7cSmrg SETFOREGROUNDCOLOR(fg); 73617a48c7cSmrg if (pApm->Chipset >= AT3D) 73717a48c7cSmrg SETROP(apmROP[rop] & 0xF0); 73817a48c7cSmrg else 73917a48c7cSmrg SETROP((apmROP[rop] & 0xF0) | 0x0A); 74017a48c7cSmrg if (pApm->apmClip) { 74117a48c7cSmrg SETCLIP_CTRL(0); 74217a48c7cSmrg pApm->apmClip = FALSE; 74317a48c7cSmrg } 74417a48c7cSmrg} 74517a48c7cSmrg 74617a48c7cSmrgstatic void A(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx, 74717a48c7cSmrg int paty, int x, int y, 74817a48c7cSmrg int w, int h) 74917a48c7cSmrg{ 75017a48c7cSmrg APMDECL(pScrn); 75117a48c7cSmrg 75217a48c7cSmrg DPRINTNAME(SubsequentMono8x8PatternFillRect); 75317a48c7cSmrg SETDESTXY(x, y); 75417a48c7cSmrg UPDATEDEST(x, y + h + 1); 75517a48c7cSmrg A(WaitForFifo)(pApm, 6); 75617a48c7cSmrg if (pApm->Chipset == AT24 && pApm->Bg8x8 != -1) { 75717a48c7cSmrg SETROP(pApm->rop); 75817a48c7cSmrg SETFOREGROUNDCOLOR(pApm->Bg8x8); 75917a48c7cSmrg#ifdef FASTER 76017a48c7cSmrg SETDEC(pApm->CurrentLayout.Setup_DEC | ((h == 1) ? DEC_OP_STRIP : DEC_OP_RECT) | 76117a48c7cSmrg DEC_DEST_XY | DEC_QUICKSTART_ONDIMX); 76217a48c7cSmrg SETWIDTHHEIGHT(w, h); 76317a48c7cSmrg#else 76417a48c7cSmrg SETWIDTHHEIGHT(w, h); 76517a48c7cSmrg SETDEC(pApm->CurrentLayout.Setup_DEC | ((h == 1) ? DEC_OP_STRIP : DEC_OP_RECT) | 76617a48c7cSmrg DEC_DEST_XY | DEC_START); 76717a48c7cSmrg#endif 76817a48c7cSmrg A(WaitForFifo)(pApm, 6); 76917a48c7cSmrg SETROP((pApm->rop & 0xF0) | 0x0A); 77017a48c7cSmrg SETFOREGROUNDCOLOR(pApm->Fg8x8); 77117a48c7cSmrg } 77217a48c7cSmrg SETPATTERN(patx, paty); 77317a48c7cSmrg#ifdef FASTER 77417a48c7cSmrg SETDEC(pApm->CurrentLayout.Setup_DEC | ((h == 1) ? DEC_OP_STRIP : DEC_OP_RECT) | 77517a48c7cSmrg DEC_DEST_XY | DEC_PATTERN_88_1bMONO | DEC_DEST_UPD_TRCORNER | 77617a48c7cSmrg (pApm->apmTransparency ? DEC_SOURCE_TRANSPARENCY : 0) | 77717a48c7cSmrg DEC_QUICKSTART_ONDIMX); 77817a48c7cSmrg SETWIDTHHEIGHT(w, h); 77917a48c7cSmrg#else 78017a48c7cSmrg SETWIDTHHEIGHT(w, h); 78117a48c7cSmrg SETDEC(pApm->CurrentLayout.Setup_DEC | ((h == 1) ? DEC_OP_STRIP : DEC_OP_RECT) | 78217a48c7cSmrg DEC_DEST_XY | DEC_PATTERN_88_1bMONO | DEC_DEST_UPD_TRCORNER | 78317a48c7cSmrg (pApm->apmTransparency ? DEC_SOURCE_TRANSPARENCY : 0) | 78417a48c7cSmrg DEC_START); 78517a48c7cSmrg#endif 78617a48c7cSmrg} 78717a48c7cSmrg 78817a48c7cSmrg#if 0 78917a48c7cSmrgstatic void 79017a48c7cSmrgA(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg, int bg, 79117a48c7cSmrg int rop, unsigned int planemask) 79217a48c7cSmrg{ 79317a48c7cSmrg APMDECL(pScrn); 79417a48c7cSmrg 79517a48c7cSmrg DPRINTNAME(SetupForCPUToScreenColorExpandFill); 79617a48c7cSmrg if (bg == -1) 79717a48c7cSmrg { 79817a48c7cSmrg#ifndef FASTER 79917a48c7cSmrg pApm->apmTransparency = TRUE; 80017a48c7cSmrg A(WaitForFifo)(pApm, 3); 80117a48c7cSmrg#else 80217a48c7cSmrg A(WaitForFifo)(pApm, 4); 80317a48c7cSmrg SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG | 80417a48c7cSmrg DEC_SOURCE_TRANSPARENCY | DEC_SOURCE_MONOCHROME | DEC_QUICKSTART_ONDIMX | 80517a48c7cSmrg DEC_DEST_UPD_TRCORNER | pApm->CurrentLayout.Setup_DEC); 80617a48c7cSmrg#endif 80717a48c7cSmrg SETFOREGROUNDCOLOR(fg); 80817a48c7cSmrg SETBACKGROUNDCOLOR(fg+1); 80917a48c7cSmrg } 81017a48c7cSmrg else 81117a48c7cSmrg { 81217a48c7cSmrg#ifndef FASTER 81317a48c7cSmrg pApm->apmTransparency = FALSE; 81417a48c7cSmrg A(WaitForFifo)(pApm, 3); 81517a48c7cSmrg#else 81617a48c7cSmrg A(WaitForFifo)(pApm, 4); 81717a48c7cSmrg SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG | 81817a48c7cSmrg DEC_DEST_UPD_TRCORNER | DEC_SOURCE_MONOCHROME | 81917a48c7cSmrg DEC_QUICKSTART_ONDIMX | pApm->CurrentLayout.Setup_DEC); 82017a48c7cSmrg#endif 82117a48c7cSmrg SETFOREGROUNDCOLOR(fg); 82217a48c7cSmrg SETBACKGROUNDCOLOR(bg); 82317a48c7cSmrg } 82417a48c7cSmrg SETROP(apmROP[rop]); 82517a48c7cSmrg} 82617a48c7cSmrg 82717a48c7cSmrgstatic void 82817a48c7cSmrgA(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int x, int y, 82917a48c7cSmrg int w, int h, int skipleft) 83017a48c7cSmrg{ 83117a48c7cSmrg APMDECL(pScrn); 83217a48c7cSmrg#ifndef FASTER 83317a48c7cSmrg u32 c; 83417a48c7cSmrg#endif 83517a48c7cSmrg 83617a48c7cSmrg DPRINTNAME(SubsequentCPUToScreenColorExpandFill); 83717a48c7cSmrg#ifndef FASTER 83817a48c7cSmrg c = DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG | 83917a48c7cSmrg DEC_SOURCE_MONOCHROME | DEC_START | DEC_DEST_UPD_TRCORNER | 84017a48c7cSmrg pApm->CurrentLayout.Setup_DEC; 84117a48c7cSmrg 84217a48c7cSmrg if (pApm->apmTransparency) 84317a48c7cSmrg c |= DEC_SOURCE_TRANSPARENCY; 84417a48c7cSmrg 84517a48c7cSmrg A(WaitForFifo)(pApm, 7); 84617a48c7cSmrg#else 84717a48c7cSmrg A(WaitForFifo)(pApm, 6); 84817a48c7cSmrg#endif 84917a48c7cSmrg 85017a48c7cSmrg SETCLIP_LEFTTOP(x+skipleft, y); 85117a48c7cSmrg SETCLIP_RIGHTBOT(x+w-1, y+h-1); 85217a48c7cSmrg SETCLIP_CTRL(0x01); 85317a48c7cSmrg pApm->apmClip = TRUE; 85417a48c7cSmrg SETSOURCEX(0); /* According to manual, it just has to be zero */ 85517a48c7cSmrg SETDESTXY(x, y); 85617a48c7cSmrg SETWIDTHHEIGHT((w + 31) & ~31, h); 85717a48c7cSmrg UPDATEDEST(x + ((w + 31) & ~31), y); 85817a48c7cSmrg 85917a48c7cSmrg#ifndef FASTER 86017a48c7cSmrg SETDEC(c); 86117a48c7cSmrg#endif 86217a48c7cSmrg} 86317a48c7cSmrg#endif 86417a48c7cSmrg 86517a48c7cSmrgstatic void 86617a48c7cSmrgA(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop, unsigned int planemask, 86717a48c7cSmrg int trans_color, int bpp, int depth) 86817a48c7cSmrg{ 86917a48c7cSmrg APMDECL(pScrn); 87017a48c7cSmrg 87117a48c7cSmrg DPRINTNAME(SetupForImageWrite); 87217a48c7cSmrg if (trans_color != -1) 87317a48c7cSmrg { 87417a48c7cSmrg#ifndef FASTER 87517a48c7cSmrg pApm->apmTransparency = TRUE; 87617a48c7cSmrg A(WaitForFifo)(pApm, 3); 87717a48c7cSmrg#else 87817a48c7cSmrg A(WaitForFifo)(pApm, 4); 87917a48c7cSmrg SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG | 88017a48c7cSmrg DEC_SOURCE_TRANSPARENCY | DEC_QUICKSTART_ONDIMX | pApm->CurrentLayout.Setup_DEC); 88117a48c7cSmrg#endif 88217a48c7cSmrg SETBACKGROUNDCOLOR(trans_color); 88317a48c7cSmrg } 88417a48c7cSmrg else { 88517a48c7cSmrg#ifndef FASTER 88617a48c7cSmrg pApm->apmTransparency = FALSE; 88717a48c7cSmrg A(WaitForFifo)(pApm, 2); 88817a48c7cSmrg#else 88917a48c7cSmrg A(WaitForFifo)(pApm, 3); 89017a48c7cSmrg SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG | 89117a48c7cSmrg DEC_QUICKSTART_ONDIMX | pApm->CurrentLayout.Setup_DEC); 89217a48c7cSmrg#endif 89317a48c7cSmrg } 89417a48c7cSmrg 89517a48c7cSmrg SETROP(apmROP[rop]); 89617a48c7cSmrg} 89717a48c7cSmrg 89817a48c7cSmrgstatic void 89917a48c7cSmrgA(SubsequentImageWriteRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h, 90017a48c7cSmrg int skipleft) 90117a48c7cSmrg{ 90217a48c7cSmrg APMDECL(pScrn); 90317a48c7cSmrg#ifndef FASTER 90417a48c7cSmrg u32 c; 90517a48c7cSmrg#endif 90617a48c7cSmrg 90717a48c7cSmrg DPRINTNAME(SubsequentImageWriteRect); 90817a48c7cSmrg#ifndef FASTER 90917a48c7cSmrg c = DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG | 91017a48c7cSmrg DEC_START | pApm->CurrentLayout.Setup_DEC; 91117a48c7cSmrg 91217a48c7cSmrg if (pApm->apmTransparency) 91317a48c7cSmrg c |= DEC_SOURCE_TRANSPARENCY; 91417a48c7cSmrg 91517a48c7cSmrg if (pApm->Chipset >= AT24) 91617a48c7cSmrg A(WaitForFifo)(pApm, 7); 91717a48c7cSmrg else 91817a48c7cSmrg A(WaitForFifo)(pApm, 3); 91917a48c7cSmrg#else 92017a48c7cSmrg if (pApm->Chipset >= AT24) 92117a48c7cSmrg A(WaitForFifo)(pApm, 6); 92217a48c7cSmrg else 92317a48c7cSmrg A(WaitForFifo)(pApm, 3); 92417a48c7cSmrg#endif 92517a48c7cSmrg 92617a48c7cSmrg SETCLIP_LEFTTOP(x+skipleft, y); 92717a48c7cSmrg SETCLIP_RIGHTBOT(x+w-1, y+h-1); 92817a48c7cSmrg SETCLIP_CTRL(0x01); 92917a48c7cSmrg pApm->apmClip = TRUE; 93017a48c7cSmrg if (pApm->Chipset < AT24) 93117a48c7cSmrg A(WaitForFifo)(pApm, 4); 93217a48c7cSmrg SETSOURCEX(0); /* According to manual, it just has to be zero */ 93317a48c7cSmrg SETDESTXY(x, y); 93417a48c7cSmrg SETWIDTHHEIGHT((w + 3) & ~3, h); 93517a48c7cSmrg 93617a48c7cSmrg#ifndef FASTER 93717a48c7cSmrg SETDEC(c); 93817a48c7cSmrg#endif 93917a48c7cSmrg} 94017a48c7cSmrg 94117a48c7cSmrgstatic void 94217a48c7cSmrgA(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn, int x, int y, 94317a48c7cSmrg int w, int h, int srcx, int srcy, 94417a48c7cSmrg int offset) 94517a48c7cSmrg{ 94617a48c7cSmrg APMDECL(pScrn); 94717a48c7cSmrg u32 c; 94817a48c7cSmrg 94917a48c7cSmrg DPRINTNAME(SubsequentScreenToScreenColorExpandFill); 95017a48c7cSmrg#ifdef FASTER 95117a48c7cSmrg c = DEC_OP_BLT | DEC_DIR_X_POS | DEC_DIR_Y_POS | DEC_SOURCE_MONOCHROME | 95217a48c7cSmrg DEC_QUICKSTART_ONDIMX | DEC_DEST_UPD_TRCORNER | pApm->CurrentLayout.Setup_DEC; 95317a48c7cSmrg#else 95417a48c7cSmrg c = DEC_OP_BLT | DEC_DIR_X_POS | DEC_DIR_Y_POS | DEC_SOURCE_MONOCHROME | 95517a48c7cSmrg DEC_START | DEC_DEST_UPD_TRCORNER | pApm->CurrentLayout.Setup_DEC; 95617a48c7cSmrg#endif 95717a48c7cSmrg 95817a48c7cSmrg if (pApm->apmTransparency) 95917a48c7cSmrg c |= DEC_SOURCE_TRANSPARENCY; 96017a48c7cSmrg 96117a48c7cSmrg if (srcy >= pApm->CurrentLayout.Scanlines) { 96217a48c7cSmrg struct ApmStippleCacheRec *pCache; 96317a48c7cSmrg CARD32 dist; 96417a48c7cSmrg 96517a48c7cSmrg /* 96617a48c7cSmrg * Offscreen linear stipple 96717a48c7cSmrg */ 96817a48c7cSmrg pCache = &pApm->apmCache[srcy / pApm->CurrentLayout.Scanlines - 1]; 96917a48c7cSmrg if (w != pCache->apmStippleCache.w * pApm->CurrentLayout.bitsPerPixel) { 97017a48c7cSmrg A(WaitForFifo)(pApm, 3); 97117a48c7cSmrg SETCLIP_LEFTTOP(x, y); 97217a48c7cSmrg SETCLIP_RIGHTBOT(x + w - 1, y + h - 1); 97317a48c7cSmrg SETCLIP_CTRL(0x01); 97417a48c7cSmrg pApm->apmClip = TRUE; 97517a48c7cSmrg w = pCache->apmStippleCache.w * pApm->CurrentLayout.bitsPerPixel; 97617a48c7cSmrg x -= srcx - pCache->apmStippleCache.x + offset; 97717a48c7cSmrg srcx = (srcy - pCache->apmStippleCache.y) & 7; 97817a48c7cSmrg srcy -= srcx; 97917a48c7cSmrg y -= srcx; 98017a48c7cSmrg h += srcx; 98117a48c7cSmrg srcx = pCache->apmStippleCache.x; 98217a48c7cSmrg } 98317a48c7cSmrg else if (pApm->apmClip) { 98417a48c7cSmrg A(WaitForFifo)(pApm, 1); 98517a48c7cSmrg SETCLIP_CTRL(0x00); 98617a48c7cSmrg pApm->apmClip = FALSE; 98717a48c7cSmrg } 98817a48c7cSmrg srcx += (srcy - pCache->apmStippleCache.y) * pCache->apmStippleCache.w; 98917a48c7cSmrg srcy = pCache->apmStippleCache.y % pApm->CurrentLayout.Scanlines; 99017a48c7cSmrg dist = srcx + srcy * pApm->CurrentLayout.displayWidth; 99117a48c7cSmrg srcx = dist & 0xFFF; 99217a48c7cSmrg srcy = dist >> 12; 99317a48c7cSmrg c |= DEC_SOURCE_CONTIG | DEC_SOURCE_LINEAR; 99417a48c7cSmrg } 99517a48c7cSmrg else if (offset) { 99617a48c7cSmrg A(WaitForFifo)(pApm, 3); 99717a48c7cSmrg SETCLIP_LEFTTOP(x, y); 99817a48c7cSmrg SETCLIP_RIGHTBOT(x + w, y + h); 99917a48c7cSmrg SETCLIP_CTRL(0x01); 100017a48c7cSmrg pApm->apmClip = TRUE; 100117a48c7cSmrg w += offset; 100217a48c7cSmrg x -= offset; 100317a48c7cSmrg } 100417a48c7cSmrg else if (pApm->apmClip) { 100517a48c7cSmrg A(WaitForFifo)(pApm, 1); 100617a48c7cSmrg SETCLIP_CTRL(0x00); 100717a48c7cSmrg pApm->apmClip = FALSE; 100817a48c7cSmrg } 100917a48c7cSmrg 101017a48c7cSmrg A(WaitForFifo)(pApm, 4); 101117a48c7cSmrg 101217a48c7cSmrg SETSOURCEXY(srcx, srcy); 101317a48c7cSmrg SETDESTXY(x, y); 101417a48c7cSmrg 101517a48c7cSmrg#ifdef FASTER 101617a48c7cSmrg SETDEC(c); 101717a48c7cSmrg SETWIDTHHEIGHT(w, h); 101817a48c7cSmrg#else 101917a48c7cSmrg SETWIDTHHEIGHT(w, h); 102017a48c7cSmrg SETDEC(c); 102117a48c7cSmrg#endif 102217a48c7cSmrg UPDATEDEST(x + w + 1, h); 102317a48c7cSmrg} 102417a48c7cSmrg 102517a48c7cSmrgstatic void 102617a48c7cSmrgA(SubsequentSolidBresenhamLine)(ScrnInfoPtr pScrn, int x1, int y1, int e1, 102717a48c7cSmrg int e2, int err, int length, int octant) 102817a48c7cSmrg{ 102917a48c7cSmrg APMDECL(pScrn); 103017a48c7cSmrg#ifdef FASTER 103117a48c7cSmrg u32 c = DEC_QUICKSTART_ONDIMX | DEC_OP_VECT_ENDP | DEC_DEST_UPD_LASTPIX | 103217a48c7cSmrg pApm->CurrentLayout.Setup_DEC; 103317a48c7cSmrg#else 103417a48c7cSmrg u32 c = DEC_START | DEC_OP_VECT_ENDP | DEC_DEST_UPD_LASTPIX | pApm->CurrentLayout.Setup_DEC; 103517a48c7cSmrg#endif 103617a48c7cSmrg int tmp; 103717a48c7cSmrg 103817a48c7cSmrg DPRINTNAME(SubsequentSolidBresenhamLine); 103917a48c7cSmrg 104017a48c7cSmrg A(WaitForFifo)(pApm, 5); 104117a48c7cSmrg SETDESTXY(x1,y1); 104217a48c7cSmrg SETDDA_ERRORTERM(err); 104317a48c7cSmrg SETDDA_ADSTEP(e1, e2); 104417a48c7cSmrg 104517a48c7cSmrg if (octant & YMAJOR) { 104617a48c7cSmrg c |= DEC_MAJORAXIS_Y; 104717a48c7cSmrg tmp = e1; e1 = e2; e2 = tmp; 104817a48c7cSmrg } 104917a48c7cSmrg else 105017a48c7cSmrg c |= DEC_MAJORAXIS_X; 105117a48c7cSmrg 105217a48c7cSmrg if (octant & XDECREASING) { 105317a48c7cSmrg c |= DEC_DIR_X_NEG; 105417a48c7cSmrg e1 = -e1; 105517a48c7cSmrg } 105617a48c7cSmrg else 105717a48c7cSmrg c |= DEC_DIR_X_POS; 105817a48c7cSmrg 105917a48c7cSmrg if (octant & YDECREASING) { 106017a48c7cSmrg c |= DEC_DIR_Y_NEG; 106117a48c7cSmrg e2 = -e2; 106217a48c7cSmrg } 106317a48c7cSmrg else 106417a48c7cSmrg c |= DEC_DIR_Y_POS; 106517a48c7cSmrg 106617a48c7cSmrg#ifdef FASTER 106717a48c7cSmrg SETDEC(c); 106817a48c7cSmrg SETWIDTH(length); 106917a48c7cSmrg#else 107017a48c7cSmrg SETWIDTH(length); 107117a48c7cSmrg SETDEC(c); 107217a48c7cSmrg#endif 107317a48c7cSmrg 107417a48c7cSmrg if (octant & YMAJOR) 107517a48c7cSmrg UPDATEDEST(x1 + e1 / 2, y1 + e2 / 2); 107617a48c7cSmrg else 107717a48c7cSmrg UPDATEDEST(x1 + e2 / 2, y1 + e1 / 2); 107817a48c7cSmrg if (pApm->apmClip) 107917a48c7cSmrg { 108017a48c7cSmrg pApm->apmClip = FALSE; 108117a48c7cSmrg A(WaitForFifo)(pApm, 1); 108217a48c7cSmrg SETCLIP_CTRL(0); 108317a48c7cSmrg } 108417a48c7cSmrg} 108517a48c7cSmrg 108617a48c7cSmrgstatic void 108717a48c7cSmrgA(SubsequentSolidBresenhamLine6422)(ScrnInfoPtr pScrn, int x1, int y1, int e1, 108817a48c7cSmrg int e2, int err, int length, int octant) 108917a48c7cSmrg{ 109017a48c7cSmrg APMDECL(pScrn); 109117a48c7cSmrg#ifdef FASTER 109217a48c7cSmrg u32 c = DEC_QUICKSTART_ONDIMX | DEC_OP_VECT_ENDP | DEC_DEST_UPD_LASTPIX | 109317a48c7cSmrg pApm->CurrentLayout.Setup_DEC; 109417a48c7cSmrg#else 109517a48c7cSmrg u32 c = DEC_START | DEC_OP_VECT_ENDP | DEC_DEST_UPD_LASTPIX | pApm->CurrentLayout.Setup_DEC; 109617a48c7cSmrg#endif 109717a48c7cSmrg int tmp; 109817a48c7cSmrg 109917a48c7cSmrg DPRINTNAME(SubsequentSolidBresenhamLine6422); 110017a48c7cSmrg 110117a48c7cSmrg A(WaitForFifo)(pApm, 1); 110217a48c7cSmrg SETDESTXY(x1,y1); 110317a48c7cSmrg A(WaitForFifo)(pApm, 4); 110417a48c7cSmrg SETDDA_ERRORTERM(err); 110517a48c7cSmrg SETDDA_ADSTEP(e1, e2); 110617a48c7cSmrg 110717a48c7cSmrg if (octant & YMAJOR) { 110817a48c7cSmrg c |= DEC_MAJORAXIS_Y; 110917a48c7cSmrg tmp = e1; e1 = e2; e2 = tmp; 111017a48c7cSmrg } 111117a48c7cSmrg else 111217a48c7cSmrg c |= DEC_MAJORAXIS_X; 111317a48c7cSmrg 111417a48c7cSmrg if (octant & XDECREASING) { 111517a48c7cSmrg c |= DEC_DIR_X_NEG; 111617a48c7cSmrg e1 = -e1; 111717a48c7cSmrg } 111817a48c7cSmrg else 111917a48c7cSmrg c |= DEC_DIR_X_POS; 112017a48c7cSmrg 112117a48c7cSmrg if (octant & YDECREASING) { 112217a48c7cSmrg c |= DEC_DIR_Y_NEG; 112317a48c7cSmrg e2 = -e2; 112417a48c7cSmrg } 112517a48c7cSmrg else 112617a48c7cSmrg c |= DEC_DIR_Y_POS; 112717a48c7cSmrg 112817a48c7cSmrg#ifdef FASTER 112917a48c7cSmrg SETDEC(c); 113017a48c7cSmrg SETWIDTH(length); 113117a48c7cSmrg#else 113217a48c7cSmrg SETWIDTH(length); 113317a48c7cSmrg SETDEC(c); 113417a48c7cSmrg#endif 113517a48c7cSmrg 113617a48c7cSmrg if (octant & YMAJOR) 113717a48c7cSmrg UPDATEDEST(x1 + e1 / 2, y1 + e2 / 2); 113817a48c7cSmrg else 113917a48c7cSmrg UPDATEDEST(x1 + e2 / 2, y1 + e1 / 2); 114017a48c7cSmrg if (pApm->apmClip) 114117a48c7cSmrg { 114217a48c7cSmrg pApm->apmClip = FALSE; 114317a48c7cSmrg A(WaitForFifo)(pApm, 1); 114417a48c7cSmrg SETCLIP_CTRL(0); 114517a48c7cSmrg } 114617a48c7cSmrg} 114717a48c7cSmrg 114817a48c7cSmrgstatic void 114917a48c7cSmrgA(SetClippingRectangle)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 115017a48c7cSmrg{ 115117a48c7cSmrg APMDECL(pScrn); 115217a48c7cSmrg 115317a48c7cSmrg DPRINTNAME(SetClippingRectangle); 115417a48c7cSmrg A(WaitForFifo)(pApm, 3); 115517a48c7cSmrg SETCLIP_LEFTTOP(x1,y1); 115617a48c7cSmrg SETCLIP_RIGHTBOT(x2,y2); 115717a48c7cSmrg SETCLIP_CTRL(0x01); 115817a48c7cSmrg pApm->apmClip = TRUE; 115917a48c7cSmrg} 116017a48c7cSmrg 116117a48c7cSmrgstatic void 116217a48c7cSmrgA(SyncBlt)(ApmPtr pApm) 116317a48c7cSmrg{ 116417a48c7cSmrg int again = (pApm->Chipset == AP6422); 116517a48c7cSmrg 116617a48c7cSmrg do { 116717a48c7cSmrg while (!(STATUS() & STATUS_HOSTBLTBUSY)) 116817a48c7cSmrg ; 116917a48c7cSmrg } 117017a48c7cSmrg while (again--); /* See remark in Sync6422 */ 117117a48c7cSmrg} 117217a48c7cSmrgstatic void 117317a48c7cSmrgA(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h, 117417a48c7cSmrg unsigned char *src, int srcwidth, int rop, 117517a48c7cSmrg unsigned int planemask, int trans, int bpp, int depth) 117617a48c7cSmrg{ 117717a48c7cSmrg APMDECL(pScrn); 117817a48c7cSmrg int dwords, skipleft, Bpp = bpp >> 3; 117917a48c7cSmrg Bool beCareful = FALSE; 118017a48c7cSmrg unsigned char *dst = ((unsigned char *)pApm->FbBase) + x * Bpp + y * pApm->CurrentLayout.bytesPerScanline; 118117a48c7cSmrg int PlusOne = 0, mask, count; 118217a48c7cSmrg 118317a48c7cSmrg DPRINTNAME(WritePixmap); 118417a48c7cSmrg if (rop == GXnoop) 118517a48c7cSmrg return; 118617a48c7cSmrg /* 118717a48c7cSmrg * The function seems to crash more than it feels good. I hope that a 118817a48c7cSmrg * good sync will help. This sync is anyway needed for direct write. 118917a48c7cSmrg */ 119017a48c7cSmrg (*pApm->AccelInfoRec->Sync)(pScrn); 119117a48c7cSmrg /* 119217a48c7cSmrg * First the fast case : source and dest have same alignment. Doc says 119317a48c7cSmrg * it's faster to do it here, which may be true since one has to read 119417a48c7cSmrg * the chip when CPU to screen-ing. 119517a48c7cSmrg */ 119617a48c7cSmrg if ((skipleft = (long)src & 3L) == ((long)dst & 3L) && rop == GXcopy) { 119717a48c7cSmrg int skipright; 119817a48c7cSmrg 119917a48c7cSmrg if (skipleft) 120017a48c7cSmrg skipleft = 4 - skipleft; 120117a48c7cSmrg dwords = (skipright = w * Bpp - skipleft) >> 2; 120217a48c7cSmrg skipright %= 4; 120317a48c7cSmrg if (!skipleft && !skipright) 120417a48c7cSmrg while (h-- > 0) { 120517a48c7cSmrg CARD32 *src2 = (CARD32 *)src; 120617a48c7cSmrg CARD32 *dst2 = (CARD32 *)dst; 120717a48c7cSmrg 120817a48c7cSmrg for (count = dwords; count-- > 0; ) 120917a48c7cSmrg *dst2++ = *src2++; 121017a48c7cSmrg src += srcwidth; 121117a48c7cSmrg dst += pApm->CurrentLayout.bytesPerScanline; 121217a48c7cSmrg } 121317a48c7cSmrg else if (!skipleft) 121417a48c7cSmrg while (h-- > 0) { 121517a48c7cSmrg CARD32 *src2 = (CARD32 *)src; 121617a48c7cSmrg CARD32 *dst2 = (CARD32 *)dst; 121717a48c7cSmrg 121817a48c7cSmrg for (count = dwords; count-- > 0; ) 121917a48c7cSmrg *dst2++ = *src2++; 122017a48c7cSmrg for (count = skipright; count-- > 0; ) 122117a48c7cSmrg ((char *)dst2)[count] = ((char *)src2)[count]; 122217a48c7cSmrg src += srcwidth; 122317a48c7cSmrg dst += pApm->CurrentLayout.bytesPerScanline; 122417a48c7cSmrg } 122517a48c7cSmrg else if (!skipright) 122617a48c7cSmrg while (h-- > 0) { 122717a48c7cSmrg CARD32 *src2 = (CARD32 *)(src + skipleft); 122817a48c7cSmrg CARD32 *dst2 = (CARD32 *)(dst + skipleft); 122917a48c7cSmrg 123017a48c7cSmrg for (count = skipleft; count-- > 0; ) 123117a48c7cSmrg dst[count] = src[count]; 123217a48c7cSmrg for (count = dwords; count-- > 0; ) 123317a48c7cSmrg *dst2++ = *src2++; 123417a48c7cSmrg src += srcwidth; 123517a48c7cSmrg dst += pApm->CurrentLayout.bytesPerScanline; 123617a48c7cSmrg } 123717a48c7cSmrg else 123817a48c7cSmrg while (h-- > 0) { 123917a48c7cSmrg CARD32 *src2 = (CARD32 *)(src + skipleft); 124017a48c7cSmrg CARD32 *dst2 = (CARD32 *)(dst + skipleft); 124117a48c7cSmrg 124217a48c7cSmrg for (count = skipleft; count-- > 0; ) 124317a48c7cSmrg dst[count] = src[count]; 124417a48c7cSmrg for (count = dwords; count-- > 0; ) 124517a48c7cSmrg *dst2++ = *src2++; 124617a48c7cSmrg for (count = skipright; count-- > 0; ) 124717a48c7cSmrg ((char *)dst2)[count] = ((char *)src2)[count]; 124817a48c7cSmrg src += srcwidth; 124917a48c7cSmrg dst += pApm->CurrentLayout.bytesPerScanline; 125017a48c7cSmrg } 125117a48c7cSmrg 125217a48c7cSmrg return; 125317a48c7cSmrg } 125417a48c7cSmrg 125517a48c7cSmrg if (skipleft) { 125617a48c7cSmrg if (Bpp == 3) 125717a48c7cSmrg skipleft = 4 - skipleft; 125817a48c7cSmrg else 125917a48c7cSmrg skipleft /= Bpp; 126017a48c7cSmrg 126117a48c7cSmrg if (x < skipleft) { 126217a48c7cSmrg skipleft = 0; 126317a48c7cSmrg beCareful = TRUE; 126417a48c7cSmrg goto BAD_ALIGNMENT; 126517a48c7cSmrg } 126617a48c7cSmrg 126717a48c7cSmrg x -= skipleft; 126817a48c7cSmrg w += skipleft; 126917a48c7cSmrg 127017a48c7cSmrg if (Bpp == 3) 127117a48c7cSmrg src -= 3 * skipleft; 127217a48c7cSmrg else /* is this Alpha friendly ? */ 127317a48c7cSmrg src = (unsigned char*)((long)src & ~0x03L); 127417a48c7cSmrg } 127517a48c7cSmrg 127617a48c7cSmrgBAD_ALIGNMENT: 127717a48c7cSmrg 127817a48c7cSmrg dwords = ((w * Bpp) + 3) >> 2; 127917a48c7cSmrg mask = (pApm->CurrentLayout.bitsPerPixel / 8) - 1; 128017a48c7cSmrg 128117a48c7cSmrg if (dwords & mask) { 128217a48c7cSmrg /* 128317a48c7cSmrg * Experimental... 128417a48c7cSmrg * It seems the AT3D needs a padding of scanline to a multiple of 128517a48c7cSmrg * 4 pixels, not only bytes. 128617a48c7cSmrg */ 128717a48c7cSmrg PlusOne = mask - (dwords & mask) + 1; 128817a48c7cSmrg } 128917a48c7cSmrg 129017a48c7cSmrg A(SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth); 129117a48c7cSmrg A(SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft); 129217a48c7cSmrg 129317a48c7cSmrg if (beCareful) { 129417a48c7cSmrg /* in cases with bad alignment we have to be careful not 129517a48c7cSmrg to read beyond the end of the source */ 129617a48c7cSmrg if (((x * Bpp) + (dwords << 2)) > srcwidth) h--; 129717a48c7cSmrg else beCareful = FALSE; 129817a48c7cSmrg } 129917a48c7cSmrg 130017a48c7cSmrg srcwidth -= (dwords << 2); 130117a48c7cSmrg 130217a48c7cSmrg while (h--) { 130317a48c7cSmrg for (count = dwords; count-- > 0; ) { 130417a48c7cSmrg A(SyncBlt)(pApm); 130517a48c7cSmrg *(CARD32*)pApm->BltMap = *(CARD32*)src; 130617a48c7cSmrg src += 4; 130717a48c7cSmrg } 130817a48c7cSmrg src += srcwidth; 130917a48c7cSmrg for (count = PlusOne; count-- > 0; ) { 131017a48c7cSmrg int status; 131117a48c7cSmrg 131217a48c7cSmrg while (!((status = STATUS()) & STATUS_HOSTBLTBUSY)) 131317a48c7cSmrg if (!(status & STATUS_ENGINEBUSY)) 131417a48c7cSmrg break; 131517a48c7cSmrg if (pApm->Chipset == AP6422) /* See remark in Sync6422 */ 131617a48c7cSmrg while (!((status = STATUS()) & STATUS_HOSTBLTBUSY)) 131717a48c7cSmrg if (!(status & STATUS_ENGINEBUSY)) 131817a48c7cSmrg break; 131917a48c7cSmrg if (status & STATUS_ENGINEBUSY) 132017a48c7cSmrg *(CARD32*)pApm->BltMap = 0x00000000; 132117a48c7cSmrg } 132217a48c7cSmrg } 132317a48c7cSmrg if (beCareful) { 132417a48c7cSmrg int shift = ((long)src & 0x03L) << 3; 132517a48c7cSmrg 132617a48c7cSmrg if (--dwords) { 132717a48c7cSmrg for (count = dwords >> 2; count-- > 0; ) { 132817a48c7cSmrg A(SyncBlt)(pApm); 132917a48c7cSmrg *(CARD32*)pApm->BltMap = *(CARD32*)src; 133017a48c7cSmrg src += 4; 133117a48c7cSmrg } 133217a48c7cSmrg } 133317a48c7cSmrg A(SyncBlt)(pApm); 133417a48c7cSmrg *((CARD32*)pApm->BltMap) = *((CARD32*)src) >> shift; 133517a48c7cSmrg } 133617a48c7cSmrg 133717a48c7cSmrg pApm->apmClip = FALSE; 133817a48c7cSmrg A(WaitForFifo)(pApm, 1); 133917a48c7cSmrg SETCLIP_CTRL(0); 134017a48c7cSmrg} 134117a48c7cSmrg 134217a48c7cSmrgstatic void 134317a48c7cSmrgA(FillImageWriteRects)(ScrnInfoPtr pScrn, int rop, unsigned int planemask, 134417a48c7cSmrg int nBox, BoxPtr pBox, int xorg, int yorg, 134517a48c7cSmrg PixmapPtr pPix) 134617a48c7cSmrg{ 134717a48c7cSmrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 134817a48c7cSmrg int x, y, phaseY, phaseX, height, width, blit_w; 134917a48c7cSmrg int pHeight = pPix->drawable.height; 135017a48c7cSmrg int pWidth = pPix->drawable.width; 135117a48c7cSmrg int depth = pPix->drawable.depth; 135217a48c7cSmrg int bpp = pPix->drawable.bitsPerPixel; 135317a48c7cSmrg unsigned char *pSrc; 135417a48c7cSmrg int srcwidth = pPix->devKind; 135517a48c7cSmrg 135617a48c7cSmrg while(nBox--) { 135717a48c7cSmrg x = pBox->x1; 135817a48c7cSmrg y = pBox->y1; 135917a48c7cSmrg phaseY = (pBox->y1 - yorg) % pHeight; 136017a48c7cSmrg if(phaseY < 0) phaseY += pHeight; 136117a48c7cSmrg phaseX = (x - xorg) % pWidth; 136217a48c7cSmrg pSrc = (unsigned char *)pPix->devPrivate.ptr + 136317a48c7cSmrg phaseX * pPix->drawable.bitsPerPixel / 8; 136417a48c7cSmrg if(phaseX < 0) phaseX += pWidth; 136517a48c7cSmrg height = pBox->y2 - pBox->y1; 136617a48c7cSmrg width = pBox->x2 - x; 136717a48c7cSmrg 136817a48c7cSmrg while(1) { 136917a48c7cSmrg int ch = height, cp = phaseY, cy = y; 137017a48c7cSmrg 137117a48c7cSmrg blit_w = pWidth - phaseX; 137217a48c7cSmrg if(blit_w > width) blit_w = width; 137317a48c7cSmrg 137417a48c7cSmrg while (ch > 0) { 137517a48c7cSmrg int h = MIN(pHeight - cp, ch); 137617a48c7cSmrg 137717a48c7cSmrg A(WritePixmap)(pScrn, x, cy, blit_w, h, pSrc + cp * srcwidth, 137817a48c7cSmrg srcwidth, rop, planemask, FALSE, bpp, depth); 137917a48c7cSmrg cy += h; 138017a48c7cSmrg ch -= h; 138117a48c7cSmrg cp = 0; 138217a48c7cSmrg } 138317a48c7cSmrg 138417a48c7cSmrg width -= blit_w; 138517a48c7cSmrg if(!width) break; 138617a48c7cSmrg x += blit_w; 138717a48c7cSmrg phaseX = (phaseX + blit_w) % pWidth; 138817a48c7cSmrg } 138917a48c7cSmrg pBox++; 139017a48c7cSmrg } 139117a48c7cSmrg 139217a48c7cSmrg SET_SYNC_FLAG(infoRec); 139317a48c7cSmrg} 139417a48c7cSmrg 139517a48c7cSmrgstatic void A(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn,int patx,int paty, 139617a48c7cSmrg int rop, unsigned int planemask, 139717a48c7cSmrg int transparency_color) 139817a48c7cSmrg{ 139917a48c7cSmrg APMDECL(pScrn); 140017a48c7cSmrg 140117a48c7cSmrg DPRINTNAME(SetupForColor8x8PatternFillRect); 140217a48c7cSmrg if (transparency_color != -1) { 140317a48c7cSmrg#ifndef FASTER 140417a48c7cSmrg pApm->apmTransparency = TRUE; 140517a48c7cSmrg A(WaitForFifo)(pApm, 2 + pApm->apmClip); 140617a48c7cSmrg#else 140717a48c7cSmrg A(WaitForFifo)(pApm, 3 + pApm->apmClip); 140817a48c7cSmrg SETDEC(pApm->CurrentLayout.Setup_DEC | DEC_OP_BLT | 140917a48c7cSmrg DEC_DEST_XY | DEC_PATTERN_88_8bCOLOR | DEC_SOURCE_TRANSPARENCY | 141017a48c7cSmrg DEC_QUICKSTART_ONDIMX); 141117a48c7cSmrg#endif 141217a48c7cSmrg SETBACKGROUNDCOLOR(transparency_color); 141317a48c7cSmrg } 141417a48c7cSmrg else { 141517a48c7cSmrg#ifndef FASTER 141617a48c7cSmrg pApm->apmTransparency = FALSE; 141717a48c7cSmrg A(WaitForFifo)(pApm, 1 + pApm->apmClip); 141817a48c7cSmrg#else 141917a48c7cSmrg A(WaitForFifo)(pApm, 2 + pApm->apmClip); 142017a48c7cSmrg SETDEC(pApm->CurrentLayout.Setup_DEC | DEC_OP_BLT | 142117a48c7cSmrg DEC_DEST_XY | DEC_PATTERN_88_8bCOLOR | DEC_QUICKSTART_ONDIMX); 142217a48c7cSmrg#endif 142317a48c7cSmrg } 142417a48c7cSmrg if (pApm->apmClip) { 142517a48c7cSmrg SETCLIP_CTRL(0); 142617a48c7cSmrg pApm->apmClip = FALSE; 142717a48c7cSmrg } 142817a48c7cSmrg SETROP(apmROP[rop]); 142917a48c7cSmrg} 143017a48c7cSmrg 143117a48c7cSmrgstatic void A(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx, 143217a48c7cSmrg int paty, int x, int y, 143317a48c7cSmrg int w, int h) 143417a48c7cSmrg{ 143517a48c7cSmrg APMDECL(pScrn); 143617a48c7cSmrg 143717a48c7cSmrg DPRINTNAME(SubsequentColor8x8PatternFillRect); 143817a48c7cSmrg#ifndef FASTER 143917a48c7cSmrg A(WaitForFifo)(pApm, 5); 144017a48c7cSmrg#else 144117a48c7cSmrg A(WaitForFifo)(pApm, 4); 144217a48c7cSmrg#endif 144317a48c7cSmrg SETSOURCEXY(patx, paty); 144417a48c7cSmrg SETDESTXY(x, y); 144517a48c7cSmrg SETWIDTHHEIGHT(w, h); 144617a48c7cSmrg UPDATEDEST(x + w + 1, y); 144717a48c7cSmrg#ifndef FASTER 144817a48c7cSmrg SETDEC(pApm->CurrentLayout.Setup_DEC | DEC_OP_BLT | 144917a48c7cSmrg DEC_DEST_XY | (pApm->apmTransparency * DEC_SOURCE_TRANSPARENCY) | 145017a48c7cSmrg DEC_PATTERN_88_8bCOLOR | DEC_START); 145117a48c7cSmrg#endif 145217a48c7cSmrg} 145317a48c7cSmrg#endif 145417a48c7cSmrg 145517a48c7cSmrgstatic void 145617a48c7cSmrgA(Sync)(ScrnInfoPtr pScrn) 145717a48c7cSmrg{ 145817a48c7cSmrg APMDECL(pScrn); 145917a48c7cSmrg volatile u32 i, stat; 146017a48c7cSmrg 146117a48c7cSmrg for(i = 0; i < MAXLOOP; i++) { 146217a48c7cSmrg stat = STATUS(); 146317a48c7cSmrg if ((!(stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY))) && 146417a48c7cSmrg ((stat & STATUS_FIFO) >= 8)) 146517a48c7cSmrg break; 146617a48c7cSmrg } 146717a48c7cSmrg if (i == MAXLOOP) { 146817a48c7cSmrg unsigned int status = STATUS(); 146917a48c7cSmrg 147017a48c7cSmrg WRXB(0x1FF, 0); 147117a48c7cSmrg if (!xf86ServerIsExiting()) 14720dd80ee0Smrg FatalError("Hung in ApmSync" APM_SUFF_24 "(%d) (Status = 0x%08X)\n", pScrn->pScreen->myNum, status); 147317a48c7cSmrg } 147417a48c7cSmrg if (pApm->apmClip) { 147517a48c7cSmrg SETCLIP_CTRL(0); 147617a48c7cSmrg pApm->apmClip = FALSE; 147717a48c7cSmrg } 147817a48c7cSmrg} 147917a48c7cSmrg 148017a48c7cSmrg#if PSZ != 24 148117a48c7cSmrgstatic void 148217a48c7cSmrgA(Sync6422)(ScrnInfoPtr pScrn) 148317a48c7cSmrg{ 148417a48c7cSmrg APMDECL(pScrn); 148517a48c7cSmrg volatile u32 i, j, stat; 148617a48c7cSmrg 148717a48c7cSmrg for (j = 0; j < 2; j++) { 148817a48c7cSmrg /* 148917a48c7cSmrg * From Henrik Harmsen : 149017a48c7cSmrg * 149117a48c7cSmrg * This is a kludge. We can't trust the status register. Don't 149217a48c7cSmrg * know why... We shouldn't be forced to read the status reg and get 149317a48c7cSmrg * a correct value more than once... 149417a48c7cSmrg */ 149517a48c7cSmrg for(i = 0; i < MAXLOOP; i++) { 149617a48c7cSmrg stat = STATUS(); 149717a48c7cSmrg if ((!(stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY))) && 149817a48c7cSmrg ((stat & STATUS_FIFO) >= 4)) 149917a48c7cSmrg break; 150017a48c7cSmrg } 150117a48c7cSmrg } 150217a48c7cSmrg if (i == MAXLOOP) { 150317a48c7cSmrg unsigned int status = STATUS(); 150417a48c7cSmrg 150517a48c7cSmrg WRXB(0x1FF, 0); 150617a48c7cSmrg if (!xf86ServerIsExiting()) 150717a48c7cSmrg FatalError("Hung in ApmSync6422() (Status = 0x%08X)\n", status); 150817a48c7cSmrg } 150917a48c7cSmrg if (pApm->apmClip) { 151017a48c7cSmrg SETCLIP_CTRL(0); 151117a48c7cSmrg pApm->apmClip = FALSE; 151217a48c7cSmrg } 151317a48c7cSmrg} 151417a48c7cSmrg#endif 151517a48c7cSmrg#include "apm_video.c" 151617a48c7cSmrg 151717a48c7cSmrg 151817a48c7cSmrg#undef RDXB 151917a48c7cSmrg#undef RDXW 152017a48c7cSmrg#undef RDXL 152117a48c7cSmrg#undef WRXB 152217a48c7cSmrg#undef WRXW 152317a48c7cSmrg#undef WRXL 152417a48c7cSmrg#undef ApmWriteSeq 152517a48c7cSmrg#define RDXB RDXB_M 152617a48c7cSmrg#define RDXW RDXW_M 152717a48c7cSmrg#define RDXL RDXL_M 152817a48c7cSmrg#define WRXB WRXB_M 152917a48c7cSmrg#define WRXW WRXW_M 153017a48c7cSmrg#define WRXL WRXL_M 153117a48c7cSmrg#define ApmWriteSeq(idx, val) do { APMVGAB(0x3C4) = (idx); APMVGAB(0x3C5) = (val); break; } while(1) 153217a48c7cSmrg#undef DPRINTNAME 153317a48c7cSmrg#undef A 153417a48c7cSmrg#undef DEPTH 153517a48c7cSmrg#undef PSZ 153617a48c7cSmrg#undef APM_SUFF_24 1537