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

📄 rio.cpp

📁 一个简单漂亮的C++编写的mp3播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		COMMANDOUT( B_01110000, B_00000000, B_00000100 );
		COMMANDOUT( B_10100000, B_00001100, B_00000100 );

		OUTPORT( m_iPortControl, B_00000000 );
		IODELAY( m_lTimeIODelayTx );

		OUTPORT( m_iPortControl, B_00000100 );
		IODELAY( m_lTimeIODelayTx );
	}

	// send 32K in 512 byte chunks
	UCHAR* pauc = (UCHAR*)pv;
	for( iA=0; iA<(32768/512); ++iA, pauc+=512 )
	{
		ulPos512ByteBlock = ((ULONG)uiPos32KBlock * 32768 + (ULONG)iA * 512) / 512;
		ulPosLo = ulPos512ByteBlock & 0xff;

		if ( m_bUseExternalFlash )
		{
			ulPosHi = POS_BANK_EXTERNALFLASH;
			ulPosMid = (ulPos512ByteBlock & 0xff00) >> 8;
		}
		else if ( m_bSpecialEdition )
		{
			ulPosHi	 = ulPos512ByteBlock / 32768;
			ulPosMid = (ulPos512ByteBlock & 0x7f00) >> 8;
		}
		else
		{
			ulPosHi = ulPos512ByteBlock / 16384;
			ulPosMid = (ulPos512ByteBlock & 0x3f00) >> 8;
		}

		// issue upload 512 byte block command
		COMMANDOUT( B_10101011, B_00001100, B_00000100 );
		COMMANDOUT( ulPosHi, B_00000000, B_00000100 );
		COMMANDOUT( B_10100001, B_00001100, B_00000100 );
		COMMANDOUT( B_10000000, B_00000000, B_00000100 );
		COMMANDOUT( B_10100010, B_00001100, B_00000100 );
		COMMANDOUT( B_00000000, B_00000000, B_00000100 );
		COMMANDOUT( ulPosLo, B_00000000, B_00000100 );
		COMMANDOUT( ulPosMid, B_00000000, B_00000100 );

		COMMANDOUT( B_10100011, B_00001100, B_00000100 );

		// create checksum of 512 byte block
		USHORT usChecksum = 0;
		USHORT* paus = (USHORT*)pauc;
		for( iB=0; iB<(512/sizeof(short)); ++iB, ++paus )
			usChecksum -= *paus;

		// clock out data
		#if defined(_WINNT)
		{
			DWORD dwSizeReturn;
			DeviceIoControl( m_hDriver, RIOIO_IOCTL_WRITEBLOCK, pauc, 512,
				NULL, 0, &dwSizeReturn, NULL );
		}
		#else
			UCHAR* pauc2 = pauc;
			for( iB=0; iB<512; ++iB, ++pauc2 )
			{
				OUTPORT( m_iPortData, (*pauc2) );

				if ( !(iB & 1) )
					OUTPORT( m_iPortControl, B_00000000 );
				else
					OUTPORT( m_iPortControl, B_00000100 );

				IODELAY( 1 );
			}
		#endif

		// prepare end of block
		CEnd512ByteBlock cEnd512ByteBlock;
		memset( &cEnd512ByteBlock, 0, sizeof(CEnd512ByteBlock) );
		cEnd512ByteBlock.m_usChecksum = usChecksum;
		if ( uiPos32KBlockNext == 0xffff )
		{
			cEnd512ByteBlock.m_ulPos512ByteBlockNextMult256 = 0xffffffff;
			cEnd512ByteBlock.m_ucPos8192KBlockNext1 = 0xff;
			cEnd512ByteBlock.m_ucPos8192KBlockNext2 = 0xff;
		}
		else
		{
			cEnd512ByteBlock.m_ulPos512ByteBlockNextMult256 = ((ULONG)uiPos32KBlockNext * 64) * 256;

			if ( !m_bSpecialEdition )
			{
				cEnd512ByteBlock.m_ucPos8192KBlockNext1 = uiPos32KBlockNext / 256;
				cEnd512ByteBlock.m_ucPos8192KBlockNext2 = uiPos32KBlockNext / 256;
			}
			else
			{
				cEnd512ByteBlock.m_ucPos8192KBlockNext1 = uiPos32KBlockNext / 512;
				cEnd512ByteBlock.m_ucPos8192KBlockNext2 = uiPos32KBlockNext / 512;
			}

			if ( m_bUseExternalFlash )
			{
				cEnd512ByteBlock.m_ulPos512ByteBlockNextMult256	+= 0x01000000;
				cEnd512ByteBlock.m_ucPos8192KBlockNext1 = 0;
				cEnd512ByteBlock.m_ucPos8192KBlockNext2 = 0;
			}
		}

		if ( uiPos32KBlockPrev == 0xffff )
		{
			cEnd512ByteBlock.m_ulPos512ByteBlockPrevMult256 = 0xffffffff;
			cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = 0xff;
			cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = 0xff;
			cEnd512ByteBlock.m_usPos32KBlockPrevMult256 = 0xffff;
		}
		else
		{
			cEnd512ByteBlock.m_ulPos512ByteBlockPrevMult256 = ((ULONG)uiPos32KBlockPrev * 64) * 256;

			if ( !m_bSpecialEdition )
			{
				cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = uiPos32KBlockPrev / 256;
				cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = uiPos32KBlockPrev / 256;
			}
			else
			{
				cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = uiPos32KBlockPrev / 512;
				cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = uiPos32KBlockPrev / 512;
			}

			if ( m_bUseExternalFlash )
			{
				cEnd512ByteBlock.m_ulPos512ByteBlockPrevMult256	+= 0x01000000;
				cEnd512ByteBlock.m_ucPos8192KBlockPrev1 = 0;
				cEnd512ByteBlock.m_ucPos8192KBlockPrev2 = 0;
			}

			cEnd512ByteBlock.m_usPos32KBlockPrevMult256 = uiPos32KBlockPrev * 256;
		}

		// output end of block
		#if defined(_WINNT)
		{
			DWORD dwSizeReturn;
			DeviceIoControl( m_hDriver, RIOIO_IOCTL_WRITEBLOCK, &cEnd512ByteBlock,
				sizeof(CEnd512ByteBlock), NULL, 0, &dwSizeReturn, NULL );
		}
		#else
			pauc2 = (UCHAR*)&cEnd512ByteBlock;
			for( iB=0; iB<sizeof(CEnd512ByteBlock); ++iB, ++pauc2 )
			{
				OUTPORT( m_iPortData, (*pauc2) );

				if ( !(iB & 1) )
					OUTPORT( m_iPortControl, B_00000000 );
				else
					OUTPORT( m_iPortControl, B_00000100 );

				IODELAY( 1 );
			}
		#endif

		// end of tx
		COMMANDOUT( B_10100001, B_00001100, B_00000100 );
		COMMANDOUT( B_00010000, B_00000000, B_00000100 );

		WAITACK();

		COMMANDOUT( B_10100001, B_00001100, B_00000100 );
		COMMANDOUT( B_01110000, B_00000000, B_00000100 );
		COMMANDOUT( B_10100000, B_00001100, B_00000100 );

		OUTPORT( m_iPortControl, B_00000000 );
		IODELAY( m_lTimeIODelayTx );

		OUTPORT( m_iPortControl, B_00000100 );
		IODELAY( m_lTimeIODelayTx );
	}

	return TRUE;
}

// tx 32K block
BOOL CRio::Tx32KBlock( void* pv, UINT uiPos32KBlock, UINT uiPos32KBlockPrev,
	UINT uiPos32KBlockNext )
{
	int iRetry = 0;
	while( iRetry < MAX_RETRY )
	{
		if ( Tx32KBlockRetry(pv, uiPos32KBlock, uiPos32KBlockPrev, uiPos32KBlockNext) )
			return TRUE;

		DELAY( CLOCK_SECOND );
		++iRetry;
	}

	LogError( CRIO_ERROR_TXBLOCKRETRY, "too many retries for tx block" );

	return FALSE;
}

// rx 32K block retry
BOOL CRio::Rx32KBlockRetry( void* pv, UINT uiPos32KBlock )
{
	ULONG ulPos512ByteBlock;
	ULONG ulPosHi;
	ULONG ulPosMid;
	ULONG ulPosLo;
	int iA, iB;

	// io intro
	if ( !IOIntro() )
		return FALSE;

	// get 32K in 512 byte chunks
	UCHAR* pauc = (UCHAR*)pv;
	for( iA=0; iA<(32768/512); ++iA, pauc+=512 )
	{
		ulPos512ByteBlock = ((ULONG)uiPos32KBlock * 32768 + (ULONG)iA * 512) / 512;
		ulPosLo = ulPos512ByteBlock & 0xff;

		if ( m_bUseExternalFlash )
		{
			ulPosHi = POS_BANK_EXTERNALFLASH;
			ulPosMid = (ulPos512ByteBlock & 0xff00) >> 8;
		}
		else if ( m_bSpecialEdition )
		{
			ulPosHi	 = ulPos512ByteBlock / 32768;
			ulPosMid = (ulPos512ByteBlock & 0x7f00) >> 8;
		}
		else
		{
			ulPosHi = ulPos512ByteBlock / 16384;
			ulPosMid = (ulPos512ByteBlock & 0x3f00) >> 8;
		}

		// issue download 512 byte block command
		COMMANDOUT( B_10101011, B_00001100, B_00000100 );
		COMMANDOUT( ulPosHi, B_00000000, B_00000100 );
		COMMANDOUT( B_10100001, B_00001100, B_00000100 );
		COMMANDOUT( B_00000000, B_00000000, B_00000100 );
		COMMANDOUT( B_10100010, B_00001100, B_00000100 );
		COMMANDOUT( B_00000000, B_00000000, B_00000100 );
		COMMANDOUT( ulPosLo, B_00000000, B_00000100 );
		COMMANDOUT( ulPosMid, B_00000000, B_00000100 );

		WAITACK();

		COMMANDOUT( B_10100000, B_00001100, B_00000100 );

		// clock in data
		#if defined(_WINNT)
		{
			DWORD dwSizeReturn;
			DeviceIoControl( m_hDriver, RIOIO_IOCTL_READBLOCK, pauc, 512,
				pauc, 512, &dwSizeReturn, NULL );
		}
		#else
			for( iB=0; iB<512; ++iB )
				*(pauc+iB) = GetDataByte();
		#endif

		// clock in 16 bytes which are ignored
		for( iB=0; iB<16; ++iB )
			GetDataByte();

		// delay
		WAITACK();
	}

	return TRUE;
}

// rx 32K block
BOOL CRio::Rx32KBlock( void* pv, UINT uiPos32KBlock )
{
	int iRetry = 0;
	while( iRetry < MAX_RETRY )
	{
		if ( Rx32KBlockRetry(pv, uiPos32KBlock) )
			return TRUE;

		DELAY( CLOCK_SECOND );
		++iRetry;
	}

	LogError( CRIO_ERROR_RXBLOCKRETRY, "too many retries for rx block" );

	return FALSE;
}

// mark bad blocks
BOOL CRio::MarkBadBlocks( BOOL (*pfProgress)(int iPos, int iCount, void* cookie), void* cookie)
{
	// create temp block
	UCHAR* paucBlock;
	NEWBLOCK( paucBlock );

	// block count
	USHORT usPos32KBlockEnd;
	if ( m_bUseExternalFlash )
		usPos32KBlockEnd = m_uiCount32KBlockAvailableExternal;
	else
		usPos32KBlockEnd = m_bSpecialEdition ? CRIO_COUNT_32KBLOCKIN64M : CRIO_COUNT_32KBLOCKIN32M;

	// assume directory block is ok
	m_cDirBlock.m_auc32KBlockUsed[ 0 ] = CRIO_ID_32KBLOCK_FREE;

	// process all blocks (except directory block)
	int iCount32KBlockBad = 0;
	USHORT usPos32KBlock;
	for( usPos32KBlock=1; usPos32KBlock<usPos32KBlockEnd; ++usPos32KBlock )
	{
		UINT uiB;

		// progress callback
		if ( pfProgress )
		{
			if ( !pfProgress(usPos32KBlock, usPos32KBlockEnd, cookie) )
			{
				LogError( CRIO_ERROR_INTERRUPTED, "operation interrupted" );
				break;
			}
		}

		// default to bad block
		UCHAR ucState = CRIO_ID_32KBLOCK_BAD;

		// create and send test block 1
		memset( paucBlock, B_10101010, CRIO_SIZE_32KBLOCK );
		if ( !Tx32KBlock(paucBlock, usPos32KBlock, 0, 0) )
			break;
		// get test block 1
		if ( !Rx32KBlock(paucBlock, usPos32KBlock) )
			break;
		// check test block 1
		for( uiB=0; uiB<CRIO_SIZE_32KBLOCK; ++uiB )
		{
			if ( *(paucBlock+uiB) != B_10101010 )
				break;
		}
		// if ok
		if ( uiB == CRIO_SIZE_32KBLOCK )
		{
			// create and send test block 2
			memset( paucBlock, B_01010101, CRIO_SIZE_32KBLOCK);
			if ( !Tx32KBlock(paucBlock, usPos32KBlock, 0, 0) )
				break;
			// get test block 2
			if ( !Rx32KBlock(paucBlock, usPos32KBlock) )
				break;
			// check test block 2
			for( uiB=0; uiB<CRIO_SIZE_32KBLOCK; ++uiB )
			{
				if ( *(paucBlock+uiB) != B_01010101 )
					break;
			}
			// if ok, block ok
			if ( uiB == CRIO_SIZE_32KBLOCK )
				ucState = CRIO_ID_32KBLOCK_FREE;
		}

		// store block state
		m_cDirBlock.m_auc32KBlockUsed[ usPos32KBlock ] = ucState;

		// adjust bad block count
		if ( ucState == CRIO_ID_32KBLOCK_BAD )
			++iCount32KBlockBad;
	}
	// if tx,rx block error or interrupted
	if ( usPos32KBlock < usPos32KBlockEnd )
		return FALSE;

	// store blocks used and bad block count
	m_cDirBlock.m_cDirHeader.m_usCount32KBlockUsed = iCount32KBlockBad;
	m_cDirBlock.m_cDirHeader.m_usCount32KBlockBad = iCount32KBlockBad;

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// operations
void CRio::UseExternalFlash( BOOL bUseExternalFlash )
{
	m_bUseExternalFlash = bUseExternalFlash;
}

BOOL CRio::CheckPresent( void )
{
	// io intro
	if ( !IOIntro() )
		return FALSE;

	// bank to check (bank 0-3 are internal, bank 4 external)
	int iPos = m_bUseExternalFlash ? POS_BANK_EXTERNALFLASH : 0;

	// issue read id command
	COMMANDOUT( 0xab, B_00001100, B_00000100 );
	COMMANDOUT( iPos, B_00000000, B_00000100 );
	COMMANDOUT( 0xa1, B_00001100, B_00000100 );
	COMMANDOUT( 0x90, B_00000000, B_00000100 );
	COMMANDOUT( 0xa2, B_00001100, B_00000100 );
	COMMANDOUT( 0x00, B_00000000, B_00000100 );
	COMMANDOUT( 0xa0, B_00001100, B_00000100 );
	UCHAR ucManufacturer = GetDataByte();
	UCHAR ucDevice = GetDataByte();

	// check manufacturer code
	switch( ucManufacturer )
	{
		case 0xa0:
		case 0xaa:
		case 0xff:
		case 0xdd:
		case 0x00:
			LogError( CRIO_ERROR_DEVICENOTFOUND, "device not found" );
			return FALSE;
	}

	// determine bank size in 512 byte blocks
	ULONG ulCount512ByteBlock;
	switch( ucDevice )
	{
		case 0xea:
		case 0x64:	ulCount512ByteBlock = 4096;		break;
		case 0xe3:
		case 0xe5:	ulCount512ByteBlock = 8192;		break;
		case 0xe6:	ulCount512ByteBlock = 16384;	break;
		case 0x73:	ulCount512ByteBlock = 32768;	break;
		case 0x75:	ulCount512ByteBlock = 65536;	break;
		default:
			LogError( CRIO_ERROR_DEVICENOTFOUND, "device not found" );
			return FALSE;
	};

	// if internal
	if ( !m_bUseExternalFlash )
	{
		// if special edition found (each bank of 4 is 512 * 32768)
		if ( ulCount512ByteBlock == 32768 )
			m_bSpecialEdition = TRUE;
	}
	// else external
	else
	{
		// convert page count to 32K block count
		m_uiCount32KBlockAvailableExternal = (ulCount512ByteBlock * 512) / CRIO_SIZE_32KBLOCK;
	}

	return TRUE;
}

CDirEntry* CRio::FindFile( const char* pszFile, CFindFile* pFindFile)
{
	// search directory entries for matching filename

    int iCountEntry = m_cDirBlock.m_cDirHeader.m_usCountEntry;
    CDirEntry* pDirEntry = m_cDirBlock.m_acDirEntry;
    int iA = 0;

    if(pFindFile)
    {
        if(pFindFile->m_iCount < iCountEntry)
        {
            iA = ++pFindFile->m_iCount;
            pDirEntry = ++pFindFile->m_iEntry;
        }
    }
	
	for(; iA<iCountEntry; ++iA, ++pDirEntry )
	{
		if ( !strcmp(pszFile, pDirEntry->m_szName) )
        {
            if(pFindFile)
            {
                pFindFile->m_iCount = iA;
                pFindFile->m_iEntry = pDirEntry;
            }

			return pDirEntry;
        }
	}

	return NULL;
}

BOOL CRio::Initialize( BOOL bMarkBadBlock, BOOL (*pfProgress)(int iPos, int iCount, void* cookie), void* cookie)

⌨️ 快捷键说明

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