1/*
2 * Copyright 1997-2003 by Alan Hourihane, North Wales, UK.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of Alan
9 * Hourihane not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission.  Alan Hourihane makes no representations about the
12 * suitability of this software for any purpose.  It is provided
13 * "as is" without express or implied warranty.
14 *
15 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY
18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
21 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22 * SOFTWARE.
23 *
24 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
25 *
26 * Trident Blade3D accelerated options.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "xf86.h"
34#include "xf86_OSproc.h"
35
36#include "xf86Pci.h"
37
38#include "miline.h"
39
40#include "trident.h"
41#include "trident_regs.h"
42
43#ifdef HAVE_XAA_H
44#include "xaarop.h"
45#include "xaalocal.h"
46
47static void BladeSync(ScrnInfoPtr pScrn);
48#if 0
49static void BladeSetupForSolidLine(ScrnInfoPtr pScrn,
50                                    int color,
51                                    int rop,
52                                    unsigned int planemask);
53static void BladeSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
54                                                int x, int y,
55                                                int dmaj, int dmin,
56                                                int e, int len,
57                                                int octant);
58static void BladeSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
59                                                int x1, int y1,
60                                                int x2, int y2,
61                                                int flags);
62static void BladeSetupForDashedLine(ScrnInfoPtr pScrn,
63                                    int fg, int bg,
64                                    int rop,
65                                    unsigned int planemask,
66                                    int length,
67                                    unsigned char *pattern);
68static void BladeSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
69                                                int x1, int y1,
70                                                int x2, int y2,
71                                                int flags, int phase);
72#endif
73static void BladeSetupForFillRectSolid(ScrnInfoPtr pScrn,
74                                        int color,
75                                        int rop,
76                                        unsigned int planemask);
77static void BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn,
78                                            int x, int y,
79                                            int w, int h);
80static void BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
81                                                int x1, int y1,
82                                                int x2, int y2,
83                                                int w, int h);
84static void BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
85                                            int xdir, int ydir,
86                                            int rop,
87                                            unsigned int planemask,
88                                            int transparency_color);
89#if 0
90static void BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
91                                            int fg, int bg,
92                                            int rop,
93                                            unsigned int planemask);
94static void BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
95                                                    int x, int y,
96                                                    int w, int h,
97                                                    int srcx, int srcy,
98                                                    int offset);
99#endif
100static void BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
101                                            int fg, int bg,
102                                            int rop,
103                                            unsigned int planemask);
104static void BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
105                                                    int x, int y,
106                                                    int w, int h,
107                                                    int skipleft);
108static void BladeSetClippingRectangle(ScrnInfoPtr pScrn,
109                                        int x1, int y1,
110                                        int x2, int y2);
111static void BladeDisableClipping(ScrnInfoPtr pScrn);
112static void BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
113                                            int patternx,
114                                            int patterny,
115                                            int fg, int bg,
116                                            int rop,
117                                            unsigned int planemask);
118static void BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
119                                                    int patternx,
120                                                    int patterny,
121                                                    int x, int y,
122                                                    int w, int h);
123#if 0
124static void BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
125                                                int patternx,
126                                                int patterny,
127                                                int rop,
128                                                unsigned int planemask,
129                                                int trans_col);
130static void BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
131                                                    int patternx,
132                                                    int patterny,
133                                                    int x, int y,
134                                                    int w, int h);
135#endif
136static void BladeSetupForImageWrite(ScrnInfoPtr pScrn,
137                                    int rop,
138                                    unsigned int planemask,
139                                    int transparency_color,
140                                    int bpp, int depth);
141static void BladeSubsequentImageWriteRect(ScrnInfoPtr pScrn,
142                                            int x, int y,
143                                            int w, int h,
144                                            int skipleft);
145
146static void
147BladeInitializeAccelerator(ScrnInfoPtr pScrn)
148{
149    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
150    CARD32 stride;
151
152    stride = (pScrn->displayWidth >> 3) << 20;
153
154    BLADE_OUT(0x21C8, stride);
155    BLADE_OUT(0x21CC, stride);
156    BLADE_OUT(0x21D0, stride);
157    BLADE_OUT(0x21D4, stride);
158    switch (pScrn->depth) {
159        case 8:
160        stride |= (0 << 29);
161        break;
162        case 15:
163        stride |= (5 << 29);
164        break;
165        case 16:
166        stride |= (1 << 29);
167        break;
168        case 24:
169        stride |= (2 << 29);
170        break;
171    }
172
173    BLADE_OUT(0x21B8, 0);
174    BLADE_OUT(0x21B8, stride);
175    BLADE_OUT(0x21BC, stride);
176    BLADE_OUT(0x21C0, stride);
177    BLADE_OUT(0x21C4, stride);
178#if 0
179    /* It appears that the driver sometimes misdetects the RAM type, so we
180     * don't force this for now */
181    if (pTrident->HasSGRAM)
182        BLADE_OUT(0x2168, 1 << 26); /* Enables Block Write if available (SGRAM) */
183    else
184        BLADE_OUT(0x2168, 0);
185#endif
186    BLADE_OUT(0x216C, 0);
187}
188#endif
189
190Bool BladeXaaInit(ScreenPtr pScreen) {
191#ifdef HAVE_XAA_H
192    XAAInfoRecPtr infoPtr;
193    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
194    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
195
196    if (pTrident->NoAccel)
197        return FALSE;
198
199    pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
200    if (!infoPtr) return FALSE;
201
202    pTrident->InitializeAccelerator = BladeInitializeAccelerator;
203    BladeInitializeAccelerator(pScrn);
204
205    infoPtr->Flags = PIXMAP_CACHE |
206                        LINEAR_FRAMEBUFFER |
207                        OFFSCREEN_PIXMAPS;
208
209    infoPtr->Sync = BladeSync;
210
211    infoPtr->SetClippingRectangle = BladeSetClippingRectangle;
212    infoPtr->DisableClipping = BladeDisableClipping;
213
214#if 0
215    infoPtr->SolidLineFlags = 0;
216    infoPtr->SetupForSolidLine = BladeSetupForSolidLine;
217    infoPtr->SubsequentSolidTwoPointLine =
218                                    BladeSubsequentSolidTwoPointLine;
219    infoPtr->SetupForDashedLine = BladeSetupForDashedLine;
220    infoPtr->SubsequentDashedTwoPointLine =
221                                    BladeSubsequentDashedTwoPointLine;
222    infoPtr->DashPatternMaxLength = 16;
223    infoPtr->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED |
224                                LINE_PATTERN_POWER_OF_2_ONLY;
225#endif
226
227    infoPtr->SolidFillFlags = NO_PLANEMASK;
228    infoPtr->SetupForSolidFill = BladeSetupForFillRectSolid;
229    infoPtr->SubsequentSolidFillRect = BladeSubsequentFillRectSolid;
230
231    infoPtr->ScreenToScreenCopyFlags = ONLY_TWO_BITBLT_DIRECTIONS |
232                                        NO_PLANEMASK |
233                                        NO_TRANSPARENCY;
234
235    infoPtr->SetupForScreenToScreenCopy =
236                                    BladeSetupForScreenToScreenCopy;
237    infoPtr->SubsequentScreenToScreenCopy =
238                                    BladeSubsequentScreenToScreenCopy;
239
240    infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
241                                    NO_TRANSPARENCY |
242                                    BIT_ORDER_IN_BYTE_MSBFIRST |
243                                    HARDWARE_PATTERN_SCREEN_ORIGIN |
244                                    HARDWARE_PATTERN_PROGRAMMED_BITS;
245
246    infoPtr->SetupForMono8x8PatternFill =
247                                    BladeSetupForMono8x8PatternFill;
248    infoPtr->SubsequentMono8x8PatternFillRect =
249                                BladeSubsequentMono8x8PatternFillRect;
250
251#if 0
252    infoPtr->Color8x8PatternFillFlags =
253                                    HARDWARE_PATTERN_SCREEN_ORIGIN |
254                                    BIT_ORDER_IN_BYTE_MSBFIRST;
255
256    infoPtr->SetupForColor8x8PatternFill =
257                                TridentSetupForColor8x8PatternFill;
258    infoPtr->SubsequentColor8x8PatternFillRect =
259                            TridentSubsequentColor8x8PatternFillRect;
260
261    infoPtr->ScreenToScreenColorExpandFillFlags = 0;
262
263    infoPtr->SetupForScreenToScreenColorExpandFill =
264                            BladeSetupForScreenToScreenColorExpand;
265    infoPtr->SubsequentScreenToScreenColorExpandFill =
266                            BladeSubsequentScreenToScreenColorExpand;
267#endif
268
269    infoPtr->CPUToScreenColorExpandFillFlags =
270                                        CPU_TRANSFER_PAD_DWORD |
271                                        LEFT_EDGE_CLIPPING |
272                                        SYNC_AFTER_COLOR_EXPAND |
273                                        NO_PLANEMASK |
274                                        BIT_ORDER_IN_BYTE_MSBFIRST |
275                                        SCANLINE_PAD_DWORD;
276    infoPtr->ColorExpandRange = 0x10000;
277    infoPtr->ColorExpandBase = pTrident->IOBase + 0x10000;
278    infoPtr->SetupForCPUToScreenColorExpandFill =
279                                BladeSetupForCPUToScreenColorExpand;
280    infoPtr->SubsequentCPUToScreenColorExpandFill =
281                                BladeSubsequentCPUToScreenColorExpand;
282
283    infoPtr->SetupForImageWrite = BladeSetupForImageWrite;
284    infoPtr->SubsequentImageWriteRect =
285                                        BladeSubsequentImageWriteRect;
286    infoPtr->ImageWriteFlags = NO_PLANEMASK |
287                                LEFT_EDGE_CLIPPING |
288                                CPU_TRANSFER_PAD_DWORD |
289                                SYNC_AFTER_IMAGE_WRITE;
290    infoPtr->ImageWriteBase = pTrident->IOBase + 0x10000;
291    infoPtr->ImageWriteRange = 0x10000;
292
293    return(XAAInit(pScreen, infoPtr));
294#else
295    return FALSE;
296#endif
297}
298
299#ifdef HAVE_XAA_H
300static void
301BladeSync(ScrnInfoPtr pScrn)
302{
303    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
304    int busy;
305    int cnt = 10000000;
306
307    if (pTrident->Clipping) BladeDisableClipping(pScrn);
308    BLADE_OUT(0x216C, 0);
309
310    BLADEBUSY(busy);
311    while (busy != 0) {
312        if (--cnt < 0) {
313            ErrorF("GE timeout\n");
314            BLADE_OUT(0x2124, 1 << 7);
315            BLADE_OUT(0x2124, 0);
316            break;
317        }
318
319        BLADEBUSY(busy);
320    }
321}
322
323static void
324BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
325                                int xdir, int ydir,
326                                int rop,
327                                unsigned int planemask,
328                                int transparency_color)
329{
330    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
331
332    pTrident->BltScanDirection = 0;
333    if ((xdir < 0) || (ydir < 0))
334        pTrident->BltScanDirection |= (1 << 1);
335
336#if 0
337    if (transparency_color != -1) {
338        BLADE_OUT(0x2168, transparency_color & 0xffffff);
339        pTrident->BltScanDirection |= (1 << 6);
340    }
341
342    REPLICATE(planemask);
343    if (planemask != (unsigned int)-1) {
344        BLADE_OUT(0x2184, ~planemask);
345        pTrident->BltScanDirection |= (1 << 5);
346    }
347
348#endif
349    BLADE_OUT(0x2148, XAAGetCopyROP(rop));
350}
351
352static void
353BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
354                                    int x1, int y1,
355                                    int x2, int y2,
356                                    int w, int h)
357{
358    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
359    int clip = 0;
360
361    if (pTrident->Clipping) clip = 1;
362
363    BLADE_OUT(0x2144, 0xE0000000 |
364                        (1 << 19) | (1 << 4) | (1 << 2) |
365                        pTrident->BltScanDirection | clip);
366
367    if (pTrident->BltScanDirection) {
368        BLADE_OUT(0x2100, ((y1 + h - 1) << 16) | (x1 + w - 1));
369        BLADE_OUT(0x2104, (y1 << 16) | x1);
370        BLADE_OUT(0x2108, ((y2 + h - 1) << 16) | (x2 + w - 1));
371        BLADE_OUT(0x210C, ((y2 & 0xfff) << 16) | (x2 & 0xfff));
372    } else {
373        BLADE_OUT(0x2100, (y1 << 16) | x1);
374        BLADE_OUT(0x2104, ((y1 + h - 1) << 16) | (x1 + w - 1));
375        BLADE_OUT(0x2108, (y2 << 16) | x2);
376        BLADE_OUT(0x210C, (((y2 + h - 1) & 0xfff) << 16) |
377                            ((x2 + w - 1) & 0xfff));
378    }
379}
380
381static void
382BladeSetClippingRectangle(ScrnInfoPtr pScrn,
383                            int x1, int y1,
384                            int x2, int y2)
385{
386    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
387
388    BLADE_OUT(0x2154, ((y1 & 0x0fff) << 16) | (x1 & 0x0fff));
389    BLADE_OUT(0x2158, ((y2 & 0x0fff) << 16) | (x2 & 0x0fff));
390    pTrident->Clipping = TRUE;
391}
392
393static void
394BladeDisableClipping(ScrnInfoPtr pScrn)
395{
396    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
397    pTrident->Clipping = FALSE;
398}
399
400#if 0
401static void
402BladeSetupForSolidLine(ScrnInfoPtr pScrn,
403                        int color,
404                        int rop,
405                        unsigned int planemask)
406{
407    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
408
409    REPLICATE(color);
410    BLADE_OUT(0x2160, color);
411    BLADE_OUT(0x2148, XAAGetCopyROP(rop));
412    pTrident->BltScanDirection = 0;
413    REPLICATE(planemask);
414    if (planemask != -1) {
415        BLADE_OUT(0x2184, ~planemask);
416        pTrident->BltScanDirection |= (1 << 5);
417    }
418}
419
420static void
421BladeSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
422                                    int x, int y,
423                                    int dmaj, int dmin,
424                                    int e, int len,
425                                    int octant)
426{
427    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
428    int tmp;
429    int D = 0, E = 0, ymajor = 0;
430
431    BLADE_OUT(0x2144, 0x20000000 |
432                        (3 << 19) | (1 << 4) | (2 << 2) |
433                        (pTrident->Clipping ? 1 : 0));
434
435    if (!(octant & YMAJOR)) {
436        if ((!(octant & XDECREASING)) && (!(octant & YDECREASING))) {
437            E = 1; D = 0;
438        }
439
440        if ((!(octant & XDECREASING)) && ( (octant & YDECREASING))) {
441            E = 1; D = 1;
442        }
443
444        if (( (octant & XDECREASING)) && (!(octant & YDECREASING))) {
445            E = 1; D = 2;
446        }
447
448        if (( (octant & XDECREASING)) && ( (octant & YDECREASING))) {
449            E = 1; D = 3;
450        }
451
452        ymajor = 0;
453    } else {
454        if ((!(octant & XDECREASING)) && (!(octant & YDECREASING))) {
455            E = 0; D = 0;
456        }
457
458        if ((!(octant & XDECREASING)) && ( (octant & YDECREASING))) {
459            E = 0; D = 2;
460        }
461
462        if (( (octant & XDECREASING)) && (!(octant & YDECREASING))) {
463            E = 0; D = 1;
464        }
465
466        if (( (octant & XDECREASING)) && ( (octant & YDECREASING))) {
467            E = 0; D = 3;
468        }
469
470        ymajor = 1 << 21;
471    }
472
473    if (E) {
474        tmp = x; x = y; y = tmp;
475    }
476
477    BLADE_OUT(0x2130, 0x00000001);
478    if (D & 0x02) {
479        BLADE_OUT(0x213C, 0x10000000 |
480                            (1 << 25) | (1 << 19) | (1 << 17) |
481                            ymajor | ((x + len - 1) << 4));
482    } else {
483        BLADE_OUT(0x213C, 0x10000000 |
484                            (1 << 25) | (1 << 19) | (1 << 17) |
485                            ymajor | ((y + len - 1) << 4));
486    }
487
488    BLADE_OUT(0x2140, (E << 30) |
489                        ((y & 0xfff) << 20) | ((x & 0xfff) << 4));
490    BLADE_OUT(0x2144, (D << 30) |
491                        (((dmaj - dmin) & 0xfff) << 16) |
492                        (-dmin & 0xfff));
493    BLADE_OUT(0x2148, ((-(dmin + e) & 0xfff) << 16));
494}
495
496static void
497BladeSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
498                                    int x1, int y1,
499                                    int x2, int y2,
500                                    int flags)
501{
502    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
503
504#if 0
505    if (flags & OMIT_LAST)
506        BladeSetClippingRectangle(pScrn, x1, y1, x2 - 1, y2 - 1);
507#endif
508
509    BLADE_OUT(0x2144, 0x20000000 |
510                        pTrident->BltScanDirection |
511                        (1 << 19) | (1 << 4) | (2 << 2));
512    BLADE_OUT(0x2130, 0x3);
513    BLADE_OUT(0x2108, (y1 << 16) | x1);
514    BLADE_OUT(0x210C, ((y2 & 0xfff) << 16) | (x2 & 0xfff));
515
516#if 0
517    if (flags & OMIT_LAST)
518    BladeDisableClipping(pScrn);
519#endif
520}
521
522static void
523BladeSetupForDashedLine(ScrnInfoPtr pScrn,
524                        int fg, int bg,
525                        int rop,
526                        unsigned int planemask,
527                        int length,
528                        unsigned char *pattern)
529{
530    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
531
532    pTrident->LinePattern = *((CARD16 *)pattern) & ((1 << length) - 1);
533    switch (length) {
534        case 2:
535        pTrident->LinePattern = pTrident->LinePattern |
536                                (pTrident->LinePattern << 2);
537        case 4:
538        pTrident->LinePattern = pTrident->LinePattern |
539                                (pTrident->LinePattern << 4);
540        case 8:
541        pTrident->LinePattern = pTrident->LinePattern |
542                                (pTrident->LinePattern << 8);
543    }
544
545    REPLICATE(fg);
546    REPLICATE(bg);
547    BLADE_OUT(0x2160, fg);
548    BLADE_OUT(0x2164, bg);
549    BLADE_OUT(0x2148, XAAGetCopyROP(rop));
550    pTrident->BltScanDirection = 0;
551    REPLICATE(planemask);
552    if (planemask != -1) {
553        BLADE_OUT(0x2184, ~planemask);
554        pTrident->BltScanDirection |= (1 << 5);
555    }
556}
557
558static void
559BladeSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
560                                    int x1, int y1,
561                                    int x2, int y2,
562                                    int flags, int phase)
563{
564    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
565
566    if (flags & OMIT_LAST)
567        BladeSetClippingRectangle(pScrn, x1, y1, x2 - 1, y2 - 1);
568
569    BLADE_OUT(0x216C, (pTrident->LinePattern >> phase) |
570                        (pTrident->LinePattern << (16 - phase)));
571    BLADE_OUT(0x2144, 0x20000000 |
572                        pTrident->BltScanDirection |
573                        (1 << 27) | (1 << 19) | (1 << 4) | (2 << 2));
574    BLADE_OUT(0x2108, (y1 << 16) | x1);
575    BLADE_OUT(0x210C, ((y2 & 0xfff) << 16) | (x2 & 0xfff));
576
577    if (flags & OMIT_LAST)
578        BladeDisableClipping(pScrn);
579}
580#endif
581
582static void
583BladeSetupForFillRectSolid(ScrnInfoPtr pScrn,
584                            int color,
585                            int rop,
586                            unsigned int planemask)
587{
588    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
589
590    REPLICATE(color);
591    BLADE_OUT(0x2160, color);
592    BLADE_OUT(0x2148, XAAGetCopyROP(rop));
593    pTrident->BltScanDirection = 0;
594#if 0
595    REPLICATE(planemask);
596    if (planemask != -1) {
597        BLADE_OUT(0x2184, ~planemask);
598        pTrident->BltScanDirection |= (1 << 5);
599    }
600#endif
601}
602
603static void
604BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn,
605                                int x, int y,
606                                int w, int h)
607{
608    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
609
610    BLADE_OUT(0x2144, 0x20000000 |
611                        pTrident->BltScanDirection |
612                        (1 << 19) | (1 << 4) | (2 << 2) |
613                        (pTrident->Clipping ? 1 : 0));
614    BLADE_OUT(0x2108, (y << 16) | x);
615    BLADE_OUT(0x210C, (((y + h - 1) & 0xfff) << 16) |
616                        ((x + w - 1) & 0xfff));
617}
618
619#if 0
620static void
621BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
622                                        int fg, int bg,
623                                        int rop,
624                                        unsigned int planemask)
625{
626    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
627
628    pTrident->ROP = rop;
629
630    REPLICATE(bg);
631    REPLICATE(fg);
632    IMAGE_OUT(0x44, fg);
633    IMAGE_OUT(0x48, bg);
634    IMAGE_OUT(0x20, 0x90000000 | XAAGetCopyROP(rop));
635    pTrident->BltScanDirection = 0;
636    REPLICATE(planemask);
637    if (planemask != -1) {
638        BLADE_OUT(0x2184, ~planemask);
639        pTrident->BltScanDirection |= (1 << 5);
640    }
641}
642
643static void
644BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
645                                            int x, int y,
646                                            int w, int h,
647                                            int srcx, int srcy,
648                                            int offset)
649{
650    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
651
652    IMAGE_OUT(0x00, (srcy << 16) | srcx);
653    IMAGE_OUT(0x04, ((srcy + h - 1) << 16) | (srcx + w - 1));
654    IMAGE_OUT(0x08, (y << 16) | x);
655    IMAGE_OUT(0x0C, ((y + h - 1) << 16) | (x + w - 1));
656
657    IMAGE_OUT(0x24, 0x80000000 |
658                    (3 << 22) | (1 << 7) |
659                    pTrident->BltScanDirection |
660                    (pTrident->ROP == GXcopy ? 0 : (1 << 10)) |
661                    (offset << 25));
662}
663#endif
664
665static void
666BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
667                                    int fg, int bg,
668                                    int rop,
669                                    unsigned int planemask)
670{
671    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
672
673    pTrident->BltScanDirection = 0;
674    BLADE_OUT(0x2148, XAAGetCopyROP(rop));
675    if (bg == -1) {
676        pTrident->BltScanDirection |= (2 << 19);
677        REPLICATE(fg);
678        BLADE_OUT(0x2160, fg);
679        BLADE_OUT(0x2164, ~fg);
680    } else {
681        pTrident->BltScanDirection |= (3 << 19);
682        REPLICATE(fg);
683        REPLICATE(bg);
684        BLADE_OUT(0x2160, fg);
685        BLADE_OUT(0x2164, bg);
686    }
687
688#if 0
689    REPLICATE(planemask);
690    if (planemask != -1) {
691        BLADE_OUT(0x2184, ~planemask);
692        pTrident->BltScanDirection |= (1 << 5);
693    }
694#endif
695}
696
697static void
698BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
699                                        int x, int y,
700                                        int w, int h,
701                                        int skipleft)
702{
703    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
704
705    if (skipleft)
706        BladeSetClippingRectangle(pScrn,
707                                    x + skipleft, y,
708                                    (x + w - 1), (y + h - 1));
709    BLADE_OUT(0x2144, 0xE0000000 |
710                        pTrident->BltScanDirection |
711                        (1 << 4) |
712                        (skipleft ? 1 : 0));
713    BLADE_OUT(0x2108, ((y & 0xfff) << 16) | (x & 0xfff));
714    BLADE_OUT(0x210C, (((y + h - 1) & 0xfff) << 16) |
715                        ((x + w - 1) & 0xfff));
716}
717
718static void
719BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
720                                int patternx, int patterny,
721                                int fg, int bg,
722                                int rop,
723                                unsigned int planemask)
724{
725    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
726
727    BladeSync(pScrn);
728    BLADE_OUT(0x2148, XAAGetPatternROP(rop));
729
730    if (bg == -1) {
731        REPLICATE(fg);
732        BLADE_OUT(0x216C, 0x80000000 | (1 << 30));
733        BLADE_OUT(0x216C, 0x80000000 | (1 << 28) | (1 << 30));
734        BLADE_OUT(0x2170, patternx);
735        BLADE_OUT(0x2170, patterny);
736        BLADE_OUT(0x2174, fg);
737#if 0
738        BLADE_OUT(0x2178, ~fg);
739#endif
740    } else {
741        REPLICATE(fg);
742        REPLICATE(bg);
743        BLADE_OUT(0x216C, 0x80000000);
744        BLADE_OUT(0x216C, 0x80000000 | (1 << 28));
745        BLADE_OUT(0x2170, patternx);
746        BLADE_OUT(0x2170, patterny);
747        BLADE_OUT(0x2174, fg);
748        BLADE_OUT(0x2178, bg);
749    }
750
751    pTrident->BltScanDirection = 0;
752#if 0
753    REPLICATE(planemask);
754    if (planemask != -1) {
755        BLADE_OUT(0x2184, ~planemask);
756        pTrident->BltScanDirection |= (1 << 5);
757    }
758#endif
759}
760
761static void
762BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
763                                        int patternx, int patterny,
764                                        int x, int y,
765                                        int w, int h)
766{
767    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
768    int clip = 0;
769
770    if (pTrident->Clipping) clip = 1;
771    BLADE_OUT(0x2144, 0x20000000 |
772                        pTrident->BltScanDirection |
773                        (7 << 12) | (1 << 4) |
774                        (1 << 19) | (2 << 2) | clip);
775    BLADE_OUT(0x2108, (y << 16) | x);
776    BLADE_OUT(0x210C, (((y + h - 1) & 0xfff) << 16) |
777                        ((x + w - 1) & 0xfff));
778}
779
780#if 0
781static void
782BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
783                                    int patternx, int patterny,
784                                    int rop,
785                                    unsigned int planemask,
786                                    int transparency_color)
787{
788    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
789
790    TGUI_PATLOC(((patterny *
791                        pScrn->displayWidth *
792                        (pScrn->bitsPerPixel / 8)) +
793                    (patternx *
794                        (pScrn->bitsPerPixel / 8))) >> 6);
795    pTrident->BltScanDirection = 0;
796    if (transparency_color != -1) {
797        BLADE_OUT(0x2168, transparency_color & 0xffffff);
798        pTrident->BltScanDirection |= (1 << 6);
799    }
800    TGUI_FMIX(XAAGetPatternROP(rop));
801    REPLICATE(planemask);
802    if (planemask != -1) {
803        BLADE_OUT(0x2184, ~planemask);
804        pTrident->BltScanDirection |= (1 << 5);
805    }
806}
807
808static void
809BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
810                                        int patternx, int patterny,
811                                        int x, int y,
812                                        int w, int h)
813{
814    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
815
816    TGUI_DEST_XY(x, y);
817    TGUI_DIM_XY(w, h);
818    TGUI_COMMAND(GE_BLT);
819    CHECKCLIPPING;
820}
821#endif
822
823static void
824BladeSetupForImageWrite(ScrnInfoPtr pScrn,
825                        int rop,
826                        unsigned int planemask,
827                        int transparency_color,
828                        int bpp, int depth)
829{
830    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
831
832    BLADE_OUT(0x2148, XAAGetCopyROP(rop));
833    pTrident->BltScanDirection = 0;
834#if 0
835    REPLICATE(planemask);
836    if (planemask != -1) {
837        BLADE_OUT(0x2184, ~planemask);
838        pTrident->BltScanDirection |= (1 << 5);
839    }
840#endif
841}
842
843static void
844BladeSubsequentImageWriteRect(ScrnInfoPtr pScrn,
845                                int x, int y,
846                                int w, int h,
847                                int skipleft)
848{
849    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
850
851    if (skipleft)
852        BladeSetClippingRectangle(pScrn,
853                                    x + skipleft, y,
854                                    (x + w - 1), (y + h - 1));
855    BLADE_OUT(0x2144, 0xE0000000 |
856                        (1 << 19) | (1 << 4) |
857                        pTrident->BltScanDirection |
858                        (skipleft ? 1 : 0));
859    BLADE_OUT(0x2108, (y << 16) | (x & 0xfff));
860    BLADE_OUT(0x210C, (((y + h - 1) & 0xfff) << 16) |
861                        ((x + w - 1) & 0xfff));
862}
863#endif
864