17706df26Smrg/* 27706df26Smrg * Copyright 1996,1997 by Alan Hourihane, Wigan, England. 37706df26Smrg * 47706df26Smrg * Permission to use, copy, modify, distribute, and sell this software and its 57706df26Smrg * documentation for any purpose is hereby granted without fee, provided that 67706df26Smrg * the above copyright notice appear in all copies and that both that 77706df26Smrg * copyright notice and this permission notice appear in supporting 87706df26Smrg * documentation, and that the name of Alan Hourihane not be used in 97706df26Smrg * advertising or publicity pertaining to distribution of the software without 107706df26Smrg * specific, written prior permission. Alan Hourihane makes no representations 117706df26Smrg * about the suitability of this software for any purpose. It is provided 127706df26Smrg * "as is" without express or implied warranty. 137706df26Smrg * 147706df26Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 157706df26Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 167706df26Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 177706df26Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 187706df26Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 197706df26Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 207706df26Smrg * PERFORMANCE OF THIS SOFTWARE. 217706df26Smrg * 227706df26Smrg * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 237706df26Smrg * 247706df26Smrg * DEC TGA accelerated options. 257706df26Smrg */ 267706df26Smrg 277706df26Smrg#ifdef HAVE_CONFIG_H 287706df26Smrg#include "config.h" 297706df26Smrg#endif 307706df26Smrg 317706df26Smrg#include "fb.h" 327706df26Smrg#include "micmap.h" 337706df26Smrg#include "xf86.h" 347706df26Smrg#include "xf86_OSproc.h" 357706df26Smrg#include "xf86PciInfo.h" 367706df26Smrg#include "xf86Pci.h" 377706df26Smrg#include "xf86cmap.h" 387706df26Smrg#include "mipointer.h" 397706df26Smrg 407706df26Smrg#include "miline.h" 417706df26Smrg 427706df26Smrg#include "tga_regs.h" 437706df26Smrg#include "BT.h" 447706df26Smrg#include "tga.h" 457706df26Smrg 46b92e825aSmrg#ifdef HAVE_XAA_H 477706df26Smrg/* defines */ 487706df26Smrg 497706df26Smrg#define BLIT_FORWARDS 0 507706df26Smrg#define BLIT_BACKWARDS 1 517706df26Smrg#define USE_BLOCK_FILL 2 527706df26Smrg#define USE_OPAQUE_FILL 3 537706df26Smrg#define MIX_SRC 0x03 547706df26Smrg 557706df26Smrg#define CE_BUFSIZE 256 567706df26Smrg 577706df26Smrg#define FB_OFFSET(x, y) (((long)(y) * pScrn->displayWidth * (pTga->Bpp)) + (long)(x) * pTga->Bpp) 587706df26Smrg 597706df26Smrg/* prototypes */ 607706df26Smrg 617706df26Smrgstatic void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 627706df26Smrg int y2, int w); 637706df26Smrgstatic void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 647706df26Smrg int y2, int w); 657706df26Smrgextern void TGASync(ScrnInfoPtr pScrn); 667706df26Smrgstatic void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 677706df26Smrg unsigned int planemask); 687706df26Smrgstatic void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); 697706df26Smrgstatic void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 707706df26Smrg int rop, unsigned int planemask, 717706df26Smrg int transparency_color); 727706df26Smrgstatic void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 737706df26Smrg int x2, int y2, int w, int h); 747706df26Smrgstatic void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 757706df26Smrg int fg, int bg, int rop, 767706df26Smrg unsigned int planemask); 777706df26Smrgstatic void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, 787706df26Smrg int paty, int x, int y, int w, 797706df26Smrg int h); 807706df26Smrgstatic void TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 817706df26Smrg int fg, int bg, 827706df26Smrg int rop, 837706df26Smrg unsigned int planemask); 847706df26Smrg 857706df26Smrgstatic void 867706df26SmrgTGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 877706df26Smrg int x, int y, int w, 887706df26Smrg int h, int skipleft); 897706df26Smrgstatic void 907706df26SmrgTGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); 917706df26Smrg 92b92e825aSmrg#endif 937706df26Smrg/* 947706df26Smrg * The following function sets up the supported acceleration. Call it 957706df26Smrg * from the FbInit() function in the SVGA driver. 967706df26Smrg */ 977706df26SmrgBool 987706df26SmrgDEC21030AccelInit(ScreenPtr pScreen) 997706df26Smrg{ 100b92e825aSmrg#ifdef HAVE_XAA_H 1017706df26Smrg XAAInfoRecPtr TGA_AccelInfoRec; 1027706df26Smrg BoxRec AvailFBArea; 1037706df26Smrg ScrnInfoPtr pScrn; 1047706df26Smrg TGAPtr pTga; 1057706df26Smrg 106b92e825aSmrg pScrn = xf86ScreenToScrn(pScreen); 1077706df26Smrg pTga = TGAPTR(pScrn); 1087706df26Smrg 1097706df26Smrg /* ErrorF("DEC21030AccelInit called!"); */ 1107706df26Smrg 1117706df26Smrg /* first, create the XAAInfoRec */ 1127706df26Smrg TGA_AccelInfoRec = XAACreateInfoRec(); 1137706df26Smrg 1147706df26Smrg /* ErrorF("XAACreateInfoRec called"); */ 1157706df26Smrg 1167706df26Smrg if(pScrn->depth == 8) { 1177706df26Smrg pTga->depthflag = BPP8PACKED; 1187706df26Smrg pTga->Bpp = 1; 1197706df26Smrg } else { 1207706df26Smrg pTga->depthflag = BPP24; 1217706df26Smrg pTga->Bpp = 4; 1227706df26Smrg } 1237706df26Smrg 1247706df26Smrg TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | 1257706df26Smrg OFFSCREEN_PIXMAPS; 1267706df26Smrg 1277706df26Smrg TGA_AccelInfoRec->Sync = TGASync; 1287706df26Smrg 1297706df26Smrg /* solid fill */ 1307706df26Smrg 1317706df26Smrg TGA_AccelInfoRec->SolidFillFlags = 0; 1327706df26Smrg TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill; 1337706df26Smrg TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect; 1347706df26Smrg 1357706df26Smrg /* screen to screen copy */ 1367706df26Smrg TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 1377706df26Smrg TGA_AccelInfoRec->SetupForScreenToScreenCopy = 1387706df26Smrg TGASetupForScreenToScreenCopy; 1397706df26Smrg TGA_AccelInfoRec->SubsequentScreenToScreenCopy = 1407706df26Smrg TGASubsequentScreenToScreenCopy; 1417706df26Smrg 1427706df26Smrg /* mono 8x8 pattern fill */ 1437706df26Smrg 1447706df26Smrg TGA_AccelInfoRec->Mono8x8PatternFillFlags = 1457706df26Smrg HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_LSBFIRST; 1467706df26Smrg TGA_AccelInfoRec->SetupForMono8x8PatternFill = 1477706df26Smrg TGASetupForMono8x8PatternFill; 1487706df26Smrg TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect = 1497706df26Smrg TGASubsequentMono8x8PatternFillRect; 1507706df26Smrg 1517706df26Smrg /* color expand */ 1527706df26Smrg /* does not work for 32bpp (yet) */ 1537706df26Smrg TGA_AccelInfoRec->ScanlineCPUToScreenColorExpandFillFlags = 1547706df26Smrg BIT_ORDER_IN_BYTE_LSBFIRST; 1557706df26Smrg 1567706df26Smrg TGA_AccelInfoRec->NumScanlineColorExpandBuffers = 1; 1577706df26Smrg pTga->buffers[0] = (CARD32 *)xnfalloc(CE_BUFSIZE); 1587706df26Smrg TGA_AccelInfoRec->ScanlineColorExpandBuffers = 1597706df26Smrg (unsigned char **)pTga->buffers; 1607706df26Smrg TGA_AccelInfoRec->SetupForScanlineCPUToScreenColorExpandFill = 1617706df26Smrg TGASetupForScanlineCPUToScreenColorExpandFill; 1627706df26Smrg TGA_AccelInfoRec->SubsequentScanlineCPUToScreenColorExpandFill = 1637706df26Smrg TGASubsequentScanlineCPUToScreenColorExpandFill; 1647706df26Smrg TGA_AccelInfoRec->SubsequentColorExpandScanline = 1657706df26Smrg TGASubsequentColorExpandScanline; 1667706df26Smrg 1677706df26Smrg /* lines */ 1687706df26Smrg 1697706df26Smrg TGA_AccelInfoRec->PolylinesThinSolid = TGAPolyLines; 1707706df26Smrg if(pTga->NoXaaPolySegment == FALSE) 1717706df26Smrg TGA_AccelInfoRec->PolySegmentThinSolid = TGAPolySegment; 1727706df26Smrg TGA_AccelInfoRec->PolylinesThinSolidFlags = 0x0; 1737706df26Smrg TGA_AccelInfoRec->PolySegmentThinSolidFlags = 0x0; 1747706df26Smrg 1757706df26Smrg TGA_AccelInfoRec->PolylinesThinDashed = TGAPolyLinesDashed; 1767706df26Smrg if(pTga->NoXaaPolySegment == FALSE) 1777706df26Smrg TGA_AccelInfoRec->PolySegmentThinDashed = TGAPolySegmentDashed; 1787706df26Smrg TGA_AccelInfoRec->PolylinesThinDashedFlags = 0x0; 1797706df26Smrg TGA_AccelInfoRec->PolySegmentThinDashedFlags = 0x0; 1807706df26Smrg TGA_AccelInfoRec->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED; 1817706df26Smrg TGA_AccelInfoRec->DashPatternMaxLength = 16; 1827706df26Smrg 1837706df26Smrg /* initialize the pixmap cache */ 1847706df26Smrg 1857706df26Smrg AvailFBArea.x1 = 0; 1867706df26Smrg AvailFBArea.y1 = 0; /* these gotta be 0 */ 1877706df26Smrg AvailFBArea.x2 = pScrn->displayWidth; 1887706df26Smrg AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth * 1897706df26Smrg pTga->Bpp); 1907706df26Smrg xf86InitFBManager(pScreen, &AvailFBArea); 1917706df26Smrg 1927706df26Smrg TGA_AccelInfoRec->PixmapCacheFlags = 0; 1937706df26Smrg 1947706df26Smrg /* initialize XAA */ 1957706df26Smrg return(XAAInit(pScreen, TGA_AccelInfoRec)); 196b92e825aSmrg#else 197b92e825aSmrg return FALSE; 198b92e825aSmrg#endif 1997706df26Smrg} 2007706df26Smrg 201b92e825aSmrg#ifdef HAVE_XAA_H 2027706df26Smrgstatic void 2037706df26SmrgTGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 2047706df26Smrg int fg, int bg, int rop, 2057706df26Smrg unsigned int planemask) 2067706df26Smrg{ 2077706df26Smrg#ifdef PROFILE 2087706df26Smrg unsigned int start, stop; 2097706df26Smrg#endif 2107706df26Smrg TGAPtr pTga = NULL; 2117706df26Smrg unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; 2127706df26Smrg TGA_DECL(); 2137706df26Smrg 2147706df26Smrg pTga = TGAPTR(pScrn); 2157706df26Smrg TGA_GET_IOBASE(); 2167706df26Smrg TGA_GET_OFFSET(); 2177706df26Smrg 2187706df26Smrg/* ErrorF("TGASetupForScanlineCPUToScreenColorExpandFill called\n"); */ 2197706df26Smrg if(pTga->depthflag == BPP8PACKED) { 2207706df26Smrg fgcolor = (fg | (fg << 8) | (fg << 16) | (fg << 24)); 2217706df26Smrg bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); 2227706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) 2237706df26Smrg | (planemask << 24); 2247706df26Smrg } 2257706df26Smrg else { 2267706df26Smrg bgcolor = bg; 2277706df26Smrg fgcolor = fg; 2287706df26Smrg pmask = planemask; 2297706df26Smrg } 2307706df26Smrg pTga->current_rop = rop | pTga->depthflag; 2317706df26Smrg 2327706df26Smrg if(bg == -1) { 2337706df26Smrg pTga->transparent_pattern_p = 1; 2347706df26Smrg if(rop == MIX_SRC) { 2357706df26Smrg pTga->block_or_opaque_p = USE_BLOCK_FILL; 2367706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 2377706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 2387706df26Smrg if(pTga->depthflag == BPP24) { 2397706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 2407706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 2417706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 2427706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 2437706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 2447706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 2457706df26Smrg } 2467706df26Smrg } 2477706df26Smrg else { 2487706df26Smrg pTga->block_or_opaque_p = USE_OPAQUE_FILL; 2497706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 2507706df26Smrg } 2517706df26Smrg } 2527706df26Smrg else { 2537706df26Smrg pTga->transparent_pattern_p = 0; 2547706df26Smrg TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); 2557706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 2567706df26Smrg } 2577706df26Smrg TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); /* we know when to 2587706df26Smrg reset this */ 2597706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 2607706df26Smrg 2617706df26Smrg TGA_SAVE_OFFSET(); 2627706df26Smrg 2637706df26Smrg return; 2647706df26Smrg} 2657706df26Smrg 2667706df26Smrgstatic void 2677706df26SmrgTGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 2687706df26Smrg int x, int y, int w, 2697706df26Smrg int h, int skipleft) 2707706df26Smrg{ 2717706df26Smrg#ifdef PROFILE 2727706df26Smrg unsigned int start, stop; 2737706df26Smrg#endif 2747706df26Smrg TGAPtr pTga; 2757706df26Smrg TGA_DECL(); 2767706df26Smrg 2777706df26Smrg pTga = TGAPTR(pScrn); 2787706df26Smrg TGA_GET_IOBASE(); 2797706df26Smrg TGA_GET_OFFSET(); 2807706df26Smrg 2817706df26Smrg/* ErrorF("TGASubsequentScanlineCPUToScreenColorExpandFill called\n"); */ 2827706df26Smrg/* ErrorF("w = %d, h = %d\n", w, h); */ 2837706df26Smrg 2847706df26Smrg pTga->ce_height = h; 2857706df26Smrg pTga->ce_width = w; 2867706df26Smrg pTga->ce_x = x; 2877706df26Smrg pTga->ce_y = y; 2887706df26Smrg pTga->ce_skipleft = skipleft; 2897706df26Smrg/* ErrorF("skipleft is %d\n", skipleft); */ 2907706df26Smrg 2917706df26Smrg if(pTga->transparent_pattern_p) { 2927706df26Smrg if(pTga->block_or_opaque_p == USE_BLOCK_FILL) 2937706df26Smrg TGA_FAST_WRITE_REG(BLOCKSTIPPLE | X11 | pTga->depthflag, 2947706df26Smrg TGA_MODE_REG); 2957706df26Smrg else 2967706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTSTIPPLE | X11 | pTga->depthflag, 2977706df26Smrg TGA_MODE_REG); 2987706df26Smrg/* ErrorF("transparent stipple with x = %d, y = %d, w = %d, h = %d\n", */ 2997706df26Smrg/* x, y, w, h); */ 3007706df26Smrg } 3017706df26Smrg else 3027706df26Smrg TGA_FAST_WRITE_REG(OPAQUESTIPPLE | X11 | pTga->depthflag, 3037706df26Smrg TGA_MODE_REG); 3047706df26Smrg 3057706df26Smrg TGA_SAVE_OFFSET(); 3067706df26Smrg return; 3077706df26Smrg} 3087706df26Smrg 3097706df26Smrgstatic void 3107706df26SmrgTGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 3117706df26Smrg{ 3127706df26Smrg#ifdef PROFILE 3137706df26Smrg unsigned int start, stop; 3147706df26Smrg#endif 3157706df26Smrg TGAPtr pTga; 3167706df26Smrg unsigned char *p = NULL; 3177706df26Smrg int width = 0; 3187706df26Smrg unsigned int addr; 3197706df26Smrg unsigned int pixelmask = 0; 3207706df26Smrg unsigned int stipple; 3217706df26Smrg unsigned int align_mask; 3227706df26Smrg int align = 0; 3237706df26Smrg int skipleft; 3247706df26Smrg 3257706df26Smrg CARD32 c = 0, d = 0; 3267706df26Smrg CARD32 *e = NULL; 3277706df26Smrg int i = 0, num_dwords = 0; 3287706df26Smrg TGA_DECL(); 3297706df26Smrg 3307706df26Smrg pTga = TGAPTR(pScrn); 3317706df26Smrg TGA_GET_IOBASE(); 3327706df26Smrg TGA_GET_OFFSET(); 3337706df26Smrg 3347706df26Smrg align_mask = (pTga->depthflag == BPP24) ? 0x0f : 0x03; 3357706df26Smrg 3367706df26Smrg#if 0 3377706df26Smrg ErrorF("TGASubsequentColorExpandScanline called\n"); 3387706df26Smrg if(pTga->transparent_pattern_p) 3397706df26Smrg ErrorF("transparent color expand\n"); 3407706df26Smrg#endif 3417706df26Smrg 3427706df26Smrg p = (unsigned char *)pTga->buffers[0]; 3437706df26Smrg addr = FB_OFFSET(pTga->ce_x, pTga->ce_y); 3447706df26Smrg width = pTga->ce_width; 3457706df26Smrg skipleft = pTga->ce_skipleft; 3467706df26Smrg 3477706df26Smrg while(width > 0) { 3487706df26Smrg if(!pTga->transparent_pattern_p) 3497706df26Smrg pixelmask = 0xFFFFFFFF; 3507706df26Smrg 3517706df26Smrg align = (addr & align_mask) / pTga->Bpp; /* no. pixels out of align */ 3527706df26Smrg if (align) { 3537706df26Smrg if (!pTga->transparent_pattern_p) 3547706df26Smrg pixelmask <<= align; 3557706df26Smrg/* ErrorF("alignment is %d\n", align); */ 3567706df26Smrg addr -= align * pTga->Bpp; 3577706df26Smrg width += align; 3587706df26Smrg 3597706df26Smrg e = (CARD32 *)p; 3607706df26Smrg num_dwords = (width / 32) + 1; 3617706df26Smrg if(num_dwords > (CE_BUFSIZE / 4)) { /* shouldn't happen */ 3627706df26Smrg ErrorF("TGASubsequentColorExpandScanline passed scanline %d bytes long, truncating\n", num_dwords * 4); 3637706df26Smrg num_dwords = CE_BUFSIZE / 4; 3647706df26Smrg } 3657706df26Smrg for(i = 0; i < num_dwords; i++) { 3667706df26Smrg c = e[i]; 3677706df26Smrg if(i == 0) 3687706df26Smrg e[i] = c << align; 3697706df26Smrg else 3707706df26Smrg e[i] = (d >> (32 - align)) | (c << align); 3717706df26Smrg d = c; 3727706df26Smrg } 3737706df26Smrg } 3747706df26Smrg 3757706df26Smrg if (!pTga->transparent_pattern_p) { 3767706df26Smrg if (skipleft) { 3777706df26Smrg pixelmask <<= skipleft; 3787706df26Smrg skipleft = 0; 3797706df26Smrg } 3807706df26Smrg if (width < 32) { 3817706df26Smrg pixelmask &= (0xFFFFFFFF >> (32 - width)); 3827706df26Smrg } 3837706df26Smrg TGA_FAST_WRITE_REG(pixelmask, TGA_PIXELMASK_REG); 3847706df26Smrg } 3857706df26Smrg else { 3867706df26Smrg unsigned int *i = NULL; 3877706df26Smrg 3887706df26Smrg/* ErrorF("transparent scanline with x = %d, y = %d, w = %d, h = %d\n", pTga->ce_x, pTga->ce_y, pTga->ce_width, pTga->ce_height); */ 3897706df26Smrg if (skipleft) { 3907706df26Smrg i = (unsigned int *)p; 3917706df26Smrg *i &= (0xFFFFFFFF << skipleft); 3927706df26Smrg skipleft = 0; 3937706df26Smrg } 3947706df26Smrg if (width < 32) { 3957706df26Smrg i = (unsigned int *)p; 3967706df26Smrg *i &= (0xFFFFFFFF >> (32 - width)); 3977706df26Smrg } 3987706df26Smrg } 3997706df26Smrg 4007706df26Smrg stipple = *((unsigned int *)p); 4017706df26Smrg switch (pTga->Chipset) { 4027706df26Smrg case PCI_CHIP_TGA2: 4037706df26Smrg *(unsigned int *)(pTga->FbBase + addr) = stipple; WMB; 4047706df26Smrg break; 4057706df26Smrg case PCI_CHIP_DEC21030: 4067706df26Smrg TGA_FAST_WRITE_REG(addr, TGA_ADDRESS_REG); 4077706df26Smrg TGA_FAST_WRITE_REG(stipple, TGA_CONTINUE_REG); 4087706df26Smrg } 4097706df26Smrg addr += 32 * pTga->Bpp; 4107706df26Smrg p += 4; 4117706df26Smrg width -= 32; 4127706df26Smrg } 4137706df26Smrg pTga->ce_height--; 4147706df26Smrg if(pTga->ce_height == 0) { 4157706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, 4167706df26Smrg TGA_MODE_REG); 4177706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 4187706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 4197706df26Smrg } 4207706df26Smrg else 4217706df26Smrg pTga->ce_y += 1; 4227706df26Smrg 4237706df26Smrg TGA_SAVE_OFFSET(); 4247706df26Smrg return; 4257706df26Smrg} 4267706df26Smrg 4277706df26Smrg/* Block Fill mode is faster, but only works for certain rops. So we will 4287706df26Smrg have to implement Opaque Fill anyway, so we will do that first, then 4297706df26Smrg do Block Fill for the special cases 4307706df26Smrg*/ 4317706df26Smrgvoid 4327706df26SmrgTGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 4337706df26Smrg unsigned int planemask) 4347706df26Smrg{ 4357706df26Smrg#ifdef PROFILE 4367706df26Smrg unsigned int start, stop; 4377706df26Smrg#endif 4387706df26Smrg TGAPtr pTga; 4397706df26Smrg unsigned int fgcolor = 0, pmask = 0; 4407706df26Smrg TGA_DECL(); 4417706df26Smrg 4427706df26Smrg pTga = TGAPTR(pScrn); 4437706df26Smrg TGA_GET_IOBASE(); 4447706df26Smrg TGA_GET_OFFSET(); 4457706df26Smrg /* ErrorF("TGASetupForSolidFill called"); */ 4467706df26Smrg 4477706df26Smrg if(pTga->depthflag == BPP8PACKED) { 4487706df26Smrg fgcolor = color | (color << 8) | (color << 16) | (color << 24); 4497706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 4507706df26Smrg (planemask << 24); 4517706df26Smrg } 4527706df26Smrg else { 4537706df26Smrg fgcolor = color; 4547706df26Smrg pmask = planemask; 4557706df26Smrg } 4567706df26Smrg 4577706df26Smrg 4587706df26Smrg if(rop == MIX_SRC) { /* we can just do a block copy */ 4597706df26Smrg pTga->block_or_opaque_p = USE_BLOCK_FILL; 4607706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 4617706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 4627706df26Smrg if(pTga->depthflag == BPP24) { 4637706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 4647706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 4657706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 4667706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 4677706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 4687706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 4697706df26Smrg } 4707706df26Smrg } 4717706df26Smrg else { 4727706df26Smrg pTga->block_or_opaque_p = USE_OPAQUE_FILL; 4737706df26Smrg pTga->current_rop = rop | pTga->depthflag; 4747706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 4757706df26Smrg/* ErrorF("opaque fill called\n"); */ 4767706df26Smrg } 4777706df26Smrg 4787706df26Smrg pTga->current_planemask = pmask; 4797706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_DATA_REG); 4807706df26Smrg TGA_SAVE_OFFSET(); 4817706df26Smrg return; 4827706df26Smrg} 4837706df26Smrg 4847706df26Smrgvoid 4857706df26SmrgTGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 4867706df26Smrg{ 4877706df26Smrg unsigned int mode_reg = 0; 4887706df26Smrg int i = 0; 4897706df26Smrg unsigned int pixel_count = 0; /* the actual # of pixels to be written */ 4907706df26Smrg unsigned int write_data = 0; /* the actual data written */ 4917706df26Smrg int a1 = 0; 4927706df26Smrg#ifdef PROFILE 4937706df26Smrg unsigned int stop, start; 4947706df26Smrg#endif 4957706df26Smrg TGAPtr pTga; 4967706df26Smrg TGA_DECL(); 4977706df26Smrg 4987706df26Smrg pTga = TGAPTR(pScrn); 4997706df26Smrg TGA_GET_IOBASE(); 5007706df26Smrg TGA_GET_OFFSET(); 5017706df26Smrg 5027706df26Smrg /* ErrorF("TGASubsequentFillRectSolid called\n"); */ 5037706df26Smrg 5047706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) { 5057706df26Smrg mode_reg = OPAQUEFILL | X11 | pTga->depthflag; 5067706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 5077706df26Smrg /* we have to set this to GXCOPY every time before we exit */ 5087706df26Smrg } 5097706df26Smrg else 5107706df26Smrg mode_reg = BLOCKFILL | X11 | pTga->depthflag; 5117706df26Smrg 5127706df26Smrg TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); 5137706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 5147706df26Smrg 5157706df26Smrg if(w > 2048) { 5167706df26Smrg ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n", w); 5177706df26Smrg w = 2048; 5187706df26Smrg } 5197706df26Smrg pixel_count = w - 1; 5207706df26Smrg 5217706df26Smrg for(i = 0; i < h; i++) { 5227706df26Smrg a1 = FB_OFFSET(x, y + i); 5237706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 5247706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); 5257706df26Smrg write_data = pixel_count; 5267706df26Smrg TGA_FAST_WRITE_REG(a1, TGA_ADDRESS_REG); 5277706df26Smrg TGA_FAST_WRITE_REG(write_data, TGA_CONTINUE_REG); 5287706df26Smrg } 5297706df26Smrg 5307706df26Smrg mode_reg = SIMPLE | X11 | pTga->depthflag; 5317706df26Smrg TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); 5327706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 5337706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, 5347706df26Smrg TGA_RASTEROP_REG); /* GXCOPY */ 5357706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 5367706df26Smrg 5377706df26Smrg TGA_SAVE_OFFSET(); 5387706df26Smrg return; 5397706df26Smrg} 5407706df26Smrg 5417706df26Smrg/* we only need to calculate the direction of a move once per move, 5427706df26Smrg so we do it in the setup function and leave it */ 5437706df26Smrg 5447706df26Smrgvoid 5457706df26SmrgTGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 5467706df26Smrg int rop, unsigned int planemask, 5477706df26Smrg int transparency_color) 5487706df26Smrg /* xdir 1 = left-to-right, -1 = right to left 5497706df26Smrg ydir 1 = top-to-bottom, -1 = bottom to top 5507706df26Smrg */ 5517706df26Smrg{ 5527706df26Smrg#ifdef PROFILE 5537706df26Smrg unsigned int start, stop; 5547706df26Smrg#endif 5557706df26Smrg TGAPtr pTga; 5567706df26Smrg unsigned int pmask = 0; 5577706df26Smrg TGA_DECL(); 5587706df26Smrg 5597706df26Smrg pTga = TGAPTR(pScrn); 5607706df26Smrg TGA_GET_IOBASE(); 5617706df26Smrg TGA_GET_OFFSET(); 5627706df26Smrg 5637706df26Smrg /* see section 6.2.9 */ 5647706df26Smrg 5657706df26Smrg if (pTga->depthflag == BPP8PACKED) { 5667706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 5677706df26Smrg (planemask << 24); 5687706df26Smrg } 5697706df26Smrg else 5707706df26Smrg pmask = planemask; 5717706df26Smrg 5727706df26Smrg pTga->current_planemask = pmask; 5737706df26Smrg TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); 5747706df26Smrg 5757706df26Smrg pTga->current_rop = rop | pTga->depthflag; 5767706df26Smrg 5777706df26Smrg /* do we copy a rectangle from top to bottom or bottom to top? */ 5787706df26Smrg if (ydir == -1) { 5797706df26Smrg pTga->blitdir = BLIT_FORWARDS; 5807706df26Smrg } 5817706df26Smrg else { 5827706df26Smrg pTga->blitdir = BLIT_BACKWARDS; 5837706df26Smrg } 5847706df26Smrg TGA_SAVE_OFFSET(); 5857706df26Smrg return; 5867706df26Smrg} 5877706df26Smrg 5887706df26Smrg/* 5897706df26Smrg * This is the implementation of the SubsequentForScreenToScreenCopy 5907706df26Smrg * that sends commands to the coprocessor to perform a screen-to-screen 5917706df26Smrg * copy of the specified areas, with the parameters from the SetUp call. 5927706df26Smrg */ 5937706df26Smrgvoid 5947706df26SmrgTGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, 5957706df26Smrg int y2, int w, int h) 5967706df26Smrg{ 5977706df26Smrg /* x1, y1 = source coords 5987706df26Smrg x2, y2 = destination coords 5997706df26Smrg w = width 6007706df26Smrg h = height 6017706df26Smrg */ 6027706df26Smrg 6037706df26Smrg int i = 0; 6047706df26Smrg void (*copy_func)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w); 6057706df26Smrg#ifdef PROFILE 6067706df26Smrg unsigned int stop, start; 6077706df26Smrg#endif 6087706df26Smrg TGAPtr pTga; 6097706df26Smrg TGA_DECL(); 6107706df26Smrg 6117706df26Smrg pTga = TGAPTR(pScrn); 6127706df26Smrg TGA_GET_IOBASE(); 6137706df26Smrg TGA_GET_OFFSET(); 6147706df26Smrg#if 0 6157706df26Smrg ErrorF("TGASubsequentScreenToScreenCopy(,%d,%d,%d,%d,%d,%d):" 6167706df26Smrg " COPY %s BLIT %s\n", 6177706df26Smrg x1, y1, x2, y2, w, h, (x2 > x1 && (x1 + w) > x2)?"BWD":"FWD", 6187706df26Smrg (pTga->blitdir == BLIT_FORWARDS)?"FWD":"BWD"); 6197706df26Smrg#endif 6207706df26Smrg TGASync(pScrn); /* ?? */ 6217706df26Smrg 6227706df26Smrg TGA_FAST_WRITE_REG(COPY | X11 | pTga->depthflag, TGA_MODE_REG); 6237706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 6247706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 6257706df26Smrg 6267706df26Smrg if(x2 > x1 && (x1 + w) > x2) 6277706df26Smrg copy_func = TGACopyLineBackwards; 6287706df26Smrg else 6297706df26Smrg copy_func = TGACopyLineForwards; 6307706df26Smrg 6317706df26Smrg TGA_SAVE_OFFSET(); 6327706df26Smrg if(pTga->blitdir == BLIT_FORWARDS) { 6337706df26Smrg for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */ 6347706df26Smrg (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); 6357706df26Smrg } 6367706df26Smrg } 6377706df26Smrg else { 6387706df26Smrg for(i = 0; i < h; i++) { 6397706df26Smrg (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); 6407706df26Smrg } 6417706df26Smrg } 6427706df26Smrg 6437706df26Smrg TGASync(pScrn); /* ?? */ 6447706df26Smrg 6457706df26Smrg TGA_GET_OFFSET(); 6467706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 6477706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 6487706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 6497706df26Smrg TGA_SAVE_OFFSET(); 6507706df26Smrg 6517706df26Smrg return; 6527706df26Smrg} 6537706df26Smrg 6547706df26Smrg 6557706df26Smrgvoid 6567706df26SmrgTGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w) 6577706df26Smrg{ 6587706df26Smrg /* copy a line of width w from x1,y1 to x2,y2 using copy mode */ 6597706df26Smrg int read; 6607706df26Smrg unsigned long source_address, destination_address; 6617706df26Smrg unsigned int mask_source, mask_destination; 6627706df26Smrg int cando; 6637706df26Smrg unsigned int cando_mask; 6647706df26Smrg int source_align, destination_align; 6657706df26Smrg int pixel_shift; 6667706df26Smrg#ifdef PROFILE 6677706df26Smrg unsigned int start, stop; 6687706df26Smrg#endif 6697706df26Smrg TGAPtr pTga; 6707706df26Smrg TGA_DECL(); 6717706df26Smrg 6727706df26Smrg pTga = TGAPTR(pScrn); 6737706df26Smrg TGA_GET_IOBASE(); 6747706df26Smrg TGA_GET_OFFSET(); 6757706df26Smrg 6767706df26Smrg cando = 32; 6777706df26Smrg cando_mask = 0xFFFFFFFFU; 6787706df26Smrg if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { 6797706df26Smrg cando = 16; 6807706df26Smrg cando_mask = 0x0000FFFFU; 6817706df26Smrg } 6827706df26Smrg 6837706df26Smrg source_address = FB_OFFSET(x1, y1); 6847706df26Smrg destination_address = FB_OFFSET(x2, y2); 6857706df26Smrg#if 0 6867706df26Smrg ErrorF("CPY-FWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx\n", 6877706df26Smrg x1, y1, x2, y2, w, source_address, destination_address); 6887706df26Smrg#endif 6897706df26Smrg read = 0; 6907706df26Smrg while (read < w) { 6917706df26Smrg 6927706df26Smrg mask_source = cando_mask; 6937706df26Smrg if ((w - read) >= cando) 6947706df26Smrg mask_destination = cando_mask; 6957706df26Smrg else 6967706df26Smrg mask_destination = cando_mask >> (cando - (w - read)); 6977706df26Smrg 6987706df26Smrg source_align = source_address & 0x07; 6997706df26Smrg source_address -= source_align; 7007706df26Smrg mask_source <<= source_align / pTga->Bpp; 7017706df26Smrg /* mask_source &= cando_mask; */ 7027706df26Smrg 7037706df26Smrg destination_align = destination_address & 0x07; 7047706df26Smrg destination_address -= destination_align; 7057706df26Smrg mask_destination <<= destination_align / pTga->Bpp; 7067706df26Smrg /* mask_destination &= cando_mask; */ 7077706df26Smrg 7087706df26Smrg if (destination_align >= source_align) 7097706df26Smrg pixel_shift = destination_align - source_align; 7107706df26Smrg else { 7117706df26Smrg pixel_shift = 8 - (source_align - destination_align); 7127706df26Smrg /* we need to prime the residue register in this case */ 7137706df26Smrg destination_address -= 8; 7147706df26Smrg mask_destination <<= 8 / pTga->Bpp; 7157706df26Smrg mask_destination &= cando_mask;/* ?? */ 7167706df26Smrg } 7177706df26Smrg 7187706df26Smrg TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 7197706df26Smrg switch (pTga->Chipset) { 7207706df26Smrg case PCI_CHIP_TGA2: 7217706df26Smrg *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; 7227706df26Smrg *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; 7237706df26Smrg break; 7247706df26Smrg case PCI_CHIP_DEC21030: 7257706df26Smrg /* use GADR and GCTR */ 7267706df26Smrg TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); 7277706df26Smrg TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); 7287706df26Smrg TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); 7297706df26Smrg TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); 7307706df26Smrg break; 7317706df26Smrg } 7327706df26Smrg 7337706df26Smrg source_address += (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 7347706df26Smrg destination_address += cando * pTga->Bpp; 7357706df26Smrg 7367706df26Smrg read += cando; 7377706df26Smrg read -= destination_align / pTga->Bpp; /* "read" is perhaps better 7387706df26Smrg called "written"... */ 7397706df26Smrg if (destination_align < source_align) { 7407706df26Smrg read -= 8 / pTga->Bpp; 7417706df26Smrg } 7427706df26Smrg } 7437706df26Smrg 7447706df26Smrg TGA_SAVE_OFFSET(); 7457706df26Smrg return; 7467706df26Smrg} 7477706df26Smrg 7487706df26Smrg 7497706df26Smrgvoid 7507706df26SmrgTGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 7517706df26Smrg int y2, int w) 7527706df26Smrg /* x1, y1 = source 7537706df26Smrg x2, y2 = destination 7547706df26Smrg w = width 7557706df26Smrg */ 7567706df26Smrg{ 7577706df26Smrg unsigned long a1, a2; 7587706df26Smrg unsigned long source_address, destination_address; 7597706df26Smrg unsigned int mask_source, mask_destination; 7607706df26Smrg int cando; 7617706df26Smrg unsigned int cando_mask; 7627706df26Smrg int source_align, destination_align; 7637706df26Smrg int pixel_shift; 7647706df26Smrg int read; 7657706df26Smrg#ifdef PROFILE 7667706df26Smrg unsigned int start, stop; 7677706df26Smrg#endif 7687706df26Smrg TGAPtr pTga; 7697706df26Smrg TGA_DECL(); 7707706df26Smrg 7717706df26Smrg pTga = TGAPTR(pScrn); 7727706df26Smrg TGA_GET_IOBASE(); 7737706df26Smrg TGA_GET_OFFSET(); 7747706df26Smrg 7757706df26Smrg cando = 32; 7767706df26Smrg cando_mask = 0xFFFFFFFFU; 7777706df26Smrg if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { 7787706df26Smrg cando = 16; 7797706df26Smrg cando_mask = 0x0000FFFFU; 7807706df26Smrg } 7817706df26Smrg 7827706df26Smrg a1 = FB_OFFSET(x1, y1); 7837706df26Smrg a2 = FB_OFFSET(x2, y2); 7847706df26Smrg 7857706df26Smrg source_address = FB_OFFSET((x1 + w) - cando, y1); 7867706df26Smrg destination_address = FB_OFFSET((x2 + w) - cando, y2); 7877706df26Smrg 7887706df26Smrg#if 0 7897706df26Smrg ErrorF("CPY-BWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx" 7907706df26Smrg " a1 0x%lx a2 0x%lx\n", 7917706df26Smrg x1, y1, x2, y2, w, source_address, destination_address, a1, a2); 7927706df26Smrg#endif 7937706df26Smrg 7947706df26Smrg read = 0; 7957706df26Smrg while (read < w) { 7967706df26Smrg mask_source = cando_mask; 7977706df26Smrg if ((w - read) >= cando) 7987706df26Smrg mask_destination = cando_mask; 7997706df26Smrg else { 8007706df26Smrg mask_destination = ((unsigned int)cando_mask) << (cando - (w - read)); 8017706df26Smrg mask_destination &= cando_mask; /* esp. for cando==16 */ 8027706df26Smrg } 8037706df26Smrg 8047706df26Smrg source_align = source_address & 0x07; 8057706df26Smrg destination_align = destination_address & 0x07; 8067706df26Smrg 8077706df26Smrg if (read == 0 && destination_align && 8087706df26Smrg (source_align > destination_align)) { 8097706df26Smrg /* we want to take out all the destination_align pixels in one 8107706df26Smrg little copy first, then move on to the main stuff */ 8117706df26Smrg unsigned long tmp_src, tmp_dest; 8127706df26Smrg unsigned int tmp_src_mask, tmp_dest_mask; 8137706df26Smrg 8147706df26Smrg tmp_src = a1 + (w - (source_align / pTga->Bpp)) * pTga->Bpp; 8157706df26Smrg tmp_dest = a2 + (w - (destination_align / pTga->Bpp) - (8 / pTga->Bpp)) * pTga->Bpp; 8167706df26Smrg tmp_src_mask = cando_mask; 8177706df26Smrg tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align) / pTga->Bpp; 8187706df26Smrg tmp_dest_mask <<= 8 / pTga->Bpp; 8197706df26Smrg pixel_shift = (8 - source_align) + destination_align; 8207706df26Smrg#if 0 8217706df26Smrg ErrorF("CPY-BWD - preliminary copy: sa = %d, da = %d, ps =%d\n", 8227706df26Smrg source_align, destination_align, pixel_shift); 8237706df26Smrg#endif 8247706df26Smrg TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 8257706df26Smrg switch (pTga->Chipset) 8267706df26Smrg { 8277706df26Smrg case PCI_CHIP_TGA2: 8287706df26Smrg *(unsigned int *)(pTga->FbBase + tmp_src) = tmp_src_mask; WMB; 8297706df26Smrg *(unsigned int *)(pTga->FbBase + tmp_dest) = tmp_dest_mask; WMB; 8307706df26Smrg break; 8317706df26Smrg case PCI_CHIP_DEC21030: 8327706df26Smrg /* use GADR and GCTR */ 8337706df26Smrg TGA_FAST_WRITE_REG(tmp_src, TGA_ADDRESS_REG); 8347706df26Smrg TGA_FAST_WRITE_REG(tmp_src_mask, TGA_CONTINUE_REG); 8357706df26Smrg TGA_FAST_WRITE_REG(tmp_dest, TGA_ADDRESS_REG); 8367706df26Smrg TGA_FAST_WRITE_REG(tmp_dest_mask, TGA_CONTINUE_REG); 8377706df26Smrg break; 8387706df26Smrg } 8397706df26Smrg 8407706df26Smrg source_address += (8 - source_align); 8417706df26Smrg mask_source >>= (8 - source_align) / pTga->Bpp; 8427706df26Smrg mask_source >>= destination_align / pTga->Bpp; 8437706df26Smrg mask_destination >>= destination_align / pTga->Bpp; 8447706df26Smrg } 8457706df26Smrg else if (read == 0 && (source_align != destination_align)) { 8467706df26Smrg source_address += (8 - source_align); 8477706df26Smrg /* mask_source >>= (8 - source_align); */ 8487706df26Smrg /* if we uncomment this, it breaks...TGA tries to 8497706df26Smrg optimize away a read of our last pixels... */ 8507706df26Smrg } 8517706df26Smrg else if (source_align) { 8527706df26Smrg source_address += (8 - source_align); 8537706df26Smrg mask_source >>= (8 - source_align) / pTga->Bpp; 8547706df26Smrg } 8557706df26Smrg 8567706df26Smrg if (destination_align) { 8577706df26Smrg destination_address += (8 - destination_align); 8587706df26Smrg mask_destination >>= (8 - destination_align) / pTga->Bpp; 8597706df26Smrg } 8607706df26Smrg 8617706df26Smrg if (destination_align >= source_align) 8627706df26Smrg pixel_shift = destination_align - source_align; 8637706df26Smrg else { 8647706df26Smrg pixel_shift = (8 - source_align) + destination_align; 8657706df26Smrg if (destination_align) { 8667706df26Smrg source_address += 8; 8677706df26Smrg mask_source >>= 8 / pTga->Bpp; 8687706df26Smrg } 8697706df26Smrg } 8707706df26Smrg 8717706df26Smrg#if 0 8727706df26Smrg ErrorF("CPY-BWD - normal: sadr 0x%lx sm 0x%x dadr 0x%lx dm 0x%x" 8737706df26Smrg " sa %d da %d ps %d read %d\n", 8747706df26Smrg source_address, mask_source, 8757706df26Smrg destination_address, mask_destination, 8767706df26Smrg source_align, destination_align, pixel_shift, read); 8777706df26Smrg#endif 8787706df26Smrg TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 8797706df26Smrg switch (pTga->Chipset) { 8807706df26Smrg case PCI_CHIP_TGA2: 8817706df26Smrg *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; 8827706df26Smrg *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; 8837706df26Smrg break; 8847706df26Smrg case PCI_CHIP_DEC21030: 8857706df26Smrg /* use GADR and GCTR */ 8867706df26Smrg TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); 8877706df26Smrg TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); 8887706df26Smrg TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); 8897706df26Smrg TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); 8907706df26Smrg break; 8917706df26Smrg } 8927706df26Smrg 8937706df26Smrg/* if(read == 0) */ 8947706df26Smrg/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */ 8957706df26Smrg/* pixel_shift); */ 8967706df26Smrg 8977706df26Smrg if (destination_align > source_align) { 8987706df26Smrg source_address -= cando * pTga->Bpp - 8; 8997706df26Smrg destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 9007706df26Smrg if (read == 0) 9017706df26Smrg read += (cando - 8 / pTga->Bpp) + source_align / pTga->Bpp; 9027706df26Smrg else 9037706df26Smrg read += cando - 8 / pTga->Bpp; 9047706df26Smrg } 9057706df26Smrg else if (destination_align == source_align) { 9067706df26Smrg source_address -= cando * pTga->Bpp; 9077706df26Smrg destination_address -= cando * pTga->Bpp; 9087706df26Smrg if (read == 0 && destination_align) 9097706df26Smrg read += (cando - (8 - destination_align) / pTga->Bpp); 9107706df26Smrg else 9117706df26Smrg read += cando; 9127706df26Smrg } 9137706df26Smrg else if (source_align > destination_align) { 9147706df26Smrg source_address -= cando * pTga->Bpp - 8; 9157706df26Smrg destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 9167706df26Smrg /* only happens when read == 0 */ 9177706df26Smrg if (destination_align) 9187706df26Smrg read += (cando - 16 / pTga->Bpp) + source_align / pTga->Bpp; 9197706df26Smrg else 9207706df26Smrg read += cando - pixel_shift / pTga->Bpp; 9217706df26Smrg } 9227706df26Smrg } 9237706df26Smrg 9247706df26Smrg TGA_SAVE_OFFSET(); 9257706df26Smrg return; 9267706df26Smrg} 9277706df26Smrg 9287706df26Smrgvoid 9297706df26SmrgTGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 9307706df26Smrg int fg, int bg, int rop, unsigned int planemask) 9317706df26Smrg{ 9327706df26Smrg#ifdef PROFILE 9337706df26Smrg unsigned int start, stop; 9347706df26Smrg#endif 9357706df26Smrg TGAPtr pTga; 9367706df26Smrg unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; 9377706df26Smrg TGA_DECL(); 9387706df26Smrg 9397706df26Smrg pTga = TGAPTR(pScrn); 9407706df26Smrg TGA_GET_IOBASE(); 9417706df26Smrg TGA_GET_OFFSET(); 9427706df26Smrg 9437706df26Smrg/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */ 9447706df26Smrg/* patx, paty, fg, bg, rop, planemask); */ 9457706df26Smrg 9467706df26Smrg if(bg == -1) /* we are transparent */ 9477706df26Smrg pTga->transparent_pattern_p = 1; 9487706df26Smrg else 9497706df26Smrg pTga->transparent_pattern_p = 0; 9507706df26Smrg 9517706df26Smrg if(rop == MIX_SRC) 9527706df26Smrg pTga->block_or_opaque_p = USE_BLOCK_FILL; 9537706df26Smrg else 9547706df26Smrg pTga->block_or_opaque_p = USE_OPAQUE_FILL; 9557706df26Smrg 9567706df26Smrg if(pTga->depthflag == BPP8PACKED) { 9577706df26Smrg fgcolor = fg | (fg << 8) | (fg << 16) | (fg << 24); 9587706df26Smrg bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); 9597706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 9607706df26Smrg (planemask << 24); 9617706df26Smrg } 9627706df26Smrg else { 9637706df26Smrg fgcolor = fg; 9647706df26Smrg bgcolor = bg; 9657706df26Smrg pmask = planemask; 9667706df26Smrg } 9677706df26Smrg 9687706df26Smrg 9697706df26Smrg if(pTga->transparent_pattern_p && 9707706df26Smrg pTga->block_or_opaque_p == USE_BLOCK_FILL) { 9717706df26Smrg /* we can use block fill mode to draw a transparent stipple */ 9727706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 9737706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 9747706df26Smrg if(pTga->depthflag == BPP24) { 9757706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 9767706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 9777706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 9787706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 9797706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 9807706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 9817706df26Smrg } 9827706df26Smrg } 9837706df26Smrg else if(pTga->transparent_pattern_p) { 9847706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 9857706df26Smrg } 9867706df26Smrg else { 9877706df26Smrg TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); 9887706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 9897706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); 9907706df26Smrg } 9917706df26Smrg pTga->current_rop = rop; 9927706df26Smrg pTga->current_planemask = pmask; 9937706df26Smrg TGA_SAVE_OFFSET(); 9947706df26Smrg return; 9957706df26Smrg} 9967706df26Smrg 9977706df26Smrgvoid 9987706df26SmrgTGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, 9997706df26Smrg int x, int y, int w, int h) 10007706df26Smrg/* patx and paty = first & second dwords of pattern to be rendered, packed */ 10017706df26Smrg{ 10027706df26Smrg TGAPtr pTga; 10037706df26Smrg int i, j; 10047706df26Smrg unsigned int stipple_mask[8], align, tmp; 10057706df26Smrg#ifdef PROFILE 10067706df26Smrg register unsigned int stop, start; 10077706df26Smrg#endif 10087706df26Smrg TGA_DECL(); 10097706df26Smrg 10107706df26Smrg 10117706df26Smrg/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); */ 10127706df26Smrg 10137706df26Smrg pTga = TGAPTR(pScrn); 10147706df26Smrg TGA_GET_IOBASE(); 10157706df26Smrg TGA_GET_OFFSET(); 10167706df26Smrg 10177706df26Smrg if(w > 2048) 10187706df26Smrg ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n"); 10197706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 10207706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 10217706df26Smrg 10227706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 10237706df26Smrg if(pTga->depthflag == BPP8PACKED) 10247706df26Smrg align = FB_OFFSET(x, y) % 4; 10257706df26Smrg else 10267706df26Smrg align = x % 4; 10277706df26Smrg 10287706df26Smrg for(i = 0; i < 4; i++) { 10297706df26Smrg tmp = (patx >> (i * 8)) & 0xFF; 10307706df26Smrg stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); 10317706df26Smrg } 10327706df26Smrg for(i = 4; i < 8; i++) { 10337706df26Smrg tmp = (paty >> ((i - 4) * 8)) & 0xFF; 10347706df26Smrg stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); 10357706df26Smrg } 10367706df26Smrg if(align) { /* stipples must be aligned to four bytes */ 10377706df26Smrg for(i = 0; i < 8; i++) { 10387706df26Smrg stipple_mask[i] = (stipple_mask[i] << align) | 10397706df26Smrg ((stipple_mask[i] & 0xFF000000) >> (32 - align)); 10407706df26Smrg } 10417706df26Smrg } 10427706df26Smrg 10437706df26Smrg if((pTga->block_or_opaque_p == USE_BLOCK_FILL) && pTga->transparent_pattern_p) { 10447706df26Smrg /* use block fill */ 10457706df26Smrg TGA_FAST_WRITE_REG(BLOCKFILL | X11 | pTga->depthflag, TGA_MODE_REG); 10467706df26Smrg 10477706df26Smrg for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 10487706df26Smrg TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 10497706df26Smrg TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 10507706df26Smrg TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 10517706df26Smrg } 10527706df26Smrg } 10537706df26Smrg else if(pTga->transparent_pattern_p) { 10547706df26Smrg /* if we can't use block fill, we'll use transparent fill */ 10557706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTFILL | X11 | pTga->depthflag, TGA_MODE_REG); 10567706df26Smrg for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 10577706df26Smrg TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 10587706df26Smrg TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 10597706df26Smrg TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 10607706df26Smrg } 10617706df26Smrg } 10627706df26Smrg else { /* use opaque fill mode */ 10637706df26Smrg/* ErrorF("Using opaque fill mode\n"); */ 10647706df26Smrg TGA_FAST_WRITE_REG(OPAQUEFILL | X11 | pTga->depthflag, TGA_MODE_REG); 10657706df26Smrg for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 10667706df26Smrg TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 10677706df26Smrg TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 10687706df26Smrg TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 10697706df26Smrg } 10707706df26Smrg } 10717706df26Smrg 10727706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 10737706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 10747706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 10757706df26Smrg 10767706df26Smrg TGA_SAVE_OFFSET(); 10777706df26Smrg 10787706df26Smrg return; 10797706df26Smrg} 10807706df26Smrg 10817706df26Smrgvoid 10827706df26SmrgTGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 10837706df26Smrg unsigned int planemask) 10847706df26Smrg{ 10857706df26Smrg#ifdef PROFILE 10867706df26Smrg unsigned int start, stop; 10877706df26Smrg#endif 10887706df26Smrg TGAPtr pTga = NULL; 10897706df26Smrg unsigned int fgcolor = 0, pmask = 0; 10907706df26Smrg TGA_DECL(); 10917706df26Smrg 10927706df26Smrg pTga = TGAPTR(pScrn); 10937706df26Smrg TGA_GET_IOBASE(); 10947706df26Smrg TGA_GET_OFFSET(); 10957706df26Smrg/* ErrorF("TGASetupForSolidLine called\n"); */ 10967706df26Smrg 10977706df26Smrg if(pTga->depthflag == BPP8PACKED) { 10987706df26Smrg fgcolor = color | (color << 8) | (color << 16) | (color << 24); 10997706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 11007706df26Smrg (planemask << 24); 11017706df26Smrg } 11027706df26Smrg else { 11037706df26Smrg fgcolor = color; 11047706df26Smrg pmask = planemask; 11057706df26Smrg } 11067706df26Smrg 11077706df26Smrg 11087706df26Smrg pTga->current_rop = rop | pTga->depthflag; 11097706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 11107706df26Smrg pTga->current_planemask = pmask; 11117706df26Smrg TGA_FAST_WRITE_REG(0xFFFF, TGA_DATA_REG); 11127706df26Smrg TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); 11137706df26Smrg TGA_SAVE_OFFSET(); 11147706df26Smrg 11157706df26Smrg return; 11167706df26Smrg} 11177706df26Smrg 11187706df26Smrgvoid 11197706df26SmrgTGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, 11207706df26Smrg int dir) 11217706df26Smrg{ 11227706df26Smrg if(dir == DEGREES_0) /* line is to the right */ 11237706df26Smrg TGASubsequentSolidLine(pScrn, x, y, x + len, y, 0x0, OMIT_LAST); 11247706df26Smrg else if(dir == DEGREES_270) /* line is down */ 11257706df26Smrg TGASubsequentSolidLine(pScrn, x, y, x, y + len, YMAJOR, OMIT_LAST); 11267706df26Smrg else 11277706df26Smrg ErrorF("TGASubsequentSolidHorVertLine passed dir %d!\n", dir); 11287706df26Smrg 11297706df26Smrg return; 11307706df26Smrg} 11317706df26Smrg 11327706df26Smrgvoid 11337706df26SmrgTGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 11347706df26Smrg int octant, int flags) 11357706df26Smrg{ 11367706df26Smrg#ifdef PROFILE 11377706df26Smrg unsigned int start, stop; 11387706df26Smrg#endif 11397706df26Smrg TGAPtr pTga = NULL; 11407706df26Smrg CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; 11417706df26Smrg int length = 0; 11427706df26Smrg TGA_DECL(); 11437706df26Smrg 11447706df26Smrg pTga = TGAPTR(pScrn); 11457706df26Smrg TGA_GET_IOBASE(); 11467706df26Smrg TGA_GET_OFFSET(); 11477706df26Smrg/* ErrorF("TGASubsequentSolidLine called\n"); */ 11487706df26Smrg 11497706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 11507706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | 11517706df26Smrg ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), TGA_MODE_REG); 11527706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 11537706df26Smrg 11547706df26Smrg address = FB_OFFSET(x1, y1); 11557706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 11567706df26Smrg abs_dx = abs(x2 - x1); 11577706df26Smrg abs_dy = abs(y2 - y1); 11587706df26Smrg if(octant & YMAJOR) 11597706df26Smrg length = abs_dy; 11607706df26Smrg else 11617706df26Smrg length = abs_dx; 11627706df26Smrg 11637706df26Smrg if(octant & YMAJOR) { 11647706df26Smrg if(octant & YDECREASING) { 11657706df26Smrg if(octant & XDECREASING) 11667706df26Smrg octant_reg = TGA_SLOPE0_REG; 11677706df26Smrg else 11687706df26Smrg octant_reg = TGA_SLOPE2_REG; 11697706df26Smrg } 11707706df26Smrg else { 11717706df26Smrg if(octant & XDECREASING) 11727706df26Smrg octant_reg = TGA_SLOPE1_REG; 11737706df26Smrg else 11747706df26Smrg octant_reg = TGA_SLOPE3_REG; 11757706df26Smrg } 11767706df26Smrg } 11777706df26Smrg else { 11787706df26Smrg if(octant & YDECREASING) { 11797706df26Smrg if(octant & XDECREASING) 11807706df26Smrg octant_reg = TGA_SLOPE4_REG; 11817706df26Smrg else 11827706df26Smrg octant_reg = TGA_SLOPE6_REG; 11837706df26Smrg } 11847706df26Smrg else { 11857706df26Smrg if(octant & XDECREASING) 11867706df26Smrg octant_reg = TGA_SLOPE5_REG; 11877706df26Smrg else 11887706df26Smrg octant_reg = TGA_SLOPE7_REG; 11897706df26Smrg } 11907706df26Smrg } 11917706df26Smrg 11927706df26Smrg TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 11937706df26Smrg if(length > 16 && length % 16) 11947706df26Smrg length -= length % 16; 11957706df26Smrg else 11967706df26Smrg length -= 16; 11977706df26Smrg 11987706df26Smrg while(length > 0) { 11997706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); 12007706df26Smrg length -= 16; 12017706df26Smrg } 12027706df26Smrg 12037706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 12047706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 12057706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 12067706df26Smrg 12077706df26Smrg TGA_SAVE_OFFSET(); 12087706df26Smrg 12097706df26Smrg return; 12107706df26Smrg} 12117706df26Smrg 12127706df26Smrgvoid 12137706df26SmrgTGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 12147706df26Smrg int octant) 12157706df26Smrg{ 12167706df26Smrg#ifdef PROFILE 12177706df26Smrg unsigned int start, stop; 12187706df26Smrg#endif 12197706df26Smrg TGAPtr pTga = NULL; 12207706df26Smrg CARD32 abs_dx = 0, abs_dy = 0, octant_reg = 0; 12217706df26Smrg TGA_DECL(); 12227706df26Smrg 12237706df26Smrg pTga = TGAPTR(pScrn); 12247706df26Smrg TGA_GET_IOBASE(); 12257706df26Smrg TGA_GET_OFFSET(); 12267706df26Smrg/* ErrorF("TGASetupForClippedLine called\n"); */ 12277706df26Smrg 12287706df26Smrg/* TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG); */ 12297706df26Smrg/* TGA_FAST_WRITE_REG(OPAQUELINE | X11 | BPP8PACKED, TGA_MODE_REG); */ 12307706df26Smrg 12317706df26Smrg abs_dx = abs(x2 - x1); 12327706df26Smrg abs_dy = abs(y2 - y1); 12337706df26Smrg 12347706df26Smrg if(octant & YMAJOR) { 12357706df26Smrg if(octant & YDECREASING) { 12367706df26Smrg if(octant & XDECREASING) 12377706df26Smrg octant_reg = TGA_NOSLOPE0_REG; 12387706df26Smrg else 12397706df26Smrg octant_reg = TGA_NOSLOPE2_REG; 12407706df26Smrg } 12417706df26Smrg else { 12427706df26Smrg if(octant & XDECREASING) 12437706df26Smrg octant_reg = TGA_NOSLOPE1_REG; 12447706df26Smrg else 12457706df26Smrg octant_reg = TGA_NOSLOPE3_REG; 12467706df26Smrg } 12477706df26Smrg } 12487706df26Smrg else { 12497706df26Smrg if(octant & YDECREASING) { 12507706df26Smrg if(octant & XDECREASING) 12517706df26Smrg octant_reg = TGA_NOSLOPE4_REG; 12527706df26Smrg else 12537706df26Smrg octant_reg = TGA_NOSLOPE6_REG; 12547706df26Smrg } 12557706df26Smrg else { 12567706df26Smrg if(octant & XDECREASING) 12577706df26Smrg octant_reg = TGA_NOSLOPE5_REG; 12587706df26Smrg else 12597706df26Smrg octant_reg = TGA_NOSLOPE7_REG; 12607706df26Smrg } 12617706df26Smrg } 12627706df26Smrg 12637706df26Smrg TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 12647706df26Smrg 12657706df26Smrg TGA_SAVE_OFFSET(); 12667706df26Smrg return; 12677706df26Smrg} 12687706df26Smrg 12697706df26Smrgvoid 12707706df26SmrgTGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len, 12717706df26Smrg int err) 12727706df26Smrg /* we are already in line mode, now we need to 12737706df26Smrg 1) write starting pixel address to gaddr 12747706df26Smrg 2) write initial error and line length to bresenham 3 12757706df26Smrg 3) write the gctr to draw the line, and repeat for lines > 16 pixels 12767706df26Smrg 4) set mode back to simple mode 12777706df26Smrg */ 12787706df26Smrg{ 12797706df26Smrg#ifdef PROFILE 12807706df26Smrg unsigned int start, stop; 12817706df26Smrg#endif 12827706df26Smrg TGAPtr pTga = NULL; 12837706df26Smrg CARD32 address = 0; 12847706df26Smrg int length = 0; 12857706df26Smrg TGA_DECL(); 12867706df26Smrg 12877706df26Smrg pTga = TGAPTR(pScrn); 12887706df26Smrg TGA_GET_IOBASE(); 12897706df26Smrg TGA_GET_OFFSET(); 12907706df26Smrg/* ErrorF("TGASubsequentClippedSolidLine called\n"); */ 12917706df26Smrg 12927706df26Smrg address = FB_OFFSET(x1, y1); 12937706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 12947706df26Smrg 12957706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop | pTga->depthflag, TGA_RASTEROP_REG); 12967706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); 12977706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 12987706df26Smrg 12997706df26Smrg length = len; 13007706df26Smrg TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); 13017706df26Smrg 13027706df26Smrg while(length > 0) { 13037706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); 13047706df26Smrg if(length > 16 && length % 16) 13057706df26Smrg length -= length % 16; 13067706df26Smrg else 13077706df26Smrg length -= 16; 13087706df26Smrg } 13097706df26Smrg 13107706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 13117706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 13127706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 13137706df26Smrg 13147706df26Smrg TGA_SAVE_OFFSET(); 13157706df26Smrg 13167706df26Smrg return; 13177706df26Smrg 13187706df26Smrg} 13197706df26Smrg 13207706df26Smrgvoid 13217706df26SmrgTGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, 13227706df26Smrg unsigned int planemask, int length, 13237706df26Smrg unsigned char *pattern) 13247706df26Smrg{ 13257706df26Smrg#ifdef PROFILE 13267706df26Smrg unsigned int start = 0, stop = 0; 13277706df26Smrg#endif 13287706df26Smrg TGAPtr pTga = NULL; 13297706df26Smrg unsigned int color1 = 0, color2 = 0, pmask = 0; 13307706df26Smrg TGA_DECL(); 13317706df26Smrg 13327706df26Smrg pTga = TGAPTR(pScrn); 13337706df26Smrg TGA_GET_IOBASE(); 13347706df26Smrg TGA_GET_OFFSET(); 13357706df26Smrg/* ErrorF("TGASetupForDashedLine called\n"); */ 13367706df26Smrg 13377706df26Smrg if(pTga->depthflag == BPP8PACKED) { 13387706df26Smrg color1 = fg | (fg << 8) | (fg << 16) | (fg << 24); 13397706df26Smrg color2 = bg | (bg << 8) | (bg << 16) | (bg << 24); 13407706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) 13417706df26Smrg | (planemask << 24); 13427706df26Smrg } 13437706df26Smrg else { 13447706df26Smrg color1 = fg; 13457706df26Smrg color2 = fg; 13467706df26Smrg pmask = planemask; 13477706df26Smrg } 13487706df26Smrg 13497706df26Smrg pTga->current_rop = rop | pTga->depthflag; 13507706df26Smrg TGA_FAST_WRITE_REG(color1, TGA_FOREGROUND_REG); 13517706df26Smrg pTga->current_planemask = pmask; 13527706df26Smrg if(bg == -1) /* transparent line */ 13537706df26Smrg pTga->transparent_pattern_p = 1; 13547706df26Smrg else { 13557706df26Smrg pTga->transparent_pattern_p = 0; 13567706df26Smrg TGA_FAST_WRITE_REG(color2, TGA_BACKGROUND_REG); 13577706df26Smrg } 13587706df26Smrg 13597706df26Smrg pTga->line_pattern = pattern[0] | (pattern[1] << 8); 13607706df26Smrg pTga->line_pattern_length = length; 13617706df26Smrg 13627706df26Smrg TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); 13637706df26Smrg TGA_SAVE_OFFSET(); 13647706df26Smrg 13657706df26Smrg return; 13667706df26Smrg} 13677706df26Smrg 13687706df26Smrgvoid 13697706df26SmrgTGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 13707706df26Smrg int y2, int octant, int flags, int phase) 13717706df26Smrg{ 13727706df26Smrg#ifdef PROFILE 13737706df26Smrg unsigned int start, stop; 13747706df26Smrg#endif 13757706df26Smrg TGAPtr pTga = NULL; 13767706df26Smrg CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; 13777706df26Smrg int length = 0; 13787706df26Smrg CARD16 line_mask = 0; 13797706df26Smrg int pattern_overflow = 0; 13807706df26Smrg int l = 0; 13817706df26Smrg TGA_DECL(); 13827706df26Smrg 13837706df26Smrg pTga = TGAPTR(pScrn); 13847706df26Smrg TGA_GET_IOBASE(); 13857706df26Smrg TGA_GET_OFFSET(); 13867706df26Smrg/* ErrorF("TGASubsequentDashedLine called\n"); */ 13877706df26Smrg 13887706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 13897706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 13907706df26Smrg if(pTga->transparent_pattern_p) 13917706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag | 13927706df26Smrg ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), 13937706df26Smrg TGA_MODE_REG); 13947706df26Smrg else 13957706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | 13967706df26Smrg ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), 13977706df26Smrg TGA_MODE_REG); 13987706df26Smrg 13997706df26Smrg address = FB_OFFSET(x1, y1); 14007706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 14017706df26Smrg abs_dx = abs(x2 - x1); 14027706df26Smrg abs_dy = abs(y2 - y1); 14037706df26Smrg if(abs_dx > abs_dy) 14047706df26Smrg length = abs_dx; 14057706df26Smrg else 14067706df26Smrg length = abs_dy; 14077706df26Smrg 14087706df26Smrg if(octant & YMAJOR) { 14097706df26Smrg if(octant & YDECREASING) { 14107706df26Smrg if(octant & XDECREASING) 14117706df26Smrg octant_reg = TGA_SLOPE0_REG; 14127706df26Smrg else 14137706df26Smrg octant_reg = TGA_SLOPE2_REG; 14147706df26Smrg } 14157706df26Smrg else { 14167706df26Smrg if(octant & XDECREASING) 14177706df26Smrg octant_reg = TGA_SLOPE1_REG; 14187706df26Smrg else 14197706df26Smrg octant_reg = TGA_SLOPE3_REG; 14207706df26Smrg } 14217706df26Smrg } 14227706df26Smrg else { 14237706df26Smrg if(octant & YDECREASING) { 14247706df26Smrg if(octant & XDECREASING) 14257706df26Smrg octant_reg = TGA_SLOPE4_REG; 14267706df26Smrg else 14277706df26Smrg octant_reg = TGA_SLOPE6_REG; 14287706df26Smrg } 14297706df26Smrg else { 14307706df26Smrg if(octant & XDECREASING) 14317706df26Smrg octant_reg = TGA_SLOPE5_REG; 14327706df26Smrg else 14337706df26Smrg octant_reg = TGA_SLOPE7_REG; 14347706df26Smrg } 14357706df26Smrg } 14367706df26Smrg /* set up our first pattern with phase. Keep track of if we overflow the 14377706df26Smrg pattern by pattern_overflow, and correct on the next write */ 14387706df26Smrg 14397706df26Smrg if(phase) { 14407706df26Smrg line_mask = pTga->line_pattern >> phase; 14417706df26Smrg l = (pTga->line_pattern_length - phase); 14427706df26Smrg } 14437706df26Smrg else { 14447706df26Smrg line_mask = pTga->line_pattern; 14457706df26Smrg l = pTga->line_pattern_length; 14467706df26Smrg } 14477706df26Smrg 14487706df26Smrg while(l < 16) { 14497706df26Smrg line_mask |= pTga->line_pattern << l; 14507706df26Smrg l += pTga->line_pattern_length; 14517706df26Smrg } 14527706df26Smrg pattern_overflow = l - 16; 14537706df26Smrg 14547706df26Smrg TGA_FAST_WRITE_REG(line_mask, TGA_DATA_REG); 14557706df26Smrg 14567706df26Smrg TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 14577706df26Smrg 14587706df26Smrg if(length > 16 && length % 16) 14597706df26Smrg length -= length % 16; 14607706df26Smrg else 14617706df26Smrg length -= 16; 14627706df26Smrg 14637706df26Smrg while(length > 0) { 14647706df26Smrg 14657706df26Smrg if(pattern_overflow) { 14667706df26Smrg line_mask = pTga->line_pattern >> (pTga->line_pattern_length - 14677706df26Smrg pattern_overflow); 14687706df26Smrg l = pattern_overflow; 14697706df26Smrg } 14707706df26Smrg else { 14717706df26Smrg line_mask = pTga->line_pattern; 14727706df26Smrg l = pTga->line_pattern_length; 14737706df26Smrg } 14747706df26Smrg while(l < 16) { 14757706df26Smrg line_mask |= (pTga->line_pattern << l); 14767706df26Smrg l += pTga->line_pattern_length; 14777706df26Smrg } 14787706df26Smrg pattern_overflow = l - 16; 14797706df26Smrg 14807706df26Smrg TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); 14817706df26Smrg length -= 16; 14827706df26Smrg } 14837706df26Smrg 14847706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 14857706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 14867706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 14877706df26Smrg 14887706df26Smrg TGA_SAVE_OFFSET(); 14897706df26Smrg 14907706df26Smrg return; 14917706df26Smrg} 14927706df26Smrg 14937706df26Smrgvoid 14947706df26SmrgTGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len, 14957706df26Smrg int err, int phase) 14967706df26Smrg{ 14977706df26Smrg#ifdef PROFILE 14987706df26Smrg unsigned int start, stop; 14997706df26Smrg#endif 15007706df26Smrg TGAPtr pTga = NULL; 15017706df26Smrg CARD32 address = 0; 15027706df26Smrg int length = 0; 15037706df26Smrg CARD16 line_mask = 0; 15047706df26Smrg int pattern_overflow = 0; 15057706df26Smrg int l = 0; 15067706df26Smrg TGA_DECL(); 15077706df26Smrg 15087706df26Smrg pTga = TGAPTR(pScrn); 15097706df26Smrg TGA_GET_IOBASE(); 15107706df26Smrg TGA_GET_OFFSET(); 15117706df26Smrg /* ErrorF("TGASubsequentClippedDashedLine called\n"); */ 15127706df26Smrg 15137706df26Smrg address = FB_OFFSET(x1, y1); 15147706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 15157706df26Smrg 15167706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 15177706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 15187706df26Smrg 15197706df26Smrg if(pTga->transparent_pattern_p) 15207706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag, TGA_MODE_REG); 15217706df26Smrg else 15227706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); 15237706df26Smrg 15247706df26Smrg length = len; 15257706df26Smrg TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); 15267706df26Smrg 15277706df26Smrg 15287706df26Smrg if(phase) { 15297706df26Smrg line_mask = pTga->line_pattern >> phase; 15307706df26Smrg l = (pTga->line_pattern_length - phase); 15317706df26Smrg } 15327706df26Smrg else { 15337706df26Smrg line_mask = pTga->line_pattern; 15347706df26Smrg l = pTga->line_pattern_length; 15357706df26Smrg } 15367706df26Smrg 15377706df26Smrg while(l < 16) { 15387706df26Smrg line_mask |= pTga->line_pattern << l; 15397706df26Smrg l += pTga->line_pattern_length; 15407706df26Smrg } 15417706df26Smrg pattern_overflow = l - 16; 15427706df26Smrg 15437706df26Smrg 15447706df26Smrg while(length > 0) { 15457706df26Smrg TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); 15467706df26Smrg 15477706df26Smrg if(pattern_overflow) { 15487706df26Smrg line_mask = pTga->line_pattern >> (pTga->line_pattern_length - 15497706df26Smrg pattern_overflow); 15507706df26Smrg l = pattern_overflow; 15517706df26Smrg } 15527706df26Smrg else { 15537706df26Smrg line_mask = pTga->line_pattern; 15547706df26Smrg l = pTga->line_pattern_length; 15557706df26Smrg } 15567706df26Smrg while(l < 16) { 15577706df26Smrg line_mask |= (pTga->line_pattern << l); 15587706df26Smrg l += pTga->line_pattern_length; 15597706df26Smrg } 15607706df26Smrg pattern_overflow = l - 16; 15617706df26Smrg 15627706df26Smrg if(length > 16 && length % 16) 15637706df26Smrg length -= length % 16; 15647706df26Smrg else 15657706df26Smrg length -= 16; 15667706df26Smrg } 15677706df26Smrg 15687706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 15697706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 15707706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 15717706df26Smrg 15727706df26Smrg TGA_SAVE_OFFSET(); 15737706df26Smrg 15747706df26Smrg return; 15757706df26Smrg} 1576b92e825aSmrg#endif 1577