Annotation of ntddk/src/video/displays/s3/bitblt.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.