Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004
[xf86-video-sis/mirage.git] / src / sis300_accel.c
blobc566353776a7bcf69f612ec0509bf19f281dc749
1 /* $XFree86$ */
2 /*
3 * 2D Acceleration for SiS 530, 620, 300, 540, 630, 730.
5 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3) All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: "This product includes
17 * software developed by Thomas Winischhofer, Vienna, Austria."
18 * 4) The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Authors: Thomas Winischhofer <thomas@winischhofer.net>
33 * Can-Ru Yeou, SiS Inc.
37 #if 0
38 #define DEBUG
39 #endif
41 #include "xf86.h"
42 #include "xf86_OSproc.h"
43 #include "xf86_ansic.h"
44 #include "xf86PciInfo.h"
45 #include "xf86Pci.h"
46 #include "compiler.h"
47 #include "xaa.h"
48 #include "xaalocal.h"
49 #include "xaarop.h"
51 #include "sis.h"
52 #include "sis300_accel.h"
54 #ifdef SISDUALHEAD
55 /* TW: This is the offset to the memory for each head */
56 #define HEADOFFSET (pSiS->dhmOffset)
57 #endif
59 #undef STSCE /* TW: Use/Don't use ScreenToScreenColorExpand - does not work */
61 #undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides
62 * illegal trapezoid data (left and right edges cross each other
63 * sometimes) which causes drawing errors. Further, I have not found
64 * out how to draw polygones with a height greater than 127...
67 static void SiSInitializeAccelerator(ScrnInfoPtr pScrn);
68 static void SiSSync(ScrnInfoPtr pScrn);
69 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
70 int xdir, int ydir, int rop,
71 unsigned int planemask, int trans_color);
72 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
73 int x1, int y1, int x2, int y2,
74 int width, int height);
75 static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
76 int rop, unsigned int planemask);
77 static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
78 int x, int y, int w, int h);
79 #ifdef TRAP
80 static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
81 int left, int dxL, int dyL, int eL,
82 int right, int dxR, int dyR, int eR);
83 #endif
84 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color,
85 int rop, unsigned int planemask);
86 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1,
87 int y1, int x2, int y2, int flags);
88 static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
89 int x, int y, int len, int dir);
90 static void SiSSetupForDashedLine(ScrnInfoPtr pScrn,
91 int fg, int bg, int rop, unsigned int planemask,
92 int length, unsigned char *pattern);
93 static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
94 int x1, int y1, int x2, int y2,
95 int flags, int phase);
96 static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
97 int patx, int paty, int fg, int bg,
98 int rop, unsigned int planemask);
99 static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
100 int patx, int paty,
101 int x, int y, int w, int h);
102 #ifdef TRAP
103 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
104 int patx, int paty,
105 int y, int h,
106 int left, int dxL, int dyL, int eL,
107 int right, int dxR, int dyR, int eR );
108 #endif
109 #if 0
110 static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn,
111 int patx, int paty, int rop,
112 unsigned int planemask,
113 int trans_color);
114 static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn,
115 int patx, int paty,
116 int x, int y, int w, int h);
117 #endif
118 #if 0
119 static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
120 int fg, int bg,
121 int rop, unsigned int planemask);
122 static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
123 int x, int y, int w, int h, int skipleft);
124 #endif
125 #ifdef STSCE
126 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
127 int fg, int bg,
128 int rop, unsigned int planemask);
129 static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
130 int x, int y, int w, int h,
131 int srcx, int srcy, int skipleft);
132 #endif
133 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
134 int fg, int bg, int rop,
135 unsigned int planemask);
136 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
137 int x, int y, int w, int h,
138 int skipleft);
139 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
141 #ifdef SISDUALHEAD
142 static void SiSRestoreAccelState(ScrnInfoPtr pScrn);
143 #endif
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 /* TW: 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 /* TW: 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 HARDWARE_PATTERN_SCREEN_ORIGIN |
256 HARDWARE_PATTERN_PROGRAMMED_BITS ;
257 #endif
259 /* per-scanline color expansion (using indirect method) */
260 if(pSiS->VGAEngine == SIS_530_VGA) {
261 pSiS->ColorExpandBufferNumber = 4;
262 pSiS->ColorExpandBufferCountMask = 0x03;
263 } else {
264 pSiS->ColorExpandBufferNumber = 16;
265 pSiS->ColorExpandBufferCountMask = 0x0F;
267 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
268 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
269 infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
271 infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
272 SiSSetupForScanlineCPUToScreenColorExpandFill;
273 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
274 SiSSubsequentScanlineCPUToScreenColorExpandFill;
275 infoPtr->SubsequentColorExpandScanline =
276 SiSSubsequentColorExpandScanline;
277 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
278 CPU_TRANSFER_PAD_DWORD |
279 SCANLINE_PAD_DWORD |
280 BIT_ORDER_IN_BYTE_MSBFIRST |
281 LEFT_EDGE_CLIPPING;
282 } else {
283 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
284 "Virtual screen width too large for accelerator engine\n");
285 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
286 "2D acceleration and Xv disabled\n");
287 pSiS->NoXvideo = TRUE;
290 #ifdef SISDUALHEAD
291 if(pSiS->DualHeadMode) {
292 infoPtr->RestoreAccelState = SiSRestoreAccelState;
294 #endif
296 /* init Frame Buffer Manager */
297 topFB = pSiS->maxxfbmem;
299 reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
301 UsableFbSize = topFB - reservedFbSize;
303 /* Layout: (Sizes do not reflect correct proportions)
304 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
305 * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series
306 * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
307 * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620
308 * topFB
311 AvailBufBase = pSiS->FbBase + UsableFbSize;
312 for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
313 pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
314 i * pSiS->PerColorExpandBufferSize;
315 pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize +
316 i * pSiS->PerColorExpandBufferSize;
318 Avail.x1 = 0;
319 Avail.y1 = 0;
320 Avail.x2 = pScrn->displayWidth;
321 Avail.y2 = (UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1;
323 if(Avail.y2 < 0) Avail.y2 = 32767;
325 if(Avail.y2 < pScrn->currentMode->VDisplay) {
326 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
327 "Not enough video RAM for accelerator. At least "
328 "%dKB needed, %ldKB available\n",
329 ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */
330 * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
331 pSiS->maxxfbmem/1024);
332 pSiS->NoAccel = TRUE;
333 pSiS->NoXvideo = TRUE;
334 XAADestroyInfoRec(pSiS->AccelInfoPtr);
335 pSiS->AccelInfoPtr = NULL;
336 return FALSE;
339 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
340 "Frame Buffer From (%d,%d) To (%d,%d)\n",
341 Avail.x1, Avail.y1, Avail.x2, Avail.y2);
343 xf86InitFBManager(pScreen, &Avail);
345 return(XAAInit(pScreen, infoPtr));
349 static void
350 SiSSync(ScrnInfoPtr pScrn)
352 SISPtr pSiS = SISPTR(pScrn);
354 PDEBUG(ErrorF("SiSSync()\n"));
356 pSiS->DoColorExpand = FALSE;
357 SiSIdle
360 #ifdef SISDUALHEAD
361 static void
362 SiSRestoreAccelState(ScrnInfoPtr pScrn)
364 SISPtr pSiS = SISPTR(pScrn);
366 /* TW: We don't need to do anything special here; forcing the
367 * other head to re-read the CmdQueLen is not necessary:
368 * After the Sync in RestoreAccelState(), the real queue
369 * length is always larger than (or at least equal to)
370 * the amount stored in CmdQueueLen of the other head,
371 * so the only thing that might happen is one unnecessary
372 * Sync on the other head. I think we can live with that.
374 pSiS->DoColorExpand = FALSE;
375 SiSIdle
377 #endif
379 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
380 int xdir, int ydir, int rop,
381 unsigned int planemask, int trans_color)
383 SISPtr pSiS = SISPTR(pScrn);
385 PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
386 xdir, ydir, rop, planemask, trans_color));
388 SiSSetupDSTColorDepth(pSiS->DstColor);
389 SiSSetupSRCPitch(pSiS->scrnOffset)
390 SiSSetupDSTRect(pSiS->scrnOffset, -1)
392 if(trans_color != -1) {
393 SiSSetupROP(0x0A)
394 SiSSetupSRCTrans(trans_color)
395 SiSSetupCMDFlag(TRANSPARENT_BITBLT)
396 } else {
397 SiSSetupROP(XAACopyROP[rop])
399 if(xdir > 0) {
400 SiSSetupCMDFlag(X_INC)
402 if(ydir > 0) {
403 SiSSetupCMDFlag(Y_INC)
407 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
408 int src_x, int src_y, int dst_x, int dst_y,
409 int width, int height)
411 SISPtr pSiS = SISPTR(pScrn);
412 long srcbase, dstbase;
414 PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
415 src_x, src_y, dst_x, dst_y, width, height));
417 srcbase = dstbase = 0;
418 if(src_y >= 2048) {
419 srcbase = pSiS->scrnOffset * src_y;
420 src_y = 0;
422 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
423 dstbase = pSiS->scrnOffset * dst_y;
424 dst_y = 0;
426 #ifdef SISDUALHEAD
427 if(pSiS->VGAEngine != SIS_530_VGA) {
428 srcbase += HEADOFFSET;
429 dstbase += HEADOFFSET;
431 #endif
432 SiSSetupSRCBase(srcbase);
433 SiSSetupDSTBase(dstbase);
435 if(!(pSiS->CommandReg & X_INC)) {
436 src_x += width-1;
437 dst_x += width-1;
439 if(!(pSiS->CommandReg & Y_INC)) {
440 src_y += height-1;
441 dst_y += height-1;
443 SiSSetupRect(width, height)
444 SiSSetupSRCXY(src_x, src_y)
445 SiSSetupDSTXY(dst_x, dst_y)
447 SiSDoCMD
450 static void
451 SiSSetupForSolidFill(ScrnInfoPtr pScrn,
452 int color, int rop, unsigned int planemask)
454 SISPtr pSiS = SISPTR(pScrn);
456 PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
457 color, rop, planemask));
459 if(pSiS->disablecolorkeycurrent) {
460 if((CARD32)color == pSiS->colorKey) {
461 rop = 5; /* NOOP */
464 SiSSetupPATFG(color)
465 SiSSetupDSTRect(pSiS->scrnOffset, -1)
466 SiSSetupDSTColorDepth(pSiS->DstColor);
467 SiSSetupROP(XAAPatternROP[rop])
468 /* SiSSetupCMDFlag(PATFG) - is zero */
471 static void
472 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
473 int x, int y, int w, int h)
475 SISPtr pSiS = SISPTR(pScrn);
476 long dstbase;
478 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
479 x, y, w, h));
480 dstbase = 0;
482 if(y >= 2048) {
483 dstbase = pSiS->scrnOffset * y;
484 y = 0;
486 #ifdef SISDUALHEAD
487 if(pSiS->VGAEngine != SIS_530_VGA) {
488 dstbase += HEADOFFSET;
490 #endif
491 SiSSetupDSTBase(dstbase)
492 SiSSetupDSTXY(x,y)
493 SiSSetupRect(w,h)
494 /* Clear commandReg because Setup can be used for Rect and Trap */
495 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
496 T_L_X_INC | T_L_Y_INC |
497 T_R_X_INC | T_R_Y_INC |
498 TRAPAZOID_FILL);
499 SiSSetupCMDFlag(X_INC | Y_INC | BITBLT)
501 SiSDoCMD
504 /* TW: Trapezoid */
505 /* This would work better if XAA would provide us with valid trapezoids.
506 * In fact, with small trapezoids the left and the right edge often cross
507 * each other or result in a line length of 0 which causes drawing errors
508 * (filling over whole scanline).
509 * Furthermore, I have not found out how to draw trapezoids with a height
510 * greater than 127.
512 #ifdef TRAP
513 static void
514 SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
515 int left, int dxL, int dyL, int eL,
516 int right, int dxR, int dyR, int eR )
518 SISPtr pSiS = SISPTR(pScrn);
519 long dstbase;
520 #if 0
521 float kL, kR;
522 #endif
524 dstbase = 0;
525 if(y >= 2048) {
526 dstbase=pSiS->scrnOffset*y;
527 y = 0;
529 #ifdef SISDUALHEAD
530 if(pSiS->VGAEngine != SIS_530_VGA) {
531 dstbase += HEADOFFSET;
533 #endif
534 SiSSetupDSTBase(dstbase)
535 /* SiSSetupRect(w,h) */
537 #if 1
538 SiSSetupPATFG(0xff0000) /* FOR TESTING */
539 #endif
541 /* Clear CommandReg because SetUp can be used for Rect and Trap */
542 pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC |
543 T_R_X_INC | T_R_Y_INC |
544 T_XISMAJORL | T_XISMAJORR |
545 BITBLT);
547 xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
548 left, right, y, h, dxL, dyL, eL, dxR, dyR, eR);
550 /* Unfortunately, we must check if the right and the left edge
551 * cross each other... INCOMPLETE (line equation wrong)
553 #if 0
554 if (dxL == 0) kL = 0;
555 else kL = (float)dyL / (float)dxL;
556 if (dxR == 0) kR = 0;
557 else kR = (float)dyR / (float)dxR;
558 xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR);
559 if ( (kR != kL) &&
560 (!(kR == 0 && kL == 0)) &&
561 (!(kR < 0 && kL > 0)) ) {
562 xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y);
563 if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) {
564 xf86DrvMsg(0, X_INFO, "Cross detected!\n");
567 #endif
569 /* Determine egde angles */
570 if(dxL < 0) { dxL = -dxL; }
571 else { SiSSetupCMDFlag(T_L_X_INC) }
572 if(dxR < 0) { dxR = -dxR; }
573 else { SiSSetupCMDFlag(T_R_X_INC) }
575 /* (Y direction always positive - do this anyway) */
576 if(dyL < 0) { dyL = -dyL; }
577 else { SiSSetupCMDFlag(T_L_Y_INC) }
578 if(dyR < 0) { dyR = -dyR; }
579 else { SiSSetupCMDFlag(T_R_Y_INC) }
581 /* Determine major axis */
582 if(dxL >= dyL) { /* X is major axis */
583 SiSSetupCMDFlag(T_XISMAJORL)
585 if(dxR >= dyR) { /* X is major axis */
586 SiSSetupCMDFlag(T_XISMAJORR)
589 /* Set up deltas */
590 SiSSetupdL(dxL, dyL)
591 SiSSetupdR(dxR, dyR)
593 #if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */
594 h &= 0x7F;
595 if (h == 0) h = 10;
596 #endif
598 /* Set up y, h, left, right */
599 SiSSetupYH(y,h)
600 SiSSetupLR(left,right)
602 /* Set up initial error term */
603 SiSSetupEL(eL)
604 SiSSetupER(eR)
606 SiSSetupCMDFlag(TRAPAZOID_FILL);
608 SiSDoCMD
610 #endif
612 static void
613 SiSSetupForSolidLine(ScrnInfoPtr pScrn,
614 int color, int rop, unsigned int planemask)
616 SISPtr pSiS = SISPTR(pScrn);
618 PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
619 color, rop, planemask));
621 SiSSetupLineCount(1)
622 SiSSetupPATFG(color)
623 SiSSetupDSTRect(pSiS->scrnOffset, -1)
624 SiSSetupDSTColorDepth(pSiS->DstColor);
625 SiSSetupROP(XAAPatternROP[rop])
626 SiSSetupCMDFlag(PATFG | LINE)
629 static void
630 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
631 int x1, int y1, int x2, int y2, int flags)
633 SISPtr pSiS = SISPTR(pScrn);
634 long dstbase,miny,maxy;
636 PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
637 x1, y1, x2, y2, flags));
639 dstbase = 0;
640 miny = (y1 > y2) ? y2 : y1;
641 maxy = (y1 > y2) ? y1 : y2;
642 if(maxy >= 2048) {
643 dstbase = pSiS->scrnOffset * miny;
644 y1 -= miny;
645 y2 -= miny;
647 #ifdef SISDUALHEAD
648 if(pSiS->VGAEngine != SIS_530_VGA) {
649 dstbase += HEADOFFSET;
651 #endif
652 SiSSetupDSTBase(dstbase)
654 SiSSetupX0Y0(x1,y1)
655 SiSSetupX1Y1(x2,y2)
656 if(flags & OMIT_LAST) {
657 SiSSetupCMDFlag(NO_LAST_PIXEL)
658 } else {
659 pSiS->CommandReg &= ~(NO_LAST_PIXEL);
662 SiSDoCMD
665 static void
666 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
667 int x, int y, int len, int dir)
669 SISPtr pSiS = SISPTR(pScrn);
670 long dstbase;
672 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
673 x, y, len, dir));
674 len--; /* starting point is included! */
676 dstbase = 0;
677 if((y >= 2048) || ((dir != DEGREES_0) && ((y + len) >= 2048))) {
678 dstbase = pSiS->scrnOffset * y;
679 y = 0;
681 #ifdef SISDUALHEAD
682 if(pSiS->VGAEngine != SIS_530_VGA) {
683 dstbase += HEADOFFSET;
685 #endif
686 SiSSetupDSTBase(dstbase)
688 SiSSetupX0Y0(x,y)
689 if(dir == DEGREES_0) {
690 SiSSetupX1Y1(x + len, y);
691 } else {
692 SiSSetupX1Y1(x, y + len);
695 SiSDoCMD
698 static void
699 SiSSetupForDashedLine(ScrnInfoPtr pScrn,
700 int fg, int bg, int rop, unsigned int planemask,
701 int length, unsigned char *pattern)
703 SISPtr pSiS = SISPTR(pScrn);
705 PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
706 fg, bg, rop, planemask, length, *(pattern+4), *pattern));
708 SiSSetupLineCount(1)
709 SiSSetupDSTRect(pSiS->scrnOffset, -1)
710 SiSSetupDSTColorDepth(pSiS->DstColor);
711 SiSSetupStyleLow(*pattern)
712 SiSSetupStyleHigh(*(pattern+4))
713 SiSSetupStylePeriod(length-1);
714 SiSSetupROP(XAAPatternROP[rop])
715 SiSSetupPATFG(fg)
716 SiSSetupCMDFlag(LINE | LINE_STYLE)
717 if(bg != -1) {
718 SiSSetupPATBG(bg)
719 } else {
720 SiSSetupCMDFlag(TRANSPARENT);
724 static void
725 SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
726 int x1, int y1, int x2, int y2,
727 int flags, int phase)
729 SISPtr pSiS = SISPTR(pScrn);
730 long dstbase,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(XAAPatternROP[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 long 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 long 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 /* TW: 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(XAAPatternROP[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 long 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 /* TW: 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(XAACopyROP[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 /* TW. 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 long 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(XAACopyROP[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 long 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 /* TW: 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 long cbo;
1206 cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
1207 #ifdef SISDUALHEAD
1208 if(pSiS->VGAEngine != SIS_530_VGA) {
1209 cbo += HEADOFFSET;
1211 #endif
1213 /* TW: 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) {}