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

📄 cem847x.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
		return Q_OK;	}	return Q_FAIL;}/****f* HwLib/CQuasar__ReadMasterDramToHost * USAGE *	NOT PRESENT in IDecoder interface *	BOOL CQuasar__ReadMasterDramToHost(IDecoder* pIDecoder, IN DWORD addr, IN DWORD PhysAddr, IN DWORD nBytes, IN DWORD reverse) * DESCRIPTION *	CQuasar__ReadMasterDramToHost writes "nBytes" from system memory "pData" to "addr" in DRAM *	memory using PCI bus master. "pData" must point to a physical contiguous buffer of nBytes, *	otherwise the system hangs. *	"nBytes" can be any value between 1 and 0xFFFF (transfer size less than 64 kBytes). *	It is not called in the actual implementation of library in order to not conflict with *	microcode, that uses PCI bus master to transfer the compressed data. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD addr - DRAM address where to start writing *	IN DWORD PhysAddr - physical address of the system buffer to write *	IN DWORD nBytes - number of bytes to write *	IN DWORD reverse - select order of bytes in DWORD * RETURN VALUE *	The return value is FALSE if IDecoder_WriteDramSlave timeout. * SEE ALSO *	IDecoder_WriteDramSlave/********************************************************************************************/BOOL CQuasar__ReadMasterDramToHost(IDecoder* pIDecoder, IN DWORD addr, IN DWORD PhysAddr, IN DWORD nBytes, IN DWORD reverse){	DWORD timeout;	CheckTransferSize(nBytes, TEXT("ReadDramMaster"))	CheckDramChannel(DRAM_HOST, TEXT("ReadDramMaster start timeout !"))	// Set up PCI master to write in system memory and start	CQuasar__WriteReg(pIDecoder, DRAM_portmux,		(CQuasar__ReadReg(pIDecoder, DRAM_portmux) & ~DRAM_portmux_CHR0_Mask) | DRAM_portmux_CHR0_to_Port1);	CQuasar__WriteReg(pIDecoder, QPM_master_xfer_enable, 1);	CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_lo, PhysAddr & 0xFFFF);	CQuasar__WriteReg(pIDecoder, QPM_to_host_addr_hi, PhysAddr >> 16);	CQuasar__WriteReg(pIDecoder, QPM_to_host_xfer_cnt, nBytes);	// select Port1 for Master Write to Host	CQuasar__WriteReg(pIDecoder, QPM_to_host_master_ena, Port1_to_MasterWriteToHost);	ProgramDramChannel(DRAM_HOST, addr, nBytes)	CheckDramChannel(DRAM_HOST, TEXT("ReadDramMaster end timeout !"))	return TRUE;}/****f* HwLib/IDecoder_ReadDramSlave * USAGE *	BOOL IDecoder_ReadDramSlave(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes) *	BOOL CEM840X__ReadSlaveDramToHost(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes) *	BOOL CEM847X__ReadSlaveDramToHost(IDecoder* pIDecoder, IN DWORD addr, OUT DWORD* pData, IN DWORD nBytes) * DESCRIPTION *	IDecoder_ReadDramSlave reads "nBytes" starting from "addr" in DRAM memory to system memory "pData". *	"nBytes" can be any value between 1 and 0xFFFF (transfer size less than 64 kBytes). *	The data is read in chunks of four bytes = one dword to increase the speed.  *	It is called by CQuasar__LoadMicroCode, CQuasar__GetOneLineRGB, CQuasar__CloseCaptionInterrupt, *	IDecoder_TestDram, IDecoder_YannTestDRAM * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD addr - DRAM address from where to start reading *	OUT DWORD* pData - address of the system buffer where to put the read data *	IN DWORD nBytes - number of bytes to read * RETURN VALUE *	The return value is FALSE if IDecoder_ReadDramSlave timeout. * SEE ALSO *	IDecoder_WriteDramSlave/********************************************************************************************/BOOL CEM847X__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 !"))	// select Port1 for Slave Write to Host	CQuasar__WriteReg(pIDecoder, QPM_to_host_master_ena, Port1_to_SlaveWriteToHost);	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;}/////////////////////////////////////////////////////////////////////////// EM847x specific code for sigma TV encoder// EM8470 supports 8/16 bits, 601,656 TvMaster/Slave#include "ctvenc.h"void CSigmaTv__StartAccessReg(ITvEncoder* pITvEncoder);void CSigmaTv__EndAccessReg(ITvEncoder* pITvEncoder);void CEM847X__InitTvEncoder (ITvEncoder* pITvEncoder){	CTvEncoder *this = (CTvEncoder*) pITvEncoder;	DWORD SymbolTableSize;	int i;	IDecoder_GetSymbolTable(this->m_pIDecoder, &this->pQ, &SymbolTableSize);	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 );	for (i=0;i<(sizeof(this->SigmaTvRegs35)/sizeof(WORD)); i++)		ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs35[i] );	ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG + 0xF, 0 );// test register	this->SigmaTvRegs[0] = Q4_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 CEM847X__SetCurrentYcYuvRgb(ITvEncoder* pITvEncoder, DWORD YcYuvRgb){	CTvEncoder *this = (CTvEncoder*) pITvEncoder;	this->YcYuvRgb = YcYuvRgb;	this->SigmaTvRegs[0] &= ~0x300;		// clear mask	switch(this->YcYuvRgb)	{	case COMPONENT_YUV:		this->SigmaTvRegs[0] |= 0x200;	// select component output		this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070) | 0x0070;// select YUV		break;	case COMPONENT_RGB:		this->SigmaTvRegs[0] |= 0x200;	// select component output		this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070) | 0x0020;// select RGB sync-on-green		break;	case COMPONENT_RGB_SCART:		this->SigmaTvRegs[0] |= 0x200;	// select component output		this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070) | 0x0010;// select RGB scart		break;	case OUTPUT_OFF:		this->SigmaTvRegs[0] |= 0x000;	// Dacs off		break;	case COMPOSITE:	default:		this->SigmaTvRegs[0] |= 0x100;	// select YC output		this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x0070);		break;	}	// update to hardware	CSigmaTv__StartAccessReg(pITvEncoder);	ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG, this->SigmaTvRegs35[0] );	ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+1, this->SigmaTvRegs35[1] );	ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG, this->SigmaTvRegs[0] );	CSigmaTv__EndAccessReg(pITvEncoder);} void CEM847X__ProgramTV( ITvEncoder* pITvEncoder, DWORD TvMaster, DWORD nbits, 						 DWORD ccir, DWORD TvStandard, DWORD DacsEnable){	CTvEncoder *this = (CTvEncoder*) pITvEncoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	DWORD Q3Ctrl3 = 0;	int i;	this->InvertField = (ccir & INVERT_FIELD_MASK)>>12;	this->TvDacsEnable = DacsEnable;	if(DacsEnable)		this->SigmaTvRegs[0] = Q4_DACS_ENABLE;	else		this->SigmaTvRegs[0] = Q4_DACS_DISABLE;	// update the values for TvStandard and take care of macrovision too	ITvEncoder_SetTVStandard(pITvEncoder, TvStandard);	if( TvStandard == SET_NTSC )		this->SigmaTvRegs35[1] = this->SigmaTvRegs35[1] & ~0x0800;	else		this->SigmaTvRegs35[1] = this->SigmaTvRegs35[1] | 0x0800;	if( nbits >= 16 )	// HD	{		this->SigmaTvRegs[0] |= 0x8;	// 16 bits - HD		this->SigmaTvRegs[1] /= 2;// SIGMATV_HSYNC_PERIOD			0x1F31		this->SigmaTvRegs[2] /= 2;// SIGMATV_HSYNC_0				0x1F32		this->SigmaTvRegs[3] /= 2;// SIGMATV_HSYNC_1				0x1F33		this->SigmaTvRegs[6] /= 2;// SIGMATV_VSYNC_ODD_PIXEL_0	0x1F36		this->SigmaTvRegs[8] /= 2;// SIGMATV_VSYNC_ODD_PIXEL_1	0x1F38		this->SigmaTvRegs[10] /= 2;// SIGMATV_VSYNC_EVEN_PIXEL_0	0x1F3A		this->SigmaTvRegs[12] /= 2;// SIGMATV_VSYNC_EVEN_PIXEL_1	0x1F3C	}	else	// SD		this->SigmaTvRegs[0] &= ~0x8;	// 8 bits	if(TvMaster)		this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x0000;	else	{		if((ccir & CCIR_MASK) == CCIR_601)			this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x8;		else			this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0xC;	}	// update the output format to hardware	ITvEncoder_SetCurrentYcYuvRgb(pITvEncoder, this->YcYuvRgb);	// update the first set of registers to hardware	CSigmaTv__StartAccessReg(pITvEncoder);	for (i=0;i<(sizeof(this->SigmaTvRegs)/sizeof(WORD)); i++)		ITvEncoder_Write( pITvEncoder, SIGMATV_CONFIG+i, this->SigmaTvRegs[i] );	CSigmaTv__EndAccessReg(pITvEncoder);	// programming correct VID_CTRL3 is resposability of CBoard... first Q/Tv Slave, second Tv/Q master	Q3Ctrl3 = IDecoder_ReadDM(this->m_pIDecoder, pQ4->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, pQ4->DICOM_Control3.addr, Q3Ctrl3 );}// 480p/59.94Hz 720 480 5994 31469 858 40 54 44 525 5 11 28WORD SigmaTv_480Pslave656[]=	{1716,   0,  0,  525,  0,  0,   0,  0,   0,   0,   0,   0};WORD SigmaTv_480Pmaster[]=		{1716,   2,108,  525,  1,  2,  12,  2, 263, 108, 274, 108};// 720p/60Hz 1280 720 6000 45000 1650 0 80 0 750 0 0 0WORD SigmaTv_720Pslave656_G[]=	{1650,1580,300,  750, 26,  1, 746,  0, 263, 826, 263, 825};//80,260WORD SigmaTv_720Pmaster[]=		{1650,   1, 80,  750,  1,  1,   2,  0, 263, 826, 264, 825};//80,260// 1080i/59.94Hz 1920 1080 5994 33716 2199 0 88 116 1125 0 0 0WORD SigmaTv_1080Islave656_GI[]={2200,2156,236, 1125, 21,  1,1124,  0, 584,1101, 561,1100};//88,132WORD SigmaTv_1080Imaster[]=		{2200,   1, 88, 1125,  1,  1,   2,  0, 563,1101, 564,1100};//88,132// the next 3 registers are used for the analog signal on HDTV#define SIGMATV_HSYNC_WIDTH		0x1F34#define SIGMATV_VSYNC_START		0x1F35#define SIGMATV_VSYNC_WIDTH		0x1F36#define SIGMATV_NTSC	0#define SIGMATV_PAL		1#define SIGMATV_PAL60	2#define SIGMATV_PALM	3#define SIGMATV_MASK	3QRESULT CEM847X__ProgramTVEx( ITvEncoder* pITvEncoder, DWORD TvMaster, DWORD nbits, 	 DWORD CcirInvSE, DWORD TvStandard, DWORD DacsEnable, MASTERPARAMS* MP, DWORD Interlaced, DWORD Polarity){	CTvEncoder *this = (CTvEncoder*) pITvEncoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	DWORD Q3Ctrl3 = 0;	WORD HSyncAnalogOffset = 0;	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);	// change register set	ITvEncoder_Write(pITvEncoder, SIGMATV_CONFIG, this->SigmaTvRegs[0] | 0x4000);	if(TvStandard == evTvHdtvStandard_1080I)//if( MP->h == 1080 )	// 1080I	{		// HSyncAnalogOffset + PostHSync should be 192 to have a nice sync		// for the analog signal		HSyncAnalogOffset = 44;	// PostHSync is 148		ITvEncoder_Write(pITvEncoder, SIGMATV_HSYNC_WIDTH, 88);		ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_START, 132);		ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_WIDTH, 880);	}	else if(TvStandard == evTvHdtvStandard_720P)//if( MP->h == 720 )	// 720P	{		// HSyncAnalogOffset + PostHSync should be 260 to have a nice sync		// for the analog signal		HSyncAnalogOffset = 40;	// PostHSync is 220		ITvEncoder_Write(pITvEncoder, SIGMATV_HSYNC_WIDTH, 80);		ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_START, 260);		ITvEncoder_Write(pITvEncoder, SIGMATV_VSYNC_WIDTH, 1280);	}	else	{		HSyncAnalogOffset = 0;		ITvEncoder_Write(pITvEncoder, SIGMATV_HSYNC_WIDTH, MP->HSyncActive);	}	// update values for Hdtv mode	this->SigmaTvRegs[0] = (DacsEnable ? Q4_DACS_ENABLE : Q4_DACS_DISABLE) |		( (nbits == 8) ? 0:8 ) |			//*** high res		( (Interlaced == 0) ? 4:0 );		// progressive//		| ( (MP->h == 576) ? 1:0 );			// Pal	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;	if(TvMaster)		this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x0000;	else	{		if((CcirInvSE & CCIR_MASK) == CCIR_601)			this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0x8;		else			this->SigmaTvRegs35[1] = (this->SigmaTvRegs35[1] & ~0x000C) | 0xC;	}	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);			VSyncEven

⌨️ 快捷键说明

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