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