📄 ltcrt.c
字号:
lpAdjustment[0].lMin = 0;
lpAdjustment[0].lMax = (LONG)hGDORageCRT->ulVTotal -
((LONG)hGDORageCRT->ulVDispEnd +
(LONG)hGDORageCRT->ulVSyncWidth);
if (lpAdjustment[0].lMax < 0)
lpAdjustment[0].lMax = 0;
// Now Horizontal values
lpAdjustment[1].lMin = -((LONG)hGDORageCRT->ulHTotal / 4);
//hard code(temporary). HTotal / 4
if (lpAdjustment[1].lMin > 0)
lpAdjustment[1].lMin = 0;
lpAdjustment[1].lMax = (LONG)hGDORageCRT->ulHTotal -
((LONG)hGDORageCRT->ulHDispEnd +
(LONG)hGDORageCRT->ulHSyncWidth);
if (lpAdjustment[1].lMax < 0)
lpAdjustment[1].lMax = 0;
} // end CRTGetDisplaySizeAdjustment
/******************************Public*Routine******************************\
* VOID CRTSetDisplayPositionAdjustment(HGDO hGDO,
* LONG lHorizontalAdjust,
* LONG lVerticalAdjust
* )
*
* CRTSetDisplayPositionAdjustment is used to set vertical and horizontal
* display position adjustments to the current mode.
*
\**************************************************************************/
VOID FAR
CRTSetDisplayPositionAdjustment(
HGDO hGDO,
LONG lVerticalAdjust,
LONG lHorizontalAdjust)
{
LPGDO_RAGE_CRT hGDORageCRT;
ULONG ulHCRTC_Data;
ULONG ulVCRTC_Data;
LONG lSync_Start;
LONG lNewH_Sync_Start;
ULONG ulSync_Strt_Wid_Data;
ULONG ulSync_Start_Hi;
hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTSetDisplayPositionAdjustment - Entry"));
// For LT Rage Pro, we need to select controller for CRTC register R/W.
if ( hGDORageCRT->ulChipFamily == FAMILY_LT_PRO ||
hGDORageCRT->ulChipFamily == FAMILY_RAGE_MOBILITY )
SelectCRTCRW(hGDO);
// Horizontal values first
// NEW_H_SYNC_STRT = DEFAULT_H_SYNC_START - lHorizontalAdjust.
lNewH_Sync_Start =(LONG)hGDORageCRT->ulInitialHSyncStart - lHorizontalAdjust;
// New Sync start must be greater than Disp End, and
// New Sync start + Sync Width must be less than Disp_Total.
// lNewH_Sync_Start = (lNewH_Sync_Start < 0) ? 0:lNewH_Sync_Start;
lNewH_Sync_Start = (lNewH_Sync_Start < (LONG)hGDORageCRT->ulHDispEnd) ?
hGDORageCRT->ulHDispEnd : lNewH_Sync_Start;
lNewH_Sync_Start = ((lNewH_Sync_Start + hGDORageCRT->ulHSyncWidth) > hGDORageCRT->ulHTotal) ?
(hGDORageCRT->ulHTotal - hGDORageCRT->ulHSyncWidth): lNewH_Sync_Start;
if (lNewH_Sync_Start != (LONG)hGDORageCRT->ulPreviousHSyncStart)
{
ulHCRTC_Data = MMREADULONG(hGDORageCRT->lpMMR, CRTC_H_SYNC_STRT_WID);
hGDORageCRT->ulPreviousHSyncStart = (ULONG)lNewH_Sync_Start;
lSync_Start = (lNewH_Sync_Start & CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_MASK);
// High bit for Horizontal_Sync_Start
lSync_Start |= ((lNewH_Sync_Start <<4) &
CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_HI_MASK);
ulHCRTC_Data &= (~CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_ALL_MASK);
ulHCRTC_Data |= lSync_Start;
// Write out new Sync_Start values.
MMWRITEULONG(hGDORageCRT->lpMMR, CRTC_H_SYNC_STRT_WID, ulHCRTC_Data);
// Store the horizontal sync start values
ulSync_Strt_Wid_Data = MMREADULONG(hGDORageCRT->lpMMR,
CRTC_H_SYNC_STRT_WID);
hGDORageCRT->ulHSyncStart = ((ulSync_Strt_Wid_Data &
CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_MASK));
ulSync_Start_Hi = (ulSync_Strt_Wid_Data &
CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_HI_MASK);
hGDORageCRT->ulHSyncStart |= (ulSync_Start_Hi >> 4);
}
// Now vertical values
// NEW_V_SYNC_STRT = DEFAULT_V_SYNC_START + lVerticalAdjust.
lSync_Start = (LONG)hGDORageCRT->ulInitialVSyncStart - lVerticalAdjust;
// New Sync start must be greater than Disp End, and
// New Sync start + Sync Width must be less than Disp_Total.
// lSync_Start = (lSync_Start < 0) ? 0:lSync_Start;
lSync_Start = (lSync_Start < (LONG)hGDORageCRT->ulVDispEnd) ?
hGDORageCRT->ulVDispEnd : lSync_Start;
lSync_Start = ((lSync_Start + hGDORageCRT->ulVSyncWidth) > hGDORageCRT->ulVTotal) ?
hGDORageCRT->ulVTotal - hGDORageCRT->ulVSyncWidth : lSync_Start;
if (lSync_Start != (LONG)hGDORageCRT->ulPreviousVSyncStart)
{
ulVCRTC_Data = MMREADULONG(hGDORageCRT->lpMMR, CRTC_V_SYNC_STRT_WID);
hGDORageCRT->ulPreviousVSyncStart = (ULONG)lSync_Start;
ulVCRTC_Data &= (~CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_STRT_MASK);
lSync_Start &= CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_STRT_MASK;
ulVCRTC_Data |= lSync_Start;
// Write out new Sync_Start values.
MMWRITEULONG(hGDORageCRT->lpMMR, CRTC_V_SYNC_STRT_WID, ulVCRTC_Data);
// Store the vertical sync start values
ulSync_Strt_Wid_Data = MMREADULONG(hGDORageCRT->lpMMR,
CRTC_V_SYNC_STRT_WID);
hGDORageCRT->ulVSyncStart = ((ulSync_Strt_Wid_Data &
CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_STRT_MASK));
}
// For LT Rage Pro, we need to restore CRTC register R/W back to 0.
if ( hGDORageCRT->ulChipFamily == FAMILY_LT_PRO ||
hGDORageCRT->ulChipFamily == FAMILY_RAGE_MOBILITY )
RestoreCRTCRW(hGDO);
} // end CRTSetDisplayPositionAdjustment
/******************************Public*Routine******************************\
* VOID CRTSetDisplaySizeAdjustment(HGDO hGDO,
* LONG lHorizontalAdjust,
* LONG lVerticalAdjust
* )
*
* GDOSetDisplaySizeAdjustment is used to set vertical and horizontal
* display size adjustments to the current mode.
*
\**************************************************************************/
BOOL FAR
CRTSetDisplaySizeAdjustment(
HGDO hGDO,
LONG lVerticalAdjust,
LONG lHorizontalAdjust)
{
LONG Sync_Ratio;
LONG lFront_Porch;
LONG lFront_Back_Porch;
ULONG ulNewV_Sync_Start;
ULONG ulNewH_Sync_Start;
LONG lNewVTotal;
LONG lNewHTotal;
LPGDO_RAGE_CRT hGDORageCRT;
ADJUSTMENT_PARAMETERS AdjustmentParameters; //GDO must fill this structure and then call DalAdjustmentTiming
//through the function pointer passed as argument to this function
//DalAdjustmentTiming would the call the GCOProgramAdjustmentTiming
//function to load the value into the crtc registers. GDO must supply
//the correct controller. DAL function is defined in dal.h as
hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTSetDisplaySizeAdjustment - Entry"));
// For LT Rage Pro, we need to select controller for CRTC register R/W.
if ( hGDORageCRT->ulChipFamily == FAMILY_LT_PRO ||
hGDORageCRT->ulChipFamily == FAMILY_RAGE_MOBILITY )
SelectCRTCRW(hGDO);
// We want to do two things here. First, and easiest, we want to
// take the incoming value in aladjust and make that our new V_TOTAL.
// When we do this though we want to keep the ratio of the front porch
// to the back porch the same. That is the second and harder part.
// Front porch is the time from V_DISP_END to V_SYNC_STRT minus the top
// overscan. The same problem exists for the horizontal case and it is
// solved the same way.
// Horizontal values first
if (lHorizontalAdjust)
{
lNewHTotal = (LONG)hGDORageCRT->ulHTotal - lHorizontalAdjust;
// New H_Total must be greater than Disp_End + Sync_Width.
// lNewHTotal = (lNewHTotal < 0) ? 0: lNewHTotal;
lNewHTotal = (lNewHTotal <
((LONG) hGDORageCRT->ulHDispEnd+ (LONG)hGDORageCRT->ulHSyncWidth)) ?
(hGDORageCRT->ulHDispEnd + hGDORageCRT->ulHSyncWidth)
: lNewHTotal;
// Now we have all the info we need to find the front and back porch.
lFront_Porch = ( hGDORageCRT->ulHSyncStart
- hGDORageCRT->ulHDispEnd
- hGDORageCRT->ulRightOverScan);
lFront_Back_Porch = (hGDORageCRT->ulHTotal
- hGDORageCRT->ulLeftOverScan
- hGDORageCRT->ulHSyncWidth
- hGDORageCRT->ulRightOverScan
- hGDORageCRT->ulHDispEnd);
Sync_Ratio = ((lFront_Porch << 16) / lFront_Back_Porch);
lFront_Porch = (((lNewHTotal
- hGDORageCRT->ulLeftOverScan
- hGDORageCRT->ulHSyncWidth
- hGDORageCRT->ulRightOverScan
- hGDORageCRT->ulHDispEnd)
* Sync_Ratio) >> 16);
ulNewH_Sync_Start = (lFront_Porch + hGDORageCRT->ulRightOverScan
+ hGDORageCRT->ulHDispEnd);
}
else
{
lNewHTotal = (LONG)hGDORageCRT->ulHTotal;
ulNewH_Sync_Start = hGDORageCRT->ulHSyncStart;
}
// Now vertical values
if (lVerticalAdjust)
{
lNewVTotal = (LONG)hGDORageCRT->ulVTotal - lVerticalAdjust;
// New V_Total must be greater than Disp_End + Sync_Width.
// lNewVTotal = (lNewVTotal < 0) ? 0: lNewVTotal;
lNewVTotal = (lNewVTotal <
((LONG)hGDORageCRT->ulVDispEnd + (LONG)hGDORageCRT->ulVSyncWidth))?
(hGDORageCRT->ulVDispEnd + hGDORageCRT->ulVSyncWidth)
: lNewVTotal;
// Now we have all the info we need to find the front and back porch.
lFront_Porch = (hGDORageCRT->ulVSyncStart
- hGDORageCRT->ulVDispEnd
- hGDORageCRT->ulBottomOverScan);
lFront_Back_Porch = (hGDORageCRT->ulVTotal
- hGDORageCRT->ulBottomOverScan
- hGDORageCRT->ulVSyncWidth
- hGDORageCRT->ulTopOverScan
- hGDORageCRT->ulVDispEnd );
Sync_Ratio = ((lFront_Porch << 16) / lFront_Back_Porch);
lFront_Porch = (((lNewVTotal
- hGDORageCRT->ulBottomOverScan
- hGDORageCRT->ulVSyncWidth
- hGDORageCRT->ulTopOverScan
- hGDORageCRT->ulVDispEnd )
* Sync_Ratio)>>16);
ulNewV_Sync_Start = (lFront_Porch + hGDORageCRT->ulVDispEnd
+ hGDORageCRT->ulBottomOverScan);
}
else
{
lNewVTotal= (LONG)hGDORageCRT->ulVTotal;
ulNewV_Sync_Start= hGDORageCRT->ulVSyncStart;
}
// For LT Rage Pro, we need to restore CRTC register R/W back to 0.
if ( hGDORageCRT->ulChipFamily == FAMILY_LT_PRO ||
hGDORageCRT->ulChipFamily == FAMILY_RAGE_MOBILITY )
RestoreCRTCRW(hGDO);
AdjustmentParameters.usCRTC_H_TOTAL = (USHORT)lNewHTotal;
AdjustmentParameters.usCRTC_H_SYNC_START = (USHORT)ulNewH_Sync_Start;
AdjustmentParameters.usCRTC_V_TOTAL = (USHORT)lNewVTotal;
AdjustmentParameters.usCRTC_V_SYNC_START = (USHORT)ulNewV_Sync_Start;
AdjustmentParameters.usPLL_REF_DIV = 0;
AdjustmentParameters.usPLL_FB_DIV = 0;
AdjustmentParameters.ucPLL_POST_DIV = 0;
return(
(*hGDORageCRT->pfnDalSetAdjustmentTimings)(hGDORageCRT->lpParameter,
hGDORageCRT->ulController,
(LPADJUSTMENT_PARAMETERS)&AdjustmentParameters)
);
} // end CRTSetDisplaySizeAdjustment
/******************************Public*Routine******************************\
* VOID FAR CRTBlank(HGDO hGDO, ULONG ulController, BOOL bBlank)
*
* Blank CRT if bBlank is TRUE. Unblank if FALSE
*
\**************************************************************************/
VOID FAR CRTBlank(HGDO hGDO, ULONG ulController, BOOL bBlank)
{
ULONG ulLCDIndex;
ULONG ulLCDGenCtrlData;
LPGDO_RAGE_CRT hGDORageCRT;
hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTBlank - Entry"));
// No LCD data register for RAGE PRO family
if(hGDORageCRT->ulChipFamily == FAMILY_GTC) // EPR# 042986 Task# 5994
{
ulLCDGenCtrlData = MMREADULONG(hGDORageCRT->lpMMR, CRTC_GEN_CNTL);
if(bBlank == TRUE)
{
// set DisplayDis bit to 1 which turns off the CRT display.
ulLCDGenCtrlData |= CRTC_GEN_CNTL_CrtcDisplayDis;
}
else
{
// set DisplayDis bit to 0 which turns on the CRT display.
ulLCDGenCtrlData &= (~CRTC_GEN_CNTL_CrtcDisplayDis);
}
MMWRITEULONG(hGDORageCRT->lpMMR, CRTC_GEN_CNTL, ulLCDGenCtrlData);
return;
}
// Set LCD_DATA register to index 1( LCD_GEN_CTRL).
ulLCDIndex = MMREADULONG(hGDORageCRT->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_lcdGenCtrlReg;
MMWRITEULONG(hGDORageCRT->lpMMR, LCD_INDEX, ulLCDIndex);
// Read LCD GEN CTRL data from LCD data register first.
ulLCDGenCtrlData = MMREADULONG(hGDORageCRT->lpMMR, LCD_DATA);
if(bBlank == TRUE)
{
// set CRT_ON bit to 0 which turns off the CRT display.
ulLCDGenCtrlData &= ~LCD_GEN_CTRL__CRT_ON;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -