719 lines
13 KiB
C
719 lines
13 KiB
C
/*++
|
||
|
||
Copyright (c) 1993, 1994 Weitek Corporation
|
||
|
||
Module Name:
|
||
|
||
p91bt489.c
|
||
|
||
Abstract:
|
||
|
||
This module contains code specific to the Bt489 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
|
||
|
||
//
|
||
// external functions in p91bt485.c
|
||
//
|
||
|
||
extern UCHAR
|
||
ReadDAC(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
ULONG ulIndex
|
||
);
|
||
|
||
extern VOID
|
||
WriteDAC(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
ULONG ulIndex,
|
||
UCHAR ucValue
|
||
);
|
||
|
||
//
|
||
// Bt489 DAC specific functions.
|
||
//
|
||
|
||
VOID
|
||
P91Bt489SetPalette(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
ULONG *pPal,
|
||
ULONG StartIndex,
|
||
ULONG Count
|
||
);
|
||
|
||
VOID
|
||
P91Bt489SetPointerPos(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
ULONG ptlX,
|
||
ULONG ptlY
|
||
);
|
||
|
||
VOID
|
||
P91Bt489SetPointerShape(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
PUCHAR pHWCursorShape
|
||
);
|
||
|
||
VOID
|
||
P91Bt489PointerOn(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
);
|
||
|
||
VOID
|
||
P91Bt489PointerOff(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
);
|
||
|
||
VOID
|
||
P91Bt489ClearPalette(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
);
|
||
|
||
BOOLEAN
|
||
P91Bt489SetMode(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
);
|
||
|
||
VOID
|
||
P91Bt489RestoreMode(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
);
|
||
|
||
VOID
|
||
P91Bt489SetClkDoubler(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
);
|
||
|
||
VOID
|
||
P91Bt489ClrClkDoubler(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
);
|
||
|
||
//
|
||
// Define the DAC support routines structure for the Bt489 DAC.
|
||
//
|
||
|
||
DAC P91Bt489 = {
|
||
DAC_ID_BT489,
|
||
NUM_DAC_REGS,
|
||
P91Bt489SetMode,
|
||
P91Bt489RestoreMode,
|
||
P91Bt489SetPalette,
|
||
P91Bt489ClearPalette,
|
||
P91Bt489PointerOn,
|
||
P91Bt489PointerOff,
|
||
P91Bt489SetPointerPos,
|
||
P91Bt489SetPointerShape,
|
||
CLK489_MAX_FREQ,
|
||
P91Bt489SetClkDoubler,
|
||
P91Bt489ClrClkDoubler,
|
||
DAC_ID_BT489,
|
||
64,
|
||
FALSE,
|
||
FALSE,
|
||
TRUE // TRUE == Supports 24BPP
|
||
};
|
||
|
||
|
||
VOID
|
||
P91Bt489SetPalette(
|
||
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
|
||
P91Bt489SetPointerPos(
|
||
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
|
||
P91Bt489SetPointerShape(
|
||
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
|
||
P91Bt489PointerOn(
|
||
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
|
||
P91Bt489PointerOff(
|
||
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
|
||
P91Bt489ClearPalette(
|
||
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
|
||
P91Bt489SetMode(
|
||
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.
|
||
|
||
--*/
|
||
{
|
||
USHORT usLoadClock;
|
||
UCHAR ucCurState;
|
||
|
||
VideoDebugPrint((0, "P91Bt489SetMode----------\n"));
|
||
|
||
// Added per code received from R. Embry
|
||
|
||
WriteDAC(HwDeviceExtension, PIXEL_MSK_REG, 0xff);
|
||
|
||
//
|
||
// 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);
|
||
WR_CMD_REG_4( CR4_MUX_81 );
|
||
break;
|
||
|
||
case 16: // This is really 555, not 565...
|
||
WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_15);
|
||
WR_CMD_REG_4( CR4_MUX_41 );
|
||
break;
|
||
|
||
case 24:
|
||
WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_32);
|
||
WR_CMD_REG_4(CR4_MUX_24BPP);
|
||
break;
|
||
|
||
case 32:
|
||
WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_32);
|
||
WR_CMD_REG_4( CR4_MUX_21 );
|
||
break;
|
||
|
||
default:
|
||
|
||
//
|
||
// Oops..invalid BPP value. Use 8BPP value for now.
|
||
//
|
||
|
||
WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_8);
|
||
WR_CMD_REG_4( CR4_MUX_81 );
|
||
break;
|
||
};
|
||
|
||
// This code added per R. Embry from ECR 2/95
|
||
|
||
usLoadClock = (USHORT) ((HwDeviceExtension->VideoData.dotfreq1 /
|
||
HwDeviceExtension->Dac.usRamdacWidth) *
|
||
HwDeviceExtension->usBitsPixel);
|
||
|
||
if ( usLoadClock > 4850 )
|
||
{
|
||
ucCurState = SCLK_INV; // Bt489 - invert SCLK if in forbidden region
|
||
}
|
||
else
|
||
{
|
||
ucCurState = 0;
|
||
}
|
||
|
||
//
|
||
// Select P9x00 video clock, disable cursor
|
||
//
|
||
|
||
WriteDAC( HwDeviceExtension, CMD_REG_2,
|
||
(UCHAR)(ucCurState | ((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
|
||
P91Bt489RestoreMode(
|
||
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((0, "P91Bt489RestoreMode----------\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)
|
||
{
|
||
// Added per code received from R. Embry
|
||
|
||
WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3);
|
||
P9_WR_REG(P9100_RAMWRITE, 0x02);
|
||
WR_CMD_REG_3(0x00);
|
||
|
||
// end added code
|
||
|
||
P9_WR_REG(P9100_RAMWRITE, 0x01);
|
||
WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3);
|
||
|
||
// ucCurState = ReadDAC(HwDeviceExtension, CMD_REG_1);
|
||
// ucCurState = ReadDAC(HwDeviceExtension, CMD_REG_2);
|
||
|
||
// RD_CMD_REG_3(ucCurState);
|
||
// RD_CMD_REG_4(ucCurState);
|
||
|
||
WR_CMD_REG_4(0x00); // zero out cmd reg 4 on Bt489
|
||
|
||
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 | DAC_CLK_2X_489) & CUR_MODE_32));
|
||
|
||
//
|
||
// Set pixel read mask.
|
||
//
|
||
|
||
WriteDAC(HwDeviceExtension, PIXEL_MSK_REG, 0xff);
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
P91Bt489SetClkDoubler(
|
||
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((0, "P91Bt489SetClkDoubler----------\n"));
|
||
RD_CMD_REG_3(ucCurState);
|
||
// per os/2 driver, write undocumented bit too
|
||
if (HwDeviceExtension->usBitsPixel == 24 )
|
||
{
|
||
WR_CMD_REG_3(ucCurState | (DAC_CLK_2X | DAC_CLK_2X_489));
|
||
}
|
||
else
|
||
{
|
||
WR_CMD_REG_3(ucCurState | DAC_CLK_2X);
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
P91Bt489ClrClkDoubler(
|
||
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((0, "P91Bt489ClrClkDoubler----------\n"));
|
||
RD_CMD_REG_3(ucCurState);
|
||
WR_CMD_REG_3(ucCurState & ~(DAC_CLK_2X | DAC_CLK_2X_489));
|
||
return;
|
||
}
|