windows-nt/Source/XPSP1/NT/drivers/video/ms/cirrus/mini/sr754x.c
2020-09-26 16:20:57 +08:00

283 lines
9.2 KiB
C

//---------------------------------------------------------------------------
/*++
Copyright (c) 1994 Cirrus Logic, Inc.
Module Name:
sr754x.c
Abstract:
This module performs the save/restore operations specific to the
CL-GD754x chipset (aka Nordic).
Environment:
kernel mode only
Notes:
Revision History:
13Oct94 mrh Initial version
--*/
//---------------------------------------------------------------------------
#include "dderror.h"
#include "devioctl.h"
#include "miniport.h"
#include "ntddvdeo.h"
#include "video.h"
#include "cirrus.h"
#include "sr754x.h"
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE,NordicSaveRegs)
#pragma alloc_text(PAGE,NordicRestoreRegs)
#endif
VP_STATUS NordicSaveRegs(
PHW_DEVICE_EXTENSION HwDeviceExtension,
PUSHORT pNordicSaveArea
)
{
UCHAR i;
UCHAR PortVal, Save2C, Save2D;
PUCHAR CRTCAddressPort, CRTCDataPort;
PUSHORT pSaveBuf;
UCHAR vShadowIndex[CL754x_NUM_VSHADOW] = {0x06,0x07,0x10,0x11,0x15,0x16};
UCHAR zShadowIndex[CL754x_NUM_ZSHADOW] = {0,2,3,4,5};
UCHAR yShadowIndex[CL754x_NUM_YSHADOW] = {0,2,3,4,5};
UCHAR xShadowIndex[CL754x_NUM_XSHADOW] = {2,3,4,5,6,7,8,9,0x0B,0x0C,0x0D,0x0E};
//
// Determine where the CRTC registers are addressed (color or mono).
//
CRTCAddressPort = HwDeviceExtension->IOAddress;
CRTCDataPort = HwDeviceExtension->IOAddress;
if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
MISC_OUTPUT_REG_READ_PORT) & 0x01)
{
CRTCAddressPort += CRTC_ADDRESS_PORT_COLOR;
CRTCDataPort += CRTC_DATA_PORT_COLOR;
}
else
{
CRTCAddressPort += CRTC_ADDRESS_PORT_MONO;
CRTCDataPort += CRTC_DATA_PORT_MONO;
}
VideoPortWritePortUchar(CRTCAddressPort, IND_CR2D);
Save2D = (VideoPortReadPortUchar(CRTCDataPort));
VideoPortWritePortUchar(CRTCAddressPort, IND_CR2C);
Save2C = (VideoPortReadPortUchar(CRTCDataPort));
pSaveBuf = pNordicSaveArea;
//Initialize the control registers to access shadowed vertical regs:
// CR2C[3] = {0} Allows access to Vert regs (CR6,CR7,CR10,CR11,CR15,CR16)
// CR2D[7] = {0} Blocks access to LCD timing regs (R2X-REX)
//
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((Save2C & ~0x08) << 8) | IND_CR2C));
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((Save2D & ~0x80) << 8) | IND_CR2D));
for (i = 0; i < CL754x_NUM_VSHADOW; i++)
{
VideoPortWritePortUchar (CRTCAddressPort, vShadowIndex[i]);
*pSaveBuf++ = (USHORT)((VideoPortReadPortUchar (CRTCDataPort)) << 8) |
vShadowIndex[i];
}
for (i = CL754x_CRTC_EXT_START; i <= CL754x_CRTC_EXT_END; i++)
{
VideoPortWritePortUchar (CRTCAddressPort, i);
*pSaveBuf++ = (USHORT)((VideoPortReadPortUchar (CRTCDataPort)) << 8) | i;
}
for (i = CL754x_HRZ_TIME_START; i <= CL754x_HRZ_TIME_END; i++)
{
VideoPortWritePortUchar (CRTCAddressPort, i);
*pSaveBuf++ = (USHORT)((VideoPortReadPortUchar (CRTCDataPort)) << 8) | i;
}
// Set CR2D [7] to {0} and CR2C[5,4] to {1,0}
// These values provide access to Y shadow registers
//
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((Save2D & ~0x80) << 8) | IND_CR2D));
PortVal = Save2C & ~0x30; // We'll use PortVal again below
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((PortVal | 0x20) << 8) | IND_CR2C));
for (i = 0; i < CL754x_NUM_YSHADOW; i++)
{
VideoPortWritePortUchar (CRTCAddressPort, yShadowIndex[i]);
*pSaveBuf++ = (USHORT)((VideoPortReadPortUchar (CRTCDataPort)) << 8) |
yShadowIndex[i];
}
// Set CR2C[5,4] to {1,1}
// This will provide access to Z shadow registers
//
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((PortVal | 0x30) << 8 )| IND_CR2C));
for (i = 0; i < CL754x_NUM_ZSHADOW; i++)
{
VideoPortWritePortUchar (CRTCAddressPort, zShadowIndex[i]);
*pSaveBuf++ = (USHORT)((VideoPortReadPortUchar (CRTCDataPort)) << 8) |
zShadowIndex[i];
}
// Set CR2C[5,4] to {0,0} and CR2D[7] to {1}
// This will provide access to X shadow registers
//
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort, // PortVal=Save2C & ~0x30
(USHORT)((PortVal << 8) | IND_CR2C));
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((Save2D | 0x80) << 8) | IND_CR2D));
for (i = 0; i < CL754x_NUM_XSHADOW; i++)
{
VideoPortWritePortUchar (CRTCAddressPort, xShadowIndex[i]);
*pSaveBuf++ = ((VideoPortReadPortUchar (CRTCDataPort)) << 8) |
xShadowIndex[i];
}
//Restore the original values for CR2C and CR2D
//
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)((Save2D << 8) | IND_CR2D));
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)((Save2C << 8) | IND_CR2C));
return NO_ERROR;
}
VP_STATUS NordicRestoreRegs(
PHW_DEVICE_EXTENSION HwDeviceExtension,
PUSHORT pNordicSaveArea
)
{
ULONG i;
UCHAR PortVal, Save2C, Save2D;
PUSHORT pSaveBuf;
PUCHAR CRTCAddressPort, CRTCDataPort;
//
// Determine where the CRTC registers are addressed (color or mono).
//
CRTCAddressPort = HwDeviceExtension->IOAddress;
CRTCDataPort = HwDeviceExtension->IOAddress;
if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
MISC_OUTPUT_REG_READ_PORT) & 0x01)
{
CRTCAddressPort += CRTC_ADDRESS_PORT_COLOR;
CRTCDataPort += CRTC_DATA_PORT_COLOR;
}
else
{
CRTCAddressPort += CRTC_ADDRESS_PORT_MONO;
CRTCDataPort += CRTC_DATA_PORT_MONO;
}
//Initialize the control registers to access shadowed vertical regs
// CR11[7] = {0} Allows access to CR0-7
// CR2C[3] = {0} Allows access to Vertical regs (CR6,CR7,CR10,CR11,CR15,CR16
// CR2D[7] = {0} Blocks access to LCD timing regs (R2X-REX)
//
VideoPortWritePortUchar(CRTCAddressPort, IND_CRTC_PROTECT);
VideoPortWritePortUchar(CRTCDataPort,
(UCHAR) (VideoPortReadPortUchar(CRTCDataPort) & ~0x80));
VideoPortWritePortUchar(CRTCAddressPort, IND_CR2C);
VideoPortWritePortUchar(CRTCDataPort,
(UCHAR) (VideoPortReadPortUchar(CRTCDataPort) & ~0x08));
VideoPortWritePortUchar(CRTCAddressPort, IND_CR2D);
VideoPortWritePortUchar(CRTCDataPort,
(UCHAR) (VideoPortReadPortUchar(CRTCDataPort) & ~0x80));
pSaveBuf = pNordicSaveArea;
for (i = 0; i < CL754x_NUM_VSHADOW; i++)
{
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort, (*pSaveBuf++));
}
// Make sure we didn't lock CR0-CR7
//
VideoPortWritePortUchar(CRTCAddressPort, IND_CRTC_PROTECT);
VideoPortWritePortUchar(CRTCDataPort,
(UCHAR) (VideoPortReadPortUchar(CRTCDataPort) & ~0x80));
for (i=0; i < (CL754x_NUM_CRTC_EXT_PORTS + CL754x_NUM_HRZ_TIME_PORTS); i++)
{
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort, (*pSaveBuf++));
}
// Set CR2D [7] to {0} and CR2C[5,4] to {1,0}; save current contents
// These values provide access to Y shadow registers
//
VideoPortWritePortUchar(CRTCAddressPort, IND_CR2D);
Save2D = (VideoPortReadPortUchar(CRTCDataPort));
VideoPortWritePortUchar(CRTCDataPort, (UCHAR)(Save2D & ~0x80));
VideoPortWritePortUchar(CRTCAddressPort, IND_CR2C);
PortVal = Save2C = (VideoPortReadPortUchar(CRTCDataPort));
PortVal &= ~0x30;
PortVal |= 0x20;
VideoPortWritePortUchar(CRTCDataPort, PortVal);
for (i = 0; i < CL754x_NUM_YSHADOW; i++)
{
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort, (*pSaveBuf++));
}
// Set CR2C[5,4] to {1,1}
// This will provide access to Z shadow registers
//
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((PortVal | 0x30) << 8) | IND_CR2C) );
for (i = 0; i < CL754x_NUM_ZSHADOW; i++)
{
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort, (*pSaveBuf++));
}
// Set CR2C[5,4] to {0,0} and CR2D[7] to {1}
// This will provide access to X shadow registers
//
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((PortVal & ~0x30) << 8) | IND_CR2C) );
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort,
(USHORT)(((Save2D | 0x80) << 8) | IND_CR2D) );
for (i = 0; i < CL754x_NUM_XSHADOW; i++)
{
VideoPortWritePortUshort((PUSHORT)CRTCAddressPort, (*pSaveBuf++));
}
// Reset the Blitter, in case it's busy
//
VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress +
GRAPH_ADDRESS_PORT), 0x0430);
VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress +
GRAPH_ADDRESS_PORT), 0x0030);
VideoPortWritePortUshort((PUSHORT) CRTCAddressPort,
(USHORT)((Save2C << 8) | IND_CR2C));
VideoPortWritePortUshort((PUSHORT) CRTCAddressPort,
(USHORT)((Save2D << 8) | IND_CR2D));
return NO_ERROR;
}