1/*
2 * Copyright 1996, 1997, 1998 by David Bateman <dbateman@ee.uts.edu.au>
3 *   Modified 1997, 1998 by Nozomi Ytow
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of the authors not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission.  The authors makes no representations
12 * about the suitability of this software for any purpose.  It is provided
13 * "as is" without express or implied warranty.
14 *
15 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28/*
29 * When monochrome tiles/stipples are cached on the HiQV chipsets the
30 * pitch of the monochrome data is the displayWidth. The HiQV manuals
31 * state that the source pitch is ignored with monochrome data, and so
32 * "officially" there the XAA cached monochrome data can't be used. But
33 * it appears that by not setting the monochrome source alignment in
34 * BR03, the monochrome source pitch is forced to the displayWidth!!
35 *
36 * To enable the use of this undocumented feature, uncomment the define
37 * below.
38 */
39#define UNDOCUMENTED_FEATURE
40
41/* All drivers should typically include these */
42#include "xf86.h"
43#include "xf86_OSproc.h"
44#include "compiler.h"
45
46/* Drivers that need to access the PCI config space directly need this */
47#include "xf86Pci.h"
48
49/* Drivers that use XAA need this */
50#include "xf86fbman.h"
51
52/* Our driver specific include file */
53#include "ct_driver.h"
54
55#define CATNAME(prefix,subname) prefix##subname
56
57#ifdef CHIPS_MMIO
58#ifdef CHIPS_HIQV
59#include "ct_BltHiQV.h"
60#define CTNAME(subname) CATNAME(CHIPSHiQV,subname)
61#else
62#include "ct_BlitMM.h"
63#define CTNAME(subname) CATNAME(CHIPSMMIO,subname)
64#endif
65#else
66#include "ct_Blitter.h"
67#define CTNAME(subname) CATNAME(CHIPS,subname)
68#endif
69
70#ifdef HAVE_XAA_H
71
72#ifdef DEBUG
73# define DEBUG_P(x) ErrorF(x"\n");
74#elif defined X_DEBUG
75# define DEBUG_P(x) snprintf(CTNAME(accel_debug),1024,x"\n");
76#else
77# define DEBUG_P(x) /**/
78#endif
79
80#ifdef X_DEBUG
81static char CTNAME(accel_debug)[1024];
82#endif
83
84#ifdef CHIPS_HIQV
85static void CTNAME(DepthChange)(ScrnInfoPtr pScrn, int depth);
86#endif
87static void CTNAME(8SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
88				int rop, unsigned int planemask);
89static void CTNAME(16SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
90				int rop, unsigned int planemask);
91static void CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
92				int rop, unsigned int planemask);
93static void CTNAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
94					int x, int y, int w, int h);
95#ifndef CHIPS_HIQV
96static void CTNAME(24SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
97					int x, int y, int w, int h);
98#else
99static void CTNAME(32SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
100				int rop, unsigned int planemask);
101static void CTNAME(32SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
102					int x, int y, int w, int h);
103#endif
104static void CTNAME(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir,
105				int ydir, int rop, unsigned int planemask,
106				int trans);
107static void CTNAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn,
108				int srcX, int srcY, int dstX, int dstY,
109				int w, int h);
110static void CTNAME(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
111				int bg, int rop, unsigned int planemask);
112static void CTNAME(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
113				int x, int y, int w, int h, int skipleft);
114#ifndef CHIPS_HIQV
115static XAACacheInfoPtr CTNAME(CacheMonoStipple)(ScrnInfoPtr pScrn,
116				PixmapPtr pPix);
117#endif
118#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
119static void CTNAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
120				int fg, int bg, int rop,
121				unsigned int planemask);
122static void CTNAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
123				int x, int y, int w, int h,
124				int srcx, int srcy, int skipleft);
125#endif
126static void CTNAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn,
127				int patx, int paty, int fg, int bg,
128				int rop, unsigned int planemask);
129static void CTNAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn,
130				int patx, int paty,
131				int x, int y, int w, int h );
132static void CTNAME(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn,
133				int patx, int paty, int rop,
134				unsigned int planemask, int trans);
135static void CTNAME(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn,
136				int patx, int paty,
137				int x, int y, int w, int h );
138#ifndef CHIPS_HIQV
139static void CTNAME(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
140   				unsigned int planemask,
141				int transparency_color, int bpp, int depth);
142static void CTNAME(SubsequentImageWriteRect)(ScrnInfoPtr pScrn,
143				int x, int y, int w, int h, int skipleft);
144#else
145static void  CTNAME(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
146		unsigned char *src, int srcwidth, int rop,
147		unsigned int planemask, int trans, int bpp, int depth);
148#if 0
149static void  CTNAME(ReadPixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
150		unsigned char *dst, int dstwidth, int bpp, int depth);
151#endif
152#endif
153#if X_BYTE_ORDER == X_BIG_ENDIAN
154# define BE_SWAP(pScrn,cPtr,x) \
155  if (!BE_SWAP_APRETURE(pScrn,cPtr)) { \
156       CARD8 XR0A = cPtr->readXR(cPtr,0x0A); \
157       cPtr->writeXR(cPtr, 0x0A, (XR0A & 0xcf) | x); \
158  }
159
160/* 16 bit Byte Swap */
161# define BE_SWAPON(pScrn,cPtr) BE_SWAP(pScrn,cPtr,0x10)
162# define BE_SWAPOFF(pScrn,cPtr) BE_SWAP(pScrn,cPtr,0x0)
163#else
164# define BE_SWAPON(pScrn,cPtr)
165# define BE_SWAPOFF(pScrn,cPtr)
166#endif
167#endif
168Bool
169CTNAME(AccelInit)(ScreenPtr pScreen)
170{
171#ifdef HAVE_XAA_H
172    XAAInfoRecPtr infoPtr;
173    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
174    CHIPSPtr cPtr = CHIPSPTR(pScrn);
175    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
176
177    DEBUG_P("AccelInit");
178    cPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
179    if(!infoPtr) return FALSE;
180
181    /*
182     * Setup some global variables
183     */
184    cAcl->BytesPerPixel = pScrn->bitsPerPixel >> 3;
185    cAcl->BitsPerPixel = pScrn->bitsPerPixel;
186    cAcl->PitchInBytes = pScrn->displayWidth * cAcl->BytesPerPixel;
187    cAcl->planemask = -1;
188    cAcl->bgColor = -1;
189    cAcl->fgColor = -1;
190    cAcl->FbOffset = 0;
191
192    /*
193     * Set up the main acceleration flags.
194     */
195    if (cAcl->CacheEnd > cAcl->CacheStart) infoPtr->Flags = PIXMAP_CACHE;
196
197    if (cPtr->Flags & ChipsLinearSupport)
198	infoPtr->Flags |= OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
199
200    infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
201
202    /*
203     * The following line installs a "Sync" function, that waits for
204     * all coprocessor operations to complete.
205     */
206    infoPtr->Sync = CTNAME(Sync);
207
208    /*
209     * Setup a Screen to Screen copy (BitBLT) primitive
210     */
211#ifndef CHIPS_HIQV
212    infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
213    if (cAcl->BitsPerPixel == 24)
214	infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
215#else
216    infoPtr->ScreenToScreenCopyFlags = 0;
217    if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
218	infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
219
220    /* A Chips and Technologies application notes says that some
221     * 65550 have a bug that prevents 16bpp transparency. It probably
222     * applies to 24 bpp as well (Someone with a 65550 care to check?).
223     * Selection of this controlled in Probe.
224     */
225    if (!(cPtr->Flags & ChipsColorTransparency))
226	infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
227#endif
228
229    infoPtr->SetupForScreenToScreenCopy = CTNAME(SetupForScreenToScreenCopy);
230    infoPtr->SubsequentScreenToScreenCopy =
231		CTNAME(SubsequentScreenToScreenCopy);
232
233    /*
234     * Install the low-level functions for drawing solid filled rectangles.
235     */
236    infoPtr->SolidFillFlags |= NO_PLANEMASK;
237    switch (cAcl->BitsPerPixel) {
238    case 8 :
239	infoPtr->SetupForSolidFill = CTNAME(8SetupForSolidFill);
240	infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
241        break;
242    case 16 :
243	infoPtr->SetupForSolidFill = CTNAME(16SetupForSolidFill);
244	infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
245        break;
246    case 24 :
247	infoPtr->SetupForSolidFill = CTNAME(24SetupForSolidFill);
248#ifdef CHIPS_HIQV
249	infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
250#else
251	/*
252	 * The version of this function here uses three different
253	 * algorithms in an attempt to maximise performance. One
254	 * for RGB_EQUAL, another for !RGB_EQUAL && GXCOPY_ONLY
255	 * and yet another for !RGB_EQUAL && !GXCOPY_ONLY. The
256	 * first two versions use the 8bpp engine for the fill,
257	 * whilst the second uses a framebuffer routine to create
258	 * one scanline of the fill in off screen memory which is
259	 * then used by a CopyArea function with a complex ROP.
260	 */
261	infoPtr->SubsequentSolidFillRect = CTNAME(24SubsequentSolidFillRect);
262#if 0
263	/* How can an unsigned quantity be less than zero? */
264        if (cAcl->ScratchAddress < 0)
265	    infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
266#endif
267#endif
268        break;
269#ifdef CHIPS_HIQV
270    case 32:
271        if (cAcl->ScratchAddress > 0) {
272	    infoPtr->SetupForSolidFill = CTNAME(32SetupForSolidFill);
273	    infoPtr->SubsequentSolidFillRect =
274		CTNAME(32SubsequentSolidFillRect);
275	}
276        break;
277#endif
278    }
279
280#ifdef CHIPS_HIQV
281    /* At 32bpp we can't use the other acceleration */
282    if (cAcl->BitsPerPixel == 32) goto chips_imagewrite;
283#endif
284
285    /*
286     * Setup the functions that perform monochrome colour expansion
287     */
288
289#ifdef CHIPS_HIQV
290    infoPtr->CPUToScreenColorExpandFillFlags =
291# if X_BYTE_ORDER != X_BIG_ENDIAN
292	BIT_ORDER_IN_BYTE_MSBFIRST |
293# endif
294	CPU_TRANSFER_PAD_QWORD |
295	LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X |
296	ROP_NEEDS_SOURCE;
297# ifdef UNDOCUMENTED_FEATURE
298    infoPtr->ScreenToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST
299	| LEFT_EDGE_CLIPPING;
300# endif
301    if (cAcl->BitsPerPixel == 24) {
302	infoPtr->CPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
303# ifdef UNDOCUMENTED_FEATURE
304	infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
305# endif
306#if X_BYTE_ORDER == X_BIG_ENDIAN
307	if (!BE_SWAP_APRETURE(pScrn,cPtr))
308	    infoPtr->CPUToScreenColorExpandFillFlags |= SYNC_AFTER_COLOR_EXPAND;
309#endif
310    }
311    /* The ct65550 has problems with transparency which leads to video
312     * corruption unless disabled.
313     */
314    if (!(cPtr->Flags & ChipsColorTransparency)) {
315	infoPtr->CPUToScreenColorExpandFillFlags |= NO_TRANSPARENCY;
316# ifdef UNDOCUMENTED_FEATURE
317	infoPtr->ScreenToScreenColorExpandFillFlags |= NO_TRANSPARENCY;
318# endif
319    }
320#else /* CHIPS_HIQV */
321    infoPtr->CPUToScreenColorExpandFillFlags =
322	BIT_ORDER_IN_BYTE_MSBFIRST | CPU_TRANSFER_PAD_DWORD |
323	ROP_NEEDS_SOURCE;
324    infoPtr->ScreenToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST;
325    infoPtr->CacheColorExpandDensity = 8;
326
327    if (cAcl->BitsPerPixel == 24)
328	infoPtr->CPUToScreenColorExpandFillFlags |= TRIPLE_BITS_24BPP |
329	    RGB_EQUAL | NO_PLANEMASK;
330#endif /* CHIPS_HIQV */
331
332    infoPtr->SetupForCPUToScreenColorExpandFill =
333		CTNAME(SetupForCPUToScreenColorExpandFill);
334    infoPtr->SubsequentCPUToScreenColorExpandFill =
335		CTNAME(SubsequentCPUToScreenColorExpandFill);
336
337#ifndef CHIPS_HIQV
338    if (cAcl->BitsPerPixel != 24) {
339#endif
340#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
341	infoPtr->SetupForScreenToScreenColorExpandFill =
342		CTNAME(SetupForScreenToScreenColorExpandFill);
343	infoPtr->SubsequentScreenToScreenColorExpandFill =
344		CTNAME(SubsequentScreenToScreenColorExpandFill);
345#endif
346#ifndef CHIPS_HIQV
347	infoPtr->CacheMonoStipple = CTNAME(CacheMonoStipple);
348    }
349#endif
350
351    infoPtr->ColorExpandBase = (unsigned char *)cAcl->BltDataWindow;
352    infoPtr->ColorExpandRange = 64 * 1024;
353
354    /* Mono 8x8 pattern fills */
355    infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
356	BIT_ORDER_IN_BYTE_MSBFIRST | HARDWARE_PATTERN_SCREEN_ORIGIN;
357
358#ifdef CHIPS_HIQV
359    infoPtr->SetupForMono8x8PatternFill =
360	CTNAME(SetupForMono8x8PatternFill);
361    infoPtr->SubsequentMono8x8PatternFillRect =
362	CTNAME(SubsequentMono8x8PatternFillRect);
363    if (cAcl->BitsPerPixel == 24)
364      infoPtr->MonoPatternPitch = 8;		/* Need 8 byte alignment */
365#else
366    if (cAcl->BitsPerPixel != 24) {
367	infoPtr->SetupForMono8x8PatternFill =
368	    CTNAME(SetupForMono8x8PatternFill);
369	infoPtr->SubsequentMono8x8PatternFillRect =
370	    CTNAME(SubsequentMono8x8PatternFillRect);
371    }
372#endif
373
374    /* Color 8x8 pattern fills, must have a displayWidth divisible by 64 */
375    if (!(pScrn->displayWidth % 64)) {
376#ifdef CHIPS_HIQV
377	infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
378	    HARDWARE_PATTERN_SCREEN_ORIGIN;
379	if (!(cPtr->Flags & ChipsColorTransparency))
380	    infoPtr->Color8x8PatternFillFlags |= NO_TRANSPARENCY;
381#else
382	infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
383	    HARDWARE_PATTERN_SCREEN_ORIGIN | NO_TRANSPARENCY;
384#endif
385
386	if (cAcl->BitsPerPixel != 24) {
387	    infoPtr->SetupForColor8x8PatternFill =
388		CTNAME(SetupForColor8x8PatternFill);
389	    infoPtr->SubsequentColor8x8PatternFillRect =
390		CTNAME(SubsequentColor8x8PatternFillRect);
391	}
392    }
393
394#ifdef CHIPS_HIQV
395chips_imagewrite:
396#endif
397
398    /* Setup for the Image Write functions */
399#ifdef CHIPS_HIQV
400    infoPtr->WritePixmapFlags = CPU_TRANSFER_PAD_QWORD | LEFT_EDGE_CLIPPING
401        | LEFT_EDGE_CLIPPING_NEGATIVE_X | ROP_NEEDS_SOURCE;
402
403    if (!(cPtr->Flags & ChipsColorTransparency))
404        infoPtr->WritePixmapFlags |= NO_TRANSPARENCY;
405    if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
406	infoPtr->WritePixmapFlags |= NO_PLANEMASK;
407
408    infoPtr->WritePixmap = CTNAME(WritePixmap);
409#if 0 /* Not used by XAA as yet, but coming soon */
410    if (cPtr->Flags & ChipsImageReadSupport) {
411	infoPtr->ReadPixmapFlags = CPU_TRANSFER_PAD_QWORD | ROP_NEEDS_SOURCE;
412	infoPtr->ReadPixmap = CTNAME(ReadPixmap);
413    }
414#endif
415
416#else
417    infoPtr->SetupForImageWrite = CTNAME(SetupForImageWrite);
418    infoPtr->SubsequentImageWriteRect = CTNAME(SubsequentImageWriteRect);
419    infoPtr->ImageWriteBase = (unsigned char *)cAcl->BltDataWindow;
420    infoPtr->ImageWriteRange = 64 * 1024;
421    infoPtr->ImageWriteFlags = NO_TRANSPARENCY | CPU_TRANSFER_PAD_DWORD
422	| ROP_NEEDS_SOURCE;
423    if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
424        infoPtr->ImageWriteFlags |= NO_PLANEMASK;
425#endif
426
427    return(XAAInit(pScreen, infoPtr));
428#else
429    return FALSE;
430#endif
431}
432
433#ifdef HAVE_XAA_H
434#ifdef CHIPS_HIQV
435void
436CTNAME(DepthChange)(ScrnInfoPtr pScrn, int depth)
437{
438    CHIPSPtr cPtr = CHIPSPTR(pScrn);
439    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
440    unsigned char mode;
441
442    DEBUG_P("DepthChange");
443    switch (depth) {
444    case 8 :
445	cPtr->AccelInfoRec->SetupForSolidFill = CTNAME(8SetupForSolidFill);
446	mode = 0x00;       			/* BitBLT engine to 8bpp  */
447	cAcl->BytesPerPixel = 1;
448	cAcl->FbOffset = 0;
449	cAcl->BitsPerPixel = 8;
450        break;
451    default :
452	cPtr->AccelInfoRec->SetupForSolidFill = CTNAME(16SetupForSolidFill);
453	mode = 0x10;       			/* BitBLT engine to 16bpp */
454	cAcl->BytesPerPixel = 2;
455	cAcl->FbOffset = cPtr->FbOffset16;
456	cAcl->BitsPerPixel = 16;
457        break;
458    }
459    cAcl->PitchInBytes = pScrn->displayWidth * cAcl->BytesPerPixel;
460    ctBLTWAIT;
461    cPtr->writeXR(cPtr, 0x20, mode);       	/* Change BitBLT engine mode */
462}
463#endif
464
465#endif
466void
467CTNAME(Sync)(ScrnInfoPtr pScrn)
468{
469#ifdef HAVE_XAA_H
470    CHIPSPtr cPtr = CHIPSPTR(pScrn);
471    DEBUG_P("sync");
472    ctBLTWAIT;
473    BE_SWAPON(pScrn,cPtr);
474#endif
475}
476
477#ifdef HAVE_XAA_H
478static void
479CTNAME(8SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
480				int rop, unsigned int planemask)
481{
482    CHIPSPtr cPtr = CHIPSPTR(pScrn);
483    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
484
485    DEBUG_P("8SetupForSolidFill");
486    ctBLTWAIT;
487    ctSETBGCOLOR8(color);
488    ctSETFGCOLOR8(color);
489    ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
490	     ctPATSOLID | ctPATMONO);
491    ctSETPITCH(0, cAcl->PitchInBytes);
492}
493
494static void
495CTNAME(16SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
496				int rop, unsigned int planemask)
497{
498    CHIPSPtr cPtr = CHIPSPTR(pScrn);
499    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
500
501    DEBUG_P("16SetupForSolidFill");
502    ctBLTWAIT;
503    ctSETBGCOLOR16(color);
504    ctSETFGCOLOR16(color);
505    ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
506	     ctPATSOLID | ctPATMONO);
507    ctSETPITCH(0, cAcl->PitchInBytes);
508}
509
510#ifdef CHIPS_HIQV
511static void
512CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
513				int rop, unsigned int planemask)
514{
515    CHIPSPtr cPtr = CHIPSPTR(pScrn);
516    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
517
518    DEBUG_P("24SetupForSolidFill");
519    ctBLTWAIT;
520    ctSETBGCOLOR24(color);
521    ctSETFGCOLOR24(color);
522    ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
523	     ctPATSOLID | ctPATMONO);
524    ctSETPITCH(0, cAcl->PitchInBytes);
525}
526
527static void
528CTNAME(32SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
529				int rop, unsigned int planemask)
530{
531    CHIPSPtr cPtr = CHIPSPTR(pScrn);
532    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
533
534    DEBUG_P("32SetupForSolidFill");
535    ctBLTWAIT;
536    memset((unsigned char *)cPtr->FbBase + cAcl->ScratchAddress, 0xAA, 8);
537    ctSETFGCOLOR16((color & 0xFFFF));
538    ctSETBGCOLOR16(((color >> 16) & 0xFFFF));
539    ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
540      ctPATMONO);
541    ctSETPATSRCADDR(cAcl->ScratchAddress);
542    ctSETPITCH(1, cAcl->PitchInBytes);
543}
544
545static void
546CTNAME(32SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
547				  int h)
548{
549    CHIPSPtr cPtr = CHIPSPTR(pScrn);
550
551    unsigned int destaddr;
552    destaddr = (y * pScrn->displayWidth + x) << 2;
553    w <<= 2;
554    DEBUG_P("32SubsequentSolidFillRect");
555    ctBLTWAIT;
556    ctSETDSTADDR(destaddr);
557    ctSETHEIGHTWIDTHGO(h, w);
558}
559#else
560
561static void
562CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
563				int rop, unsigned int planemask)
564{
565    unsigned char pixel1, pixel2, pixel3;
566    CHIPSPtr cPtr = CHIPSPTR(pScrn);
567    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
568
569    DEBUG_P("24SetupForSolidFill");
570    cAcl->rgb24equal = (((((color & 0xFF) == ((color & 0xFF00) >> 8)) &&
571		       ((color & 0xFF) == ((color & 0xFF0000) >> 16)))) ||
572		       /* Check the rop for paranoid reasons */
573		       (rop == GXclear) || (rop == GXnoop) ||
574		       (rop == GXinvert) || (rop == GXset));
575    if (cAcl->rgb24equal) {
576	cAcl->CommandFlags = ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM |
577	         ctLEFT2RIGHT | ctPATSOLID | ctPATMONO;
578	ctBLTWAIT;
579	ctSETFGCOLOR8(color&0xFF);
580	ctSETBGCOLOR8(color&0xFF);
581	ctSETPITCH(0, cAcl->PitchInBytes);
582    } else {
583	cAcl->rop24bpp = rop;
584	if (rop == GXcopy) {
585	    pixel3 = color & 0xFF;
586	    pixel2 = (color >> 8) & 0xFF;
587	    pixel1 = (color >> 16) & 0xFF;
588	    cAcl->fgpixel = pixel1;
589	    cAcl->bgpixel = pixel2;
590	    cAcl->fillindex = 0;
591	    cAcl->fastfill = FALSE;
592
593	    /* Test for the special case where two of the byte of the
594	     * 24bpp colour are the same. This can double the speed
595	     */
596	    if (pixel1 == pixel2) {
597		cAcl->fgpixel = pixel3;
598		cAcl->bgpixel = pixel1;
599		cAcl->fastfill = TRUE;
600		cAcl->fillindex = 1;
601	    } else if (pixel1 == pixel3) {
602		cAcl->fgpixel = pixel2;
603		cAcl->bgpixel = pixel1;
604		cAcl->fastfill = TRUE;
605		cAcl->fillindex = 2;
606	    } else if (pixel2 == pixel3) {
607		cAcl->fastfill = TRUE;
608	    } else {
609		cAcl->xorpixel = pixel2 ^ pixel3;
610	    }
611
612	    cAcl->CommandFlags = ctSRCMONO | ctSRCSYSTEM | ctTOP2BOTTOM |
613	             ctLEFT2RIGHT;
614	    ctBLTWAIT;
615	    if (cAcl->fastfill) {
616		ctSETFGCOLOR8(cAcl->fgpixel);
617	    }
618	    ctSETBGCOLOR8(cAcl->bgpixel);
619	    ctSETSRCADDR(0);
620	    ctSETPITCH(0, cAcl->PitchInBytes);
621	} else {
622	    if (cAcl->color24bpp != color) {
623		cAcl->color24bpp = color;
624		cAcl->width24bpp = 0;
625	    }
626	    cAcl->rop24bpp = rop;
627	    ctBLTWAIT;
628	    ctSETROP(ctTOP2BOTTOM | ctLEFT2RIGHT | ChipsAluConv[rop & 0xF]);
629	    ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
630	}
631    }
632}
633
634static void
635CTNAME(24SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
636				  int h)
637{
638    static unsigned int dwords[3] = { 0x24499224, 0x92244992, 0x49922449};
639    int srcaddr, destaddr, line, i;
640    register int width;
641    CHIPSPtr cPtr = CHIPSPTR(pScrn);
642    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
643
644    DEBUG_P("24SubsequentSolidFillRect");
645    if (cAcl->rgb24equal) {
646	destaddr = y * pScrn->displayWidth + x;
647	destaddr += destaddr << 1;
648	ctBLTWAIT;
649	ctSETROP(cAcl->CommandFlags);
650	ctSETDSTADDR(destaddr);
651	ctSETHEIGHTWIDTHGO(h, (w + (w << 1)));
652    } else {
653	if (cAcl->rop24bpp == GXcopy ) {
654	    unsigned int *base = (unsigned int *)cAcl->BltDataWindow;
655	    destaddr = y * cAcl->PitchInBytes + x * 3;
656	    w *= 3;
657	    width = ((w  + 31) & ~31) >> 5;
658
659	    ctBLTWAIT;
660	    ctSETDSTADDR(destaddr);
661
662	    if (!cAcl->fastfill) ctSETFGCOLOR8(cAcl->fgpixel);
663	    ctSETROP(cAcl->CommandFlags | ChipsAluConv[GXcopy & 0xF]);
664	    ctSETDSTADDR(destaddr);
665	    if (cAcl->fastfill) {
666		ctSETHEIGHTWIDTHGO(h, w);
667		line = 0;
668		while (line < h) {
669		    base = (unsigned int *)cAcl->BltDataWindow;
670		    for (i = 0; i < width; i++) {
671			*base++ = dwords[((cAcl->fillindex + i) % 3)];
672		    }
673		    line++;
674		}
675	    } else {
676		ctSETHEIGHTWIDTHGO(1, w);
677		i = 0;
678		while(i < width){
679		    *base++ = dwords[(i++ % 3)];
680		}
681		for(line = 0; (h >> line ) > 1; line++){;}
682		i = 0;
683		ctBLTWAIT;
684		ctSETFGCOLOR8(cAcl->xorpixel);
685		ctSETROP(cAcl->CommandFlags | ChipsAluConv[GXxor & 0xF] |
686			 ctBGTRANSPARENT);
687		ctSETDSTADDR(destaddr);
688		ctSETHEIGHTWIDTHGO(1, w);
689		base = (unsigned int *)cAcl->BltDataWindow;
690		while(i < width) {
691		    *base++ = dwords[((++i) % 3)];
692		}
693		srcaddr = destaddr;
694		if(line){
695		    i = 0;
696		    ctBLTWAIT;
697		    ctSETROP(ctTOP2BOTTOM | ctLEFT2RIGHT |
698			     ChipsAluConv[GXcopy & 0xF]);
699		    ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
700		    ctSETSRCADDR(srcaddr);
701
702		    while(i < line){
703		        destaddr = srcaddr + (cAcl->PitchInBytes << i);
704			ctBLTWAIT;
705			ctSETDSTADDR(destaddr);
706			ctSETHEIGHTWIDTHGO((1 << i), w);
707			i++;
708		    }
709
710		    if((1 <<  line)  < h){
711			destaddr = srcaddr + (cAcl->PitchInBytes << line);
712			ctBLTWAIT;
713			ctSETDSTADDR(destaddr);
714			ctSETHEIGHTWIDTHGO(h-(1 << line), w);
715		    }
716
717		    ctBLTWAIT;
718		    ctSETROP(ctSRCMONO | ctSRCSYSTEM | ctTOP2BOTTOM |
719			     ctLEFT2RIGHT | ChipsAluConv[GXcopy & 0xF]);
720		    ctSETSRCADDR(0);
721		    ctSETPITCH(0, cAcl->PitchInBytes);
722		}
723	    }
724	} else {
725	    register unsigned char *base;
726	    if (cAcl->width24bpp < w) {
727		base = (unsigned char *)cPtr->FbBase + cAcl->ScratchAddress +
728		    ((3 * cAcl->width24bpp + 3) & ~0x3);
729		width = w - cAcl->width24bpp;
730		ctBLTWAIT;
731		/* Load of a single scanline into framebuffer */
732		while (width > 0) {
733		    *(unsigned int *)base = cAcl->color24bpp |
734		      (cAcl->color24bpp << 24);
735		    *(unsigned int *)(base + 4) = (cAcl->color24bpp >> 8) |
736		      (cAcl->color24bpp << 16);
737		    *(unsigned int *)(base + 8) = (cAcl->color24bpp >> 16) |
738		      (cAcl->color24bpp << 8);
739		    base += 12;
740		    width -= 4;
741		}
742		cAcl->width24bpp = w - width;
743	    }
744	    line = 0;
745	    destaddr = 3 * (y * pScrn->displayWidth + x);
746	    w *= cAcl->BytesPerPixel;
747	    while (line < h) {
748		ctBLTWAIT;
749		ctSETSRCADDR(cAcl->ScratchAddress);
750		ctSETDSTADDR(destaddr);
751		ctSETHEIGHTWIDTHGO(1, w);
752		destaddr += (3 * pScrn->displayWidth);
753		line++;
754	    }
755	}
756    }
757}
758#endif
759
760static void
761CTNAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
762				  int h)
763{
764    CHIPSPtr cPtr = CHIPSPTR(pScrn);
765    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
766    int destaddr;
767
768    DEBUG_P("SubsequentSolidFillRect");
769    destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
770#ifdef CHIPS_HIQV
771    destaddr += cAcl->FbOffset;
772#endif
773    w *= cAcl->BytesPerPixel;
774    ctBLTWAIT;
775    ctSETDSTADDR(destaddr);
776    ctSETHEIGHTWIDTHGO(h, w);
777}
778
779/*
780 * Screen-to-screen BitBLT.
781 *
782 */
783
784static void
785CTNAME(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir,
786				int rop, unsigned int planemask, int trans)
787{
788    CHIPSPtr cPtr = CHIPSPTR(pScrn);
789    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
790
791    DEBUG_P("SetupForScreenToScreenCopy");
792    cAcl->CommandFlags = 0;
793
794    /* Set up the blit direction. */
795    if (ydir < 0)
796	cAcl->CommandFlags |= ctBOTTOM2TOP;
797    else
798	cAcl->CommandFlags |= ctTOP2BOTTOM;
799    if (xdir < 0)
800	cAcl->CommandFlags |= ctRIGHT2LEFT;
801    else
802	cAcl->CommandFlags |= ctLEFT2RIGHT;
803#ifdef CHIPS_HIQV
804    if (trans != -1) {
805	cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
806	    ctCOLORTRANSNEQUAL;
807	ctBLTWAIT;
808	/* BR03[0x27] sometimes set after reset, so must ensure it is zero */
809	ctSETMONOCTL(ctDWORDALIGN);
810        switch (cAcl->BitsPerPixel) {
811        case 8:
812	    ctSETBGCOLOR8(trans);
813	    break;
814        case 16:
815	    ctSETBGCOLOR16(trans);
816	    break;
817        case 24:
818	    ctSETBGCOLOR24(trans);
819	    break;
820        }
821    } else
822#endif
823    ctBLTWAIT;
824    switch (cAcl->BitsPerPixel) {
825#if 0
826    case 8:
827        if ((planemask & 0xFF) == 0xFF) {
828	    ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
829	} else {
830	    ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
831	    ctSETPATSRCADDR(cAcl->ScratchAddress);
832	    ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
833	}
834	break;
835    case 16:
836        if ((planemask & 0xFFFF) == 0xFFFF) {
837	    ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
838	} else {
839	    ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
840	    ctSETPATSRCADDR(cAcl->ScratchAddress);
841	    ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
842	}
843	break;
844#endif
845    default:
846	ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
847	break;
848    }
849    ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
850}
851
852static void
853CTNAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int srcX, int srcY,
854				int dstX, int dstY, int w, int h)
855{
856    CHIPSPtr cPtr = CHIPSPTR(pScrn);
857    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
858    unsigned int srcaddr, destaddr;
859
860    DEBUG_P("SubsequentScreenToScreenCopy");
861#ifdef CHIPS_HIQV
862    if (cAcl->CommandFlags & ctBOTTOM2TOP) {
863        srcaddr = (srcY + h - 1) * pScrn->displayWidth;
864	destaddr = (dstY + h - 1) * pScrn->displayWidth;
865    } else {
866        srcaddr = srcY * pScrn->displayWidth;
867        destaddr = dstY * pScrn->displayWidth;
868    }
869    if (cAcl->CommandFlags & ctRIGHT2LEFT) {
870	srcaddr = ( srcaddr + srcX + w ) * cAcl->BytesPerPixel - 1 ;
871	destaddr = ( destaddr + dstX + w ) * cAcl->BytesPerPixel - 1;
872    } else {
873	srcaddr = (srcaddr + srcX) * cAcl->BytesPerPixel;
874	destaddr = (destaddr + dstX) * cAcl->BytesPerPixel;
875    }
876    srcaddr += cAcl->FbOffset;
877    destaddr += cAcl->FbOffset;
878#else
879    if (cAcl->CommandFlags & ctTOP2BOTTOM) {
880        srcaddr = srcY * pScrn->displayWidth;
881        destaddr = dstY * pScrn->displayWidth;
882    } else {
883        srcaddr = (srcY + h - 1) * pScrn->displayWidth;
884	destaddr = (dstY + h - 1) * pScrn->displayWidth;
885    }
886    if (cAcl->CommandFlags & ctLEFT2RIGHT) {
887	srcaddr = (srcaddr + srcX) * cAcl->BytesPerPixel;
888	destaddr = (destaddr + dstX) * cAcl->BytesPerPixel;
889    } else {
890	srcaddr = ( srcaddr + srcX + w ) * cAcl->BytesPerPixel - 1 ;
891	destaddr = ( destaddr + dstX + w ) * cAcl->BytesPerPixel - 1;
892    }
893#endif
894    w *= cAcl->BytesPerPixel;
895    ctBLTWAIT;
896    ctSETSRCADDR(srcaddr);
897    ctSETDSTADDR(destaddr);
898    ctSETHEIGHTWIDTHGO(h, w);
899}
900
901
902static void
903CTNAME(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
904				int bg, int rop, unsigned int planemask)
905{
906    CHIPSPtr cPtr = CHIPSPTR(pScrn);
907    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
908
909    DEBUG_P("SetupForCPUToScreenColorExpandFill");
910
911    BE_SWAPOFF(pScrn,cPtr);
912
913    ctBLTWAIT;
914    cAcl->CommandFlags = 0;
915    if (bg == -1) {
916	cAcl->CommandFlags |= ctBGTRANSPARENT;	/* Background = Destination */
917        switch (cAcl->BitsPerPixel) {
918        case 8:
919	    ctSETFGCOLOR8(fg);
920	    break;
921        case 16:
922	    ctSETFGCOLOR16(fg);
923	    break;
924        case 24:
925#ifdef CHIPS_HIQV
926	    ctSETFGCOLOR24(fg);
927#else
928	    ctSETFGCOLOR8(fg);
929#endif
930	    break;
931        }
932    }
933    else {
934        switch (cAcl->BitsPerPixel) {
935        case 8:
936	    ctSETBGCOLOR8(bg);
937	    ctSETFGCOLOR8(fg);
938	    break;
939        case 16:
940	    ctSETBGCOLOR16(bg);
941	    ctSETFGCOLOR16(fg);
942	    break;
943        case 24:
944#ifdef CHIPS_HIQV
945	    ctSETBGCOLOR24(bg);
946	    ctSETFGCOLOR24(fg);
947#else
948	    ctSETBGCOLOR8(bg);
949	    ctSETFGCOLOR8(fg);
950#endif
951	    break;
952        }
953    }
954
955#ifdef CHIPS_HIQV
956    ctSETMONOCTL(ctDWORDALIGN);
957#endif
958
959    ctSETSRCADDR(0);
960
961    switch (cAcl->BitsPerPixel) {
962    case 8:
963        if ((planemask & 0xFF) == 0xFF) {
964	    ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
965		    ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
966	} else {
967	    ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
968		    ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
969	    ctSETPATSRCADDR(cAcl->ScratchAddress);
970	    ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
971	}
972	break;
973    case 16:
974        if ((planemask & 0xFFFF) == 0xFFFF) {
975	    ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
976		    ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
977	} else {
978	    ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
979		    ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
980	    ctSETPATSRCADDR(cAcl->ScratchAddress);
981	    ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
982	}
983	break;
984    default:
985	ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
986		 ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
987	break;
988    }
989    ctSETPITCH(0, cAcl->PitchInBytes);
990}
991
992static void
993CTNAME(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
994				int x, int y, int w, int h, int skipleft)
995{
996    CHIPSPtr cPtr = CHIPSPTR(pScrn);
997    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
998    int destaddr;
999
1000    DEBUG_P("SubsequentCPUToScreenColorExpandFill");
1001    destaddr = (y * pScrn->displayWidth + x + skipleft) *
1002               cAcl->BytesPerPixel;
1003#ifdef CHIPS_HIQV
1004    destaddr += cAcl->FbOffset;
1005#endif
1006    w = (w - skipleft) * cAcl->BytesPerPixel;
1007    ctBLTWAIT;
1008    ctSETDSTADDR(destaddr);
1009#ifdef CHIPS_HIQV
1010    ctSETMONOCTL(ctDWORDALIGN | ctCLIPLEFT(skipleft));
1011#endif
1012    ctSETHEIGHTWIDTHGO(h, w);
1013}
1014
1015#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
1016static void
1017CTNAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
1018				int fg, int bg, int rop,
1019				unsigned int planemask)
1020{
1021    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1022    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1023
1024    DEBUG_P("SetupForScreenToScreenColorExpandFill");
1025    cAcl->CommandFlags = 0;
1026    ctBLTWAIT;
1027    if (bg == -1) {
1028	cAcl->CommandFlags |= ctBGTRANSPARENT;	/* Background = Destination */
1029        switch (cAcl->BitsPerPixel) {
1030        case 8:
1031	    ctSETFGCOLOR8(fg);
1032	    break;
1033        case 16:
1034	    ctSETFGCOLOR16(fg);
1035	    break;
1036        case 24:
1037#ifdef CHIPS_HIQV
1038	    ctSETFGCOLOR24(fg);
1039#else
1040	    ctSETFGCOLOR8(fg);
1041#endif
1042	    break;
1043        }
1044    }
1045    else {
1046        switch (cAcl->BitsPerPixel) {
1047        case 8:
1048	    ctSETBGCOLOR8(bg);
1049	    ctSETFGCOLOR8(fg);
1050	    break;
1051        case 16:
1052	    ctSETBGCOLOR16(bg);
1053	    ctSETFGCOLOR16(fg);
1054	    break;
1055        case 24:
1056#ifdef CHIPS_HIQV
1057	    ctSETBGCOLOR24(bg);
1058	    ctSETFGCOLOR24(fg);
1059#else
1060	    ctSETBGCOLOR8(bg);
1061	    ctSETFGCOLOR8(fg);
1062#endif
1063	    break;
1064        }
1065    }
1066
1067    switch (cAcl->BitsPerPixel) {
1068    case 8:
1069        if ((planemask & 0xFF) == 0xFF) {
1070	    ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
1071		 ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
1072	} else {
1073	    ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
1074		    ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
1075	    ctSETPATSRCADDR(cAcl->ScratchAddress);
1076	    ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
1077	}
1078	break;
1079    case 16:
1080        if ((planemask & 0xFFFF) == 0xFFFF) {
1081	    ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
1082		 ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
1083	} else {
1084	    ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
1085		    ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
1086	    ctSETPATSRCADDR(cAcl->ScratchAddress);
1087	    ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
1088	}
1089	break;
1090    default:
1091	ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
1092		 ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
1093	break;
1094    }
1095    ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
1096}
1097#endif
1098#ifndef CHIPS_HIQV
1099/*
1100 * The non-HiQV chips don't have left-edge clippling of monochrome sources.
1101 * However you can have the monochrome source starting on a byte boundary.
1102 * Hence have 8 rotated copies of the monochrome source to simulate left
1103 * edge clipping with these chips. This requires the XAACacheMonoStipple
1104 * function to be replaced, if we are to use ScreenToScreenColorExpand.
1105 */
1106
1107static XAACacheInfoPtr
1108CTNAME(CacheMonoStipple)(ScrnInfoPtr pScrn, PixmapPtr pPix)
1109{
1110    int w = pPix->drawable.width;
1111    int h = pPix->drawable.height;
1112    XAAInfoRecPtr infoRec = (CHIPSPTR(pScrn))->AccelInfoRec;
1113    XAAPixmapCachePrivatePtr pCachePriv =
1114	(XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
1115    XAACacheInfoPtr pCache, cacheRoot = NULL;
1116    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1117    int i, j, max = 0, funcNo, pad, dwords, bpp = cAcl->BitsPerPixel;
1118    int *current;
1119    StippleScanlineProcPtr StippleFunc;
1120    static StippleScanlineProcPtr *StippleTab = NULL;
1121    unsigned char *data, *srcPtr, *dstPtr;
1122
1123    if (!StippleTab)
1124        StippleTab = XAAGetStippleScanlineFuncMSBFirst();
1125
1126    DEBUG_P("CacheMonoStipple");
1127    if((h <= 128) && (w <= 128 * bpp / 8)) {
1128	if(pCachePriv->Info128) {
1129	    cacheRoot = pCachePriv->Info128;
1130	    max = pCachePriv->Num128x128;
1131	    current = &pCachePriv->Current128;
1132	} else {
1133	    cacheRoot = pCachePriv->InfoPartial;
1134	    max = pCachePriv->NumPartial;
1135	    current = &pCachePriv->CurrentPartial;
1136	}
1137    } else if((h <= 256) && (w <= 256 * bpp / 8)){
1138	cacheRoot = pCachePriv->Info256;
1139	max = pCachePriv->Num256x256;
1140	current = &pCachePriv->Current256;
1141    } else if((h <= 512) && (w <= 512 * bpp / 8)){
1142	cacheRoot = pCachePriv->Info512;
1143	max = pCachePriv->Num512x512;
1144	current = &pCachePriv->Current512;
1145    } else { /* something's wrong */
1146	ErrorF("Something's wrong in XAACacheMonoStipple()\n");
1147	return pCachePriv->Info128;
1148    }
1149
1150    pCache = cacheRoot;
1151
1152    /* lets look for it */
1153    for(i = 0; i < max; i++, pCache++) {
1154	if((pCache->serialNumber == pPix->drawable.serialNumber) &&
1155	    (pCache->fg == -1) && (pCache->bg == -1)) {
1156	    pCache->trans_color = -1;
1157	    dwords =
1158	    cAcl->SlotWidth = ((pCache->w * bpp) >> 5) >> 1;
1159	    return pCache;
1160	}
1161    }
1162
1163    pCache = &cacheRoot[(*current)++];
1164    if(*current >= max) *current = 0;
1165
1166    pCache->serialNumber = pPix->drawable.serialNumber;
1167    pCache->trans_color = pCache->bg = pCache->fg = -1;
1168    pCache->orig_w = w;  pCache->orig_h = h;
1169
1170    if(w <= 32) {
1171        if(w & (w - 1))	funcNo = 1;
1172        else    	funcNo = 0;
1173    } else 		funcNo = 2;
1174
1175    pad = (((pCache->w * bpp) + 31) >> 5) << 2;
1176    dstPtr = data = malloc(pad * pCache->h);
1177    srcPtr = (unsigned char*)pPix->devPrivate.ptr;
1178    StippleFunc = StippleTab[funcNo];
1179
1180    dwords = ((pCache->w * bpp) >> 5) >> 3;
1181    cAcl->SlotWidth = dwords << 2;
1182
1183    for(i = 0; i < h; i++) {
1184	for(j = 0; j < 8; j++) {
1185	    (*StippleFunc)((CARD32*)dstPtr + j * dwords,
1186			   (CARD32*)srcPtr, j, w, dwords);
1187	}
1188	srcPtr += pPix->devKind;
1189	dstPtr += pad;
1190    }
1191
1192    while((h<<1) <= pCache->h) {
1193	memcpy(data + (pad * h), data, pad * h);
1194	h <<= 1;
1195    }
1196
1197    if(h < pCache->h)
1198	memcpy(data + (pad * h), data, pad * (pCache->h - h));
1199
1200    (*infoRec->WritePixmapToCache)(
1201	pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
1202	pad, bpp, pScrn->depth);
1203
1204    free(data);
1205
1206    return pCache;
1207}
1208#endif
1209#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
1210static void
1211CTNAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
1212				int x, int y, int w, int h,
1213				int srcx, int srcy, int skipleft)
1214{
1215    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1216    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1217    int srcaddr, destaddr;
1218
1219    DEBUG_P("SubsequentScreenToScreenColorExpandFill");
1220#ifdef CHIPS_HIQV
1221    srcaddr = (srcy * pScrn->displayWidth + srcx) * cAcl->BytesPerPixel
1222		+ ((skipleft & ~0x3F) >> 3);
1223    if ( y < pScrn->virtualY)
1224	srcaddr += cAcl->FbOffset;
1225    else
1226	srcaddr += cPtr->FbOffset16;
1227#else
1228    srcaddr = (srcy * pScrn->displayWidth + srcx) * cAcl->BytesPerPixel
1229		+ ((skipleft &  0x07) * cAcl->SlotWidth)
1230		+ ((skipleft & ~0x07) >> 3);
1231#endif
1232    destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
1233#ifdef CHIPS_HIQV
1234    destaddr += cAcl->FbOffset;
1235#endif
1236    w *= cAcl->BytesPerPixel;
1237    ctBLTWAIT;
1238    ctSETSRCADDR(srcaddr);
1239    ctSETDSTADDR(destaddr);
1240#ifdef CHIPS_HIQV
1241    ctSETMONOCTL(ctCLIPLEFT(skipleft & 0x3F));
1242#endif
1243    ctSETHEIGHTWIDTHGO(h, w);
1244}
1245#endif
1246static void
1247CTNAME(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
1248				    int rop, unsigned int planemask,
1249				    int trans)
1250{
1251    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1252    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1253    unsigned int patternaddr;
1254
1255    DEBUG_P("SetupForColor8x8PatternFill");
1256    cAcl->CommandFlags = ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM |
1257		ctLEFT2RIGHT;
1258    patternaddr = (paty * pScrn->displayWidth +
1259		   (patx & ~0x3F)) * cAcl->BytesPerPixel;
1260    cAcl->patternyrot = (patx & 0x3F) >> 3;
1261
1262    ctBLTWAIT;
1263    ctSETPATSRCADDR(patternaddr);
1264#ifdef CHIPS_HIQV
1265    if (trans != -1) {
1266	cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
1267	    ctCOLORTRANSNEQUAL;
1268	ctSETMONOCTL(ctDWORDALIGN);
1269        switch (cAcl->BitsPerPixel) {
1270        case 8:
1271	    ctSETBGCOLOR8(trans);
1272	    break;
1273        case 16:
1274	    ctSETBGCOLOR16(trans);
1275	    break;
1276        case 24:
1277	    ctSETBGCOLOR24(trans);
1278	    break;
1279        }
1280    } else
1281#endif
1282    ctSETPITCH(8 * cAcl->BytesPerPixel, cAcl->PitchInBytes);
1283}
1284
1285static void
1286CTNAME(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx, int paty,
1287				 int x, int y, int w, int h)
1288{
1289    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1290    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1291    unsigned int destaddr;
1292
1293    DEBUG_P("SubsequentColor8x8PatternFillRect");
1294    destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
1295#ifdef CHIPS_HIQV
1296    destaddr += cAcl->FbOffset;
1297#endif
1298    w *= cAcl->BytesPerPixel;
1299    ctBLTWAIT;
1300    ctSETDSTADDR(destaddr);
1301#ifdef CHIPS_HIQV
1302    ctSETROP(cAcl->CommandFlags | (((y + cAcl->patternyrot) & 0x7) << 20));
1303#else
1304    ctSETROP(cAcl->CommandFlags | (((y + cAcl->patternyrot) & 0x7) << 16));
1305#endif
1306    ctSETHEIGHTWIDTHGO(h, w);
1307}
1308
1309static void
1310CTNAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
1311				int fg, int bg, int rop,
1312				unsigned int planemask)
1313{
1314    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1315    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1316    unsigned int patternaddr;
1317
1318    DEBUG_P("SetupForMono8x8PatternFill");
1319    cAcl->CommandFlags = ctPATMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
1320	ChipsAluConv2[rop & 0xF];
1321
1322#ifdef CHIPS_HIQV
1323    patternaddr = paty * pScrn->displayWidth + patx;
1324    patternaddr *= cAcl->BytesPerPixel;
1325#else
1326    patternaddr = (paty * pScrn->displayWidth + patx) * cAcl->BytesPerPixel;
1327#endif
1328    ctBLTWAIT;
1329    ctSETPATSRCADDR(patternaddr);
1330    if (bg == -1) {
1331	cAcl->CommandFlags |= ctBGTRANSPARENT;	/* Background = Destination */
1332        switch (cAcl->BitsPerPixel) {
1333        case 8:
1334	    ctSETFGCOLOR8(fg);
1335	    break;
1336        case 16:
1337	    ctSETFGCOLOR16(fg);
1338	    break;
1339        case 24:
1340	    ctSETFGCOLOR24(fg);
1341	    break;
1342        }
1343    }
1344    else {
1345        switch (cAcl->BitsPerPixel) {
1346        case 8:
1347	    ctSETBGCOLOR8(bg);
1348	    ctSETFGCOLOR8(fg);
1349	    break;
1350        case 16:
1351	    ctSETBGCOLOR16(bg);
1352	    ctSETFGCOLOR16(fg);
1353	    break;
1354        case 24:
1355	    ctSETBGCOLOR24(bg);
1356	    ctSETFGCOLOR24(fg);
1357	    break;
1358        }
1359    }
1360#ifdef CHIPS_HIQV
1361    ctSETMONOCTL(ctDWORDALIGN);
1362#endif
1363    ctSETPITCH(1,cAcl->PitchInBytes);
1364}
1365
1366static void
1367CTNAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx,
1368				int paty, int x, int y, int w, int h )
1369{
1370    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1371    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1372    int destaddr;
1373    DEBUG_P("SubsequentMono8x8PatternFillRect");
1374    destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
1375#ifdef CHIPS_HIQV
1376    destaddr += cAcl->FbOffset;
1377#endif
1378    w *= cAcl->BytesPerPixel;
1379
1380    ctBLTWAIT;
1381    ctSETDSTADDR(destaddr);
1382#ifdef CHIPS_HIQV
1383    ctSETROP(cAcl->CommandFlags | ((y & 0x7) << 20));
1384#else
1385    ctSETROP(cAcl->CommandFlags | ((y & 0x7) << 16));
1386#endif
1387    ctSETHEIGHTWIDTHGO(h, w);
1388}
1389
1390#ifndef	CHIPS_HIQV
1391static void
1392CTNAME(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
1393				int transparency_color, int bpp, int depth)
1394{
1395    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1396    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1397
1398    DEBUG_P("SetupForImageWrite");
1399    cAcl->CommandFlags = ctSRCSYSTEM | ctTOP2BOTTOM | ctLEFT2RIGHT;
1400    ctBLTWAIT;
1401
1402    switch (cAcl->BitsPerPixel) {
1403    case 8:
1404        if ((planemask & 0xFF) == 0xFF) {
1405	    ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
1406	} else {
1407	    ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
1408	    ctSETPATSRCADDR(cAcl->ScratchAddress);
1409	    ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
1410	}
1411	break;
1412    case 16:
1413        if ((planemask & 0xFFFF) == 0xFFFF) {
1414	    ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
1415	} else {
1416	    ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
1417	    ctSETPATSRCADDR(cAcl->ScratchAddress);
1418	    ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
1419	}
1420	break;
1421    default:
1422	ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
1423	break;
1424    }
1425    ctSETSRCADDR(0);
1426}
1427
1428static void
1429CTNAME(SubsequentImageWriteRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
1430				int skipleft)
1431{
1432    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1433    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1434    int destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
1435    DEBUG_P("SubsequentImageWriteRect");
1436    w *= cAcl->BytesPerPixel;
1437    ctBLTWAIT;
1438    ctSETPITCH(((w + 3) & ~0x3), cAcl->PitchInBytes);
1439    ctSETDSTADDR(destaddr);
1440    ctSETHEIGHTWIDTHGO(h, w);
1441}
1442
1443#else
1444/*
1445 * Copyright 1997
1446 * Digital Equipment Corporation. All rights reserved.
1447 * This software is furnished under license and may be used and copied only in
1448 * accordance with the following terms and conditions.  Subject to these
1449 * conditions, you may download, copy, install, use, modify and distribute
1450 * this software in source and/or binary form. No title or ownership is
1451 * transferred hereby.
1452 * 1) Any source code used, modified or distributed must reproduce and retain
1453 *    this copyright notice and list of conditions as they appear in the
1454 *    source file.
1455 *
1456 * 2) No right is granted to use any trade name, trademark, or logo of Digital
1457 *    Equipment Corporation. Neither the "Digital Equipment Corporation" name
1458 *    nor any trademark or logo of Digital Equipment Corporation may be used
1459 *    to endorse or promote products derived from this software without the
1460 *    prior written permission of Digital Equipment Corporation.
1461 *
1462 * 3) This software is provided "AS-IS" and any express or implied warranties,
1463 *    including but not limited to, any implied warranties of merchantability,
1464 *    fitness for a particular purpose, or non-infringement are disclaimed. In
1465 *    no event shall DIGITAL be liable for any damages whatsoever, and in
1466 *    particular, DIGITAL shall not be liable for special, indirect,
1467 *    consequential, or incidental damages or damages for lost profits, loss
1468 *    of revenue or loss of use, whether such damages arise in contract,
1469 *    negligence, tort, under statute, in equity, at law or otherwise, even if
1470 *    advised of the possibility of such damage.
1471 */
1472
1473/* The code below comes from the idea supplied by the people at DEC, like
1474 * the copyright above says. But its had to go through a large evolution
1475 * to fit it into the new design for XFree86 4.0
1476 */
1477
1478static void
1479MoveDWORDS(register CARD32* dest, register CARD32* src, register int dwords )
1480{
1481     while(dwords & ~0x03) {
1482	*dest = *src;
1483	*(dest + 1) = *(src + 1);
1484	*(dest + 2) = *(src + 2);
1485	*(dest + 3) = *(src + 3);
1486	src += 4;
1487	dest += 4;
1488	dwords -= 4;
1489     }
1490     switch(dwords){
1491     case 1:
1492       *dest = *src;
1493       break;
1494     case 2:
1495       *dest = *src;
1496       *(dest + 1) = *(src + 1);
1497       break;
1498     case 3:
1499       *dest = *src;
1500       *(dest + 1) = *(src + 1);
1501       *(dest + 2) = *(src + 2);
1502       break;
1503     }
1504}
1505
1506static __inline__ void
1507MoveDataFromCPU(unsigned char *src, unsigned char *dest, int srcwidth,
1508	 int window, int h, int dwords)
1509{
1510    if(srcwidth == (dwords << 2)) {
1511	int decrement = window / dwords;
1512	while(h > decrement) {
1513	    MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * decrement);
1514	    src += (srcwidth * decrement);
1515	    h -= decrement;
1516	}
1517	if(h) {
1518	    MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * h);
1519	}
1520    } else {
1521	while(h--) {
1522	    MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords);
1523	    src += srcwidth;
1524	}
1525    }
1526}
1527
1528static __inline__ void
1529MoveDataToCPU(unsigned char *src, unsigned char *dest, int dstwidth,
1530	 int window, int h, int dwords)
1531{
1532    if(dstwidth == (dwords << 2)) {
1533	int decrement = window / dwords;
1534	while(h > decrement) {
1535	    MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * decrement);
1536	    dest += (dstwidth * decrement);
1537	    h -= decrement;
1538	}
1539	if(h) {
1540	    MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * h);
1541	}
1542    } else {
1543	while(h--) {
1544	    MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords);
1545	    dest += dstwidth;
1546	}
1547    }
1548}
1549
1550static void
1551CTNAME(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
1552		unsigned char *src, int srcwidth, int rop,
1553		unsigned int planemask, int trans, int bpp, int depth)
1554{
1555    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1556    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1557    unsigned int bytesPerLine;
1558    unsigned int byteWidthSrc;
1559    unsigned int destpitch;
1560    int dwords;
1561    int skipleft;
1562    int destaddr;
1563
1564    DEBUG_P("WritePixmap");
1565#ifdef DEBUG
1566    ErrorF("WritePixmap x %d, y %d, w %d, h %d, src 0x%X, srcwidth %d, rop 0x%X, planemask 0x%X, trans 0x%X, bpp %d, depth %d\n", x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
1567#endif
1568    bytesPerLine = w * (bpp >> 3);
1569    byteWidthSrc = ((srcwidth * (bpp >> 3) + 3L) & ~0x3L);
1570    cAcl->CommandFlags = ctSRCSYSTEM | ctLEFT2RIGHT | ctTOP2BOTTOM;
1571    skipleft = (unsigned long)src & 0x7;
1572    src = (unsigned char *)((unsigned long)src & ~0x7L);
1573    dwords = (((skipleft  + bytesPerLine + 0x7) & ~0x7)) >> 2;
1574    destaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
1575    destpitch = pScrn->displayWidth * (bpp >> 3);
1576    destaddr += cAcl->FbOffset;
1577
1578    ctBLTWAIT;
1579
1580    if (trans != -1) {
1581	cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
1582	    ctCOLORTRANSNEQUAL;
1583	ctSETMONOCTL(ctDWORDALIGN);
1584        switch (cAcl->BitsPerPixel) {
1585        case 8:
1586	    ctSETBGCOLOR8(trans);
1587	    break;
1588        case 16:
1589	    ctSETBGCOLOR16(trans);
1590	    break;
1591        case 24:
1592	    ctSETBGCOLOR24(trans);
1593	    break;
1594        }
1595    }
1596
1597    switch (cAcl->BitsPerPixel) {
1598    case 8:
1599        if ((planemask & 0xFF) == 0xFF) {
1600	    ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
1601	} else {
1602	    ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
1603	    ctSETPATSRCADDR(cAcl->ScratchAddress);
1604	    ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
1605	}
1606	break;
1607    case 16:
1608        if ((planemask & 0xFFFF) == 0xFFFF) {
1609	    ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
1610	} else {
1611	    ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
1612	    ctSETPATSRCADDR(cAcl->ScratchAddress);
1613	    ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
1614	}
1615	break;
1616    default:
1617	ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
1618	break;
1619    }
1620
1621    /*
1622     *
1623     *  CT6555X requires quad-word padding, but XAA provides double-word
1624     *  padding. If the width of a region to be transferred happens to be
1625     *  quad-word aligned, the transfer is straightforward.  If the
1626     *  region is double-word aligned, a pair of contiguous scanlines
1627     *  is quad-word aligned.  In latter case, we can use interleaved
1628     *  transfer twice.  It is faster than transfer line by line.
1629     *
1630     */
1631
1632    ctSETSRCADDR(skipleft);
1633    ctSETDSTADDR(destaddr);
1634
1635    if ((byteWidthSrc & 0x7) == 0) {  /* quad-word aligned */
1636
1637	ctSETPITCH(byteWidthSrc, destpitch);
1638	ctSETHEIGHTWIDTHGO(h, bytesPerLine);
1639
1640	MoveDataFromCPU((unsigned char *)src,
1641		(unsigned char *)cAcl->BltDataWindow,
1642		srcwidth, 16384, h, dwords);
1643
1644    } else {
1645	unsigned int vert = h;
1646
1647	h = (vert + 1) >> 1;
1648
1649	ctSETPITCH(byteWidthSrc << 1, destpitch << 1);
1650	ctSETHEIGHTWIDTHGO(h, bytesPerLine);
1651
1652	MoveDataFromCPU((unsigned char *)src,
1653		(unsigned char *)cAcl->BltDataWindow,
1654		srcwidth<<1, 16384, h, dwords);
1655
1656	h = vert  >> 1;
1657	src += srcwidth;
1658	y++;
1659
1660	destaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
1661	destaddr += cAcl->FbOffset;
1662
1663	ctBLTWAIT;
1664	ctSETDSTADDR(destaddr);
1665	ctSETHEIGHTWIDTHGO(h, bytesPerLine);
1666
1667	MoveDataFromCPU((unsigned char *)src,
1668		(unsigned char *)cAcl->BltDataWindow,
1669		srcwidth<<1, 16384, h, dwords);
1670    }
1671
1672    cPtr->AccelInfoRec->NeedToSync = TRUE;
1673}
1674
1675#if 0
1676static void
1677CTNAME(ReadPixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
1678		unsigned char *dst, int dstwidth, int bpp, int depth)
1679{
1680    CHIPSPtr cPtr = CHIPSPTR(pScrn);
1681    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
1682    unsigned int bytesPerLine;
1683    unsigned int byteWidthDst;
1684    unsigned int srcpitch;
1685    int dwords;
1686    int srcaddr;
1687
1688    DEBUG_P("ReadPixmap");
1689    bytesPerLine = w * (bpp >> 3);
1690    byteWidthDst = ((dstwidth * (bpp >> 3) + 3L) & ~0x3L);
1691    dwords = (((bytesPerLine + 0x7) & ~0x7)) >> 2;
1692    srcaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
1693    srcpitch = pScrn->displayWidth * (bpp >> 3);
1694    srcaddr += cAcl->FbOffset;
1695
1696    ctBLTWAIT;
1697    ctSETROP( ctDSTSYSTEM | ctLEFT2RIGHT | ctTOP2BOTTOM |
1698	      ChipsAluConv[GXcopy & 0xF]);
1699    ctSETDSTADDR(0);
1700    ctSETSRCADDR(srcaddr);
1701
1702    if ((byteWidthDst & 0x7) == 0) {  /* quad-word aligned */
1703
1704	ctSETPITCH(srcpitch, byteWidthDst);
1705	ctSETHEIGHTWIDTHGO(h, bytesPerLine);
1706
1707	BE_SWAPOFF(pScrn,cPtr);
1708	MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
1709		 (unsigned char *)dst, dstwidth, 16384, h, dwords);
1710	BE_SWAPON(pScrn,cPtr);
1711
1712    } else {
1713	unsigned int vert = h;
1714
1715	h = (vert + 1) >> 1;
1716
1717	ctSETPITCH(srcpitch << 1, byteWidthDst << 1);
1718	ctSETHEIGHTWIDTHGO(h, bytesPerLine);
1719
1720	BE_SWAPOFF(pScrn,cPtr);
1721	MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
1722		 (unsigned char *)dst, dstwidth<<1, 16384, h, dwords);
1723	BE_SWAPON(pScrn,cPtr);
1724
1725	h = vert  >> 1;
1726	dst += dstwidth;
1727	y++;
1728	srcaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
1729	srcaddr += cAcl->FbOffset;
1730	ctBLTWAIT;
1731	ctSETSRCADDR(srcaddr);
1732	ctSETHEIGHTWIDTHGO(h, bytesPerLine);
1733
1734	BE_SWAPFF(pScrn,cPtr);
1735	MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
1736		 (unsigned char *)dst, dstwidth<<1, 16384, h, dwords);
1737	BE_SWAPON(pScrn,cPtr);
1738    }
1739
1740    cPtr->AccelInfoRec->NeedToSync = TRUE;
1741}
1742#endif /* ReadPixmap */
1743
1744#endif
1745
1746#endif
1747