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.
1551 lines
40 KiB
1551 lines
40 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: pointer.c
|
|
*
|
|
* Copyright (c) 1992-1995 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
//
|
|
// This will disable the sync with vertical retrace. Stress tests are failing with v-sync enabled.
|
|
//
|
|
|
|
#define NO_VERTICAL_SYNC
|
|
|
|
BOOL flag_shape;
|
|
BYTE HardWareCursorShape [CURSOR_CX][CURSOR_CY] ;
|
|
|
|
// BEGIN MACH32 ----------------------------------------------------------------
|
|
|
|
VOID vI32SetCursorOffset(PDEV *ppdev)
|
|
{
|
|
BYTE mem;
|
|
BYTE bytes_pp;
|
|
ULONG vga_mem;
|
|
LONG width;
|
|
LONG height;
|
|
LONG depth;
|
|
|
|
height = ppdev->ppointer->hwCursor.y;
|
|
depth = ppdev->cBitsPerPel;
|
|
width = ppdev->lDelta / depth;
|
|
|
|
mem = (BYTE) I32_IB(ppdev->pjIoBase, MEM_BNDRY);
|
|
|
|
if(mem&0x10)
|
|
{
|
|
vga_mem=(ULONG)(mem&0xf);
|
|
vga_mem=0x40000*vga_mem; /* vga boundary is enabled */
|
|
}
|
|
else
|
|
{
|
|
vga_mem=0;
|
|
}
|
|
|
|
switch(depth)
|
|
{
|
|
case 32:
|
|
bytes_pp=8;
|
|
break;
|
|
|
|
case 24:
|
|
bytes_pp=6;
|
|
break;
|
|
|
|
case 16:
|
|
bytes_pp=4;
|
|
break;
|
|
|
|
case 8:
|
|
bytes_pp=2;
|
|
break;
|
|
|
|
case 4:
|
|
bytes_pp=1;
|
|
break;
|
|
}
|
|
|
|
ppdev->ppointer->mono_offset = (vga_mem +
|
|
((ULONG)height*(ULONG)width*(ULONG)bytes_pp));
|
|
#if 0
|
|
DbgOut("Height %x\n", height);
|
|
DbgOut("Height %x\n", width);
|
|
DbgOut("Height %x\n", bytes_pp);
|
|
DbgOut("Mono Offset %x\n", ppdev->ppointer->mono_offset);
|
|
#endif
|
|
}
|
|
|
|
VOID vI32UpdateCursorOffset(
|
|
PDEV *ppdev,
|
|
LONG lXOffset,
|
|
LONG lYOffset,
|
|
LONG lCurOffset)
|
|
{
|
|
PBYTE pjIoBase = ppdev->pjIoBase;
|
|
|
|
I32_OW_DIRECT(pjIoBase, CURSOR_OFFSET_HI, 0) ;
|
|
I32_OW_DIRECT(pjIoBase, HORZ_CURSOR_OFFSET, (lXOffset & 0xff) | (lYOffset << 8));
|
|
I32_OW_DIRECT(pjIoBase, CURSOR_OFFSET_LO, (WORD)lCurOffset) ;
|
|
I32_OW_DIRECT(pjIoBase, CURSOR_OFFSET_HI, (lCurOffset >> 16) | 0x8000) ;
|
|
}
|
|
|
|
VOID vI32UpdateCursorPosition(
|
|
PDEV *ppdev,
|
|
LONG x,
|
|
LONG y)
|
|
{
|
|
PBYTE pjIoBase = ppdev->pjIoBase;
|
|
|
|
I32_OW_DIRECT(pjIoBase, HORZ_CURSOR_POSN, x); /* set base of cursor to X */
|
|
I32_OW_DIRECT(pjIoBase, VERT_CURSOR_POSN, y); /* set base of cursor to Y */
|
|
}
|
|
|
|
VOID vI32CursorOff(PDEV *ppdev)
|
|
{
|
|
I32_OW_DIRECT(ppdev->pjIoBase, CURSOR_OFFSET_HI, 0);
|
|
}
|
|
|
|
VOID vI32CursorOn(PDEV *ppdev, LONG lCurOffset)
|
|
{
|
|
I32_OW_DIRECT(ppdev->pjIoBase, CURSOR_OFFSET_HI, (lCurOffset >> 16) | 0x8000) ;
|
|
}
|
|
|
|
VOID vI32PointerBlit(
|
|
PDEV* ppdev,
|
|
LONG x,
|
|
LONG y,
|
|
LONG cx,
|
|
LONG cy,
|
|
PBYTE pbsrc,
|
|
LONG lDelta)
|
|
{
|
|
BYTE* pjIoBase = ppdev->pjIoBase;
|
|
WORD wCmd;
|
|
WORD wWords;
|
|
WORD wPixels;
|
|
UINT i;
|
|
|
|
wWords = (WORD)(cx + 15) / 16;
|
|
wPixels = (WORD) (wWords*16L/ppdev->cBitsPerPel);
|
|
|
|
wCmd = FG_COLOR_SRC_HOST | DRAW | WRITE | DATA_WIDTH | LSB_FIRST;
|
|
|
|
I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 7);
|
|
I32_OW(pjIoBase, ALU_FG_FN, OVERPAINT);
|
|
I32_OW(pjIoBase, DP_CONFIG, wCmd);
|
|
|
|
I32_OW(pjIoBase, DEST_X_START, LOWORD(x));
|
|
I32_OW(pjIoBase, CUR_X, LOWORD(x));
|
|
I32_OW(pjIoBase, DEST_X_END, LOWORD(x) + wPixels);
|
|
|
|
I32_OW(pjIoBase, CUR_Y, LOWORD(y));
|
|
I32_OW(pjIoBase, DEST_Y_END, (LOWORD(y) + 1));
|
|
|
|
for (i=0; i < (UINT) wWords; i++)
|
|
{
|
|
if (i % 8 == 0)
|
|
I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 10);
|
|
|
|
I32_OW(pjIoBase, PIX_TRANS, *((USHORT UNALIGNED *)pbsrc)++ );
|
|
}
|
|
}
|
|
|
|
VOID vPointerBlitLFB(
|
|
PDEV* ppdev,
|
|
LONG x,
|
|
LONG y,
|
|
LONG cx,
|
|
LONG cy,
|
|
PBYTE pbsrc,
|
|
LONG lDelta)
|
|
{
|
|
BYTE* pjDst;
|
|
|
|
ASSERTDD(ppdev->iBitmapFormat == BMF_24BPP, "BMF should be 24 here\n");
|
|
|
|
pjDst = ppdev->pjScreen + ppdev->lDelta * y + x * 3;
|
|
|
|
//
|
|
// Set cx equal to number of bytes.
|
|
//
|
|
|
|
cx >>= 3;
|
|
|
|
while (cy-- > 0)
|
|
{
|
|
memcpy( pjDst, pbsrc, cx);
|
|
pjDst += cx;
|
|
pbsrc += lDelta;
|
|
}
|
|
}
|
|
|
|
// END MACH32 ------------------------------------------------------------------
|
|
|
|
// BEGIN MACH64 ----------------------------------------------------------------
|
|
|
|
BOOLEAN flag_enable=FALSE;
|
|
|
|
/*
|
|
----------------------------------------------------------------------
|
|
-- NAME: vDacRegs
|
|
--
|
|
-- DESCRIPTION:
|
|
-- Calculate DAC regsiter I/O locations
|
|
--
|
|
----------------------------------------------------------------------
|
|
*/
|
|
|
|
_inline VOID vDacRegs(PDEV* ppdev, UCHAR** ucReg, UCHAR** ucCntl)
|
|
{
|
|
if (ppdev->FeatureFlags & EVN_PACKED_IO)
|
|
{
|
|
*ucReg = (ppdev->pjIoBase + DAC_REGS*4);
|
|
*ucCntl = (ppdev->pjIoBase + DAC_CNTL*4);
|
|
}
|
|
else
|
|
{
|
|
*ucReg = (ppdev->pjIoBase + ioDAC_REGS - ioBASE);
|
|
*ucCntl = (ppdev->pjIoBase + ioDAC_CNTL - ioBASE);
|
|
}
|
|
}
|
|
|
|
VOID vM64SetCursorOffset(PDEV* ppdev)
|
|
{
|
|
LONG bytes_pp;
|
|
LONG width;
|
|
LONG height;
|
|
LONG depth;
|
|
|
|
height = ppdev->ppointer->hwCursor.y;
|
|
depth = ppdev->cBitsPerPel;
|
|
width = ppdev->lDelta / depth;
|
|
|
|
|
|
switch(depth)
|
|
{
|
|
case 32:
|
|
bytes_pp=8;
|
|
break;
|
|
|
|
case 24:
|
|
bytes_pp=6;
|
|
break;
|
|
|
|
case 16:
|
|
bytes_pp=4;
|
|
break;
|
|
|
|
case 8:
|
|
bytes_pp=2;
|
|
break;
|
|
|
|
case 4:
|
|
bytes_pp=1;
|
|
break;
|
|
}
|
|
|
|
ppdev->ppointer->mono_offset = (ULONG)height*(ULONG)width*(ULONG)bytes_pp;
|
|
ppdev->ppointer->mono_offset += ppdev->ulVramOffset*2;
|
|
}
|
|
|
|
VOID vM64UpdateCursorOffset(
|
|
PDEV* ppdev,
|
|
LONG lXOffset,
|
|
LONG lYOffset,
|
|
LONG lCurOffset)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
|
|
ppdev->pfnCursorOff(ppdev);
|
|
M64_OD_DIRECT(pjMmBase,CUR_OFFSET, lCurOffset >> 1);
|
|
M64_OD_DIRECT(pjMmBase,CUR_HORZ_VERT_OFF, lXOffset | (lYOffset << 16));
|
|
ppdev->pfnCursorOn(ppdev, lCurOffset);
|
|
}
|
|
|
|
VOID vM64UpdateCursorPosition(
|
|
PDEV* ppdev,
|
|
LONG x,
|
|
LONG y)
|
|
{
|
|
M64_OD_DIRECT(ppdev->pjMmBase, CUR_HORZ_VERT_POSN, x | (y << 16));
|
|
}
|
|
|
|
VOID vM64CursorOff(PDEV* ppdev)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
ULONG ldata;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
ULONG ldata1;
|
|
|
|
// Read the no. of total verticales lines (including the overscan)
|
|
ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
|
|
ldata1 = ldata1&0x7ff;
|
|
|
|
again:
|
|
//read the current verticale line
|
|
ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
|
|
ldata = (ldata&0x7ff0000)>>16;
|
|
|
|
//synchronise the drawing with the vertical line
|
|
if (ldata >= (ldata1-3))
|
|
{
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
//Disable the hardware cursor
|
|
ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
|
|
M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata & ~GEN_TEST_CNTL_CursorEna);
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
}
|
|
else
|
|
{
|
|
goto again;
|
|
}
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
}
|
|
|
|
VOID vM64CursorOn(PDEV* ppdev, LONG lCurOffset)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
ULONG ldata;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
ULONG ldata1;
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
if (!flag_enable)
|
|
{
|
|
flag_enable=TRUE;
|
|
ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
|
|
M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata | GEN_TEST_CNTL_CursorEna);
|
|
}
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
/*
|
|
* Read the no. of total vertical lines (including the overscan)
|
|
*/
|
|
ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
|
|
ldata1 = ldata1&0x7ff;
|
|
|
|
again:
|
|
/*
|
|
* read the current vertical line
|
|
*/
|
|
ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
|
|
ldata = (ldata&0x7ff0000)>>16;
|
|
|
|
/*
|
|
* Synchronise the drawing of cursor
|
|
*/
|
|
if (ldata >= (ldata1-3))
|
|
{
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
ppdev->pfnUpdateCursorPosition(ppdev,ppdev->ppointer->ptlLastPosition.x+0,ppdev->ppointer->ptlLastPosition.y+0);
|
|
ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
|
|
M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata | GEN_TEST_CNTL_CursorEna);
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
}
|
|
else
|
|
{
|
|
goto again;
|
|
}
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
}
|
|
|
|
VOID vM64SetCursorOffset_TVP(PDEV* ppdev)
|
|
{
|
|
}
|
|
|
|
VOID vM64UpdateCursorOffset_TVP(
|
|
PDEV* ppdev,
|
|
LONG lXOffset,
|
|
LONG lYOffset,
|
|
LONG lCurOffset)
|
|
{
|
|
ppdev->ppointer->ptlLastOffset.x=lXOffset;
|
|
ppdev->ppointer->ptlLastOffset.y=lYOffset;
|
|
|
|
/* Change the offset... used in UpdateCursorPosition */
|
|
}
|
|
|
|
VOID vM64UpdateCursorPosition_TVP(
|
|
PDEV* ppdev,
|
|
LONG x,
|
|
LONG y)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
ULONG dacRead;
|
|
|
|
//DbgOut("\nvUpdateCursorPosition_TVP_M64 called");
|
|
|
|
ppdev->ppointer->ptlLastPosition.y=y;
|
|
ppdev->ppointer->ptlLastPosition.x=x;
|
|
|
|
// Note: SetCursorOffset, UpdateCursorOffset must set ptlLastOffset
|
|
x+= 64-ppdev->ppointer->ptlLastOffset.x;
|
|
y+= 64-ppdev->ppointer->ptlLastOffset.y;
|
|
|
|
// check for coordinate violations
|
|
if (x < 0) x = 0;
|
|
if (y < 0) y = 0;
|
|
|
|
dacRead = M64_ID(pjMmBase,DAC_CNTL);
|
|
M64_OD_DIRECT(pjMmBase, DAC_CNTL, (dacRead & 0xfffffffc) | 3);
|
|
M64_OD_DIRECT(pjMmBase, DAC_REGS+REG_W, (y<<16) | x);
|
|
dacRead = M64_ID(pjMmBase,DAC_CNTL);
|
|
M64_OD_DIRECT(pjMmBase, DAC_CNTL, dacRead & 0xfffffffc);
|
|
}
|
|
|
|
VOID vM64CursorOff_TVP(PDEV* ppdev)
|
|
{
|
|
UCHAR * ucDacReg;
|
|
UCHAR * ucDacCntl;
|
|
|
|
// Initialize DAC registers
|
|
vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
|
|
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
rioOB(ucDacReg+REG_W, 6); // register 6
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
|
|
rioOB(ucDacReg+REG_M, 0); // (+Mask) disable
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
}
|
|
|
|
VOID vM64CursorOn_TVP(PDEV* ppdev, LONG lCurOffset)
|
|
{
|
|
UCHAR * ucDacReg;
|
|
UCHAR * ucDacCntl;
|
|
|
|
/*
|
|
* Initialize DAC registers
|
|
*/
|
|
vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
|
|
|
|
/*
|
|
* Access cursor control register
|
|
*/
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
rioOB(ucDacReg+REG_W, 6); // register 6
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
|
|
rioOB(ucDacReg+REG_M, 2); // XGA cursor type
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
}
|
|
|
|
VOID vM64SetCursorOffset_IBM514(PDEV* ppdev)
|
|
{
|
|
}
|
|
|
|
VOID vM64UpdateCursorOffset_IBM514(
|
|
PDEV* ppdev,
|
|
LONG lXOffset,
|
|
LONG lYOffset,
|
|
LONG lCurOffset)
|
|
{
|
|
ppdev->ppointer->ptlLastOffset.x=lXOffset ;//-64;
|
|
ppdev->ppointer->ptlLastOffset.y=lYOffset ;//-64;
|
|
/*
|
|
* These two statements have been introduced in order to solve the ghost cursor on IBM Dac cards
|
|
*/
|
|
ppdev->pfnUpdateCursorPosition(ppdev,ppdev->ppointer->ptlLastPosition.x+0,ppdev->ppointer->ptlLastPosition.y+0);
|
|
ppdev->pfnCursorOn(ppdev, lCurOffset);
|
|
|
|
/* Change the offset... used in UpdateCursorPosition */
|
|
}
|
|
|
|
VOID vM64UpdateCursorPosition_IBM514(
|
|
PDEV* ppdev,
|
|
LONG x,
|
|
LONG y)
|
|
{
|
|
UCHAR * ucDacReg;
|
|
UCHAR * ucDacCntl;
|
|
|
|
// Initialize DAC registers
|
|
vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
|
|
|
|
ppdev->ppointer->ptlLastPosition.y=y;
|
|
ppdev->ppointer->ptlLastPosition.x=x;
|
|
|
|
|
|
// Note: SetCursorOffset, UpdateCursorOffset must set ptlLastOffset
|
|
x-= ppdev->ppointer->ptlLastOffset.x;
|
|
y-= ppdev->ppointer->ptlLastOffset.y;
|
|
|
|
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc)| 1);
|
|
rioOB(ucDacReg+REG_R, 1);
|
|
rioOB(ucDacReg+REG_W, 0x31);
|
|
|
|
rioOB(ucDacReg+REG_D, 0);
|
|
rioOB(ucDacReg+REG_M, x&0xFF);
|
|
rioOB(ucDacReg+REG_M, (UCHAR)(x>>8));
|
|
rioOB(ucDacReg+REG_M, y&0xFF);
|
|
rioOB(ucDacReg+REG_M, (UCHAR)(y>>8));
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
}
|
|
|
|
VOID vM64CursorOff_IBM514(PDEV* ppdev) // DONE
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
UCHAR * ucDacReg;
|
|
UCHAR * ucDacCntl;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
ULONG ldata;
|
|
ULONG ldata1;
|
|
|
|
/*
|
|
* Read the no. of total vertical lines (including the overscan)
|
|
*/
|
|
ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
|
|
ldata1 = ldata1&0x7ff;
|
|
|
|
again:
|
|
/*
|
|
* Read the current vertical line
|
|
*/
|
|
ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
|
|
ldata = (ldata&0x7ff0000)>>16;
|
|
|
|
/*
|
|
* Synchronise the drawing with the vertical line
|
|
*/
|
|
if (ldata >= (ldata1-3))
|
|
{
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
/*
|
|
* Initialize DAC registers
|
|
*/
|
|
vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
|
|
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc)|1);
|
|
rioOB(ucDacReg+REG_R, 1);
|
|
rioOB(ucDacReg+REG_W, 0x30);
|
|
rioOB(ucDacReg+REG_D, 0); // (+Data)
|
|
rioOB(ucDacReg+REG_M, 0); // (+Mask)
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
}
|
|
else
|
|
{
|
|
goto again;
|
|
}
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
}
|
|
|
|
VOID vM64CursorOn_IBM514(PDEV* ppdev, LONG lCurOffset) //DONE
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
UCHAR * ucDacReg;
|
|
UCHAR * ucDacCntl;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
ULONG ldata;
|
|
ULONG ldata1;
|
|
|
|
/*
|
|
* Read the no. of total vertical lines (including the overscan)
|
|
*/
|
|
ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
|
|
ldata1 = ldata1&0x7ff;
|
|
|
|
again:
|
|
/*
|
|
* Read the current verticale line
|
|
*/
|
|
ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
|
|
ldata = (ldata&0x7ff0000)>>16;
|
|
|
|
/*
|
|
* Synchronise the drawing of cursor
|
|
*/
|
|
if (ldata >= (ldata1-3))
|
|
{
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
// Initialize DAC registers
|
|
vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
|
|
|
|
// access cursor control register
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 1);
|
|
rioOB(ucDacReg+REG_R, 1);
|
|
rioOB(ucDacReg+REG_W, 0x30);
|
|
rioOB(ucDacReg+REG_D, 0); // register 6
|
|
rioOB(ucDacReg+REG_M, 0xE); // register 6
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
}
|
|
else
|
|
{
|
|
goto again;
|
|
}
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
}
|
|
|
|
VOID vM64UpdateCursorOffset_CT(
|
|
PDEV* ppdev,
|
|
LONG lXOffset,
|
|
LONG lYOffset,
|
|
LONG lCurOffset)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
|
|
ppdev->pfnCursorOff(ppdev);
|
|
M64_OD_DIRECT(pjMmBase, CUR_OFFSET, lCurOffset >> 1);
|
|
M64_OD_DIRECT(pjMmBase, CUR_HORZ_VERT_OFF, lXOffset | (lYOffset << 16));
|
|
|
|
ppdev->pfnCursorOn(ppdev, lCurOffset);
|
|
}
|
|
|
|
VOID vM64CursorOff_CT(PDEV* ppdev)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
ULONG ldata;
|
|
ULONG ldata1;
|
|
|
|
// Read the no. of total verticales lines (including the overscan)
|
|
ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
|
|
ldata1 = ldata1&0x7ff;
|
|
|
|
again:
|
|
//read the current verticale line
|
|
ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
|
|
ldata = (ldata&0x7ff0000)>>16;
|
|
|
|
//synchronise the drawing with the vertical line
|
|
if (ldata >= (ldata1-3))
|
|
{
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
ppdev->pfnUpdateCursorPosition(ppdev, -1, -1);
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
}
|
|
else
|
|
{
|
|
goto again;
|
|
}
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
}
|
|
|
|
VOID vM64CursorOn_CT(PDEV* ppdev, LONG lCurOffset)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
ULONG ldata;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
ULONG ldata1;
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
if (!flag_enable)
|
|
{
|
|
flag_enable=TRUE;
|
|
ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
|
|
M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata | GEN_TEST_CNTL_CursorEna);
|
|
}
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
/*
|
|
* Read the no. of total vertical lines (including the overscan)
|
|
*/
|
|
ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
|
|
ldata1 = ldata1&0x7ff;
|
|
|
|
again:
|
|
/*
|
|
* read the current vertical line
|
|
*/
|
|
ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
|
|
ldata = (ldata&0x7ff0000)>>16;
|
|
|
|
/*
|
|
* Synchronise the drawing of cursor
|
|
*/
|
|
if (ldata >= (ldata1-3))
|
|
{
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
ppdev->pfnUpdateCursorPosition(ppdev,ppdev->ppointer->ptlLastPosition.x+0,ppdev->ppointer->ptlLastPosition.y+0);
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
}
|
|
else
|
|
{
|
|
goto again;
|
|
}
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
}
|
|
|
|
VOID vM64PointerBlit(
|
|
PDEV *ppdev,
|
|
LONG x,
|
|
LONG y,
|
|
LONG cx,
|
|
LONG cy,
|
|
PBYTE pbsrc,
|
|
LONG lDelta)
|
|
{
|
|
BYTE* pjMmBase = ppdev->pjMmBase;
|
|
LONG cxbytes;
|
|
|
|
cxbytes = cx / 8;
|
|
|
|
M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 7);
|
|
//M64_OD(pjMmBase, CONTEXT_LOAD_CNTL, CONTEXT_LOAD_CmdLoad | ppdev->iDefContext );
|
|
|
|
M64_OD(pjMmBase,DP_PIX_WIDTH, 0x020202); // assert 8 bpp
|
|
M64_OD(pjMmBase,DST_OFF_PITCH,(ppdev->ulVramOffset + ((y*ppdev->lDelta) >> 3)) |
|
|
(ROUND8(cxbytes) << 19));
|
|
|
|
if (cxbytes >= (LONG)ppdev->cxScreen)
|
|
{
|
|
M64_OD(pjMmBase,SC_RIGHT, cxbytes);
|
|
}
|
|
|
|
M64_OD(pjMmBase,DP_MIX, (OVERPAINT << 16));
|
|
M64_OD(pjMmBase,DP_SRC, DP_SRC_Host << 8);
|
|
|
|
M64_OD(pjMmBase,DST_Y_X, 0L);
|
|
M64_OD(pjMmBase,DST_HEIGHT_WIDTH, 1 | (cxbytes << 16));
|
|
|
|
vM64DataPortOutB(ppdev, pbsrc, cxbytes);
|
|
|
|
// Fix a timing problem that leaves a remnant line segment in the lower right
|
|
// of the 64x64 cursor.
|
|
vM64QuietDown(ppdev, pjMmBase);
|
|
|
|
M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 3);
|
|
M64_OD(pjMmBase, DP_PIX_WIDTH, ppdev->ulMonoPixelWidth);
|
|
M64_OD(pjMmBase, DST_OFF_PITCH, ppdev->ulScreenOffsetAndPitch);
|
|
M64_OD(pjMmBase, SC_RIGHT, M64_MAX_SCISSOR_R);
|
|
}
|
|
|
|
VOID vM64PointerBlit_TVP(
|
|
PDEV *ppdev,
|
|
LONG x,
|
|
LONG y,
|
|
LONG cx,
|
|
LONG cy,
|
|
PBYTE pbsrc,
|
|
LONG lDelta)
|
|
{
|
|
PBYTE cur_data;
|
|
ULONG i;
|
|
UCHAR * ucDacReg;
|
|
UCHAR * ucDacCntl;
|
|
|
|
// Initialize DAC registers
|
|
vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
|
|
|
|
cur_data=pbsrc;
|
|
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc); // Disable cursor
|
|
rioOB(ucDacReg+REG_W, 6); // register 6
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
|
|
rioOB(ucDacReg+REG_M, 0); // (+Mask) disable
|
|
|
|
|
|
// set cursor RAM write address to 0
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
rioOB(ucDacReg+REG_W, 0);
|
|
|
|
|
|
|
|
// select cursor RAM data register - auto increments with each write
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
|
|
|
|
|
|
for (i = 0; i < 1024; i++)
|
|
{
|
|
rioOB(ucDacReg+REG_R, *cur_data++);
|
|
}
|
|
|
|
// select default palette registers
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
|
|
|
|
rioOB(ucDacReg+REG_W, 6); // register 6
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
|
|
rioOB(ucDacReg+REG_M, 2); // XGA cursor type
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
}
|
|
|
|
VOID vM64PointerBlit_IBM514(
|
|
PDEV *ppdev,
|
|
LONG x,
|
|
LONG y,
|
|
LONG cx,
|
|
LONG cy,
|
|
PBYTE pbsrc,
|
|
LONG lDelta)
|
|
{
|
|
PBYTE cur_data, pjMmBase = ppdev->pjMmBase;
|
|
ULONG i;
|
|
UCHAR * ucDacReg;
|
|
UCHAR * ucDacCntl;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
ULONG ldata;
|
|
ULONG ldata1;
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
// Initialize DAC registers
|
|
vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
|
|
|
|
cur_data=pbsrc;
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
/*
|
|
* Read the no. of total vertical lines (including the overscan)
|
|
*/
|
|
ldata1 = M64_ID(pjMmBase, CRTC_V_TOTAL_DISP);
|
|
ldata1 = ldata1&0x7ff;
|
|
|
|
again:
|
|
/*
|
|
* Read the current vertical line
|
|
*/
|
|
ldata = M64_ID(pjMmBase, CRTC_CRNT_VLINE);
|
|
ldata = (ldata&0x7ff0000)>>16;
|
|
|
|
// synchronise the drawing of cursor
|
|
if (ldata >= (ldata1-3))
|
|
{
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc)|1); // Disable cursor
|
|
rioOB(ucDacReg+REG_R, 1);
|
|
rioOB(ucDacReg+REG_W, 0);
|
|
rioOB(ucDacReg+REG_D, 1);
|
|
|
|
#ifndef NO_VERTICAL_SYNC
|
|
|
|
}
|
|
else
|
|
{
|
|
goto again;
|
|
}
|
|
|
|
#endif // !NO_VERTICAL_SYNC
|
|
|
|
// select cursor RAM data register - auto increments with each write
|
|
|
|
|
|
for (i = 0; i < 1024; i++)
|
|
{
|
|
rioOB(ucDacReg+REG_M, *cur_data++);
|
|
}
|
|
|
|
/* Set HOT SPOT registers.. RSL Important? */
|
|
rioOB(ucDacReg+REG_W, 0x35);
|
|
rioOB(ucDacReg+REG_D, 0);
|
|
rioOB(ucDacReg+REG_M, 0);
|
|
rioOB(ucDacReg+REG_M, 0);
|
|
rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
|
|
}
|
|
|
|
// END MACH64 ------------------------------------------------------------------
|
|
|
|
/******************************Public*Routine******************************\
|
|
* CopyMonoCursor
|
|
*
|
|
* Copies two monochrome masks into a 2bpp bitmap. Returns TRUE if it
|
|
* can make a hardware cursor, FALSE if not.
|
|
*
|
|
* modified by Wendy Yee -1992-10-16- to accomodate 68800
|
|
\**************************************************************************/
|
|
|
|
BOOLEAN CopyMonoCursor(PDEV *ppdev, BYTE *pjSrcAnd, BYTE *pjSrcOr)
|
|
{
|
|
BYTE jSrcAnd;
|
|
BYTE jSrcOr;
|
|
LONG count;
|
|
BYTE *pjDest;
|
|
BYTE jDest = 0;
|
|
LONG nbytes;
|
|
|
|
|
|
pjDest = (PBYTE) HardWareCursorShape;
|
|
|
|
if ( ppdev->FeatureFlags & EVN_TVP_DAC_CUR)
|
|
{
|
|
nbytes=CURSOR_CX*CURSOR_CY/8;
|
|
|
|
for (count = 0; count < nbytes; count++)
|
|
{
|
|
*(pjDest )= *pjSrcOr; // Gives outline!
|
|
*(pjDest+nbytes)= *pjSrcAnd;
|
|
|
|
pjDest++;
|
|
pjSrcOr++;
|
|
pjSrcAnd++;
|
|
|
|
}
|
|
for (;count < 512; count++)
|
|
{
|
|
*pjDest=0;
|
|
*(pjDest+nbytes)=0xFF;
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
for (count = 0; count < (CURSOR_CX * CURSOR_CY);)
|
|
{
|
|
if (!(count & 0x07)) // need new src byte every 8th count;
|
|
{ // each byte = 8 pixels
|
|
jSrcAnd = *(pjSrcAnd++);
|
|
jSrcOr = *(pjSrcOr++);
|
|
}
|
|
|
|
if (jSrcAnd & 0x80) // AND mask's white-1 background
|
|
{
|
|
if (jSrcOr & 0x80) // XOR mask's white-1 outline
|
|
jDest |= 0xC0; // Complement
|
|
else
|
|
jDest |= 0x80; // Set destination to Transparent
|
|
}
|
|
else
|
|
{ // AND mask's cursor silhouette in black-0
|
|
if (jSrcOr & 0x80)
|
|
jDest |= 0x40; // Color 1 - white
|
|
else
|
|
jDest |= 0x00; // Color 0 - black
|
|
}
|
|
count++;
|
|
|
|
if (!(count & 0x3)) // New DestByte every 4 times for 4 pixels per byte
|
|
{
|
|
*pjDest = jDest; // save pixel after rotating to right 3x
|
|
pjDest++;
|
|
jDest = 0;
|
|
}
|
|
else
|
|
{
|
|
jDest >>= 2; // Next Pixel
|
|
}
|
|
|
|
jSrcOr <<= 1;
|
|
jSrcAnd <<= 1;
|
|
}
|
|
|
|
while (count++ < 64*64)
|
|
if (!(count & 0x3)) // need new src byte every 8th count;
|
|
{ // each byte = 8 pixels
|
|
*pjDest =0xaa;
|
|
pjDest++;
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
ULONG lSetMonoHwPointerShape(
|
|
SURFOBJ *pso,
|
|
SURFOBJ *psoMask,
|
|
SURFOBJ *psoColor,
|
|
XLATEOBJ *pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl,
|
|
FLONG fl)
|
|
{
|
|
LONG count;
|
|
ULONG cy;
|
|
PBYTE pjSrcAnd, pjSrcXor;
|
|
LONG lDeltaSrc, lDeltaDst;
|
|
LONG lSrcWidthInBytes;
|
|
ULONG cxSrc = pso->sizlBitmap.cx;
|
|
ULONG cySrc = pso->sizlBitmap.cy;
|
|
ULONG cxSrcBytes;
|
|
BYTE AndMask[CURSOR_CX][CURSOR_CX/8];
|
|
BYTE XorMask[CURSOR_CY][CURSOR_CY/8];
|
|
PBYTE pjDstAnd = (PBYTE)AndMask;
|
|
PBYTE pjDstXor = (PBYTE)XorMask;
|
|
PDEV* ppdev;
|
|
PCUROBJ ppointer;
|
|
|
|
ppdev=(PDEV*)pso->dhpdev;
|
|
ppointer = ppdev->ppointer;
|
|
|
|
// If the mask is NULL this implies the pointer is not
|
|
// visible.
|
|
|
|
if (psoMask == NULL)
|
|
{
|
|
if (ppointer->flPointer & MONO_POINTER_UP)
|
|
{
|
|
//DbgOut("\nThe cursor was disabled because of psoMask");
|
|
ppdev->pfnCursorOff(ppdev);
|
|
ppointer->flPointer &= ~MONO_POINTER_UP;
|
|
}
|
|
return (SPS_ACCEPT_NOEXCLUDE) ;
|
|
}
|
|
|
|
// Get the bitmap dimensions.
|
|
|
|
cxSrc = psoMask->sizlBitmap.cx ;
|
|
cySrc = psoMask->sizlBitmap.cy ;
|
|
|
|
// set the dest and mask to 0xff
|
|
|
|
memset(pjDstAnd, 0xFFFFFFFF, CURSOR_CX/8 * CURSOR_CY);
|
|
|
|
// Zero the dest XOR mask
|
|
|
|
memset(pjDstXor, 0, CURSOR_CX/8 * CURSOR_CY);
|
|
|
|
cxSrcBytes = (cxSrc + 7) / 8;
|
|
|
|
if ((lDeltaSrc = psoMask->lDelta) < 0)
|
|
lSrcWidthInBytes = -lDeltaSrc;
|
|
else
|
|
lSrcWidthInBytes = lDeltaSrc;
|
|
|
|
pjSrcAnd = (PBYTE) psoMask->pvScan0;
|
|
|
|
// Height of just AND mask
|
|
|
|
cySrc = cySrc / 2;
|
|
|
|
// Point to XOR mask
|
|
|
|
pjSrcXor = pjSrcAnd + (cySrc * lDeltaSrc);
|
|
|
|
// Offset from end of one dest scan to start of next
|
|
|
|
lDeltaDst = CURSOR_CX/8;
|
|
|
|
for (cy = 0; cy < cySrc; ++cy)
|
|
{
|
|
memcpy(pjDstAnd, pjSrcAnd, cxSrcBytes);
|
|
memcpy(pjDstXor, pjSrcXor, cxSrcBytes);
|
|
|
|
// Point to next source and dest scans
|
|
|
|
pjSrcAnd += lDeltaSrc;
|
|
pjSrcXor += lDeltaSrc;
|
|
pjDstAnd += lDeltaDst;
|
|
pjDstXor += lDeltaDst;
|
|
}
|
|
|
|
|
|
if (CopyMonoCursor(ppdev, (PBYTE)AndMask, (PBYTE)XorMask))
|
|
{
|
|
// Down load the pointer shape to the engine.
|
|
|
|
count = CURSOR_CX * CURSOR_CY * 2;
|
|
if (ppdev->iAsic == ASIC_88800GX)
|
|
{
|
|
// double buffering used for Ghost EPR
|
|
if (!ppdev->bAltPtrActive)
|
|
{
|
|
ppointer = ppdev->ppointer = &ppdev->pointer1;
|
|
ppdev->pointer1.ptlHotSpot = ppdev->pointer2.ptlHotSpot;
|
|
ppdev->pointer1.ptlLastPosition= ppdev->pointer2.ptlLastPosition;
|
|
ppdev->pointer1.ptlLastOffset = ppdev->pointer2.ptlLastOffset;
|
|
ppdev->pointer1.flPointer = ppdev->pointer2.flPointer;
|
|
ppdev->pointer1.szlPointer = ppdev->pointer2.szlPointer;
|
|
}
|
|
else
|
|
{
|
|
ppointer = ppdev->ppointer = &ppdev->pointer2;
|
|
ppdev->pointer2.ptlHotSpot = ppdev->pointer1.ptlHotSpot;
|
|
ppdev->pointer2.ptlLastPosition= ppdev->pointer1.ptlLastPosition;
|
|
ppdev->pointer2.ptlLastOffset = ppdev->pointer1.ptlLastOffset;
|
|
ppdev->pointer2.flPointer = ppdev->pointer1.flPointer;
|
|
ppdev->pointer2.szlPointer = ppdev->pointer1.szlPointer;
|
|
}
|
|
ppdev->bAltPtrActive = !ppdev->bAltPtrActive;
|
|
}
|
|
ppdev->pfnSetCursorOffset(ppdev);
|
|
ppdev->pfnPointerBlit(ppdev,
|
|
ppointer->hwCursor.x,
|
|
ppointer->hwCursor.y,
|
|
count,
|
|
1L,
|
|
(PBYTE) &HardWareCursorShape,
|
|
0L);
|
|
}
|
|
else
|
|
return(SPS_ERROR);
|
|
|
|
|
|
// Set the position of the cursor.
|
|
if (fl & SPS_ANIMATEUPDATE)
|
|
{
|
|
//DbgOut("animate cursor\n");
|
|
if ( (ppointer->ptlLastPosition.x < 0) ||
|
|
(ppointer->ptlLastPosition.y < 0) )
|
|
{
|
|
ppointer->ptlLastPosition.x = x - CURSOR_CX;
|
|
ppointer->ptlLastPosition.y = y - CURSOR_CY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ppointer->ptlLastPosition.x = -x - 2;
|
|
ppointer->ptlLastPosition.y = -y - 2;
|
|
// DbgOut("See what last position we set in DrvSetPointerShape: x=%d y=%d\n",ppointer->ptlLastPosition.x,ppointer->ptlLastPosition.y);
|
|
}
|
|
|
|
if (x == -1)
|
|
{
|
|
ppointer->ptlLastPosition.x = x;
|
|
ppointer->ptlLastPosition.y = y;
|
|
return (SPS_ACCEPT_NOEXCLUDE) ;
|
|
}
|
|
|
|
//flag for enforcing a special approach from DrvMovePointer
|
|
flag_shape=TRUE;
|
|
DrvMovePointer(pso, x, y, NULL) ;
|
|
|
|
if (!(ppointer->flPointer & MONO_POINTER_UP))
|
|
{
|
|
ppointer->ptlLastPosition.x = x;
|
|
ppointer->ptlLastPosition.y = y;
|
|
ppdev->pfnCursorOn(ppdev, ppointer->mono_offset);
|
|
ppointer->flPointer |= MONO_POINTER_UP;
|
|
}
|
|
|
|
return (SPS_ACCEPT_NOEXCLUDE) ;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID DrvSetPointerShape
|
|
*
|
|
* Sets the new pointer shape.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
ULONG DrvSetPointerShape(
|
|
SURFOBJ* pso,
|
|
SURFOBJ* psoMask,
|
|
SURFOBJ* psoColor,
|
|
XLATEOBJ* pxlo,
|
|
LONG xHot,
|
|
LONG yHot,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL* prcl,
|
|
FLONG fl)
|
|
{
|
|
ULONG ulRet ;
|
|
PDEV* ppdev ;
|
|
LONG lX ;
|
|
PCUROBJ ppointer;
|
|
|
|
ppdev=(PDEV*)pso->dhpdev;
|
|
ppointer = ppdev->ppointer;
|
|
|
|
// Save the position and hot spot in pdev
|
|
|
|
ppointer->ptlHotSpot.x = xHot ;
|
|
ppointer->ptlHotSpot.y = yHot ;
|
|
|
|
ppointer->szlPointer.cx = psoMask->sizlBitmap.cx ;
|
|
ppointer->szlPointer.cy = psoMask->sizlBitmap.cy / 2;
|
|
|
|
// The pointer may be larger than we can handle.
|
|
// We don't want to draw colour cursors either - let GDI do it
|
|
// If it is we must cleanup the screen and let the engine
|
|
// take care of it.
|
|
|
|
if (psoMask->sizlBitmap.cx > CURSOR_CX ||
|
|
psoMask->sizlBitmap.cy > CURSOR_CY ||
|
|
psoColor != NULL ||
|
|
ppointer->flPointer & NO_HARDWARE_CURSOR)
|
|
{
|
|
// Disable the mono hardware pointer.
|
|
if (ppointer->flPointer & MONO_POINTER_UP)
|
|
{
|
|
ppdev->pfnCursorOff(ppdev);
|
|
ppointer->flPointer &= ~MONO_POINTER_UP;
|
|
}
|
|
|
|
return (SPS_DECLINE);
|
|
}
|
|
|
|
// odd cursor positions not displayed in 1280 mode
|
|
|
|
lX = x-xHot;
|
|
if (ppdev->cxScreen == 0x500)
|
|
lX &= 0xfffffffe;
|
|
|
|
if(ppdev->iAsic == ASIC_88800GX)
|
|
{
|
|
//disable the hardware cursor
|
|
ppdev->pfnCursorOff(ppdev);
|
|
|
|
#if MULTI_BOARDS
|
|
{
|
|
OH* poh;
|
|
|
|
if (x != -1)
|
|
{
|
|
poh = ((DSURF*) pso->dhsurf)->poh;
|
|
x += poh->x;
|
|
y += poh->y;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// Take care of the monochrome pointer.
|
|
ulRet = lSetMonoHwPointerShape(pso, psoMask, psoColor, pxlo,
|
|
xHot, yHot, x, y, prcl, fl) ;
|
|
|
|
return (ulRet) ;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID DrvMovePointer
|
|
*
|
|
* NOTE: Because we have set GCAPS_ASYNCMOVE, this call may occur at any
|
|
* time, even while we're executing another drawing call!
|
|
*
|
|
* Consequently, we have to explicitly synchronize any shared
|
|
* resources. In our case, since we touch the CRTC register here
|
|
* and in the banking code, we synchronize access using a critical
|
|
* section.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID DrvMovePointer(
|
|
SURFOBJ* pso,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL* prcl)
|
|
{
|
|
PDEV* ppdev ;
|
|
PCUROBJ ppointer;
|
|
|
|
LONG lXOffset, lYOffset;
|
|
LONG lCurOffset;
|
|
BOOL bUpdatePtr = FALSE;
|
|
BOOL bUpdateOffset = FALSE;
|
|
|
|
ppdev=(PDEV*)pso->dhpdev;
|
|
ppointer = ppdev->ppointer;
|
|
|
|
// If x is -1 then take down the cursor.
|
|
|
|
if (x == -1)
|
|
{
|
|
ppointer->ptlLastPosition.x=-1;
|
|
ppointer->ptlLastPosition.y=y;
|
|
ppdev->pfnCursorOff(ppdev);
|
|
ppointer->flPointer &= ~MONO_POINTER_UP;
|
|
return;
|
|
}
|
|
|
|
#if MULTI_BOARDS
|
|
if (flag_shape!=TRUE)
|
|
{
|
|
OH* poh;
|
|
|
|
poh = ((DSURF*) pso->dhsurf)->poh;
|
|
x += poh->x;
|
|
y += poh->y;
|
|
}
|
|
#endif
|
|
|
|
// Adjust the actual pointer position depending upon
|
|
// the hot spot.
|
|
|
|
x -= ppointer->ptlHotSpot.x ;
|
|
y -= ppointer->ptlHotSpot.y ;
|
|
|
|
// odd cursor positions not displayed in 1280 mode
|
|
|
|
if (ppdev->cxScreen == 0x500)
|
|
x &= 0xfffffffe;
|
|
|
|
// get current offsets
|
|
lXOffset = ppointer->ptlLastOffset.x;
|
|
lYOffset = ppointer->ptlLastOffset.y;
|
|
lCurOffset = ppointer->mono_offset;
|
|
|
|
/*
|
|
;
|
|
;Deal with changes in X:
|
|
;
|
|
*/
|
|
if (x!=ppointer->ptlLastPosition.x) /* did our X coordinate change? */
|
|
{
|
|
bUpdatePtr = TRUE;
|
|
if (x<0) /* is cursor negative? */
|
|
{
|
|
bUpdateOffset = TRUE;
|
|
lXOffset = -x; /* reset size of cursor to < original */
|
|
x = 0; /* set cursor to origin */
|
|
}
|
|
else if (ppointer->ptlLastPosition.x<=0)
|
|
{
|
|
bUpdateOffset = TRUE; /* reset size of cursor to original */
|
|
lXOffset = 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
;
|
|
;Deal with changes in Y
|
|
;
|
|
*/
|
|
if (y!=ppointer->ptlLastPosition.y)
|
|
{
|
|
bUpdatePtr = TRUE;
|
|
if (y<0)
|
|
{
|
|
// Move start pointer of cursor down and cursor base up to
|
|
// compensate. The (-4) is the pitch if the cursor in dwords
|
|
bUpdateOffset = TRUE;
|
|
lYOffset = -y; /* reset size of cursor to < original */
|
|
lCurOffset -= 4*y;
|
|
|
|
y = 0; /* set base of cursor to Y */
|
|
}
|
|
else if (ppointer->ptlLastPosition.y<=0)
|
|
{
|
|
bUpdateOffset = TRUE; /* reset size of cursor to original */
|
|
lYOffset = 0;
|
|
}
|
|
}
|
|
|
|
if(ppdev->iAsic != ASIC_88800GX)
|
|
{
|
|
flag_shape=FALSE;
|
|
}
|
|
|
|
if (flag_shape)
|
|
{
|
|
flag_shape=FALSE;
|
|
ppointer->ptlLastPosition.x=x;
|
|
ppointer->ptlLastPosition.y=y;
|
|
|
|
if (bUpdateOffset)
|
|
{
|
|
ppdev->pfnUpdateCursorOffset(ppdev, lXOffset, lYOffset, lCurOffset);
|
|
ppointer->ptlLastOffset.x=lXOffset;
|
|
ppointer->ptlLastOffset.y=lYOffset;
|
|
ppointer->flPointer |= MONO_POINTER_UP;
|
|
}
|
|
else
|
|
{
|
|
if (ppdev->iAsic == ASIC_88800GX)
|
|
{
|
|
//this is a new statement imposed by double buffering
|
|
ppdev->pfnUpdateCursorOffset(ppdev, lXOffset, lYOffset, lCurOffset);
|
|
ppointer->flPointer |= MONO_POINTER_UP;
|
|
//only for no double buffering
|
|
//ppdev->_vCursorOn(ppdev, lCurOffset);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ppointer->ptlLastPosition.x=x;
|
|
ppointer->ptlLastPosition.y=y;
|
|
|
|
if (bUpdateOffset)
|
|
{
|
|
ppdev->pfnUpdateCursorOffset(ppdev, lXOffset, lYOffset, lCurOffset);
|
|
ppointer->ptlLastOffset.x=lXOffset;
|
|
ppointer->ptlLastOffset.y=lYOffset;
|
|
ppointer->flPointer |= MONO_POINTER_UP;
|
|
}
|
|
|
|
if (bUpdatePtr)
|
|
{
|
|
ppdev->pfnUpdateCursorPosition(ppdev, x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vDisablePointer
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vDisablePointer(
|
|
PDEV* ppdev)
|
|
{
|
|
// Nothing to do, really
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vAssertModePointer
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vAssertModePointer(
|
|
PDEV* ppdev,
|
|
BOOL bEnable)
|
|
{
|
|
if (!bEnable)
|
|
{
|
|
ppdev->pfnCursorOff(ppdev);
|
|
ppdev->ppointer->flPointer &= ~MONO_POINTER_UP;
|
|
}
|
|
else
|
|
{
|
|
flag_enable = FALSE; // force initial cursor enable
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL bEnablePointer
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL bEnablePointer(
|
|
PDEV* ppdev)
|
|
{
|
|
OH* poh;
|
|
|
|
ppdev->ppointer = &ppdev->pointer1;
|
|
ppdev->bAltPtrActive = FALSE;
|
|
|
|
// Allocate first buffer
|
|
poh = pohAllocate(ppdev, NULL,
|
|
ppdev->cxMemory,
|
|
(1024+(ppdev->lDelta-1))/ppdev->lDelta,
|
|
FLOH_MAKE_PERMANENT);
|
|
if (poh != NULL)
|
|
{
|
|
ppdev->ppointer->hwCursor.x = poh->x;
|
|
ppdev->ppointer->hwCursor.y = poh->y;
|
|
|
|
// Allocate second buffer
|
|
poh = pohAllocate(ppdev, NULL,
|
|
ppdev->cxMemory,
|
|
(1024+(ppdev->lDelta-1))/ppdev->lDelta,
|
|
FLOH_MAKE_PERMANENT);
|
|
if (poh != NULL)
|
|
{
|
|
ppdev->pointer2.hwCursor.x = poh->x;
|
|
ppdev->pointer2.hwCursor.y = poh->y;
|
|
|
|
if (ppdev->iMachType == MACH_MM_32 || ppdev->iMachType == MACH_IO_32)
|
|
{
|
|
ppdev->pfnSetCursorOffset = vI32SetCursorOffset;
|
|
ppdev->pfnUpdateCursorOffset = vI32UpdateCursorOffset;
|
|
ppdev->pfnUpdateCursorPosition = vI32UpdateCursorPosition;
|
|
ppdev->pfnCursorOff = vI32CursorOff;
|
|
ppdev->pfnCursorOn = vI32CursorOn;
|
|
// 24bpp on mach32 is only available with linear frame buffer.
|
|
// vI32PointerBlit can't handle 24bpp.
|
|
if (ppdev->iBitmapFormat == BMF_24BPP)
|
|
ppdev->pfnPointerBlit = vPointerBlitLFB;
|
|
else
|
|
ppdev->pfnPointerBlit = vI32PointerBlit;
|
|
}
|
|
else
|
|
{
|
|
if (ppdev->FeatureFlags & EVN_TVP_DAC_CUR)
|
|
{
|
|
/* TVP DAC Hardware Cursor is Buggy in Hardware */
|
|
ppdev->pfnSetCursorOffset = vM64SetCursorOffset_TVP;
|
|
ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset_TVP;
|
|
ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition_TVP;
|
|
ppdev->pfnCursorOff = vM64CursorOff_TVP;
|
|
ppdev->pfnCursorOn = vM64CursorOn_TVP;
|
|
|
|
ppdev->pfnPointerBlit = vM64PointerBlit_TVP;
|
|
}
|
|
else if (ppdev->FeatureFlags & EVN_IBM514_DAC_CUR)
|
|
{
|
|
/*
|
|
* On the DEC Alpha, the hardware cursor on the IBM 514
|
|
* DAC does not work properly.
|
|
*/
|
|
#if defined(ALPHA)
|
|
ppdev->ppointer->flPointer |= NO_HARDWARE_CURSOR;
|
|
#endif
|
|
ppdev->pfnSetCursorOffset = vM64SetCursorOffset_IBM514;
|
|
ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset_IBM514;
|
|
ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition_IBM514;
|
|
ppdev->pfnCursorOff = vM64CursorOff_IBM514;
|
|
ppdev->pfnCursorOn = vM64CursorOn_IBM514;
|
|
ppdev->pfnPointerBlit = vM64PointerBlit_IBM514;
|
|
}
|
|
else if (ppdev->FeatureFlags & EVN_INT_DAC_CUR)
|
|
{
|
|
ppdev->pfnSetCursorOffset = vM64SetCursorOffset;
|
|
ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset_CT;
|
|
ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition;
|
|
ppdev->pfnCursorOff = vM64CursorOff_CT;
|
|
ppdev->pfnCursorOn = vM64CursorOn_CT;
|
|
ppdev->pfnPointerBlit = vM64PointerBlit;
|
|
}
|
|
else
|
|
{
|
|
ppdev->pfnSetCursorOffset = vM64SetCursorOffset;
|
|
ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset;
|
|
ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition;
|
|
ppdev->pfnCursorOff = vM64CursorOff;
|
|
ppdev->pfnCursorOn = vM64CursorOn;
|
|
ppdev->pfnPointerBlit = vM64PointerBlit;
|
|
}
|
|
}
|
|
|
|
if (ppdev->pModeInfo->ModeFlags & AMI_ODD_EVEN ||
|
|
ppdev->iAsic == ASIC_38800_1)
|
|
{
|
|
ppdev->ppointer->flPointer |= NO_HARDWARE_CURSOR;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
ppdev->ppointer->flPointer |= NO_HARDWARE_CURSOR;
|
|
return TRUE;
|
|
}
|