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

1.1       root        1: /******************************Module*Header*******************************\
                      2: * Module Name: pointer.c
                      3: *
                      4: * This module contains the hardware cursor support for Disp.
                      5: *
                      6: * Copyright (c) 1992 Microsoft Corporation
                      7: \**************************************************************************/
                      8: 
                      9: #include "driver.h"
                     10: 
                     11: 
                     12: ULONG DrvSetColorPointerShape(
                     13:     SURFOBJ     *pso,
                     14:     SURFOBJ     *psoMask,
                     15:     SURFOBJ     *psoColor,
                     16:     XLATEOBJ    *pxlo,
                     17:     LONG        xHot,
                     18:     LONG        yHot,
                     19:     LONG        x,
                     20:     LONG        y,
                     21:     RECTL       *prcl,
                     22:     FLONG       fl
                     23: );
                     24: 
                     25: ULONG DrvSetMonoHwPointerShape(
                     26:     SURFOBJ     *pso,
                     27:     SURFOBJ     *psoMask,
                     28:     SURFOBJ     *psoColor,
                     29:     XLATEOBJ    *pxlo,
                     30:     LONG        xHot,
                     31:     LONG        yHot,
                     32:     LONG        x,
                     33:     LONG        y,
                     34:     RECTL       *prcl,
                     35:     FLONG       fl
                     36: );
                     37: 
                     38: ULONG DrvSetBt485PointerShape(
                     39:     SURFOBJ     *pso,
                     40:     SURFOBJ     *psoMask,
                     41:     SURFOBJ     *psoColor,
                     42:     XLATEOBJ    *pxlo,
                     43:     LONG        xHot,
                     44:     LONG        yHot,
                     45:     LONG        x,
                     46:     LONG        y,
                     47:     RECTL       *prcl,
                     48:     FLONG       fl
                     49: );
                     50: 
                     51: 
                     52: 
                     53: VOID DrvMoveColorPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl);
                     54: VOID DrvMoveHwPointer(SURFOBJ *pso,LONG x,LONG y,RECTL *prcl);
                     55: VOID DrvMoveBt485Pointer(SURFOBJ *pso, LONG x, LONG y, RECTL *prcl);
                     56: 
                     57: 
                     58: 
                     59: /*****************************************************************************
                     60:  * DrvMovePointer -
                     61:  ****************************************************************************/
                     62: VOID DrvMovePointer(
                     63:     SURFOBJ *pso,
                     64:     LONG x,
                     65:     LONG y,
                     66:     RECTL *prcl)
                     67: {
                     68:     PPDEV   ppdev;
                     69: 
                     70:     ppdev = (PPDEV) pso->dhpdev;
                     71: 
                     72:     if (ppdev->flPointer & COLOR_POINTER)
                     73:         DrvMoveColorPointer(pso, x, y, prcl);
                     74:     else
                     75:     {
                     76:         if (ppdev->bBt485Dac == TRUE)
                     77:         {
                     78:             DrvMoveBt485Pointer(pso, x, y, prcl);
                     79:         }
                     80:         else
                     81:         {
                     82:             DrvMoveHwPointer(pso, x, y, prcl);
                     83:         }
                     84:     }
                     85: }
                     86: 
                     87: 
                     88: /*****************************************************************************
                     89:  * DrvMoveColorPointer -
                     90:  ****************************************************************************/
                     91: VOID DrvMoveColorPointer(
                     92:     SURFOBJ *pso,
                     93:     LONG x,
                     94:     LONG y,
                     95:     RECTL *prcl)
                     96: {
                     97:     INT     xDest, yDest;
                     98:     WORD    cmd;
                     99:     RECTL   rclClip;
                    100:     PPDEV   ppdev;
                    101: 
                    102:     ppdev = (PPDEV) pso->dhpdev;
                    103: 
                    104:     // Sync with the rest of the driver.
                    105: 
                    106:     GPWAIT();
                    107: 
                    108:     // If x is -1 then take down the cursor.
                    109: 
                    110:     if (x == -1)
                    111:     {
                    112:         ppdev->flPointer |= TAKE_DOWN_POINTER;
                    113:     }
                    114: 
                    115:     // Adjust the actual position on the screen for the hot spot.
                    116: 
                    117:     xDest = x - ppdev->ptlHotSpot.x;
                    118:     yDest = y - ppdev->ptlHotSpot.y;
                    119: 
                    120:     // If the save buffer has valid data, copy whats in the save
                    121:     // buffer back to the screen.
                    122: 
                    123:     if (((ppdev->flPointer & VALID_SAVE_BUFFER) &&
                    124:         (!(ppdev->flPointer & ANIMATEUPDATE)))  ||
                    125:         ((ppdev->flPointer & VALID_SAVE_BUFFER) &&
                    126:          (ppdev->flPointer & ANIMATEUPDATE)     &&
                    127:          ((ppdev->ptlLastPosition.x != xDest)   ||
                    128:           (ppdev->ptlLastPosition.y != yDest))))
                    129:     {
                    130:         // The restore will always take place to the screen,
                    131:         // so limit the clip area to the screen.
                    132: 
                    133:         rclClip.left   = 0;
                    134:         rclClip.top    = 0;
                    135:         rclClip.right  = ppdev->cxScreen;
                    136:         rclClip.bottom = ppdev->cyScreen;
                    137: 
                    138:         vSetS3ClipRect(ppdev, &rclClip);
                    139: 
                    140:         cmd  = BITBLT             | DRAW | DIR_TYPE_XY |
                    141:                DRAWING_DIR_TBLRXM | WRITE;
                    142: 
                    143:         FIFOWAIT(FIFO_2_EMPTY);
                    144: 
                    145:         TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
                    146:         OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    147: 
                    148:         FIFOWAIT(FIFO_7_EMPTY);
                    149: 
                    150:         OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1);
                    151:         OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1));
                    152:         OUTPW(CUR_X, COLOR_POINTER_SAVE_X);
                    153:         OUTPW(CUR_Y, COLOR_POINTER_Y);
                    154:         OUTPW(DEST_X, ppdev->ptlLastPosition.x);
                    155:         OUTPW(DEST_Y, ppdev->ptlLastPosition.y);
                    156: 
                    157:         OUTPW(CMD, cmd);
                    158: 
                    159:         // Indicate that the save buffer is no longer valid.
                    160: 
                    161:         ppdev->flPointer &= ~VALID_SAVE_BUFFER;
                    162: 
                    163:     }
                    164: 
                    165:     // If we're just taking down the pointer then were done,
                    166:     // so this an early exit.
                    167: 
                    168:     if (ppdev->flPointer & TAKE_DOWN_POINTER )
                    169:     {
                    170:         ppdev->flPointer &= ~TAKE_DOWN_POINTER;
                    171:         vResetS3Clipping(ppdev);
                    172:         return;
                    173:     }
                    174: 
                    175: 
                    176:     // Set the clipping for the pointers masks, save, and work area.
                    177: 
                    178:     rclClip.left   = 0;
                    179:     rclClip.top    = COLOR_POINTER_Y;
                    180:     rclClip.right  = COLOR_POINTER_SAVE_X + COLOR_POINTER_CX;
                    181:     rclClip.bottom = (COLOR_POINTER_Y + COLOR_POINTER_CY);
                    182: 
                    183:     vSetS3ClipRect(ppdev, &rclClip);
                    184: 
                    185:     if (!(ppdev->flPointer & ANIMATEUPDATE) ||
                    186:         !(ppdev->flPointer & VALID_SAVE_BUFFER))
                    187:     {
                    188:         // Save the area under where we plan to draw the new cursor.
                    189: 
                    190:         cmd  = BITBLT             | DRAW | DIR_TYPE_XY |
                    191:                DRAWING_DIR_TBLRXM | WRITE;
                    192: 
                    193:         FIFOWAIT(FIFO_2_EMPTY);
                    194: 
                    195:         TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
                    196:         OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    197: 
                    198:         FIFOWAIT(FIFO_7_EMPTY);
                    199: 
                    200:         OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1);
                    201:         OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1));
                    202:         OUTPW(CUR_X, xDest);
                    203:         OUTPW(CUR_Y, yDest);
                    204:         OUTPW(DEST_X,COLOR_POINTER_SAVE_X);
                    205:         OUTPW(DEST_Y,COLOR_POINTER_Y);
                    206: 
                    207:         OUTPW(CMD, cmd);
                    208:     }
                    209: 
                    210:     // Validate the save buffer.
                    211: 
                    212:     ppdev->flPointer |= VALID_SAVE_BUFFER;
                    213: 
                    214:     // Now copy the saved data to the work buffer.
                    215: 
                    216:     cmd  = BITBLT             | DRAW | DIR_TYPE_XY |
                    217:            DRAWING_DIR_TBLRXM | WRITE;
                    218: 
                    219:     FIFOWAIT(FIFO_2_EMPTY);
                    220: 
                    221:     TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
                    222:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    223: 
                    224:     FIFOWAIT(FIFO_7_EMPTY);
                    225: 
                    226:     OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1);
                    227:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1));
                    228:     OUTPW(CUR_X, COLOR_POINTER_SAVE_X);
                    229:     OUTPW(CUR_Y, COLOR_POINTER_Y);
                    230:     OUTPW(DEST_X,COLOR_POINTER_WORK_X);
                    231:     OUTPW(DEST_Y,COLOR_POINTER_Y);
                    232: 
                    233:     OUTPW(CMD, cmd);
                    234: 
                    235:     // Record the current position as the last position;
                    236: 
                    237:     ppdev->ptlLastPosition.x = xDest;
                    238:     ppdev->ptlLastPosition.y = yDest;
                    239: 
                    240:     // AND in the AND mask to the work buffer
                    241: 
                    242:     cmd  = BITBLT             | DRAW                | DIR_TYPE_XY |
                    243:            DRAWING_DIR_TBLRXM | MULTIPLE_PIXELS     | WRITE;
                    244: 
                    245:     FIFOWAIT(FIFO_6_EMPTY);
                    246: 
                    247:     TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | SCREEN_AND_NEW);
                    248:     TEST_AND_SET_FRGD_COLOR(0xff);
                    249:     TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | SCREEN_AND_NEW);
                    250:     SET_BKGD_COLOR(0x00);
                    251:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
                    252:     TEST_AND_SET_RD_MASK(COLOR_POINTER_AND_PLANE);
                    253: 
                    254: 
                    255:     FIFOWAIT(FIFO_7_EMPTY);
                    256: 
                    257:     OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1);
                    258:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1));
                    259:     OUTPW(CUR_X, 0);
                    260:     OUTPW(CUR_Y, COLOR_POINTER_Y);
                    261:     OUTPW(DEST_X,COLOR_POINTER_WORK_X);
                    262:     OUTPW(DEST_Y,COLOR_POINTER_Y);
                    263:     OUTPW(CMD, cmd);
                    264: 
                    265:     FIFOWAIT(FIFO_1_EMPTY);
                    266: 
                    267:     TEST_AND_SET_RD_MASK(0xff);
                    268: 
                    269:     // Or in the Color data to the work buffer.
                    270: 
                    271:     cmd  = BITBLT             | DRAW         | DIR_TYPE_XY |
                    272:            DRAWING_DIR_TBLRXM | SINGLE_PIXEL | WRITE;
                    273: 
                    274:     FIFOWAIT(FIFO_3_EMPTY);
                    275: 
                    276:     TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | SCREEN_OR_NEW);
                    277:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    278: 
                    279:     FIFOWAIT(FIFO_7_EMPTY);
                    280: 
                    281:     OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1);
                    282:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1));
                    283:     OUTPW(CUR_X, COLOR_POINTER_COLOR_DATA_X);
                    284:     OUTPW(CUR_Y, COLOR_POINTER_Y);
                    285:     OUTPW(DEST_X,COLOR_POINTER_WORK_X);
                    286:     OUTPW(DEST_Y,COLOR_POINTER_Y);
                    287:     OUTPW(CMD, cmd);
                    288: 
                    289:     // Now copy the work buffer to the screen.
                    290: 
                    291:     rclClip.left   = 0;
                    292:     rclClip.top    = 0;
                    293:     rclClip.right  = ppdev->cxScreen;
                    294:     rclClip.bottom = ppdev->cyScreen;
                    295: 
                    296:     vSetS3ClipRect(ppdev, &rclClip);
                    297: 
                    298:     cmd  = BITBLT             | DRAW | DIR_TYPE_XY |
                    299:            DRAWING_DIR_TBLRXM | WRITE;
                    300: 
                    301:     FIFOWAIT(FIFO_2_EMPTY);
                    302: 
                    303:     TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
                    304:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    305: 
                    306:     FIFOWAIT(FIFO_7_EMPTY);
                    307: 
                    308:     OUTPW(RECT_WIDTH, ppdev->szlPointer.cx - 1);
                    309:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | ppdev->szlPointer.cy - 1));
                    310:     OUTPW(CUR_X, COLOR_POINTER_WORK_X);
                    311:     OUTPW(CUR_Y, COLOR_POINTER_Y);
                    312:     OUTPW(DEST_X, xDest);
                    313:     OUTPW(DEST_Y, yDest);
                    314:     OUTPW(CMD, cmd);
                    315: 
                    316:     FIFOWAIT(FIFO_1_EMPTY);
                    317: 
                    318:     TEST_AND_SET_RD_MASK(0xff);
                    319: 
                    320:     // If the GDI requests the bounding box of the pointer,
                    321:     // return it.
                    322: 
                    323:     if (prcl != NULL)
                    324:     {
                    325:         prcl->left   = xDest;
                    326:         prcl->top    = yDest;
                    327:         prcl->right  = xDest + ppdev->szlPointer.cx;
                    328:         prcl->bottom = yDest + ppdev->szlPointer.cy;
                    329: 
                    330:     }
                    331: 
                    332:     // Reset the clipping.  This can go when no H/W clipping is done
                    333:     // on the color pointer.
                    334: 
                    335:     vResetS3Clipping(ppdev);
                    336: }
                    337: 
                    338: /*****************************************************************************
                    339:  * DrvMoveHwPointer -
                    340:  ****************************************************************************/
                    341: VOID DrvMoveHwPointer(
                    342:     SURFOBJ *pso,
                    343:     LONG x,
                    344:     LONG y,
                    345:     RECTL *prcl)
                    346: {
                    347:     WORD    msb, lsb;
                    348: 
                    349:     PPDEV   ppdev;
                    350: 
                    351:     ppdev = (PPDEV) pso->dhpdev;
                    352: 
                    353:     // Save the CRTC Index.
                    354: 
                    355:     ppdev->CrtcIndex = INP(CRTC_INDEX);
                    356: 
                    357:     // If x is -1 then take down the cursor.
                    358: 
                    359:     if (x == -1)
                    360:     {
                    361:         OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8)));
                    362:     }
                    363: 
                    364:     // Adjust the actual pointer position depending upon
                    365:     // the hot spot.
                    366: 
                    367:     x -= ppdev->ptlHotSpot.x;
                    368:     y -= ppdev->ptlHotSpot.y;
                    369: 
                    370:     // Record the current position as the last position;
                    371: 
                    372:     ppdev->ptlLastPosition.x = x;
                    373:     ppdev->ptlLastPosition.y = y;
                    374: 
                    375:     if (x <= 0)
                    376:     {
                    377:         OUTPW (CRTC_INDEX, ((-x << 8) | HGC_DX));
                    378:         x = 0;
                    379:     }
                    380:     else
                    381:     {
                    382:         OUTPW (CRTC_INDEX, ((0 << 8) | HGC_DX));
                    383:     }
                    384: 
                    385:     if (y <= 0)
                    386:     {
                    387:         OUTPW (CRTC_INDEX, ((-y << 8) | HGC_DY));
                    388:         y = 0;
                    389:     }
                    390:     else
                    391:     {
                    392:         OUTPW (CRTC_INDEX, ((0 << 8) | HGC_DY));
                    393:     }
                    394: 
                    395:     // Set the position of the cursor.
                    396: 
                    397:     msb = HIBYTE (x);
                    398:     lsb = LOBYTE (x);
                    399:     OUTPW (CRTC_INDEX, ((lsb << 8) | HGC_ORGX_LSB));
                    400:     OUTPW (CRTC_INDEX, ((msb << 8) | HGC_ORGX_MSB));
                    401: 
                    402:     msb = HIBYTE (y);
                    403:     lsb = LOBYTE (y);
                    404:     OUTPW (CRTC_INDEX, ((lsb << 8) | HGC_ORGY_LSB));
                    405:     OUTPW (CRTC_INDEX, ((msb << 8) | HGC_ORGY_MSB));
                    406: 
                    407:     // Restore the CRTC index
                    408: 
                    409:     OUTP(CRTC_INDEX, ppdev->CrtcIndex);
                    410: 
                    411: }
                    412: 
                    413: /*****************************************************************************
                    414:  * DrvMoveBt485Pointer -
                    415:  ****************************************************************************/
                    416: VOID DrvMoveBt485Pointer(
                    417:     SURFOBJ *pso,
                    418:     LONG x,
                    419:     LONG y,
                    420:     RECTL *prcl)
                    421: {
                    422:     WORD    msb, lsb;
                    423: 
                    424:     PPDEV   ppdev;
                    425: 
                    426:     ppdev = (PPDEV) pso->dhpdev;
                    427: 
                    428:     // Save the CRTC Index.
                    429: 
                    430:     ppdev->CrtcIndex = INP(CRTC_INDEX);
                    431: 
                    432:     // If x is -1 then take down the cursor.
                    433: 
                    434:     if (x == -1)
                    435:     {
                    436:         OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                    437:         OUTP  (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE);
                    438:         OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl));
                    439: 
                    440:         return;
                    441:     }
                    442: 
                    443:     // Adjust the actual pointer position depending upon
                    444:     // the hot spot.
                    445: 
                    446:     x -= ppdev->ptlHotSpot.x;
                    447:     y -= ppdev->ptlHotSpot.y;
                    448: 
                    449:     // Record the current position as the last position;
                    450: 
                    451:     ppdev->ptlLastPosition.x = x;
                    452:     ppdev->ptlLastPosition.y = y;
                    453: 
                    454:     // Adjust for the placement in the Bt485
                    455: 
                    456:     x += 64;
                    457:     y += 64;
                    458: 
                    459:     // Set the position of the cursor.
                    460: 
                    461:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0300));
                    462: 
                    463:     msb = HIBYTE (x);
                    464:     lsb = LOBYTE (x);
                    465: 
                    466:     OUTP(BT485_CURSOR_X_LOW,  lsb);
                    467:     OUTP(BT485_CURSOR_X_HIGH, msb);
                    468: 
                    469:     msb = HIBYTE (y);
                    470:     lsb = LOBYTE (y);
                    471: 
                    472:     OUTP(BT485_CURSOR_Y_LOW,  lsb);
                    473:     OUTP(BT485_CURSOR_Y_HIGH, msb);
                    474: 
                    475:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl));
                    476: 
                    477:     // Restore the CRTC index
                    478: 
                    479:     OUTP(CRTC_INDEX, ppdev->CrtcIndex);
                    480: 
                    481: }
                    482: 
                    483: 
                    484: 
                    485: /*****************************************************************************
                    486:  * DrvSetPointerShape -
                    487:  ****************************************************************************/
                    488: ULONG DrvSetPointerShape(
                    489:     SURFOBJ     *pso,
                    490:     SURFOBJ     *psoMask,
                    491:     SURFOBJ     *psoColor,
                    492:     XLATEOBJ    *pxlo,
                    493:     LONG        xHot,
                    494:     LONG        yHot,
                    495:     LONG        x,
                    496:     LONG        y,
                    497:     RECTL       *prcl,
                    498:     FLONG       fl)
                    499: {
                    500:     ULONG   ulRet;
                    501:     PPDEV   ppdev;
                    502:     BOOL    bResetAnimateFlag;
                    503: 
                    504:     ppdev = (PPDEV) pso->dhpdev;
                    505: 
                    506:     // Save the hot spot in the pdev.
                    507: 
                    508:     ppdev->ptlHotSpot.x = xHot;
                    509:     ppdev->ptlHotSpot.y = yHot;
                    510: 
                    511:     ppdev->szlPointer.cx = psoMask->sizlBitmap.cx;
                    512:     ppdev->szlPointer.cy = psoMask->sizlBitmap.cy / 2;
                    513: 
                    514:     // The pointer may be larger than we can handle.
                    515:     // If it is we must cleanup the screen and let the engine
                    516:     // take care of it.
                    517: 
                    518:     if (psoMask->sizlBitmap.cx > 64 || psoMask->sizlBitmap.cy > 64)
                    519:     {
                    520:         // If it's a color pointer take it down.
                    521: 
                    522:         if (   (ppdev->flPointer & COLOR_POINTER)
                    523:             && (ppdev->flPointer & VALID_SAVE_BUFFER)
                    524:            )
                    525:         {
                    526:             ulRet = DrvSetColorPointerShape(pso, NULL, NULL, NULL,
                    527:                                             0, 0, 0, 0, NULL, 0);
                    528:         }
                    529: 
                    530:         // Disable the mono hardware pointer.
                    531: 
                    532:         if (ppdev->bBt485Dac == TRUE)
                    533:         {
                    534:             // Disable the H/W cursor on the Bt 485.
                    535: 
                    536:             OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                    537:             OUTP  (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE);
                    538:             OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl));
                    539: 
                    540:         }
                    541:         else
                    542:         {
                    543:             OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8)));
                    544:         }
                    545: 
                    546:         // reset our local pointer flags.
                    547: 
                    548:         ppdev->flPointer = 0;
                    549: 
                    550:         return (SPS_DECLINE);
                    551: 
                    552:     }
                    553: 
                    554:     // Set the AnimateUpdate flag.
                    555: 
                    556:     if ((fl & SPS_ANIMATEUPDATE) &&
                    557:         ((x - xHot) == ppdev->ptlLastPosition.x) &&
                    558:         ((y - yHot) == ppdev->ptlLastPosition.y))
                    559:     {
                    560:         ppdev->flPointer |= ANIMATEUPDATE;
                    561:     }
                    562:     else
                    563:     {
                    564:         ppdev->flPointer &= ~ANIMATEUPDATE;
                    565:     }
                    566: 
                    567:     if (psoColor != NULL)
                    568:     {
                    569:         // Disable the mono hardware pointer.
                    570: 
                    571:         if (ppdev->bBt485Dac == TRUE)
                    572:         {
                    573:             // Disable the H/W cursor on the Bt 485.
                    574: 
                    575:             OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                    576:             OUTP  (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE);
                    577:             OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl));
                    578: 
                    579:         }
                    580:         else
                    581:         {
                    582:             OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8)));
                    583:         }
                    584: 
                    585:         ppdev->flPointer |= COLOR_POINTER;
                    586:         ulRet = DrvSetColorPointerShape(pso, psoMask, psoColor, pxlo,
                    587:                                         xHot, yHot, x, y, prcl, fl);
                    588: 
                    589:     }
                    590:     else
                    591:     {
                    592:         // Take down the color pointer if it is visible.
                    593: 
                    594:         if (   (ppdev->flPointer & COLOR_POINTER)
                    595:             && (ppdev->flPointer & VALID_SAVE_BUFFER)
                    596:            )
                    597:         {
                    598:             // If we are making a transition from a color to a monochrome pointer
                    599:             // and we haven't moved the pointer, and we're still in Animate Update mode,
                    600:             // then we have to turn off the Animate Update flag for this call to turn off
                    601:             // the color pointer.
                    602: 
                    603:             if (ppdev->flPointer & ANIMATEUPDATE)
                    604:             {
                    605:                 bResetAnimateFlag = TRUE;
                    606:                 ppdev->flPointer &= ~ANIMATEUPDATE;
                    607:             }
                    608:             else
                    609:             {
                    610:                 bResetAnimateFlag = FALSE;
                    611:             }
                    612: 
                    613:             ulRet = DrvSetColorPointerShape(pso, NULL, NULL, NULL,
                    614:                                             0, 0, 0, 0, NULL, 0);
                    615: 
                    616:             if (bResetAnimateFlag == TRUE)
                    617:             {
                    618:                 ppdev->flPointer |= ANIMATEUPDATE;
                    619:             }
                    620:         }
                    621: 
                    622:         // Take care of the monochrome pointer.
                    623: 
                    624:         ppdev->flPointer &= ~COLOR_POINTER;
                    625: 
                    626:         if (ppdev->bBt485Dac == TRUE)
                    627:         {
                    628:             ulRet = DrvSetBt485PointerShape(pso, psoMask, psoColor, pxlo,
                    629:                                             xHot, yHot, x, y, prcl, fl);
                    630:         }
                    631:         else
                    632:         {
                    633:             ulRet = DrvSetMonoHwPointerShape(pso, psoMask, psoColor, pxlo,
                    634:                                              xHot, yHot, x, y, prcl, fl);
                    635:         }
                    636:     }
                    637: 
                    638:     // Now that we have done an animation update, revert to a normal
                    639:     // pointer.
                    640: 
                    641:     if (ppdev->flPointer & ANIMATEUPDATE)
                    642:     {
                    643:         ppdev->flPointer &= ~ANIMATEUPDATE;
                    644:     }
                    645: 
                    646:     return (ulRet);
                    647: }
                    648: 
                    649: 
                    650: /*****************************************************************************
                    651:  * DrvSetColorPointerShape -
                    652:  ****************************************************************************/
                    653: ULONG DrvSetColorPointerShape(
                    654:     SURFOBJ     *pso,
                    655:     SURFOBJ     *psoMask,
                    656:     SURFOBJ     *psoColor,
                    657:     XLATEOBJ    *pxlo,
                    658:     LONG        xHot,
                    659:     LONG        yHot,
                    660:     LONG        x,
                    661:     LONG        y,
                    662:     RECTL       *prcl,
                    663:     FLONG       fl)
                    664: {
                    665:     UINT    i, j, k;
                    666:     PBYTE   pb;
                    667:     WORD    Cmd;
                    668:     UINT    cxMask, cyMask, cyAND, cyXOR, cxANDBytes, cxXORBytes;
                    669:     UINT    cxColor, cyColor;
                    670:     PBYTE   pjAND, pjXOR, pjColor;
                    671:     LONG    lDelta, lColorDelta;
                    672:     PBYTE   pb4Bpp;
                    673:     UINT    nSrcBytes;
                    674:     PULONG  pulXlate;
                    675:     RECTL   rclClip;
                    676:     PPDEV   ppdev;
                    677:     BYTE    LineBuff8Bpp[64];
                    678: 
                    679:     DISPDBG((3, "S3.DLL:DrvSetColorPointerShape  - Entry\n"));
                    680: 
                    681:     ppdev = (PPDEV) pso->dhpdev;
                    682: 
                    683:     // Sync this operation with the rest of the driver.
                    684: 
                    685:     GPWAIT();
                    686: 
                    687:     // Remove the current pointer, if it is on the screen.
                    688: 
                    689:     if ((ppdev->flPointer & VALID_SAVE_BUFFER) && (!(ppdev->flPointer & ANIMATEUPDATE)))
                    690:     {
                    691:         DrvMovePointer(pso, -1, -1, NULL);
                    692:     }
                    693: 
                    694:     // If the pointer is completely transparent, then just return.
                    695: 
                    696:     if (psoMask == NULL)
                    697:     {
                    698:         return (SPS_ACCEPT_EXCLUDE);
                    699:     }
                    700: 
                    701:     // If the GDI requests the bounding box of the pointer,
                    702:     // return it.
                    703: 
                    704:     if (prcl != NULL)
                    705:     {
                    706:         cxMask = psoMask->sizlBitmap.cx;
                    707:         cyMask = psoMask->sizlBitmap.cy;
                    708: 
                    709:         prcl->left   = x - xHot;
                    710:         prcl->top    = y - yHot;
                    711:         prcl->right  = prcl->left + cxMask;
                    712:         prcl->bottom = prcl->top  + cyMask;
                    713: 
                    714:     }
                    715: 
                    716:     // Set the clipping.
                    717: 
                    718:     rclClip.left   = 0;
                    719:     rclClip.top    = COLOR_POINTER_Y;
                    720:     rclClip.right  = COLOR_POINTER_CX * 3;
                    721:     rclClip.bottom = COLOR_POINTER_Y + COLOR_POINTER_CY;
                    722: 
                    723:     vSetS3ClipRect(ppdev, &rclClip);
                    724: 
                    725:     // Get the bitmap dimensions.
                    726: 
                    727:     cxMask = psoMask->sizlBitmap.cx;
                    728:     cyMask = psoMask->sizlBitmap.cy;
                    729: 
                    730:     cxColor = psoColor->sizlBitmap.cx;
                    731:     cyColor = psoColor->sizlBitmap.cy;
                    732: 
                    733:     cyAND = cyXOR = cyMask / 2;
                    734:     cxANDBytes = cxXORBytes = cxMask / 8;
                    735: 
                    736:     // Set up pointers to the AND and XOR masks.
                    737: 
                    738:     pjAND  =  psoMask->pvScan0;
                    739:     lDelta = psoMask->lDelta;
                    740:     pjXOR  = pjAND + (cyAND * lDelta);
                    741: 
                    742:     pjColor = psoColor->pvScan0;
                    743:     lColorDelta = psoColor->lDelta;
                    744: 
                    745:     // Zero out coprocessor memory for the masks, color data,
                    746:     // and the work area.  Be carefull not to wipe out the save area.
                    747: 
                    748:     Cmd = RECTANGLE_FILL |
                    749:           DRAW           | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
                    750:           LAST_PIXEL_ON  | SINGLE_PIXEL       | WRITE;
                    751: 
                    752:     FIFOWAIT(FIFO_3_EMPTY);
                    753: 
                    754:     TEST_AND_SET_FRGD_MIX(LOGICAL_0);
                    755:     TEST_AND_SET_WRT_MASK(0xff);
                    756:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    757: 
                    758:     FIFOWAIT(FIFO_5_EMPTY);
                    759: 
                    760:     OUTPW(CUR_X, 0);
                    761:     OUTPW(CUR_Y, COLOR_POINTER_Y);
                    762:     OUTPW(RECT_WIDTH, (COLOR_POINTER_CX * 2) - 1);
                    763:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | COLOR_POINTER_CY - 1));
                    764:     OUTPW(CMD, Cmd);
                    765: 
                    766:     // Copy the AND mask to the off screen memory.
                    767: 
                    768:     Cmd = RECTANGLE_FILL | BUS_SIZE_8         | WAIT |
                    769:           DRAW           | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
                    770:           LAST_PIXEL_ON  | MULTIPLE_PIXELS    | WRITE;
                    771: 
                    772: 
                    773:     FIFOWAIT(FIFO_6_EMPTY);
                    774: 
                    775:     TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT);
                    776:     TEST_AND_SET_FRGD_COLOR(0xff);
                    777:     TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT);
                    778:     SET_BKGD_COLOR(0x00);
                    779:     TEST_AND_SET_WRT_MASK(COLOR_POINTER_AND_PLANE);
                    780:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
                    781: 
                    782:     FIFOWAIT(FIFO_5_EMPTY);
                    783: 
                    784:     OUTPW(CUR_X, 0);
                    785:     OUTPW(CUR_Y, COLOR_POINTER_Y);
                    786:     OUTPW(RECT_WIDTH, cxMask - 1);
                    787:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyAND - 1));
                    788: 
                    789:     GPWAIT();
                    790: 
                    791:     OUTPW(CMD, Cmd);
                    792: 
                    793:     CHECK_DATA_READY;
                    794: 
                    795:     // Now transfer the AND mask data.
                    796: 
                    797:     FIFOWAIT(FIFO_8_EMPTY);
                    798: 
                    799:     pb = pjAND;
                    800:     for (i = 0; i < cyAND; i++)
                    801:     {
                    802:         vDataPortOutB(ppdev,(PBYTE) pb, cxANDBytes);
                    803:         pb += lDelta;
                    804:     }
                    805: 
                    806:     CHECK_DATA_COMPLETE;
                    807: 
                    808: 
                    809:     // Copy the XOR mask to the off screen memory.
                    810: 
                    811:     Cmd = RECTANGLE_FILL | BUS_SIZE_8         | WAIT |
                    812:           DRAW           | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
                    813:           LAST_PIXEL_ON  | MULTIPLE_PIXELS    | WRITE;
                    814: 
                    815:     FIFOWAIT(FIFO_6_EMPTY);
                    816: 
                    817:     TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT);
                    818:     TEST_AND_SET_FRGD_COLOR(0xff);
                    819:     TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT);
                    820:     SET_BKGD_COLOR(0x00);
                    821:     TEST_AND_SET_WRT_MASK(COLOR_POINTER_XOR_PLANE);
                    822:     OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
                    823: 
                    824:     FIFOWAIT(FIFO_5_EMPTY);
                    825: 
                    826:     OUTPW(CUR_X, 0);
                    827:     OUTPW(CUR_Y, COLOR_POINTER_Y);
                    828:     OUTPW(RECT_WIDTH, cxMask - 1);
                    829:     OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyXOR - 1));
                    830: 
                    831:     GPWAIT();
                    832: 
                    833:     OUTPW(CMD, Cmd);
                    834: 
                    835:     // Now transfer the XOR mask data.
                    836: 
                    837:     FIFOWAIT(FIFO_8_EMPTY);
                    838: 
                    839:     pb = pjXOR;
                    840:     for (i = 0; i < cyXOR; i++)
                    841:     {
                    842:         vDataPortOutB(ppdev,(PBYTE) pb, cxXORBytes);
                    843:         pb += lDelta;
                    844:     }
                    845: 
                    846:     FIFOWAIT(FIFO_1_EMPTY);
                    847: 
                    848:     TEST_AND_SET_WRT_MASK(0xff);
                    849: 
                    850:     if (psoColor->iBitmapFormat == BMF_8BPP)
                    851:     {
                    852:         // Copy the Color mask to the off screen memory.
                    853: 
                    854:         Cmd = RECTANGLE_FILL | BUS_SIZE_8         | WAIT |
                    855:               DRAW           | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
                    856:               LAST_PIXEL_ON  | SINGLE_PIXEL       | WRITE;
                    857: 
                    858:         FIFOWAIT(FIFO_7_EMPTY);
                    859: 
                    860:         TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT);
                    861:         OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    862:         OUTPW(CUR_X, COLOR_POINTER_CX);
                    863:         OUTPW(CUR_Y, COLOR_POINTER_Y);
                    864:         OUTPW(RECT_WIDTH, cxColor - 1);
                    865:         OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyColor - 1));
                    866: 
                    867:         GPWAIT();
                    868: 
                    869:         OUTPW(CMD, Cmd);
                    870: 
                    871:         CHECK_DATA_READY;
                    872: 
                    873:         // Now transfer the data.
                    874: 
                    875:         // Note: It would nice to do the entire bitmap in one
                    876:         //       fell swoop, but there is no gaurantee source will
                    877:         //       wrap on a bitmap boundary.
                    878: 
                    879:         FIFOWAIT(FIFO_8_EMPTY);
                    880: 
                    881:         pb = pjColor;
                    882:         for (i = 0; i < cyColor; i++)
                    883:         {
                    884:             vDataPortOutB(ppdev,pb, cxColor);
                    885:             pb += lColorDelta;
                    886:         }
                    887: 
                    888:         CHECK_DATA_COMPLETE;
                    889:     }
                    890:     else
                    891:     {
                    892:         Cmd = RECTANGLE_FILL | BUS_SIZE_8         | WAIT |
                    893:               DRAW           | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
                    894:               LAST_PIXEL_ON  | SINGLE_PIXEL       | WRITE;
                    895: 
                    896:         FIFOWAIT(FIFO_7_EMPTY);
                    897: 
                    898:         TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT);
                    899:         OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
                    900:         OUTPW(CUR_X, COLOR_POINTER_CX);
                    901:         OUTPW(CUR_Y, COLOR_POINTER_Y);
                    902:         OUTPW(RECT_WIDTH, cxColor - 1);
                    903:         OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cyColor - 1));
                    904: 
                    905:         GPWAIT();
                    906: 
                    907:         OUTPW(CMD, Cmd);
                    908: 
                    909:         CHECK_DATA_READY;
                    910: 
                    911:         // Now transfer the data.
                    912: 
                    913:         // Note: It would nice to do the entire bitmap in one
                    914:         //       fell swoop, but there is no gaurantee source will
                    915:         //       wrap on a bitmap boundary.
                    916: 
                    917:         pb4Bpp = pjColor;
                    918:         nSrcBytes = (cxColor + 1) / 2;
                    919: 
                    920:         if (pxlo->flXlate & XO_TABLE)
                    921:         {
                    922:             pulXlate = pxlo->pulXlate;
                    923:         }
                    924:         else
                    925:         {
                    926:             pulXlate = XLATEOBJ_piVector(pxlo);
                    927:         }
                    928: 
                    929:         FIFOWAIT(FIFO_8_EMPTY);
                    930: 
                    931:         for (i = 0; i < cyColor; i++)
                    932:         {
                    933:             for (k = 0, j = 0; j < nSrcBytes; j++)
                    934:             {
                    935:                 LineBuff8Bpp[k++] = (BYTE) pulXlate[(pb4Bpp[j] & 0xF0) >> 4];
                    936:                 LineBuff8Bpp[k++] = (BYTE) pulXlate[pb4Bpp[j] & 0x0F];
                    937:             }
                    938: 
                    939:             vDataPortOutB(ppdev,LineBuff8Bpp, cxColor);
                    940:             pb4Bpp += lColorDelta;
                    941:         }
                    942: 
                    943:         CHECK_DATA_COMPLETE;
                    944:     }
                    945: 
                    946:     // Set the position of the cursor.
                    947: 
                    948:     DrvMovePointer(pso, x, y, NULL);
                    949: 
                    950:     return (SPS_ACCEPT_EXCLUDE);
                    951: }
                    952: 
                    953: /*****************************************************************************
                    954:  * DrvSetMonoHwPointerShape -
                    955:  ****************************************************************************/
                    956: ULONG DrvSetMonoHwPointerShape(
                    957:     SURFOBJ     *pso,
                    958:     SURFOBJ     *psoMask,
                    959:     SURFOBJ     *psoColor,
                    960:     XLATEOBJ    *pxlo,
                    961:     LONG        xHot,
                    962:     LONG        yHot,
                    963:     LONG        x,
                    964:     LONG        y,
                    965:     RECTL       *prcl,
                    966:     FLONG       fl)
                    967: {
                    968:     UINT    i, j, k, cxMask, cyMask, cyAND, cxAND, cyXOR, cxXOR;
                    969:     PBYTE   pjAND, pjXOR;
                    970:     PWORD   pwS3AndMask, pwS3XorMask, pInterleavedMasks;
                    971:     WORD    msb, lsb;
                    972:     INT     lDelta;
                    973:     PPDEV   ppdev;
                    974:     WORD    PointerDataY;
                    975:     BYTE    s3AndMask[64][8],
                    976:             s3XorMask[64][8];
                    977:     WORD    s3InterleavedMasks[512];
                    978: 
                    979:     DISPDBG((3, "S3.DLL:DrvSetMonoHwPointerShape - Entry\n"));
                    980: 
                    981:     ppdev = (PPDEV) pso->dhpdev;
                    982: 
                    983:     // If the mask is NULL this implies the pointer is not
                    984:     // visible.
                    985: 
                    986:     if (psoMask == NULL)
                    987:     {
                    988:         OUTPW (CRTC_INDEX, (ppdev->HgcMode & ~(HGC_ENABLE << 8)));
                    989:         return (SPS_ACCEPT_NOEXCLUDE);
                    990:     }
                    991: 
                    992:     // Init the AND and XOR masks.
                    993: 
                    994:     memset (s3AndMask, 0xFF, 512);
                    995:     memset (s3XorMask, 0x00, 512);
                    996: 
                    997:     // Get the bitmap dimensions.
                    998: 
                    999:     cxMask = psoMask->sizlBitmap.cx;
                   1000:     cyMask = psoMask->sizlBitmap.cy;
                   1001: 
                   1002:     cyAND = cyXOR = cyMask / 2;
                   1003:     cxAND = cxXOR = cxMask / 8;
                   1004: 
                   1005:     // Set up pointers to the AND and XOR masks.
                   1006: 
                   1007:     pjAND  =  psoMask->pvScan0;
                   1008:     lDelta = psoMask->lDelta;
                   1009:     pjXOR  = pjAND + (cyAND * lDelta);
                   1010: 
                   1011:     // Copy the AND mask.
                   1012: 
                   1013:     memset (s3AndMask, 0xFFFFFFFF, 512);
                   1014:     memset (s3XorMask, 0, 512);
                   1015: 
                   1016:     for (i = 0; i < cyAND; i++)
                   1017:     {
                   1018:         // Copy over a line of the AND mask.
                   1019: 
                   1020:         for (j = 0; j < cxAND; j++)
                   1021:         {
                   1022:             s3AndMask[i][j] = pjAND[j];
                   1023:         }
                   1024: 
                   1025:         // point to the next line of the AND mask.
                   1026: 
                   1027:         pjAND += lDelta;
                   1028:     }
                   1029: 
                   1030:     // Copy the XOR mask.
                   1031: 
                   1032:     for (i = 0; i < cyXOR; i++)
                   1033:     {
                   1034:         // Copy over a line of the XOR mask.
                   1035: 
                   1036:         for (j = 0; j < cxXOR; j++)
                   1037:         {
                   1038:             s3XorMask[i][j] = pjXOR[j];
                   1039:         }
                   1040: 
                   1041:         // point to the next line of the XOR mask.
                   1042: 
                   1043:         pjXOR += lDelta;
                   1044:     }
                   1045: 
                   1046:     // Interleave the S3AND and S3XOR masks.
                   1047:     // This will allow an rep stosw instruction to down
                   1048:     // load the mask to the card..
                   1049: 
                   1050:     pwS3AndMask = (PWORD) s3AndMask;
                   1051:     pwS3XorMask = (PWORD) s3XorMask;
                   1052:     pInterleavedMasks = s3InterleavedMasks;
                   1053: 
                   1054:     // Interleave the S3AND and S3XOR masks.
                   1055:     // This will allow an rep stosw instruction to down
                   1056:     // load the mask to the card..
                   1057: 
                   1058:     pwS3AndMask = (PWORD) s3AndMask;
                   1059:     pwS3XorMask = (PWORD) s3XorMask;
                   1060:     pInterleavedMasks = s3InterleavedMasks;
                   1061: 
                   1062:     k = 256;
                   1063: 
                   1064:     for (i = 0; i < k; i++)
                   1065:     {
                   1066:         *pInterleavedMasks++ = *pwS3AndMask++;
                   1067:         *pInterleavedMasks++ = *pwS3XorMask++;
                   1068:     }
                   1069: 
                   1070:     // Down load the pointer shape to the S3 chip.
                   1071:     // Determine Which Monochrome pointer buffer is available.
                   1072: 
                   1073:     if (ppdev->MonoPointerData == 0)
                   1074:     {
                   1075:         PointerDataY = LOWORD (PTR_DATA_Y);
                   1076:         ppdev->MonoPointerData = 1;
                   1077:     }
                   1078:     else
                   1079:     {
                   1080:         PointerDataY = LOWORD (PTR_DATA_Y - 1);
                   1081:         ppdev->MonoPointerData = 0;
                   1082:     }
                   1083: 
                   1084:     // Set the clipping window to include the last line of offscreen
                   1085:     // memory.
                   1086: 
                   1087:     vResetS3Clipping(ppdev);
                   1088: 
                   1089:     // Wait for Fifo 7 to empty.
                   1090: 
                   1091:     FIFOWAIT(FIFO_7_EMPTY);
                   1092: 
                   1093:     // Now set up for the rectangle.
                   1094: 
                   1095:     OUTPW (CUR_X, PTR_DATA_X);
                   1096:     OUTPW (CUR_Y, PointerDataY);
                   1097: 
                   1098:     OUTPW (RECT_WIDTH, ppdev->cxMaxRam - 1);
                   1099:     OUTPW (MULTIFUNC_CNTL, RECT_HEIGHT);
                   1100: 
                   1101:     OUTPW (MULTIFUNC_CNTL, DATA_EXTENSION);
                   1102: 
                   1103:     TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT);
                   1104: 
                   1105:     GPWAIT();
                   1106: 
                   1107:     OUTPW (CMD, (RECTANGLE_FILL | BYTE_SWAP |
                   1108:                  BUS_SIZE_16    | WAIT      |
                   1109:                  DRAWING_DIR_TBLRXM         |
                   1110:                  DRAW      | WRITE));
                   1111: 
                   1112:     CHECK_DATA_READY;
                   1113: 
                   1114:     // Now down load the masks.
                   1115: 
                   1116:     vDataPortOut(ppdev, (PWORD) s3InterleavedMasks, 512);
                   1117: 
                   1118:     CHECK_DATA_COMPLETE;
                   1119: 
                   1120:     // This should do it. (the cursor should be downloaded)
                   1121:     // Now, wasn't that simple, NOT!
                   1122: 
                   1123:     // Note: At one point we disabled the pointer before setting the new one.
                   1124:     //       this caused an excessive flicker of the pointer, so we removed the disable.
                   1125:     //       At another point, we found the cursor jumped to the left for 1 frame if
                   1126:     //       we did not disable the cursor for non-animated pointers.  So, now
                   1127:     //       we handle each case separately.
                   1128: 
                   1129: 
                   1130:     if (!(ppdev->flPointer & ANIMATEUPDATE))
                   1131:     {
                   1132:         OUTPW (CRTC_INDEX, (ppdev->HgcMode | (HGC_DISABLE << 8)));
                   1133:     }
                   1134: 
                   1135:     // Set the hardware graphics cursor storage area start address for
                   1136:     // the new pointer data.
                   1137: 
                   1138:     msb = HIBYTE (PointerDataY);
                   1139:     lsb = LOBYTE (PointerDataY);
                   1140: 
                   1141:     OUTPW (CRTC_INDEX, ((msb << 8) | CR4C));
                   1142:     OUTPW (CRTC_INDEX, ((lsb << 8) | CR4D));
                   1143: 
                   1144:     // Set the position of the cursor.
                   1145:     // Need to do this twice, due to shadowing in the 928 and 801/805.
                   1146: 
                   1147:     DrvMoveHwPointer(pso, x, y, NULL);
                   1148: 
                   1149:     // On the 928, 801/805 wait for vertical interval then set the
                   1150:     // position a second time.
                   1151: 
                   1152:     if (ppdev->s3ChipID >= 0x90)
                   1153:     {
                   1154:         while (INP(STATUS_1) & VSY_NOT);
                   1155:         DrvMoveHwPointer(pso, x, y, NULL);
                   1156: 
                   1157:         while (!(INP(STATUS_1) & VSY_NOT));
                   1158:         DrvMoveHwPointer(pso, x, y, NULL);
                   1159: 
                   1160:     }
                   1161: 
                   1162:     OUTPW (CRTC_INDEX, (ppdev->HgcMode | (HGC_ENABLE << 8)));
                   1163: 
                   1164:     // Reset the clipping.  This can go when no H/W clipping is done
                   1165:     // on the color pointer.
                   1166: 
                   1167:     vResetS3Clipping(ppdev);
                   1168: 
                   1169:     return (SPS_ACCEPT_NOEXCLUDE);
                   1170: }
                   1171: 
                   1172: 
                   1173: 
                   1174: /*****************************************************************************
                   1175:  * DrvSetBt485PointerShape -
                   1176:  ****************************************************************************/
                   1177: ULONG DrvSetBt485PointerShape(
                   1178:     SURFOBJ     *pso,
                   1179:     SURFOBJ     *psoMask,
                   1180:     SURFOBJ     *psoColor,
                   1181:     XLATEOBJ    *pxlo,
                   1182:     LONG        xHot,
                   1183:     LONG        yHot,
                   1184:     LONG        x,
                   1185:     LONG        y,
                   1186:     RECTL       *prcl,
                   1187:     FLONG       fl)
                   1188: {
                   1189:     UINT    i, j, cxMask, cyMask, cyAND, cxAND, cyXOR, cxXOR;
                   1190:     PBYTE   pjAND, pjXOR;
                   1191:     INT     lDelta;
                   1192:     PPDEV   ppdev;
                   1193:     BYTE    s3AndMask[64][8],
                   1194:             s3XorMask[64][8];
                   1195: 
                   1196:     DISPDBG((3, "S3.DLL:DrvSetBt485PointerShape - Entry\n"));
                   1197: 
                   1198:     ppdev = (PPDEV) pso->dhpdev;
                   1199: 
                   1200:     // If the mask is NULL this implies the pointer is not
                   1201:     // visible.
                   1202: 
                   1203:     if (psoMask == NULL)
                   1204:     {
                   1205:         // Disable the H/W cursor on the Bt 485.
                   1206: 
                   1207:         OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                   1208:         OUTP  (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE);
                   1209:         OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl));
                   1210: 
                   1211:         return (SPS_ACCEPT_NOEXCLUDE);
                   1212:     }
                   1213: 
                   1214:     // Init the AND and XOR masks.
                   1215: 
                   1216:     memset (s3AndMask, 0xFF, 512);
                   1217:     memset (s3XorMask, 0x00, 512);
                   1218: 
                   1219:     // Get the bitmap dimensions.
                   1220: 
                   1221:     cxMask = psoMask->sizlBitmap.cx;
                   1222:     cyMask = psoMask->sizlBitmap.cy;
                   1223: 
                   1224:     cyAND = cyXOR = cyMask / 2;
                   1225:     cxAND = cxXOR = cxMask / 8;
                   1226: 
                   1227:     // Set up pointers to the AND and XOR masks.
                   1228: 
                   1229:     pjAND  =  psoMask->pvScan0;
                   1230:     lDelta = psoMask->lDelta;
                   1231:     pjXOR  = pjAND + (cyAND * lDelta);
                   1232: 
                   1233:     // Copy the AND mask.
                   1234: 
                   1235:     for (i = 0; i < cyAND; i++)
                   1236:     {
                   1237:         // Copy over a line of the AND mask.
                   1238: 
                   1239:         for (j = 0; j < cxAND; j++)
                   1240:         {
                   1241:             s3AndMask[i][j] = pjAND[j];
                   1242:         }
                   1243: 
                   1244:         // point to the next line of the AND mask.
                   1245: 
                   1246:         pjAND += lDelta;
                   1247:     }
                   1248: 
                   1249:     // Copy the XOR mask.
                   1250: 
                   1251:     for (i = 0; i < cyXOR; i++)
                   1252:     {
                   1253:         // Copy over a line of the XOR mask.
                   1254: 
                   1255:         for (j = 0; j < cxXOR; j++)
                   1256:         {
                   1257:             s3XorMask[i][j] = pjXOR[j];
                   1258:         }
                   1259: 
                   1260:         // point to the next line of the XOR mask.
                   1261: 
                   1262:         pjXOR += lDelta;
                   1263:     }
                   1264: 
                   1265:     pjAND = (PBYTE) s3AndMask;
                   1266:     pjXOR = (PBYTE) s3XorMask;
                   1267: 
                   1268:     // Set the cursor for 64 X 64, and set the 2 MSB's for the cursor
                   1269:     // RAM addr to 0.
                   1270:     // First get access to Command Register 3
                   1271: 
                   1272:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0100));
                   1273:     OUTP  (BT485_ADDR_CMD_REG0, ppdev->Bt485CmdReg0 | BT485_CMD_REG_3_ACCESS);
                   1274: 
                   1275:     OUTPW (CRTC_INDEX, ppdev->ExtDacCtl);
                   1276:     OUTP  (0x3c8, 0x01);
                   1277: 
                   1278:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                   1279:     OUTP  (BT485_ADDR_CMD_REG3, ppdev->Bt485CmdReg3);
                   1280: 
                   1281:     // Disable the H/W cursor on the Bt 485.
                   1282: 
                   1283:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                   1284:     OUTP  (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 & BT485_CURSOR_DISABLE);
                   1285: 
                   1286:     // Down load the AND mask
                   1287: 
                   1288:     OUTPW (CRTC_INDEX, ppdev->ExtDacCtl);
                   1289:     OUTP (BT485_ADDR_CUR_RAM_WRITE, 0x0);
                   1290: 
                   1291:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                   1292: 
                   1293:     // Down load the XOR mask
                   1294: 
                   1295:     for (i = 0 ; i < 512 ; i++)
                   1296:     {
                   1297:         OUTP (BT485_CUR_RAM_ARRAY_DATA, pjXOR[i]);
                   1298:     }
                   1299: 
                   1300:     // Down load the AND mask
                   1301: 
                   1302:     for (i = 0 ; i < 512 ; i++)
                   1303:     {
                   1304:         OUTP (BT485_CUR_RAM_ARRAY_DATA, pjAND[i]);
                   1305:     }
                   1306: 
                   1307:     // Set the position of the cursor.
                   1308:     // Need to do this twice, due to shadowing in the 928 and 801/805.
                   1309: 
                   1310:     DrvMoveBt485Pointer(pso, x, y, NULL);
                   1311: 
                   1312:     // Enable the H/W cursor
                   1313: 
                   1314:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl | 0x0200));
                   1315:     OUTP  (BT485_ADDR_CMD_REG2, ppdev->Bt485CmdReg2 | BT485_CURSOR_MODE2);
                   1316: 
                   1317:     // Reset DAC extended registers.
                   1318: 
                   1319:     OUTPW (CRTC_INDEX, (ppdev->ExtDacCtl));
                   1320: 
                   1321:     return (SPS_ACCEPT_NOEXCLUDE);
                   1322: }
                   1323: 
                   1324: 
                   1325: 
                   1326: 

unix.superglobalmegacorp.com

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