|
|
/*++
Copyright (c) 1993, 1994 Weitek Corporation
Module Name:
bt485.c
Abstract:
This module contains code specific to the Bt485 DAC on P9x0x adapters.
Environment:
Kernel mode
Revision History may be found at the end of this file.
--*/
#include "p9.h"
#include "p9gbl.h"
#include "p9000.h"
#include "bt485.h"
#include "p91regs.h"
#include "p91dac.h"
#define PIX_PORT_15 0x30
//
// DAC specific static data.
//
UCHAR ReadDAC( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ulIndex );
VOID WriteDAC( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ulIndex, UCHAR ucValue );
VOID P91Bt485SetPalette( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG *pPal, ULONG StartIndex, ULONG Count );
VOID P91Bt485SetPointerPos( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ptlX, ULONG ptlY );
VOID P91Bt485SetPointerShape( PHW_DEVICE_EXTENSION HwDeviceExtension, PUCHAR pHWCursorShape );
VOID P91Bt485PointerOn( PHW_DEVICE_EXTENSION HwDeviceExtension );
VOID P91Bt485PointerOff( PHW_DEVICE_EXTENSION HwDeviceExtension );
VOID P91Bt485ClearPalette( PHW_DEVICE_EXTENSION HwDeviceExtension );
BOOLEAN P91Bt485SetMode( PHW_DEVICE_EXTENSION HwDeviceExtension );
VOID P91Bt485RestoreMode( PHW_DEVICE_EXTENSION HwDeviceExtension );
VOID P91Bt485SetClkDoubler( PHW_DEVICE_EXTENSION HwDeviceExtension );
VOID P91Bt485ClrClkDoubler( PHW_DEVICE_EXTENSION HwDeviceExtension );
//
// Define the DAC support routines structure for the Bt485 DAC.
//
DAC P91Bt485 = { DAC_ID_BT485, NUM_DAC_REGS, P91Bt485SetMode, P91Bt485RestoreMode, P91Bt485SetPalette, P91Bt485ClearPalette, P91Bt485PointerOn, P91Bt485PointerOff, P91Bt485SetPointerPos, P91Bt485SetPointerShape, CLK_MAX_FREQ, P91Bt485SetClkDoubler, P91Bt485ClrClkDoubler, DAC_ID_BT485, 32, FALSE, FALSE, FALSE };
//
// Power 9100 Bt485 DAC register definitions. See comments in
// VLGetBaseAddrP91().
//
ULONG P91_Bt485_DAC_Regs[] = { P9100_RAMWRITE, P9100_PALETDATA, P9100_PIXELMASK, P9100_RAMREAD, P9100_COLORWRITE, P9100_COLORDATA, P9100_COMREG0, P9100_COLORREAD, P9100_COMREG1, P9100_COMREG2, P9100_COMREG3, P9100_CURSORDATA, P9100_CURSORX0, P9100_CURSORX1, P9100_CURSORY0, P9100_CURSORY1 };
VOID P91Bt485SetPalette( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG *pPal, ULONG StartIndex, ULONG Count )
/*++
Routine Description:
Sets the Device palette
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
pPal - Pointer to the array of pallete entries.
StartIndex - Specifies the first pallete entry provided in pPal.
Count - Number of palette entries in pPal
Return Value:
None.
--*/
{ UCHAR *pBytePal;
PAL_WR_ADDR((UCHAR) StartIndex);
pBytePal = (PUCHAR) pPal;
//
// Load the palette with RGB values. The input palette has 4 bytes
// per entry, the last of which is ignored.
//
while (Count--) { PAL_WR_DATA(*pBytePal++); PAL_WR_DATA(*pBytePal++); PAL_WR_DATA(*pBytePal++); pBytePal++; } }
VOID P91Bt485SetPointerPos( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ptlX, ULONG ptlY )
/*++
Routine Description:
Move Hardware Pointer.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
ptlX, ptlY - Requested X,Y position for the pointer.
Return Value:
TRUE
--*/
{
//
// Strip off the invalid bits and update the cursor position regs.
//
WR_CURS_POS_X(((ptlX + CURSOR_WIDTH) & 0xFFF)); WR_CURS_POS_Y(((ptlY + CURSOR_HEIGHT) & 0xFFF));
return; }
VOID P91Bt485SetPointerShape( PHW_DEVICE_EXTENSION HwDeviceExtension, PUCHAR pHWCursorShape )
/*++
Routine Description:
Sets the hardware cursor shape.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
pHWCursorShape - Pointer to the cursor bitmap.
Return Value:
None.
--*/
{ ULONG iCount;
//
// The # of bytes of cursor bitmap data to send *= 2 for and/xor mask
// *= 8 for 8bit/byte
// *= 2 for 2 loops
//
ULONG iLoop = (CURSOR_WIDTH * CURSOR_HEIGHT * 2) / (8 * 2);
//
// AND mask will be loaded to plane 1.
//
PAL_WR_ADDR(0x80);
iCount = iLoop;
WAIT_FOR_RETRACE();
while (iCount--) { WR_CURS_DATA(*pHWCursorShape++); }
//
// XOR mask will be loaded to plane 0.
//
PAL_WR_ADDR(0x00);
iCount = iLoop;
WAIT_FOR_RETRACE();
while (iCount--) { WR_CURS_DATA(*pHWCursorShape++); }
return; }
VOID P91Bt485PointerOn( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
Routine Description:
Turn on the hardware cursor.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
None.
--*/
{
//
// Turn the cursor on only if it was disabled.
//
if (!CURS_IS_ON()) { WAIT_FOR_RETRACE(); CURS_ON(); }
return; }
VOID P91Bt485PointerOff( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
Routine Description:
Turn off the hardware cursor.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
None.
--*/
{
//
// Turn the cursor off only if it was enabled.
//
if (CURS_IS_ON()) { WAIT_FOR_RETRACE(); CURS_OFF(); }
return; }
VOID P91Bt485ClearPalette( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
Routine Description:
Clears the palette to all 0's
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
None.
--*/
{ int Count;
//
// Calculate the number of palette entries. It is assumed that the
// caller has already determined that the current mode makes use
// of the palette,
//
Count = 1 << HwDeviceExtension->usBitsPixel;
//
// Fill the palette with RGB values of 0.
//
while (Count--) { PAL_WR_DATA(0); PAL_WR_DATA(0); PAL_WR_DATA(0); }
return; }
BOOLEAN P91Bt485SetMode( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
Routine Description:
Initializes the DAC for the current mode.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
None.
--*/ { UCHAR ucCurState;
//
// Enable 8bit dacs, allow access to Command Register 3.
//
//
// Enable accesses to CMD_REG_3. For the Power 9100, to access command
// register 3, you must have CR07 TRUE and you must load a one into
// the address register.
//
if (IS_DEV_P9100) P9_WR_REG(P9100_RAMWRITE, 0x01);
WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3 | MODE_8_BIT);
//
// Set the DAC Pixel port value for the current bit depth.
// Note: The BT485 does not support 24bpp mode.
//
switch (HwDeviceExtension->usBitsPixel) { case 8: WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_8); break;
case 16: // This is really 555, not 565...
WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_15); break;
case 32: WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_32); break;
default:
//
// Oops..invalid BPP value. Use 8BPP value for now.
//
WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_8); break; };
//
// Select P9x00 video clock, disable cursor
//
WriteDAC(HwDeviceExtension, CMD_REG_2, (PORTSEL_MSKD | PCLK1_SEL) & DIS_CURS);
//
// Select 32x32x2 cursor mode, and clock doubler mode if neccessary.
//
RD_CMD_REG_3(ucCurState);
if (HwDeviceExtension->VideoData.dotfreq1 > HwDeviceExtension->Dac.ulMaxClkFreq) { //
// Enable the DAC clock doubler mode.
//
HwDeviceExtension->Dac.DACSetClkDblMode(HwDeviceExtension); } else { //
// Disable the DAC clock doubler mode.
//
HwDeviceExtension->Dac.DACClrClkDblMode(HwDeviceExtension); }
//
// Set the pixel read mask.
//
WriteDAC(HwDeviceExtension, PIXEL_MSK_REG, 0xff);
//
// Set cursor colors 1 and 2.
//
WriteDAC(HwDeviceExtension, CURS_CLR_ADDR, 1); WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0x00); WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0x00); WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0x00); WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0xFF); WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0xFF); WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0xFF);
return(TRUE); }
VOID P91Bt485RestoreMode( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
routine description:
Restore the DAC to its pristine state.
arguments:
hwdeviceextension - pointer to the miniport driver's device extension.
return value:
--*/
{ UCHAR ucCurState;
VideoDebugPrint((1, "P91Bt485RestoreMode----------\n"));
//
// Enable accesses to CMD_REG_3. For the Power 9100, to access command
// register 3, you must have CR07 TRUE and you must load a one into
// the address register.
//
if (IS_DEV_P9100) { P9_WR_REG(P9100_RAMWRITE, 0x01); WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3); WR_CMD_REG_3(0x00); WriteDAC(HwDeviceExtension, CMD_REG_0, 0x00); WriteDAC(HwDeviceExtension, CMD_REG_1, 0x00); WriteDAC(HwDeviceExtension, CMD_REG_2, 0x00); return; }
WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3);
//
// Set pixel port for 8bit pixels.
//
WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_8);
//
// Select VGA video clock, disable cursor.
//
WriteDAC(HwDeviceExtension, (ULONG) CMD_REG_2, (UCHAR)(ReadDAC(HwDeviceExtension, (ULONG) CMD_REG_2) & DIS_CURS));
//
// Select 32x32 cursor, clear clock doubler bit.
//
RD_CMD_REG_3(ucCurState); WR_CMD_REG_3(ucCurState & (~DAC_CLK_2X & CUR_MODE_32));
//
// Set pixel read mask.
//
WriteDAC(HwDeviceExtension, PIXEL_MSK_REG, 0xff); return; }
VOID P91Bt485SetClkDoubler( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
routine description:
Enable the DAC's internal clock doubler.
arguments:
hwdeviceextension - pointer to the miniport driver's device extension.
return value:
--*/
{ UCHAR ucCurState;
VideoDebugPrint((1, "P91Bt485SetClkDoubler----------\n")); RD_CMD_REG_3(ucCurState); WR_CMD_REG_3(ucCurState | DAC_CLK_2X); return; }
VOID P91Bt485ClrClkDoubler( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
routine description:
Disable the DAC's internal clock doubler.
arguments:
hwdeviceextension - pointer to the miniport driver's device extension.
return value:
--*/ { UCHAR ucCurState;
VideoDebugPrint((1, "P91Bt485ClrClkDoubler----------\n")); RD_CMD_REG_3(ucCurState); WR_CMD_REG_3(ucCurState & ~DAC_CLK_2X); return; }
UCHAR ReadDAC( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ulIndex )
/*++
routine description:
Read a value from the specified index from the DAC.
arguments:
hwdeviceextension - pointer to the miniport driver's device extension, ulIndex - index register.
return value: Value.
--*/ { if (IS_DEV_P9100) { #if 0
return((UCHAR) P9_RD_REG(ulIndex)); #else
return( (UCHAR) (VideoPortReadRegisterUlong( (PULONG)((PUCHAR) HwDeviceExtension->Coproc + (ulIndex - 2)) ) >> 16) ); #endif
} else { return(VideoPortReadPortUchar((PUCHAR)(ULONG_PTR)ulIndex)); }
} // End of ReadDAC()
VOID WriteDAC( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ulIndex, UCHAR ucValue )
/*++
routine description:
Write the specified value to the specified index to the DAC.
arguments:
hwdeviceextension - pointer to the miniport driver's device extension, ulIndex - index register, ucValue - value to write. return value: None.
--*/ { if (IS_DEV_P9100) { #if 0
P9_WR_REG(ulIndex, ucValue); #endif
VideoPortWriteRegisterUlong( (PULONG)((PUCHAR)HwDeviceExtension->Coproc + (ulIndex - 2)), (((ULONG) ucValue) << 16) ); } else { VideoPortWritePortUchar((PUCHAR)(ULONG_PTR)ulIndex, ucValue); }
return;
} // End of WriteDAC()
|