|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: bitblt.c ! 3: * ! 4: * Banked Frame Buffer bitblit ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: * ! 8: \**************************************************************************/ ! 9: ! 10: #include "driver.h" ! 11: ! 12: #define SRCBM_CACHE 1 ! 13: ! 14: BOOL bTest = FALSE; ! 15: ! 16: ULONG nColorBrushes, ! 17: nColorBrushCacheHit, ! 18: nColorBrushExpansionCacheHit, ! 19: nColorBrushCacheInvalidations; ! 20: ! 21: ULONG nMonoBrushes, ! 22: nMonoBrushCacheHit, ! 23: nMonoBrushExpansionCacheHit, ! 24: nMonoBrushCacheInvalidations; ! 25: ! 26: ULONG n8BppBitmaps, ! 27: n8BppBmCacheHits; ! 28: ! 29: ULONG n1BppBitmaps, ! 30: n1BppBmCacheHits; ! 31: ! 32: ! 33: extern ULONG nSsbMovedToHostFromSrcBmCache; ! 34: ! 35: BYTE ajMonoPatPlanes[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; ! 36: ! 37: ! 38: /// Define the A vector polynomial bits ! 39: // ! 40: // Each bit corresponds to one of the terms in the polynomial ! 41: // ! 42: // Rop(D,S,P) = a + a D + a S + a P + a DS + a DP + a SP + a DSP ! 43: // 0 d s p ds dp sp dsp ! 44: ! 45: #define AVEC_NOT 0x01 ! 46: #define AVEC_D 0x02 ! 47: #define AVEC_S 0x04 ! 48: #define AVEC_P 0x08 ! 49: #define AVEC_DS 0x10 ! 50: #define AVEC_DP 0x20 ! 51: #define AVEC_SP 0x40 ! 52: #define AVEC_DSP 0x80 ! 53: ! 54: #define AVEC_NEED_SOURCE (AVEC_S | AVEC_DS | AVEC_SP | AVEC_DSP) ! 55: #define AVEC_NEED_PATTERN (AVEC_P | AVEC_DP | AVEC_SP | AVEC_DSP) ! 56: ! 57: #define BB_TARGET_SCREEN 0x0001 ! 58: #define BB_TARGET_ONLY 0x0002 ! 59: #define BB_SOURCE_COPY 0x0004 ! 60: #define BB_PATTERN_COPY 0x0008 ! 61: ! 62: ! 63: /******************************Public*Data*********************************\ ! 64: * ROP translation table ! 65: * ! 66: * Translates the usual ternary rop into A-vector notation. Each bit in ! 67: * this new notation corresponds to a term in a polynomial translation of ! 68: * the rop. ! 69: * ! 70: * Rop(D,S,P) = a + a D + a S + a P + a DS + a DP + a SP + a DSP ! 71: * 0 d s p ds dp sp dsp ! 72: \**************************************************************************/ ! 73: ! 74: BYTE gajRop[] = ! 75: { ! 76: 0x00, 0xff, 0xb2, 0x4d, 0xd4, 0x2b, 0x66, 0x99, ! 77: 0x90, 0x6f, 0x22, 0xdd, 0x44, 0xbb, 0xf6, 0x09, ! 78: 0xe8, 0x17, 0x5a, 0xa5, 0x3c, 0xc3, 0x8e, 0x71, ! 79: 0x78, 0x87, 0xca, 0x35, 0xac, 0x53, 0x1e, 0xe1, ! 80: 0xa0, 0x5f, 0x12, 0xed, 0x74, 0x8b, 0xc6, 0x39, ! 81: 0x30, 0xcf, 0x82, 0x7d, 0xe4, 0x1b, 0x56, 0xa9, ! 82: 0x48, 0xb7, 0xfa, 0x05, 0x9c, 0x63, 0x2e, 0xd1, ! 83: 0xd8, 0x27, 0x6a, 0x95, 0x0c, 0xf3, 0xbe, 0x41, ! 84: 0xc0, 0x3f, 0x72, 0x8d, 0x14, 0xeb, 0xa6, 0x59, ! 85: 0x50, 0xaf, 0xe2, 0x1d, 0x84, 0x7b, 0x36, 0xc9, ! 86: 0x28, 0xd7, 0x9a, 0x65, 0xfc, 0x03, 0x4e, 0xb1, ! 87: 0xb8, 0x47, 0x0a, 0xf5, 0x6c, 0x93, 0xde, 0x21, ! 88: 0x60, 0x9f, 0xd2, 0x2d, 0xb4, 0x4b, 0x06, 0xf9, ! 89: 0xf0, 0x0f, 0x42, 0xbd, 0x24, 0xdb, 0x96, 0x69, ! 90: 0x88, 0x77, 0x3a, 0xc5, 0x5c, 0xa3, 0xee, 0x11, ! 91: 0x18, 0xe7, 0xaa, 0x55, 0xcc, 0x33, 0x7e, 0x81, ! 92: 0x80, 0x7f, 0x32, 0xcd, 0x54, 0xab, 0xe6, 0x19, ! 93: 0x10, 0xef, 0xa2, 0x5d, 0xc4, 0x3b, 0x76, 0x89, ! 94: 0x68, 0x97, 0xda, 0x25, 0xbc, 0x43, 0x0e, 0xf1, ! 95: 0xf8, 0x07, 0x4a, 0xb5, 0x2c, 0xd3, 0x9e, 0x61, ! 96: 0x20, 0xdf, 0x92, 0x6d, 0xf4, 0x0b, 0x46, 0xb9, ! 97: 0xb0, 0x4f, 0x02, 0xfd, 0x64, 0x9b, 0xd6, 0x29, ! 98: 0xc8, 0x37, 0x7a, 0x85, 0x1c, 0xe3, 0xae, 0x51, ! 99: 0x58, 0xa7, 0xea, 0x15, 0x8c, 0x73, 0x3e, 0xc1, ! 100: 0x40, 0xbf, 0xf2, 0x0d, 0x94, 0x6b, 0x26, 0xd9, ! 101: 0xd0, 0x2f, 0x62, 0x9d, 0x04, 0xfb, 0xb6, 0x49, ! 102: 0xa8, 0x57, 0x1a, 0xe5, 0x7c, 0x83, 0xce, 0x31, ! 103: 0x38, 0xc7, 0x8a, 0x75, 0xec, 0x13, 0x5e, 0xa1, ! 104: 0xe0, 0x1f, 0x52, 0xad, 0x34, 0xcb, 0x86, 0x79, ! 105: 0x70, 0x8f, 0xc2, 0x3d, 0xa4, 0x5b, 0x16, 0xe9, ! 106: 0x08, 0xf7, 0xba, 0x45, 0xdc, 0x23, 0x6e, 0x91, ! 107: 0x98, 0x67, 0x2a, 0xd5, 0x4c, 0xb3, 0xfe, 0x01 ! 108: }; ! 109: ! 110: BOOL b8BppHostToScrnCachedWithRop( ! 111: SURFOBJ *psoTrg, ! 112: SURFOBJ *psoSrc, ! 113: CLIPOBJ *pco, ! 114: XLATEOBJ *pxlo, ! 115: RECTL *prclTrg, ! 116: POINTL *pptlSrc, ! 117: WORD s3Rop); ! 118: ! 119: BOOL b1BppHostToScrnCachedWithRop( ! 120: SURFOBJ *psoTrg, ! 121: SURFOBJ *psoSrc, ! 122: CLIPOBJ *pco, ! 123: XLATEOBJ *pxlo, ! 124: RECTL *prclTrg, ! 125: POINTL *pptlSrc, ! 126: WORD s3Rop); ! 127: ! 128: BOOL b8BppHostToScrnWithRop( ! 129: SURFOBJ *psoTrg, ! 130: SURFOBJ *psoSrc, ! 131: CLIPOBJ *pco, ! 132: XLATEOBJ *pxlo, ! 133: RECTL *prclTrg, ! 134: POINTL *pptlSrc, ! 135: WORD s3Rop); ! 136: ! 137: VOID vLowLevel8BppHostToScrnWithRop( ! 138: PPDEV ppdev, ! 139: PPOINT pptTrg, ! 140: PSIZE psizBlt, ! 141: PWORD pwFirstWord, ! 142: INT lSrcDelta, ! 143: XLATEOBJ *pxlo, ! 144: WORD s3Rop); ! 145: ! 146: BOOL b1BppHostToScrnWithRop( ! 147: SURFOBJ *psoTrg, ! 148: SURFOBJ *psoSrc, ! 149: CLIPOBJ *pco, ! 150: XLATEOBJ *pxlo, ! 151: RECTL *prclTrg, ! 152: POINTL *pptlSrc, ! 153: WORD s3Rop); ! 154: ! 155: VOID vLowLevel1BppHostToScrnWithRop( ! 156: PPDEV ppdev, ! 157: PPOINT pptTrg, ! 158: PSIZE psizBlt, ! 159: INT xSrc, ! 160: PWORD pwFirstWord, ! 161: INT lSrcDelta, ! 162: XLATEOBJ *pxlo, ! 163: WORD s3Rop); ! 164: ! 165: BOOL b4BppHostToScrnWithRop( ! 166: SURFOBJ *psoTrg, ! 167: SURFOBJ *psoSrc, ! 168: CLIPOBJ *pco, ! 169: XLATEOBJ *pxlo, ! 170: RECTL *prclTrg, ! 171: POINTL *pptlSrc, ! 172: WORD s3Rop); ! 173: ! 174: ! 175: VOID vLowLevel4BppHostToScrnWithRop( ! 176: PPDEV ppdev, ! 177: PPOINT pptTrg, ! 178: PSIZE psizBlt, ! 179: INT xSrc, ! 180: PWORD pwFirstWord, ! 181: INT lSrcDelta, ! 182: XLATEOBJ *pxlo, ! 183: WORD s3Rop); ! 184: ! 185: ! 186: WORD wXlateSrcRop3toS3Rop(PPDEV pdev, WORD rop3); ! 187: ! 188: ROP4 bXlatePatRop4toS3Rop( ! 189: PPDEV pdev, ! 190: ROP4 rop4); ! 191: ! 192: BOOL bDownLoadBrushIntoColorCache( ! 193: PPDEV ppdev, ! 194: PS3BRUSH ps3Brush, ! 195: PPOINT ppt); ! 196: ! 197: BOOL bDownLoadBrushIntoMonoCache( ! 198: PPDEV ppdev, ! 199: PS3BRUSH p3Brush, ! 200: PXYZPOINT pxyzPt); ! 201: ! 202: BOOL bExpandColorBrushIntoHorzCache( ! 203: PPDEV ppdev, ! 204: PPOINT ppt); ! 205: ! 206: BOOL bExpandMonoBrushIntoHorzCache( ! 207: PPDEV ppdev, ! 208: PXYZPOINT pxyzPtl, ! 209: INT zHorz); ! 210: ! 211: BOOL bExpandColorBrushIntoVertCache( ! 212: PPDEV ppdev, ! 213: PPOINT ppt); ! 214: ! 215: BOOL bExpandMonoBrushIntoVertCache( ! 216: PPDEV ppdev, ! 217: PXYZPOINT pxyzPt, ! 218: INT zVert); ! 219: ! 220: BOOL bColorHorzCacheToScreen( ! 221: PPDEV ppdev, ! 222: PS3BRUSH ps3Brush, ! 223: PPOINT pptBrushOrg, ! 224: PPOINT pptDest, ! 225: PSIZE psizDest, ! 226: WORD s3ForeRop, ! 227: WORD s3BackRop); ! 228: ! 229: BOOL bColorExpandHorzCacheToScreen( ! 230: PPDEV ppdev, ! 231: PS3BRUSH ps3Brush, ! 232: INT zHorz, ! 233: PPOINT pptBrushOrg, ! 234: PPOINT pptDest, ! 235: PSIZE psizDest, ! 236: WORD s3ForeRop, ! 237: WORD s3BackRop); ! 238: ! 239: BOOL bCpyColorHorzCacheToScreen( ! 240: PPDEV ppdev, ! 241: PS3BRUSH ps3Brush, ! 242: PPOINT pptBrushOrg, ! 243: PPOINT pptDest, ! 244: PSIZE psizDest); ! 245: ! 246: BOOL bCpyColorExpandHorzCacheToScreen( ! 247: PPDEV ppdev, ! 248: PS3BRUSH ps3Brush, ! 249: INT zHorz, ! 250: PPOINT pptBrushOrg, ! 251: PPOINT pptDest, ! 252: PSIZE psizDest); ! 253: ! 254: BOOL bColorVertCacheToScreen( ! 255: PPDEV ppdev, ! 256: PS3BRUSH ps3Brush, ! 257: PPOINT pptBrushOrg, ! 258: PPOINT pptDest, ! 259: PSIZE psizDest, ! 260: WORD s3ForeRop, ! 261: WORD s3BackRop); ! 262: ! 263: BOOL bColorExpandVertCacheToScreen( ! 264: PPDEV ppdev, ! 265: PS3BRUSH ps3Brush, ! 266: INT zHorz, ! 267: PPOINT pptBrushOrg, ! 268: PPOINT pptDest, ! 269: PSIZE psizDest, ! 270: WORD s3ForeRop, ! 271: WORD s3BackRop); ! 272: ! 273: ! 274: BOOL bPuntBlit( ! 275: SURFOBJ *psoTrg, ! 276: SURFOBJ *psoSrc, ! 277: SURFOBJ *psoMask, ! 278: CLIPOBJ *pco, ! 279: XLATEOBJ *pxlo, ! 280: RECTL *prclTrg, ! 281: POINTL *pptlSrc, ! 282: POINTL *pptlMask, ! 283: BRUSHOBJ *pbo, ! 284: POINTL *pptlBrush, ! 285: ROP4 rop4); ! 286: ! 287: BOOL bScrnToScrnPuntBlit( ! 288: SURFOBJ *psoTrg, ! 289: SURFOBJ *psoSrc, ! 290: SURFOBJ *psoMask, ! 291: CLIPOBJ *pco, ! 292: XLATEOBJ *pxlo, ! 293: RECTL *prclTrg, ! 294: POINTL *pptlSrc, ! 295: POINTL *pptlMask, ! 296: BRUSHOBJ *pbo, ! 297: POINTL *pptlBrush, ! 298: ROP4 rop4); ! 299: ! 300: ! 301: BOOL bSpecialBlits( ! 302: SURFOBJ *psoTrg, ! 303: SURFOBJ *psoSrc, ! 304: SURFOBJ *psoMask, ! 305: CLIPOBJ *pco, ! 306: XLATEOBJ *pxlo, ! 307: RECTL *prclTrg, ! 308: POINTL *pptlSrc, ! 309: POINTL *pptlMask, ! 310: BRUSHOBJ *pbo, ! 311: POINTL *pptlBrush, ! 312: ROP4 rop4); ! 313: ! 314: BOOL bScrnToScrnWithRop( ! 315: SURFOBJ *psoTrg, ! 316: SURFOBJ *psoSrc, ! 317: CLIPOBJ *pco, ! 318: RECTL *prclTrg, ! 319: POINTL *pptlSrc, ! 320: WORD s3Rop); ! 321: ! 322: ! 323: VOID S3ScrnToScrnBlt( ! 324: PPDEV ppdev, ! 325: INT xSrc, ! 326: INT ySrc, ! 327: INT xTrg, ! 328: INT yTrg, ! 329: INT width, ! 330: INT height, ! 331: WORD s3Rop, ! 332: WORD Cmd); ! 333: ! 334: BOOL bPatternSolid( ! 335: SURFOBJ *psoTrg, ! 336: SURFOBJ *psoSrc, ! 337: SURFOBJ *psoMask, ! 338: CLIPOBJ *pco, ! 339: XLATEOBJ *pxlo, ! 340: RECTL *prclTrg, ! 341: POINTL *pptlSrc, ! 342: POINTL *pptlMask, ! 343: BRUSHOBJ *pbo, ! 344: POINTL *pptlBrush, ! 345: ROP4 rop4); ! 346: ! 347: VOID vS3SolidPattern( ! 348: PPDEV ppdev, ! 349: INT left, ! 350: INT top, ! 351: INT width, ! 352: INT height, ! 353: INT color, ! 354: WORD s3Mix); ! 355: ! 356: ! 357: BOOL bPatternBrush( ! 358: SURFOBJ *psoTrg, ! 359: CLIPOBJ *pco, ! 360: RECTL *prclTrg, ! 361: BRUSHOBJ *pbo, ! 362: POINTL *pptlBrush, ! 363: ROP4 rop4); ! 364: ! 365: ! 366: ! 367: /***************************************************************************** ! 368: * S3 (Banked Frame Buffer) DrvCopyBits ! 369: * ! 370: * An I/O through the transfer register take 43 clocks. ! 371: * A Memory access on the S3 takes 23 clocks, the memory window wins, ! 372: * so this transfers bits through the memory window for some things. ! 373: ****************************************************************************/ ! 374: BOOL DrvCopyBits( ! 375: SURFOBJ *psoDest, ! 376: SURFOBJ *psoSrc, ! 377: CLIPOBJ *pco, ! 378: XLATEOBJ *pxlo, ! 379: RECTL *prclDest, ! 380: POINTL *pptlSrc) ! 381: { ! 382: #if defined(_X86_) || defined(i386) ! 383: ! 384: INT cy; ! 385: RECTL rclScans; ! 386: RECTL rclDest, rclTmp; ! 387: SURFOBJ *pso; ! 388: PPDEV ppdev; ! 389: BOOL bRet, bResetBounds; ! 390: ! 391: DISPDBG((3,"S3.DLL!DrvCopyBits - Entry\n")); ! 392: ! 393: bResetBounds = FALSE; ! 394: ! 395: rclDest = *prclDest; ! 396: ! 397: cy = prclDest->bottom - prclDest->top; ! 398: ! 399: if (psoDest->iType == STYPE_DEVICE) ! 400: { ! 401: ppdev = (PPDEV) psoDest->dhsurf; ! 402: ! 403: GPWAIT(); ! 404: ! 405: if (pco == NULL) ! 406: pco = ppdev->pcoDefault; ! 407: ! 408: if (psoSrc->iType == STYPE_DEVICE) ! 409: { ! 410: // At this point we know it's a screen to screen copy. ! 411: // If a color translation needs to be applied then go through ScrnToScrnPuntBlit ! 412: ! 413: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) ! 414: { ! 415: bScrnToScrnWithRop(psoDest, psoSrc, pco, prclDest, pptlSrc, OVERPAINT); ! 416: return (TRUE); ! 417: } ! 418: else ! 419: { ! 420: bRet = bScrnToScrnPuntBlit(psoDest, ! 421: psoSrc, ! 422: NULL, ! 423: pco, ! 424: pxlo, ! 425: prclDest, ! 426: pptlSrc, ! 427: NULL, ! 428: NULL, ! 429: NULL, ! 430: 0x0000CCCC); ! 431: ! 432: return (bRet); ! 433: } ! 434: } ! 435: ! 436: else if (psoSrc->lDelta < 0) ! 437: { ! 438: rclScans.top = prclDest->top; ! 439: rclScans.bottom = rclScans.top + cy; ! 440: ! 441: pso = ppdev->pSurfObj; ! 442: psoDest = pso; ! 443: bBankEnumStart(ppdev, &rclScans, pso, pco); ! 444: } ! 445: ! 446: else ! 447: { ! 448: switch (psoSrc->iBitmapFormat) ! 449: { ! 450: case BMF_DEVICE: ! 451: case BMF_8BPP: ! 452: bRet = b8BppHostToScrnCachedWithRop(psoDest, psoSrc, ! 453: pco, pxlo, ! 454: prclDest, pptlSrc, ! 455: OVERPAINT); ! 456: break; ! 457: ! 458: case BMF_1BPP: ! 459: bRet = b1BppHostToScrnCachedWithRop(psoDest, psoSrc, ! 460: pco, pxlo, ! 461: prclDest, pptlSrc, ! 462: OVERPAINT); ! 463: break; ! 464: ! 465: case BMF_4BPP: ! 466: bRet = b4BppHostToScrnWithRop(psoDest, psoSrc, pco, pxlo, ! 467: prclDest, pptlSrc, OVERPAINT); ! 468: break; ! 469: ! 470: case BMF_16BPP: ! 471: case BMF_24BPP: ! 472: case BMF_32BPP: ! 473: case BMF_4RLE: ! 474: case BMF_8RLE: ! 475: default: ! 476: bRet = FALSE; ! 477: } ! 478: ! 479: if (bRet == TRUE) ! 480: { ! 481: return (TRUE); ! 482: } ! 483: ! 484: rclScans.top = prclDest->top; ! 485: rclScans.bottom = rclScans.top + cy; ! 486: ! 487: pso = ppdev->pSurfObj; ! 488: psoDest = pso; ! 489: bBankEnumStart(ppdev, &rclScans, pso, pco); ! 490: } ! 491: } ! 492: else ! 493: { ! 494: rclScans.top = pptlSrc->y; ! 495: rclScans.bottom = pptlSrc->y + cy; ! 496: ! 497: ppdev = (PPDEV) psoSrc->dhsurf; ! 498: ! 499: GPWAIT(); ! 500: ! 501: if (pco == NULL) ! 502: { ! 503: pco = ppdev->pcoDefault; ! 504: ! 505: // BUGBUG: This mucking around with pcoDefaults's rclBounds is ! 506: // no longer required by bSrcBankEnumStart: ! 507: ! 508: rclTmp = pco->rclBounds; ! 509: pco->rclBounds = *prclDest; ! 510: bResetBounds = TRUE; ! 511: } ! 512: ! 513: pso = ppdev->pSurfObj; ! 514: psoSrc = pso; ! 515: bSrcBankEnumStart(ppdev, &rclScans, pso, pco, prclDest); ! 516: } ! 517: ! 518: do ! 519: { ! 520: bRet = EngCopyBits(psoDest, psoSrc, pco, pxlo, &rclDest, pptlSrc); ! 521: ! 522: } while (bRet && (bBankEnum(ppdev, &rclScans, pso, pco))); ! 523: ! 524: bBankEnumEnd(ppdev, pso, pco); ! 525: ! 526: if (bResetBounds) ! 527: { ! 528: ppdev->pcoDefault->rclBounds = rclTmp; ! 529: } ! 530: ! 531: return(bRet); ! 532: ! 533: #else ! 534: ! 535: // A DrvCopyBits is just a simplified DrvBitBlt: ! 536: ! 537: return(DrvBitBlt(psoDest, ! 538: psoSrc, ! 539: NULL, // psoMask ! 540: pco, ! 541: pxlo, ! 542: prclDest, ! 543: pptlSrc, ! 544: NULL, // pptlMask ! 545: NULL, // pbo ! 546: NULL, // pptlBrush ! 547: 0x0000CCCC)); // mix = SRCCOPY ! 548: ! 549: #endif ! 550: } ! 551: ! 552: ! 553: ! 554: ! 555: /***************************************************************************** ! 556: * S3 DrvBitBlt ! 557: ****************************************************************************/ ! 558: BOOL DrvBitBlt( ! 559: SURFOBJ *psoTrg, ! 560: SURFOBJ *psoSrc, ! 561: SURFOBJ *psoMask, ! 562: CLIPOBJ *pco, ! 563: XLATEOBJ *pxlo, ! 564: RECTL *prclTrg, ! 565: POINTL *pptlSrc, ! 566: POINTL *pptlMask, ! 567: BRUSHOBJ *pbo, ! 568: POINTL *pptlBrush, ! 569: ROP4 rop4) ! 570: ! 571: { ! 572: BOOL b; ! 573: PPDEV ppdev; ! 574: ! 575: DISPDBG((3,"S3.DLL!DrvBitBlt - Entry\n")); ! 576: ! 577: // Since we don't support Device-Format Bitmaps, either the source ! 578: // or the destination (or both) will be the device surface: ! 579: ! 580: if (psoTrg->iType == STYPE_DEVICE) ! 581: ppdev = (PPDEV) psoTrg->dhpdev; ! 582: else ! 583: ppdev = (PPDEV) psoSrc->dhpdev; ! 584: ! 585: // Protect the driver from a potentially NULL clip object. ! 586: ! 587: if (pco == NULL) ! 588: { ! 589: pco = ppdev->pcoDefault; ! 590: } ! 591: ! 592: if (bTest == FALSE) ! 593: { ! 594: b = bSpecialBlits(psoTrg, psoSrc, psoMask, ! 595: pco, pxlo, ! 596: prclTrg, pptlSrc, pptlMask, ! 597: pbo, pptlBrush, ! 598: rop4); ! 599: } ! 600: else ! 601: { ! 602: b = FALSE; ! 603: } ! 604: ! 605: if (b != TRUE) ! 606: { ! 607: bPuntBlit(psoTrg, ! 608: psoSrc, ! 609: psoMask, ! 610: pco, ! 611: pxlo, ! 612: prclTrg, ! 613: pptlSrc, ! 614: pptlMask, ! 615: pbo, ! 616: pptlBrush, ! 617: rop4); ! 618: } ! 619: ! 620: return (TRUE); ! 621: } ! 622: ! 623: /***************************************************************************** ! 624: * S3 General purpose blit handler. This routine will handle any blit. ! 625: * Albeit slow, but it will be handled. ! 626: * ! 627: * Returns TRUE if the blit was handled. ! 628: ****************************************************************************/ ! 629: BOOL bPuntBlit( ! 630: SURFOBJ *psoTrg, ! 631: SURFOBJ *psoSrc, ! 632: SURFOBJ *psoMask, ! 633: CLIPOBJ *pco, ! 634: XLATEOBJ *pxlo, ! 635: RECTL *prclTrg, ! 636: POINTL *pptlSrc, ! 637: POINTL *pptlMask, ! 638: BRUSHOBJ *pbo, ! 639: POINTL *pptlBrush, ! 640: ROP4 rop4) ! 641: { ! 642: ! 643: ! 644: #if defined(_X86_) || defined(i386) ! 645: ! 646: RECTL rclScans; ! 647: RECTL rclTrg; ! 648: PPDEV ppdevTrg, ppdevSrc, ppdevBank; ! 649: SURFOBJ *psoBank; ! 650: BOOL bRet; ! 651: PPDEV ppdev; ! 652: ! 653: DISPDBG((2,"S3.DLL!bPuntBlit - Entry\n")); ! 654: ! 655: if (psoTrg->iType == STYPE_DEVICE) ! 656: ppdev = (PPDEV) psoTrg->dhsurf; ! 657: else ! 658: ppdev = (PPDEV) psoSrc->dhsurf; ! 659: ! 660: // Wait for the S3 coprocessor to finish with the VRAM before we touch it through ! 661: // the apperature. ! 662: ! 663: GPWAIT(); ! 664: ! 665: rclTrg = *prclTrg; ! 666: ! 667: rclScans.top = prclTrg->top; ! 668: rclScans.bottom = prclTrg->bottom; ! 669: ! 670: // Get the correct surface object for the target and the source ! 671: ! 672: if ((psoTrg->iType == STYPE_DEVICE) && ! 673: ((psoSrc == NULL) || (psoSrc->iType != STYPE_DEVICE))) ! 674: { ! 675: ppdevTrg = (PPDEV) psoTrg->dhsurf; ! 676: psoTrg = ppdevTrg->pSurfObj; ! 677: ! 678: bBankEnumStart(ppdevTrg, &rclScans, psoTrg, pco); ! 679: ppdevBank = ppdevTrg; ! 680: psoBank = psoTrg; ! 681: ! 682: } ! 683: ! 684: else if ((psoTrg->iType != STYPE_DEVICE) && ! 685: (psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE)) ! 686: { ! 687: ppdevSrc = (PPDEV) psoSrc->dhsurf; ! 688: psoSrc = ppdevSrc->pSurfObj; ! 689: ! 690: rclScans.top = pptlSrc->y; ! 691: rclScans.bottom = pptlSrc->y + (prclTrg->bottom - prclTrg->top); ! 692: ! 693: bSrcBankEnumStart(ppdevSrc, &rclScans, psoSrc, pco, prclTrg); ! 694: ppdevBank = ppdevSrc; ! 695: psoBank = psoSrc; ! 696: ! 697: } ! 698: else ! 699: { ! 700: bRet = bScrnToScrnPuntBlit(psoTrg, ! 701: psoSrc, ! 702: psoMask, ! 703: pco, ! 704: pxlo, ! 705: prclTrg, ! 706: pptlSrc, ! 707: pptlMask, ! 708: pbo, ! 709: pptlBrush, ! 710: rop4); ! 711: return (bRet); ! 712: } ! 713: ! 714: do ! 715: { ! 716: bRet = EngBitBlt(psoTrg, ! 717: psoSrc, ! 718: psoMask, ! 719: pco, ! 720: pxlo, ! 721: &rclTrg, ! 722: pptlSrc, ! 723: pptlMask, ! 724: pbo, ! 725: pptlBrush, ! 726: rop4); ! 727: ! 728: } while ((bBankEnum(ppdevBank, &rclScans, psoBank, pco)) && bRet); ! 729: ! 730: bBankEnumEnd(ppdevBank, psoBank, pco); ! 731: ! 732: return bRet; ! 733: ! 734: #else ! 735: ! 736: BOOL bRet; ! 737: PPDEV ppdev; ! 738: RECTL rclSrc; ! 739: ! 740: if (psoTrg->iType == STYPE_DEVICE) ! 741: { ! 742: ppdev = (PPDEV) psoTrg->dhsurf; ! 743: ! 744: if ((psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE)) ! 745: { ! 746: // ------------------------------------------------------- ! 747: // Handle screen-to-screen blit: ! 748: ! 749: // We have to copy both the source rectangle and the destination ! 750: // rectangle to the temporary bitmap (the destination rectangle ! 751: // is needed if there's complex clipping or if there's a ROP that ! 752: // affects need the destination). ! 753: // ! 754: // We simply copy the smallest entire rectangle containing both ! 755: // the source and the destination rectangles: ! 756: ! 757: rclSrc.left = min(pptlSrc->x, prclTrg->left); ! 758: rclSrc.top = min(pptlSrc->y, prclTrg->top); ! 759: rclSrc.right = max(pptlSrc->x + prclTrg->right - prclTrg->left, ! 760: prclTrg->right); ! 761: rclSrc.bottom = max(pptlSrc->y + prclTrg->bottom - prclTrg->top, ! 762: prclTrg->bottom); ! 763: ! 764: vPuntGetBits(ppdev, psoSrc, &rclSrc); ! 765: ! 766: // Now do the copy entirely on the temporary bitmap surface: ! 767: ! 768: bRet = EngBitBlt(ppdev->psoTemp, ! 769: ppdev->psoTemp, ! 770: psoMask, ! 771: pco, ! 772: pxlo, ! 773: prclTrg, ! 774: pptlSrc, ! 775: pptlMask, ! 776: pbo, ! 777: pptlBrush, ! 778: rop4); ! 779: ! 780: // Just have to copy the destination back to the surface: ! 781: ! 782: if (bRet) ! 783: { ! 784: vPuntPutBits(ppdev, psoTrg, prclTrg); ! 785: } ! 786: } ! 787: else ! 788: { ! 789: // ------------------------------------------------------- ! 790: // Handle bitmap-to-screen blit: ! 791: ! 792: // Make a copy of the destination rectangle in case the ROP ! 793: // modifies the destination: ! 794: ! 795: vPuntGetBits(ppdev, psoTrg, prclTrg); ! 796: ! 797: // Do the blit operation on the temporary bitmap: ! 798: ! 799: bRet = EngBitBlt(ppdev->psoTemp, ! 800: psoSrc, ! 801: psoMask, ! 802: pco, ! 803: pxlo, ! 804: prclTrg, ! 805: pptlSrc, ! 806: pptlMask, ! 807: pbo, ! 808: pptlBrush, ! 809: rop4); ! 810: ! 811: // Copy everything back to the surface: ! 812: ! 813: if (bRet) ! 814: { ! 815: vPuntPutBits(ppdev, psoTrg, prclTrg); ! 816: } ! 817: } ! 818: } ! 819: else ! 820: { ! 821: // ------------------------------------------------------- ! 822: // Handle screen-to-bitmap blit: ! 823: ! 824: ppdev = (PPDEV) psoSrc->dhsurf; ! 825: ! 826: // Copy the source rectangle to the temporary bitmap, then get ! 827: // GDI to blit to the target surface: ! 828: ! 829: rclSrc.left = pptlSrc->x; ! 830: rclSrc.top = pptlSrc->y; ! 831: rclSrc.right = pptlSrc->x + (prclTrg->right - prclTrg->left); ! 832: rclSrc.bottom = pptlSrc->y + (prclTrg->bottom - prclTrg->top); ! 833: ! 834: vPuntGetBits(ppdev, psoSrc, &rclSrc); ! 835: ! 836: bRet = EngBitBlt(psoTrg, ! 837: ppdev->psoTemp, ! 838: psoMask, ! 839: pco, ! 840: pxlo, ! 841: prclTrg, ! 842: pptlSrc, ! 843: pptlMask, ! 844: pbo, ! 845: pptlBrush, ! 846: rop4); ! 847: } ! 848: ! 849: vResetS3Clipping(ppdev); // Always reset after using vPunt routines ! 850: ! 851: return(bRet); ! 852: ! 853: #endif ! 854: } ! 855: ! 856: /****************************************************************************** ! 857: * bScrnToScrnPuntBlit - Screen To Screen Punt Blit ! 858: *****************************************************************************/ ! 859: BOOL bScrnToScrnPuntBlit( ! 860: SURFOBJ *psoTrg, ! 861: SURFOBJ *psoSrc, ! 862: SURFOBJ *psoMask, ! 863: CLIPOBJ *pco, ! 864: XLATEOBJ *pxlo, ! 865: RECTL *prclTrg, ! 866: POINTL *pptlSrc, ! 867: POINTL *pptlMask, ! 868: BRUSHOBJ *pbo, ! 869: POINTL *pptlBrush, ! 870: ROP4 rop4) ! 871: { ! 872: ! 873: SIZEL sizl; ! 874: HSURF hsurfBm; ! 875: SURFOBJ *psoTempSrc; ! 876: WORD cmd; ! 877: INT i, cxInWords; ! 878: PBYTE pb; ! 879: PWORD pw; ! 880: PPDEV ppdev; ! 881: RECTL rclScans, rclTrg; ! 882: BOOL bRet; ! 883: POINTL ptlTempSrc; ! 884: ! 885: DISPDBG((2,"S3.DLL!bScrnToScrnPuntBlit - Entry\n")); ! 886: ! 887: // Pickup our pdev and a pointer to the surface object. ! 888: ! 889: ppdev = (PPDEV) psoTrg->dhsurf; ! 890: psoTrg = ppdev->pSurfObj; ! 891: ! 892: // Set the default bounding rectangle for the bank manager. ! 893: ! 894: rclTrg = *prclTrg; ! 895: ! 896: // Create a temporary surface and bitmap. ! 897: ! 898: sizl.cx = prclTrg->right - prclTrg->left; ! 899: sizl.cy = prclTrg->bottom - prclTrg->top; ! 900: ! 901: hsurfBm = (HSURF) EngCreateBitmap(sizl, ! 902: sizl.cx, ! 903: BMF_8BPP, ! 904: BMF_TOPDOWN, ! 905: NULL); ! 906: if (hsurfBm == NULL) ! 907: { ! 908: DISPDBG((0, "S3.DLL!bScrnToScrnPuntBlit - EngCreateBitmap failed\n")); ! 909: return(FALSE); ! 910: } ! 911: ! 912: // Get a pointer to the surface object. ! 913: ! 914: psoTempSrc = EngLockSurface(hsurfBm); ! 915: ! 916: // Copy the bits into it. ! 917: ! 918: if (!(sizl.cx & 0x01)) ! 919: { ! 920: cmd = RECTANGLE_FILL | BYTE_SWAP | BUS_SIZE_16 | ! 921: DRAWING_DIR_TBLRXM | DIR_TYPE_XY | WAIT | ! 922: DRAW | LAST_PIXEL_ON | READ; ! 923: } ! 924: else ! 925: { ! 926: cmd = RECTANGLE_FILL | BUS_SIZE_8 | ! 927: DRAWING_DIR_TBLRXM | DIR_TYPE_XY | WAIT | ! 928: DRAW | LAST_PIXEL_ON | READ; ! 929: } ! 930: ! 931: FIFOWAIT(FIFO_7_EMPTY); ! 932: ! 933: TEST_AND_SET_RD_MASK(0xff); ! 934: OUTPW (MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 935: ! 936: OUTPW (CUR_X, pptlSrc->x); ! 937: OUTPW (CUR_Y, pptlSrc->y); ! 938: OUTPW (RECT_WIDTH, (sizl.cx - 1)); ! 939: OUTPW (MULTIFUNC_CNTL, (RECT_HEIGHT | (sizl.cy - 1))); ! 940: ! 941: GPWAIT(); ! 942: ! 943: OUTPW (CMD, cmd); ! 944: ! 945: // Wait for the Data Available. ! 946: ! 947: while (!(inpw(GP_STAT) & READ_DATA_AVAILABLE)); ! 948: ! 949: // Now transfer the data from the screen to the host memory bitmap. ! 950: ! 951: if (!(sizl.cx & 0x01)) ! 952: { ! 953: cxInWords = (sizl.cx + 1) / 2; ! 954: pw = (PWORD) psoTempSrc->pvScan0; ! 955: for (i = 0; i < sizl.cy; i++) ! 956: { ! 957: vDataPortIn(ppdev, pw, cxInWords); ! 958: ((PBYTE) pw) += psoTempSrc->lDelta; ! 959: } ! 960: } ! 961: else ! 962: { ! 963: pb = psoTempSrc->pvScan0; ! 964: for (i = 0; i < sizl.cy; i++) ! 965: { ! 966: vDataPortInB(ppdev, pb, sizl.cx); ! 967: pb += psoTempSrc->lDelta; ! 968: } ! 969: } ! 970: ! 971: // Set the new source position ! 972: ! 973: ptlTempSrc.x = 0; ! 974: ptlTempSrc.y = 0; ! 975: ! 976: // Do the banked blit operation. ! 977: ! 978: rclScans.top = prclTrg->top; ! 979: rclScans.bottom = prclTrg->bottom; ! 980: ! 981: bBankEnumStart(ppdev, &rclScans, psoTrg, pco); ! 982: ! 983: do ! 984: { ! 985: bRet = EngBitBlt(psoTrg, ! 986: psoTempSrc, ! 987: psoMask, ! 988: pco, ! 989: pxlo, ! 990: &rclTrg, ! 991: &ptlTempSrc, ! 992: pptlMask, ! 993: pbo, ! 994: pptlBrush, ! 995: rop4); ! 996: ! 997: } while ((bBankEnum(ppdev, &rclScans, psoTrg, pco)) && bRet); ! 998: ! 999: bBankEnumEnd(ppdev, psoTrg, pco); ! 1000: ! 1001: // free the temp bitmap. ! 1002: ! 1003: EngUnlockSurface(psoTempSrc); ! 1004: EngDeleteSurface(hsurfBm); ! 1005: ! 1006: return (bRet); ! 1007: ! 1008: } ! 1009: ! 1010: /***************************************************************************** ! 1011: * S3 Special case Blit handler ! 1012: * ! 1013: * Returns TRUE if the blit was handled. ! 1014: ****************************************************************************/ ! 1015: BOOL bSpecialBlits( ! 1016: SURFOBJ *psoTrg, ! 1017: SURFOBJ *psoSrc, ! 1018: SURFOBJ *psoMask, ! 1019: CLIPOBJ *pco, ! 1020: XLATEOBJ *pxlo, ! 1021: RECTL *prclTrg, ! 1022: POINTL *pptlSrc, ! 1023: POINTL *pptlMask, ! 1024: BRUSHOBJ *pbo, ! 1025: POINTL *pptlBrush, ! 1026: ROP4 rop4) ! 1027: { ! 1028: BOOL bRet; ! 1029: PPDEV ppdev; ! 1030: ROP4 s3Rop4; ! 1031: WORD avecRop, s3Rop; ! 1032: BRUSHOBJ bo; ! 1033: ! 1034: bRet = FALSE; ! 1035: ! 1036: if (psoTrg->iType == STYPE_DEVICE) ! 1037: ppdev = (PPDEV) psoTrg->dhsurf; ! 1038: else ! 1039: ppdev = (PPDEV) psoSrc->dhsurf; ! 1040: ! 1041: // NOTE: If the ForeRop and BackRop are the same implicitly ! 1042: // there is no mask. ! 1043: ! 1044: // First test for copy opperations. ! 1045: ! 1046: if (rop4 == 0x0000CCCC) ! 1047: { ! 1048: if ((psoTrg->iType == STYPE_DEVICE) && (psoSrc->iType == STYPE_DEVICE)) ! 1049: { ! 1050: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) ! 1051: { ! 1052: bRet = bScrnToScrnWithRop(psoTrg, psoSrc, pco, prclTrg, pptlSrc, OVERPAINT); ! 1053: return(bRet); ! 1054: } ! 1055: else ! 1056: { ! 1057: return (FALSE); ! 1058: } ! 1059: } ! 1060: ! 1061: } ! 1062: ! 1063: // Check for a mask. If there is one, at this time, reject the ! 1064: // acceleration. ! 1065: ! 1066: if (psoMask != NULL) ! 1067: { ! 1068: return (FALSE); ! 1069: } ! 1070: ! 1071: // If the background and foreground rops are not the same ! 1072: // reject the blit. ! 1073: ! 1074: if (((rop4 & 0xFF00) >> 8) != (rop4 & 0xff)) ! 1075: { ! 1076: return (FALSE); ! 1077: } ! 1078: ! 1079: // Pickup the avec for some quick decision later. ! 1080: ! 1081: avecRop = gajRop[(rop4 & 0xff)]; ! 1082: ! 1083: // Check for a DIB. If this is a DIB reject the blit. ! 1084: // BUGBUG: At some future date (post BETA2) this should be optimized. ! 1085: ! 1086: if ((avecRop & AVEC_NEED_SOURCE) && (psoSrc->lDelta < 0)) ! 1087: { ! 1088: return (FALSE); ! 1089: } ! 1090: ! 1091: // Check for whitness or blackness ! 1092: ! 1093: if (((rop4 & 0xff) == 0xff) || ! 1094: ((rop4 & 0xff) == 0x00)) ! 1095: { ! 1096: if ((rop4 & 0xff) == 0xff) ! 1097: s3Rop4 = LOGICAL_1; ! 1098: else ! 1099: s3Rop4 = LOGICAL_0; ! 1100: ! 1101: bRet = bPatternSolid(psoTrg, psoSrc, psoMask, ! 1102: pco, pxlo, ! 1103: prclTrg, pptlSrc, pptlMask, ! 1104: pbo, pptlBrush, ! 1105: s3Rop4); ! 1106: return (bRet); ! 1107: } ! 1108: ! 1109: // Check for Dest Invert ! 1110: ! 1111: if ((rop4 & 0xff) == 0x55) ! 1112: { ! 1113: s3Rop4 = SCREEN_XOR_NEW; ! 1114: bo.iSolidColor = 0xffff; ! 1115: ! 1116: bRet = bPatternSolid(psoTrg, psoSrc, psoMask, ! 1117: pco, pxlo, ! 1118: prclTrg, pptlSrc, pptlMask, ! 1119: &bo, pptlBrush, ! 1120: s3Rop4); ! 1121: return (bRet); ! 1122: ! 1123: } ! 1124: ! 1125: ! 1126: // Check for brushes. ! 1127: ! 1128: if ((avecRop & AVEC_NEED_PATTERN) && (!(avecRop & AVEC_NEED_SOURCE))) ! 1129: { ! 1130: // Translate the rop from GDI to S3. ! 1131: ! 1132: s3Rop4 = bXlatePatRop4toS3Rop(ppdev, rop4); ! 1133: ! 1134: // Check for a Solid Brush. ! 1135: ! 1136: if (pbo == NULL || pbo->iSolidColor != -1) ! 1137: { ! 1138: bRet = bPatternSolid(psoTrg, psoSrc, psoMask, ! 1139: pco, pxlo, ! 1140: prclTrg, pptlSrc, pptlMask, ! 1141: pbo, pptlBrush, ! 1142: s3Rop4); ! 1143: } ! 1144: ! 1145: // Handle this as a Pattern Brush. ! 1146: ! 1147: else ! 1148: { ! 1149: bRet = bPatternBrush(psoTrg, pco, prclTrg, pbo, pptlBrush, s3Rop4); ! 1150: } ! 1151: ! 1152: } ! 1153: ! 1154: // Check if we may be able to optimize for screen to screen or ! 1155: // host to screen blits. ! 1156: ! 1157: else if ((!(avecRop & AVEC_NEED_PATTERN)) && ! 1158: (avecRop & AVEC_NEED_SOURCE)) ! 1159: { ! 1160: s3Rop = wXlateSrcRop3toS3Rop(ppdev, LOWORD(rop4)); ! 1161: if (s3Rop != 0) ! 1162: { ! 1163: if ((psoTrg->iType == STYPE_DEVICE) && ! 1164: (psoSrc->iType == STYPE_DEVICE) && ! 1165: ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))) ! 1166: { ! 1167: bRet = bScrnToScrnWithRop(psoTrg, psoSrc, pco, prclTrg, ! 1168: pptlSrc, s3Rop); ! 1169: } ! 1170: else if (psoSrc->iType == STYPE_BITMAP) ! 1171: { ! 1172: switch (psoSrc->iBitmapFormat) ! 1173: { ! 1174: case BMF_DEVICE: ! 1175: case BMF_8BPP: ! 1176: bRet = b8BppHostToScrnCachedWithRop(psoTrg, ! 1177: psoSrc, ! 1178: pco, ! 1179: pxlo, ! 1180: prclTrg, ! 1181: pptlSrc, ! 1182: s3Rop); ! 1183: break; ! 1184: ! 1185: case BMF_1BPP: ! 1186: bRet = b1BppHostToScrnCachedWithRop(psoTrg, ! 1187: psoSrc, ! 1188: pco, ! 1189: pxlo, ! 1190: prclTrg, ! 1191: pptlSrc, ! 1192: s3Rop); ! 1193: break; ! 1194: ! 1195: case BMF_4BPP: ! 1196: bRet = b4BppHostToScrnWithRop(psoTrg, ! 1197: psoSrc, ! 1198: pco, ! 1199: pxlo, ! 1200: prclTrg, ! 1201: pptlSrc, ! 1202: s3Rop); ! 1203: break; ! 1204: ! 1205: case BMF_16BPP: ! 1206: case BMF_24BPP: ! 1207: case BMF_32BPP: ! 1208: case BMF_4RLE: ! 1209: case BMF_8RLE: ! 1210: default: ! 1211: bRet = FALSE; ! 1212: break; ! 1213: } ! 1214: } ! 1215: } ! 1216: ! 1217: else ! 1218: { ! 1219: DISPDBG((0,"S3.DLL!bSpecialBlits - Missed SrcBlt opportunity - rop: 0x%x\n", ! 1220: rop4)); ! 1221: } ! 1222: } ! 1223: ! 1224: else if ((rop4 & 0xff) == 0xc0) // Merge Copy ! 1225: { ! 1226: if ((psoTrg->iType == STYPE_DEVICE) && ! 1227: (psoSrc->iType == STYPE_DEVICE) && ! 1228: ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))) ! 1229: ! 1230: { ! 1231: bRet = bScrnToScrnWithRop(psoTrg, psoSrc, ! 1232: pco, prclTrg, pptlSrc, ! 1233: OVERPAINT); ! 1234: ! 1235: if (bRet) ! 1236: { ! 1237: if (pbo == NULL || pbo->iSolidColor != -1) ! 1238: { ! 1239: bRet = bPatternSolid(psoTrg, psoSrc, psoMask, ! 1240: pco, pxlo, ! 1241: prclTrg, pptlSrc, pptlMask, ! 1242: pbo, pptlBrush, ! 1243: SCREEN_AND_NEW); ! 1244: } ! 1245: else ! 1246: { ! 1247: bRet = bPatternBrush(psoTrg, pco, prclTrg, ! 1248: pbo, pptlBrush, ! 1249: (SCREEN_AND_NEW << 8) | SCREEN_AND_NEW); ! 1250: } ! 1251: } ! 1252: } ! 1253: else if (psoSrc->iType == STYPE_BITMAP) ! 1254: { ! 1255: switch (psoSrc->iBitmapFormat) ! 1256: { ! 1257: case BMF_DEVICE: ! 1258: case BMF_8BPP: ! 1259: bRet = b8BppHostToScrnCachedWithRop(psoTrg, ! 1260: psoSrc, ! 1261: pco, ! 1262: pxlo, ! 1263: prclTrg, ! 1264: pptlSrc, ! 1265: OVERPAINT); ! 1266: break; ! 1267: ! 1268: case BMF_1BPP: ! 1269: bRet = b1BppHostToScrnCachedWithRop(psoTrg, ! 1270: psoSrc, ! 1271: pco, ! 1272: pxlo, ! 1273: prclTrg, ! 1274: pptlSrc, ! 1275: OVERPAINT); ! 1276: break; ! 1277: ! 1278: case BMF_4BPP: ! 1279: bRet = b4BppHostToScrnWithRop(psoTrg, ! 1280: psoSrc, ! 1281: pco, ! 1282: pxlo, ! 1283: prclTrg, ! 1284: pptlSrc, ! 1285: OVERPAINT); ! 1286: break; ! 1287: ! 1288: case BMF_16BPP: ! 1289: case BMF_24BPP: ! 1290: case BMF_32BPP: ! 1291: case BMF_4RLE: ! 1292: case BMF_8RLE: ! 1293: default: ! 1294: bRet = FALSE; ! 1295: break; ! 1296: } ! 1297: ! 1298: if (bRet) ! 1299: { ! 1300: if (pbo == NULL || pbo->iSolidColor != -1) ! 1301: { ! 1302: bRet = bPatternSolid(psoTrg, psoSrc, psoMask, ! 1303: pco, pxlo, ! 1304: prclTrg, pptlSrc, pptlMask, ! 1305: pbo, pptlBrush, ! 1306: SCREEN_AND_NEW); ! 1307: } ! 1308: else ! 1309: { ! 1310: bRet = bPatternBrush(psoTrg, pco, prclTrg, ! 1311: pbo, pptlBrush, ! 1312: (SCREEN_AND_NEW << 8) | SCREEN_AND_NEW); ! 1313: } ! 1314: } ! 1315: } ! 1316: } ! 1317: ! 1318: ! 1319: ! 1320: return (bRet); ! 1321: } ! 1322: ! 1323: ! 1324: /***************************************************************************** ! 1325: * S3 Screen to Screen with a Rop ! 1326: * ! 1327: * Returns TRUE if the blit was handled. ! 1328: ****************************************************************************/ ! 1329: BOOL bScrnToScrnWithRop( ! 1330: SURFOBJ *psoTrg, ! 1331: SURFOBJ *psoSrc, ! 1332: CLIPOBJ *pco, ! 1333: RECTL *prclTrg, ! 1334: POINTL *pptlSrc, ! 1335: WORD s3Rop) ! 1336: { ! 1337: INT width, height, xTrg, yTrg, xSrc, ySrc, cx, cy; ! 1338: WORD cmd, wDirCode; ! 1339: RECTL rclSrc, rclTrg; ! 1340: ULONG DirClip; ! 1341: BOOL bMore, bIntersect, bClipRequired; ! 1342: UINT i; ! 1343: ENUMRECTS8 EnumRects8; ! 1344: PPDEV ppdev; ! 1345: RECTL rclBounds; ! 1346: BYTE iDComplexity; ! 1347: ! 1348: // Get the pdev. ! 1349: ! 1350: ppdev = (PPDEV) psoTrg->dhpdev; ! 1351: ! 1352: // There are two completely different code paths. ! 1353: // for the complex and non-complex clip cases. ! 1354: // This is because most of the direction and intersection ! 1355: // calculations need to be done after the clipping. ! 1356: ! 1357: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX) ! 1358: { ! 1359: // Make a copy of the target, since we will have to change ! 1360: // it for clipping. ! 1361: ! 1362: rclTrg = *prclTrg; ! 1363: ! 1364: if (iDComplexity == DC_RECT) ! 1365: { ! 1366: rclBounds = pco->rclBounds; ! 1367: ! 1368: // First handle the trivial rejection. ! 1369: ! 1370: bClipRequired = bIntersectTest(&rclTrg, &rclBounds); ! 1371: ! 1372: // define the clipped target rectangle. ! 1373: ! 1374: if (bClipRequired) ! 1375: { ! 1376: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 1377: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 1378: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 1379: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 1380: } ! 1381: else ! 1382: { ! 1383: // The destination rectangle is completely clipped out, ! 1384: // so just return. ! 1385: ! 1386: return (TRUE); ! 1387: } ! 1388: } ! 1389: ! 1390: // define the cx & cy. ! 1391: ! 1392: width = (rclTrg.right - rclTrg.left) - 1; ! 1393: height = (rclTrg.bottom - rclTrg.top) - 1; ! 1394: ! 1395: // calculate the cx & cy shift for the source. ! 1396: ! 1397: cx = rclTrg.left - prclTrg->left; ! 1398: cy = rclTrg.top - prclTrg->top; ! 1399: ! 1400: // define the source rectangle. ! 1401: ! 1402: rclSrc.left = pptlSrc->x + cx; ! 1403: rclSrc.top = pptlSrc->y + cy; ! 1404: rclSrc.right = pptlSrc->x + width + 1; ! 1405: rclSrc.bottom = pptlSrc->y + height + 1; ! 1406: ! 1407: // Determine the direction of the blit. ! 1408: // First, check for an intersection of the souce and dest rects. ! 1409: ! 1410: bIntersect = bIntersectTest(&rclTrg, &rclSrc); ! 1411: ! 1412: // Set defaults for the S3 blit direction and the ! 1413: // initial coordinates ! 1414: ! 1415: wDirCode = DRAWING_DIR_TBLRXM; ! 1416: ! 1417: xTrg = rclTrg.left; ! 1418: yTrg = rclTrg.top; ! 1419: xSrc = rclSrc.left; ! 1420: ySrc = rclSrc.top; ! 1421: ! 1422: // If the source & dest rects intersect adjust the ! 1423: // blit direction and initial coordinates. ! 1424: ! 1425: if (bIntersect) ! 1426: { ! 1427: // The horizontal copy direction. ! 1428: ! 1429: if (rclTrg.left > rclSrc.left) ! 1430: { ! 1431: // R to L ! 1432: ! 1433: xTrg = rclTrg.right - 1; ! 1434: xSrc = rclSrc.left + width; ! 1435: wDirCode &= ~PLUS_X; ! 1436: } ! 1437: ! 1438: // The vertical copy direction. ! 1439: ! 1440: if (rclTrg.top > rclSrc.top) ! 1441: { ! 1442: // B to T ! 1443: ! 1444: yTrg = rclTrg.bottom - 1; ! 1445: ySrc = rclSrc.top + height; ! 1446: wDirCode &= ~PLUS_Y; ! 1447: } ! 1448: } ! 1449: ! 1450: // Create the S3 Command. ! 1451: ! 1452: cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE; ! 1453: cmd |= wDirCode; ! 1454: ! 1455: // Do the blit. ! 1456: ! 1457: S3ScrnToScrnBlt(ppdev, xSrc, ySrc, xTrg, yTrg, width, height, s3Rop, cmd); ! 1458: ! 1459: } ! 1460: else ! 1461: { ! 1462: // This a complex clip. ! 1463: ! 1464: DirClip = CD_ANY; ! 1465: wDirCode = DRAWING_DIR_TBLRXM; ! 1466: ! 1467: if (prclTrg->left > pptlSrc->x) ! 1468: wDirCode &= ~PLUS_X; ! 1469: ! 1470: if (prclTrg->top > pptlSrc->y) ! 1471: wDirCode &= ~PLUS_Y; ! 1472: ! 1473: switch (wDirCode) ! 1474: { ! 1475: case DRAWING_DIR_TBLRXM: ! 1476: DirClip = CD_RIGHTDOWN; ! 1477: break; ! 1478: ! 1479: case DRAWING_DIR_TBRLXM: ! 1480: DirClip = CD_LEFTDOWN; ! 1481: break; ! 1482: ! 1483: case DRAWING_DIR_BTLRXM: ! 1484: DirClip = CD_RIGHTUP; ! 1485: break; ! 1486: ! 1487: case DRAWING_DIR_BTRLXM: ! 1488: DirClip = CD_LEFTUP; ! 1489: break; ! 1490: } ! 1491: ! 1492: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, DirClip, 0); ! 1493: ! 1494: do ! 1495: { ! 1496: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), ! 1497: (PULONG) &EnumRects8); ! 1498: ! 1499: for (i = 0; i < EnumRects8.c; i++) ! 1500: { ! 1501: rclTrg = *prclTrg; ! 1502: rclBounds = EnumRects8.arcl[i]; ! 1503: ! 1504: // handle the trivial rejection. ! 1505: ! 1506: bClipRequired = bIntersectTest(&rclTrg, &rclBounds); ! 1507: ! 1508: // define the clipped target rectangle. ! 1509: ! 1510: if (bClipRequired) ! 1511: { ! 1512: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 1513: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 1514: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 1515: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 1516: } ! 1517: else ! 1518: { ! 1519: // The destination rectangle is completely clipped out, ! 1520: // so use as an early out. ! 1521: ! 1522: continue; ! 1523: } ! 1524: ! 1525: // define the cx & cy. ! 1526: ! 1527: width = (rclTrg.right - rclTrg.left) - 1; ! 1528: height = (rclTrg.bottom - rclTrg.top) - 1; ! 1529: ! 1530: // calculate the cx & cy shift for the source. ! 1531: ! 1532: cx = rclTrg.left - prclTrg->left; ! 1533: cy = rclTrg.top - prclTrg->top; ! 1534: ! 1535: // define the source rectangle. ! 1536: ! 1537: rclSrc.left = pptlSrc->x + cx; ! 1538: rclSrc.top = pptlSrc->y + cy; ! 1539: rclSrc.right = rclSrc.left + width + 1; ! 1540: rclSrc.bottom = rclSrc.top + height + 1; ! 1541: ! 1542: // Determine the direction of the blit. ! 1543: // First, check for an intersection of the souce and dest rects. ! 1544: ! 1545: bIntersect = bIntersectTest(&rclTrg, &rclSrc); ! 1546: ! 1547: // Set defaults for the S3 blit direction and the ! 1548: // initial coordinates ! 1549: ! 1550: wDirCode = DRAWING_DIR_TBLRXM; ! 1551: ! 1552: xTrg = rclTrg.left; ! 1553: yTrg = rclTrg.top; ! 1554: xSrc = rclSrc.left; ! 1555: ySrc = rclSrc.top; ! 1556: ! 1557: // If the source & dest rects intersect adjust the ! 1558: // blit direction and initial coordinates. ! 1559: ! 1560: if (bIntersect) ! 1561: { ! 1562: // The horizontal copy direction. ! 1563: ! 1564: if (rclTrg.left > rclSrc.left) ! 1565: { ! 1566: // R to L ! 1567: ! 1568: xTrg = rclTrg.right - 1; ! 1569: xSrc = rclSrc.left + width; ! 1570: wDirCode &= ~PLUS_X; ! 1571: } ! 1572: ! 1573: // The vertical copy direction. ! 1574: ! 1575: if (rclTrg.top > rclSrc.top) ! 1576: { ! 1577: // B to T ! 1578: ! 1579: yTrg = rclTrg.bottom - 1; ! 1580: ySrc = rclSrc.top + height; ! 1581: wDirCode &= ~PLUS_Y; ! 1582: } ! 1583: } ! 1584: ! 1585: // Create the S3 Command. ! 1586: ! 1587: cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE; ! 1588: cmd |= wDirCode; ! 1589: ! 1590: // Do the blit. ! 1591: ! 1592: S3ScrnToScrnBlt(ppdev, xSrc, ySrc, xTrg, yTrg, width, height, s3Rop, cmd); ! 1593: ! 1594: } ! 1595: ! 1596: } while (bMore); ! 1597: } ! 1598: return(TRUE); ! 1599: } ! 1600: ! 1601: ! 1602: /***************************************************************************** ! 1603: * S3ScrnToScrnBlt ! 1604: ****************************************************************************/ ! 1605: VOID S3ScrnToScrnBlt( ! 1606: PPDEV ppdev, ! 1607: INT xSrc, ! 1608: INT ySrc, ! 1609: INT xTrg, ! 1610: INT yTrg, ! 1611: INT width, ! 1612: INT height, ! 1613: WORD s3Rop, ! 1614: WORD cmd) ! 1615: { ! 1616: ! 1617: #if DBG ! 1618: ! 1619: if (cmd & 0x20) ! 1620: { ! 1621: ASSERTS3(((xTrg + width) < (INT) ppdev->cxScreen), ! 1622: "S3.DLL!S3ScrnToScrnBlt - Blit Operation over right edge (1)\n"); ! 1623: } ! 1624: ! 1625: #endif ! 1626: // This is where the actual S3 registers are set. ! 1627: ! 1628: FIFOWAIT(FIFO_2_EMPTY); ! 1629: ! 1630: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | s3Rop); ! 1631: ! 1632: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 1633: ! 1634: FIFOWAIT(FIFO_7_EMPTY); ! 1635: ! 1636: OUTPW(RECT_WIDTH, width); ! 1637: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | height)); ! 1638: OUTPW(CUR_X, xSrc); ! 1639: OUTPW(CUR_Y, ySrc); ! 1640: OUTPW(DEST_X, xTrg); ! 1641: OUTPW(DEST_Y, yTrg); ! 1642: ! 1643: OUTPW(CMD, cmd); ! 1644: } ! 1645: ! 1646: ! 1647: /***************************************************************************** ! 1648: * S3 Brush Pattern ! 1649: * ! 1650: * Returns TRUE if the blit was handled. ! 1651: ****************************************************************************/ ! 1652: BOOL bPatternBrush( ! 1653: SURFOBJ *psoTrg, ! 1654: CLIPOBJ *pco, ! 1655: RECTL *prclTrg, ! 1656: BRUSHOBJ *pbo, ! 1657: POINTL *pptlBrush, ! 1658: ROP4 s3Rop4) // Note that the least significant byte is ! 1659: // the S3 foreground ROP, and the next byte ! 1660: // is the S3 background ROP. So you can't ! 1661: // just pass in a plain S3 ROP constant! ! 1662: ! 1663: { ! 1664: PPDEV ppdev; ! 1665: PS3BRUSH ps3Brush; ! 1666: POINT pt; ! 1667: XYZPOINT xyzPt; ! 1668: INT zHorz, zVert, i; ! 1669: POINT ptDest; ! 1670: SIZE sizDest; ! 1671: WORD s3ForeRop, s3BackRop; ! 1672: BOOL bClipRequired, bMore; ! 1673: RECTL rclTrg, rclBounds; ! 1674: BYTE iDComplexity; ! 1675: ENUMRECTS8 EnumRects8; ! 1676: ! 1677: DISPDBG((3, "S3.DLL!bPatternBrush - Entry\n")); ! 1678: ! 1679: // Get the pdev. ! 1680: ! 1681: ppdev = (PPDEV) psoTrg->dhpdev; ! 1682: ! 1683: // Get the pointer to our drivers realization of the brush. ! 1684: ! 1685: if (pbo->pvRbrush != NULL) ! 1686: { ! 1687: ps3Brush = pbo->pvRbrush; ! 1688: } ! 1689: else ! 1690: { ! 1691: ps3Brush = BRUSHOBJ_pvGetRbrush(pbo); ! 1692: ! 1693: // Fail if we do not handle the brush. ! 1694: ! 1695: if (ps3Brush == NULL) ! 1696: return (FALSE); ! 1697: } ! 1698: ! 1699: s3ForeRop = (WORD) (s3Rop4 & 0xFF); ! 1700: s3BackRop = (WORD) ((s3Rop4 >> 8) & 0xFF); ! 1701: ! 1702: if (ps3Brush->iBitmapFormat == BMF_1BPP) ! 1703: { ! 1704: DISPDBG((3, "S3.DLL!bPatternBrush - 1BPP brush\n")); ! 1705: ! 1706: // If we have never seen this brush before then allocate a slot ! 1707: // for it. ! 1708: ! 1709: // Keep a count of number of brushes we have seen. ! 1710: // This will be used to determine if the cache system is adaquate. ! 1711: ! 1712: nMonoBrushes++; ! 1713: ! 1714: // If we have never seen this brush before or if the cache has ! 1715: // changed since the last time ! 1716: // we have seen it then allocate a new cache entry for it. ! 1717: ! 1718: if ((ps3Brush->iBrushCacheID == -1) || ! 1719: (ps3Brush->iPatternID != ppdev->pulMonoBrushCacheEntries[ps3Brush->iBrushCacheID])) ! 1720: { ! 1721: // If we have run out of cache entries invalidate the entire cache. ! 1722: ! 1723: if (ppdev->iNextMonoBrushCacheSlot >= ppdev->iMaxCachedMonoBrushes) ! 1724: { ! 1725: nMonoBrushCacheInvalidations++; ! 1726: ! 1727: memset(ppdev->pulMonoBrushCacheEntries, 0, ppdev->iMaxCachedMonoBrushes * sizeof(ULONG)); ! 1728: ppdev->iNextMonoBrushCacheSlot = 0; ! 1729: } ! 1730: ! 1731: // Get a slot in the cache for this brush. ! 1732: ! 1733: i = (ppdev->iNextMonoBrushCacheSlot)++; ! 1734: ps3Brush->iBrushCacheID = i; ! 1735: ! 1736: // Calculate the address of the brush in the cache. ! 1737: ! 1738: xyzPt.x = MONO_PATTERN_CACHE_X + ((i >> 3) * 16); ! 1739: xyzPt.y = MONO_PATTERN_CACHE_Y; ! 1740: xyzPt.z = ajMonoPatPlanes[i & 0x7]; ! 1741: ! 1742: // Associate the brush with this cache entry. ! 1743: ! 1744: ppdev->pulMonoBrushCacheEntries[i] = ps3Brush->iPatternID; ! 1745: ! 1746: // Get an expansion cache slot for this brush. ! 1747: ! 1748: i = ppdev->iNextMonoBrushExpansionSlot; ! 1749: i = ++i % MAX_MONO_BRUSH_EXPANSION_SLOTS; ! 1750: ppdev->iNextMonoBrushExpansionSlot = i; ! 1751: ps3Brush->iExpansionCacheID = i; ! 1752: ! 1753: // Associate this brush with this expansion cache slot. ! 1754: ! 1755: ppdev->aulMonoExpansionCacheTag[i] = ps3Brush->iPatternID; ! 1756: ! 1757: // Set the expansion caches planes ! 1758: ! 1759: zHorz = zVert = ajMonoPatPlanes[i]; ! 1760: ! 1761: // Down load the brush to the cache and expand it into ! 1762: // the horizontal and vertical caches. ! 1763: ! 1764: bDownLoadBrushIntoMonoCache(ppdev, ps3Brush, &xyzPt); ! 1765: bExpandMonoBrushIntoHorzCache(ppdev, &xyzPt, zHorz); ! 1766: bExpandMonoBrushIntoVertCache(ppdev, &xyzPt, zVert); ! 1767: ! 1768: } ! 1769: else ! 1770: { ! 1771: // We got a cache hit, so keep the statistic. ! 1772: ! 1773: nMonoBrushCacheHit++; ! 1774: ! 1775: // Calculate the address of the brush in the cache. ! 1776: ! 1777: i = ps3Brush->iBrushCacheID; ! 1778: xyzPt.x = MONO_PATTERN_CACHE_X + ((i >> 3) * 16); ! 1779: xyzPt.y = MONO_PATTERN_CACHE_Y; ! 1780: xyzPt.z = ajMonoPatPlanes[i & 0x7]; ! 1781: ! 1782: // Check for an hit in the expansion cache. ! 1783: ! 1784: if (ps3Brush->iPatternID == ppdev->aulMonoExpansionCacheTag[(i = ps3Brush->iExpansionCacheID)]) ! 1785: { ! 1786: zHorz = zVert = ajMonoPatPlanes[i]; ! 1787: nMonoBrushExpansionCacheHit++; ! 1788: } ! 1789: else ! 1790: { ! 1791: // Get an expansion cache slot for this brush. ! 1792: ! 1793: i = ppdev->iNextMonoBrushExpansionSlot; ! 1794: i = ++i % MAX_MONO_BRUSH_EXPANSION_SLOTS; ! 1795: ppdev->iNextMonoBrushExpansionSlot = i; ! 1796: ps3Brush->iExpansionCacheID = i; ! 1797: ! 1798: // Associate this brush with this expansion cache slot. ! 1799: ! 1800: ppdev->aulMonoExpansionCacheTag[i] = ps3Brush->iPatternID; ! 1801: ! 1802: // Set the expansion caches planes ! 1803: ! 1804: zHorz = zVert = ajMonoPatPlanes[i]; ! 1805: ! 1806: bExpandMonoBrushIntoHorzCache(ppdev, &xyzPt, zHorz); ! 1807: bExpandMonoBrushIntoVertCache(ppdev, &xyzPt, zVert); ! 1808: } ! 1809: } ! 1810: } ! 1811: else ! 1812: { ! 1813: DISPDBG((3, "S3.DLL!bPatternBrush - 8BPP brush\n")); ! 1814: ! 1815: // If we have never seen this brush before then allocate a slot ! 1816: // for it. ! 1817: ! 1818: // Keep a count of number of brushes we have seen. ! 1819: // This will be used to determine if the cache system is adaquate. ! 1820: ! 1821: nColorBrushes++; ! 1822: ! 1823: // If we have never seen this brush before or if the cache ! 1824: // has changed since the last time ! 1825: // we have seen it then allocate a new cache entry for it. ! 1826: ! 1827: if ((ps3Brush->iBrushCacheID == -1) || ! 1828: (ps3Brush->iPatternID != ppdev->pulColorBrushCacheEntries[ps3Brush->iBrushCacheID])) ! 1829: { ! 1830: // If we have run out of cache entries invalidate the entire cache. ! 1831: ! 1832: if (ppdev->iNextColorBrushCacheSlot >= ppdev->iMaxCachedColorBrushes) ! 1833: { ! 1834: nColorBrushCacheInvalidations++; ! 1835: ! 1836: memset(ppdev->pulColorBrushCacheEntries, 0, ppdev->iMaxCachedColorBrushes * sizeof(ULONG)); ! 1837: ppdev->iNextColorBrushCacheSlot = 0; ! 1838: } ! 1839: ! 1840: // Get a slot in the cache for this brush. ! 1841: ! 1842: i = (ppdev->iNextColorBrushCacheSlot)++; ! 1843: ps3Brush->iBrushCacheID = i; ! 1844: ! 1845: // Calculate the address of the brush in the cache. ! 1846: ! 1847: pt.x = COLOR_PATTERN_CACHE_X + ((i >> 2) * 16); ! 1848: pt.y = COLOR_PATTERN_CACHE_Y + ((i & 0x3) * 16); ! 1849: ! 1850: // Associate the brush with this cache entry. ! 1851: ! 1852: ppdev->pulColorBrushCacheEntries[i] = ps3Brush->iPatternID; ! 1853: ppdev->ulColorExpansionCacheTag = ps3Brush->iPatternID; ! 1854: ! 1855: // Down load the brush to the cache and expand it into ! 1856: // the horizontal and vertical caches. ! 1857: ! 1858: bDownLoadBrushIntoColorCache(ppdev, ps3Brush, &pt); ! 1859: bExpandColorBrushIntoHorzCache(ppdev, &pt); ! 1860: bExpandColorBrushIntoVertCache(ppdev, &pt); ! 1861: } ! 1862: else ! 1863: { ! 1864: // We got a cache hit, so keep the statistic. ! 1865: ! 1866: nColorBrushCacheHit++; ! 1867: ! 1868: // Calculate the address of the brush in the cache. ! 1869: ! 1870: i = ps3Brush->iBrushCacheID; ! 1871: pt.x = COLOR_PATTERN_CACHE_X + ((i >> 2) * 16); ! 1872: pt.y = COLOR_PATTERN_CACHE_Y + ((i & 0x3) * 16); ! 1873: ! 1874: if (ps3Brush->iPatternID == ppdev->ulColorExpansionCacheTag) ! 1875: { ! 1876: nColorBrushExpansionCacheHit++; ! 1877: } ! 1878: else ! 1879: { ! 1880: ppdev->ulColorExpansionCacheTag = ps3Brush->iPatternID; ! 1881: ! 1882: bExpandColorBrushIntoHorzCache(ppdev, &pt); ! 1883: bExpandColorBrushIntoVertCache(ppdev, &pt); ! 1884: } ! 1885: } ! 1886: } ! 1887: ! 1888: // Handle the clipping. ! 1889: ! 1890: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX) ! 1891: { ! 1892: if (iDComplexity == DC_TRIVIAL) ! 1893: { ! 1894: rclTrg = *prclTrg; ! 1895: } ! 1896: else ! 1897: { ! 1898: rclTrg = *prclTrg; ! 1899: rclBounds = pco->rclBounds; ! 1900: ! 1901: // First handle the trivial rejection. ! 1902: ! 1903: bClipRequired = bIntersectTest(&rclTrg, &rclBounds); ! 1904: ! 1905: if (bClipRequired) ! 1906: { ! 1907: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 1908: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 1909: rclTrg.right = min(rclTrg.right, rclBounds.right); ! 1910: rclTrg.bottom = min(rclTrg.bottom, rclBounds.bottom); ! 1911: } ! 1912: else ! 1913: { ! 1914: // The brush is completely clipped out. ! 1915: // so just return sucessfull. ! 1916: ! 1917: return (TRUE); ! 1918: } ! 1919: } ! 1920: ! 1921: ptDest.x = rclTrg.left; ! 1922: ptDest.y = rclTrg.top; ! 1923: sizDest.cx = rclTrg.right - rclTrg.left; ! 1924: sizDest.cy = rclTrg.bottom - rclTrg.top; ! 1925: ! 1926: // Color expand the monochrome brush in the Hoizontal Cache to the ! 1927: // screen. ! 1928: ! 1929: if (s3ForeRop == OVERPAINT && s3BackRop == OVERPAINT) ! 1930: { ! 1931: if (ps3Brush->iBitmapFormat == BMF_1BPP) ! 1932: { ! 1933: bCpyColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz, ! 1934: (PPOINT) pptlBrush, ! 1935: &ptDest, &sizDest); ! 1936: } ! 1937: else ! 1938: { ! 1939: // NOTE: The S3-911/924 requries the cx of any "rolling blt" ! 1940: // to have a cx of >= 64 pels. This is due to how the ! 1941: // chip's internal FIFO works. This test will catch all ! 1942: // the souce copy operations that can be accelerated, ! 1943: // with the rolling blit. ! 1944: ! 1945: if ((sizDest.cx >= 64) || ! 1946: (sizDest.cx > sizDest.cy)) ! 1947: { ! 1948: bCpyColorHorzCacheToScreen(ppdev, ps3Brush, ! 1949: (PPOINT) pptlBrush, ! 1950: &ptDest, &sizDest); ! 1951: } ! 1952: else ! 1953: { ! 1954: bColorVertCacheToScreen(ppdev, ps3Brush, ! 1955: (PPOINT) pptlBrush, ! 1956: &ptDest, &sizDest, ! 1957: s3ForeRop, s3BackRop); ! 1958: } ! 1959: } ! 1960: } ! 1961: else ! 1962: { ! 1963: if (sizDest.cy > sizDest.cx) ! 1964: { ! 1965: if (ps3Brush->iBitmapFormat == BMF_1BPP) ! 1966: { ! 1967: bColorExpandVertCacheToScreen(ppdev, ps3Brush, zVert, ! 1968: (PPOINT) pptlBrush, ! 1969: &ptDest, &sizDest, ! 1970: s3ForeRop, s3BackRop); ! 1971: } ! 1972: else ! 1973: { ! 1974: bColorVertCacheToScreen(ppdev, ps3Brush, ! 1975: (PPOINT) pptlBrush, ! 1976: &ptDest, &sizDest, ! 1977: s3ForeRop, s3BackRop); ! 1978: } ! 1979: } ! 1980: else ! 1981: { ! 1982: if (ps3Brush->iBitmapFormat == BMF_1BPP) ! 1983: { ! 1984: bColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz, ! 1985: (PPOINT) pptlBrush, ! 1986: &ptDest, &sizDest, ! 1987: s3ForeRop, s3BackRop); ! 1988: } ! 1989: else ! 1990: { ! 1991: bColorHorzCacheToScreen(ppdev, ps3Brush, ! 1992: (PPOINT) pptlBrush, ! 1993: &ptDest, &sizDest, ! 1994: s3ForeRop, s3BackRop); ! 1995: } ! 1996: } ! 1997: } ! 1998: } ! 1999: else ! 2000: { ! 2001: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); ! 2002: ! 2003: do ! 2004: { ! 2005: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), ! 2006: (PULONG) &EnumRects8); ! 2007: ! 2008: for (i = 0; i < (INT) EnumRects8.c; i++) ! 2009: { ! 2010: rclBounds = EnumRects8.arcl[i]; ! 2011: ! 2012: if (rclBounds.left < prclTrg->left) ! 2013: rclBounds.left = prclTrg->left; ! 2014: ! 2015: if (rclBounds.right > prclTrg->right) ! 2016: rclBounds.right = prclTrg->right; ! 2017: ! 2018: if (rclBounds.top < prclTrg->top) ! 2019: rclBounds.top = prclTrg->top; ! 2020: ! 2021: if (rclBounds.bottom > prclTrg->bottom) ! 2022: rclBounds.bottom = prclTrg->bottom; ! 2023: ! 2024: // Get the height and width for the blit. ! 2025: ! 2026: ptDest.x = rclBounds.left; ! 2027: ptDest.y = rclBounds.top; ! 2028: sizDest.cx = rclBounds.right - rclBounds.left; ! 2029: sizDest.cy = rclBounds.bottom - rclBounds.top; ! 2030: ! 2031: // Color expand the monochrome brush in the Hoizontal Cache ! 2032: // to the screen. ! 2033: ! 2034: if (s3ForeRop == OVERPAINT && s3BackRop == OVERPAINT) ! 2035: { ! 2036: if (ps3Brush->iBitmapFormat == BMF_1BPP) ! 2037: { ! 2038: bCpyColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz, ! 2039: (PPOINT) pptlBrush, ! 2040: &ptDest, &sizDest); ! 2041: ! 2042: } ! 2043: else ! 2044: { ! 2045: if ((sizDest.cx >= 64) || ! 2046: (sizDest.cx > sizDest.cy)) ! 2047: { ! 2048: bCpyColorHorzCacheToScreen(ppdev, ps3Brush, ! 2049: (PPOINT) pptlBrush, ! 2050: &ptDest, &sizDest); ! 2051: } ! 2052: else ! 2053: { ! 2054: bColorVertCacheToScreen(ppdev, ps3Brush, ! 2055: (PPOINT) pptlBrush, ! 2056: &ptDest, &sizDest, ! 2057: s3ForeRop, s3BackRop); ! 2058: } ! 2059: } ! 2060: } ! 2061: else ! 2062: { ! 2063: if (sizDest.cy > sizDest.cx) ! 2064: { ! 2065: if (ps3Brush->iBitmapFormat == BMF_1BPP) ! 2066: { ! 2067: bColorExpandVertCacheToScreen(ppdev, ps3Brush, zVert, ! 2068: (PPOINT) pptlBrush, ! 2069: &ptDest, &sizDest, ! 2070: s3ForeRop, s3BackRop); ! 2071: } ! 2072: else ! 2073: { ! 2074: bColorVertCacheToScreen(ppdev, ps3Brush, ! 2075: (PPOINT) pptlBrush, ! 2076: &ptDest, &sizDest, ! 2077: s3ForeRop, s3BackRop); ! 2078: } ! 2079: } ! 2080: else ! 2081: { ! 2082: if (ps3Brush->iBitmapFormat == BMF_1BPP) ! 2083: { ! 2084: bColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz, ! 2085: (PPOINT) pptlBrush, ! 2086: &ptDest, &sizDest, ! 2087: s3ForeRop, s3BackRop); ! 2088: } ! 2089: else ! 2090: { ! 2091: bColorHorzCacheToScreen(ppdev, ps3Brush, ! 2092: (PPOINT) pptlBrush, ! 2093: &ptDest, &sizDest, ! 2094: s3ForeRop, s3BackRop); ! 2095: } ! 2096: ! 2097: } ! 2098: } ! 2099: } ! 2100: } while (bMore); ! 2101: ! 2102: } ! 2103: ! 2104: return (TRUE); ! 2105: ! 2106: } ! 2107: ! 2108: /***************************************************************************** ! 2109: * wXlateSrcRop3toS3Rop - Translate the Source to Dest Rop 3 to an S3 rop ! 2110: ****************************************************************************/ ! 2111: WORD wXlateSrcRop3toS3Rop(PPDEV pdev, WORD rop3) ! 2112: { ! 2113: WORD s3Rop; ! 2114: ! 2115: switch (LOBYTE(rop3)) ! 2116: { ! 2117: case 0xBB: // DSno ! 2118: s3Rop = SCREEN_OR_NOT_NEW; ! 2119: break; ! 2120: ! 2121: case 0x33: // Sn ! 2122: s3Rop = NOT_NEW; ! 2123: break; ! 2124: ! 2125: case 0x44: // SDna ! 2126: s3Rop = NOT_SCREEN_AND_NEW; ! 2127: break; ! 2128: ! 2129: case 0x66: // DSx ! 2130: s3Rop = SCREEN_XOR_NEW; ! 2131: break; ! 2132: ! 2133: case 0x77: // DSan ! 2134: s3Rop = NOT_SCREEN_OR_NOT_NEW; ! 2135: break; ! 2136: ! 2137: case 0x88: // DSa ! 2138: s3Rop = SCREEN_AND_NEW; ! 2139: break; ! 2140: ! 2141: case 0x99: // DSxn ! 2142: s3Rop = NOT_SCREEN_XOR_NEW; ! 2143: break; ! 2144: ! 2145: case 0xDD: // SDno ! 2146: s3Rop = NOT_SCREEN_OR_NEW; ! 2147: break; ! 2148: ! 2149: case 0xCC: // S ! 2150: s3Rop = OVERPAINT; ! 2151: break; ! 2152: ! 2153: case 0x11: // DSon ! 2154: s3Rop = NOT_SCREEN_AND_NOT_NEW; ! 2155: break; ! 2156: ! 2157: case 0x22: // DSna ! 2158: s3Rop = SCREEN_AND_NOT_NEW; ! 2159: break; ! 2160: ! 2161: case 0xEE: // SDo ! 2162: s3Rop = SCREEN_OR_NEW; ! 2163: break; ! 2164: ! 2165: default: ! 2166: s3Rop = 0; ! 2167: break; ! 2168: } ! 2169: ! 2170: return (s3Rop); ! 2171: ! 2172: } ! 2173: ! 2174: ! 2175: /***************************************************************************** ! 2176: * Translate the ROP4 to S3 rops. ! 2177: ****************************************************************************/ ! 2178: ! 2179: ROP4 bXlatePatRop4toS3Rop( ! 2180: PPDEV pdev, ! 2181: ROP4 rop4) ! 2182: { ! 2183: WORD s3Rop; ! 2184: ROP4 s3Rop4; ! 2185: ! 2186: switch (rop4 & 0xff) ! 2187: { ! 2188: case 0x00: // 0 ! 2189: s3Rop = LOGICAL_0; ! 2190: break; ! 2191: ! 2192: case 0x05: // ~(P | D) ! 2193: s3Rop = NOT_SCREEN_AND_NOT_NEW; ! 2194: break; ! 2195: ! 2196: case 0x0A: // ~P & D ! 2197: s3Rop = SCREEN_AND_NOT_NEW; ! 2198: break; ! 2199: ! 2200: case 0x0F: // ~P ! 2201: s3Rop = NOT_NEW; ! 2202: break; ! 2203: ! 2204: case 0x50: // P & ~D ! 2205: s3Rop = NOT_SCREEN_AND_NEW; ! 2206: break; ! 2207: ! 2208: case 0x55: // ~D ! 2209: s3Rop = NOT_SCREEN; ! 2210: break; ! 2211: ! 2212: case 0x5A: // P ^ D ! 2213: s3Rop = SCREEN_XOR_NEW; ! 2214: break; ! 2215: ! 2216: case 0x5F: // ~(P & D) ! 2217: s3Rop = NOT_SCREEN_OR_NOT_NEW; ! 2218: break; ! 2219: ! 2220: case 0xA0: // P & D ! 2221: s3Rop = SCREEN_AND_NEW; ! 2222: break; ! 2223: ! 2224: case 0xA5: // ~(P ^ D) ! 2225: s3Rop = NOT_SCREEN_XOR_NEW; ! 2226: break; ! 2227: ! 2228: case 0xAA: // D ! 2229: s3Rop = LEAVE_ALONE; ! 2230: break; ! 2231: ! 2232: case 0xAF: // ~P | D ! 2233: s3Rop = SCREEN_OR_NOT_NEW; ! 2234: break; ! 2235: ! 2236: case 0xF0: // P ! 2237: s3Rop = OVERPAINT; ! 2238: break; ! 2239: ! 2240: case 0xF5: // P | ~D ! 2241: s3Rop = NOT_SCREEN_OR_NEW; ! 2242: break; ! 2243: ! 2244: case 0xFA: // P | D ! 2245: s3Rop = SCREEN_OR_NEW; ! 2246: break; ! 2247: ! 2248: case 0xFF: // 1 ! 2249: s3Rop = LOGICAL_1; ! 2250: break; ! 2251: } ! 2252: ! 2253: s3Rop4 = s3Rop | (s3Rop << 8); ! 2254: ! 2255: return(s3Rop4); ! 2256: } ! 2257: ! 2258: /***************************************************************************** ! 2259: * Download the Color Brush to the Color brush cache in ! 2260: * graphics memory. ! 2261: ****************************************************************************/ ! 2262: BOOL bDownLoadBrushIntoColorCache( ! 2263: PPDEV ppdev, ! 2264: PS3BRUSH ps3Brush, ! 2265: PPOINT ppt) ! 2266: { ! 2267: WORD Cmd; ! 2268: ! 2269: DISPDBG((3, "S3.DLL!bDownLoadBrushIntoColorCache - Entry\n")); ! 2270: ! 2271: // Down load the initial pattern image, the upper left 8 X 8 cell. ! 2272: ! 2273: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT | ! 2274: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 2275: LAST_PIXEL_ON | WRITE; ! 2276: ! 2277: // Setup the S3 chip. ! 2278: ! 2279: FIFOWAIT(FIFO_6_EMPTY); ! 2280: ! 2281: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT); ! 2282: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 2283: ! 2284: OUTPW(CUR_X, ppt->x); ! 2285: OUTPW(CUR_Y, ppt->y); ! 2286: ! 2287: OUTPW(RECT_WIDTH, 7); ! 2288: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7)); ! 2289: ! 2290: GPWAIT(); ! 2291: OUTPW(CMD, Cmd); ! 2292: ! 2293: // Now transfer the data from host memory to graphics memory. ! 2294: ! 2295: CHECK_DATA_READY; ! 2296: ! 2297: vDataPortOutB(ppdev, ps3Brush->ajPattern, 64); ! 2298: ! 2299: CHECK_DATA_COMPLETE; ! 2300: ! 2301: // Make the pattern double wide. Make copy of the pattern to the right ! 2302: // of the original pattern. ! 2303: ! 2304: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2305: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM; ! 2306: ! 2307: FIFOWAIT(FIFO_8_EMPTY); ! 2308: ! 2309: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 2310: ! 2311: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 2312: ! 2313: OUTPW(CUR_X, ppt->x); ! 2314: OUTPW(CUR_Y, ppt->y); ! 2315: OUTPW(DEST_X, ppt->x + 8); ! 2316: OUTPW(DEST_Y, ppt->y); ! 2317: ! 2318: OUTPW(CMD, Cmd); ! 2319: ! 2320: // Make the pattern double high. Make a copy of the double pattern ! 2321: // pattern below the original one. ! 2322: ! 2323: FIFOWAIT(FIFO_6_EMPTY); ! 2324: ! 2325: OUTPW(RECT_WIDTH, 15); ! 2326: ! 2327: OUTPW(CUR_X, ppt->x); ! 2328: OUTPW(CUR_Y, ppt->y); ! 2329: OUTPW(DEST_X, ppt->x); ! 2330: OUTPW(DEST_Y, ppt->y + 8); ! 2331: ! 2332: OUTPW(CMD, Cmd); ! 2333: ! 2334: return(TRUE); ! 2335: } ! 2336: ! 2337: ! 2338: ! 2339: /***************************************************************************** ! 2340: * Download the Monochrome Brush to the Monochrome brush cache in ! 2341: * graphics memory. ! 2342: ****************************************************************************/ ! 2343: BOOL bDownLoadBrushIntoMonoCache( ! 2344: PPDEV ppdev, ! 2345: PS3BRUSH p3Brush, ! 2346: PXYZPOINT pxyzPt) ! 2347: { ! 2348: WORD Cmd; ! 2349: INT i; ! 2350: BYTE ajPattern[8]; ! 2351: ! 2352: DISPDBG((3, "S3.DLL!bDownLoadBrushIntoMonoCache - Entry\n")); ! 2353: ! 2354: // Compress the dword aligned pattern to a byte aligned pattern. ! 2355: ! 2356: for (i = 0; i < 8; i++) ! 2357: { ! 2358: ajPattern[i] = p3Brush->ajPattern[i * p3Brush->lDeltaPattern]; ! 2359: } ! 2360: ! 2361: // Down load the initial pattern image, the upper left 8 X 8 cell. ! 2362: ! 2363: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT | ! 2364: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 2365: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE; ! 2366: ! 2367: // Setup the S3 chip. ! 2368: ! 2369: FIFOWAIT(FIFO_8_EMPTY); ! 2370: ! 2371: TEST_AND_SET_FRGD_MIX(LOGICAL_1); ! 2372: TEST_AND_SET_BKGD_MIX(LOGICAL_0); ! 2373: ! 2374: TEST_AND_SET_WRT_MASK(LOWORD(pxyzPt->z)); ! 2375: ! 2376: OUTPW(CUR_X, pxyzPt->x); ! 2377: OUTPW(CUR_Y, pxyzPt->y); ! 2378: ! 2379: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA)); ! 2380: OUTPW(RECT_WIDTH, 7); ! 2381: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7)); ! 2382: ! 2383: GPWAIT(); ! 2384: OUTPW(CMD, Cmd); ! 2385: ! 2386: // Now transfer the data from host memory to graphics memory. ! 2387: ! 2388: CHECK_DATA_READY; ! 2389: ! 2390: vDataPortOutB(ppdev, ajPattern, 8); ! 2391: ! 2392: CHECK_DATA_COMPLETE; ! 2393: ! 2394: // Make the pattern double wide. Make copy of the pattern to the right ! 2395: // of the original pattern. ! 2396: ! 2397: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2398: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM; ! 2399: ! 2400: FIFOWAIT(FIFO_8_EMPTY); ! 2401: ! 2402: TEST_AND_SET_RD_MASK (LOWORD(pxyzPt->z)); ! 2403: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 2404: ! 2405: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 2406: ! 2407: OUTPW(CUR_X, pxyzPt->x); ! 2408: OUTPW(CUR_Y, pxyzPt->y); ! 2409: OUTPW(DEST_X, pxyzPt->x + 8); ! 2410: OUTPW(DEST_Y, pxyzPt->y); ! 2411: ! 2412: OUTPW(CMD, Cmd); ! 2413: ! 2414: // Make the pattern double high. Make a copy of the double pattern ! 2415: // pattern below the original one. ! 2416: ! 2417: FIFOWAIT(FIFO_6_EMPTY); ! 2418: ! 2419: OUTPW(RECT_WIDTH, 15); ! 2420: ! 2421: OUTPW(CUR_X, pxyzPt->x); ! 2422: OUTPW(CUR_Y, pxyzPt->y); ! 2423: OUTPW(DEST_X, pxyzPt->x); ! 2424: OUTPW(DEST_Y, pxyzPt->y + 8); ! 2425: ! 2426: OUTPW(CMD, Cmd); ! 2427: ! 2428: // Reset the read and write masks. ! 2429: ! 2430: FIFOWAIT(FIFO_2_EMPTY); ! 2431: ! 2432: TEST_AND_SET_WRT_MASK(0xff); ! 2433: TEST_AND_SET_RD_MASK(0xff); ! 2434: ! 2435: return(TRUE); ! 2436: } ! 2437: ! 2438: ! 2439: /***************************************************************************** ! 2440: * Expand the color brush in the vertical dimension. ! 2441: ****************************************************************************/ ! 2442: BOOL bExpandColorBrushIntoVertCache( ! 2443: PPDEV ppdev, ! 2444: PPOINT ppt) ! 2445: { ! 2446: WORD Cmd; ! 2447: ! 2448: DISPDBG((3, "S3.DLL!bExpandColorBrushIntoVertCache - Entry\n")); ! 2449: ! 2450: // Copy the cached double wide, double high pattern to the Horizontal ! 2451: // expansion cache area. ! 2452: ! 2453: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2454: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM; ! 2455: ! 2456: FIFOWAIT(FIFO_1_EMPTY); ! 2457: ! 2458: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 2459: ! 2460: FIFOWAIT(FIFO_8_EMPTY); ! 2461: ! 2462: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 2463: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15)); ! 2464: OUTPW(RECT_WIDTH, 15); ! 2465: ! 2466: OUTPW(CUR_X, ppt->x); ! 2467: OUTPW(CUR_Y, ppt->y); ! 2468: OUTPW(DEST_X, COLOR_VERT_EXPANSION_CACHE_X); ! 2469: OUTPW(DEST_Y, COLOR_VERT_EXPANSION_CACHE_Y); ! 2470: ! 2471: OUTPW(CMD, Cmd); ! 2472: ! 2473: // Now the rolling blit to fill all the way. ! 2474: ! 2475: FIFOWAIT(FIFO_6_EMPTY); ! 2476: ! 2477: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | COLOR_VERT_EXPANSION_CACHE_CY - 17)); ! 2478: ! 2479: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X); ! 2480: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y); ! 2481: OUTPW(DEST_X, COLOR_VERT_EXPANSION_CACHE_X); ! 2482: OUTPW(DEST_Y, COLOR_VERT_EXPANSION_CACHE_Y + 16); ! 2483: ! 2484: OUTPW(CMD, Cmd); ! 2485: ! 2486: return(TRUE); ! 2487: ! 2488: } ! 2489: ! 2490: ! 2491: ! 2492: /***************************************************************************** ! 2493: * Expand the monochrome brush in the vertical dimension. ! 2494: ****************************************************************************/ ! 2495: BOOL bExpandMonoBrushIntoVertCache( ! 2496: PPDEV ppdev, ! 2497: PXYZPOINT pxyzPt, ! 2498: INT zVert) ! 2499: { ! 2500: WORD Cmd; ! 2501: ! 2502: DISPDBG((3, "S3.DLL!bExpandMonoBrushIntoVertCache - Entry\n")); ! 2503: ! 2504: // Copy the cached double wide, double high pattern to the Horizontal ! 2505: // expansion cache area. ! 2506: ! 2507: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2508: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM; ! 2509: ! 2510: FIFOWAIT(FIFO_7_EMPTY); ! 2511: ! 2512: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY)); ! 2513: ! 2514: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT); ! 2515: TEST_AND_SET_FRGD_COLOR(0xff); ! 2516: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT); ! 2517: SET_BKGD_COLOR(0); ! 2518: ! 2519: TEST_AND_SET_RD_MASK(LOWORD(pxyzPt->z)); ! 2520: TEST_AND_SET_WRT_MASK(LOWORD(zVert)); ! 2521: ! 2522: FIFOWAIT(FIFO_7_EMPTY); ! 2523: ! 2524: OUTPW(RECT_WIDTH, 15); ! 2525: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15)); ! 2526: ! 2527: OUTPW(CUR_X, pxyzPt->x); ! 2528: OUTPW(CUR_Y, pxyzPt->y); ! 2529: OUTPW(DEST_X, MONO_VERT_EXPANSION_CACHE_X); ! 2530: OUTPW(DEST_Y, MONO_VERT_EXPANSION_CACHE_Y); ! 2531: ! 2532: OUTPW(CMD, Cmd); ! 2533: ! 2534: // Now the rolling blit to fill all the way. ! 2535: ! 2536: FIFOWAIT(FIFO_7_EMPTY); ! 2537: ! 2538: TEST_AND_SET_RD_MASK(zVert); ! 2539: ! 2540: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | MONO_VERT_EXPANSION_CACHE_CY - 17)); ! 2541: ! 2542: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X); ! 2543: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y); ! 2544: OUTPW(DEST_X, MONO_VERT_EXPANSION_CACHE_X); ! 2545: OUTPW(DEST_Y, MONO_VERT_EXPANSION_CACHE_Y + 16); ! 2546: ! 2547: OUTPW(CMD, Cmd); ! 2548: ! 2549: // Now reset the read and write plan masks. ! 2550: ! 2551: FIFOWAIT(FIFO_2_EMPTY); ! 2552: ! 2553: TEST_AND_SET_WRT_MASK(0xff); ! 2554: TEST_AND_SET_RD_MASK(0xff); ! 2555: ! 2556: return(TRUE); ! 2557: ! 2558: } ! 2559: ! 2560: /***************************************************************************** ! 2561: * Expand the color brush in the horizontal dimension. ! 2562: ****************************************************************************/ ! 2563: BOOL bExpandColorBrushIntoHorzCache( ! 2564: PPDEV ppdev, ! 2565: PPOINT ppt) ! 2566: { ! 2567: WORD Cmd; ! 2568: ! 2569: DISPDBG((3, "S3.DLL!bExpandColorBrushIntoHorzCache - Entry\n")); ! 2570: ! 2571: // Copy the cached double wide, double high pattern to the Horizontal ! 2572: // expansion cache area. ! 2573: ! 2574: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2575: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM; ! 2576: ! 2577: FIFOWAIT(FIFO_1_EMPTY); ! 2578: ! 2579: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 2580: ! 2581: FIFOWAIT(FIFO_8_EMPTY); ! 2582: ! 2583: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 2584: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15)); ! 2585: OUTPW(RECT_WIDTH, 15); ! 2586: ! 2587: OUTPW(CUR_X, ppt->x); ! 2588: OUTPW(CUR_Y, ppt->y); ! 2589: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 2590: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y); ! 2591: ! 2592: OUTPW(CMD, Cmd); ! 2593: ! 2594: // Expand the 16 X 16 double wide, double high. ! 2595: // First to a 32 X 16 ! 2596: ! 2597: FIFOWAIT(FIFO_5_EMPTY); ! 2598: ! 2599: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 2600: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y); ! 2601: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X + 16); ! 2602: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y); ! 2603: ! 2604: OUTPW(CMD, Cmd); ! 2605: ! 2606: // Now 64 X 16 ! 2607: ! 2608: FIFOWAIT(FIFO_6_EMPTY); ! 2609: ! 2610: OUTPW(RECT_WIDTH, 31); ! 2611: ! 2612: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 2613: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y); ! 2614: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X + 32); ! 2615: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y); ! 2616: ! 2617: OUTPW(CMD, Cmd); ! 2618: ! 2619: // Now the rolling blit to fill all the way to 512 pels. ! 2620: ! 2621: FIFOWAIT(FIFO_7_EMPTY); ! 2622: ! 2623: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 65); ! 2624: ! 2625: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 2626: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y); ! 2627: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X + 64); ! 2628: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y); ! 2629: ! 2630: OUTPW(CMD, Cmd); ! 2631: ! 2632: return(TRUE); ! 2633: } ! 2634: ! 2635: ! 2636: ! 2637: ! 2638: /***************************************************************************** ! 2639: * Expand the monochrome brush in the horizontal dimension. ! 2640: ****************************************************************************/ ! 2641: BOOL bExpandMonoBrushIntoHorzCache( ! 2642: PPDEV ppdev, ! 2643: PXYZPOINT pxyzPt, ! 2644: INT zHorz) ! 2645: { ! 2646: WORD Cmd; ! 2647: ! 2648: DISPDBG((3, "S3.DLL!bExpandMonoBrushIntoHorzCache - Entry\n")); ! 2649: ! 2650: // Copy the cached double wide, double high pattern to the Horizontal ! 2651: // expansion cache area. ! 2652: ! 2653: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2654: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM; ! 2655: ! 2656: FIFOWAIT(FIFO_7_EMPTY); ! 2657: ! 2658: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY)); ! 2659: ! 2660: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT); ! 2661: TEST_AND_SET_FRGD_COLOR(0xff); ! 2662: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT); ! 2663: SET_BKGD_COLOR(0); ! 2664: ! 2665: TEST_AND_SET_RD_MASK(LOWORD(pxyzPt->z)); ! 2666: TEST_AND_SET_WRT_MASK(LOWORD(zHorz)); ! 2667: ! 2668: FIFOWAIT(FIFO_7_EMPTY); ! 2669: ! 2670: OUTPW(RECT_WIDTH, 15); ! 2671: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15)); ! 2672: ! 2673: OUTPW(CUR_X, pxyzPt->x); ! 2674: OUTPW(CUR_Y, pxyzPt->y); ! 2675: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X); ! 2676: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y); ! 2677: ! 2678: OUTPW(CMD, Cmd); ! 2679: ! 2680: // Expand the 16 X 16 double wide, double high. ! 2681: // First to a 32 X 16 ! 2682: ! 2683: FIFOWAIT(FIFO_7_EMPTY); ! 2684: ! 2685: TEST_AND_SET_RD_MASK(LOWORD(zHorz)); ! 2686: ! 2687: OUTPW(RECT_WIDTH, 15); ! 2688: ! 2689: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 2690: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y); ! 2691: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X + 16); ! 2692: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y); ! 2693: ! 2694: OUTPW(CMD, Cmd); ! 2695: ! 2696: // Now 64 X 16 ! 2697: ! 2698: FIFOWAIT(FIFO_6_EMPTY); ! 2699: ! 2700: OUTPW(RECT_WIDTH, 31); ! 2701: ! 2702: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 2703: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y); ! 2704: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X + 32); ! 2705: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y); ! 2706: ! 2707: OUTPW(CMD, Cmd); ! 2708: ! 2709: // Now the rolling blit to fill all the way to 512 pels. ! 2710: ! 2711: FIFOWAIT(FIFO_7_EMPTY); ! 2712: ! 2713: OUTPW(RECT_WIDTH, MONO_HORZ_EXPANSION_CACHE_CX - 65); ! 2714: ! 2715: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 2716: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y); ! 2717: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X + 64); ! 2718: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y); ! 2719: ! 2720: OUTPW(CMD, Cmd); ! 2721: ! 2722: // Now reset the read and write plan masks. ! 2723: ! 2724: FIFOWAIT(FIFO_2_EMPTY); ! 2725: ! 2726: TEST_AND_SET_WRT_MASK(0xff); ! 2727: TEST_AND_SET_RD_MASK(0xff); ! 2728: ! 2729: return(TRUE); ! 2730: } ! 2731: ! 2732: ! 2733: /***************************************************************************** ! 2734: * Color brush in the Vertical Cache to the screen. ! 2735: ****************************************************************************/ ! 2736: BOOL bColorVertCacheToScreen( ! 2737: PPDEV ppdev, ! 2738: PS3BRUSH ps3Brush, ! 2739: PPOINT pptBrushOrg, ! 2740: PPOINT pptDest, ! 2741: PSIZE psizDest, ! 2742: WORD s3ForeRop, ! 2743: WORD s3BackRop) ! 2744: { ! 2745: WORD Cmd; ! 2746: INT ixBlits, ixLast, ! 2747: iyFirst, iyBlits, iyLast, ! 2748: xOffset, yOffset, ! 2749: i, j; ! 2750: ! 2751: DISPDBG((3, "S3.DLL!bColorVertCacheToScreen - Entry\n")); ! 2752: ! 2753: // Take into account the pptBrushOrg. ! 2754: ! 2755: xOffset = pptDest->x - pptBrushOrg->x; ! 2756: yOffset = pptDest->y - pptBrushOrg->y; ! 2757: ! 2758: if (xOffset < 0) ! 2759: xOffset = 8 - (-xOffset % 8); ! 2760: else ! 2761: xOffset %= 8; ! 2762: ! 2763: if (yOffset < 0) ! 2764: yOffset = 8 - (-yOffset % 8); ! 2765: else ! 2766: yOffset %= 8; ! 2767: ! 2768: // Color Expand the monochrome vertical cache to the screen. ! 2769: // This is done in a loop to handle the general case ROPs. ! 2770: ! 2771: if (psizDest->cy < 8 - yOffset) ! 2772: { ! 2773: iyFirst = psizDest->cy; ! 2774: iyBlits = 0; ! 2775: iyLast = 0; ! 2776: ! 2777: } ! 2778: else if (psizDest->cy - yOffset < COLOR_VERT_EXPANSION_CACHE_CY - 8) ! 2779: { ! 2780: iyFirst = 8 - yOffset; ! 2781: iyBlits = 0; ! 2782: iyLast = psizDest->cy - iyFirst; ! 2783: } ! 2784: else ! 2785: { ! 2786: iyFirst = 8 - yOffset; ! 2787: iyBlits = (psizDest->cy - iyFirst) / (COLOR_VERT_EXPANSION_CACHE_CY - 8); ! 2788: iyLast = (psizDest->cy - iyFirst) % (COLOR_VERT_EXPANSION_CACHE_CY - 8); ! 2789: } ! 2790: ! 2791: ixBlits = psizDest->cx / 8; ! 2792: ixLast = psizDest->cx % 8; ! 2793: ! 2794: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2795: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM; ! 2796: ! 2797: FIFOWAIT(FIFO_4_EMPTY); ! 2798: ! 2799: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | s3ForeRop); ! 2800: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 2801: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7)); ! 2802: OUTPW(RECT_WIDTH, 7); ! 2803: ! 2804: for(i = 0; i < ixBlits; i++) ! 2805: { ! 2806: ASSERTS3(((pptDest->x + (i * 8) + 7) < (INT) ppdev->cxScreen), ! 2807: "S3.DLL!bColorVertCacheToScreen - Blit Operation over right edge (1)\n"); ! 2808: ! 2809: if (iyFirst != 0) ! 2810: { ! 2811: FIFOWAIT(FIFO_6_EMPTY); ! 2812: ! 2813: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1)); ! 2814: ! 2815: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset); ! 2816: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y + yOffset); ! 2817: OUTPW(DEST_X, pptDest->x + (i * 8)); ! 2818: OUTPW(DEST_Y, pptDest->y); ! 2819: ! 2820: OUTPW(CMD, Cmd); ! 2821: } ! 2822: ! 2823: if (iyBlits != 0) ! 2824: { ! 2825: FIFOWAIT(FIFO_1_EMPTY); ! 2826: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (COLOR_VERT_EXPANSION_CACHE_CY - 8) - 1)); ! 2827: } ! 2828: ! 2829: for (j = 0; j <iyBlits; j++) ! 2830: { ! 2831: FIFOWAIT(FIFO_5_EMPTY); ! 2832: ! 2833: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset); ! 2834: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y); ! 2835: OUTPW(DEST_X, pptDest->x + (i * 8)); ! 2836: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 2837: (j * (COLOR_VERT_EXPANSION_CACHE_CY - 8))); ! 2838: ! 2839: OUTPW(CMD, Cmd); ! 2840: } ! 2841: ! 2842: if (iyLast != 0) ! 2843: { ! 2844: FIFOWAIT(FIFO_6_EMPTY); ! 2845: ! 2846: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1)); ! 2847: ! 2848: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset); ! 2849: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y); ! 2850: OUTPW(DEST_X, pptDest->x + (i * 8)); ! 2851: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 2852: (iyBlits * (COLOR_VERT_EXPANSION_CACHE_CY - 8))); ! 2853: ! 2854: OUTPW(CMD, Cmd); ! 2855: } ! 2856: } ! 2857: ! 2858: if (ixLast != 0) ! 2859: { ! 2860: FIFOWAIT(FIFO_1_EMPTY); ! 2861: OUTPW(RECT_WIDTH, ixLast - 1); ! 2862: ! 2863: ASSERTS3(((pptDest->x + (ixBlits * 8) + (ixLast - 1)) < (INT) ppdev->cxScreen), ! 2864: "S3.DLL!bColorVertCacheToScreen - Blit Operation over right edge (2)\n"); ! 2865: ! 2866: if (iyFirst != 0) ! 2867: { ! 2868: FIFOWAIT(FIFO_6_EMPTY); ! 2869: ! 2870: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1)); ! 2871: ! 2872: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset); ! 2873: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y + yOffset); ! 2874: OUTPW(DEST_X, pptDest->x + (ixBlits * 8)); ! 2875: OUTPW(DEST_Y, pptDest->y); ! 2876: ! 2877: OUTPW(CMD, Cmd); ! 2878: } ! 2879: ! 2880: if (iyBlits != 0) ! 2881: { ! 2882: FIFOWAIT(FIFO_1_EMPTY); ! 2883: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (COLOR_VERT_EXPANSION_CACHE_CY - 8) - 1)); ! 2884: } ! 2885: ! 2886: for (j = 0; j <iyBlits; j++) ! 2887: { ! 2888: FIFOWAIT(FIFO_5_EMPTY); ! 2889: ! 2890: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset); ! 2891: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y); ! 2892: OUTPW(DEST_X, pptDest->x + (ixBlits * 8)); ! 2893: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 2894: (j * (COLOR_VERT_EXPANSION_CACHE_CY - 8))); ! 2895: ! 2896: OUTPW(CMD, Cmd); ! 2897: } ! 2898: ! 2899: if (iyLast != 0) ! 2900: { ! 2901: FIFOWAIT(FIFO_6_EMPTY); ! 2902: ! 2903: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1)); ! 2904: ! 2905: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset); ! 2906: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y); ! 2907: OUTPW(DEST_X, pptDest->x + (ixBlits * 8)); ! 2908: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 2909: (iyBlits * (COLOR_VERT_EXPANSION_CACHE_CY - 8))); ! 2910: ! 2911: OUTPW(CMD, Cmd); ! 2912: } ! 2913: } ! 2914: ! 2915: return(TRUE); ! 2916: } ! 2917: ! 2918: /***************************************************************************** ! 2919: * Color expand the monochrome brush in the Vertical Cache to the screen. ! 2920: ****************************************************************************/ ! 2921: BOOL bColorExpandVertCacheToScreen( ! 2922: PPDEV ppdev, ! 2923: PS3BRUSH ps3Brush, ! 2924: INT zVert, ! 2925: PPOINT pptBrushOrg, ! 2926: PPOINT pptDest, ! 2927: PSIZE psizDest, ! 2928: WORD s3ForeRop, ! 2929: WORD s3BackRop) ! 2930: { ! 2931: WORD Cmd; ! 2932: INT ixBlits, ixLast, ! 2933: iyFirst, iyBlits, iyLast, ! 2934: xOffset, yOffset, ! 2935: i, j; ! 2936: ! 2937: DISPDBG((3, "S3.DLL!bColorExpandVertCacheToScreen - Entry\n")); ! 2938: ! 2939: // Take into account the pptBrushOrg. ! 2940: ! 2941: xOffset = pptDest->x - pptBrushOrg->x; ! 2942: yOffset = pptDest->y - pptBrushOrg->y; ! 2943: ! 2944: if (xOffset < 0) ! 2945: xOffset = 8 - (-xOffset % 8); ! 2946: else ! 2947: xOffset %= 8; ! 2948: ! 2949: if (yOffset < 0) ! 2950: yOffset = 8 - (-yOffset % 8); ! 2951: else ! 2952: yOffset %= 8; ! 2953: ! 2954: // Color Expand the monochrome vertical cache to the screen. ! 2955: // This is done in a loop to handle the general case ROPs. ! 2956: ! 2957: if (psizDest->cy < 8 - yOffset) ! 2958: { ! 2959: iyFirst = psizDest->cy; ! 2960: iyBlits = 0; ! 2961: iyLast = 0; ! 2962: ! 2963: } ! 2964: else if (psizDest->cy - yOffset < MONO_VERT_EXPANSION_CACHE_CY - 8) ! 2965: { ! 2966: iyFirst = 8 - yOffset; ! 2967: iyBlits = 0; ! 2968: iyLast = psizDest->cy - iyFirst; ! 2969: } ! 2970: else ! 2971: { ! 2972: iyFirst = 8 - yOffset; ! 2973: iyBlits = (psizDest->cy - iyFirst) / (MONO_VERT_EXPANSION_CACHE_CY - 8); ! 2974: iyLast = (psizDest->cy - iyFirst) % (MONO_VERT_EXPANSION_CACHE_CY - 8); ! 2975: } ! 2976: ! 2977: ixBlits = psizDest->cx / 8; ! 2978: ixLast = psizDest->cx % 8; ! 2979: ! 2980: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 2981: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM; ! 2982: ! 2983: FIFOWAIT(FIFO_7_EMPTY); ! 2984: ! 2985: TEST_AND_SET_RD_MASK(zVert); ! 2986: ! 2987: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3ForeRop); ! 2988: TEST_AND_SET_FRGD_COLOR(LOWORD(ps3Brush->ulForeColor)); ! 2989: ! 2990: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | s3BackRop); ! 2991: SET_BKGD_COLOR(LOWORD(ps3Brush->ulBackColor)); ! 2992: ! 2993: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY)); ! 2994: ! 2995: OUTPW(RECT_WIDTH, 7); ! 2996: ! 2997: for(i = 0; i < ixBlits; i++) ! 2998: { ! 2999: ASSERTS3(((pptDest->x + (i * 8) + 7) < (INT) ppdev->cxScreen), ! 3000: "S3.DLL!bColorExpandVertCacheToScreen - Blit Operation over right edge (1)\n"); ! 3001: ! 3002: if (iyFirst != 0) ! 3003: { ! 3004: FIFOWAIT(FIFO_6_EMPTY); ! 3005: ! 3006: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1)); ! 3007: ! 3008: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset); ! 3009: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y + yOffset); ! 3010: OUTPW(DEST_X, pptDest->x + (i * 8)); ! 3011: OUTPW(DEST_Y, pptDest->y); ! 3012: ! 3013: OUTPW(CMD, Cmd); ! 3014: } ! 3015: ! 3016: if (iyBlits != 0) ! 3017: { ! 3018: FIFOWAIT(FIFO_1_EMPTY); ! 3019: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (MONO_VERT_EXPANSION_CACHE_CY - 8) - 1)); ! 3020: } ! 3021: ! 3022: for (j = 0; j <iyBlits; j++) ! 3023: { ! 3024: FIFOWAIT(FIFO_5_EMPTY); ! 3025: ! 3026: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset); ! 3027: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y); ! 3028: OUTPW(DEST_X, pptDest->x + (i * 8)); ! 3029: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 3030: (j * (MONO_VERT_EXPANSION_CACHE_CY - 8))); ! 3031: ! 3032: OUTPW(CMD, Cmd); ! 3033: } ! 3034: ! 3035: if (iyLast != 0) ! 3036: { ! 3037: FIFOWAIT(FIFO_6_EMPTY); ! 3038: ! 3039: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1)); ! 3040: ! 3041: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset); ! 3042: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y); ! 3043: OUTPW(DEST_X, pptDest->x + (i * 8)); ! 3044: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 3045: (iyBlits * (MONO_VERT_EXPANSION_CACHE_CY - 8))); ! 3046: ! 3047: OUTPW(CMD, Cmd); ! 3048: } ! 3049: } ! 3050: ! 3051: if (ixLast != 0) ! 3052: { ! 3053: FIFOWAIT(FIFO_1_EMPTY); ! 3054: OUTPW(RECT_WIDTH, ixLast - 1); ! 3055: ! 3056: ASSERTS3(((pptDest->x + (ixBlits * 8) + (ixLast - 1)) < (INT) ppdev->cxScreen), ! 3057: "S3.DLL!bColorExpandVertCacheToScreen - Blit Operation over right edge (2)\n"); ! 3058: ! 3059: if (iyFirst != 0) ! 3060: { ! 3061: FIFOWAIT(FIFO_6_EMPTY); ! 3062: ! 3063: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1)); ! 3064: ! 3065: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset); ! 3066: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y + yOffset); ! 3067: OUTPW(DEST_X, pptDest->x + (ixBlits * 8)); ! 3068: OUTPW(DEST_Y, pptDest->y); ! 3069: ! 3070: OUTPW(CMD, Cmd); ! 3071: } ! 3072: ! 3073: if (iyBlits != 0) ! 3074: { ! 3075: FIFOWAIT(FIFO_1_EMPTY); ! 3076: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (MONO_VERT_EXPANSION_CACHE_CY - 8) - 1)); ! 3077: } ! 3078: ! 3079: for (j = 0; j <iyBlits; j++) ! 3080: { ! 3081: FIFOWAIT(FIFO_5_EMPTY); ! 3082: ! 3083: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset); ! 3084: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y); ! 3085: OUTPW(DEST_X, pptDest->x + (ixBlits * 8)); ! 3086: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 3087: (j * (MONO_VERT_EXPANSION_CACHE_CY - 8))); ! 3088: ! 3089: OUTPW(CMD, Cmd); ! 3090: } ! 3091: ! 3092: if (iyLast != 0) ! 3093: { ! 3094: FIFOWAIT(FIFO_6_EMPTY); ! 3095: ! 3096: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1)); ! 3097: ! 3098: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset); ! 3099: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y); ! 3100: OUTPW(DEST_X, pptDest->x + (ixBlits * 8)); ! 3101: OUTPW(DEST_Y, pptDest->y + iyFirst + ! 3102: (iyBlits * (MONO_VERT_EXPANSION_CACHE_CY - 8))); ! 3103: ! 3104: OUTPW(CMD, Cmd); ! 3105: } ! 3106: } ! 3107: ! 3108: // Reset the Read Mask ! 3109: ! 3110: FIFOWAIT(FIFO_2_EMPTY); ! 3111: ! 3112: TEST_AND_SET_WRT_MASK(0xff); ! 3113: TEST_AND_SET_RD_MASK(0xff); ! 3114: ! 3115: return(TRUE); ! 3116: } ! 3117: ! 3118: ! 3119: /***************************************************************************** ! 3120: * Color brush in the Hoizontal Cache to the screen. ! 3121: ****************************************************************************/ ! 3122: BOOL bColorHorzCacheToScreen( ! 3123: PPDEV ppdev, ! 3124: PS3BRUSH ps3Brush, ! 3125: PPOINT pptBrushOrg, ! 3126: PPOINT pptDest, ! 3127: PSIZE psizDest, ! 3128: WORD s3ForeRop, ! 3129: WORD s3BackRop) ! 3130: { ! 3131: WORD Cmd; ! 3132: INT xLeft, cxLeft, cxRight, ixBlits, i, j, x, cx, ! 3133: iyBlits, iyLast, ! 3134: xOffset, yOffset; ! 3135: ! 3136: DISPDBG((3, "S3.DLL!bColorHorzCacheToScreen - Entry\n")); ! 3137: ! 3138: // Take into account the pptBrushOrg. ! 3139: ! 3140: xOffset = pptDest->x - pptBrushOrg->x; ! 3141: yOffset = pptDest->y - pptBrushOrg->y; ! 3142: ! 3143: if (xOffset < 0) ! 3144: xOffset = 8 - (-xOffset % 8); ! 3145: else ! 3146: xOffset %= 8; ! 3147: ! 3148: if (yOffset < 0) ! 3149: yOffset = 8 - (-yOffset % 8); ! 3150: else ! 3151: yOffset %= 8; ! 3152: ! 3153: // Color Expand the monochrome horizontal cache to the screen. ! 3154: // This is done in a loop to handle the general case ROPs. ! 3155: ! 3156: xLeft = pptDest->x; ! 3157: cxLeft = COLOR_HORZ_EXPANSION_CACHE_CX - xOffset; ! 3158: ! 3159: if ((cx = psizDest->cx - cxLeft) < 0) ! 3160: { ! 3161: cxLeft = psizDest->cx; ! 3162: ixBlits = 0; ! 3163: cxRight = 0; ! 3164: } ! 3165: else ! 3166: { ! 3167: ixBlits = cx / COLOR_HORZ_EXPANSION_CACHE_CX; ! 3168: cxRight = cx % COLOR_HORZ_EXPANSION_CACHE_CX; ! 3169: } ! 3170: ! 3171: iyBlits = psizDest->cy / 8; ! 3172: iyLast = psizDest->cy % 8; ! 3173: ! 3174: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 3175: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM; ! 3176: ! 3177: FIFOWAIT(FIFO_3_EMPTY); ! 3178: ! 3179: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | s3ForeRop); ! 3180: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 3181: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7)); ! 3182: ! 3183: for (i = 0; i < iyBlits; i++) ! 3184: { ! 3185: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen), ! 3186: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (1)\n"); ! 3187: ! 3188: FIFOWAIT(FIFO_6_EMPTY); ! 3189: ! 3190: OUTPW(RECT_WIDTH, cxLeft - 1); ! 3191: ! 3192: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X + xOffset); ! 3193: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3194: OUTPW(DEST_X, pptDest->x); ! 3195: OUTPW(DEST_Y, pptDest->y + (i * 8)); ! 3196: ! 3197: OUTPW(CMD, Cmd); ! 3198: ! 3199: // If the the cxDest is wider than the cxHorzCache then fill in the ! 3200: // right side of the fill area. ! 3201: ! 3202: if (cx > 0) ! 3203: { ! 3204: FIFOWAIT(FIFO_1_EMPTY); ! 3205: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 1); ! 3206: ! 3207: for (j = 0; j < ixBlits; j++) ! 3208: { ! 3209: x = pptDest->x + cxLeft + (j * COLOR_HORZ_EXPANSION_CACHE_CX); ! 3210: ! 3211: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen), ! 3212: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (2)\n"); ! 3213: ! 3214: FIFOWAIT(FIFO_5_EMPTY); ! 3215: ! 3216: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 3217: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3218: OUTPW(DEST_X, x); ! 3219: OUTPW(DEST_Y, pptDest->y + (i * 8)); ! 3220: ! 3221: OUTPW(CMD, Cmd); ! 3222: } ! 3223: ! 3224: if (cxRight != 0) ! 3225: { ! 3226: x = pptDest->x + cxLeft + (ixBlits * COLOR_HORZ_EXPANSION_CACHE_CX); ! 3227: ! 3228: ASSERTS3(((x + (cxRight - 1)) < (INT) ppdev->cxScreen), ! 3229: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (3)\n"); ! 3230: ! 3231: FIFOWAIT(FIFO_6_EMPTY); ! 3232: ! 3233: OUTPW(RECT_WIDTH, cxRight - 1); ! 3234: ! 3235: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 3236: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3237: OUTPW(DEST_X, x); ! 3238: OUTPW(DEST_Y, pptDest->y + (i * 8)); ! 3239: ! 3240: OUTPW(CMD, Cmd); ! 3241: } ! 3242: } ! 3243: } ! 3244: ! 3245: if (iyLast != 0) ! 3246: { ! 3247: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen), ! 3248: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (4)\n"); ! 3249: ! 3250: FIFOWAIT(FIFO_7_EMPTY); ! 3251: ! 3252: OUTPW(RECT_WIDTH, cxLeft - 1); ! 3253: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1)); ! 3254: ! 3255: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X + xOffset); ! 3256: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3257: OUTPW(DEST_X, pptDest->x); ! 3258: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8)); ! 3259: ! 3260: OUTPW(CMD, Cmd); ! 3261: ! 3262: // If the the cxDest is wider than the cxHorzCache then fill in the ! 3263: // right side of the fill area. ! 3264: ! 3265: if (cx > 0) ! 3266: { ! 3267: FIFOWAIT(FIFO_1_EMPTY); ! 3268: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 1); ! 3269: ! 3270: for (j = 0; j < ixBlits; j++) ! 3271: { ! 3272: x = pptDest->x + cxLeft + (j * COLOR_HORZ_EXPANSION_CACHE_CX); ! 3273: ! 3274: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen), ! 3275: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (5)\n"); ! 3276: ! 3277: FIFOWAIT(FIFO_5_EMPTY); ! 3278: ! 3279: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 3280: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3281: OUTPW(DEST_X, x); ! 3282: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8)); ! 3283: ! 3284: OUTPW(CMD, Cmd); ! 3285: } ! 3286: ! 3287: if (cxRight != 0) ! 3288: { ! 3289: x = pptDest->x + cxLeft + (ixBlits * COLOR_HORZ_EXPANSION_CACHE_CX); ! 3290: ! 3291: ASSERTS3(((x + (cxRight - 1)) < (INT) ppdev->cxScreen), ! 3292: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (6)\n"); ! 3293: ! 3294: FIFOWAIT(FIFO_6_EMPTY); ! 3295: ! 3296: OUTPW(RECT_WIDTH, cxRight - 1); ! 3297: ! 3298: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 3299: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3300: OUTPW(DEST_X, x); ! 3301: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8)); ! 3302: ! 3303: OUTPW(CMD, Cmd); ! 3304: } ! 3305: } ! 3306: } ! 3307: ! 3308: return(TRUE); ! 3309: } ! 3310: ! 3311: /***************************************************************************** ! 3312: * Color expand the monochrome brush in the Hoizontal Cache to the screen. ! 3313: ****************************************************************************/ ! 3314: BOOL bColorExpandHorzCacheToScreen( ! 3315: PPDEV ppdev, ! 3316: PS3BRUSH ps3Brush, ! 3317: INT zHorz, ! 3318: PPOINT pptBrushOrg, ! 3319: PPOINT pptDest, ! 3320: PSIZE psizDest, ! 3321: WORD s3ForeRop, ! 3322: WORD s3BackRop) ! 3323: { ! 3324: WORD Cmd; ! 3325: INT xLeft, cxLeft, xMiddle, cxMiddle, xRight, cxRight, i, ! 3326: iyBlits, iyLast, ! 3327: xOffset, yOffset; ! 3328: ! 3329: DISPDBG((3, "S3.DLL!bColorExpandHorzCacheToScreen - Entry\n")); ! 3330: ! 3331: // Take into account the pptBrushOrg. ! 3332: ! 3333: xOffset = pptDest->x - pptBrushOrg->x; ! 3334: yOffset = pptDest->y - pptBrushOrg->y; ! 3335: ! 3336: if (xOffset < 0) ! 3337: xOffset = 8 - (-xOffset % 8); ! 3338: else ! 3339: xOffset %= 8; ! 3340: ! 3341: if (yOffset < 0) ! 3342: yOffset = 8 - (-yOffset % 8); ! 3343: else ! 3344: yOffset %= 8; ! 3345: ! 3346: // Color Expand the monochrome horizontal cache to the screen. ! 3347: // This is done in a loop to handle the general case ROPs. ! 3348: ! 3349: xLeft = pptDest->x; ! 3350: cxLeft = MONO_HORZ_EXPANSION_CACHE_CX - xOffset; ! 3351: ! 3352: if (psizDest->cx < cxLeft) ! 3353: { ! 3354: cxLeft = psizDest->cx; ! 3355: xRight = 0; ! 3356: cxRight = 0; ! 3357: } ! 3358: else ! 3359: { ! 3360: xRight = pptDest->x + cxLeft; ! 3361: cxRight = psizDest->cx - cxLeft; ! 3362: } ! 3363: ! 3364: // This little hack is for 1280 mode. ! 3365: // Really the correct solution is to use the H/W support. ! 3366: ! 3367: if (cxRight > MONO_HORZ_EXPANSION_CACHE_CX) ! 3368: { ! 3369: xMiddle = xRight; ! 3370: xRight += MONO_HORZ_EXPANSION_CACHE_CX; ! 3371: cxMiddle = MONO_HORZ_EXPANSION_CACHE_CX; ! 3372: cxRight -= MONO_HORZ_EXPANSION_CACHE_CX; ! 3373: } ! 3374: else ! 3375: { ! 3376: xMiddle = 0; ! 3377: cxMiddle = 0; ! 3378: } ! 3379: ! 3380: iyBlits = psizDest->cy / 8; ! 3381: iyLast = psizDest->cy % 8; ! 3382: ! 3383: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 3384: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM; ! 3385: ! 3386: FIFOWAIT(FIFO_7_EMPTY); ! 3387: ! 3388: TEST_AND_SET_RD_MASK(zHorz); ! 3389: ! 3390: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3ForeRop); ! 3391: TEST_AND_SET_FRGD_COLOR(LOWORD(ps3Brush->ulForeColor)); ! 3392: ! 3393: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | s3BackRop); ! 3394: SET_BKGD_COLOR(LOWORD(ps3Brush->ulBackColor)); ! 3395: ! 3396: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY)); ! 3397: ! 3398: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7)); ! 3399: ! 3400: for (i = 0; i < iyBlits; i++) ! 3401: { ! 3402: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen), ! 3403: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (1)\n"); ! 3404: ! 3405: FIFOWAIT(FIFO_6_EMPTY); ! 3406: ! 3407: OUTPW(RECT_WIDTH, cxLeft - 1); ! 3408: ! 3409: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X + xOffset); ! 3410: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3411: OUTPW(DEST_X, pptDest->x); ! 3412: OUTPW(DEST_Y, pptDest->y + (i * 8)); ! 3413: ! 3414: OUTPW(CMD, Cmd); ! 3415: ! 3416: if (cxMiddle != 0) ! 3417: { ! 3418: ASSERTS3(((xMiddle + (cxMiddle - 1)) < (INT) ppdev->cxScreen), ! 3419: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (2)\n"); ! 3420: ! 3421: FIFOWAIT(FIFO_6_EMPTY); ! 3422: ! 3423: OUTPW(RECT_WIDTH, cxMiddle - 1); ! 3424: ! 3425: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 3426: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3427: OUTPW(DEST_X, xMiddle); ! 3428: OUTPW(DEST_Y, pptDest->y + (i * 8)); ! 3429: ! 3430: OUTPW(CMD, Cmd); ! 3431: } ! 3432: ! 3433: // If the the cxDest is wider than the cxHorzCache then fill in the ! 3434: // right side of the fill area. ! 3435: ! 3436: if (cxRight != 0) ! 3437: { ! 3438: ASSERTS3(((xRight + (cxRight - 1)) < (INT) ppdev->cxScreen), ! 3439: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (3)\n"); ! 3440: ! 3441: FIFOWAIT(FIFO_6_EMPTY); ! 3442: ! 3443: OUTPW(RECT_WIDTH, cxRight - 1); ! 3444: ! 3445: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 3446: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3447: OUTPW(DEST_X, xRight); ! 3448: OUTPW(DEST_Y, pptDest->y + (i * 8)); ! 3449: ! 3450: OUTPW(CMD, Cmd); ! 3451: } ! 3452: } ! 3453: ! 3454: if (iyLast != 0) ! 3455: { ! 3456: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen), ! 3457: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (3)\n"); ! 3458: ! 3459: FIFOWAIT(FIFO_7_EMPTY); ! 3460: ! 3461: OUTPW(RECT_WIDTH, cxLeft - 1); ! 3462: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1)); ! 3463: ! 3464: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X + xOffset); ! 3465: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3466: OUTPW(DEST_X, pptDest->x); ! 3467: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8)); ! 3468: ! 3469: OUTPW(CMD, Cmd); ! 3470: ! 3471: if (cxMiddle != 0) ! 3472: { ! 3473: ASSERTS3(((xMiddle + (cxMiddle - 1)) < (INT) ppdev->cxScreen), ! 3474: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (4)\n"); ! 3475: ! 3476: FIFOWAIT(FIFO_6_EMPTY); ! 3477: ! 3478: OUTPW(RECT_WIDTH, cxMiddle - 1); ! 3479: ! 3480: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 3481: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3482: OUTPW(DEST_X, xMiddle); ! 3483: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8)); ! 3484: ! 3485: OUTPW(CMD, Cmd); ! 3486: } ! 3487: ! 3488: // If the the cxDest is wider than the cxHorzCache then fill in the ! 3489: // right side of the fill area. ! 3490: ! 3491: if (cxRight != 0) ! 3492: { ! 3493: ASSERTS3(((xRight + (cxRight - 1)) < (INT) ppdev->cxScreen), ! 3494: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (4)\n"); ! 3495: ! 3496: FIFOWAIT(FIFO_6_EMPTY); ! 3497: ! 3498: OUTPW(RECT_WIDTH, cxRight - 1); ! 3499: ! 3500: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 3501: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3502: OUTPW(DEST_X, xRight); ! 3503: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8)); ! 3504: ! 3505: OUTPW(CMD, Cmd); ! 3506: } ! 3507: } ! 3508: ! 3509: // Reset the Read Mask ! 3510: ! 3511: FIFOWAIT(FIFO_2_EMPTY); ! 3512: ! 3513: TEST_AND_SET_WRT_MASK(0xff); ! 3514: TEST_AND_SET_RD_MASK(0xff); ! 3515: ! 3516: return(TRUE); ! 3517: } ! 3518: ! 3519: ! 3520: /***************************************************************************** ! 3521: * Copy Optimized ! 3522: * Color brush in the Hoizontal Cache to the screen. ! 3523: ****************************************************************************/ ! 3524: BOOL bCpyColorHorzCacheToScreen( ! 3525: PPDEV ppdev, ! 3526: PS3BRUSH ps3Brush, ! 3527: PPOINT pptBrushOrg, ! 3528: PPOINT pptDest, ! 3529: PSIZE psizDest) ! 3530: { ! 3531: WORD Cmd; ! 3532: INT cx, cxLeft, ixBlits, ixLast, i, ! 3533: cy, x, xOffset, yOffset; ! 3534: ! 3535: DISPDBG((3, "S3.DLL!bCpyColorHorzCacheToScreen - Entry\n")); ! 3536: ! 3537: // Take into account the pptBrushOrg. ! 3538: ! 3539: xOffset = pptDest->x - pptBrushOrg->x; ! 3540: yOffset = pptDest->y - pptBrushOrg->y; ! 3541: ! 3542: if (xOffset < 0) ! 3543: xOffset = 8 - (-xOffset % 8); ! 3544: else ! 3545: xOffset %= 8; ! 3546: ! 3547: if (yOffset < 0) ! 3548: yOffset = 8 - (-yOffset % 8); ! 3549: else ! 3550: yOffset %= 8; ! 3551: ! 3552: // First Color Expand the monochrome horizontal cache to the screen. ! 3553: ! 3554: cxLeft = COLOR_HORZ_EXPANSION_CACHE_CX - xOffset; ! 3555: if (psizDest->cx < cxLeft) ! 3556: cxLeft = psizDest->cx; ! 3557: ! 3558: cy = 8; ! 3559: if (psizDest->cy < cy) ! 3560: cy = psizDest->cy; ! 3561: ! 3562: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 3563: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM; ! 3564: ! 3565: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen), ! 3566: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (1)\n"); ! 3567: ! 3568: FIFOWAIT(FIFO_2_EMPTY); ! 3569: ! 3570: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 3571: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 3572: ! 3573: FIFOWAIT(FIFO_7_EMPTY); ! 3574: ! 3575: OUTPW(RECT_WIDTH, cxLeft - 1); ! 3576: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (cy - 1))); ! 3577: ! 3578: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X + xOffset); ! 3579: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3580: OUTPW(DEST_X, pptDest->x); ! 3581: OUTPW(DEST_Y, pptDest->y); ! 3582: ! 3583: OUTPW(CMD, Cmd); ! 3584: ! 3585: // If the the cxDest is wider than the cxHorzCache then fill in the ! 3586: // right side of the fill area. ! 3587: ! 3588: if ((cx = psizDest->cx - cxLeft) > 0) ! 3589: { ! 3590: ixBlits = cx / COLOR_HORZ_EXPANSION_CACHE_CX; ! 3591: ixLast = cx % COLOR_HORZ_EXPANSION_CACHE_CX; ! 3592: ! 3593: FIFOWAIT(FIFO_1_EMPTY); ! 3594: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 1); ! 3595: ! 3596: for (i = 0; i < ixBlits; i++) ! 3597: { ! 3598: x = pptDest->x + cxLeft + (i * COLOR_HORZ_EXPANSION_CACHE_CX); ! 3599: ! 3600: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen), ! 3601: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (2)\n"); ! 3602: ! 3603: FIFOWAIT(FIFO_5_EMPTY); ! 3604: ! 3605: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 3606: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3607: OUTPW(DEST_X, x); ! 3608: OUTPW(DEST_Y, pptDest->y); ! 3609: ! 3610: OUTPW(CMD, Cmd); ! 3611: } ! 3612: ! 3613: if (ixLast != 0) ! 3614: { ! 3615: x = pptDest->x + cxLeft + (ixBlits * COLOR_HORZ_EXPANSION_CACHE_CX); ! 3616: ! 3617: ASSERTS3(((x + (ixLast - 1)) < (INT) ppdev->cxScreen), ! 3618: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (3)\n"); ! 3619: ! 3620: FIFOWAIT(FIFO_6_EMPTY); ! 3621: ! 3622: OUTPW(RECT_WIDTH, ixLast - 1); ! 3623: ! 3624: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X); ! 3625: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3626: OUTPW(DEST_X, x); ! 3627: OUTPW(DEST_Y, pptDest->y); ! 3628: ! 3629: OUTPW(CMD, Cmd); ! 3630: } ! 3631: } ! 3632: ! 3633: // If the cyDest is taller than 8 pels do a rolling blit to fill in ! 3634: // the bottom of the fill area. ! 3635: ! 3636: if (psizDest->cy > 8) ! 3637: { ! 3638: ASSERTS3(((pptDest->x + (psizDest->cx - 1)) < (INT) ppdev->cxScreen), ! 3639: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (4)\n"); ! 3640: ! 3641: FIFOWAIT(FIFO_7_EMPTY); ! 3642: ! 3643: OUTPW(RECT_WIDTH, psizDest->cx - 1); ! 3644: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | psizDest->cy - (cy + 1))); ! 3645: ! 3646: OUTPW(CUR_X, pptDest->x); ! 3647: OUTPW(CUR_Y, pptDest->y); ! 3648: OUTPW(DEST_X, pptDest->x); ! 3649: OUTPW(DEST_Y, pptDest->y + 8); ! 3650: ! 3651: OUTPW(CMD, Cmd); ! 3652: } ! 3653: ! 3654: return(TRUE); ! 3655: } ! 3656: ! 3657: /***************************************************************************** ! 3658: * Copy Optimized ! 3659: * Color expand the monochrome brush in the Hoizontal Cache to the screen. ! 3660: ****************************************************************************/ ! 3661: BOOL bCpyColorExpandHorzCacheToScreen( ! 3662: PPDEV ppdev, ! 3663: PS3BRUSH ps3Brush, ! 3664: INT zHorz, ! 3665: PPOINT pptBrushOrg, ! 3666: PPOINT pptDest, ! 3667: PSIZE psizDest) ! 3668: { ! 3669: WORD Cmd; ! 3670: INT cx, cxLeft, ixBlits, ixLast, i, ! 3671: cy, x, xOffset, yOffset; ! 3672: ! 3673: DISPDBG((3, "S3.DLL!bCpyColorExpandHorzCacheToScreen - Entry\n")); ! 3674: ! 3675: // Take into account the pptBrushOrg. ! 3676: ! 3677: xOffset = pptDest->x - pptBrushOrg->x; ! 3678: yOffset = pptDest->y - pptBrushOrg->y; ! 3679: ! 3680: if (xOffset < 0) ! 3681: xOffset = 8 - (-xOffset % 8); ! 3682: else ! 3683: xOffset %= 8; ! 3684: ! 3685: if (yOffset < 0) ! 3686: yOffset = 8 - (-yOffset % 8); ! 3687: else ! 3688: yOffset %= 8; ! 3689: ! 3690: // First Color Expand the monochrome horizontal cache to the screen. ! 3691: ! 3692: cxLeft = MONO_HORZ_EXPANSION_CACHE_CX - xOffset; ! 3693: if (psizDest->cx < cxLeft) ! 3694: cxLeft = psizDest->cx; ! 3695: ! 3696: cy = 8; ! 3697: if (psizDest->cy < cy) ! 3698: cy = psizDest->cy; ! 3699: ! 3700: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE | ! 3701: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM; ! 3702: ! 3703: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen), ! 3704: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (1)\n"); ! 3705: ! 3706: FIFOWAIT(FIFO_6_EMPTY); ! 3707: ! 3708: TEST_AND_SET_RD_MASK(zHorz); ! 3709: ! 3710: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT); ! 3711: TEST_AND_SET_FRGD_COLOR(LOWORD(ps3Brush->ulForeColor)); ! 3712: ! 3713: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT); ! 3714: SET_BKGD_COLOR(LOWORD(ps3Brush->ulBackColor)); ! 3715: ! 3716: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY)); ! 3717: ! 3718: FIFOWAIT(FIFO_7_EMPTY); ! 3719: ! 3720: OUTPW(RECT_WIDTH, cxLeft - 1); ! 3721: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (cy - 1))); ! 3722: ! 3723: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X + xOffset); ! 3724: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3725: OUTPW(DEST_X, pptDest->x); ! 3726: OUTPW(DEST_Y, pptDest->y); ! 3727: ! 3728: OUTPW(CMD, Cmd); ! 3729: ! 3730: // If the the cxDest is wider than the cxHorzCache then fill in the ! 3731: // right side of the fill area. ! 3732: ! 3733: if ((cx = psizDest->cx - cxLeft) > 0) ! 3734: { ! 3735: ixBlits = cx / MONO_HORZ_EXPANSION_CACHE_CX; ! 3736: ixLast = cx % MONO_HORZ_EXPANSION_CACHE_CX; ! 3737: ! 3738: FIFOWAIT(FIFO_1_EMPTY); ! 3739: OUTPW(RECT_WIDTH, MONO_HORZ_EXPANSION_CACHE_CX - 1); ! 3740: ! 3741: for (i = 0; i < ixBlits; i++) ! 3742: { ! 3743: x = pptDest->x + cxLeft + (i * MONO_HORZ_EXPANSION_CACHE_CX); ! 3744: ! 3745: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen), ! 3746: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (2)\n"); ! 3747: ! 3748: FIFOWAIT(FIFO_5_EMPTY); ! 3749: ! 3750: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 3751: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3752: OUTPW(DEST_X, x); ! 3753: OUTPW(DEST_Y, pptDest->y); ! 3754: ! 3755: OUTPW(CMD, Cmd); ! 3756: } ! 3757: ! 3758: if (ixLast != 0) ! 3759: { ! 3760: x = pptDest->x + cxLeft + (ixBlits * MONO_HORZ_EXPANSION_CACHE_CX); ! 3761: ! 3762: ASSERTS3(((x + (ixLast - 1)) < (INT) ppdev->cxScreen), ! 3763: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (3)\n"); ! 3764: ! 3765: FIFOWAIT(FIFO_6_EMPTY); ! 3766: ! 3767: OUTPW(RECT_WIDTH, ixLast - 1); ! 3768: ! 3769: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X); ! 3770: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset); ! 3771: OUTPW(DEST_X, x); ! 3772: OUTPW(DEST_Y, pptDest->y); ! 3773: ! 3774: OUTPW(CMD, Cmd); ! 3775: } ! 3776: } ! 3777: ! 3778: // If the cyDest is taller than 8 pels do a rolling blit to fill in ! 3779: // the bottom of the fill area. ! 3780: ! 3781: if (psizDest->cy > 8) ! 3782: { ! 3783: ASSERTS3(((pptDest->x + (psizDest->cx - 1)) < (INT) ppdev->cxScreen), ! 3784: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (4)\n"); ! 3785: ! 3786: FIFOWAIT(FIFO_2_EMPTY); ! 3787: ! 3788: TEST_AND_SET_RD_MASK(0xff); ! 3789: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT); ! 3790: ! 3791: FIFOWAIT(FIFO_8_EMPTY); ! 3792: ! 3793: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 3794: ! 3795: OUTPW(RECT_WIDTH, psizDest->cx - 1); ! 3796: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | psizDest->cy - (cy + 1))); ! 3797: ! 3798: OUTPW(CUR_X, pptDest->x); ! 3799: OUTPW(CUR_Y, pptDest->y); ! 3800: OUTPW(DEST_X, pptDest->x); ! 3801: OUTPW(DEST_Y, pptDest->y + 8); ! 3802: ! 3803: OUTPW(CMD, Cmd); ! 3804: } ! 3805: ! 3806: // Reset the Read Mask ! 3807: ! 3808: FIFOWAIT(FIFO_2_EMPTY); ! 3809: ! 3810: TEST_AND_SET_WRT_MASK(0xff); ! 3811: TEST_AND_SET_RD_MASK(0xff); ! 3812: ! 3813: return(TRUE); ! 3814: } ! 3815: ! 3816: ! 3817: /***************************************************************************** ! 3818: * S3 Solid Pattern ! 3819: * ! 3820: * Returns TRUE if the blit was handled. ! 3821: ****************************************************************************/ ! 3822: BOOL bPatternSolid( ! 3823: SURFOBJ *psoTrg, ! 3824: SURFOBJ *psoSrc, ! 3825: SURFOBJ *psoMask, ! 3826: CLIPOBJ *pco, ! 3827: XLATEOBJ *pxlo, ! 3828: RECTL *prclTrg, ! 3829: POINTL *pptlSrc, ! 3830: POINTL *pptlMask, ! 3831: BRUSHOBJ *pbo, ! 3832: POINTL *pptlBrush, ! 3833: ROP4 s3Rop4) ! 3834: { ! 3835: INT width,height; ! 3836: WORD s3Mix; ! 3837: BOOL bMore; ! 3838: UINT i; ! 3839: ENUMRECTS8 EnumRects8; ! 3840: ! 3841: LONG rleft; // render coordinates ! 3842: LONG rtop; ! 3843: LONG rright; ! 3844: LONG rbottom; ! 3845: LONG cleft; // clip coorindates ! 3846: LONG ctop; ! 3847: LONG cright; ! 3848: LONG cbottom; ! 3849: LONG left; ! 3850: LONG top; ! 3851: RECTL rclBounds; ! 3852: BOOL bClipRequired, bDrawRequired; ! 3853: PPDEV ppdev; ! 3854: ! 3855: DISPDBG((3,"S3.DLL!bPatternSolid - Entry\n")); ! 3856: ! 3857: // Get the pdev. ! 3858: ! 3859: ppdev = (PPDEV) psoTrg->dhpdev; ! 3860: ! 3861: // Just use the for ground mix. ! 3862: ! 3863: s3Mix = (WORD) (s3Rop4 & 0xFF); ! 3864: ! 3865: // Dereference the target rectangle. ! 3866: ! 3867: rleft = prclTrg->left; ! 3868: rtop = prclTrg->top; ! 3869: rright = prclTrg->right; ! 3870: rbottom = prclTrg->bottom; ! 3871: ! 3872: // Use software clipping. It's faster than H/W clipping. ! 3873: ! 3874: if (pco->iDComplexity != DC_COMPLEX) ! 3875: { ! 3876: if (pco->iDComplexity == DC_TRIVIAL) ! 3877: { ! 3878: width = (rright - rleft) - 1; ! 3879: height = (rbottom - rtop) - 1; ! 3880: ! 3881: bDrawRequired = TRUE; ! 3882: } ! 3883: else ! 3884: { ! 3885: bDrawRequired = FALSE; ! 3886: ! 3887: rclBounds = pco->rclBounds; ! 3888: ! 3889: // First handle the trivial rejection. ! 3890: ! 3891: bClipRequired = bIntersectTest(prclTrg, &rclBounds); ! 3892: ! 3893: if (bClipRequired) ! 3894: { ! 3895: rleft = max (rleft, rclBounds.left); ! 3896: rtop = max (rtop, rclBounds.top); ! 3897: width = (min(rright, rclBounds.right) - rleft) - 1; ! 3898: height = (min(rbottom, rclBounds.bottom) - rtop) - 1; ! 3899: ! 3900: bDrawRequired = TRUE; ! 3901: } ! 3902: } ! 3903: ! 3904: if (bDrawRequired && width >= 0 && height >= 0) ! 3905: { ! 3906: vS3SolidPattern(ppdev, ! 3907: rleft, rtop, width, height, ! 3908: (pbo != NULL)? pbo->iSolidColor: 0, s3Mix); ! 3909: } ! 3910: } ! 3911: else ! 3912: { ! 3913: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); ! 3914: ! 3915: do ! 3916: { ! 3917: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), ! 3918: (PULONG) &EnumRects8); ! 3919: for (i = 0; i < EnumRects8.c; i++) ! 3920: { ! 3921: // Do a trivial reject on Y. ! 3922: ! 3923: if (rtop > (cbottom = EnumRects8.arcl[i].bottom)) ! 3924: continue; ! 3925: if (rbottom < (ctop = EnumRects8.arcl[i].top)) ! 3926: continue; ! 3927: ! 3928: // Do a trivial reject on X. ! 3929: ! 3930: if (rleft > (cright = EnumRects8.arcl[i].right)) ! 3931: continue; ! 3932: if (rright < (cleft = EnumRects8.arcl[i].left)) ! 3933: continue; ! 3934: ! 3935: // It's not a trivial reject, so calculate the ! 3936: // minimal clip area. ! 3937: ! 3938: left = max (rleft, cleft); ! 3939: top = max (rtop, ctop); ! 3940: width = (min(rright, cright) - left) - 1; ! 3941: height = (min(rbottom, cbottom) - top) - 1; ! 3942: ! 3943: if (width < 0 || height < 0) ! 3944: continue; ! 3945: ! 3946: vS3SolidPattern(ppdev, ! 3947: left, top, ! 3948: width, height, ! 3949: (pbo != NULL)? pbo->iSolidColor: 0, s3Mix); ! 3950: } ! 3951: } while (bMore); ! 3952: } ! 3953: ! 3954: return (TRUE); ! 3955: } ! 3956: ! 3957: /***************************************************************************** ! 3958: * vS3SolidPattern ! 3959: ****************************************************************************/ ! 3960: VOID vS3SolidPattern( ! 3961: PPDEV ppdev, ! 3962: INT left, ! 3963: INT top, ! 3964: INT width, ! 3965: INT height, ! 3966: INT color, ! 3967: WORD s3Mix) ! 3968: { ! 3969: FIFOWAIT(FIFO_8_EMPTY); ! 3970: ! 3971: ASSERTS3 (((left + width) < (INT) ppdev->cxScreen), ! 3972: "S3.DLL!vS3SolidPattern - (left + width) > (ppdev->cxScreen - 1)\n"); ! 3973: ! 3974: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3Mix); ! 3975: TEST_AND_SET_FRGD_COLOR(color); ! 3976: ! 3977: OUTPW (MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 3978: ! 3979: OUTPW (CUR_X, left); ! 3980: OUTPW (CUR_Y, top); ! 3981: OUTPW (RECT_WIDTH, width); ! 3982: OUTPW (MULTIFUNC_CNTL, (RECT_HEIGHT | height)); ! 3983: ! 3984: OUTPW (CMD, RECTANGLE_FILL | DRAWING_DIR_TBLRXM | ! 3985: DRAW | DIR_TYPE_XY | ! 3986: LAST_PIXEL_ON | MULTIPLE_PIXELS | ! 3987: WRITE); ! 3988: } ! 3989: ! 3990: /***************************************************************************** ! 3991: * S3 8bpp Cached Managed Host to Screen Copy ! 3992: * ! 3993: * Returns TRUE if the blit was handled. ! 3994: ****************************************************************************/ ! 3995: BOOL b8BppHostToScrnCachedWithRop( ! 3996: SURFOBJ *psoTrg, ! 3997: SURFOBJ *psoSrc, ! 3998: CLIPOBJ *pco, ! 3999: XLATEOBJ *pxlo, ! 4000: RECTL *prclTrg, ! 4001: POINTL *pptlSrc, ! 4002: WORD s3Rop) ! 4003: { ! 4004: BOOL bRet; ! 4005: HSURF hsurf; ! 4006: PPDEV ppdev; ! 4007: POINTL ptlSrc; ! 4008: RECTL rclTrg; ! 4009: SIZEL sizlBitmap; ! 4010: ! 4011: PSAVEDSCRNBITSHDR pssbhInPdev; ! 4012: PSAVEDSCRNBITS pssbNewNode, pssbTemp; ! 4013: ! 4014: DISPDBG((3, "S3.DLL!b8BppHostToScrnCachedWithRop - entry\n")); ! 4015: ! 4016: n8BppBitmaps++; ! 4017: ! 4018: ppdev = (PPDEV) psoTrg->dhpdev; ! 4019: hsurf = psoSrc->hsurf; ! 4020: ! 4021: #if 0 ! 4022: DISPDBG((2, "\thsurf : %x\n", hsurf)); ! 4023: DISPDBG((2, "\tpsoSrc->iUniq : %x\n", psoSrc->iUniq)); ! 4024: DISPDBG((2, "\tpsoSrc->sizlBitmap.cx: %d\n", psoSrc->sizlBitmap.cx)); ! 4025: DISPDBG((2, "\tpsoSrc->sizlBitmap.cy: %d\n", psoSrc->sizlBitmap.cy)); ! 4026: #endif ! 4027: ! 4028: #if SRCBM_CACHE ! 4029: ! 4030: // Is this bitmap in the cache? ! 4031: ! 4032: if ((hsurf == ppdev->hsurfCachedBitmap) && ! 4033: (psoSrc->iUniq == ppdev->iUniqCachedBitmap)) ! 4034: { ! 4035: if ((((pxlo == NULL) || ! 4036: (pxlo->flXlate & XO_TRIVIAL)) && (ppdev->iUniqXlate == 1)) || ! 4037: (pxlo->iUniq == ppdev->iUniqXlate)) ! 4038: { ! 4039: // The bitmap is in the cache ! 4040: // Keep a cache hit count. ! 4041: ! 4042: n8BppBmCacheHits++; ! 4043: ! 4044: // Blt from the cache. ! 4045: ! 4046: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X; ! 4047: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y; ! 4048: ! 4049: return(bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg, ! 4050: &ptlSrc, s3Rop)); ! 4051: } ! 4052: } ! 4053: ! 4054: // The bitmap is not in the cache. ! 4055: // Is it small enough to fit into the cache? ! 4056: ! 4057: sizlBitmap = psoSrc->sizlBitmap; ! 4058: ! 4059: if ((sizlBitmap.cx <= OFF_SCREEN_BITMAP_CX) && ! 4060: (sizlBitmap.cy <= OFF_SCREEN_BITMAP_CY)) ! 4061: { ! 4062: // It will fit in the cache. ! 4063: // If the cache is being used for some saved screen bits ! 4064: // move them to host memory. ! 4065: ! 4066: if (ppdev->SavedScreenBitsHeader.iUniq != -1) ! 4067: { ! 4068: nSsbMovedToHostFromSrcBmCache++; ! 4069: ! 4070: DISPDBG((1, "S3.DLL - Saved Screen Bits Moved to Host Memory from Source Bitmap Cache Manager \n")); ! 4071: ! 4072: // Move the actual bits to host memory. ! 4073: ! 4074: bRet = bMoveSaveScreenBitsToHost(ppdev, &pssbNewNode); ! 4075: ! 4076: if (bRet == FALSE) ! 4077: return(FALSE); ! 4078: ! 4079: // Connect this newNode to the beginning of the list of ! 4080: // save screen bits nodes. ! 4081: ! 4082: pssbhInPdev = &(ppdev->SavedScreenBitsHeader); ! 4083: ! 4084: pssbTemp = pssbhInPdev->pssbLink; ! 4085: pssbhInPdev->pssbLink = pssbNewNode; ! 4086: pssbNewNode->ssbh.pssbLink = pssbTemp; ! 4087: ! 4088: // Invalidate the Save Screen bits in off screen memory ! 4089: ! 4090: ppdev->SavedScreenBitsHeader.iUniq = (ULONG) -1; ! 4091: } ! 4092: ! 4093: ! 4094: // Set the cache tags. ! 4095: ! 4096: ppdev->hsurfCachedBitmap = hsurf; ! 4097: ppdev->iUniqCachedBitmap = psoSrc->iUniq; ! 4098: ! 4099: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) ! 4100: { ! 4101: ppdev->iUniqXlate = 1; ! 4102: } ! 4103: else ! 4104: { ! 4105: ppdev->iUniqXlate = pxlo->iUniq; ! 4106: } ! 4107: ! 4108: // Put the entire bitmap into the cache. ! 4109: ! 4110: rclTrg.left = OFF_SCREEN_BITMAP_X; ! 4111: rclTrg.top = OFF_SCREEN_BITMAP_Y; ! 4112: rclTrg.right = OFF_SCREEN_BITMAP_X + sizlBitmap.cx; ! 4113: rclTrg.bottom = OFF_SCREEN_BITMAP_Y + sizlBitmap.cy; ! 4114: ! 4115: ptlSrc.x = 0; ! 4116: ptlSrc.y = 0; ! 4117: ! 4118: bRet = b8BppHostToScrnWithRop(psoTrg, psoSrc, ppdev->pcoFullRam, ! 4119: pxlo, &rclTrg, &ptlSrc, OVERPAINT); ! 4120: ! 4121: if (bRet == TRUE) ! 4122: { ! 4123: // Blt from the cache. ! 4124: ! 4125: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X; ! 4126: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y; ! 4127: ! 4128: bRet = bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg, ! 4129: &ptlSrc, s3Rop); ! 4130: ! 4131: } ! 4132: } ! 4133: else ! 4134: { ! 4135: // The bitmap was too large to cache. ! 4136: // So, just blt it directly to the screen. ! 4137: ! 4138: bRet = b8BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo, ! 4139: prclTrg, pptlSrc, s3Rop); ! 4140: } ! 4141: #else ! 4142: ! 4143: bRet = b8BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo, ! 4144: prclTrg, pptlSrc, s3Rop); ! 4145: ! 4146: #endif ! 4147: ! 4148: return (bRet); ! 4149: } ! 4150: ! 4151: /***************************************************************************** ! 4152: * S3 8bpp Host to Screen Copy ! 4153: * ! 4154: * Returns TRUE if the blit was handled. ! 4155: ****************************************************************************/ ! 4156: BOOL b8BppHostToScrnWithRop( ! 4157: SURFOBJ *psoTrg, ! 4158: SURFOBJ *psoSrc, ! 4159: CLIPOBJ *pco, ! 4160: XLATEOBJ *pxlo, ! 4161: RECTL *prclTrg, ! 4162: POINTL *pptlSrc, ! 4163: WORD s3Rop) ! 4164: { ! 4165: LONG lSrcDelta; ! 4166: PWORD pwFirstWord; ! 4167: BOOL bMore; ! 4168: PPDEV ppdev; ! 4169: BYTE iDComplexity; ! 4170: RECTL rclTrg, rclBounds; ! 4171: POINT ptSrc; ! 4172: INT i; ! 4173: SIZE sizBlt; ! 4174: ! 4175: ENUMRECTS8 EnumRects8; ! 4176: ! 4177: DISPDBG((3, "S3.DLL!b8BppHostToScrnWithRop - entry\n")); ! 4178: ! 4179: ppdev = (PPDEV) psoTrg->dhpdev; ! 4180: ! 4181: // Pickup some convienent locals. ! 4182: ! 4183: lSrcDelta = psoSrc->lDelta; ! 4184: ! 4185: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX) ! 4186: { ! 4187: // Make a copy of the target, since we will have to change ! 4188: // it for clipping. ! 4189: ! 4190: rclTrg = *prclTrg; ! 4191: ! 4192: if (iDComplexity == DC_RECT) ! 4193: { ! 4194: rclBounds = pco->rclBounds; ! 4195: ! 4196: // Handle the trivial rejection and ! 4197: // define the clipped target rectangle. ! 4198: ! 4199: if (bIntersectTest(&rclTrg, &rclBounds)) ! 4200: { ! 4201: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 4202: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 4203: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 4204: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 4205: } ! 4206: else ! 4207: { ! 4208: // The destination rectangle is completely clipped out, ! 4209: // so just return. ! 4210: ! 4211: return (TRUE); ! 4212: } ! 4213: } ! 4214: ! 4215: // define the cx & cy for the blit. ! 4216: ! 4217: sizBlt.cx = rclTrg.right - rclTrg.left; ! 4218: sizBlt.cy = rclTrg.bottom - rclTrg.top; ! 4219: ! 4220: // calculate the cx & cy shift (due to clipping) for the source. ! 4221: // and define the upper left corner of the source. ! 4222: ! 4223: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left); ! 4224: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top); ! 4225: ! 4226: // Calculate the first word to blit ! 4227: ! 4228: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0) ! 4229: + (ptSrc.y * lSrcDelta) + ptSrc.x); ! 4230: ! 4231: vLowLevel8BppHostToScrnWithRop(ppdev, (PPOINT) &rclTrg, &sizBlt, ! 4232: pwFirstWord, lSrcDelta, pxlo, s3Rop); ! 4233: ! 4234: } ! 4235: else ! 4236: { ! 4237: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); ! 4238: ! 4239: do ! 4240: { ! 4241: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), (PULONG) &EnumRects8); ! 4242: ! 4243: for (i = 0; i < (INT) EnumRects8.c; i++) ! 4244: { ! 4245: rclTrg = *prclTrg; ! 4246: rclBounds = EnumRects8.arcl[i]; ! 4247: ! 4248: // Handle the trivial rejection and ! 4249: // define the clipped target rectangle. ! 4250: ! 4251: if (bIntersectTest(&rclTrg, &rclBounds)) ! 4252: { ! 4253: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 4254: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 4255: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 4256: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 4257: ! 4258: // define the cx & cy for the blit. ! 4259: ! 4260: sizBlt.cx = rclTrg.right - rclTrg.left; ! 4261: sizBlt.cy = rclTrg.bottom - rclTrg.top; ! 4262: ! 4263: // calculate the cx & cy shift (due to clipping) for the source. ! 4264: // and define the upper left corner of the source. ! 4265: ! 4266: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left); ! 4267: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top); ! 4268: ! 4269: // Calculate the first word to blit ! 4270: ! 4271: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0) ! 4272: + (ptSrc.y * lSrcDelta) + ptSrc.x); ! 4273: ! 4274: vLowLevel8BppHostToScrnWithRop(ppdev, ! 4275: (PPOINT) &rclTrg, ! 4276: &sizBlt, ! 4277: pwFirstWord, ! 4278: lSrcDelta, ! 4279: pxlo, ! 4280: s3Rop); ! 4281: } ! 4282: } ! 4283: } while (bMore); ! 4284: } ! 4285: ! 4286: return (TRUE); ! 4287: } ! 4288: ! 4289: ! 4290: ! 4291: /***************************************************************************** ! 4292: * Low Level 8bpp host to screen copy. ! 4293: ****************************************************************************/ ! 4294: VOID vLowLevel8BppHostToScrnWithRop( ! 4295: PPDEV ppdev, ! 4296: PPOINT pptTrg, ! 4297: PSIZE psizBlt, ! 4298: PWORD pwFirstWord, ! 4299: INT lSrcDelta, ! 4300: XLATEOBJ *pxlo, ! 4301: WORD s3Rop) ! 4302: { ! 4303: PWORD pw; ! 4304: INT i, j; ! 4305: WORD Cmd; ! 4306: PBYTE pbSrc; ! 4307: INT nSrc; ! 4308: PULONG pulXlate; ! 4309: INT cy, wpl; ! 4310: BYTE LineBuff[DRIVERS_MAX_CX]; ! 4311: ! 4312: // Setup the S3 chip. ! 4313: ! 4314: cy = psizBlt->cy; ! 4315: ! 4316: Cmd = RECTANGLE_FILL | BYTE_SWAP | BUS_SIZE_16 | WAIT | ! 4317: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 4318: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE; ! 4319: ! 4320: FIFOWAIT(FIFO_7_EMPTY); ! 4321: ! 4322: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | s3Rop); ! 4323: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 4324: ! 4325: OUTPW(CUR_X, pptTrg->x); ! 4326: OUTPW(CUR_Y, pptTrg->y); ! 4327: OUTPW(RECT_WIDTH, psizBlt->cx - 1); ! 4328: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cy - 1)); ! 4329: ! 4330: GPWAIT(); ! 4331: ! 4332: OUTPW(CMD, Cmd); ! 4333: ! 4334: CHECK_DATA_READY; ! 4335: ! 4336: wpl = (psizBlt->cx + 1) >> 1; ! 4337: ! 4338: // We may have to do some color translation. ! 4339: ! 4340: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) ! 4341: { ! 4342: // Now transfer the data. ! 4343: ! 4344: // Note: It would nice to do the entire bitmap in one ! 4345: // fell swoop, but there is no gaurantee source will ! 4346: // wrap on a bitmap boundary. ! 4347: ! 4348: pw = pwFirstWord; ! 4349: for (i = 0; i < cy; i++) ! 4350: { ! 4351: vDataPortOut(ppdev, (PWORD) pw, wpl); ! 4352: ((PBYTE) pw) += lSrcDelta; ! 4353: } ! 4354: } ! 4355: else ! 4356: { ! 4357: if (pxlo->flXlate & XO_TABLE) ! 4358: { ! 4359: pulXlate = pxlo->pulXlate; ! 4360: } ! 4361: else ! 4362: { ! 4363: pulXlate = XLATEOBJ_piVector(pxlo); ! 4364: } ! 4365: ! 4366: pbSrc = (PBYTE) pwFirstWord; ! 4367: nSrc = wpl * 2; ! 4368: ! 4369: for (i = 0; i < cy; i++) ! 4370: { ! 4371: for (j = 0; j < nSrc; j++) ! 4372: { ! 4373: LineBuff[j] = LOBYTE(pulXlate[pbSrc[j]]); ! 4374: } ! 4375: ! 4376: vDataPortOut(ppdev, (PWORD) LineBuff, wpl); ! 4377: pbSrc += lSrcDelta; ! 4378: } ! 4379: } ! 4380: ! 4381: CHECK_DATA_COMPLETE; ! 4382: ! 4383: return; ! 4384: ! 4385: } ! 4386: ! 4387: ! 4388: /***************************************************************************** ! 4389: * S3 1bpp Cached Managed Host to Screen With Rop ! 4390: * ! 4391: * Returns TRUE if the blit was handled. ! 4392: ****************************************************************************/ ! 4393: BOOL b1BppHostToScrnCachedWithRop( ! 4394: SURFOBJ *psoTrg, ! 4395: SURFOBJ *psoSrc, ! 4396: CLIPOBJ *pco, ! 4397: XLATEOBJ *pxlo, ! 4398: RECTL *prclTrg, ! 4399: POINTL *pptlSrc, ! 4400: WORD s3Rop) ! 4401: { ! 4402: BOOL bRet; ! 4403: HSURF hsurf; ! 4404: PPDEV ppdev; ! 4405: POINTL ptlSrc; ! 4406: RECTL rclTrg; ! 4407: SIZEL sizlBitmap; ! 4408: ! 4409: PSAVEDSCRNBITSHDR pssbhInPdev; ! 4410: PSAVEDSCRNBITS pssbNewNode, pssbTemp; ! 4411: ! 4412: DISPDBG((3, "S3.DLL!b1BppHostToScrnCachedWithRop - entry\n")); ! 4413: ! 4414: n1BppBitmaps++; ! 4415: ! 4416: ppdev = (PPDEV) psoTrg->dhpdev; ! 4417: hsurf = psoSrc->hsurf; ! 4418: ! 4419: #if 1 ! 4420: DISPDBG((2, "\thsurf : %x\n", hsurf)); ! 4421: DISPDBG((2, "\tpsoSrc->iUniq : %x\n", psoSrc->iUniq)); ! 4422: DISPDBG((2, "\tpsoSrc->sizlBitmap.cx: %d\n", psoSrc->sizlBitmap.cx)); ! 4423: DISPDBG((2, "\tpsoSrc->sizlBitmap.cy: %d\n", psoSrc->sizlBitmap.cy)); ! 4424: #endif ! 4425: ! 4426: #if SRCBM_CACHE ! 4427: ! 4428: // Is this bitmap in the cache? ! 4429: ! 4430: if ((hsurf == ppdev->hsurfCachedBitmap) && ! 4431: (psoSrc->iUniq == ppdev->iUniqCachedBitmap)) ! 4432: { ! 4433: if ((((pxlo == NULL) || ! 4434: (pxlo->flXlate & XO_TRIVIAL)) && (ppdev->iUniqXlate == 1)) || ! 4435: (pxlo->iUniq == ppdev->iUniqXlate)) ! 4436: { ! 4437: // The bitmap is in the cache ! 4438: // Keep a cache hit count. ! 4439: ! 4440: n1BppBmCacheHits++; ! 4441: ! 4442: // Blt from the cache. ! 4443: ! 4444: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X; ! 4445: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y; ! 4446: ! 4447: return(bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg, ! 4448: &ptlSrc, s3Rop)); ! 4449: } ! 4450: } ! 4451: ! 4452: // The bitmap is not in the cache. ! 4453: // Is it small enough to fit into the cache? ! 4454: ! 4455: sizlBitmap = psoSrc->sizlBitmap; ! 4456: ! 4457: if ((sizlBitmap.cx <= OFF_SCREEN_BITMAP_CX) && ! 4458: (sizlBitmap.cy <= OFF_SCREEN_BITMAP_CY)) ! 4459: { ! 4460: // It will fit in the cache. ! 4461: // If the cache is being used for some saved screen bits ! 4462: // move them to host memory. ! 4463: ! 4464: if (ppdev->SavedScreenBitsHeader.iUniq != -1) ! 4465: { ! 4466: nSsbMovedToHostFromSrcBmCache++; ! 4467: ! 4468: DISPDBG((1, "S3.DLL - Saved Screen Bits Moved to Host Memory from Source Bitmap Cache Manager \n")); ! 4469: ! 4470: // Move the actual bits to host memory. ! 4471: ! 4472: bRet = bMoveSaveScreenBitsToHost(ppdev, &pssbNewNode); ! 4473: ! 4474: if (bRet == FALSE) ! 4475: return(FALSE); ! 4476: ! 4477: // Connect this newNode to the beginning of the list of ! 4478: // save screen bits nodes. ! 4479: ! 4480: pssbhInPdev = &(ppdev->SavedScreenBitsHeader); ! 4481: ! 4482: pssbTemp = pssbhInPdev->pssbLink; ! 4483: pssbhInPdev->pssbLink = pssbNewNode; ! 4484: pssbNewNode->ssbh.pssbLink = pssbTemp; ! 4485: ! 4486: // Invalidate the Save Screen bits in off screen memory ! 4487: ! 4488: ppdev->SavedScreenBitsHeader.iUniq = (ULONG) -1; ! 4489: } ! 4490: ! 4491: ! 4492: // Set the cache tags. ! 4493: ! 4494: ppdev->hsurfCachedBitmap = hsurf; ! 4495: ppdev->iUniqCachedBitmap = psoSrc->iUniq; ! 4496: ! 4497: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) ! 4498: { ! 4499: ppdev->iUniqXlate = 1; ! 4500: } ! 4501: else ! 4502: { ! 4503: ppdev->iUniqXlate = pxlo->iUniq; ! 4504: } ! 4505: ! 4506: // Put the entire bitmap into the cache. ! 4507: ! 4508: rclTrg.left = OFF_SCREEN_BITMAP_X; ! 4509: rclTrg.top = OFF_SCREEN_BITMAP_Y; ! 4510: rclTrg.right = OFF_SCREEN_BITMAP_X + sizlBitmap.cx; ! 4511: rclTrg.bottom = OFF_SCREEN_BITMAP_Y + sizlBitmap.cy; ! 4512: ! 4513: ptlSrc.x = 0; ! 4514: ptlSrc.y = 0; ! 4515: ! 4516: bRet = b1BppHostToScrnWithRop(psoTrg, psoSrc, ppdev->pcoFullRam, ! 4517: pxlo, &rclTrg, &ptlSrc, OVERPAINT); ! 4518: ! 4519: if (bRet == TRUE) ! 4520: { ! 4521: // Blt from the cache. ! 4522: ! 4523: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X; ! 4524: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y; ! 4525: ! 4526: bRet = bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg, ! 4527: &ptlSrc, s3Rop); ! 4528: ! 4529: } ! 4530: } ! 4531: else ! 4532: { ! 4533: // The bitmap was too large to cache. ! 4534: // So, just blt it directly to the screen. ! 4535: ! 4536: bRet = b1BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo, ! 4537: prclTrg, pptlSrc, s3Rop); ! 4538: } ! 4539: #else ! 4540: ! 4541: bRet = b1BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo, ! 4542: prclTrg, pptlSrc, s3Rop); ! 4543: ! 4544: #endif ! 4545: ! 4546: return (bRet); ! 4547: } ! 4548: ! 4549: ! 4550: ! 4551: ! 4552: ! 4553: /***************************************************************************** ! 4554: * S3 1bpp Host to Screen With ROP ! 4555: * ! 4556: * Returns TRUE if the blit was handled. ! 4557: ****************************************************************************/ ! 4558: BOOL b1BppHostToScrnWithRop( ! 4559: SURFOBJ *psoTrg, ! 4560: SURFOBJ *psoSrc, ! 4561: CLIPOBJ *pco, ! 4562: XLATEOBJ *pxlo, ! 4563: RECTL *prclTrg, ! 4564: POINTL *pptlSrc, ! 4565: WORD s3Rop) ! 4566: { ! 4567: LONG lSrcDelta; ! 4568: PWORD pwFirstWord; ! 4569: BOOL bMore; ! 4570: PPDEV ppdev; ! 4571: BYTE iDComplexity; ! 4572: RECTL rclTrg, rclBounds; ! 4573: POINT ptSrc; ! 4574: INT i; ! 4575: SIZE sizBlt; ! 4576: ! 4577: ENUMRECTS8 EnumRects8; ! 4578: ! 4579: DISPDBG((3, "S3.DLL!b1BppHostToScrnWithRop - entry\n")); ! 4580: ! 4581: ppdev = (PPDEV) psoTrg->dhpdev; ! 4582: ! 4583: // Pickup some convienent locals. ! 4584: ! 4585: lSrcDelta = psoSrc->lDelta; ! 4586: ! 4587: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX) ! 4588: { ! 4589: // Make a copy of the target, since we will have to change ! 4590: // it for clipping. ! 4591: ! 4592: rclTrg = *prclTrg; ! 4593: ! 4594: if (iDComplexity == DC_RECT) ! 4595: { ! 4596: rclBounds = pco->rclBounds; ! 4597: ! 4598: // Handle the trivial rejection and ! 4599: // define the clipped target rectangle. ! 4600: ! 4601: if (bIntersectTest(&rclTrg, &rclBounds)) ! 4602: { ! 4603: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 4604: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 4605: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 4606: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 4607: } ! 4608: else ! 4609: { ! 4610: // The destination rectangle is completely clipped out, ! 4611: // so just return. ! 4612: ! 4613: return (TRUE); ! 4614: } ! 4615: } ! 4616: ! 4617: // define the cx & cy for the blit. ! 4618: ! 4619: sizBlt.cx = rclTrg.right - rclTrg.left; ! 4620: sizBlt.cy = rclTrg.bottom - rclTrg.top; ! 4621: ! 4622: // calculate the cx & cy shift (due to clipping) for the source. ! 4623: // and define the upper left corner of the source. ! 4624: ! 4625: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left); ! 4626: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top); ! 4627: ! 4628: // Calculate the first word to blit ! 4629: ! 4630: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0) ! 4631: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 8)); ! 4632: ! 4633: vSetS3ClipRect(ppdev, &rclTrg); ! 4634: vLowLevel1BppHostToScrnWithRop(ppdev, ! 4635: (PPOINT) &rclTrg, ! 4636: &sizBlt, ! 4637: ptSrc.x, ! 4638: pwFirstWord, ! 4639: lSrcDelta, ! 4640: pxlo, ! 4641: s3Rop); ! 4642: ! 4643: } ! 4644: else ! 4645: { ! 4646: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); ! 4647: ! 4648: do ! 4649: { ! 4650: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), (PULONG) &EnumRects8); ! 4651: ! 4652: for (i = 0; i < (INT) EnumRects8.c; i++) ! 4653: { ! 4654: rclTrg = *prclTrg; ! 4655: rclBounds = EnumRects8.arcl[i]; ! 4656: ! 4657: // Handle the trivial rejection and ! 4658: // define the clipped target rectangle. ! 4659: ! 4660: if (bIntersectTest(&rclTrg, &rclBounds)) ! 4661: { ! 4662: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 4663: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 4664: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 4665: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 4666: ! 4667: // define the cx & cy for the blit. ! 4668: ! 4669: sizBlt.cx = rclTrg.right - rclTrg.left; ! 4670: sizBlt.cy = rclTrg.bottom - rclTrg.top; ! 4671: ! 4672: // calculate the cx & cy shift (due to clipping) for the source. ! 4673: // and define the upper left corner of the source. ! 4674: ! 4675: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left); ! 4676: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top); ! 4677: ! 4678: // Calculate the first word to blit ! 4679: ! 4680: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0) ! 4681: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 8)); ! 4682: ! 4683: vSetS3ClipRect(ppdev, &rclTrg); ! 4684: vLowLevel1BppHostToScrnWithRop(ppdev, ! 4685: (PPOINT) &rclTrg, ! 4686: &sizBlt, ! 4687: ptSrc.x, ! 4688: pwFirstWord, ! 4689: lSrcDelta, ! 4690: pxlo, ! 4691: s3Rop); ! 4692: } ! 4693: } ! 4694: } while (bMore); ! 4695: } ! 4696: ! 4697: vResetS3Clipping(ppdev); ! 4698: ! 4699: return (TRUE); ! 4700: } ! 4701: ! 4702: ! 4703: /***************************************************************************** ! 4704: * Low Level 1bpp host to screen copy. ! 4705: * ! 4706: * Note: This routine should be modified to handle separate foreground ! 4707: * and background mix modes. ! 4708: ****************************************************************************/ ! 4709: VOID vLowLevel1BppHostToScrnWithRop( ! 4710: PPDEV ppdev, ! 4711: PPOINT pptTrg, ! 4712: PSIZE psizBlt, ! 4713: INT xSrc, ! 4714: PWORD pwFirstWord, ! 4715: INT lSrcDelta, ! 4716: XLATEOBJ *pxlo, ! 4717: WORD s3Rop) ! 4718: { ! 4719: PBYTE pb1bpp; ! 4720: INT i, x, cx, cy, nSrcBytes, xClip; ! 4721: WORD Cmd; ! 4722: PULONG pulXlate; ! 4723: ! 4724: if (pxlo->flXlate & XO_TABLE) ! 4725: { ! 4726: pulXlate = pxlo->pulXlate; ! 4727: } ! 4728: else ! 4729: { ! 4730: pulXlate = XLATEOBJ_piVector(pxlo); ! 4731: } ! 4732: ! 4733: ! 4734: x = pptTrg->x; ! 4735: cx = psizBlt->cx; ! 4736: ! 4737: // Take care of the non-byte aligned source case. ! 4738: ! 4739: if (xSrc & 0x7) ! 4740: { ! 4741: xClip = x; ! 4742: x -= (xSrc & 0x7); ! 4743: cx += (xSrc & 0x7); ! 4744: ! 4745: FIFOWAIT(FIFO_1_EMPTY); ! 4746: outpw (MULTIFUNC_CNTL, (CLIP_LEFT | xClip)); ! 4747: } ! 4748: ! 4749: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT | ! 4750: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 4751: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE; ! 4752: ! 4753: // Setup the S3 chip. ! 4754: ! 4755: cy = psizBlt->cy; ! 4756: ! 4757: FIFOWAIT(FIFO_4_EMPTY); ! 4758: ! 4759: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3Rop); ! 4760: TEST_AND_SET_FRGD_COLOR(LOWORD(pulXlate[1])); ! 4761: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | s3Rop); ! 4762: SET_BKGD_COLOR(LOWORD(pulXlate[0])); ! 4763: ! 4764: FIFOWAIT(FIFO_5_EMPTY); ! 4765: ! 4766: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA)); ! 4767: ! 4768: OUTPW(CUR_X, x); ! 4769: OUTPW(CUR_Y, pptTrg->y); ! 4770: OUTPW(RECT_WIDTH, cx - 1); ! 4771: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cy - 1)); ! 4772: ! 4773: GPWAIT(); ! 4774: ! 4775: OUTPW(CMD, Cmd); ! 4776: ! 4777: CHECK_DATA_READY; ! 4778: ! 4779: pb1bpp = (PBYTE) pwFirstWord; ! 4780: nSrcBytes = (cx + 7) / 8; ! 4781: ! 4782: for (i = 0; i < cy; i++) ! 4783: { ! 4784: vDataPortOutB(ppdev, pb1bpp, nSrcBytes); ! 4785: pb1bpp += lSrcDelta; ! 4786: } ! 4787: ! 4788: CHECK_DATA_COMPLETE; ! 4789: ! 4790: return; ! 4791: ! 4792: } ! 4793: ! 4794: ! 4795: /***************************************************************************** ! 4796: * S3 4bpp Host to Screen Copy ! 4797: * ! 4798: * Returns TRUE if the blit was handled. ! 4799: ****************************************************************************/ ! 4800: BOOL b4BppHostToScrnWithRop( ! 4801: SURFOBJ *psoTrg, ! 4802: SURFOBJ *psoSrc, ! 4803: CLIPOBJ *pco, ! 4804: XLATEOBJ *pxlo, ! 4805: RECTL *prclTrg, ! 4806: POINTL *pptlSrc, ! 4807: WORD s3Rop) ! 4808: { ! 4809: LONG lSrcDelta; ! 4810: PWORD pwFirstWord; ! 4811: BOOL bMore; ! 4812: PPDEV ppdev; ! 4813: BYTE iDComplexity; ! 4814: RECTL rclTrg, rclBounds; ! 4815: POINT ptSrc; ! 4816: INT i; ! 4817: SIZE sizBlt; ! 4818: ! 4819: ENUMRECTS8 EnumRects8; ! 4820: ! 4821: DISPDBG((2, "S3.DLL!b4BppHostToScrnWithRop - entry\n")); ! 4822: ! 4823: ppdev = (PPDEV) psoTrg->dhpdev; ! 4824: ! 4825: // Pickup some convienent locals. ! 4826: ! 4827: lSrcDelta = psoSrc->lDelta; ! 4828: ! 4829: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX) ! 4830: { ! 4831: // Make a copy of the target, since we will have to change ! 4832: // it for clipping. ! 4833: ! 4834: rclTrg = *prclTrg; ! 4835: ! 4836: if (iDComplexity == DC_RECT) ! 4837: { ! 4838: rclBounds = pco->rclBounds; ! 4839: ! 4840: // Handle the trivial rejection and ! 4841: // define the clipped target rectangle. ! 4842: ! 4843: if (bIntersectTest(&rclTrg, &rclBounds)) ! 4844: { ! 4845: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 4846: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 4847: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 4848: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 4849: } ! 4850: else ! 4851: { ! 4852: // The destination rectangle is completely clipped out, ! 4853: // so just return. ! 4854: ! 4855: return (TRUE); ! 4856: } ! 4857: } ! 4858: ! 4859: // define the cx & cy for the blit. ! 4860: ! 4861: sizBlt.cx = rclTrg.right - rclTrg.left; ! 4862: sizBlt.cy = rclTrg.bottom - rclTrg.top; ! 4863: ! 4864: // calculate the cx & cy shift (due to clipping) for the source. ! 4865: // and define the upper left corner of the source. ! 4866: ! 4867: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left); ! 4868: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top); ! 4869: ! 4870: // Calculate the first word to blit ! 4871: ! 4872: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0) ! 4873: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 2)); ! 4874: ! 4875: vSetS3ClipRect(ppdev, &rclTrg); ! 4876: vLowLevel4BppHostToScrnWithRop(ppdev, (PPOINT) &rclTrg, &sizBlt, ! 4877: ptSrc.x, ! 4878: pwFirstWord, lSrcDelta, pxlo, s3Rop); ! 4879: ! 4880: } ! 4881: else ! 4882: { ! 4883: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); ! 4884: ! 4885: do ! 4886: { ! 4887: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), (PULONG) &EnumRects8); ! 4888: ! 4889: for (i = 0; i < (INT) EnumRects8.c; i++) ! 4890: { ! 4891: rclTrg = *prclTrg; ! 4892: rclBounds = EnumRects8.arcl[i]; ! 4893: ! 4894: // Handle the trivial rejection and ! 4895: // define the clipped target rectangle. ! 4896: ! 4897: if (bIntersectTest(&rclTrg, &rclBounds)) ! 4898: { ! 4899: rclTrg.left = max (rclTrg.left, rclBounds.left); ! 4900: rclTrg.top = max (rclTrg.top, rclBounds.top); ! 4901: rclTrg.right = min (rclTrg.right, rclBounds.right); ! 4902: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom); ! 4903: ! 4904: // define the cx & cy for the blit. ! 4905: ! 4906: sizBlt.cx = rclTrg.right - rclTrg.left; ! 4907: sizBlt.cy = rclTrg.bottom - rclTrg.top; ! 4908: ! 4909: // calculate the cx & cy shift (due to clipping) for the source. ! 4910: // and define the upper left corner of the source. ! 4911: ! 4912: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left); ! 4913: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top); ! 4914: ! 4915: // Calculate the first word to blit ! 4916: ! 4917: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0) ! 4918: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 2)); ! 4919: ! 4920: vSetS3ClipRect(ppdev, &rclTrg); ! 4921: vLowLevel4BppHostToScrnWithRop(ppdev, (PPOINT) &rclTrg, &sizBlt, ! 4922: ptSrc.x, ! 4923: pwFirstWord, lSrcDelta, pxlo, s3Rop); ! 4924: } ! 4925: } ! 4926: } while (bMore); ! 4927: } ! 4928: ! 4929: vResetS3Clipping(ppdev); ! 4930: ! 4931: return (TRUE); ! 4932: ! 4933: } ! 4934: ! 4935: ! 4936: ! 4937: ! 4938: /***************************************************************************** ! 4939: * Low Level 4bpp host to screen copy. ! 4940: ****************************************************************************/ ! 4941: VOID vLowLevel4BppHostToScrnWithRop( ! 4942: PPDEV ppdev, ! 4943: PPOINT pptTrg, ! 4944: PSIZE psizBlt, ! 4945: INT xSrc, ! 4946: PWORD pwFirstWord, ! 4947: INT lSrcDelta, ! 4948: XLATEOBJ *pxlo, ! 4949: WORD s3Rop) ! 4950: { ! 4951: PBYTE pb4Bpp; ! 4952: INT i, j, k, x, cx, cy, nSrcBytes, xClip; ! 4953: WORD Cmd; ! 4954: PULONG pulXlate; ! 4955: ! 4956: BYTE LineBuff8Bpp[DRIVERS_MAX_CX]; ! 4957: ! 4958: if (pxlo->flXlate & XO_TABLE) ! 4959: { ! 4960: pulXlate = pxlo->pulXlate; ! 4961: } ! 4962: else ! 4963: { ! 4964: pulXlate = XLATEOBJ_piVector(pxlo); ! 4965: } ! 4966: ! 4967: pb4Bpp = (PBYTE) pwFirstWord; ! 4968: ! 4969: x = pptTrg->x; ! 4970: cx = psizBlt->cx; ! 4971: cy = psizBlt->cy; ! 4972: ! 4973: // Take care of the non-byte aligned source case. ! 4974: ! 4975: if (xSrc & 0x1) ! 4976: { ! 4977: xClip = x; ! 4978: x--; ! 4979: cx++; ! 4980: ! 4981: FIFOWAIT(FIFO_1_EMPTY); ! 4982: outpw (MULTIFUNC_CNTL, (CLIP_LEFT | xClip)); ! 4983: } ! 4984: ! 4985: nSrcBytes = (cx + 1) / 2; ! 4986: ! 4987: // Setup the S3 chip. ! 4988: ! 4989: Cmd = RECTANGLE_FILL | BYTE_SWAP | BUS_SIZE_16 | WAIT | ! 4990: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY | ! 4991: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE; ! 4992: ! 4993: FIFOWAIT(FIFO_7_EMPTY); ! 4994: ! 4995: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | s3Rop); ! 4996: outpw(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES)); ! 4997: ! 4998: outpw(CUR_X, x); ! 4999: outpw(CUR_Y, pptTrg->y); ! 5000: outpw(RECT_WIDTH, cx - 1); ! 5001: outpw(MULTIFUNC_CNTL, (RECT_HEIGHT | cy - 1)); ! 5002: ! 5003: GPWAIT(); ! 5004: ! 5005: outpw(CMD, Cmd); ! 5006: ! 5007: CHECK_DATA_READY; ! 5008: ! 5009: // Now transfer the data. ! 5010: ! 5011: for (i = 0; i < cy; i++) ! 5012: { ! 5013: for (k = 0, j = 0; j < nSrcBytes; j++) ! 5014: { ! 5015: LineBuff8Bpp[k++] = (BYTE) pulXlate[(pb4Bpp[j] & 0xF0) >> 4]; ! 5016: LineBuff8Bpp[k++] = (BYTE) pulXlate[pb4Bpp[j] & 0x0F]; ! 5017: } ! 5018: ! 5019: vDataPortOut(ppdev, (PWORD) LineBuff8Bpp, nSrcBytes); ! 5020: pb4Bpp += lSrcDelta; ! 5021: } ! 5022: ! 5023: CHECK_DATA_COMPLETE; ! 5024: ! 5025: return; ! 5026: ! 5027: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.