📄 msvd.c
字号:
#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 + -