📄 ltcrt.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*****************************************************************************\
*
* Module Name LTCRT.C
* Project 3D RAGE PRO/LT Rage Pro
* Device Rage
*
* Description Contains the functions required for implementation of
* a CRT Graphics Display Object (GDO) for the Display
* Abstraction Layer.
*
* (c) 1997 ATI Technologies Inc. (unpublished)
*
* All rights reserved. This notice is intended as a precaution against
* inadvertent publication and does not imply publication or any waiver
* of confidentiality. The year included in the foregoing notice is the
* year of creation of the work.
*
* Programmer's Note:
* Great care was taken and considerable effort was expended to make the
* code in this file 100% BIOS independant. This has been done so that in
* an OS that supports multiple displays and multiple adapters the problems
* multiple BIOSes raise totally disappear. Since this effort has been made
* it follows that further modifications to this file should NOT include ANY
* calls to the BIOS. The sole purpose of the code in this file is to avoid
* any reliance on the BIOS.
*
*
\*****************************************************************************/
#include "dal.h"
#include "ltcrtl.h"
#include "ltddc.h"
#include "rprod.h"
/******************************Public*Routine******************************\
* BOOL CRTEnable(HW_DEVICE_EXTENSION* phde, HGDO hGDO,
* HW_ASIC_ID phasicid, HW_DISPLAY_ENABLEDATE FAR* lpEnableData)
*
*
* CRTEnable determines if the graphics adapter is supported, and if the
* graphics adapter's hardware has support for a DAC type supported by
* the object. GDOEnable is the initial entry point exported by the graphics
* display object. It fills a HW_DISPLAY_ENABLEDATA structure with
* information, and calling addresses of functions supported by the graphics
* display object.
*
\**************************************************************************/
BOOL FAR
CRTEnable(
HDDL hDDL,
HGDO hGDO,
LPHW_ASIC_ID lpHwAsicID,
LPHW_DISPLAY_ENABLEDATA lpEnableData
)
{
LPGDO_RAGE_CRT hGDORageCRT;
ULONG ulTemp;
hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTEnable - Entry"));
DALASSERT(HW_DISPLAY_EXTENSION_SIZE >= sizeof(GDO_RAGE_CRT),
"Size of GDO structure is too large!");
if (lpEnableData->ulSize != sizeof(HW_DISPLAY_ENABLEDATA))
{
DALASSERT(FALSE, "Hardware Enable Data structure mismatch w/ DAL!");
return(FALSE);
}
hGDORageCRT->lpLibVersionString = (LPVOID)R3CRTGDOLIB;
lpEnableData->ulFunctionHooks = (
GDO_HOOK_VERTICAL_POSITION_ADJUSTMENT |
GDO_HOOK_HORIZONTAL_POSITION_ADJUSTMENT |
GDO_HOOK_VERTICAL_SIZE_ADJUSTMENT |
GDO_HOOK_HORIZONTAL_SIZE_ADJUSTMENT |
GDO_HOOK_DPMS |
GDO_HOOK_GET_EDID_DATA | // Added to get EDID Data
GDO_HOOK_GET_MONITOR_INFO | // Added to get Monitor info
GDO_HOOK_HORIZONTAL_SYNC |
GDO_HOOK_VERTICAL_SYNC |
GDO_HOOK_COMPOSITE_SYNC |
GDO_HOOK_MODE_CHANGES
);
lpEnableData->ulDisplayVersion = R3LIB_VERSION;
// lpEnableData->ulDisplayVersion = RAGECRT_VERSION;
lpEnableData->ulDisplayType = HW_DISPLAY_TYPE_CRT;
lpEnableData->lpDisplayName = RAGECRT_NAME;
lpEnableData->pfnDisable = CRTDisable;
lpEnableData->pfnEnable = CRTEnable;
lpEnableData->pfnSetDisplayOff = CRTSetDisplayOff;
lpEnableData->pfnSetDisplayOn = CRTSetDisplayOn;
lpEnableData->pfnBlanking = CRTBlank;
lpEnableData->pfnGetDisplayPositionAdjustment =
CRTGetDisplayPositionAdjustment;
lpEnableData->pfnSetDisplayPositionAdjustment =
CRTSetDisplayPositionAdjustment;
lpEnableData->pfnGetDisplaySizeAdjustment = CRTGetDisplaySizeAdjustment;
lpEnableData->pfnSetDisplaySizeAdjustment = CRTSetDisplaySizeAdjustment;
lpEnableData->pfnSetDPMS = CRTSetDPMS;
lpEnableData->pfnIsDisplayPhysicallyConnected =
CRTIsDisplayPhysicallyConnected;
lpEnableData->pfnIsModeSupported = CRTIsModeSupported;
lpEnableData->pfnSetMode = CRTSetMode;
lpEnableData->pfnPreModeChange = CRTPreModeChange;
lpEnableData->pfnPostModeChange = CRTPostModeChange;
lpEnableData->pfnGetEdidData = CRTGetEdidData;
lpEnableData->pfnGetMonitorInfo = CRTGetMonitorInfo;
lpEnableData->pfnGetSyncVerticalAdjustment=CRTGetVerticalSyncAdjustment;
lpEnableData->pfnGetSyncHorizontalAdjustment=CRTGetHorizontalSyncAdjustment;
lpEnableData->pfnGetSyncCompositeAdjustment=CRTGetCompositeSyncAdjustment;
lpEnableData->pfnSetSyncVerticalAdjustment=CRTSetVerticalSyncAdjustment;
lpEnableData->pfnSetSyncHorizontalAdjustment=CRTSetHorizontalSyncAdjustment;
lpEnableData->pfnSetSyncCompositeAdjustment=CRTSetCompositeSyncAdjustment;
hGDORageCRT->ulChipFamily = lpHwAsicID->ulChipFamily;
hGDORageCRT->ulChipID = lpHwAsicID->ulChipID;
hGDORageCRT->ulVRamInstalled = lpHwAsicID->ulVRamInstalled;
hGDORageCRT->ulVRamType = lpHwAsicID->ulVRamType;
hGDORageCRT->ulVRamBitWidth = lpHwAsicID->ulVRamBitWidth;
hGDORageCRT->lpIO = lpHwAsicID->lpIO;
hGDORageCRT->lpMMR = lpHwAsicID->lpMMR;
hGDORageCRT->lpRomBaseAddress = lpHwAsicID->lpRomBaseAddress;
hGDORageCRT->lpRomHeader = lpHwAsicID->lpRomHeader;
hGDORageCRT->lpucVgaBuffer = lpHwAsicID->lpucVgaBuffer;
hGDORageCRT->usRealSegment = lpHwAsicID->usRealSegment;
hGDORageCRT->ulReferenceFrequency = lpHwAsicID->ulReferenceFrequency;
hGDORageCRT->ulFlag = 0; // EPR 40230
hGDORageCRT->hDDL = hDDL;
// Must be called after hDDL is intialized.
vGetCRTGDORegFlag(hGDO);
// Get registry based retry counter.
vCrtGDOGetRegistryRetryCounter( hGDO ); // EPR 40230
hGDORageCRT->ulController = PRIMARY_CONTROLLER;
lpEnableData->ulDisplayCaps |= GDO_CAPS_ACTIVATE_BEFORE_DETECT;
// No LCD data register for RAGE PRO family
if(hGDORageCRT->ulChipFamily == FAMILY_GTC) // EPR# 042986 Task# 5994
{
lpEnableData->bEnabledAtBoot = TRUE;
return(TRUE);
}
// Read the Engine ON bit to check if CRT is ON at boot
ulTemp = MMREADULONG(hGDORageCRT->lpMMR, LCD_INDEX);
ulTemp &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulTemp |= LCD_INDEX_lcdGenCtrlReg;
MMWRITEULONG(hGDORageCRT->lpMMR, LCD_INDEX, ulTemp);
// Read LCD GEN CTRL data from LCD data register first.
ulTemp = MMREADULONG(hGDORageCRT->lpMMR, LCD_DATA);
if (ulTemp & LCD_GEN_CTRL__CRT_ON)
{
lpEnableData->bEnabledAtBoot = TRUE;
}
else
{
lpEnableData->bEnabledAtBoot = FALSE;
}
if((hGDORageCRT->ulChipFamily == FAMILY_RAGE_MOBILITY) ||
(hGDORageCRT->ulChipFamily == FAMILY_RAGE_XL))
{
CRTDetectionImproved(hGDO); // Initialize FORCE_DAC_DATA_SEL and
// FORCE_DAC_DATA registers for CRT detection.
}
return(TRUE);
} // end CRTEnable
/******************************Public*Routine******************************\
* VOID CRTDisable(HGDO hGDO)
*
*
* CRTDisable is used by DAL to notify the graphics display object
* that the display is no longer needed.
*
* The graphics display object frees locks, allocated resources,
* and returns the display to the state it was in before the graphics
* display object was loaded.
*
\**************************************************************************/
VOID FAR
CRTDisable(
HGDO hGDO
)
{
LPGDO_RAGE_CRT hGDORageCRT;
hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTDisable - Entry"));
// there shouldn't be anything to do here...
} // end CRTDisable
/******************************Public*Routine******************************\
* VOID CRTGetDisplayPositionAdjustment(HGDO hGDO,
* LPHW_ADJUSTMENT lpadjustment,
* LPDEVMODE_INFO lpmi)
*
* CRTGetDisplayPositionAdjustment is used to query the minimum, maximum,
* and default, values for vertical and horizontal display position
* adjustments.
*
* NOTE:
* The default and the Step values this rountine calaculates may have to
* be tuned based on the visual results that these values generate.
*
\**************************************************************************/
VOID FAR
CRTGetDisplayPositionAdjustment(
HGDO hGDO,
LPHW_ADJUSTMENT lpAdjustment,
LPDEVMODE_INFO lpMI
)
{
LPGDO_RAGE_CRT hGDORageCRT;
hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTGetDisplayPositionAdjustment - Entry"));
// what we want to do is get the values from the HW registers that
// allow us to change the position of the display on the screen.
// the numbers that we are interested in are Sync_Width, TotalDisp
// and Disp_End for both the horizontal and the vertical
// The limits for the position adjustment are as follows:
// Sync_Start has to be greater than Disp end and less than or equal
// to TotalDisp - Sync_Width.
lpAdjustment[0].lStep = 1; // vertical, unit is line
lpAdjustment[0].lDefault = 0;
lpAdjustment[1].lStep = 1; // Horizontal, unit is pixel
lpAdjustment[1].lDefault = 0;
// Vertical values first
lpAdjustment[0].lMin = (LONG)hGDORageCRT->ulInitialVSyncStart -
((LONG)hGDORageCRT->ulVTotal - (LONG)hGDORageCRT->ulVSyncWidth);
if (lpAdjustment[0].lMin > 0)
lpAdjustment[0].lMin = 0;
lpAdjustment[0].lMax = (LONG)hGDORageCRT->ulInitialVSyncStart
-(LONG)hGDORageCRT->ulVDispEnd;
if (lpAdjustment[0].lMax < 0)
lpAdjustment[0].lMax = 0;
// Now Horizontal values
lpAdjustment[1].lMin = ((LONG)hGDORageCRT->ulInitialHSyncStart -
((LONG)hGDORageCRT->ulHTotal -
(LONG)hGDORageCRT->ulHSyncWidth)) * 3 / 4;
if (lpAdjustment[1].lMin > 0)
lpAdjustment[1].lMin = 0;
lpAdjustment[1].lMax = (LONG)hGDORageCRT->ulInitialHSyncStart
-(LONG)hGDORageCRT->ulHDispEnd;
if (lpAdjustment[1].lMax < 0)
lpAdjustment[1].lMax = 0;
} // end CRTGetDisplayPositionAdjustment
/******************************Public*Routine******************************\
* VOID CRTGetDisplaySizeAdjustment(HGDO hGDO,
* LPHW_ADJUSTMENT lpadjustment,
* LPDEVMODE_INFO lpmi)
*
* CRTGetDisplaySizeAdjustment is used to query the minimum, maximum, and
* default values for vertical and horizontal display size adjustments.
*
\**************************************************************************/
VOID FAR
CRTGetDisplaySizeAdjustment(
HGDO hGDO,
LPHW_ADJUSTMENT lpAdjustment,
LPDEVMODE_INFO lpMI
)
{
LPGDO_RAGE_CRT hGDORageCRT;
hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTGetDisplaySizeAdjustment - Entry"));
// The limits for the size adjustment are as follows:
// New Total must be greater than Disp_End + Sync_Width. However,
// We haven't figured out what is maximum value of New Total;
lpAdjustment[0].lStep = 1; // vertical, unit is line
lpAdjustment[0].lDefault = 0;
lpAdjustment[1].lStep = 1; // Horizontal, unit is pixel
lpAdjustment[1].lDefault = 0;
// Vertical values first
lpAdjustment[0].lMin = -((LONG)hGDORageCRT->ulVTotal / 4);
//hard code(temporary). VTotal / 4
if (lpAdjustment[0].lMin > 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -