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