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

📄 msvd.c

📁 Maria2 CarTV 20060707 Tony
💻 C
📖 第 1 页 / 共 4 页
字号:
        #endif
            msLPFCtl(LPF_CTL_TV_NORMAL);
    }
}

#if( ENABLE_SECAM )
XDATA BYTE g_ucMSVDSecamCtl;
void msVDSecamColorCtl( BOOL bColorOn )
{
    BYTE ucData = 0x0C;
    BYTE ucBank;
    ucBank=msReadByte(BK0_00_REGBK);

    if( bColorOn )
        ucData = 0x00;
    msWriteByte( BK0_00_REGBK, REG_BANK3_COMB);

    msWriteByteMask( BK3_C5, ucData, 0x0C);
    msWriteByte(BK0_00_REGBK, ucBank);
}

void msVDSecamHandler(void)
{
    BYTE ucBank;

    if( g_ucVDSecamHandlerTimer )
        return;

    g_ucVDSecamHandlerTimer = 20;

    ucBank = msReadByte( BK0_00_REGBK);

    {
        WORD wVdStatus;

        wVdStatus = msVDGetSyncStatus();

        if(wVdStatus&VD_HSYNC_LOCKED)
        {
            msVDSecamColorCtl(_ENABLE);
        }
        else
        {
            msVDSecamColorCtl(_DISABLE);
        }
    }

    // Adjust Secam detect threoshold by burst mag
    // BurstMag>>4 = 6, 0B0A09 = 002160
    {
        BYTE ucBurstMag;
        DWORD dwData;
        BYTE ucNoiseMag;
        BYTE ucBurstPhsErr;
        BYTE ucSecamBurstPhsErr;


        ucBurstMag = msDSP_Std_GetBurstMag()>>4;
        dwData = ((DWORD)0x2160*(DWORD)ucBurstMag)/6;
        dwData = (dwData>>3)+ (g_dwVDSecamHandler_PreMagThl-(g_dwVDSecamHandler_PreMagThl>>3));

        ucBurstPhsErr = msDSP_Std_GetPhaseError();
        ucSecamBurstPhsErr = msDSP_Std_GetSecamPhaseError();

        ucNoiseMag = msDSP_Std_GetNoiseMag()>>1;

       	g_wVDSecamHandler_PreNoiseMag = ucNoiseMag;

        if ((g_VdInfo.ucVideoSystem == SIG_PAL) && (ucNoiseMag >= 0x10))
        {
            if (ucSecamBurstPhsErr <= 0x5B)
                g_ucVDSecamThdCnt ++ ;
            else if (ucSecamBurstPhsErr >= 0x60)
                g_ucVDSecamThdCnt -= 8 ;
            if (g_ucVDSecamThdCnt > 128) // negative
                g_ucVDSecamThdCnt = 0 ;
            else if (g_ucVDSecamThdCnt > 48)
                g_ucVDSecamThdCnt = 48 ;

        }
        else
                g_ucVDSecamThdCnt = 0 ;
        if( g_VdInfo.ucVideoSystem == SIG_SECAM )
        {
            if( ucNoiseMag < 3 )
            {
                if( dwData < 0x000590 )
                    dwData = 0x000590;
            }
            else if( ucNoiseMag < 10 )
            {
                if( dwData < 0x0010B0 )
                    dwData = 0x0010B0;
            }
            else if( (ucBurstMag<5 )||(ucNoiseMag >= 0x10) )
                dwData = 0x001BD0;
            g_dwVDSecamHandler_PreMagThl = dwData ;
            dwData -= 0x100;
        }
        else
        {
            if ( (g_ucVDSecamThdCnt > 24) || (ucNoiseMag >= 0x64) )  // notice ucNoiseMag is >>1
                    dwData = 0x00FFFF;
            else if ((ucBurstPhsErr > 0x20) && (ucNoiseMag < 3)) // Clean signal. Threshold for SECAM could be lower.
            {
                if (dwData < 0x000590)
                    dwData = 0x000590;
            }
            else if ((ucBurstPhsErr > 0x20) && (ucNoiseMag < 13)) // Clean signal. Threshold for SECAM could be lower.
            {
                if (dwData < 0x0010B0)
                    dwData = 0x0010B0;
            }
            else if (ucBurstPhsErr > 0x50) // Large burst phase error might come from SECAM signal but threshold shall not be too low if signal is not clean
            {
                if((ucBurstMag<5 )||(ucNoiseMag >= 0x13))
                    dwData = 0x001BD0;
            }
            else  // To avoid mis-judging PAL to SECAM (set higher threshold if burst phase error is small)
            {
                if( dwData < 0x001BD0 )
                    dwData = 0x001BD0;
            }
            g_dwVDSecamHandler_PreMagThl = dwData ;
        }
//        printf("  01====%x", ucBurstMag);
//        printf("  02====%x", ucBurstPhsErr);
//        printf("  03====%x", ucSecamBurstPhsErr);
//        printf("  04====%x", ucNoiseMag);
//        printf("  05====%x", g_ucVDSecamThdCnt);

//        printf("  01====%x", msDSP_Std_GetBurstMag());
//        printf("  02====%x", msDSP_Std_GetPhaseError());
//        printf("  03====%x", msDSP_Std_GetSecamPhaseError());
//        printf("  04====%x", msDSP_Std_GetNoiseMag());
//        printf("  05====%x", ((dwData>>8)&0xFF));
//        printMsg("\r\n");
        msWriteByte(BK0_00_REGBK, REG_BANK3_COMB);

        msWriteByte(BK3_A9, dwData&0xFF);
        msWriteByte(BK3_AA, (dwData>>8)&0xFF);
        msWriteByteMask(BK3_AB, (dwData>>16), 0x0F);
    }
    msWriteByte( BK0_00_REGBK, ucBank );
}
#endif

#ifdef VD_PATCH_001
// Call this function one time when no signal
BOOL msVD_Patch_001(void)
{
    if( (msVDSpecialRead( 0x00, BK2_01 )&0xF0) == 0x30 )
    {
        //msVDReset();
        msVD_FSM_Reset();
        return TRUE;
    }
    return FALSE;
}
#endif

#ifdef VD_PATCH_002
// Call this function when mode change!
BOOL msVD_Patch_002( BYTE ucCurVideoSystem )
{
    BOOL bResult = 0;

    if( ucCurVideoSystem == SIG_NTSC )
    {
        if( g_msVD_Patch002_LastVideoSystem != SIG_NTSC )
        {
            putstr("\r\nPatch002:-> NTSC");
            bResult = 1;
        }
    }

    if( bResult )
        msVD_FSM_Reset();

    g_msVD_Patch002_LastVideoSystem = ucCurVideoSystem;

    //printf("\r\nExit msVD_Patch_002 ->%d", bResult);
    return bResult;
}
#endif

#ifdef VD_PATCH_003
XDATA BYTE g_msVD_Patch003_StableCounter;
BOOL msVD_Patch_003(BYTE ucFlag)
{
    if( (ucFlag == 0)||( !msVDGetColorLockBit()) )
    {
        g_msVD_Patch003_StableCounter = 0;
    }
    else
    {
        if( (msVDSpecialRead( 0x0E, 0x01 ) > 0x70)
          &&(msDSP_Std_GetNoiseMag() < 0x20)) // Clean signal
        {
            ++ g_msVD_Patch003_StableCounter;
            if( g_msVD_Patch003_StableCounter > 3 )
            {
                g_msVD_Patch003_StableCounter = 0;
                putstr("\r\nPatch003: Phase Error!");
                msVD_FSM_Reset();
                return TRUE;
            }
        }
        else
        {
            g_msVD_Patch003_StableCounter = 0;
        }
    }
    return FALSE;
}
#endif

#ifdef VD_PATCH_004
XDATA g_msVD_Patch004_StableCounter;
void msVD_Patch_004( BOOL bEnable )
{
    if( bEnable )
    {
        int iTmp = msVDGetVTotal();
        if( abs(iTmp - msGetVerticalTotal()) >= 50  )
            ++ g_msVD_Patch004_StableCounter;
        else
            g_msVD_Patch004_StableCounter = 0;

        if( g_msVD_Patch004_StableCounter > 10 )
        {
            msVD_FSM_Reset();
            //msVDReset();
            g_msVD_Patch004_StableCounter = 0;
        }
    }
    else
    {
        g_msVD_Patch004_StableCounter = 0;
    }
}
#endif

#ifdef VD_PATCH_005
XDATA BYTE g_msVD_Patch005_VDAbnormalCounter;
void msVD_Patch_005( BYTE ucResetTime )
{
    if( ucResetTime )
    {
        g_msVD_Patch005_VDAbnormalCounter = 0;
        g_msVD_Patch005_Timer = ucResetTime;
    }
    else
    {
        BYTE ucScalerStatus;

        if( g_msVD_Patch005_Timer )
            return;
        g_msVD_Patch005_Timer = 10;

        ucScalerStatus = msVDCheckScalerStatus(0);
        if( ucScalerStatus != 0 )
        {
            g_msVD_Patch005_VDAbnormalCounter ++;
            if( g_msVD_Patch005_VDAbnormalCounter > 3 )
            {
                g_msVD_Patch005_VDAbnormalCounter = 0;
                putstr("\r\n=====VD output abnormally=====");
                // Reset VD
                msVD_FSM_Reset();
            }
        }
        else
        {
            g_msVD_Patch005_VDAbnormalCounter = 0;
        }
    }
}
#endif

void msVDCombLineBufferCtl( BYTE flag )
{
    BYTE ucBank = msReadByte( BK0_00_REGBK);

    msWriteByte( BK0_00_REGBK, REG_BANK3_COMB);

    if( flag == MSVD_COMB_LINE_BUFFER_CTL_HW_AUTO )
    {
        msWriteByteMask(BK3_50, 0x07, 0x07); // Line buffer free run mode: Auto
    }
    else
    {
        bit bCurLineLockStatus = 0;

        msWriteByte( BK0_00_REGBK, REG_BANK2_VD);

        // Get line lock status
        if( msVDDSPReadByte( 0x21 )&_BIT7 )
            bCurLineLockStatus = 1;

        msWriteByte(BK0_00_REGBK, REG_BANK3_COMB);
        if( bCurLineLockStatus ) // Current is line lock mode
        {
            if( (g_VdInfo.wVideoStatus&VD_FSC_TYPE) == VD_FSC_4XXX ) // PAL/NTSC443/SECAM
                msWriteByteMask(BK3_50, 0x05, 0x07); // Line buffer free run mode: Decided by register
            else // NTSC
                msWriteByteMask(BK3_50, 0x02, 0x07); // Line buffer free run mode: Decided by register
        }
        else // Current is not line lock mode
        {
            if( IsAVInUse()&&(g_VdInfo.ucVideoSystem == SIG_NTSC_443) )
            {
                msWriteByteMask(BK3_50, 0x06, 0x07); // Line buffer free run mode: Decided by register
                msWriteByte( BK3_52, 0x67 ); // H return position L
                msWriteByte( BK3_53, 0x04 ); // H return position H
            }
            else
            {
                WORD wHTotal;

                msWriteByte(BK0_00_REGBK, REG_BANK2_VD);
                wHTotal = msVDDSPRead2Bytes( DSP_3C );
                //printf("\r\nAFEC:HTotal:%d", wHTotal);

                msWriteByte(BK0_00_REGBK, REG_BANK3_COMB);
                if( wHTotal > 1151 )
                {
                    // Force 1151 pixel
                    msWriteByteMask(BK3_50, 0x06, 0x07); // Line buffer free run mode: Decided by register
                    msWriteByte( BK3_52, 0x7F ); // H return position L
                    msWriteByte( BK3_53, 0x04 ); // H return position H
                }
                else
                {
                    msWriteByteMask(BK3_50, 0x07, 0x07); // Line buffer free run mode: Auto
                    //msWriteByte( BK3_52, 0x8E ); // H return position L
                    //msWriteByte( BK3_53, 0x03 ); // H return position H
                }
            }
        }
    }

    msWriteByte( BK0_00_REGBK, ucBank );
}

void msVDNoiseHandlerInit(void)
{
    BYTE ucBank;
    WORD wTmp;

    ucBank = msReadByte( BK0_00_REGBK );
    msWriteByte( BK0_00_REGBK, REG_BANK2_VD );

    wTmp = msVDDSPRead2Bytes(DSP_10);

    wTmp |= 0x0080;
    msVDDSPWriteByte(DSP_10, wTmp);
    msVDDSPWriteByte(DSP_10+1, wTmp>>8);

    msVDNoiseHandlerReset();

    msWriteByte( BK0_00_REGBK, ucBank );
}

void msVDNoiseHandlerReset(void)
{
    BYTE ucBank;

    ucBank = msReadByte( BK0_00_REGBK);
    msWriteByte( BK0_00_REGBK, REG_BANK2_VD );

    g_ucNoiseDebounce = 0;
    bNoisy_Det = 0;
    bLastNoisyStatus = bNoisy_Det;

    msVDDSPWriteByte( DSP_84, msVDDSPReadByte(DSP_84)&(~_BIT1) ); // Clean mode
    msWriteByteMask( BK2_38_VSTROBE_LIMIT, 0x03, 0x07 );
    msWriteByteMask( BK2_97_EDGES_CLEAN_TH, 0x00, 0xC0 );
    msWriteByte( BK2_73_INI_CTRL2, 0x10 ); // V-Slice=2/8,H-Slice=4/8
    msWriteByte( BK2_79_656_HDES1, 0x17 );
    msWriteByte( BK2_7A, 0x20 );

    msWriteByte( BK0_00_REGBK, REG_BANK3_COMB );
    if( g_VdInfo.ucVideoSystem != SIG_SECAM )
    {
        msWriteByteMask( BK3_6F_MAX_CRMA, 0x00, 0x03 ); // Cb/Cr low pass mode
    }
    g_ucMSVDNoiseHandlerTimer = 200;

    msWriteByte( BK0_00_REGBK, ucBank );
}

void msVDNoiseHandler(void)
{
    BYTE ucBank;
    WORD wNoiseMag;

    if( g_ucMSVDNoiseHandlerTimer )
        return;

    g_ucMSVDNoiseHandlerTimer = 20;

    ucBank = msReadByte( BK0_00_REGBK);
    msWriteByte(BK0_00_REGBK, REG_BANK2_VD);

    // Noise detection ...

    //wNoiseMag = msDSP_Std_GetNoiseMag();
    wNoiseMag = msVDDSPReadByte( DSP_2A );
    if( g_ucNoiseDebounce < 30 )
    {
        if( wNoiseMag > 0x40 )
            g_ucNoiseDebounce += 4;
        else if( wNoiseMag >= 0x30 )
            g_ucNoiseDebounce += 2;
        else if( wNoiseMag > 0x28 )
            g_ucNoiseDebounce ++;
    }
    if( g_ucNoiseDebounce != 0 )
    {
        if( wNoiseMag < 0x10 )
        {
            if( g_ucNoiseDebounce < 6 )
                g_ucNoiseDebounce = 0;
            else
                g_ucNoiseDebounce -= 6;
        }
        else if( wNoiseMag < 0x20 )
            g_ucNoiseDebounce --;
    }

    if( g_ucNoiseDebounce >= 30 )
    {
        bNoisy_Det = 1;

⌨️ 快捷键说明

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