Pull XORG-6_8_0 to CYGWIN branch
[xf86-video-sis/mirage.git] / src / sis300_accel.c
blob78d93e6b50b1b7816466efbfc312e972f9bec256
1 /* $XFree86$ */
2 /* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c,v 1.6 2004/08/04 15:46:33 twini Exp $ */
3 /*
4 * 2D Acceleration for SiS 530, 620, 300, 540, 630, 730.
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1) Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2) Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3) The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Authors: Thomas Winischhofer <thomas@winischhofer.net>
31 * Can-Ru Yeou, SiS Inc.
35 #if 0
36 #define DEBUG
37 #endif
39 #include "xf86.h"
40 #include "xf86_OSproc.h"
41 #include "xf86_ansic.h"
42 #include "xf86PciInfo.h"
43 #include "xf86Pci.h"
44 #include "compiler.h"
45 #include "xaa.h"
46 #include "xaarop.h"
48 #include "sis.h"
49 #include "sis300_accel.h"
51 #ifdef SISDUALHEAD
52 /* TW: This is the offset to the memory for each head */
53 #define HEADOFFSET (pSiS->dhmOffset)
54 #endif
56 #undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work */
58 #undef TRAP /* Use/Don't use Trapezoid Fills - does not work - XAA provides
59 * illegal trapezoid data (left and right edges cross each other
60 * sometimes) which causes drawing errors. Further, I have not found
61 * out how to draw polygones with a height greater than 127...
64 static void SiSInitializeAccelerator(ScrnInfoPtr pScrn);
65 static void SiSSync(ScrnInfoPtr pScrn);
66 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
67 int xdir, int ydir, int rop,
68 unsigned int planemask, int trans_color);
69 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
70 int x1, int y1, int x2, int y2,
71 int width, int height);
72 static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
73 int rop, unsigned int planemask);
74 static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
75 int x, int y, int w, int h);
76 #ifdef TRAP
77 static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
78 int left, int dxL, int dyL, int eL,
79 int right, int dxR, int dyR, int eR);
80 #endif
81 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color,
82 int rop, unsigned int planemask);
83 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1,
84 int y1, int x2, int y2, int flags);
85 static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
86 int x, int y, int len, int dir);
87 static void SiSSetupForDashedLine(ScrnInfoPtr pScrn,
88 int fg, int bg, int rop, unsigned int planemask,
89 int length, unsigned char *pattern);
90 static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
91 int x1, int y1, int x2, int y2,
92 int flags, int phase);
93 static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
94 int patx, int paty, int fg, int bg,
95 int rop, unsigned int planemask);
96 static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
97 int patx, int paty,
98 int x, int y, int w, int h);
99 #ifdef TRAP
100 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
101 int patx, int paty,
102 int y, int h,
103 int left, int dxL, int dyL, int eL,
104 int right, int dxR, int dyR, int eR );
105 #endif
106 #if 0
107 static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn,
108 int patx, int paty, int rop,
109 unsigned int planemask,
110 int trans_color);
111 static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn,
112 int patx, int paty,
113 int x, int y, int w, int h);
114 #endif
115 #if 0
116 static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
117 int fg, int bg,
118 int rop, unsigned int planemask);
119 static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
120 int x, int y, int w, int h, int skipleft);
121 #endif
122 #ifdef STSCE
123 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
124 int fg, int bg,
125 int rop, unsigned int planemask);
126 static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
127 int x, int y, int w, int h,
128 int srcx, int srcy, int skipleft);
129 #endif
130 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
131 int fg, int bg, int rop,
132 unsigned int planemask);
133 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
134 int x, int y, int w, int h,
135 int skipleft);
136 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
138 #ifdef SISDUALHEAD
139 static void SiSRestoreAccelState(ScrnInfoPtr pScrn);
140 #endif
142 extern unsigned char SiSGetCopyROP(int rop);
143 extern unsigned char SiSGetPatternROP(int rop);
145 static void
146 SiSInitializeAccelerator(ScrnInfoPtr pScrn)
148 SISPtr pSiS = SISPTR(pScrn);
150 pSiS->DoColorExpand = FALSE;
153 Bool
154 SiS300AccelInit(ScreenPtr pScreen)
156 XAAInfoRecPtr infoPtr;
157 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
158 SISPtr pSiS = SISPTR(pScrn);
159 int topFB;
160 int reservedFbSize;
161 int UsableFbSize;
162 unsigned char *AvailBufBase;
163 BoxRec Avail;
164 int i;
166 pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
167 if (!infoPtr) return FALSE;
169 SiSInitializeAccelerator(pScrn);
171 infoPtr->Flags = LINEAR_FRAMEBUFFER |
172 OFFSCREEN_PIXMAPS |
173 PIXMAP_CACHE;
175 /* sync */
176 infoPtr->Sync = SiSSync;
178 /* Acceleration only supported at 8, 16 and 32 bpp */
179 if((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) &&
180 (pScrn->bitsPerPixel != 32))
181 return FALSE;
183 /* Although SiS states that the 300 series supports a
184 * virtual framebuffer of 4096x4096, the 2D accelerator
185 * does not seem to know that. If the destination bitmap
186 * pitch is > 8192 (which easily happens in 32bpp mode),
187 * the accelerator engine collapses.
188 * TODO: Find out about the 530 and 620
191 if(pSiS->scrnOffset < 8192) {
193 /* screen to screen copy */
194 infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
195 infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
196 infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK |
197 TRANSPARENCY_GXCOPY_ONLY;
199 /* solid fills */
200 infoPtr->SetupForSolidFill = SiSSetupForSolidFill;
201 infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect;
202 #ifdef TRAP
203 infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap;
204 #endif
205 infoPtr->SolidFillFlags = NO_PLANEMASK;
207 /* solid line */
208 infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
209 infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
210 infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine;
211 infoPtr->SolidLineFlags = NO_PLANEMASK;
213 /* dashed line */
214 infoPtr->SetupForDashedLine = SiSSetupForDashedLine;
215 infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine;
216 infoPtr->DashPatternMaxLength = 64;
217 infoPtr->DashedLineFlags = NO_PLANEMASK |
218 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
220 /* 8x8 mono pattern fill */
221 infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill;
222 infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill;
223 #ifdef TRAP
224 infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap;
225 #endif
226 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
227 HARDWARE_PATTERN_SCREEN_ORIGIN |
228 HARDWARE_PATTERN_PROGRAMMED_BITS |
229 /* NO_TRANSPARENCY | */
230 BIT_ORDER_IN_BYTE_MSBFIRST ;
232 #ifdef STSCE
233 /* Screen To Screen Color Expand */
234 /* The hardware does support this the way we need it */
235 infoPtr->SetupForScreenToScreenColorExpandFill =
236 SiSSetupForScreenToScreenColorExpand;
237 infoPtr->SubsequentScreenToScreenColorExpandFill =
238 SiSSubsequentScreenToScreenColorExpand;
239 infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
240 BIT_ORDER_IN_BYTE_MSBFIRST ;
241 #endif
243 #if 0
244 /* CPU To Screen Color Expand --- implement another instead of this one! */
245 infoPtr->SetupForCPUToScreenColorExpandFill =
246 SiSSetupForCPUToScreenColorExpand;
247 infoPtr->SubsequentCPUToScreenColorExpandFill =
248 SiSSubsequentCPUToScreenColorExpand;
249 infoPtr->ColorExpandRange = PATREGSIZE;
250 infoPtr->ColorExpandBase = pSiS->IOBase+PBR(0);
251 infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK |
252 BIT_ORDER_IN_BYTE_MSBFIRST |
253 NO_TRANSPARENCY |
254 SYNC_AFTER_COLOR_EXPAND;
255 #endif
257 /* per-scanline color expansion (using indirect method) */
258 if(pSiS->VGAEngine == SIS_530_VGA) {
259 pSiS->ColorExpandBufferNumber = 4;
260 pSiS->ColorExpandBufferCountMask = 0x03;
261 } else {
262 pSiS->ColorExpandBufferNumber = 16;
263 pSiS->ColorExpandBufferCountMask = 0x0F;
265 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
266 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
267 infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
269 infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
270 SiSSetupForScanlineCPUToScreenColorExpandFill;
271 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
272 SiSSubsequentScanlineCPUToScreenColorExpandFill;
273 infoPtr->SubsequentColorExpandScanline =
274 SiSSubsequentColorExpandScanline;
275 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
276 CPU_TRANSFER_PAD_DWORD |
277 SCANLINE_PAD_DWORD |
278 BIT_ORDER_IN_BYTE_MSBFIRST |
279 LEFT_EDGE_CLIPPING;
280 } else {
281 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
282 "Virtual screen width too large for accelerator engine\n");
283 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
284 "2D acceleration and Xv disabled\n");
285 pSiS->NoXvideo = TRUE;
288 #ifdef SISDUALHEAD
289 if(pSiS->DualHeadMode) {
290 infoPtr->RestoreAccelState = SiSRestoreAccelState;
292 #endif
294 /* init Frame Buffer Manager */
295 topFB = pSiS->maxxfbmem;
297 reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
299 UsableFbSize = topFB - reservedFbSize;
301 /* Layout: (Sizes do not reflect correct proportions)
302 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
303 * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series
304 * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
305 * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620
306 * topFB
309 AvailBufBase = pSiS->FbBase + UsableFbSize;
310 for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
311 pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
312 i * pSiS->PerColorExpandBufferSize;
313 pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize +
314 i * pSiS->PerColorExpandBufferSize;
316 Avail.x1 = 0;
317 Avail.y1 = 0;
318 Avail.x2 = pScrn->displayWidth;
319 Avail.y2 = (UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1;
321 if(Avail.y2 < 0) Avail.y2 = 32767;
323 if(Avail.y2 < pScrn->currentMode->VDisplay) {
324 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
325 "Not enough video RAM for accelerator. At least "
326 "%dKB needed, %ldKB available\n",
327 ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */
328 * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
329 pSiS->maxxfbmem/1024);
330 pSiS->NoAccel = TRUE;
331 pSiS->NoXvideo = TRUE;
332 XAADestroyInfoRec(pSiS->AccelInfoPtr);
333 pSiS->AccelInfoPtr = NULL;
334 return FALSE;
337 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
338 "Frame Buffer From (%d,%d) To (%d,%d)\n",
339 Avail.x1, Avail.y1, Avail.x2, Avail.y2);
341 xf86InitFBManager(pScreen, &Avail);
343 return(XAAInit(pScreen, infoPtr));
347 static void
348 SiSSync(ScrnInfoPtr pScrn)
350 SISPtr pSiS = SISPTR(pScrn);
352 PDEBUG(ErrorF("SiSSync()\n"));
354 pSiS->DoColorExpand = FALSE;
355 SiSIdle
358 #ifdef SISDUALHEAD
359 static void
360 SiSRestoreAccelState(ScrnInfoPtr pScrn)
362 SISPtr pSiS = SISPTR(pScrn);
364 /* We don't need to do anything special here; forcing the
365 * other head to re-read the CmdQueLen is not necessary:
366 * After the Sync in RestoreAccelState(), the real queue
367 * length is always larger than (or at least equal to)
368 * the amount stored in CmdQueueLen of the other head,
369 * so the only thing that might happen is one unnecessary
370 * Sync on the other head. I think we can live with that.
372 pSiS->DoColorExpand = FALSE;
373 SiSIdle
375 #endif
377 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
378 int xdir, int ydir, int rop,
379 unsigned int planemask, int trans_color)
381 SISPtr pSiS = SISPTR(pScrn);
383 PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
384 xdir, ydir, rop, planemask, trans_color));
386 SiSSetupDSTColorDepth(pSiS->DstColor);
387 SiSSetupSRCPitch(pSiS->scrnOffset)
388 SiSSetupDSTRect(pSiS->scrnOffset, -1)
390 if(trans_color != -1) {
391 SiSSetupROP(0x0A)
392 SiSSetupSRCTrans(trans_color)
393 SiSSetupCMDFlag(TRANSPARENT_BITBLT)
394 } else {
395 SiSSetupROP(SiSGetCopyROP(rop))
397 if(xdir > 0) {
398 SiSSetupCMDFlag(X_INC)
400 if(ydir > 0) {
401 SiSSetupCMDFlag(Y_INC)
405 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
406 int src_x, int src_y, int dst_x, int dst_y,
407 int width, int height)
409 SISPtr pSiS = SISPTR(pScrn);
410 CARD32 srcbase, dstbase;
412 PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
413 src_x, src_y, dst_x, dst_y, width, height));
415 srcbase = dstbase = 0;
416 if(src_y >= 2048) {
417 srcbase = pSiS->scrnOffset * src_y;
418 src_y = 0;
420 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
421 dstbase = pSiS->scrnOffset * dst_y;
422 dst_y = 0;
424 #ifdef SISDUALHEAD
425 if(pSiS->VGAEngine != SIS_530_VGA) {
426 srcbase += HEADOFFSET;
427 dstbase += HEADOFFSET;
429 #endif
430 SiSSetupSRCBase(srcbase);
431 SiSSetupDSTBase(dstbase);
433 if(!(pSiS->CommandReg & X_INC)) {
434 src_x += width-1;
435 dst_x += width-1;
437 if(!(pSiS->CommandReg & Y_INC)) {
438 src_y += height-1;
439 dst_y += height-1;
441 SiSSetupRect(width, height)
442 SiSSetupSRCXY(src_x, src_y)
443 SiSSetupDSTXY(dst_x, dst_y)
445 SiSDoCMD
448 static void
449 SiSSetupForSolidFill(ScrnInfoPtr pScrn,
450 int color, int rop, unsigned int planemask)
452 SISPtr pSiS = SISPTR(pScrn);
454 PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
455 color, rop, planemask));
457 if(pSiS->disablecolorkeycurrent) {
458 if((CARD32)color == pSiS->colorKey) {
459 rop = 5; /* NOOP */
462 SiSSetupPATFG(color)
463 SiSSetupDSTRect(pSiS->scrnOffset, -1)
464 SiSSetupDSTColorDepth(pSiS->DstColor);
465 SiSSetupROP(SiSGetPatternROP(rop))
466 /* SiSSetupCMDFlag(PATFG) - is zero */
469 static void
470 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
471 int x, int y, int w, int h)
473 SISPtr pSiS = SISPTR(pScrn);
474 CARD32 dstbase;
476 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
477 x, y, w, h));
478 dstbase = 0;
480 if(y >= 2048) {
481 dstbase = pSiS->scrnOffset * y;
482 y = 0;
484 #ifdef SISDUALHEAD
485 if(pSiS->VGAEngine != SIS_530_VGA) {
486 dstbase += HEADOFFSET;
488 #endif
489 SiSSetupDSTBase(dstbase)
490 SiSSetupDSTXY(x,y)
491 SiSSetupRect(w,h)
492 /* Clear commandReg because Setup can be used for Rect and Trap */
493 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
494 T_L_X_INC | T_L_Y_INC |
495 T_R_X_INC | T_R_Y_INC |
496 TRAPAZOID_FILL);
497 SiSSetupCMDFlag(X_INC | Y_INC | BITBLT)
499 SiSDoCMD
502 /* Trapezoid */
503 /* This would work better if XAA would provide us with valid trapezoids.
504 * In fact, with small trapezoids the left and the right edge often cross
505 * each other or result in a line length of 0 which causes drawing errors
506 * (filling over whole scanline).
507 * Furthermore, I have not found out how to draw trapezoids with a height
508 * greater than 127.
510 #ifdef TRAP
511 static void
512 SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
513 int left, int dxL, int dyL, int eL,
514 int right, int dxR, int dyR, int eR )
516 SISPtr pSiS = SISPTR(pScrn);
517 CARD32 dstbase;
518 #if 0
519 float kL, kR;
520 #endif
522 dstbase = 0;
523 if(y >= 2048) {
524 dstbase=pSiS->scrnOffset*y;
525 y = 0;
527 #ifdef SISDUALHEAD
528 if(pSiS->VGAEngine != SIS_530_VGA) {
529 dstbase += HEADOFFSET;
531 #endif
532 SiSSetupDSTBase(dstbase)
533 /* SiSSetupRect(w,h) */
535 #if 1
536 SiSSetupPATFG(0xff0000) /* FOR TESTING */
537 #endif
539 /* Clear CommandReg because SetUp can be used for Rect and Trap */
540 pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC |
541 T_R_X_INC | T_R_Y_INC |
542 T_XISMAJORL | T_XISMAJORR |
543 BITBLT);
545 xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
546 left, right, y, h, dxL, dyL, eL, dxR, dyR, eR);
548 /* Unfortunately, we must check if the right and the left edge
549 * cross each other... INCOMPLETE (line equation wrong)
551 #if 0
552 if (dxL == 0) kL = 0;
553 else kL = (float)dyL / (float)dxL;
554 if (dxR == 0) kR = 0;
555 else kR = (float)dyR / (float)dxR;
556 xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR);
557 if ( (kR != kL) &&
558 (!(kR == 0 && kL == 0)) &&
559 (!(kR < 0 && kL > 0)) ) {
560 xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y);
561 if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) {
562 xf86DrvMsg(0, X_INFO, "Cross detected!\n");
565 #endif
567 /* Determine egde angles */
568 if(dxL < 0) { dxL = -dxL; }
569 else { SiSSetupCMDFlag(T_L_X_INC) }
570 if(dxR < 0) { dxR = -dxR; }
571 else { SiSSetupCMDFlag(T_R_X_INC) }
573 /* (Y direction always positive - do this anyway) */
574 if(dyL < 0) { dyL = -dyL; }
575 else { SiSSetupCMDFlag(T_L_Y_INC) }
576 if(dyR < 0) { dyR = -dyR; }
577 else { SiSSetupCMDFlag(T_R_Y_INC) }
579 /* Determine major axis */
580 if(dxL >= dyL) { /* X is major axis */
581 SiSSetupCMDFlag(T_XISMAJORL)
583 if(dxR >= dyR) { /* X is major axis */
584 SiSSetupCMDFlag(T_XISMAJORR)
587 /* Set up deltas */
588 SiSSetupdL(dxL, dyL)
589 SiSSetupdR(dxR, dyR)
591 #if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */
592 h &= 0x7F;
593 if (h == 0) h = 10;
594 #endif
596 /* Set up y, h, left, right */
597 SiSSetupYH(y,h)
598 SiSSetupLR(left,right)
600 /* Set up initial error term */
601 SiSSetupEL(eL)
602 SiSSetupER(eR)
604 SiSSetupCMDFlag(TRAPAZOID_FILL);
606 SiSDoCMD
608 #endif
610 static void
611 SiSSetupForSolidLine(ScrnInfoPtr pScrn,
612 int color, int rop, unsigned int planemask)
614 SISPtr pSiS = SISPTR(pScrn);
616 PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
617 color, rop, planemask));
619 SiSSetupLineCount(1)
620 SiSSetupPATFG(color)
621 SiSSetupDSTRect(pSiS->scrnOffset, -1)
622 SiSSetupDSTColorDepth(pSiS->DstColor);
623 SiSSetupROP(SiSGetPatternROP(rop))
624 SiSSetupCMDFlag(PATFG | LINE)
627 static void
628 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
629 int x1, int y1, int x2, int y2, int flags)
631 SISPtr pSiS = SISPTR(pScrn);
632 CARD32 dstbase;
633 int miny,maxy;
635 PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
636 x1, y1, x2, y2, flags));
638 dstbase = 0;
639 miny = (y1 > y2) ? y2 : y1;
640 maxy = (y1 > y2) ? y1 : y2;
641 if(maxy >= 2048) {
642 dstbase = pSiS->scrnOffset * miny;
643 y1 -= miny;
644 y2 -= miny;
646 #ifdef SISDUALHEAD
647 if(pSiS->VGAEngine != SIS_530_VGA) {
648 dstbase += HEADOFFSET;
650 #endif
651 SiSSetupDSTBase(dstbase)
653 SiSSetupX0Y0(x1,y1)
654 SiSSetupX1Y1(x2,y2)
655 if(flags & OMIT_LAST) {
656 SiSSetupCMDFlag(NO_LAST_PIXEL)
657 } else {
658 pSiS->CommandReg &= ~(NO_LAST_PIXEL);
661 SiSDoCMD
664 static void
665 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
666 int x, int y, int len, int dir)
668 SISPtr pSiS = SISPTR(pScrn);
669 CARD32 dstbase;
671 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
672 x, y, len, dir));
673 len--; /* starting point is included! */
675 dstbase = 0;
676 if((y >= 2048) || ((dir != DEGREES_0) && ((y + len) >= 2048))) {
677 dstbase = pSiS->scrnOffset * y;
678 y = 0;
680 #ifdef SISDUALHEAD
681 if(pSiS->VGAEngine != SIS_530_VGA) {
682 dstbase += HEADOFFSET;
684 #endif
685 SiSSetupDSTBase(dstbase)
687 SiSSetupX0Y0(x,y)
688 if(dir == DEGREES_0) {
689 SiSSetupX1Y1(x + len, y);
690 } else {
691 SiSSetupX1Y1(x, y + len);
694 SiSDoCMD
697 static void
698 SiSSetupForDashedLine(ScrnInfoPtr pScrn,
699 int fg, int bg, int rop, unsigned int planemask,
700 int length, unsigned char *pattern)
702 SISPtr pSiS = SISPTR(pScrn);
704 PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
705 fg, bg, rop, planemask, length, *(pattern+4), *pattern));
707 SiSSetupLineCount(1)
708 SiSSetupDSTRect(pSiS->scrnOffset, -1)
709 SiSSetupDSTColorDepth(pSiS->DstColor);
710 SiSSetupStyleLow(*pattern)
711 SiSSetupStyleHigh(*(pattern+4))
712 SiSSetupStylePeriod(length-1);
713 SiSSetupROP(SiSGetPatternROP(rop))
714 SiSSetupPATFG(fg)
715 SiSSetupCMDFlag(LINE | LINE_STYLE)
716 if(bg != -1) {
717 SiSSetupPATBG(bg)
718 } else {
719 SiSSetupCMDFlag(TRANSPARENT);
723 static void
724 SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
725 int x1, int y1, int x2, int y2,
726 int flags, int phase)
728 SISPtr pSiS = SISPTR(pScrn);
729 CARD32 dstbase;
730 int miny,maxy;
732 PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n",
733 x1, y1, x2, y2, flags, phase));
735 dstbase = 0;
736 miny = (y1 > y2) ? y2 : y1;
737 maxy = (y1 > y2) ? y1 : y2;
738 if(maxy >= 2048) {
739 dstbase = pSiS->scrnOffset * miny;
740 y1 -= miny;
741 y2 -= miny;
743 #ifdef SISDUALHEAD
744 if(pSiS->VGAEngine != SIS_530_VGA) {
745 dstbase += HEADOFFSET;
747 #endif
748 SiSSetupDSTBase(dstbase)
750 SiSSetupX0Y0(x1,y1)
751 SiSSetupX1Y1(x2,y2)
752 if(flags & OMIT_LAST) {
753 SiSSetupCMDFlag(NO_LAST_PIXEL)
754 } else {
755 pSiS->CommandReg &= ~(NO_LAST_PIXEL);
758 SiSDoCMD
761 static void
762 SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
763 int patx, int paty, int fg, int bg,
764 int rop, unsigned int planemask)
766 SISPtr pSiS = SISPTR(pScrn);
768 PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
769 patx, paty, fg, bg, rop, planemask));
770 SiSSetupDSTRect(pSiS->scrnOffset, -1)
771 SiSSetupDSTColorDepth(pSiS->DstColor);
772 SiSSetupMONOPAT(patx,paty)
773 SiSSetupPATFG(fg)
774 SiSSetupROP(SiSGetPatternROP(rop))
775 SiSSetupCMDFlag(PATMONO)
776 if(bg != -1) {
777 SiSSetupPATBG(bg)
778 } else {
779 SiSSetupCMDFlag(TRANSPARENT)
783 static void
784 SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
785 int patx, int paty,
786 int x, int y, int w, int h)
788 SISPtr pSiS = SISPTR(pScrn);
789 CARD32 dstbase;
791 PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
792 patx, paty, x, y, w, h));
793 dstbase = 0;
795 if(y >= 2048) {
796 dstbase = pSiS->scrnOffset * y;
797 y = 0;
799 #ifdef SISDUALHEAD
800 if(pSiS->VGAEngine != SIS_530_VGA) {
801 dstbase += HEADOFFSET;
803 #endif
804 SiSSetupDSTBase(dstbase)
805 SiSSetupDSTXY(x, y)
806 SiSSetupRect(w, h)
807 /* Clear commandReg because Setup can be used for Rect and Trap */
808 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
809 T_L_X_INC | T_L_Y_INC |
810 T_R_X_INC | T_R_Y_INC |
811 TRAPAZOID_FILL);
812 SiSSetupCMDFlag(X_INC | Y_INC)
814 SiSDoCMD
817 /* Trapezoid */
818 #ifdef TRAP
819 static void
820 SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
821 int patx, int paty,
822 int y, int h,
823 int left, int dxL, int dyL, int eL,
824 int right, int dxR, int dyR, int eR )
826 SISPtr pSiS = SISPTR(pScrn);
827 CARD32 dstbase;
829 PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
830 y, h, left, right, dxL, dxR, eL, eR));
832 dstbase = 0;
833 if(y >= 2048) {
834 dstbase = pSiS->scrnOffset * y;
835 y = 0;
837 #ifdef SISDUALHEAD
838 if(pSiS->VGAEngine != SIS_530_VGA) {
839 dstbase += HEADOFFSET;
841 #endif
842 SiSSetupDSTBase(dstbase)
844 /* Clear CommandReg because SetUp can be used for Rect and Trap */
845 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
846 T_L_X_INC | T_L_Y_INC |
847 T_R_X_INC | T_R_Y_INC |
848 BITBLT);
850 if(dxL < 0) { dxL = -dxL; }
851 else { SiSSetupCMDFlag(T_L_X_INC) }
852 if(dxR < 0) { dxR = -dxR; }
853 else { SiSSetupCMDFlag(T_R_X_INC) }
855 if(dyL < 0) { dyL = -dyL; }
856 else { SiSSetupCMDFlag(T_L_Y_INC) }
857 if(dyR < 0) { dyR = -dyR; }
858 else { SiSSetupCMDFlag(T_R_Y_INC) }
860 /* Determine major axis */
861 if(dxL >= dyL) { /* X is major axis */
862 SiSSetupCMDFlag(T_XISMAJORL)
864 if(dxR >= dyR) { /* X is major axis */
865 SiSSetupCMDFlag(T_XISMAJORR)
868 SiSSetupYH(y,h)
869 SiSSetupLR(left,right)
871 SiSSetupdL(dxL, dyL)
872 SiSSetupdR(dxR, dyR)
874 SiSSetupEL(eL)
875 SiSSetupER(eR)
877 SiSSetupCMDFlag(TRAPAZOID_FILL);
879 SiSDoCMD
881 #endif
884 #if 0
886 /* The following (already commented) functions have NOT been adapted for dual-head mode */
888 /* ----- CPU To Screen Color Expand (single task) ------------------------- */
890 /* This does not work. Assumingly for the same
891 * reason why STSColorExpand does not work either.
893 static void
894 SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
895 int fg, int bg,
896 int rop, unsigned int planemask)
898 SISPtr pSiS = SISPTR(pScrn);
900 PDEBUG(ErrorF("Setup CPUToScreen ColorExpand(0x%x,0x%x, 0x%x,0x%x)\n",
901 fg, bg, rop, planemask));
903 /* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/
904 SiSSetupDSTRect(pSiS->scrnOffset, -1)
905 SiSSetupDSTColorDepth(pSiS->DstColor);
906 SiSSetupSRCXY(0,0)
907 SiSSetupSRCFG(fg)
908 SiSSetupROP(SiSGetPatternROP(rop))
909 SiSSetupCMDFlag(X_INC | Y_INC | COLOREXP)
910 if(bg == -1) {
911 SiSSetupCMDFlag(TRANSPARENT)
912 } else {
913 SiSSetupSRCBG(bg)
917 static void
918 SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
919 int x, int y, int w, int h, int skipleft)
921 SISPtr pSiS = SISPTR(pScrn);
922 CARD32 dstbase;
924 PDEBUG(ErrorF("Subsequent CPUToScreen ColorExpand(%d,%d, %d,%d, %d)\n",
925 x, y, w, h, skipleft));
927 dstbase = 0;
928 if(y >= 2048) {
929 dstbase = pSiS->scrnOffset * y;
930 y = 0;
932 SiSSetupDSTBase(dstbase)
934 /* SiSSetupSRCPitch(((w+31)&0xFFE0)/8)*/
935 SiSSetupSRCPitch((w+7)/8)
936 SiSSetupDSTXY(x,y)
937 SiSSetupRect(w,h)
938 /* SiSDoCMD*/
939 pSiS->DoColorExpand = TRUE;
941 #endif
943 /* ------ Screen To Screen Color Expand ------------------------------- */
945 /* The hareware does not seem to support this the way we need it */
947 #ifdef STSCE
948 static void
949 SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
950 int fg, int bg,
951 int rop, unsigned int planemask)
953 SISPtr pSiS = SISPTR(pScrn);
955 PDEBUG(ErrorF("Setup ScreenToScreen ColorExp(0x%x,0x%x, 0x%x)\n",
956 fg, bg, rop));
958 SiSSetupDSTColorDepth(pSiS->DstColor)
959 SiSSetupDSTRect(pSiS->scrnOffset, -1)
960 SiSSetupROP(SiSGetCopyROP(rop))
961 SiSSetupSRCFG(fg)
962 /* SiSSetupSRCXY(0,0) */
964 if(bg == -1) {
965 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | X_INC |
966 Y_INC | SRCVIDEO);
967 } else {
968 SiSSetupSRCBG(bg);
969 SiSSetupCMDFlag(ENCOLOREXP | X_INC | Y_INC |
970 SRCVIDEO);
973 #endif
975 /* This method blits in a single task; this does not seem to work
976 * because the hardware does not use the source pitch as scanline
977 * offset but only to calculate pattern address from source X and Y.
978 * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
979 * offset, but this does not seem to be supported by the hardware.
981 #ifdef STSCE
983 /* For testing, these are the methods: (use only one at a time!) */
985 #undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
986 * This would work if the hareware used the source pitch for
987 * incrementing the source address after each scanline - but
988 * it doesn't do this! The first line of the area is correctly
989 * color expanded, but since the source pitch is ignored and
990 * the source address not incremented correctly, the following
991 * lines are color expanded with any bit pattern that is left
992 * in the unused space of the source bitmap (which is organized
993 * with the depth of the screen framebuffer hence with a pitch
994 * of scrnOffset).
997 #undef pitchdw /* Use source pitch "displayWidth / 8" instead
998 * of scrnOffset (=displayWidth * bpp / 8)
999 * This can't work, because the pitch of the source
1000 * bitmap is scrnoffset!
1003 #define nopitch /* Calculate srcbase with srcx and srcy, set the
1004 * pitch to scrnOffset (which IS the correct pitch
1005 * for the source bitmap) and set srcx and srcy both
1006 * to 0.
1007 * This would work if the hareware used the source pitch for
1008 * incrementing the source address after each scanline - but
1009 * it doesn't do this! Again: The first line of the area is
1010 * correctly color expanded, but since the source pitch is
1011 * ignored for scanline address incremention, the following
1012 * lines are not correctly color expanded.
1013 * WHATEVER I write to source pitch is ignored!
1016 static void
1017 SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
1018 int x, int y, int w, int h,
1019 int srcx, int srcy, int skipleft)
1021 SISPtr pSiS = SISPTR(pScrn);
1022 CARD32 srcbase, dstbase;
1023 #if 0
1024 int _x0, _y0, _x1, _y1;
1025 #endif
1026 #ifdef pitchdw
1027 int newsrcx, newsrcy;
1029 /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
1030 * We recalulate srcx and srcy based on pitch = displayWidth / 8
1032 newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) /
1033 (pScrn->displayWidth/8);
1034 newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) %
1035 (pScrn->displayWidth/8);
1036 #endif
1037 xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
1038 x, y, w, h, srcx, srcy, skipleft);
1040 srcbase = dstbase = 0;
1042 #ifdef pitchdw
1043 if(newsrcy >= 2048) {
1044 srcbase = (pScrn->displayWidth / 8) * newsrcy;
1045 newsrcy = 0;
1047 #endif
1048 #ifdef nopitch
1049 srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8));
1050 #endif
1051 #ifdef npitch
1052 if(srcy >= 2048) {
1053 srcbase = pSiS->scrnOffset * srcy;
1054 srcy = 0;
1056 #endif
1057 if(y >= 2048) {
1058 dstbase = pSiS->scrnOffset * y;
1059 y = 0;
1061 #ifdef SISDUALHEAD
1062 if(pSiS->VGAEngine != SIS_530_VGA) {
1063 srcbase += HEADOFFSET;
1064 dstbase += HEADOFFSET;
1066 #endif
1067 SiSSetupSRCBase(srcbase)
1068 SiSSetupDSTBase(dstbase)
1070 #ifdef pitchdw
1071 SiSSetupSRCPitch(pScrn->displayWidth/8)
1072 #endif
1073 #ifdef nopitch
1074 SiSSetupSRCPitch(pSiS->scrnOffset)
1075 /* SiSSetupSRCPitch(100) */ /* For test - has NO effect WHATSOEVER */
1076 #endif
1077 #ifdef npitch
1078 SiSSetupSRCPitch(pSiS->scrnOffset)
1079 #endif
1081 SiSSetupRect(w,h)
1083 #if 0 /* How do I implement the offset? Not this way, that's for sure.. */
1084 if (skipleft > 0) {
1085 _x0 = x+skipleft;
1086 _y0 = y;
1087 _x1 = x+w;
1088 _y1 = y+h;
1089 SiSSetupClipLT(_x0, _y0);
1090 SiSSetupClipRB(_x1, _y1);
1091 SiSSetupCMDFlag(CLIPENABLE);
1093 #endif
1094 #ifdef pitchdw
1095 SiSSetupSRCXY(newsrcx, newsrcy)
1096 #endif
1097 #ifdef nopitch
1098 SiSSetupSRCXY(0,0)
1099 #endif
1100 #ifdef npitch
1101 SiSSetupSRCXY(srcx, srcy)
1102 #endif
1104 SiSSetupDSTXY(x,y)
1106 SiSDoCMD
1108 #endif
1110 /* ----- CPU To Screen Color Expand (scanline-wise) ----------------- */
1112 /* We do it using the indirect method */
1114 static void
1115 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
1116 int fg, int bg, int rop, unsigned int planemask)
1118 SISPtr pSiS=SISPTR(pScrn);
1120 /* TW: Make sure that current CPU-driven BitBlt buffer stage is 0
1121 * This is required!!! (Otherwise -> drawing errors)
1123 while((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x1F00) != 0) {} /* WDR: == 0x10 */
1125 SiSSetupSRCXY(0,0);
1126 SiSSetupROP(SiSGetCopyROP(rop));
1127 SiSSetupSRCFG(fg);
1128 SiSSetupDSTRect(pSiS->scrnOffset, -1);
1129 SiSSetupDSTColorDepth(pSiS->DstColor);
1130 if(bg == -1) {
1131 SiSSetupCMDFlag(TRANSPARENT |
1132 ENCOLOREXP |
1133 X_INC | Y_INC |
1134 SRCCPUBLITBUF);
1135 } else {
1136 SiSSetupSRCBG(bg);
1137 SiSSetupCMDFlag(ENCOLOREXP |
1138 X_INC | Y_INC |
1139 SRCCPUBLITBUF);
1144 static void
1145 SiSSubsequentScanlineCPUToScreenColorExpandFill(
1146 ScrnInfoPtr pScrn, int x, int y, int w,
1147 int h, int skipleft)
1149 SISPtr pSiS = SISPTR(pScrn);
1150 int _x0, _y0, _x1, _y1;
1151 CARD32 dstbase;
1153 dstbase = 0;
1154 if((y >= 2048) || ((y + h) >= 2048)) {
1155 dstbase = pSiS->scrnOffset * y;
1156 y = 0;
1158 #ifdef SISDUALHEAD
1159 if(pSiS->VGAEngine != SIS_530_VGA) {
1160 dstbase += HEADOFFSET;
1162 #endif
1164 /* Wait until there is no color expansion command in queue
1165 * (This solves the OpenOffice.org window-move bug)
1166 * Added Idle-check - bit 23 is set sometimes, although
1167 * engine is actually idle!
1168 * Update: Bit 23 is not reliable. After heavy 3D engine
1169 * action, this bit never gets cleared again. So do
1170 * SiSIdle instead.
1172 if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) {
1173 /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */
1174 SiSIdle
1177 SiSSetupDSTBase(dstbase)
1179 if(skipleft > 0) {
1180 _x0 = x + skipleft;
1181 _y0 = y;
1182 _x1 = x + w;
1183 _y1 = y + h;
1184 SiSSetupClipLT(_x0, _y0);
1185 SiSSetupClipRB(_x1, _y1);
1186 SiSSetupCMDFlag(CLIPENABLE);
1187 } else {
1188 pSiS->CommandReg &= (~CLIPENABLE);
1191 SiSSetupRect(w, 1);
1192 SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
1193 pSiS->xcurrent = x;
1194 pSiS->ycurrent = y;
1197 static void
1198 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
1200 SISPtr pSiS=SISPTR(pScrn);
1201 #if 0
1202 int newhead,bltbufstage,newtail;
1203 #endif
1204 CARD32 cbo;
1206 cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
1207 #ifdef SISDUALHEAD
1208 if(pSiS->VGAEngine != SIS_530_VGA) {
1209 cbo += HEADOFFSET;
1211 #endif
1213 /* Wait until there is no color expansion command in queue
1214 * (This solves the GTK-big-font bug)
1215 * Added Idle-check - bit 23 is set sometimes, although
1216 * engine is actually idle!
1217 * Update: Bit 23 is not reliable. After heavy 3D engine
1218 * action, this bit never gets cleared again. So do
1219 * SiSIdle instead.
1221 if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) {
1222 /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */
1223 SiSIdle
1226 SiSSetupSRCBase(cbo);
1228 SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent);
1230 SiSDoCMD
1232 pSiS->ycurrent++;
1234 if(pSiS->VGAEngine == SIS_530_VGA) {
1235 while(MMIO_IN8(pSiS->IOBase, 0x8242) & 0x80) {}