⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ltcrt.c

📁 此代码为WCE5.0下显示器的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

    DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTIsDisplayPhysicallyConnected - Entry"));

    // EPR 32286
    // Try to talk to a DDC monitor first. If Edid is read from DDC CRT,
    // then CRT is physically connected.
    if(CRTEdidDetection(hGDO))
    {
        DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: A DDC CRT is detected."));
        return TRUE;
    }

    //
    // The monitor either wasn't connected or it is a non-DDC monitor.
    // So, use software algorithm to handle CRT detection.
    //

    // Checks controller number. 0: primary, 1: Secondary
    if ( hGDORageCRT->ulController == PRIMARY_CONTROLLER)
    {
        // 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.
        // set CRTC_RW_SELECT bit to 0 which makes register R/W go to
        // primary CRTC, and turn on CRT.
        ulLCDGenCtrlData = MMREADULONG(hGDORageCRT->lpMMR, LCD_DATA);
        ulLCDGenCtrlData &= (~LCD_GEN_CTL_CrtcRWSelect);
        ulLCDGenCtrlData |= LCD_GEN_CTRL__CRT_ON;
        MMWRITEULONG(hGDORageCRT->lpMMR, LCD_DATA, ulLCDGenCtrlData);

        // enables the DAC compare which we will need later and
        // select data source for the monitor (primary).
        ulDACCntlData=
        ulDACCntlTemp = MMREADULONG(hGDORageCRT->lpMMR, DAC_CNTL);
        ulDACCntlTemp &= (~DAC_CNTL__DAC_CMP_DIS);
        ulDACCntlTemp &= (~DAC_CNTL_Dac1ClkSel);
        MMWRITEULONG(hGDORageCRT->lpMMR, DAC_CNTL, ulDACCntlTemp);

        // Preserve CRTC_GEN_CNTL and enable Overscan in VGA.
        ulCRTCGenCntlTemp =
        ulCRTCGenCntlData = MMREADULONG(hGDORageCRT->lpMMR, CRTC_GEN_CNTL);
        ulCRTCGenCntlTemp &= (~CRTC_GEN_CNTL_CrtcDisplayDis);
        ulCRTCGenCntlTemp |= CRTC_GEN_CNTL_CrtcVgaXoverscan;
        MMWRITEULONG(hGDORageCRT->lpMMR, CRTC_GEN_CNTL, ulCRTCGenCntlTemp);
    } else {
        // Set LCD_DATA register to index 1( LCD_GEN_CTRL).
        ulLCDIndexData =
        ulLCDIndex = MMREADULONG(hGDORageCRT->lpMMR, LCD_INDEX);
        ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
        ulLCDIndex |= LCD_INDEX_lcdGenCtrlReg;
        ulLCDIndex &= (~LCD_INDEX_Crtc2DisplayDis);
        MMWRITEULONG(hGDORageCRT->lpMMR, LCD_INDEX, ulLCDIndex);

        // Read LCD GEN CTRL data from LCD data register first.
        // set CRTC_RW_SELECT bit to 1 which makes register R/W go to
        // secondary CRTC, and turn on CRT.
        ulLCDGenCtrlData =
        ulLCDGenCtrlTemp = MMREADULONG(hGDORageCRT->lpMMR, LCD_DATA);
        ulLCDGenCtrlTemp |= (LCD_GEN_CTL_CrtcRWSelect | LCD_GEN_CTRL__CRT_ON);
        MMWRITEULONG(hGDORageCRT->lpMMR, LCD_DATA, ulLCDGenCtrlTemp);

        // enables the DAC compare which we will need later and
        // select data source for the monitor (secondary).
        ulDACCntlData=
        ulDACCntlTemp = MMREADULONG(hGDORageCRT->lpMMR, DAC_CNTL);
        ulDACCntlTemp &= (~DAC_CNTL__DAC_CMP_DIS);
        ulDACCntlTemp |= DAC_CNTL_Dac1ClkSel;
        MMWRITEULONG(hGDORageCRT->lpMMR, DAC_CNTL, ulDACCntlTemp);
    }

    //
    // Preserve Sequencer Data (Index 1) and allow CPU:CRT interleaved access
    // to video memory.
    //
    MMWRITEUCHAR(hGDORageCRT->lpMMR, SEQUENCER_INDEX,
                                     SEQUENCER_CLOCK_MODE, 0);
    ucSequencerTemp =
    ucSequencerData = MMREADUCHAR(hGDORageCRT->lpMMR, SEQUENCER_DATA, 0);
    ucSequencerTemp &= (~SEQUENCER_CLOCK_MODE__SEQ_MAXBW);
    MMWRITEUCHAR(hGDORageCRT->lpMMR, SEQUENCER_DATA, ucSequencerTemp, 0);

    lMaxLines = MMREADULONG(hGDORageCRT->lpMMR, CRTC_V_TOTAL_DISP);

    lMaxLines = ((lMaxLines & CRTC_V_TOTAL_DISP__CRTC_V_DISP_MASK)>>16);

    ulOverTopBottom = MMREADULONG(hGDORageCRT->lpMMR, OVR_WID_TOP_BOTTOM);

    ulOverClr = MMREADULONG(hGDORageCRT->lpMMR, OVR_CLR); //preserve Overscan color.

    MMWRITEULONG(hGDORageCRT->lpMMR, OVR_CLR, CRT_DETECT_COLOR);

    // If Overscan bottom width less than 2, write 2 to Overscan bottom width.
    if ((ulOverTopBottom & 0x1FF0000) < 2 )
    {
        MMWRITEULONG(hGDORageCRT->lpMMR, OVR_WID_TOP_BOTTOM,
                                             (ulOverTopBottom | 0x020000));
    }

    lCurrentLine = ( (MMREADULONG(hGDORageCRT->lpMMR, CRTC_CRNT_VLINE) &
                    CRTC_VLINE_CRNT_VLINE__CRTC_CRNT_VLINE_MASK) >> 16);

    while (lCurrentLine != 0)
    {
        lCurrentLine = ( (MMREADULONG(hGDORageCRT->lpMMR, CRTC_CRNT_VLINE) &
                        CRTC_VLINE_CRNT_VLINE__CRTC_CRNT_VLINE_MASK) >> 16);
    }

    while (bInDACCntlLoop == FALSE)
    {
        lCurrentLine = ( (MMREADULONG(hGDORageCRT->lpMMR, CRTC_CRNT_VLINE) &
                        CRTC_VLINE_CRNT_VLINE__CRTC_CRNT_VLINE_MASK) >> 16);
        while (lCurrentLine == (lMaxLines+2))
        {
            if ((MMREADULONG(hGDORageCRT->lpMMR, DAC_CNTL)) & DAC_CNTL__DAC_CMP_OUTPUT)
            {
                lOneCount++;
            }
            else
            {
                lZeroCount++;
            }
            lCurrentLine = ( (MMREADULONG(hGDORageCRT->lpMMR, CRTC_CRNT_VLINE) &
                            CRTC_VLINE_CRNT_VLINE__CRTC_CRNT_VLINE_MASK) >> 16);
            bInDACCntlLoop = TRUE;

        }// end while
    }

    // restore all the registers that we played with.
    MMWRITEULONG(hGDORageCRT->lpMMR, DAC_CNTL, ulDACCntlData);
    MMWRITEULONG(hGDORageCRT->lpMMR, OVR_CLR, ulOverClr);
    MMWRITEULONG(hGDORageCRT->lpMMR, OVR_WID_TOP_BOTTOM, ulOverTopBottom);
    MMWRITEUCHAR(hGDORageCRT->lpMMR, SEQUENCER_INDEX,
                                     SEQUENCER_CLOCK_MODE, 0);
    MMWRITEUCHAR(hGDORageCRT->lpMMR, SEQUENCER_DATA, ucSequencerData, 0);

    if ( hGDORageCRT->ulController == PRIMARY_CONTROLLER)
    {
        // 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);
        // Restore LCD GEN Control register
        MMWRITEULONG(hGDORageCRT->lpMMR, LCD_DATA, ulLCDGenCtrlData);
        // Restore CRTC GEN Control register.
        MMWRITEULONG(hGDORageCRT->lpMMR, CRTC_GEN_CNTL, ulCRTCGenCntlData);
    }
    else
    {
        // 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);
        // Restore LCD GEN Control register
        MMWRITEULONG(hGDORageCRT->lpMMR, LCD_DATA, ulLCDGenCtrlData);
        // Restore LCD Index register.
        MMWRITEULONG(hGDORageCRT->lpMMR, LCD_INDEX, ulLCDIndexData);
    }

    DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: Zero Count= %8x,  One Count= %8x",lZeroCount, lOneCount));
    // It is important to note here that although this algorthim seems
    // to produce good results it can not be considered a 100% accurate
    // way of determining CRT connectedness.  It does seem to be the best
    // algorithm in terms of detecting connectedness and minimizing visual
    // artifacts.
    if (lZeroCount < lOneCount)
    {
        DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRT is physically Connected (Software)"));
        return (TRUE);
    }
    else
    {
        DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRT is not physically Connected (Software)"));
        return(FALSE);
    }

} // End CRTSoftwareDetection

/******************************Public*Routine******************************\
* EPR 32286
* BOOL FAR CRTEdidDetection(GDO hGDO)
*
* This function will call the NO-BIOS code to get partial EDID from DDC CRT.
* This feature can be used to decide if a DDC monitor is attached.
*
* Step 1. Read EDID through DVI.
*         If EDID is read successfully and display type is CRT,
*         then return TRUE. Otherwise, go to Step 2.
* Step 2. Read EDID through regular CRT connector.
*
\**************************************************************************/

BOOL FAR CRTEdidDetection(HGDO hGDO)
{
    EDID_BUFFER   EdidQueryBuffer;

    LPGDO_RAGE_CRT  hGDORageCRT;
    hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;

    DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTEdidDetection - Entry"));

    //
    // Read partial EDID through DVI and then check device type.
    //

    hGDORageCRT->bREADEDIDFROMDVI = TRUE;

    if(DDC2DETQuery(hGDO, hGDORageCRT->hDDL,
                    (LPUCHAR)&EdidQueryBuffer.aucEdidDataBuffer))
    {
        // Check display type.
        if( CRTEDIDCHECKDISPLAYTYPE(hGDO, hGDORageCRT->hDDL, (LPUCHAR)&EdidQueryBuffer.aucEdidDataBuffer)
            == HW_DISPLAY_TYPE_CRT)
            return TRUE;
    }

    //
    // Read partial EDID through regular CRT connector.
    //
    hGDORageCRT->bREADEDIDFROMDVI = FALSE;

    if( DDC2DETQuery(hGDO, hGDORageCRT->hDDL,
                    (LPUCHAR)&EdidQueryBuffer.aucEdidDataBuffer))
    {
        return TRUE;
    }

    // Fail to get Edid from CRT.
    return FALSE;
}

/******************************Public*Routine******************************\
* VOID CRTDetectionImproved(HGDO hGDO)
*
* This routine assigns proper value to FORCE_DAC_DATA_SEL and
* FORCE_DAC_DATA to improve CRT detection.
*
\**************************************************************************/
VOID FAR
CRTDetectionImproved(HGDO hGDO)
{
    ULONG           ulLCDIndex;
    ULONG           ulLCDMiscCntlData;
    LPGDO_RAGE_CRT  hGDORageCRT;

    hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;

    // Set LCD_DATA register to index 14( LCD_MISC_CNTL).
    ulLCDIndex = MMREADULONG(hGDORageCRT->lpMMR, LCD_INDEX);
    ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
    ulLCDIndex |= LCD_INDEX_LcdMiscCntl;
    MMWRITEULONG(hGDORageCRT->lpMMR, LCD_INDEX, ulLCDIndex);

    // Read LCD MISC_CTRL data from LCD data register first.
    ulLCDMiscCntlData = MMREADULONG(hGDORageCRT->lpMMR, LCD_DATA);

    //
    // Assign "11" to FORCE_DAC_DATA_SEL.
    // Assign "52"(Hex) to FORCE_DAC_DATA.
    //
    ulLCDMiscCntlData &= (~LCD_MISC_CNTL__FORCE_DAC_DATA_SEL_MASK);
    ulLCDMiscCntlData |= 0x00C00000;

    ulLCDMiscCntlData &= (~LCD_MISC_CNTL__FORCE_DAC_DATA_MASK);
    ulLCDMiscCntlData |= 0x52000000;

    MMWRITEULONG(hGDORageCRT->lpMMR, LCD_DATA, ulLCDMiscCntlData);

} // End CRTDetectionImproved

/******************************Public*Routine******************************\
* BOOL CRTIsModeSupported(HGDO hGDO, LPDEVMODE_INFO lpMI, ULONG ulController)
*
* CRTIsModeSupported determines if the requsted mode is supported by the
* device.
*
\**************************************************************************/
BOOL FAR
CRTIsModeSupported(
    HGDO hGDO,
    LPDEVMODE_INFO lpMI,
    ULONG ulController
    )
{
    DALDEBUG((DALDBG_ENTRY_EXIT, "ATIRAGE.SYS! GDO-CRT: CRTIsModeSupported - Entry"));
    // some work obviously needs to be done here...
    return(TRUE);
} // end CRTIsModeSupported

/******************************Public*Routine********************************\
* VOID CRTSetMode(HGDO hGDO,
*                 LPDEVMODE_INFO lpMI,
*                 ULONG ulController,
*                 PFNGDOTIMINGS pfnDalSetAdjustmentTimings,
*                 LPHANDLE lpParameter)
*
* CRTSetMode is called to allow the GDO to set up some default values for
* certain paramaters.
\****************************************************************************/
VOID FAR
CRTSetMode(HGDO hGDO,
  LPDEVMODE_INFO lpMI,
  ULONG ulController,
  PFNDALTIMINGS pfnDalSetAdjustmentTimings,
  LPHANDLE lpParameter
  )
{

    LPGDO_RAGE_CRT  hGDORageCRT;

    hGDORageCRT = (LPGDO_RAGE_CRT)hGDO;

    DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-CRT: CRTSetMode - Entry"));

    //Save adjustment function for later use
    hGDORageCRT->pfnDalSetAdjustmentTimings = pfnDalSetAdjustmentTimings;
    hGDORageCRT->lpParameter = lpParameter;

    // fill in controller information. 0: Primary, otherwise: secondary.
    hGDORageCRT->ulController = ulController;

} // end CRTSetMode

/******************************Public*Routine********************************\
* VOID CRTPreModeChange(HGDO hGDO,
*                 LPDEVMODE_INFO lpMI)
* GDOPreModeChange performs any pre-mode configuration required by
* the controller before a mode change occurs.
*
\****************************************************************************/
VOID FAR
CRTPreModeChange(HGDO hGDO,
  LPDEVMODE_INFO lpMI
  )
{
    // there shouldn't be anything to do here...
}// CRTPreModeChange

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -