📄 cem840x.c
字号:
(((Rate==32000) || (Rate==64000)) ? Q3_ASpdifStat1_32k : (((Rate==44100) || (Rate==88200)) ? Q3_ASpdifStat1_44k : Q3_ASpdifStat1_48k)); } CQuasar__WriteReg(pIDecoder, AUDIO_spdif_chstat1, HIWORD(this->ChannelStatus)); return Q_OK;}BOOL CEM840X__ReadSlaveDramToHost(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes){ UCHAR* pBytes = (UCHAR*)pData; DWORD i, timeout; CheckTransferSize(nBytes, TEXT("ReadDramSlave")) CheckDramChannel(DRAM_HOST, TEXT("ReadDramSlave start timeout !")) ProgramDramChannel(DRAM_HOST, addr, nBytes) for(i=0; i<nBytes/4; i++) { OSPutDword(CQuasar__ReadReg(pIDecoder, READ_3210), pBytes); pBytes += 4; } switch(nBytes % 4) { case 3: OSPutDword(CQuasar__ReadReg(pIDecoder, READ_210), pBytes); break; case 2: OSPutDword(CQuasar__ReadReg(pIDecoder, READ_10), pBytes); break; case 1: OSPutDword(CQuasar__ReadReg(pIDecoder, READ_0), pBytes); default: break; } CheckDramChannel(DRAM_HOST, TEXT("ReadDramSlave end timeout !")) return TRUE;}QRESULT CEM840X__SetDisplayFilter(IDecoder* pIDecoder, BYTE FilterId, BYTE* pData, DWORD dwSize){ IDecoder_WriteDM(pIDecoder, Q3.DICOM_Control.addr, IDecoder_ReadDM(pIDecoder, Q3.DICOM_Control.addr) | Q3CTRL1_FILTER_MASK); return Q_OK;}QRESULT CEM840X__ProgramVClk(IDecoder* pIDecoder, DWORD* pFreq){ return E_NOT_SUPPORTED;}QRESULT CEM840X__ReadLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD* pData){ return E_NOT_SUPPORTED;}QRESULT CEM840X__WriteLbcReg(IDecoder* pIDecoder, DWORD Address, DWORD Data){ return E_NOT_SUPPORTED;}QRESULT CEM840X__WriteDataToLBC(IDecoder* pIDecoder, IN DWORD Type, IN DWORD Addr, IN DWORD nBytes){ return E_NOT_SUPPORTED;}QRESULT CEM840X__ReadDataFromLBC(IDecoder* pIDecoder, IN DWORD Type, IN DWORD Addr, IN DWORD nBytes){ return E_NOT_SUPPORTED;}/////////////////////////////////////////////////////////////////////////// EM840x specific code for sigma TV encoder// EM840x supports only 8 bits, 601, TvMaster#include "ctvenc.h"void CSigmaTv__StartAccessReg(ITvEncoder* pITvEncoder);void CSigmaTv__EndAccessReg(ITvEncoder* pITvEncoder);void CEM840X__InitTvEncoder (ITvEncoder* pITvEncoder){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; DWORD SymbolTableSize; int i; CSigmaTv__StartAccessReg( pITvEncoder ); // clean all the registers ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG, 0x8000 | this->SigmaTvRegs[0] ); for (i=0;i<13; i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+3+i, 0 ); IDecoder_GetSymbolTable(this->m_pIDecoder, &this->pQ, &SymbolTableSize); this->SigmaTvRegs[0] = DACS_DISABLE; for (i=0;i<(sizeof(this->SigmaTvRegs)/sizeof(WORD)); i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs[i] ); CSigmaTv__EndAccessReg( pITvEncoder );}void CEM840X__ProgramTV( ITvEncoder* pITvEncoder, DWORD TvMaster, DWORD nbits, DWORD ccir, DWORD TvStandard, DWORD DacsEnable){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; DWORD Q3Ctrl3 = 0; int i; this->TvDacsEnable = DacsEnable; this->InvertField = (ccir & INVERT_FIELD_MASK)>>12; if(DacsEnable) this->SigmaTvRegs[0] = DACS_ENABLE;// SIGMATV_CONFIG 0x1F30 else this->SigmaTvRegs[0] = DACS_DISABLE;// SIGMATV_CONFIG 0x1F30 ITvEncoder_SetTVStandard(pITvEncoder, TvStandard); CSigmaTv__StartAccessReg( pITvEncoder ); for (i=0;i<(sizeof(this->SigmaTvRegs)/sizeof(WORD)); i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs[i] ); // programming correct VID_CTRL3 is resposability of CBoard... first Q/Tv Slave, second Tv/Q master Q3Ctrl3 = ITvEncoder_Read( pITvEncoder, Q3.DICOM_Control3.addr + 0x1000) & ~Q3CTRL3_TVSYNCS_ENABLE; if(TvMaster) // Enable HSync & VSync from SigmaTV Q3Ctrl3 |= Q3CTRL3_TVSYNCS_ENABLE | Q3CTRL3_VS_ENABLE | Q3CTRL3_HS_ENABLE; else { // HSync & VSync from SigmaTV are disabled // power off completely the TVencoder and VgaSync this->SigmaTvRegs[0] = PICT_SYNC_OFF;// SIGMATV_CONFIG 0x1F30 ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG, this->SigmaTvRegs[0] ); } ITvEncoder_Write(pITvEncoder, Q3.DICOM_Control3.addr + 0x1000, Q3Ctrl3 ); CSigmaTv__EndAccessReg( pITvEncoder );}#define SIGMATV_NTSC 0#define SIGMATV_PAL 1#define SIGMATV_PAL60 2#define SIGMATV_PALM 3#define SIGMATV_MASK 3QRESULT CEM840X__ProgramTVEx( ITvEncoder* pITvEncoder, DWORD TvMaster, DWORD nbits, DWORD CcirInvSE, DWORD TvStandard, DWORD DacsEnable, MASTERPARAMS* MP, DWORD Interlaced, DWORD Polarity){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; DWORD Q3Ctrl3 = 0; WORD HSyncAnalogOffset = 2; WORD HSyncTotalPixels, HSyncActivePixels, VSyncTotalLines, VSyncActiveLines; WORD VSyncOddField0, VSyncOddField1, VSyncEvenField0, VSyncEvenField1; WORD HSyncOddField0, HSyncOddField1, HSyncEvenField0, HSyncEvenField1; int i; this->TvDacsEnable = DacsEnable; this->InvertField = (CcirInvSE & INVERT_FIELD_MASK)>>12; CSigmaTv__StartAccessReg(pITvEncoder); this->SigmaTvRegs[0] = (DacsEnable ? DACS_ENABLE : DACS_DISABLE) | 8 | // custom sync ( (Interlaced == 0) ? 4:0 ); // progressive this->SigmaTvRegs[0] = (this->SigmaTvRegs[0] & ~SIGMATV_MASK); switch (TvStandard) { case evTvHdtvStandard_PAL: case evTvHdtvStandard_576P: this->SigmaTvRegs[0] |= SIGMATV_PAL; break; case evTvHdtvStandard_PAL60: this->SigmaTvRegs[0] |= SIGMATV_PAL60; break; case evTvHdtvStandard_PALM: this->SigmaTvRegs[0] |= SIGMATV_PALM; break; default://NTSC, 480P, Hdtv break; } this->CurrentTvStandard = TvStandard; HSyncTotalPixels = (WORD)MP->HSyncTotal*((nbits==8) ? 2:1); HSyncActivePixels = (WORD)MP->HSyncActive * ((nbits==8) ? 2:1); VSyncTotalLines = (WORD)MP->VSyncTotal/(Interlaced ? 2:1); VSyncActiveLines = (WORD)(Interlaced ? ((MP->VSyncActive + 1)/2) : MP->VSyncActive); // SIGMATV_HSYNC_PERIOD this->SigmaTvRegs[1] = HSyncTotalPixels; // SIGMATV_VSYNC_PERIOD - total lines per frame this->SigmaTvRegs[4] = (WORD)MP->VSyncTotal; if(Interlaced) { DWORD VSyncActIsOdd = MP->VSyncActive & 1; // for VSyncActive odd I will add a half line to every sync VSyncOddField0 = 1; VSyncOddField1 = (WORD)(VSyncOddField0 + MP->VSyncActive/2); VSyncEvenField0 = (WORD)(1 + MP->VSyncTotal/2); VSyncEvenField1 = (WORD)(VSyncEvenField0 + MP->VSyncActive/2 + VSyncActIsOdd); HSyncOddField0 = (WORD)(HSyncAnalogOffset + HSyncActivePixels/2); HSyncOddField1 = (WORD)(HSyncOddField0 + (VSyncActIsOdd * (HSyncTotalPixels/2))); HSyncEvenField0 = (WORD)(HSyncOddField0 + HSyncTotalPixels/2); HSyncEvenField1 = (WORD)(HSyncEvenField0 - (VSyncActIsOdd * (HSyncTotalPixels/2))); if( this->InvertField ) { // It starts with even field. Field even=bottom= nVSync goes low when nHSync is hi. VSyncOddField0 += (WORD)(MP->VSyncTotal/2 + 1); VSyncOddField1 += (WORD)(MP->VSyncTotal/2 + 1); VSyncEvenField0 -= (WORD)(MP->VSyncTotal/2); VSyncEvenField1 -= (WORD)(MP->VSyncTotal/2); } else { // It starts with odd field. Field odd=top= nVSync goes low when nHSync is low. } } else // progressive { VSyncOddField0 = 1; VSyncOddField1 = (WORD)(VSyncOddField0 + MP->VSyncActive); VSyncEvenField0 = 0; VSyncEvenField1 = 0; HSyncOddField0 = HSyncAnalogOffset; HSyncOddField1 = HSyncOddField0; HSyncEvenField0 = 0; HSyncEvenField1 = 0; } if(Polarity & HS_ACTIVE_LOW) { this->SigmaTvRegs[2] = HSyncAnalogOffset;// SIGMATV_HSYNC_0 this->SigmaTvRegs[3] = HSyncAnalogOffset + HSyncActivePixels;// SIGMATV_HSYNC_1 } else { this->SigmaTvRegs[2] = HSyncAnalogOffset + HSyncActivePixels;// SIGMATV_HSYNC_0 this->SigmaTvRegs[3] = HSyncAnalogOffset;// SIGMATV_HSYNC_1 } if(Polarity & VS_ACTIVE_LOW) { // the YOffset for analog and digital video is the same this->SigmaTvRegs[5] = VSyncOddField0;// SIGMATV_VSYNC_ODD_LINE_0 this->SigmaTvRegs[7] = VSyncOddField1;// SIGMATV_VSYNC_ODD_LINE_1 this->SigmaTvRegs[9] = VSyncEvenField0;// SIGMATV_VSYNC_EVEN_LINE_0 this->SigmaTvRegs[11]= VSyncEvenField1;// SIGMATV_VSYNC_EVEN_LINE_1 } else { // YOffset for analog video should be decreased by VSyncActive // SIGMATV_VSYNC_ODD_LINE_0 triggers the analog VSync signal for odd field this->SigmaTvRegs[5] = VSyncOddField1;// SIGMATV_VSYNC_ODD_LINE_0 this->SigmaTvRegs[7] = VSyncOddField0;// SIGMATV_VSYNC_ODD_LINE_1 this->SigmaTvRegs[9] = VSyncEvenField1;// SIGMATV_VSYNC_EVEN_LINE_0 this->SigmaTvRegs[11]= VSyncEvenField0;// SIGMATV_VSYNC_EVEN_LINE_1 } this->SigmaTvRegs[6] = HSyncOddField0;// SIGMATV_VSYNC_ODD_PIXEL_0 this->SigmaTvRegs[8] = HSyncOddField1;// SIGMATV_VSYNC_ODD_PIXEL_1 this->SigmaTvRegs[10] = HSyncEvenField0;// SIGMATV_VSYNC_EVEN_PIXEL_0 this->SigmaTvRegs[12] = HSyncEvenField1;// SIGMATV_VSYNC_EVEN_PIXEL_1 if(!TvMaster) { // HSync & VSync from SigmaTV are disabled // power off completely the TVencoder and VgaSync this->SigmaTvRegs[0] = PICT_SYNC_OFF;// SIGMATV_CONFIG 0x1F30 } // update the first set of registers to hardware for (i=0;i<(sizeof(this->SigmaTvRegs)/sizeof(WORD)); i++) ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs[i] ); CSigmaTv__EndAccessReg(pITvEncoder); // update the output format to hardware ITvEncoder_SetCurrentYcYuvRgb(pITvEncoder, this->YcYuvRgb); // programming correct VID_CTRL3 is resposability of CBoard... first Q/Tv Slave, second Tv/Q master Q3Ctrl3 = IDecoder_ReadDM( this->m_pIDecoder, Q3.DICOM_Control3.addr) & ~Q3CTRL3_TVSYNCS_ENABLE; if(TvMaster) // Enable HSync & VSync from SigmaTV Q3Ctrl3 |= Q3CTRL3_TVSYNCS_ENABLE | Q3CTRL3_VS_ENABLE | Q3CTRL3_HS_ENABLE; IDecoder_WriteDM(this->m_pIDecoder, Q3.DICOM_Control3.addr, Q3Ctrl3 ); ITvEncoder_EnableMacrovision(pITvEncoder, CURRENT_MACROVISION); return Q_OK;}void CEM840X__DisableTVBlackout(ITvEncoder* pITvEncoder){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; CSigmaTv__StartAccessReg( pITvEncoder ); this->SigmaTvRegs[0] = (this->SigmaTvRegs[0] & ~DACS_MASK) | DACS_ENABLE; ITvEncoder_Write( pITvEncoder,SIGMATV_CONFIG, this->SigmaTvRegs[0]); CSigmaTv__EndAccessReg( pITvEncoder );}void CEM840X__InitVtable(IDecoder* pIDecoder){ CQuasar *this = (CQuasar*) pIDecoder; this->VTable.SetMicrocode = CEM840X__SetMicrocode; this->VTable.InitPtsFifo = CEM840X__InitPtsFifo; this->VTable.PtsFifoEmptiness = CEM840X__PtsFifoEmptiness; this->VTable.WritePTS = CEM840X__WritePTS; this->VTable.WritePCR = CEM840X__WritePCR; this->VTable.SetPIODir = CEM840X__SetPIODir; this->VTable.WritePIO = CEM840X__WritePIO; this->VTable.ReadPIO = CEM840X__ReadPIO; this->VTable.SetAudioSampleRate = CEM840X__SetAudioSampleRate; this->VTable.ReadDramSlave = CEM840X__ReadSlaveDramToHost; this->VTable.InitPropertySet = CEM840X__InitPropertySet; this->VTable.SetProperty = CEM840X__SetProperty; this->VTable.GetProperty = CEM840X__GetProperty; this->VTable.SetDisplayFilter = CEM840X__SetDisplayFilter; this->VTable.ProgramVClk = CEM840X__ProgramVClk; this->VTable.ReadLbcReg = CEM840X__ReadLbcReg; this->VTable.WriteLbcReg = CEM840X__WriteLbcReg; this->VTable.WriteDataToLBC = CEM840X__WriteDataToLBC; this->VTable.ReadDataFromLBC = CEM840X__ReadDataFromLBC;}void CEM840X__TvInitVtable(ITvEncoder* pITvEncoder){ CTvEncoder *this = (CTvEncoder*) pITvEncoder; this->VTable.InitTvEncoder = CEM840X__InitTvEncoder; this->VTable.ProgramTV = CEM840X__ProgramTV; this->VTable.ProgramTVEx = CEM840X__ProgramTVEx; this->VTable.DisableTVBlackout = CEM840X__DisableTVBlackout;}#undef DEFINE_ENTRY#define DEFINE_ENTRY(Symbol) Q3.Symbol.str = #Symbol;#include "symbols.h"QRESULT InitializeSymbolsTable( IDecoder* pIDecoder ){ SymbolEntry* pSymbolEntry; int i; CommonSymbols pSymbolEntry = (SymbolEntry*)&Q3; for( i=0;i<( sizeof(Q3)/sizeof(SymbolEntry) );i++ ) { if( !CQuasar__SearchSymbol(pIDecoder, pSymbolEntry->str, &pSymbolEntry->addr)) { pSymbolEntry->addr = 0; QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("Symbol %s not found"), pSymbolEntry->str )); OSsprintf(g_InfoError, TEXT("Symbol %s not found"), pSymbolEntry->str ); return E_GET_SYMBOLS_FAILED; } pSymbolEntry++; } return Q_OK;}#endif // EM840X_OBJECT/////////////////////////////////////////////////////////////////////////////////////////// code for EM840X_OBJECT define only//#if defined EM840X_OBJECT && !defined EM847X_OBJECTvoid CQuasar__InitVtable(IDecoder* pIDecoder){ CEM840X__InitVtable(pIDecoder);}void CSigmaTv__InitVtable(ITvEncoder* pITvEncoder){ CEM840X__TvInitVtable(pITvEncoder);}#endif // EM840X_OBJECT & !EM847X_OBJECT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -