1340e3fbdSmrg/* 2340e3fbdSmrg * Copyright 2001 Ani Joshi <ajoshi@unixbox.com> 3340e3fbdSmrg * 4340e3fbdSmrg * XFree86 4.x driver for S3 chipsets 5340e3fbdSmrg * 6340e3fbdSmrg * 7340e3fbdSmrg * Permission to use, copy, modify, distribute, and sell this software and its 8340e3fbdSmrg * documentation for any purpose is hereby granted without fee, provided that 9340e3fbdSmrg * the above copyright notice appear in all copies and that both that copyright 10340e3fbdSmrg * notice and this permission notice appear in supporting documentation and 11340e3fbdSmrg * that the name of Ani Joshi not be used in advertising or 12340e3fbdSmrg * publicity pertaining to distribution of the software without specific, 13340e3fbdSmrg * written prior permission. Ani Joshi makes no representations 14340e3fbdSmrg * about the suitability of this software for any purpose. It is provided 15340e3fbdSmrg * "as-is" without express or implied warranty. 16340e3fbdSmrg * 17340e3fbdSmrg * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18340e3fbdSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19340e3fbdSmrg * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20340e3fbdSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21340e3fbdSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22340e3fbdSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23340e3fbdSmrg * PERFORMANCE OF THIS SOFTWARE. 24340e3fbdSmrg * 25340e3fbdSmrg * 26340e3fbdSmrg */ 27340e3fbdSmrg 28340e3fbdSmrg#ifdef HAVE_CONFIG_H 29340e3fbdSmrg#include "config.h" 30340e3fbdSmrg#endif 31340e3fbdSmrg 32340e3fbdSmrg#include "xf86.h" 33340e3fbdSmrg 34340e3fbdSmrg#include "miline.h" 35340e3fbdSmrg 36340e3fbdSmrg#include "s3.h" 37340e3fbdSmrg#include "s3_reg.h" 38340e3fbdSmrg 39b27e1915Smrg#ifdef HAVE_XAA_H 40340e3fbdSmrg 41340e3fbdSmrg#if 0 42340e3fbdSmrgstatic Bool NicePattern; 43340e3fbdSmrgstatic int DashPatternSize; 44340e3fbdSmrg#define MAX_LINE_PATTERN_LENGTH 512 45340e3fbdSmrg#define LINE_PATTERN_START ((MAX_LINE_PATTERN_LENGTH >> 5) - 1) 46340e3fbdSmrgstatic CARD32 DashPattern[MAX_LINE_PATTERN_LENGTH >> 5]; 47340e3fbdSmrg#endif 48340e3fbdSmrg 49340e3fbdSmrg 50340e3fbdSmrgstatic void S3Sync(ScrnInfoPtr pScrn) 51340e3fbdSmrg{ 52340e3fbdSmrg WaitIdle(); 53340e3fbdSmrg} 54340e3fbdSmrg 55340e3fbdSmrgstatic void S3SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 56340e3fbdSmrg unsigned int planemask) 57340e3fbdSmrg{ 58340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 59340e3fbdSmrg 60340e3fbdSmrg WaitQueue16_32(4,6); 61340e3fbdSmrg SET_PIX_CNTL(0); 62340e3fbdSmrg SET_FRGD_COLOR(color); 63340e3fbdSmrg SET_FRGD_MIX(FSS_FRGDCOL | s3alu[rop]); 64340e3fbdSmrg SET_WRT_MASK(planemask); 65340e3fbdSmrg} 66340e3fbdSmrg 67340e3fbdSmrgstatic void S3SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 68340e3fbdSmrg int w, int h) 69340e3fbdSmrg{ 70340e3fbdSmrg#ifdef S3_NEWMMIO 71340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 72340e3fbdSmrg#endif 73340e3fbdSmrg 74340e3fbdSmrg WaitQueue(5); 75340e3fbdSmrg SET_CURPT((short)x, (short)y); 76340e3fbdSmrg SET_AXIS_PCNT(w - 1, h - 1); 77340e3fbdSmrg SET_CMD(CMD_RECT | DRAW | INC_X | INC_Y | WRTDATA); 78340e3fbdSmrg} 79340e3fbdSmrg 80340e3fbdSmrg 81340e3fbdSmrgstatic void S3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 82340e3fbdSmrg int ydir, int rop, 83340e3fbdSmrg unsigned int planemask, 84340e3fbdSmrg int trans_color) 85340e3fbdSmrg{ 86340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 87340e3fbdSmrg 88340e3fbdSmrg pS3->BltDir = CMD_BITBLT | DRAW | WRTDATA; 89340e3fbdSmrg 90340e3fbdSmrg if (xdir == 1) 91340e3fbdSmrg pS3->BltDir |= INC_X; 92340e3fbdSmrg if (ydir == 1) 93340e3fbdSmrg pS3->BltDir |= INC_Y; 94340e3fbdSmrg 95340e3fbdSmrg pS3->trans_color = trans_color; 96340e3fbdSmrg 97340e3fbdSmrg WaitQueue16_32(3,4); 98340e3fbdSmrg SET_PIX_CNTL(0); 99340e3fbdSmrg SET_FRGD_MIX(FSS_BITBLT | s3alu[rop]); 100340e3fbdSmrg SET_WRT_MASK(planemask); 101340e3fbdSmrg} 102340e3fbdSmrg 103340e3fbdSmrg 104340e3fbdSmrgstatic void S3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 105340e3fbdSmrg int srcx, int srcy, 106340e3fbdSmrg int dstx, int dsty, 107340e3fbdSmrg int w, int h) 108340e3fbdSmrg{ 109340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 110340e3fbdSmrg 111340e3fbdSmrg w--; 112340e3fbdSmrg h--; 113340e3fbdSmrg 114340e3fbdSmrg if (!(pS3->BltDir & INC_Y)) { 115340e3fbdSmrg srcy += h; 116340e3fbdSmrg dsty += h; 117340e3fbdSmrg } 118340e3fbdSmrg 119340e3fbdSmrg if (!(pS3->BltDir & INC_X)) { 120340e3fbdSmrg srcx += w; 121340e3fbdSmrg dstx += w; 122340e3fbdSmrg } 123340e3fbdSmrg 124340e3fbdSmrg if (pS3->trans_color == -1) { 125340e3fbdSmrg WaitQueue(7); 126340e3fbdSmrg SET_CURPT((short)srcx, (short)srcy); 127340e3fbdSmrg SET_DESTSTP((short)dstx, (short)dsty); 128340e3fbdSmrg SET_AXIS_PCNT((short)w, (short)h); 129340e3fbdSmrg SET_CMD(pS3->BltDir); 130340e3fbdSmrg } else { 131340e3fbdSmrg WaitQueue16_32(2,3); 132340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH | 0x0100); 133340e3fbdSmrg SET_COLOR_CMP(pS3->trans_color); 134340e3fbdSmrg 135340e3fbdSmrg WaitQueue(8); 136340e3fbdSmrg SET_CURPT((short)srcx, (short)srcy); 137340e3fbdSmrg SET_DESTSTP((short)dstx, (short)dsty); 138340e3fbdSmrg SET_AXIS_PCNT((short)w, (short)h); 139340e3fbdSmrg SET_CMD(pS3->BltDir); 140340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH); 141340e3fbdSmrg } 142340e3fbdSmrg} 143340e3fbdSmrg 144bd35f0dbSahoka#if 0 145340e3fbdSmrgstatic void S3SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, 146340e3fbdSmrg int patx, int paty, 147340e3fbdSmrg int rop, unsigned int planemask, 148340e3fbdSmrg int trans_color) 149340e3fbdSmrg{ 150340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 151340e3fbdSmrg 152340e3fbdSmrg pS3->trans_color = trans_color; 153340e3fbdSmrg 154340e3fbdSmrg WaitQueue16_32(3,4); 155340e3fbdSmrg SET_PIX_CNTL(0); 156340e3fbdSmrg SET_FRGD_MIX(FSS_BITBLT | s3alu[rop]); 157340e3fbdSmrg SET_WRT_MASK(planemask); 158340e3fbdSmrg} 159340e3fbdSmrg 160340e3fbdSmrgstatic void S3SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, 161340e3fbdSmrg int patx, int paty, 162340e3fbdSmrg int x, int y, 163340e3fbdSmrg int w, int h) 164340e3fbdSmrg{ 165340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 166340e3fbdSmrg 167340e3fbdSmrg if (pS3->trans_color == -1) { 168340e3fbdSmrg WaitQueue(7); 169340e3fbdSmrg SET_CURPT((short)patx, (short)paty); 170340e3fbdSmrg SET_DESTSTP((short)x, (short)y); 171340e3fbdSmrg SET_AXIS_PCNT(w - 1, h - 1); 172340e3fbdSmrg SET_CMD(CMD_PFILL | DRAW | INC_Y | INC_X | WRTDATA); 173340e3fbdSmrg } else { 174340e3fbdSmrg WaitQueue16_32(2,3); 175340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH | 0x0100); 176340e3fbdSmrg SET_COLOR_CMP(pS3->trans_color); 177340e3fbdSmrg 178340e3fbdSmrg WaitQueue(8); 179340e3fbdSmrg SET_CURPT((short)patx, (short)paty); 180340e3fbdSmrg SET_DESTSTP((short)x, (short)y); 181340e3fbdSmrg SET_AXIS_PCNT(w - 1, h - 1); 182340e3fbdSmrg SET_CMD(CMD_PFILL | DRAW | INC_Y | INC_X | WRTDATA); 183340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH); 184340e3fbdSmrg } 185340e3fbdSmrg} 186bd35f0dbSahoka#endif 187340e3fbdSmrg 188340e3fbdSmrg#ifdef S3_NEWMMIO 189340e3fbdSmrgstatic void S3SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 190340e3fbdSmrg int fg, int bg, 191340e3fbdSmrg int rop, 192340e3fbdSmrg unsigned int planemask) 193340e3fbdSmrg{ 194340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 195340e3fbdSmrg 196340e3fbdSmrg WaitQueue16_32(3,4); 197340e3fbdSmrg if (bg == -1) { 198340e3fbdSmrg if (pS3->ColorExpandBug) { 199340e3fbdSmrg SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | MIX_XOR); 200340e3fbdSmrg SET_BKGD_COLOR(0); 201340e3fbdSmrg } else 202340e3fbdSmrg SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | MIX_DST); 203340e3fbdSmrg } else { 204340e3fbdSmrg SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | s3alu[rop]); 205340e3fbdSmrg SET_BKGD_COLOR(bg); 206340e3fbdSmrg } 207340e3fbdSmrg 208340e3fbdSmrg WaitQueue16_32(3,5); 209340e3fbdSmrg SET_FRGD_COLOR(fg); 210340e3fbdSmrg SET_WRT_MASK(planemask); 211340e3fbdSmrg SET_PIX_CNTL(MIXSEL_EXPPC); 212340e3fbdSmrg} 213340e3fbdSmrg 214340e3fbdSmrg 215340e3fbdSmrgstatic void S3SubsequentCPUToScreenColorExpandFill32(ScrnInfoPtr pScrn, 216340e3fbdSmrg int x, int y, 217340e3fbdSmrg int w, int h, 218340e3fbdSmrg int skipleft) 219340e3fbdSmrg{ 220340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 221340e3fbdSmrg 222340e3fbdSmrg WaitQueue(4); 223340e3fbdSmrg SET_CURPT((short)x, (short)y); 224340e3fbdSmrg SET_AXIS_PCNT((short)w-1, (short)h-1); 225340e3fbdSmrg 226340e3fbdSmrg WaitIdle(); 227340e3fbdSmrg SET_CMD(CMD_RECT | BYTSEQ | _32BIT | PCDATA | DRAW | 228340e3fbdSmrg PLANAR | INC_Y | INC_X | WRTDATA); 229340e3fbdSmrg} 230340e3fbdSmrg#endif 231340e3fbdSmrg 232340e3fbdSmrg#if 0 233340e3fbdSmrg#ifndef S3_NEWMMIO 234340e3fbdSmrg 235340e3fbdSmrgstatic void S3SetupForScanlineImageWriteNoMMIO(ScrnInfoPtr pScrn, int rop, 236340e3fbdSmrg unsigned int planemask, 237340e3fbdSmrg int trans_color, 238340e3fbdSmrg int bpp, int depth) 239340e3fbdSmrg{ 240340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 241340e3fbdSmrg 242340e3fbdSmrg WaitQueue16_32(3,4) 243340e3fbdSmrg SET_FRGD_MIX(FSS_PCDATA | s3alu[rop]); 244340e3fbdSmrg SET_WRT_MASK(planemask); 245340e3fbdSmrg SET_PIX_CNTL(0); 246340e3fbdSmrg} 247340e3fbdSmrg 248340e3fbdSmrgstatic void S3SubsequentScanlineImageWriteRectNoMMIO(ScrnInfoPtr pScrn, 249340e3fbdSmrg int x, int y, 250340e3fbdSmrg int w, int h, 251340e3fbdSmrg int skipleft) 252340e3fbdSmrg{ 253340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 254340e3fbdSmrg 255340e3fbdSmrg pS3->imageWidth = w; 256340e3fbdSmrg pS3->imageHeight = h; 257340e3fbdSmrg 258340e3fbdSmrg WaitQueue(5); 259340e3fbdSmrg SET_CURPT((short)x, (short)y); 260340e3fbdSmrg SET_AXIS_PCNT((short)w-1, (short)h-1); 261340e3fbdSmrg WaitIdle(); 262340e3fbdSmrg SET_CMD(CMD_RECT | BYTSEQ | _16BIT | INC_Y | INC_X | DRAW | 263340e3fbdSmrg PCDATA | WRTDATA); 264340e3fbdSmrg} 265340e3fbdSmrg 266340e3fbdSmrg 267340e3fbdSmrgstatic void S3SubsequentImageWriteScanlineNoMMIO(ScrnInfoPtr pScrn, 268340e3fbdSmrg int bufno) 269340e3fbdSmrg{ 270340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 271340e3fbdSmrg int i, j; 272340e3fbdSmrg int w, h; 273340e3fbdSmrg CARD16 *src = (CARD16 *)&pS3->imageBuffer; 274340e3fbdSmrg 275340e3fbdSmrg w = pS3->imageWidth * pS3->s3Bpp; 276340e3fbdSmrg h = pS3->imageHeight; 277340e3fbdSmrg 278340e3fbdSmrg for(j=0; j<h; j++) { 279340e3fbdSmrg for(i=0; i<(w & ~1); ) { 280340e3fbdSmrg /* XXX not for 32bpp */ 281340e3fbdSmrg SET_PIX_TRANS_W(ldw_u(src)); 282340e3fbdSmrg src++; 283340e3fbdSmrg i += 2; 284340e3fbdSmrg } 285340e3fbdSmrg } 286340e3fbdSmrg} 287340e3fbdSmrg 288340e3fbdSmrg#endif 289340e3fbdSmrg#endif 290340e3fbdSmrg 291340e3fbdSmrg 292340e3fbdSmrgstatic void S3SetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 293340e3fbdSmrg unsigned int planemask) 294340e3fbdSmrg{ 295340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 296340e3fbdSmrg 297340e3fbdSmrg WaitQueue16_32(4,6); 298340e3fbdSmrg SET_PIX_CNTL(0); 299340e3fbdSmrg SET_FRGD_COLOR(color); 300340e3fbdSmrg SET_FRGD_MIX(FSS_FRGDCOL | s3alu[rop]); 301340e3fbdSmrg SET_WRT_MASK(planemask); 302340e3fbdSmrg} 303340e3fbdSmrg 304340e3fbdSmrg 305340e3fbdSmrgstatic void S3SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, 306340e3fbdSmrg int x, int y, 307340e3fbdSmrg int major, int minor, 308340e3fbdSmrg int err, int len, int octant) 309340e3fbdSmrg{ 310340e3fbdSmrg#ifdef S3_NEWMMIO 311340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 312340e3fbdSmrg#endif 313340e3fbdSmrg unsigned short cmd; 314340e3fbdSmrg int error, e1, e2; 315340e3fbdSmrg 316340e3fbdSmrg error = minor + err; 317340e3fbdSmrg e1 = minor; /* was: major, wrong (twini@xfree86.org) */ 318340e3fbdSmrg e2 = minor - major; 319340e3fbdSmrg 320340e3fbdSmrg if (major) { 321340e3fbdSmrg cmd = CMD_LINE | DRAW | WRTDATA | LASTPIX; 322340e3fbdSmrg 323340e3fbdSmrg if (octant & YMAJOR) 324340e3fbdSmrg cmd |= YMAJAXIS; 325340e3fbdSmrg if (!(octant & XDECREASING)) 326340e3fbdSmrg cmd |= INC_X; 327340e3fbdSmrg if (!(octant & YDECREASING)) 328340e3fbdSmrg cmd |= INC_Y; 329340e3fbdSmrg 330340e3fbdSmrg WaitQueue(7); 331340e3fbdSmrg SET_CURPT((short)x, (short)y); 332340e3fbdSmrg SET_ERR_TERM((short)error); 333340e3fbdSmrg SET_DESTSTP((short)e2, (short)e1); 334340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len); 335340e3fbdSmrg SET_CMD(cmd); 336340e3fbdSmrg } else { 337340e3fbdSmrg WaitQueue(4); 338340e3fbdSmrg SET_CURPT((short)x, (short)y); 339340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len-1); 340340e3fbdSmrg SET_CMD(CMD_LINE | DRAW | LINETYPE | WRTDATA | VECDIR_270); 341340e3fbdSmrg } 342340e3fbdSmrg} 343340e3fbdSmrg 344340e3fbdSmrg 345340e3fbdSmrg 346340e3fbdSmrgstatic void S3SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, 347340e3fbdSmrg int x, int y, int len, int dir) 348340e3fbdSmrg{ 349340e3fbdSmrg if (dir == DEGREES_0) 350340e3fbdSmrg S3SubsequentSolidFillRect(pScrn, x, y, len, 1); 351340e3fbdSmrg else 352340e3fbdSmrg S3SubsequentSolidFillRect(pScrn, x, y, 1, len); 353340e3fbdSmrg} 354340e3fbdSmrg 355340e3fbdSmrg 356340e3fbdSmrg#if 0 357340e3fbdSmrg 358340e3fbdSmrgstatic void S3SetupForDashedLine(ScrnInfoPtr pScrn, 359340e3fbdSmrg int fg, int bg, 360340e3fbdSmrg int rop, unsigned int planemask, 361340e3fbdSmrg int len, unsigned char *pattern) 362340e3fbdSmrg{ 363340e3fbdSmrg#ifdef S3_NEWMMIO 364340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 365340e3fbdSmrg 366340e3fbdSmrg S3SetupForCPUToScreenColorExpandFill(pScrn, bg, fg, rop, planemask); 367340e3fbdSmrg#endif 368340e3fbdSmrg 369340e3fbdSmrg WaitQueue(4); 370340e3fbdSmrg 371340e3fbdSmrg NicePattern = FALSE; 372340e3fbdSmrg 373340e3fbdSmrg if (len <= 32) { 374340e3fbdSmrg register CARD32 scratch = DashPattern[LINE_PATTERN_START]; 375340e3fbdSmrg 376340e3fbdSmrg if (len & (len - 1)) { 377340e3fbdSmrg while (len < 16) { 378340e3fbdSmrg scratch |= (scratch >> len); 379340e3fbdSmrg len <<= 1; 380340e3fbdSmrg } 381340e3fbdSmrg scratch |= (scratch >> len); 382340e3fbdSmrg DashPattern[LINE_PATTERN_START] = scratch; 383340e3fbdSmrg } else { 384340e3fbdSmrg switch (len) { 385340e3fbdSmrg case 2: 386340e3fbdSmrg scratch |= scratch >> 2; 387340e3fbdSmrg case 4: 388340e3fbdSmrg scratch |= scratch >> 4; 389340e3fbdSmrg case 8: 390340e3fbdSmrg scratch |= scratch >> 8; 391340e3fbdSmrg case 16: 392340e3fbdSmrg scratch |= scratch >> 16; 393340e3fbdSmrg DashPattern[LINE_PATTERN_START] = scratch; 394340e3fbdSmrg case 32: 395340e3fbdSmrg NicePattern = TRUE; 396340e3fbdSmrg default: 397340e3fbdSmrg break; 398340e3fbdSmrg } 399340e3fbdSmrg } 400340e3fbdSmrg } 401340e3fbdSmrg 402340e3fbdSmrg DashPatternSize = len; 403340e3fbdSmrg} 404340e3fbdSmrg 405340e3fbdSmrg 406340e3fbdSmrgstatic void S3SubsequentDashedBresenhamLine32(ScrnInfoPtr pScrn, 407340e3fbdSmrg int x, int y, 408340e3fbdSmrg int absmaj, int absmin, 409340e3fbdSmrg int err, int len, 410340e3fbdSmrg int octant, int phase) 411340e3fbdSmrg{ 412340e3fbdSmrg#ifdef S3_NEWMMIO 413340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 414340e3fbdSmrg#endif 415340e3fbdSmrg register int count = (len + 31) >> 5; 416340e3fbdSmrg register CARD32 pattern; 417340e3fbdSmrg int error, e1, e2; 418340e3fbdSmrg 419340e3fbdSmrg error = absmin + err; 420340e3fbdSmrg e1 = absmaj; 421340e3fbdSmrg e2 = absmin - absmaj; 422340e3fbdSmrg 423340e3fbdSmrg if (err) { 424340e3fbdSmrg unsigned short cmd = _32BIT | PLANAR | WRTDATA | DRAW | 425340e3fbdSmrg PCDATA | LASTPIX | CMD_LINE; 426340e3fbdSmrg 427340e3fbdSmrg if (octant & YMAJOR) 428340e3fbdSmrg cmd |= YMAJAXIS; 429340e3fbdSmrg if (!(octant & XDECREASING)) 430340e3fbdSmrg cmd |= INC_X; 431340e3fbdSmrg if (!(octant & YDECREASING)) 432340e3fbdSmrg cmd |= INC_Y; 433340e3fbdSmrg 434340e3fbdSmrg WaitQueue(7); 435340e3fbdSmrg SET_CURPT((short)x, (short)y); 436340e3fbdSmrg SET_ERR_TERM((short)error); 437340e3fbdSmrg SET_DESTSTP((short)e2, (short)e1); 438340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len); 439340e3fbdSmrg SET_CMD(cmd); 440340e3fbdSmrg } else { 441340e3fbdSmrg if (octant & YMAJOR) { 442340e3fbdSmrg WaitQueue(4); 443340e3fbdSmrg SET_CURPT((short)x, (short)y); 444340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len - 1); 445340e3fbdSmrg 446340e3fbdSmrg if (octant & YDECREASING) { 447340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 448340e3fbdSmrg CMD_LINE | LINETYPE | VECDIR_090); 449340e3fbdSmrg } else { 450340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 451340e3fbdSmrg CMD_LINE | LINETYPE | VECDIR_270); 452340e3fbdSmrg } 453340e3fbdSmrg } else { 454340e3fbdSmrg if (octant & XDECREASING) { 455340e3fbdSmrg WaitQueue(4); 456340e3fbdSmrg SET_CURPT((short)x, (short)y); 457340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len - 1); 458340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 459340e3fbdSmrg PCDATA | CMD_LINE | LINETYPE | VECDIR_180); 460340e3fbdSmrg } else { 461340e3fbdSmrg WaitQueue(4); 462340e3fbdSmrg SET_CURPT((short)x, (short)y); 463340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len - 1); 464340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 465340e3fbdSmrg PCDATA | CMD_RECT | INC_Y | INC_X); 466340e3fbdSmrg } 467340e3fbdSmrg } 468340e3fbdSmrg } 469340e3fbdSmrg 470340e3fbdSmrg if (NicePattern) { 471340e3fbdSmrg#ifdef S3_NEWMMIO 472340e3fbdSmrg register CARD32 *dest = (CARD32*)&IMG_TRANS; 473340e3fbdSmrg#endif 474340e3fbdSmrg 475340e3fbdSmrg pattern = (phase) ? (DashPattern[LINE_PATTERN_START] << phase) | 476340e3fbdSmrg (DashPattern[LINE_PATTERN_START] >> (32 - phase)) : 477340e3fbdSmrg DashPattern[LINE_PATTERN_START]; 478340e3fbdSmrg 479340e3fbdSmrg#ifdef S3_NEWMMIO 480340e3fbdSmrg while (count & ~0x03) { 481340e3fbdSmrg dest[0] = dest[1] = dest[2] = dest[3] = pattern; 482340e3fbdSmrg dest += 4; 483340e3fbdSmrg count -= 4; 484340e3fbdSmrg } 485340e3fbdSmrg switch (count) { 486340e3fbdSmrg case 1: 487340e3fbdSmrg dest[0] = pattern; 488340e3fbdSmrg break; 489340e3fbdSmrg case 2: 490340e3fbdSmrg dest[0] = dest[1] = pattern; 491340e3fbdSmrg break; 492340e3fbdSmrg case 3: 493340e3fbdSmrg dest[0] = dest[1] = dest[2] = pattern; 494340e3fbdSmrg break; 495340e3fbdSmrg } 496340e3fbdSmrg#else 497340e3fbdSmrg 498340e3fbdSmrg while (count--) 499340e3fbdSmrg SET_PIX_TRANS_L(pattern); 500340e3fbdSmrg#endif 501340e3fbdSmrg } else if (DashPatternSize < 32) { 502340e3fbdSmrg register int offset = phase; 503340e3fbdSmrg 504340e3fbdSmrg while (count--) { 505340e3fbdSmrg SET_PIX_TRANS_L((DashPattern[LINE_PATTERN_START] << offset) | 506340e3fbdSmrg (DashPattern[LINE_PATTERN_START] >> 507340e3fbdSmrg (DashPatternSize - offset))); 508340e3fbdSmrg offset += 32; 509340e3fbdSmrg while (offset > DashPatternSize) 510340e3fbdSmrg offset -= DashPatternSize; 511340e3fbdSmrg } 512340e3fbdSmrg } else { 513340e3fbdSmrg int offset = phase; 514340e3fbdSmrg register unsigned char *srcp = (unsigned char *)(DashPattern) + 515340e3fbdSmrg (MAX_LINE_PATTERN_LENGTH >> 3) - 1; 516340e3fbdSmrg register CARD32 *scratch; 517340e3fbdSmrg int scratch2, shift; 518340e3fbdSmrg 519340e3fbdSmrg while (count--) { 520340e3fbdSmrg shift = DashPatternSize - offset; 521340e3fbdSmrg scratch = (CARD32*)(srcp - (offset >> 3) - 3); 522340e3fbdSmrg scratch2 = offset & 0x07; 523340e3fbdSmrg 524340e3fbdSmrg if (shift & ~31) { 525340e3fbdSmrg if (scratch2) { 526340e3fbdSmrg pattern = (*scratch << scratch2) | 527340e3fbdSmrg (*(scratch - 1) >> (32 - scratch2)); 528340e3fbdSmrg } else 529340e3fbdSmrg pattern = *scratch; 530340e3fbdSmrg } else { 531340e3fbdSmrg pattern = (*((CARD32*)(srcp - 3)) >> shift) | 532340e3fbdSmrg (*scratch << scratch2); 533340e3fbdSmrg } 534340e3fbdSmrg SET_PIX_TRANS_L(pattern); 535340e3fbdSmrg offset += 32; 536340e3fbdSmrg while (offset >= DashPatternSize) 537340e3fbdSmrg offset -= DashPatternSize; 538340e3fbdSmrg } 539340e3fbdSmrg } 540340e3fbdSmrg} 541340e3fbdSmrg 542b27e1915Smrg#endif 543340e3fbdSmrg#endif 544340e3fbdSmrg 545340e3fbdSmrg#ifdef S3_NEWMMIO 546340e3fbdSmrgBool S3AccelInitNewMMIO(ScreenPtr pScreen) 547340e3fbdSmrg#else 548340e3fbdSmrgBool S3AccelInitPIO(ScreenPtr pScreen) 549340e3fbdSmrg#endif 550340e3fbdSmrg{ 551b27e1915Smrg#ifdef HAVE_XAA_H 552b27e1915Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 553340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 554340e3fbdSmrg XAAInfoRecPtr pXAA; 555340e3fbdSmrg 556340e3fbdSmrg if (pS3->Chipset == PCI_CHIP_968) 557340e3fbdSmrg pS3->ColorExpandBug = TRUE; 558340e3fbdSmrg else 559340e3fbdSmrg pS3->ColorExpandBug = FALSE; 560340e3fbdSmrg 561340e3fbdSmrg if (!(pXAA = XAACreateInfoRec())) 562340e3fbdSmrg return FALSE; 563340e3fbdSmrg 564340e3fbdSmrg pS3->pXAA = pXAA; 565340e3fbdSmrg 566340e3fbdSmrg pXAA->Flags = (PIXMAP_CACHE | OFFSCREEN_PIXMAPS | 567340e3fbdSmrg LINEAR_FRAMEBUFFER); 568340e3fbdSmrg 569340e3fbdSmrg pXAA->Sync = S3Sync; 570340e3fbdSmrg 571340e3fbdSmrg pXAA->SetupForSolidFill = S3SetupForSolidFill; 572340e3fbdSmrg pXAA->SubsequentSolidFillRect = S3SubsequentSolidFillRect; 573340e3fbdSmrg 574340e3fbdSmrg pXAA->SetupForScreenToScreenCopy = S3SetupForScreenToScreenCopy; 575340e3fbdSmrg pXAA->SubsequentScreenToScreenCopy = S3SubsequentScreenToScreenCopy; 576bd35f0dbSahoka pXAA->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 577340e3fbdSmrg 578bd35f0dbSahoka#if 0 579bd35f0dbSahoka/* 580bd35f0dbSahoka 8x8 color pattern filling doesn't work properly after introducing 581bd35f0dbSahoka framebuffer manager initialization before XAA initialization. There 582bd35f0dbSahoka are problems with addressing a colour patterns from offscreen area. 583bd35f0dbSahoka*/ 584340e3fbdSmrg pXAA->SetupForColor8x8PatternFill = S3SetupForColor8x8PatternFill; 585340e3fbdSmrg pXAA->SubsequentColor8x8PatternFillRect = S3SubsequentColor8x8PatternFillRect; 586bd35f0dbSahoka pXAA->Color8x8PatternFillFlags = NO_TRANSPARENCY | 587bd35f0dbSahoka HARDWARE_PATTERN_SCREEN_ORIGIN | 588bd35f0dbSahoka BIT_ORDER_IN_BYTE_MSBFIRST; 589bd35f0dbSahoka 590bd35f0dbSahoka pXAA->CachePixelGranularity = 0; 591bd35f0dbSahoka#endif 592340e3fbdSmrg 593340e3fbdSmrg#ifdef S3_NEWMMIO 594340e3fbdSmrg pXAA->SetupForCPUToScreenColorExpandFill = 595340e3fbdSmrg S3SetupForCPUToScreenColorExpandFill; 596340e3fbdSmrg pXAA->SubsequentCPUToScreenColorExpandFill = 597340e3fbdSmrg S3SubsequentCPUToScreenColorExpandFill32; 598340e3fbdSmrg pXAA->ColorExpandBase = (void *) &IMG_TRANS; 599340e3fbdSmrg pXAA->ColorExpandRange = 0x8000; 600340e3fbdSmrg pXAA->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD | 601340e3fbdSmrg BIT_ORDER_IN_BYTE_MSBFIRST | 602340e3fbdSmrg SCANLINE_PAD_DWORD; 603340e3fbdSmrg#endif 604340e3fbdSmrg 605340e3fbdSmrg#if 0 606340e3fbdSmrg#ifndef S3_NEWMMIO 607340e3fbdSmrg pXAA->ScanlineImageWriteFlags = NO_TRANSPARENCY; 608340e3fbdSmrg pXAA->SetupForScanlineImageWrite = 609340e3fbdSmrg S3SetupForScanlineImageWriteNoMMIO; 610340e3fbdSmrg pXAA->SubsequentScanlineImageWriteRect = 611340e3fbdSmrg S3SubsequentScanlineImageWriteRectNoMMIO; 612340e3fbdSmrg pXAA->SubsequentImageWriteScanline = 613340e3fbdSmrg S3SubsequentImageWriteScanlineNoMMIO; 614340e3fbdSmrg pXAA->NumScanlineImageWriteBuffers = 1; 615340e3fbdSmrg pXAA->ScanlineImageWriteBuffers = &pS3->imageBuffer; 616340e3fbdSmrg#endif 617340e3fbdSmrg#endif 618340e3fbdSmrg 619340e3fbdSmrg pXAA->SetupForSolidLine = S3SetupForSolidLine; 620340e3fbdSmrg pXAA->SubsequentSolidBresenhamLine = S3SubsequentSolidBresenhamLine; 621340e3fbdSmrg pXAA->SubsequentSolidHorVertLine = S3SubsequentSolidHorVertLine; 622340e3fbdSmrg pXAA->SolidBresenhamLineErrorTermBits = 12; 623340e3fbdSmrg#if 0 624340e3fbdSmrg /* kinda buggy... and its faster without it */ 625340e3fbdSmrg pXAA->SetupForDashedLine = S3SetupForDashedLine; 626340e3fbdSmrg pXAA->SubsequentDashedBresenhamLine = S3SubsequentDashedBresenhamLine32; 627340e3fbdSmrg pXAA->DashPatternMaxLength = MAX_LINE_PATTERN_LENGTH; 628340e3fbdSmrg#endif 629340e3fbdSmrg 630340e3fbdSmrg return XAAInit(pScreen, pXAA); 631b27e1915Smrg#else 632b27e1915Smrg return FALSE; 633b27e1915Smrg#endif 634340e3fbdSmrg} 635