/*************************************************************************** * * ****************************************** * * Copyright (c) 1995, Cirrus Logic, Inc. * * * All Rights Reserved * * ****************************************** * * PROJECT: Laguna I (CL-GD5462) - * * FILE: pointer.c * * AUTHOR: Benny Ng * * DESCRIPTION: * This module contains the SW & HW curosr support for the * Laguna NT driver. * * MODULES: * DrvMovePointer() * DrvSetPointerShape() * * REVISION HISTORY: * 6/20/95 Benny Ng Initial version * * $Log: X:/log/laguna/nt35/displays/cl546x/POINTER.C $ * * Rev 1.39 Mar 04 1998 15:30:24 frido * Added new shadow macros. * * Rev 1.38 Jan 19 1998 10:26:26 frido * HP#86 (no PDR yet). Removed hardware cursor for 1600x1200 >=65Hz. * * Rev 1.37 Nov 03 1997 11:30:16 frido * Added REQUIRE macros. * * Rev 1.36 23 Sep 1997 10:48:22 bennyn * Not use HW cursor if the resolution is below 640x480 * * Rev 1.35 11 Jun 1997 15:13:14 bennyn * Fixed PDR 9747 Punt to SW cursor in 1600x1200x8 & x16 at 65,70,75 Hz * * Rev 1.34 11 Jun 1997 14:02:30 bennyn * Fixed PDR 9741 (animated cursor turns back) * * Rev 1.33 28 May 1997 14:17:58 bennyn * Fixed PDR 9741 and eliminated dead code * * Rev 1.32 01 May 1997 15:02:12 bennyn * Punt the cursor if it is in interlace modes * * Rev 1.31 09 Apr 1997 10:53:36 SueS * Changed type of pointer_switch to eliminate compiler warning. * * Rev 1.30 08 Apr 1997 15:22:50 SueS * Don't use color for monochrome animated cursors - otherwise we'll * reference a NULL pointer. * * Rev 1.29 07 Apr 1997 12:44:50 BENNYN * Added the checking ptrmaskhandle equal to NULL * * Rev 1.28 02 Apr 1997 14:24:14 noelv * NT 35.1 wass accessing a NULL pointer in DrvMovePointer * Removed SW cursor and chainblt cursor code * * Rev 1.27 21 Mar 1997 13:37:44 noelv * * Combined do_flag and sw_test_flag into pointer_switch * * Rev 1.26 03 Feb 1997 13:35:22 bennyn * Modified the 5465 cursor algorithm * * Rev 1.25 30 Jan 1997 17:15:02 bennyn * Added cursor algorithm for 5465 * * Rev 1.24 17 Dec 1996 17:01:10 SueS * Added test for writing to log file based on cursor at (0,0). * * Rev 1.23 10 Dec 1996 14:32:46 bennyn * * Fixed cursor mask from device bitmap problem * * Rev 1.22 26 Nov 1996 10:43:04 SueS * Changed WriteLogFile parameters for buffering. * * Rev 1.21 13 Nov 1996 17:00:52 SueS * Changed WriteFile calls to WriteLogFile. * * Rev 1.20 01 Nov 1996 09:26:46 BENNYN * * Cleanup unused code * * Rev 1.19 23 Oct 1996 14:44:44 BENNYN * * Fixed the YUV cursor problems * * Rev 1.18 06 Sep 1996 09:07:02 noelv * * Cleaned up NULL driver code. * * Rev 1.17 26 Aug 1996 17:35:08 bennyn * * Restore the changes for the losed version * * Rev 1.16 20 Aug 1996 11:04:20 noelv * Bugfix release from Frido 8-19-96 * * Rev 1.3 17 Aug 1996 19:39:20 frido * Fixed DirectDraw cursor problem. * * Rev 1.2 17 Aug 1996 13:34:56 frido * New release from Bellevue. * * Rev 1.1 15 Aug 1996 11:40:18 frido * Added precompiled header. * * Rev 1.0 14 Aug 1996 17:16:30 frido * Initial revision. * * Rev 1.13 25 Jul 1996 15:56:00 bennyn * * Modified to support DirectDraw * * Rev 1.12 18 Jun 1996 12:44:18 noelv * Fixed the way interleave is calculated. * * Rev 1.11 28 May 1996 15:11:28 noelv * Updated data logging. * * Rev 1.10 01 May 1996 12:23:30 bennyn * * Rev 1.9 01 May 1996 12:05:36 bennyn * Fixed resolution change bug for NT4.0 * * Rev 1.8 01 May 1996 11:00:48 bennyn * * Modified for NT4.0 * * Rev 1.7 04 Apr 1996 13:20:24 noelv * Frido release 26 * * Rev 1.4 28 Mar 1996 20:22:28 frido * Removed warning messages from new Bellevue release. * * Rev 1.6 25 Mar 1996 18:55:30 noelv * Fixed bouncing screeen when cursor is disabled. * * Rev 1.5 08 Mar 1996 17:27:38 noelv * * Added NULL_POINTER flag * * Rev 1.4 07 Mar 1996 18:22:46 bennyn * * Removed read/modify/write on CONTROL reg * * Rev 1.3 05 Mar 1996 11:58:26 noelv * Frido version 19 * * Rev 1.1 20 Jan 1996 01:22:00 frido * * * Rev 1.10 15 Jan 1996 16:59:58 NOELV * AB workaround reductions * * Rev 1.9 11 Jan 1996 09:22:04 NOELV * Removed al 16 bit writes to X,Y,and BLTEXT registers. * * Rev 1.8 10 Jan 1996 16:20:56 NOELV * Added increased logging capabilities. * Added null driver capabilities. * * Rev 1.7 29 Nov 1995 12:11:42 noelv * * Coded a workaround for HW bug. The screen corrupts sometimes when the curs * I changed the code to turn the cursor off as little as possible. * * Rev 1.6 29 Sep 1995 10:26:20 bennyn * * Punt the cursor to GDI for 1600x1200 modes * * Rev 1.5 29 Sep 1995 09:54:58 bennyn * * Rev 1.4 27 Sep 1995 16:45:40 bennyn * Fixed the HW cursor AND mask * * Rev 1.3 26 Sep 1995 16:27:50 bennyn * * Rev 1.2 26 Sep 1995 09:35:16 bennyn * Enable HW cursor * * Rev 1.1 21 Aug 1995 13:52:16 NOELV * Initial port to real hardware. * Converted all 32 bit register writes to 2 16 bit regiser writes. * * Rev 1.0 25 Jul 1995 11:19:28 NOELV * Initial revision. * * Rev 1.6 06 Jul 1995 09:57:10 BENNYN * * Fixed the problem switching between full-screen & Windowed DOS box * * Rev 1.5 29 Jun 1995 09:50:54 BENNYN * Fixed the unsupport cursor request problem * * Rev 1.4 29 Jun 1995 09:01:30 BENNYN * * Rev 1.3 28 Jun 1995 11:13:32 BENNYN * Fixed 16-bit/pixel problem * * Rev 1.2 22 Jun 1995 13:33:32 BENNYN * * Added SW cursor auto BLT * * Rev 1.1 20 Jun 1995 16:09:30 BENNYN * * **************************************************************************** ****************************************************************************/ /*----------------------------- INCLUDES ----------------------------------*/ #include "precomp.h" /*----------------------------- DEFINES -----------------------------------*/ //#define DBGBRK //#define DBGDISP #define CURSOR_DBG_LEVEL 1 #define MAX_CNT 0x7FFF #define BLT_FLAG_BIT 0x2L #define BYTES_PER_TILE 0x800 // 2048 /*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/ /*--------------------------- ENUMERATIONS --------------------------------*/ /*----------------------------- TYPEDEFS ----------------------------------*/ typedef union _HOST_DATA { BYTE bData[4]; DWORD dwData; } HOST_DATA; /*-------------------------- STATIC VARIABLES -----------------------------*/ /*-------------------------- GLOBAL FUNCTIONS -----------------------------*/ VOID CopyLgHWPtrMaskData(PPDEV ppdev, LONG Ycord, LONG lSrcDelta, LONG cy, ULONG tileszx, BYTE *pANDSrcScan, BYTE *pXORSrcScan); ULONG ConvertMaskBufToLinearAddr(PPDEV ppdev); VOID RestoreSaveShowCursor(PPDEV ppdev, LONG x, LONG y); #if POINTER_SWITCH_ENABLED int pointer_switch=0; #endif #if LOG_QFREE unsigned long QfreeData[32]; #endif /**************************************************************************** * FUNCTION NAME: InitPointerHW() * * DESCRIPTION: Initialization the cursor palette colors. * ****************************************************************************/ VOID InitPointerHW (PPDEV ppdev) { ULONG ultmp; // Enable HW cursor color access ultmp = LLDR_SZ (grPalette_State); ultmp |= 0x8; LL8 (grPalette_State, ultmp); // Write HW cursor BK & FG color ultmp = 0; LL8 (grPalette_Write_Address, ultmp); LL8 (grPalette_Data, ultmp); LL8 (grPalette_Data, ultmp); LL8 (grPalette_Data, ultmp); ultmp = 0xF; LL8 (grPalette_Write_Address, ultmp); ultmp = 0xFF; LL8 (grPalette_Data, ultmp); LL8 (grPalette_Data, ultmp); LL8 (grPalette_Data, ultmp); // Disable HW cursor color access ultmp = LLDR_SZ (grPalette_State); ultmp &= 0xFFF7; LL8 (grPalette_State, ultmp); } /**************************************************************************** * FUNCTION NAME: InitPointer() * * DESCRIPTION: Initialization the variables used by the pointer. * * REVISION HISTORY: * 6/20/95 Benny Ng Initial version ****************************************************************************/ VOID InitPointer(PPDEV ppdev) { ULONG ultmp; SIZEL reqsz; ppdev->PointerUsage = HW_CURSOR; DISPDBG((CURSOR_DBG_LEVEL, "HW cursor\n")); ppdev->bYUVuseSWPtr = FALSE; ppdev->PtrImageHandle = NULL; ppdev->PtrABltHandle = NULL; // Get the current tile size if (ppdev->lTileSize == (LONG) 128) { reqsz.cx = 128; reqsz.cy = 8; } else if (ppdev->lTileSize == (LONG) 256) { reqsz.cx = 256; reqsz.cy = 4; } else { reqsz.cx = 1024; reqsz.cy = 1; }; InitPointerHW (ppdev); // Allocate the mask buffer from offscreen memory DISPDBG((CURSOR_DBG_LEVEL, "Allocating Pointer Mask\n")); ppdev->PtrMaskHandle = AllocOffScnMem(ppdev, &reqsz, 0, NULL); #ifdef WINNT_VER40 ppdev->CShsem = NULL; #endif } /**************************************************************************** * FUNCTION NAME: DrvMovePointer() * * DESCRIPTION: This function Moves the hardware pointer to a new position. * * REVISION HISTORY: * 6/20/95 Benny Ng Initial version ****************************************************************************/ VOID DrvMovePointer(SURFOBJ *pso, LONG x, LONG y, RECTL *prcl) { LONG adjx, adjy; LONG delaycnt = 0; PPDEV ppdev = (PPDEV) pso->dhpdev; if (x==0 && y==0) { // // This isn't used in the released code. This is test code for setting // the sw_test_flag to different values by pointing the cursor to // 'special' places. Used to turn different test features on and off. // #if (POINTER_SWITCH_ENABLED) if (pointer_switch) pointer_switch = 0; else pointer_switch = 1; #endif #if ENABLE_LOG_SWITCH && POINTER_SWITCH_ENABLED if (pointer_switch) { CreateLogFile(ppdev->hDriver, &ppdev->TxtBuffIndex); ppdev->pmfile = ppdev->hDriver; // handle to the miniport lg_i = sprintf(lg_buf, "Log file opened\r\n"); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } else CloseLogFile(ppdev->pmfile, ppdev->TxtBuff, &ppdev->TxtBuffIndex); #endif #if NULL_HW // // Enables and disables the "infinitly fast hardware" feature. // then "on" all register writes go to a chunk of blank memory // on the host. Register reads proceed normally. // if (ppdev->pLgREGS == ppdev->pLgREGS_real) ppdev->pLgREGS = (GAR *)ppdev->buffer; else ppdev->pLgREGS = ppdev->pLgREGS_real; #endif #if LOG_QFREE { int i; DISPDBG((CURSOR_DBG_LEVEL,"Dumping QFREE log.\n")); lg_i = sprintf(lg_buf,"\r\n\r\n"); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); for (i=0; i<32; ++i) { lg_i = sprintf(lg_buf,"QFREE %d: %d times.\r\n", i, QfreeData[i]); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); QfreeData[i] = 0; } } #endif } // End if x==0 and y==0 #if LOG_CALLS #if ENABLE_LOG_SWITCH if (pointer_switch) #endif { lg_i = sprintf(lg_buf,"DrvMovePointer: x=%d, y=%d \r\n", x, y); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } #endif #if NULL_POINTER if (pointer_switch) return; #endif if ((ppdev->PointerUsage == DEF_CURSOR) || (ppdev->PtrMaskHandle == NULL)) return; adjx = x; adjy = y; // Check whether want to hide the pointer. if (x == -1) { #if HW_PRESET_BUG LL16 (grCursor_X, (WORD)0xFFFF); LL16 (grCursor_Y, (WORD)0xFFFF); #else // Disable the Hw cursor by clearing the hw cursor enable // bit in CURSOR_CONTROL reg ultmp = LLDR_SZ (grCursor_Control); if (ultmp & 1) { ultmp &= 0xFFFE; LL16 (grCursor_Control, ultmp); } #endif } else if ((adjx >= 0) && (adjy >= 0)) { // Restore the current pointer area screen image from offscreen memory. // Save the new pointer area screen image to offscreen memory. // Show the curosr using both AND and XOR masks RestoreSaveShowCursor(ppdev, adjx, adjy); ppdev->PtrX = adjx; ppdev->PtrY = adjy; if (prcl != NULL) { prcl->left = ppdev->PtrX; prcl->top = ppdev->PtrY; prcl->right = prcl->left + ppdev->PtrSzX; prcl->bottom = prcl->top + ppdev->PtrSzY; ppdev->prcl.left = prcl->left; ppdev->prcl.top = prcl->top; ppdev->prcl.right = prcl->right; ppdev->prcl.bottom = prcl->bottom; } } return; } /**************************************************************************** * FUNCTION NAME: DrvSetPointerShape() * * DESCRIPTION: This function sets the new pointer shape. * * REVISION HISTORY: * 6/20/95 Benny Ng Initial version ****************************************************************************/ ULONG DrvSetPointerShape(SURFOBJ *pso, SURFOBJ *psoMask, SURFOBJ *psoColor, XLATEOBJ *pxlo, LONG xHot, LONG yHot, LONG x, LONG y, RECTL *prcl, FLONG fl) { BOOL bAnimatedCursor = FALSE; LONG lSrcDelta; ULONG retul; ULONG cx, cy; LONG bpp; SIZEL tilesz; SIZEL reqsz; BYTE *pANDSrcScan; BYTE *pXORSrcScan; LONG Ycord; ULONG curloc; ULONG ultmp; PPDEV ppdev = (PPDEV) pso->dhpdev; #if NULL_POINTER if (pointer_switch) return SPS_ACCEPT_NOEXCLUDE; #endif DISPDBG((CURSOR_DBG_LEVEL, "DrvSetPointerShape %d, x=%d, y=%d, xHot=%d, yHot=%d\n", ppdev->PointerUsage, x, y, xHot, yHot)); // If no HW cursor mask buffer allocated from offscreen memory, // or If in intrelace mode, Use SW cursor // Use SW cursor if ((ppdev->PtrMaskHandle == NULL) || (ppdev->ulFreq < 50)) return (SPS_DECLINE); // HW cursor bug in 1600x1200-8bpp & 16bpp with refresh rate 65, // 70 or 75Hz. Use SW cursor if ((ppdev->cxScreen == 1600) && (ppdev->cyScreen == 1200) && ((ppdev->ulBitCount == 8) || (ppdev->ulBitCount == 16))) { if (ppdev->ulFreq >= 65) return (SPS_DECLINE); }; // Don't use HW cursor if resolution below 640x480 if ((ppdev->cxScreen < 640) || (ppdev->cyScreen < 480)) return (SPS_DECLINE); // Get dimensions of the pointer cx = psoMask->sizlBitmap.cx ; cy = psoMask->sizlBitmap.cy >> 1; // Calculate bytes per pixel bpp = ppdev->iBytesPerPixel; // Get the current tile size if (ppdev->lTileSize == (LONG) 128) { tilesz.cx = 128; tilesz.cy = 16; } else if (ppdev->lTileSize == (LONG) 256) { tilesz.cx = 256; tilesz.cy = 8; } else { tilesz.cx = 2048; tilesz.cy = 1; }; lSrcDelta = psoMask->lDelta; retul = SPS_ACCEPT_NOEXCLUDE; // We can still draw while HW cursor is on the screen. // Check whether we should let the GDI handle the pointer if ((ppdev->PointerUsage == DEF_CURSOR) || (psoMask == (SURFOBJ *) NULL) || (cx > HW_POINTER_DIMENSION) || (cy > (HW_POINTER_DIMENSION - 1)) || (psoColor != NULL) || (fl & SPS_ASYNCCHANGE) || // We can't change the cursor shape while drawing. (fl & SPS_ANIMATESTART) || // We don't do animated cursors (fl & SPS_ANIMATEUPDATE) || // We don't do animated cursors !(fl & SPS_CHANGE)) { bAnimatedCursor = TRUE; #if HW_PRESET_BUG LL16 (grCursor_X, (WORD)0xFFFF); LL16 (grCursor_Y, (WORD)0xFFFF); #else // Disable the Hw cursor by clearing the hw cursor enable // bit in CURSOR_CONTROL reg ultmp = LLDR_SZ (grCursor_Control); if (ultmp & 1) { ultmp &= 0xFFFE; LL16 (grCursor_Control, ultmp); } #endif }; // Save the position informations // ppdev->PtrXHotSpot = xHot; ppdev->PtrYHotSpot = yHot; ppdev->PtrSzX = cx; ppdev->PtrSzY = cy; // Setup the AND and XOR mask data pointer pANDSrcScan = psoMask->pvScan0; pXORSrcScan = psoMask->pvScan0; pXORSrcScan += (cy * lSrcDelta); // If animated cursor generate the XOR mask from psoColor->pvScan0 // data if ((bAnimatedCursor) && (psoColor != NULL)) { PDSURF pDSURF; POFMHDL pOFMHDL; SURFOBJ* pDsurfSo; BYTE XorMaskBuf[130]; BYTE *pColorSrcScan; BYTE maskval; LONG ii, jj, kk, mm; BOOL bCalc; bCalc = FALSE; pColorSrcScan = NULL; if (psoColor->pvScan0 != NULL) { // From host memory pColorSrcScan = psoColor->pvScan0; } else { // From device bitmap pDSURF = (DSURF *) psoColor->dhsurf; pDsurfSo = (SURFOBJ*) pDSURF->pso; if (pDsurfSo != NULL) { pColorSrcScan = pDsurfSo->pvScan0; } else { pOFMHDL = (OFMHDL *) pDSURF->pofm; if (pOFMHDL != NULL) { bCalc = TRUE; pColorSrcScan = (BYTE *)((pOFMHDL->aligned_y * ppdev->lDeltaScreen) + pOFMHDL->aligned_x + (ULONG) ppdev->pjScreen); }; // endif (pOFMHDL != NULL) }; // endif (pDsurfSo != NULL) }; // endif (psoColor->pvScan0 != NULL) if (pColorSrcScan != NULL) { mm = 0; for (ii=0; ii < 0x20; ii++) { for (jj=0; jj < 0x4; jj++) { maskval = 0; for (kk=0; kk < 0x8; kk++) { maskval = maskval << 1; if ((*pColorSrcScan & 1) != 0) maskval |= 0x1; pColorSrcScan += ppdev->iBytesPerPixel; }; // endfor kk XorMaskBuf[mm++] = maskval; }; // endfor jj if (bCalc) { pColorSrcScan = (BYTE *)(((pOFMHDL->aligned_y+ii) * ppdev->lDeltaScreen) + pOFMHDL->aligned_x + (ULONG) ppdev->pjScreen); }; }; // endfor ii pXORSrcScan = &XorMaskBuf[0]; }; // endif (pColorSrcScan != NULL) }; // endif (bAnimatedCursor) // Set Laguna Command Control Register SWIZ_CNTL bit ppdev->grCONTROL |= SWIZ_CNTL; LL16(grCONTROL, ppdev->grCONTROL); // Setup the laguna registers for byte to byte BLT extents REQUIRE(6); LL_DRAWBLTDEF(0x102000CC, 0); LL_OP1 (0,0); Ycord = ppdev->PtrMaskHandle->aligned_y; LL_OP0_MONO (ppdev->PtrMaskHandle->aligned_x, Ycord); // Use the AND and XOR mask to create the mask buffer for Laguna HW. CopyLgHWPtrMaskData(ppdev, Ycord, lSrcDelta, cy, tilesz.cx, pANDSrcScan, pXORSrcScan); // Set the HW cursor mask location register curloc = ConvertMaskBufToLinearAddr(ppdev); curloc = (curloc >> 8) & 0xFFFC; LL16 (grCursor_Location, curloc); // Clear Laguna Command Control Register SWIZ_CNTL bit ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL; LL16(grCONTROL, ppdev->grCONTROL); // Specific the exclude rectange if (prcl != NULL) { prcl->left = x - xHot; prcl->top = y - yHot; prcl->right = prcl->left + cx; prcl->bottom = prcl->top + cy; ppdev->prcl.left = prcl->left; ppdev->prcl.top = prcl->top; ppdev->prcl.right = prcl->right; ppdev->prcl.bottom = prcl->bottom; }; if (bAnimatedCursor) { DISPDBG((CURSOR_DBG_LEVEL, "DrvSetPointerShape - SPS_DECLINE\n")); // Indicate use animiated cursor ppdev->bYUVuseSWPtr = TRUE; if (!ppdev->bYUVSurfaceOn) return (SPS_DECLINE); }; if ((ppdev->bYUVuseSWPtr) && (x == -1) && (y == -1)) { #if HW_PRESET_BUG LL16 (grCursor_X, (WORD)0xFFFF); LL16 (grCursor_Y, (WORD)0xFFFF); #else // Disable the Hw cursor by clearing the hw cursor enable // bit in CURSOR_CONTROL reg ultmp = LLDR_SZ (grCursor_Control); if (ultmp & 1) { ultmp &= 0xFFFE; LL16 (grCursor_Control, ultmp); } #endif ppdev->bYUVuseSWPtr = FALSE; return (SPS_DECLINE); }; // Enable the Hw cursor by setting the hw cursor enable // bit in CURSOR_CONTROL reg ultmp = LLDR_SZ (grCursor_Control); if ((ultmp & 1) == 0) { ultmp |= 0x0001; LL16 (grCursor_Control, ultmp); }; // Indicate use HW cursor ppdev->bYUVuseSWPtr = FALSE; // Show the pointer by using the mask buffer DrvMovePointer(pso, x, y, prcl); return (retul); } /**************************************************************************** * FUNCTION NAME: CopyLgHWPtrMaskData() * * DESCRIPTION: Using the AND & XOR source mask data to generate * a 64x64 bits pointer size mask buffer in the offscreen * memory for Laguna HW. * * REVISION HISTORY: * 6/20/95 Benny Ng Initial version ****************************************************************************/ VOID CopyLgHWPtrMaskData(PPDEV ppdev, LONG Ycord, LONG lSrcDelta, LONG cy, ULONG tileszx, BYTE *pANDSrcScan, BYTE *pXORSrcScan) { LONG i, j, k; LONG cnt; LONG DWcnt; PDWORD pPattern; LONG TileSize; HOST_DATA MaskPattern; pPattern = &MaskPattern.dwData; TileSize = ppdev->lTileSize; REQUIRE(3); LL_MBLTEXT (TileSize, (1024/TileSize)); DWcnt = tileszx / sizeof(DWORD); // Copy the mask data into the 64x64 space with unused portion // fill with AND or XOR default mask value. cnt = DWcnt; k = 0; for (i=0; i < 64; i++) { // Copy XOR mask for (j=0; j < 8; j++) { // Copy one screen line mask data from source to destination if ((j < lSrcDelta) && (i < cy)) { MaskPattern.bData[k++] = *pXORSrcScan; pXORSrcScan++; } else { MaskPattern.bData[k++] = 0x0; }; if (k > 3) { REQUIRE(1); LL32 (grHOSTDATA[0], *pPattern); k = 0; cnt--; }; // endif (k > 3) }; // endfor j // Copy AND mask for (j=0; j < 8; j++) { // Copy one screen line mask data from source to destination if ((j < lSrcDelta) && (i < cy)) { MaskPattern.bData[k++] = *pANDSrcScan; pANDSrcScan++; } else { MaskPattern.bData[k++] = 0xFF; }; if (k > 3) { *pPattern = ~ *pPattern; REQUIRE(1); LL32 (grHOSTDATA[0], *pPattern); k = 0; cnt--; }; // endif (k > 3) }; // endfor j // Check whether one tile row size of host data is written to the // HOSTDATA register. if (cnt == 0) { // Reset the row data count cnt = DWcnt; }; // endif (cnt == 0) }; // end for i }; /**************************************************************************** * FUNCTION NAME: RestoreSaveShowCursor() * * DESCRIPTION: Restore the screen image (if needed), save the new * cursor location the image to offscreen memory and * show the cursor in the new location * * REVISION HISTORY: * 6/20/95 Benny Ng Initial version ****************************************************************************/ VOID RestoreSaveShowCursor(PPDEV ppdev, LONG x, LONG y) { ULONG curloc; LONG ltmpX, ltmpY; DISPDBG((CURSOR_DBG_LEVEL, "DrvMovePointer - RestoreSaveShowCursor\n")); ltmpX = x; ltmpY = y; // Set Hw cursor preset register curloc = 0; if ((ltmpY = (y - ppdev->PtrYHotSpot)) < 0) { curloc = (-ltmpY) & 0x7F; ltmpY = 0; } if ((ltmpX = (x - ppdev->PtrXHotSpot)) < 0) { curloc = curloc | (((-ltmpX) << 8) & 0x7F00); ltmpX = 0; } LL16 (grCursor_Preset, curloc); // Set Hw cursor X & Y registers LL16 (grCursor_X, (WORD)ltmpX); LL16 (grCursor_Y, (WORD)ltmpY); return; }; /**************************************************************************** * FUNCTION NAME: ConvertMaskBufToLinearAddr() * * DESCRIPTION: Convert the HW cursor mask buffer address to linear offset * address. * * Input: Pointer to the OFMHDL structure. * * Output: 32-bits Linear address pointer. * * REVISION HISTORY: * 6/12/95 Benny Ng Initial version ****************************************************************************/ ULONG ConvertMaskBufToLinearAddr(PPDEV ppdev) { #if DRIVER_5465 ULONG Page; ULONG Bank; ULONG CurLoc; ULONG DP; #endif // DRIVER_5465 ULONG retaddr; ULONG xtile, ytile; ULONG tileszx, tileszy; ULONG tileno; ULONG xByteOffset, yByteOffset; ULONG bpp; ULONG TilesPerLine, Interleave; #ifdef DBGDISP DISPDBG((CURSOR_DBG_LEVEL, "ConvertMaskBufToLinearAddr\n")); #endif // Calculate the linear address from the X & Y coordinate if ((ppdev->lTileSize == (LONG) 128) || (ppdev->lTileSize == (LONG) 256)) { if (ppdev->lTileSize == (LONG) 128) { tileszx = 128; tileszy = 16; } else if (ppdev->lTileSize == (LONG) 256) { tileszx = 256; tileszy = 8; }; Interleave = LLDR_SZ(grTILE_CTRL); TilesPerLine = Interleave & 0x3F; Interleave = ((Interleave >> 6) & 0x3); Interleave = 1 << Interleave; bpp = ppdev->ulBitCount/8; #if DRIVER_5465 DP = TilesPerLine * tileszx; Page = (ppdev->PtrMaskHandle->aligned_y) / (tileszy * Interleave) * TilesPerLine + (ppdev->PtrMaskHandle->aligned_x/tileszx); Bank = (((ppdev->PtrMaskHandle->aligned_x / tileszx) + (ppdev->PtrMaskHandle->aligned_y / tileszy)) % Interleave) + ((Page/512) << (Interleave >> 1)); Page = Page & 0x1FF; CurLoc = (Bank<<20) + (Page<<11) + (ppdev->PtrMaskHandle->aligned_y % tileszy) * tileszx; retaddr = CurLoc; #else // calculate x tile coordinate and byte offset into tile due to x // xTileCoord = x / TileWidth // xByteOffset = x % TileWidth xtile = ppdev->PtrMaskHandle->aligned_x / tileszx; xByteOffset = ppdev->PtrMaskHandle->aligned_x % tileszx; // calculate y tile coordinate and byte offset into tile due to y // yTileCoord = y / TileHeight // yByteOffset = (y % TileHeight) * TileWidth // byteOffset = yByteOffset + xByteOffset ytile = ppdev->PtrMaskHandle->aligned_y / tileszy; yByteOffset = (ppdev->PtrMaskHandle->aligned_y % tileszy) * tileszx; // calculate tile number from start of RDRAM // (the LS 0,1,or 2 bits of this will become the bank selects based // on interleave of 1,2,or 4) // // tileNo = ((yTile / Interleave) * TilesPerLine) * Interleave // + xTile * Interleave // + (yTile + xTile) % Interleave // (the "+xTile" takes care of interleave rotation) tileno = (((ytile / Interleave) * TilesPerLine) * Interleave) + (xtile * Interleave) + ((ytile + xtile) % Interleave); // calculate linear offset // LinOffset = tileNo * BYTES_PER_TILE + xByteOffset + yByteOffset retaddr = (tileno * BYTES_PER_TILE) + xByteOffset + yByteOffset; #endif // DRIVER_5465 } else { // Calculate the linear address from the X & Y coordinate retaddr = (ULONG) ppdev->PtrMaskHandle->aligned_x + (ULONG) ppdev->lDeltaScreen * ppdev->PtrMaskHandle->aligned_y; }; return (retaddr); };