Annotation of ntddk/src/video/displays/s3/pointer.c, revision 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.