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