Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1060 lines
30 KiB

/***************************************************************************
*
* ******************************************
* * 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);
};