Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004
[xf86-video-sis/mirage.git] / src / sis_accel.c
bloba19afcd9a73b51ad902c9559120aff251e1099de
1 /* $XFree86$ */
2 /*
3 * 2D acceleration for SiS5597/5598 and 6326
5 * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
6 * Parts Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
8 * Licensed under the following terms:
10 * Permission to use, copy, modify, distribute, and sell this software and its
11 * documentation for any purpose is hereby granted without fee, provided that
12 * the above copyright notice appears in all copies and that both that copyright
13 * notice and this permission notice appear in supporting documentation, and
14 * and that the name of the copyright holder not be used in advertising
15 * or publicity pertaining to distribution of the software without specific,
16 * written prior permission. The copyright holder makes no representations
17 * about the suitability of this software for any purpose. It is provided
18 * "as is" without expressed or implied warranty.
20 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
22 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
23 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
24 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
25 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
26 * PERFORMANCE OF THIS SOFTWARE.
28 * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>,
29 * Mike Chapman <mike@paranoia.com>,
30 * Juanjo Santamarta <santamarta@ctv.es>,
31 * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
32 * David Thomas <davtom@dream.org.uk>,
33 * Thomas Winischhofer <thomas@winischhofer.net>.
36 #if 0
37 #define CTSCE /* TW: Include enhanced color expansion code */
38 #endif /* This produces drawing errors sometimes */
40 #include "xf86.h"
41 #include "xf86_OSproc.h"
42 #include "xf86_ansic.h"
44 #include "xf86PciInfo.h"
45 #include "xf86Pci.h"
47 #include "sis_accel.h"
48 #include "sis_regs.h"
49 #include "sis.h"
50 #include "xaarop.h"
52 static void SiSSync(ScrnInfoPtr pScrn);
53 static void SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
54 int rop, unsigned int planemask);
55 static void SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
56 int y, int w, int h);
57 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
58 int xdir, int ydir, int rop,
59 unsigned int planemask, int transparency_color);
60 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
61 int x1, int y1, int x2,
62 int y2, int w, int h);
63 static void SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
64 int patternx, int patterny, int fg, int bg,
65 int rop, unsigned int planemask);
66 static void SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
67 int patternx, int patterny, int x, int y,
68 int w, int h);
69 #if 0
70 static void SiSSetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn,
71 int fg, int bg,
72 int rop, unsigned int planemask);
73 static void SiSSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
74 int x, int y, int w, int h,
75 int srcx, int srcy, int offset );
76 #endif
77 static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn,
78 int left, int top, int right, int bottom);
79 static void SiSDisableClipping (ScrnInfoPtr pScrn);
80 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn,
81 int color, int rop, unsigned int planemask);
82 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
83 int x1, int y1, int x2, int y2, int flags);
84 static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
85 int x, int y, int len, int dir);
86 #ifdef CTSCE
87 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
88 int fg, int bg, int rop,
89 unsigned int planemask);
90 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
91 int x, int y, int w, int h,
92 int skipleft);
93 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
94 #endif
96 Bool
97 SiSAccelInit(ScreenPtr pScreen)
99 XAAInfoRecPtr infoPtr;
100 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
101 SISPtr pSiS = SISPTR(pScrn);
102 BoxRec AvailFBArea;
103 int topFB, i;
104 int reservedFbSize;
105 int UsableFbSize;
106 unsigned char *AvailBufBase;
108 pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
109 if (!infoPtr) return FALSE;
111 infoPtr->Flags = LINEAR_FRAMEBUFFER |
112 OFFSCREEN_PIXMAPS |
113 PIXMAP_CACHE;
115 /* Sync */
116 infoPtr->Sync = SiSSync;
118 /* Screen To Screen copy */
119 infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
120 infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
121 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
123 /* Solid fill */
124 infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid;
125 infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid;
126 infoPtr->SolidFillFlags = NO_PLANEMASK;
128 /* On 5597/5598 and 6326, clipping and lines only work
129 for 1024, 2048, 4096 logical width */
130 if(pSiS->ValidWidth) {
131 /* Clipping */
132 infoPtr->SetClippingRectangle = SiSSetClippingRectangle;
133 infoPtr->DisableClipping = SiSDisableClipping;
134 infoPtr->ClippingFlags =
135 HARDWARE_CLIP_SOLID_LINE |
136 HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
137 HARDWARE_CLIP_MONO_8x8_FILL |
138 HARDWARE_CLIP_SOLID_FILL ;
140 /* Solid Lines */
141 infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
142 infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
143 infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine;
144 infoPtr->SolidLineFlags = NO_PLANEMASK;
147 if(pScrn->bitsPerPixel != 24) {
148 /* 8x8 mono pattern */
149 infoPtr->SetupForMono8x8PatternFill = SiSSetupForMono8x8PatternFill;
150 infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMono8x8PatternFillRect;
151 infoPtr->Mono8x8PatternFillFlags =
152 NO_PLANEMASK |
153 HARDWARE_PATTERN_PROGRAMMED_BITS |
154 HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
155 BIT_ORDER_IN_BYTE_MSBFIRST;
158 #ifdef CTSCE
159 if(pScrn->bitsPerPixel != 24) {
160 /* TW: per-scanline color expansion (using indirect method) */
161 pSiS->ColorExpandBufferNumber = 4;
162 pSiS->ColorExpandBufferCountMask = 0x03;
163 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31) / 32) * 4;
165 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
166 infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
168 infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
169 SiSSetupForScanlineCPUToScreenColorExpandFill;
170 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
171 SiSSubsequentScanlineCPUToScreenColorExpandFill;
172 infoPtr->SubsequentColorExpandScanline =
173 SiSSubsequentColorExpandScanline;
174 infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
175 NO_PLANEMASK |
176 CPU_TRANSFER_PAD_DWORD |
177 SCANLINE_PAD_DWORD |
178 BIT_ORDER_IN_BYTE_MSBFIRST |
179 LEFT_EDGE_CLIPPING;
180 } else {
181 pSiS->ColorExpandBufferNumber = 0;
183 #else
184 pSiS->ColorExpandBufferNumber = 0;
185 #endif
187 topFB = pSiS->maxxfbmem;
189 reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
191 UsableFbSize = topFB - reservedFbSize;
193 /* Layout: (Sizes do not reflect correct proportions)
194 * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
195 * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor
196 * topFB
199 if(pSiS->ColorExpandBufferNumber) {
200 AvailBufBase = pSiS->FbBase + UsableFbSize;
201 for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
202 pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
203 i * pSiS->PerColorExpandBufferSize;
204 pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize +
205 i * pSiS->PerColorExpandBufferSize;
208 AvailFBArea.x1 = 0;
209 AvailFBArea.y1 = 0;
210 AvailFBArea.x2 = pScrn->displayWidth;
211 AvailFBArea.y2 = UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8) - 1;
213 if (AvailFBArea.y2 < 0)
214 AvailFBArea.y2 = 32767;
216 if(AvailFBArea.y2 < pScrn->currentMode->VDisplay) {
217 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
218 "Not enough video RAM for accelerator. At least "
219 "%dKB needed, %ldKB available\n",
220 ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */
221 * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
222 pSiS->maxxfbmem/1024);
223 pSiS->NoAccel = TRUE;
224 pSiS->NoXvideo = TRUE;
225 XAADestroyInfoRec(pSiS->AccelInfoPtr);
226 pSiS->AccelInfoPtr = NULL;
227 return FALSE;
230 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
231 "Frame Buffer From (%d,%d) To (%d,%d)\n",
232 AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2);
234 xf86InitFBManager(pScreen, &AvailFBArea);
236 return(XAAInit(pScreen, infoPtr));
239 /* sync */
240 static void
241 SiSSync(ScrnInfoPtr pScrn) {
242 SISPtr pSiS = SISPTR(pScrn);
243 sisBLTSync;
246 /* Clipping */
247 static void SiSSetClippingRectangle( ScrnInfoPtr pScrn,
248 int left, int top, int right, int bottom)
250 SISPtr pSiS = SISPTR(pScrn);
252 sisBLTSync;
253 sisSETCLIPTOP(left,top);
254 sisSETCLIPBOTTOM(right,bottom);
255 pSiS->ClipEnabled = TRUE;
258 static void SiSDisableClipping(ScrnInfoPtr pScrn)
260 SISPtr pSiS = SISPTR(pScrn);
261 pSiS->ClipEnabled = FALSE;
264 /* Screen to screen copy */
265 static void
266 SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
267 int rop, unsigned int planemask,
268 int transparency_color)
270 SISPtr pSiS = SISPTR(pScrn);
271 sisBLTSync;
272 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
274 sisSETROP(XAACopyROP[rop]);
275 pSiS->Xdirection = xdir;
276 pSiS->Ydirection = ydir;
279 static void
280 SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
281 int y2, int w, int h)
283 SISPtr pSiS = SISPTR(pScrn);
284 int srcaddr, destaddr;
285 int op ;
287 op = sisCMDBLT | sisSRCVIDEO;
288 if(pSiS->Ydirection == -1) {
289 op |= sisBOTTOM2TOP;
290 srcaddr = (y1 + h - 1) * pSiS->CurrentLayout.displayWidth;
291 destaddr = (y2 + h - 1) * pSiS->CurrentLayout.displayWidth;
292 } else {
293 op |= sisTOP2BOTTOM;
294 srcaddr = y1 * pSiS->CurrentLayout.displayWidth;
295 destaddr = y2 * pSiS->CurrentLayout.displayWidth;
297 if(pSiS->Xdirection == -1) {
298 op |= sisRIGHT2LEFT;
299 srcaddr += x1 + w - 1;
300 destaddr += x2 + w - 1;
301 } else {
302 op |= sisLEFT2RIGHT;
303 srcaddr += x1;
304 destaddr += x2;
306 if (pSiS->ClipEnabled)
307 op |= sisCLIPINTRN | sisCLIPENABL;
309 srcaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
310 destaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
311 if(((pSiS->CurrentLayout.bitsPerPixel / 8) > 1) && (pSiS->Xdirection == -1)) {
312 srcaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
313 destaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
316 sisBLTSync;
317 sisSETSRCADDR(srcaddr);
318 sisSETDSTADDR(destaddr);
319 sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
320 sisSETCMD(op);
323 /* solid fill */
324 static void
325 SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
326 unsigned int planemask)
328 SISPtr pSiS = SISPTR(pScrn);
330 sisBLTSync;
331 sisSETBGROPCOL(XAACopyROP[rop], color);
332 sisSETFGROPCOL(XAACopyROP[rop], color);
333 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
336 static void
337 SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
339 SISPtr pSiS = SISPTR(pScrn);
340 int destaddr, op;
342 destaddr = y * pSiS->CurrentLayout.displayWidth + x;
344 op = sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT;
346 if(pSiS->ClipEnabled)
347 op |= sisCLIPINTRN | sisCLIPENABL;
349 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
351 sisBLTSync;
352 sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
353 sisSETDSTADDR(destaddr);
354 sisSETCMD(op);
357 /* 8x8 mono */
358 static void
359 SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
360 int fg, int bg, int rop, unsigned int planemask)
362 SISPtr pSiS = SISPTR(pScrn);
363 unsigned int *patternRegPtr;
364 int i;
366 (void)XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop);
368 sisBLTSync;
369 if(bg != -1) {
370 sisSETBGROPCOL(0xcc, bg); /* copy */
371 } else {
372 sisSETBGROPCOL(0xAA, bg); /* noop */
374 sisSETFGROPCOL(rop, fg);
375 sisSETPITCH(0, pSiS->scrnOffset);
376 sisSETSRCADDR(0);
377 patternRegPtr = (unsigned int *)sisSETPATREG();
378 pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ;
379 pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ;
380 for ( i = 0 ; i < 16 /* sisPatternHeight */ ; ) {
381 patternRegPtr[i++] = patternx ;
382 patternRegPtr[i++] = patterny ;
386 static void
387 SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
388 int patterny, int x, int y, int w, int h)
390 SISPtr pSiS = SISPTR(pScrn);
391 int dstaddr;
392 register unsigned char *patternRegPtr;
393 register unsigned char *srcPatternRegPtr;
394 register unsigned int *patternRegPtrL;
395 int i, k;
396 unsigned short tmp;
397 int shift;
398 int op = sisCMDCOLEXP |
399 sisTOP2BOTTOM |
400 sisLEFT2RIGHT |
401 sisPATFG |
402 sisSRCBG;
404 if (pSiS->ClipEnabled)
405 op |= sisCLIPINTRN | sisCLIPENABL;
407 dstaddr = ( y * pSiS->CurrentLayout.displayWidth + x ) *
408 pSiS->CurrentLayout.bitsPerPixel / 8;
410 sisBLTSync;
412 patternRegPtr = sisSETPATREG();
413 srcPatternRegPtr = (unsigned char *)pSiS->sisPatternReg ;
414 shift = 8 - patternx ;
415 for ( i = 0, k = patterny ; i < 8 ; i++, k++ ) {
416 tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ;
417 tmp >>= shift ;
418 patternRegPtr[i] = tmp & 0xff;
420 patternRegPtrL = (unsigned int *)sisSETPATREG();
421 for ( i = 2 ; i < 16 /* sisPatternHeight */; ) {
422 patternRegPtrL[i++] = patternRegPtrL[0];
423 patternRegPtrL[i++] = patternRegPtrL[1];
426 sisSETDSTADDR(dstaddr);
427 sisSETHEIGHTWIDTH(h-1, w*(pSiS->CurrentLayout.bitsPerPixel/8)-1);
428 sisSETCMD(op);
431 /* Line */
432 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn,
433 int color, int rop, unsigned int planemask)
435 SISPtr pSiS = SISPTR(pScrn);
437 sisBLTSync;
438 sisSETBGROPCOL(XAACopyROP[rop], 0);
439 sisSETFGROPCOL(XAACopyROP[rop], color);
442 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
443 int x1, int y1, int x2, int y2, int flags)
446 SISPtr pSiS = SISPTR(pScrn);
447 int op ;
448 int major, minor, err,K1,K2, tmp;
450 op = sisCMDLINE | sisSRCFG;
452 if ((flags & OMIT_LAST))
453 op |= sisLASTPIX;
455 if (pSiS->ClipEnabled)
456 op |= sisCLIPINTRN | sisCLIPENABL;
458 if ((major = x2 - x1) <= 0) {
459 major = -major;
460 } else
461 op |= sisXINCREASE;
463 if ((minor = y2 - y1) <= 0) {
464 minor = -minor;
465 } else
466 op |= sisYINCREASE;
468 if (minor >= major) {
469 tmp = minor;
470 minor = major;
471 major = tmp;
472 } else
473 op |= sisXMAJOR;
475 K1 = (minor - major)<<1;
476 K2 = minor<<1;
477 err = (minor<<1) - major;
479 sisBLTSync;
480 sisSETXStart(x1);
481 sisSETYStart(y1);
482 sisSETLineSteps((short)K1,(short)K2);
483 sisSETLineErrorTerm((short)err);
484 sisSETLineMajorCount((short)major);
485 sisSETCMD(op);
488 static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
489 int x, int y, int len, int dir)
491 SISPtr pSiS = SISPTR(pScrn);
492 int destaddr, op;
494 destaddr = y * pSiS->CurrentLayout.displayWidth + x;
496 op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT;
498 if (pSiS->ClipEnabled)
499 op |= sisCLIPINTRN | sisCLIPENABL;
501 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
503 sisBLTSync;
505 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
507 if(dir == DEGREES_0) {
508 sisSETHEIGHTWIDTH(0, len * (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
509 } else {
510 sisSETHEIGHTWIDTH(len - 1, (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
513 sisSETDSTADDR(destaddr);
514 sisSETCMD(op);
517 #ifdef CTSCE
518 /* TW: ----- CPU To Screen Color Expand (scanline-wise) ------ */
519 static void
520 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
521 int fg, int bg, int rop, unsigned int planemask)
523 SISPtr pSiS=SISPTR(pScrn);
525 pSiS->CommandReg = 0;
527 pSiS->CommandReg |= (sisCMDECOLEXP |
528 sisLEFT2RIGHT |
529 sisTOP2BOTTOM);
531 sisBLTSync;
533 /* TW: The combination of flags in the following
534 * is not understandable. However, this is the
535 * only combination that seems to work.
537 if(bg == -1) {
538 sisSETROPBG(0xAA); /* dst = dst (=noop) */
539 pSiS->CommandReg |= sisSRCFG;
540 } else {
541 sisSETBGROPCOL(XAAPatternROP[rop], bg);
542 pSiS->CommandReg |= sisSRCFG | sisPATBG;
545 sisSETFGROPCOL(XAACopyROP[rop], fg);
547 sisSETDSTPITCH(pSiS->scrnOffset);
551 static void
552 SiSSubsequentScanlineCPUToScreenColorExpandFill(
553 ScrnInfoPtr pScrn, int x, int y, int w,
554 int h, int skipleft)
556 SISPtr pSiS = SISPTR(pScrn);
557 int _x0, _y0, _x1, _y1;
558 int op = pSiS->CommandReg;
560 if(skipleft > 0) {
561 _x0 = x + skipleft;
562 _y0 = y;
563 _x1 = x + w;
564 _y1 = y + h;
565 sisSETCLIPTOP(_x0, _y0);
566 sisSETCLIPBOTTOM(_x1, _y1);
567 op |= sisCLIPENABL;
568 } else {
569 op &= (~(sisCLIPINTRN | sisCLIPENABL));
572 sisSETSRCPITCH(((((w+7)/8)+3) >> 2) * 4);
574 sisSETHEIGHTWIDTH(1-1, (w * (pSiS->CurrentLayout.bitsPerPixel/8)) - 1);
576 pSiS->xcurrent = x;
577 pSiS->ycurrent = y;
579 pSiS->CommandReg = op;
582 static void
583 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
585 SISPtr pSiS = SISPTR(pScrn);
586 long cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
587 int op = pSiS->CommandReg;
588 int destaddr;
590 destaddr = (pSiS->ycurrent * pSiS->CurrentLayout.displayWidth) + pSiS->xcurrent;
591 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
593 /* TW: Wait until there is no color expansion command in queue */
594 /* sisBLTSync; */
596 sisSETSRCADDR(cbo);
598 sisSETDSTADDR(destaddr);
600 sisSETCMD(op);
602 pSiS->ycurrent++;
604 /* TW: Wait for eventual color expand commands to finish */
605 /* (needs to be done, otherwise the data in the buffer may
606 * be overwritten while accessed by the hardware)
608 while((MMIO_IN32(pSiS->IOBase, 0x8284) & 0x80000000)) {}
610 sisBLTSync;
612 #endif /* CTSCE */