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

📄 madevdrv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
				if ( sdResult < MASMW_SUCCESS )
				{
					return sdResult;
				}
				bCh = (UINT8)( sdResult & 0x0F );

				/* save channel # */

				/* stereo   */
				if( dSaSlot[i]==0 && (pgMaDevDrvInfo->StreamInfo[0].dFormat&0x80) )
				{
					++dRegIndex;

					bPacket[dPp++] = (UINT8)(  dRegIndex       & 0x7F );	/* address part */
					bPacket[dPp++] = (UINT8)( (dRegIndex >> 7) | 0x80 );

					/* read WT#25 regs and copy to WT#26 */

					for( j=0 ; j<5 ; j++ )
					{
						/* read reg */
						sdResult = MaDevDrv_ReceiveData( dRegIndex-6+j );
						/* error  */
						if ( sdResult < MASMW_SUCCESS )
						{
							return sdResult;
						}
						bPacket[dPp++] = (UINT8)sdResult;
					}
					bPacket[dPp++] = (UINT8)(  0x40 | bCh      | 0x80 );	/* data part, KeyOn */

					/* set STEREO bit */
					MaDevDrv_WriteIntermediateReg( MAI_STM_CTRL, MAB_STEREO );

					--dRegIndex;

				}

				bPacket[dPp++] = (UINT8)(  dRegIndex       & 0x7F );	/* address part */
				bPacket[dPp++] = (UINT8)( (dRegIndex >> 7) | 0x80 );
				bPacket[dPp++] = (UINT8)(  0x40 | bCh      | 0x80 );	/* data part, KeyOn */

				/* enable stream PG Irq */
				if( dSeqId==0 )
				{
					ControlInterrupt( MAI_IRQ_CONTROL_1, ENABLE_IRQ, (UINT8)(0x01<<dSaSlot[i]) );
				}

				pgMaDevDrvInfo->StreamInfo[dSaSlot[i]].bState = MADEVDRV_STREAM_STATE_PLAYING;
			}

			/* write packet */
			sdResult = MaDevDrv_SendDirectPacket( bPacket, dPp );


			/* error  */
			if ( sdResult != MASMW_SUCCESS )
			{
				return sdResult;
			}
		}
		else
		{
			/* Stop */
			pgMaDevDrvInfo->StreamInfo[dSaId].bState = MADEVDRV_STREAM_STATE_IDLE;


			/* disable stream PG Irq */
			if( dSeqId==0 )
			{
				ControlInterrupt( MAI_IRQ_CONTROL_1, DISABLE_IRQ, (UINT8)(0x01<<dSaId) );
			}

			/* make packet for KeyOff */

			/* Stream#0/#1 <-> WT#25/#26 */
			dRegIndex = dRegIndexTbl[dSaId];


			sdResult = MaDevDrv_ReceiveData( dRegIndex );
			/* error  */
			if ( sdResult < MASMW_SUCCESS )
			{
				return sdResult;
			}
			bCh = (UINT8)( sdResult & 0x0F );

			bPacket[0] = (UINT8)(  dRegIndex       & 0x7F );	/* address part */
			bPacket[1] = (UINT8)( (dRegIndex >> 7) | 0x80 );
			bPacket[2] = (UINT8)(  0x30 | bCh      | 0x80 );	/* data part, KeyOff */

			/* write packet */
			sdResult = MaDevDrv_SendDirectPacket( bPacket, 3 );

			/* error  */
			if ( sdResult != MASMW_SUCCESS )
			{
				return sdResult;
			}

			/* stereo   */
			if( dSaId==0 && (pgMaDevDrvInfo->StreamInfo[0].dFormat&0x80) )
			{
				dRegIndex += 6;
				bPacket[0] = (UINT8)(  dRegIndex       & 0x7F );	/* address part */
				bPacket[1] = (UINT8)( (dRegIndex >> 7) | 0x80 );
				bPacket[2] = (UINT8)(  0x30 | bCh      | 0x80 );	/* data part, KeyOff */

				/* write packet */
				sdResult = MaDevDrv_SendDirectPacket( bPacket, 3 );

				/* error  */
				if ( sdResult != MASMW_SUCCESS )
				{
					return sdResult;
				}
				/* wait 20us */
				machdep_Wait( 20000 );

				/* clear STEREO bit */
				MaDevDrv_WriteIntermediateReg( MAI_STM_CTRL, 0 );
			}
		}
	}
	else									/* update */
	{
		if ( pgMaDevDrvInfo->StreamInfo[dSaId].bState>MADEVDRV_STREAM_STATE_STANDBY )
		{
			/* Stream Update */
			sdResult = StreamUpdate( dSaId );
		}
	}

	return sdResult;
}
/****************************************************************************
 *	MaDevDrv_IrqProc
 *
 *	Description:
 *			
 *	Argument:
 *			dIrqFlag
 *			dOldSetting
 *	Return:
 *			None
 *
 ****************************************************************************/
void MaDevDrv_IrqProc( UINT32 dIrqFlag, UINT8 bOldSetting )
{
	UINT32	i;
	UINT32	dIrqNum;

	/* IRQ Priority Table */
	static UINT8	bIrqPriority[12] = { 3, 2, 6, 10, 0, 1, 7, 8, 9 ,4, 5, 11};
/*
 *						   0 STMPG#0	stream PG interrupt #0
 *						   1 STMPG#1	stream PG interrupt #1
 *						   2 SIRQ#0		software interrupt #0
 *						   3 SIRQ#1		software interrupt #1
 *						   4 TM#0		timer #0
 *						   5 TM#1		timer #1
 *						   6 TM#2		tiemr #2
 *						   7 FIFO		FIFO
 *						   8 SIRQ#2		software interrupt #2
 *						   9 SIRQ#3		software interrupt #3
 *						  10 SIRQ#4		software interrupt #4
 *						  11 SIRQ#5		software interrupt #5
*/

	/* IRQ Mask Table */
	static UINT32	dIrqMask[12] = {	0x0001,		/* STM#0 	*/
										0x0002,		/* STM#1 	*/
										0x0004,		/* SIRQ#0	*/
										0x0008,		/* SIRQ#1	*/
										0x0010,		/* TM#0		*/
										0x0020,		/* TM#1		*/
										0x0040,		/* TM#2		*/
										0x0080,		/* FIFO		*/
										0x0400,		/* SIRQ#2	*/
										0x0800,		/* SIRQ#3	*/
										0x1000,		/* SIRQ#4	*/
										0x2000 };	/* SIRQ#5	*/
										
	MADEVDRV_DBGMSG(("    MaDevDrv_IrqProc\n"));
	
#if !MASMW_GENERATE_TASK
	(void)bOldSetting;
#endif


	/* call specified Irq Proc */
	for ( i = 0; i < 12; i++ )
	{
		dIrqNum = (UINT32)bIrqPriority[i];

		if ( ( dIrqFlag & dIrqMask[dIrqNum] ) != 0 )
		{
			if ( dIrqNum < 7 )
			{
				/* set REG_ID #0   */
				WriteStatusFlagReg( (UINT8)MAI_IRQ_FLAG_1 );

				/* clear IRQ flag */
				machdep_WriteDataReg( (UINT8)( dIrqMask[dIrqNum] ) );
			}
			else if ( dIrqNum > 7 )
			{
				/* set REG_ID #16   */
				WriteStatusFlagReg( (UINT8)MAI_IRQ_FLAG_2 );

				/* clear IRQ flag */
				machdep_WriteDataReg( (UINT8)( dIrqMask[dIrqNum]>>8 ) );
			}

			switch( dIrqNum ) {
				case 0:		/* STM#0 */
				case 1:		/* STM#1 */
				case 2:		/* SIRQ#0 */
				case 3:		/* SIRQ#1 */
				case 10:	/* SIRQ#4 */
					if( pgMaDevDrvInfo->dActiveSequencer&MADEVDRV_ACTIVE_DELAYEDSEQ ) {
						/* call registered IRQ function */
						pgMaDevDrvInfo->pIntFunc[dIrqNum](0);
					}
					break;
					
				case 6:		/* Timer#2 */
					if( (pgMaDevDrvInfo->dActiveSequencer&MADEVDRV_ACTIVE_PHRASESEQ) ||
				      (pgMaDevDrvInfo->dActiveSequencer&MADEVDRV_ACTIVE_HVSEQ) )
					{
						/* call registered IRQ function */
						pgMaDevDrvInfo->pIntFunc[dIrqNum](0);
					}
					break;
				case 7:		/* FIFO ? */
				case 8:		/* SIRQ#2 ? */
				case 9:		/* SIRQ#3 ? */
					if( !(pgMaDevDrvInfo->dActiveSequencer&MADEVDRV_ACTIVE_DELAYEDSEQ) ) {
						pgMaDevDrvInfo->dPendingIrq |= dIrqMask[dIrqNum];
					}
					else {
						/* call registered IRQ function */
						pgMaDevDrvInfo->pIntFunc[dIrqNum](0);
					}
					break;
				default:
					/* call registered IRQ function */
					pgMaDevDrvInfo->pIntFunc[dIrqNum](0);
					break;
			}

			if ( dIrqNum == 7 )
			{
				/* set REG_ID #0   */
				WriteStatusFlagReg( (UINT8)MAI_IRQ_FLAG_1 );

				/* clear IRQ flag */
				machdep_WriteDataReg( (UINT8)( MAB_IRQFLAG_FIFO ) );
			}
		}
	}
	pgMaDevDrvInfo->bIrqProc = 0;

#if MASMW_GENERATE_TASK
	/* enable irq */
	WriteStatusFlagReg( bOldSetting );
#endif
}
/****************************************************************************
 *	MaDevDrv_ClearIrqProc
 *
 *	Description:
 *			Clear Irq Proc Task
 *	Argument:
 *			None
 *	Return:
 *			None
 *
 ****************************************************************************/
void MaDevDrv_ClearIrqProc( void )
{
	pgMaDevDrvInfo->bStatusReg		= 0x80;	
	pgMaDevDrvInfo->bIrqProc		= 0;
	pgMaDevDrvInfo->bMaskInterrupt	= 0;

	machdep_WriteStatusFlagReg( 0x80 );
}

/****************************************************************************
 *	MaDevDrv_EnableIrq
 *
 *	Description:
 *			Enable Irq
 *	Argument:
 *			None
 *	Return:
 *			None
 *
 ****************************************************************************/
void MaDevDrv_EnableIrq( void )
{
	/* enable interrupt if needed */
	if ( (--pgMaDevDrvInfo->bMaskInterrupt)==0 )
	{
		WriteStatusFlagReg( MAB_IRQ_ENABLE );
	}
}

/****************************************************************************
 *	MaDevDrv_DisableIrq
 *
 *	Description:
 *			Disable Irq
 *	Argument:
 *			None
 *	Return:
 *			None
 *
 ****************************************************************************/
void MaDevDrv_DisableIrq( void )
{
	/*Diasble IRQ if necessary and increment access counter */
	if( pgMaDevDrvInfo->bMaskInterrupt++==0 )
	{
		WriteStatusFlagReg( 0 );
	}
}

/****************************************************************************
 *	MaDevDrv_VerifyRegisters
 *
 *	Description:
 *			Verify the initialized registers by software reset
 *	Argument:
 *			None
 *	Return:
 *			0		success
 *			-1		error
 *
 ****************************************************************************/
SINT32 MaDevDrv_VerifyRegisters( void )
{
	SINT32	sdResult;
	UINT32	i;

	sdResult = MASMW_SUCCESS;

	for( i=MAC_CHANNEL_VOLUME ; i<MAC_CHANNEL_VOLUME+16 ; i++ )
	{
		sdResult = MaDevDrv_ReceiveData( i );
		if ( sdResult < MASMW_SUCCESS )
		{
			return sdResult;
		}
		if( (sdResult&0xff)!=0x60 ) return MASMW_ERROR_SOFTRESET;
	}
	for( i=MAC_CHANNEL_PANPOT ; i<MAC_CHANNEL_PANPOT+16 ; i++ )
	{
		sdResult = MaDevDrv_ReceiveData( i );
		if ( sdResult < MASMW_SUCCESS )
		{
			return sdResult;
		}
		if( (sdResult&0xff)!=0x3c ) return MASMW_ERROR_SOFTRESET;
	}
	return MASMW_SUCCESS;
}

/****************************************************************************
 *	StreamSetup
 *
 *	Description:
 *			Setup wave data to the stream audio.
 *	Arguments:
 *			dSaId	stream audio slot number
 *	Return:
 *			0		success
 *			< 0		error code
 *
 ****************************************************************************/
static SINT32 StreamSetup( UINT32 dSaId )
{
	UINT8	bZeroVal;
	UINT32	dFormat;
	UINT8 *	pbWaveData;
	UINT32	dWaveSize;
	UINT32	dRamAdrs;
	SINT32	sdResult;

	/* error  */
	if ( dSaId >= MA_MAX_STREAM_AUDIO ) return MASMW_ERROR;

	/* clear StreamPG counter */
	MaDevDrv_WriteIntermediateReg( MAI_STM_CTRL, (UINT8)(0x01<<dSaId) );
	MaDevDrv_WriteIntermediateReg( MAI_STM_CTRL, 0 );

	/* get stream info */
	dFormat    = pgMaDevDrvInfo->StreamInfo[dSaId].dFormat;
	pbWaveData = pgMaDevDrvInfo->StreamInfo[dSaId].pbWaveData;
	dWaveSize  = pgMaDevDrvInfo->StreamInfo[dSaId].dWaveSize;

	dRamAdrs = (UINT32)(MA_RAM_START_ADDRESS + (MA_RAM_BLOCK_SIZE * (7-dSaId)) + 0x20);

	if ( dWaveSize == MA_WAVE_SIZE )
	{
		pgMaDevDrvInfo->StreamInfo[dSaId].dEndPoint = dWaveSize;
	}
	else
	{
		if ( (dFormat&0x7f) < 2 )				/* ADPCM */
		{
			pgMaDevDrvInfo->StreamInfo[dSaId].dEndPoint = (dWaveSize % MA_WAVE_SIZE);
		}
		else if( (dFormat&0x7f) <= 3 )			/* 8bit PCM */
		{
			if( dFormat&0x80 )
				pgMaDevDrvInfo->StreamInfo[dSaId].dEndPoint =
					( (dWaveSize + (dWaveSize / MA_WAVE_SIZE)*2 ) % MA_WAVE_SIZE );
			else
				pgMaDevDrvInfo->StreamInfo[dSaId].dEndPoint =
					( (dWaveSize + (dWaveSize / MA_WAVE_SIZE) ) % MA_WAVE_SIZE );
		}
		else 									/* 16bit PCM */
		{
			if( dFormat&0x80 )
				pgMaDevDrvInfo->StreamInfo[dSaId].dEndPoint =
					( (dWaveSize + (dWaveSize / MA_WAVE_SIZE)*4 ) % MA_WAVE_SIZE );
			else
				pgMaDevDrvInfo->StreamInfo[dSaId].dEndPoint =
					( (dWaveSize + (dWaveSize / MA_WAVE_SIZE)*2 ) % MA_WAVE_SIZE );
		}
	}

	pgMaDevDrvInfo->dStreamEoInfo	= 0;

	if ( dWaveSize > MA_WAVE_SIZE )
	{
		/* write wave data to RAM */
		sdResult = MaDevDrv_SendDirectRamData( dRamAdrs, 0, pbWaveData, MA_WAVE_SIZE );

		/* error  */
		if ( sdResult != MASMW_SUCCESS )
		{
			return sdResult;
		}

		if ( (dFormat&0x7f) < 2 )				/* ADPCM */
		{
			dWaveSize   -= MA_WAVE_SIZE;
			pbWaveData  += MA_WAVE_SIZE;
		}
		else if( (dFormat&0x7f) <=3 )				/* 8bit PCM */
		{
			/* stereo */
			if( dFormat&0x80 )
			{
				dWaveSize   -= (MA_WAVE_SIZE - 2);
				pbWaveData  += (MA_WAVE_SIZE - 2);
			}
			/* mono */
			else
			{
				dWaveSize   -= (MA_WAVE_SIZE - 1);
				pbWaveData  += (MA_WAVE_SIZE - 1);
			}
		}
		else						/* 16bit PCM */
		{
			/* stereo */
			if( dFormat&0x80 )
			{
				dWaveSize   -= (MA_WAVE_SIZE - 4);
				pbWaveData  += (MA_WAVE_SIZE - 4);
			}
			/* mono */
			else
			{
				dWaveSize   -= (MA_WAVE_SIZE - 2);
				pbWaveData  += (MA_WAVE_SIZE - 2);
			}
		}
	}
	else
	{
		/* write wave data to RAM */
		sdResult = MaDevDrv_SendDirectRamData( dRamAdrs, 0, pbWaveData, dWaveSize );

		/* error  */
		if ( sdResult != MASMW_SUCCESS )
		{
			return sdResult;
		}

		/* set Zero value */
		switch( dFormat&0x7f ) {
			case 0:					/* MA-2 ADPCM */
			case 1:					/* ADPCM */
			case 2:					/* 8-bit ofset binary */
				bZeroVal = (UINT8)0x80;
				break;
			case 3:					/* 8-bit 2's comp binary */
			case 4:					/* 16-bit 2's comp binary */
				bZeroVal = 0x00;
				break;

⌨️ 快捷键说明

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