www.pudn.com > OS.rar > SACM_HAL.asm, change:2006-12-11,size:44590b


//======================================================================= 
 
.include GPL162001.inc 
.include SACM_Constant.inc		// for flag / buffer constants 
.include Snd_ArithmConfig.inc	// define compiler config const 
.include Ram_External.inc		//xiaolei add for UpSampling use 
//======================================================================= 
.public F_SACM_EndPlay 
.public _SACM_EndPlay		//guili 2005.11.1 
.public _SACM_Speed_Init 
.public F_SACM_Speed_Init 
 
.public F_DecodeInit_setIRQ 
.public F_SACM_SendDACMulti 
 
.ifdef C_SND_MP3_SETVOLMUME 
	.external R_SACM_Play_MP3_Gain 
.endif 
 
.external R_SACM_DAC_Out_PTR_Play 
.external R_SACM_DAC_Out_PTR_Play	//guili 2005.12.01 for S480 no Speed control 
.external R_SACM_Play_Gain		//guili 2005.12.01 for S480 no Speed control 
.external R_CODEC_TYPE 
.external _SndSACM_curDACConfig		//2005/08/17 for DAC1 DAC2 
 
.external R_Right_ChannelData 
.external R_Left_ChannelData 
.external R_Decode_Finish_A 
 
RAM_SACM_HAL:	.SECTION	.ORAM //added by benwang 01.04 
.public R_DAC_OUT_FIFO_Depth		//cfwei20050105 
.public R_DAC_OUT_isUpSampling		//cfwei20050106 
.public R_DAC_ReservedData			//xiaolei add for CTTS Playing 2006/10/30 
.var R_DAC_OUT_FIFO_Depth		//cfwei20050105 
.var R_DAC_OUT_isUpSampling		//cfwei20050106 
.var R_DAC_ReservedData			//xiaolei add for CTTS Playing 2006/10/30 
 
.ifdef ROMCODE005 
	.external OFILTER_BUF		//added by benwang 0322 
	.external OFILTER_BUF_PTR	//added by benwang 0322 
	.external DAC_16K_FLAG		//added by benwang 0322 
	.external AD_CBUF			//added by benwang 0322 
	.external AD_BUF_PTR		//added by benwang 0322 
.else 
	.public R_ISR_16K		//add by zgq 2005/03 
.ifdef C_SND_UPSAMPLE_16KHZ 
	.public DAC_16K_FLAG 
.endif	//End C_SND_UPSAMPLE_16KHZ 
.ifdef C_SND_UPSAMPLE_32KHZ 
	.public DAC_32K_FLAG 
 
	DAC_32K_FLAG:		.dw ? 
.endif	//End C_SND_UPSAMPLE_32KHZ 
 
.ifdef C_SND_UPSAMPLE_16KHZ 
	DAC_16K_FLAG:		.dw ?//initialize:0 
.endif	//End C_SND_UPSAMPLE_16KHZ 
	//DAC_Out_Data:		.dw 0 
	R_ISR_16K:		.dw ? 
.endif //ROMCODE005 
 
//======================================================================= 
.CODE 
////////////////////////////////////////////////////////////////////// 
// Function:	F_SACM_EndPlay 
// Description:	call back from kernel when bit stream decoding is done 
// Syntax:	F_SACM_EndPlay 
// Destory:	R1 
// Parameter:	None 
// Return:	R1: 16-bit unsign PCM 
////////////////////////////////////////////////////////////////////// 
F_SACM_EndPlay: .PROC 
_SACM_EndPlay:			//guili 2005.11.1 
	// implemented by designer and SA 
	// User can also handle concatenation , Ramp down ant etc. 
	retf; 
.ENDP 
 
////////////////////////////////////////////////////////////////////// 
// Function:	F_SACM_Speed_Init 
// Description:	Hardware initilazation, System Clock, DAC, INT 
// call by decode.asm to initilaize the hardware for decode  // by Arthur 
// Syntax:	F_SACM_Speed_Init 
// Destory:	R1 
// Parameter:	None 
// Return:	None 
////////////////////////////////////////////////////////////////////// 
_SACM_Speed_Init:		//cfwei 20040421 
F_SACM_Speed_Init:		//ywang 2005/01/08 
	// removed to F_SACM_EnableDAC //cfwei20041209 
	retf 
 
////////////////////////////////////////////////////////////////////// 
// in: 	R1 = CODEC 
// out:	R1 = FIFO Depth (how many datas send to FIFO when one interrupt come) 
// 	R2 = 0:normal_Gain4 1:upsampling multiFIFO 2:normal_noGain 
////////////////////////////////////////////////////////////////////// 
M_GetCodec_Priority: .MACRO 
	r2 = SEG T_GetCodec_Priority 
	DS = r2 
	r2 = r1 lsl 1 
	r2 += OFFSET T_GetCodec_Priority 
	r1 = DS:[r2++] 
	r2 = DS:[r2] 
.ENDM 
 
//========== T_GetCodec_Priority start ========== 
//don't change function order	//the first is R_DAC_OUT_FIFO_Depth;the second is 
T_GetCodec_Priority:			//isUpSampling data 
.ifdef C_SND_UPSAMPLE_16KHZ 
//16KHz UpSampling for S200	//play 1 word test 
	.dw	8,0		//MS01			//NoNeed to UpSampling to MIDI 
	.dw	8,0		//MS02 
	.dw	8,1		//A1600 
	.dw	2,1		//S200 
	.dw	2,1		//S200TTS 
	.dw	8,1		//S320 
	.dw	8,1		//S320TTS 
	.dw	2,1		//S480 
	.dw	8,1		//S530 
	.dw	8,1		//S600 
	.dw	8,1		//S600TTS 
	.dw	8,1		//S720 
	.dw	8,1		//S480_2 
	.dw	0,0		//DVR 
	.dw	8,1		//DVR1600PLAY 
	.dw	8,1		//A4800 
	.dw	8,0		//MP3			//16 
	.dw	8,1		//ETTS			//17 
	.dw	8,0		//CTTS			//18 
	.dw	8,1		//CTTS_ETTS		//19 
	.dw	8,1		//A1600Skip		//20 
	.dw 8,1		//DVR520 
	.dw 8,1		//DVR4800 
//	.dw 10,0	//A1800			23 
	.dw 8,0		//A1800		23	//modify by chengye 
	.dw 0,0		//DVR1800		24 
	.dw 8,1		//A3200			25 
	.dw 8,0		//A1800_SKIP	26 
	.dw 0,0		//DVR3200		27 
.else 
	.ifdef C_SND_UPSAMPLE_32KHZ 
		.dw	8,0		//MS01			//NoNeed to UpSampling to MIDI 
		.dw	8,0		//MS02 
		.dw	8,1		//A1600 
		.dw	4,1		//S200 
		.dw	4,1		//S200TTS 
		.dw	8,1		//S320 
		.dw	8,1		//S320TTS 
		.dw	2,1		//S480 
		.dw	8,1		//S530 
		.dw	8,1		//S600 
		.dw	8,1		//S600TTS 
		.dw	8,1		//S720 
		.dw	8,1		//S480_2 
		.dw	0,0		//DVR 
		.dw	8,1		//DVR1600PLAY 
		.dw	8,1		//A4800 
		.dw	8,1		//MP3			//16 
		.dw	8,1		//ETTS			//17 
		.dw	8,0		//CTTS			//18 
		.dw	8,1		//CTTS_ETTS		//19 
		.dw	8,1		//A1600Skip		//20 
		.dw 8,1		//DVR520 
		.dw 8,1		//DVR4800 
		.dw 8,0		//A1800			23 
		.dw 0,0		//DVR1800		24 
		.dw 8,1		//A3200			25 
		.dw 8,0		//A1800_SKIP	26 
		.dw 0,0		//DVR3200		27 
	.else 
		.dw	8,0		//MS01 
		.dw	8,0		//MS02 
		.dw	8,0		//A1600 
		.dw	1,0		//S200					//Here the S200 must be the "1" 
		.dw	1,0		//S200TTS 
		.dw	8,0		//S320 
		.dw	8,0		//S320TTS 
		.dw	1,0		//S480 
	//	.dw	8,0		//S480 
		.dw	4,0		//S530 
		.dw	8,0		//S600 
		.dw	8,0		//S600TTS 
		.dw	8,0		//S720 
		.dw	8,0		//S480_2 
		.dw	0,0		//DVR 
		.dw	8,0		//DVR1600PLAY 
		.dw	8,0		//A4800 
		.dw	8,0		//MP3			//16 
		.dw	8,0		//ETTS			//17 
		.dw	8,0		//CTTS			//18 
		.dw	8,0		//CTTS_ETTS		//19 
		.dw	8,0		//A1600Skip		//20 
		.dw 8,0		//DVR520 
		.dw 8,0		//DVR4800 
		.dw 8,0		//A1800			23		//A1800 is specially MaxUp to 32K 
		.dw 0,0		//DVR1800		24 
		.dw 8,0		//A3200			25 
		.dw 8,0		//A1800_SKIP	26		//A1800 is specially MaxUp to 32K 
		.dw 0,0		//DVR3200		27 
	.endif		//C_SND_UPSAMPLE_32KHZ end 
.endif			//C_SND_UPSAMPLE_16KHZ end 
////////////////////////////////////////////////////////////////////// 
// in: 	R1 = CODEC 
// out:	R1 = DAC timer 
////////////////////////////////////////////////////////////////////// 
M_GetCodec_DACProload: .MACRO		//get the preload value 
.if 0								//For different Platform 
	r2 = [_SndSACM_curDACConfig] 
	cmp	r2,(C_DAC1+C_DAC2) 
	jz	?L_DAC1DAC2# 
 
	r2 = SEG T_GetCodec_DACProload 
	DS = r2 
	r1 += OFFSET T_GetCodec_DACProload 
	r1 = DS:[r1] 
	jmp ?L_End# 
 
?L_DAC1DAC2#: 
	r2 = SEG T_GetCodec_DACProload_Double 
	DS = r2 
	r1 += OFFSET T_GetCodec_DACProload_Double 
	r1 = DS:[r1] 
?L_End#: 
.else 
	r2 = SEG T_GetCodec_DACProload_2002 
	DS = r2 
	r1 += OFFSET T_GetCodec_DACProload_2002 
	r1 = DS:[r1] 
.endif 
.ENDM 
 
//========== T_GetCodec_DACProload start ========== 
//For UpSmapling, Change the First Table tempairaly 
//don't change function order 
//.ifdef C_SYSTEM_PLATFORM2002 
T_GetCodec_DACProload_2002: 
	.dw	C_SampleRate_16K		//MS01 
	.dw	C_SampleRate_16K		//MS02 
	.dw	C_SampleRate_8K		//A1600 
	//.dw	C_SampleRate_8K		//S200 
	.dw	C_SampleRate_11_025K		//S200 
	.dw	C_SampleRate_11_025K		//S200TTS 
	.dw	C_SampleRate_8K		//S320 
	.dw	C_SampleRate_11_025K		//S320TTS 
	.dw	C_SampleRate_8K		//S480 
	.dw	C_SampleRate_8K		//S530 
	.dw	0		//C_Timer_Setting_9200_For_48MHz		//S600 a little special 
	.dw	0		//C_Timer_Setting_9200_For_48MHz		//S600TTS a little special 
	.dw	C_SampleRate_8K		//S720 
	.dw	C_SampleRate_8K		//S480_2 
	.dw	0					//DVR 
	.dw	C_SampleRate_8K		//DVR1600PLAY 
	.dw	C_SampleRate_16K		//A4800 
	.dw	C_SampleRate_8K		//MP3		//16			//For MP3 Play Samplate init to 8KHz 
	.dw	C_SampleRate_11_025K		//ETTS		//17 
	.dw	C_SampleRate_8K				//CTTS		//18 
	.dw	0					//CTTS_ETTS	//19 
	.dw	C_SampleRate_8K		//A1600Skip	20 
	.dw C_SampleRate_8K		//DVR520	21 
	.dw 0		//DVR4800	22 
	.dw C_SampleRate_16K	//A1800	23 
	.dw 0					//DVR1800	24 
	.dw C_SampleRate_8K		//A3200	25				//modify by chengye 2006/9/14 
	.dw C_SampleRate_16K	//A1800_SKIP	26 
	.dw 0					//DVR3200		27 
 
//.endif //end of C_SYSTEM_PLATFORM2002 
.if 0		//For Spl162001 Platform only 
T_GetCodec_DACProload: 
.ifdef C_SND_UPSAMPLE_16KHZ 
//	.dw C_Timer_Setting_16K_For_48MHz		//16KHz UpSampling for S200 
	.dw	C_Timer_Setting_16K_For_48MHz		//MS01		//NoNeed to UpSampling 
	.dw	C_Timer_Setting_16K_For_48MHz		//MS02 
	.dw	C_Timer_Setting_16K_For_48MHz		//A1600 
	.dw	C_Timer_Setting_16K_For_48MHz		//S200 
	.dw	C_Timer_Setting_22K_For_48MHz		//S200TTS 
	.dw	C_Timer_Setting_16K_For_48MHz		//S320 
	.dw	C_Timer_Setting_22K_For_48MHz		//S320TTS 
	.dw	C_Timer_Setting_16K_For_48MHz		//S480 
	.dw	C_Timer_Setting_16K_For_48MHz		//S530 
	.dw	C_Timer_Setting_18400_For_48MHz		//S600 
	.dw	C_Timer_Setting_18400_For_48MHz		//S600TTS 
	.dw	C_Timer_Setting_16K_For_48MHz		//S720 
	.dw	C_Timer_Setting_16K_For_48MHz		//S480_2 
	.dw	0					//DVR 
	.dw	C_Timer_Setting_16K_For_48MHz		//DVR1600PLAY 
	.dw	C_Timer_Setting_16K_For_48MHz		//A4800 
	.dw	0					//MP3		//16 
	.dw	C_Timer_Setting_22K_For_48MHz		//ETTS		//17 
	.dw	0					//CTTS		//18 
	.dw	0					//CTTS_ETTS	//19 
	.dw	C_Timer_Setting_16K_For_48MHz		//A1600Skip	20 
	.dw C_Timer_Setting_16K_For_48MHz		//DVR520	21 
	.dw C_Timer_Setting_16K_For_48MHz		//DVR4800	22 
	.dw C_Timer_Setting_16K_For_48MHz		//A1800		23 
	.dw 0					//DVR1800	24 
	.dw C_Timer_Setting_16K_For_48MHz		//A3200		25 
	.dw C_Timer_Setting_16K_For_48MHz		//A1800_SKIP	26 
.else 
	.ifdef C_SND_UPSAMPLE_32KHZ 
		.dw	C_Timer_Setting_16K_For_48MHz		//MS01		//NoNeed to UpSampling 
		.dw	C_Timer_Setting_16K_For_48MHz		//MS02 
 
		.dw	C_Timer_Setting_32K_For_48MHz		//A1600 
		.dw	C_Timer_Setting_32K_For_48MHz		//S200 
		.dw	C_Timer_Setting_44K_For_48MHz		//S200TTS 
		.dw	C_Timer_Setting_32K_For_48MHz		//S320 
		.dw	C_Timer_Setting_44K_For_48MHz		//S320TTS 
		.dw	C_Timer_Setting_32K_For_48MHz		//S480 
		.dw	C_Timer_Setting_32K_For_48MHz		//S530 
		.dw	C_Timer_Setting_18400_For_48MHz/2		//S600 
		.dw	C_Timer_Setting_18400_For_48MHz/2		//S600TTS 
		.dw	C_Timer_Setting_32K_For_48MHz		//S720 
		.dw	C_Timer_Setting_32K_For_48MHz		//S480_2 
		.dw	0					//DVR 
		.dw	C_Timer_Setting_32K_For_48MHz		//DVR1600PLAY 
		.dw	C_Timer_Setting_32K_For_48MHz		//A4800 
		.dw	0					//MP3		//16 
		.dw	C_Timer_Setting_44K_For_48MHz		//ETTS		//17 
		.dw	0					//CTTS		//18 
		.dw	0					//CTTS_ETTS	//19 
		.dw	C_Timer_Setting_32K_For_48MHz		//A1600Skip	20 
		.dw C_Timer_Setting_32K_For_48MHz		//DVR520	21 
		.dw C_Timer_Setting_32K_For_48MHz		//DVR4800	22 
		.dw C_Timer_Setting_16K_For_48MHz		//A1800		23	UpX2 only 
		.dw 0					//DVR1800	24 
		.dw C_Timer_Setting_32K_For_48MHz		//A3200		25 
		.dw C_Timer_Setting_16K_For_48MHz		//A1800_SKIP 26 UpX2 only 
	.else 
		.dw	C_Timer_Setting_16K_For_48MHz		//MS01 
		.dw	C_Timer_Setting_16K_For_48MHz		//MS02 
		.dw	C_Timer_Setting_8K_For_48MHz		//A1600 
		.dw	C_Timer_Setting_8K_For_48MHz		//S200 
		.dw	C_Timer_Setting_11K_For_48MHz		//S200TTS 
		.dw	C_Timer_Setting_8K_For_48MHz		//S320 
		.dw	C_Timer_Setting_11K_For_48MHz		//S320TTS 
		.dw	C_Timer_Setting_8K_For_48MHz		//S480 
		.dw	C_Timer_Setting_8K_For_48MHz		//S530 
		.dw	C_Timer_Setting_9200_For_48MHz		//S600 
		.dw	C_Timer_Setting_9200_For_48MHz		//S600TTS 
		.dw	C_Timer_Setting_8K_For_48MHz		//S720 
		.dw	C_Timer_Setting_8K_For_48MHz		//S480_2 
		.dw	0					//DVR 
		.dw	C_Timer_Setting_8K_For_48MHz		//DVR1600PLAY 
		.dw	C_Timer_Setting_8K_For_48MHz		//A4800 
		.dw	0					//MP3		//16 
		.dw	C_Timer_Setting_11K_For_48MHz		//ETTS		//17 
		.dw	0					//CTTS		//18 
		.dw	0					//CTTS_ETTS	//19 
		.dw	C_Timer_Setting_8K_For_48MHz		//A1600Skip	20 
		.dw C_Timer_Setting_8K_For_48MHz		//DVR520	21 
		.dw C_Timer_Setting_8K_For_48MHz		//DVR4800	22 
		.dw C_Timer_Setting_16K_For_48MHz		//A1800		23 
		.dw 0					//DVR1800	24 
		.dw C_Timer_Setting_8K_For_48MHz		//A3200		25 
		.dw C_Timer_Setting_16K_For_48MHz		//A1800_SKIP	26 
	.endif	//C_SND_UPSAMPLE_32KHZ end 
.endif		//C_SND_UPSAMPLE_16KHZ end 
 
//don't change function order 
T_GetCodec_DACProload_Double: 
.ifdef C_SND_UPSAMPLE_16KHZ 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//MS01 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//MS02 
 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//A1600 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//S200 
	.dw	C_Timer_Setting_22K_For_48MHz_Double		//S200TTS 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//S320 
	.dw	C_Timer_Setting_22K_For_48MHz_Double		//S320TTS 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//S480 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//S530 
	.dw	C_Timer_Setting_18400_For_48MHz_Double		//S600 
	.dw	C_Timer_Setting_18400_For_48MHz_Double		//S600TTS 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//S720 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//S480_2 
	.dw	0						//DVR 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//DVR1600PLAY 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//A4800 
	.dw	0						//MP3		//16 
	.dw	C_Timer_Setting_22K_For_48MHz_Double		//ETTS		//17 
	.dw	0						//CTTS		//18 
	.dw	0						//CTTS_ETTS	//19 
	.dw	C_Timer_Setting_16K_For_48MHz_Double		//A1600Skip	//20 
	.dw C_Timer_Setting_16K_For_48MHz_Double		//DVR520	21 
	.dw C_Timer_Setting_16K_For_48MHz_Double		//DVR4800	22 
	.dw C_Timer_Setting_16K_For_48MHz_Double	//A1800	23 
	.dw 0										//DVR1800	24 
	.dw C_Timer_Setting_16K_For_48MHz_Double		//A3200	25 
	.dw C_Timer_Setting_16K_For_48MHz_Double	//A1800_SKIP	26 
.else 
	.ifdef C_SND_UPSAMPLE_32KHZ 
		.dw	C_Timer_Setting_16K_For_48MHz_Double		//MS01 
		.dw	C_Timer_Setting_16K_For_48MHz_Double		//MS02 
 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//A1600 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//S200 
		.dw	C_Timer_Setting_44K_For_48MHz_Double/2		//S200TTS 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//S320 
		.dw	C_Timer_Setting_44K_For_48MHz_Double/2		//S320TTS 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//S480 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//S530 
		.dw	C_Timer_Setting_18400_For_48MHz_Double/2		//S600 
		.dw	C_Timer_Setting_18400_For_48MHz_Double/2		//S600TTS 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//S720 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//S480_2 
		.dw	0						//DVR 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//DVR1600PLAY 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//A4800 
		.dw	0						//MP3		//16 
		.dw	C_Timer_Setting_44K_For_48MHz_Double/2		//ETTS		//17 
		.dw	0						//CTTS		//18 
		.dw	0						//CTTS_ETTS	//19 
		.dw	C_Timer_Setting_32K_For_48MHz_Double		//A1600Skip	//20 
		.dw C_Timer_Setting_32K_For_48MHz_Double		//DVR520	21 
		.dw C_Timer_Setting_32K_For_48MHz_Double		//DVR4800	22 
		.dw C_Timer_Setting_16K_For_48MHz_Double	//A1800	23 
		.dw 0										//DVR1800	24 
		.dw C_Timer_Setting_32K_For_48MHz_Double		//A3200	25 
		.dw C_Timer_Setting_16K_For_48MHz_Double	//A1800_SKIP	26 
	.else 
		.dw	C_Timer_Setting_16K_For_48MHz_Double		//MS01 
		.dw	C_Timer_Setting_16K_For_48MHz_Double		//MS02 
		.dw	C_Timer_Setting_16K_For_48MHz_Double		//A1600 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//S200 
		.dw	C_Timer_Setting_11K_For_48MHz_Double		//S200TTS 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//S320 
		.dw	C_Timer_Setting_11K_For_48MHz_Double		//S320TTS 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//S480 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//S530 
		.dw	C_Timer_Setting_9200_For_48MHz_Double		//S600 
		.dw	C_Timer_Setting_9200_For_48MHz_Double		//S600TTS 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//S720 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//S480_2 
		.dw	0						//DVR 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//DVR1600PLAY 
		.dw	C_Timer_Setting_16K_For_48MHz_Double		//A4800 
		.dw	0						//MP3		//16 
		.dw	C_Timer_Setting_11K_For_48MHz_Double		//ETTS		//17 
		.dw	0						//CTTS		//18 
		.dw	0						//CTTS_ETTS	//19 
		.dw	C_Timer_Setting_8K_For_48MHz_Double		//A1600Skip	//20 
		.dw C_Timer_Setting_8K_For_48MHz_Double		//DVR520	21 
		.dw C_Timer_Setting_8K_For_48MHz_Double		//DVR4800	22 
		.dw C_Timer_Setting_16K_For_48MHz_Double	//A1800	23 
		.dw 0										//DVR1800	24 
		.dw C_Timer_Setting_8K_For_48MHz_Double		//A3200	25 
		.dw C_Timer_Setting_16K_For_48MHz_Double	//A1800_SKIP	26 
	.endif 
.endif	//C_SND_UPSAMPLE_16KHZ end 
.endif				//end 0, for different platform 
////////////////////////////////////////////////////////////////////// 
M_GetCodec_PWMProload: .MACRO 
 
.if 0 
	r2 = SEG T_GetCodec_PWMProload 
	DS = r2 
	r1 += OFFSET T_GetCodec_PWMProload 
	r1 = DS:[r1] 
.endif 
 
	r2 = SEG T_GetCodec_PWMProload_2002 
	DS = r2 
	r1 += OFFSET T_GetCodec_PWMProload_2002 
	r1 = DS:[r1] 
 
.ENDM 
 
//========== T_GetCodec_PWMProload start ========== 
//don't change function order 
T_GetCodec_PWMProload_2002: 
	.dw	C_SampleRate_16K		//MS01 
	.dw	C_SampleRate_16K		//MS02 
	.dw	C_SampleRate_8K		//A1600 
	.dw	C_SampleRate_8K		//S200 
	.dw	C_SampleRate_11_025K		//S200TTS 
	.dw	C_SampleRate_8K		//S320 
	.dw	C_SampleRate_11_025K		//S320TTS 
	.dw	C_SampleRate_8K		//S480 
	.dw	C_SampleRate_8K		//S530 
	.dw	0		//C_Timer_Setting_9200_For_48MHz		//S600 a little special 
	.dw	0		//C_Timer_Setting_9200_For_48MHz		//S600TTS a little special 
	.dw	C_SampleRate_8K		//S720 
	.dw	C_SampleRate_8K		//S480_2 
	.dw	0					//DVR 
	.dw	C_SampleRate_8K		//DVR1600PLAY 
	.dw	C_SampleRate_8K		//A4800 
	.dw	0					//MP3		//16 
	.dw	C_SampleRate_11_025K		//ETTS		//17 
	.dw	0					//CTTS		//18 
	.dw	0					//CTTS_ETTS	//19 
	.dw	C_SampleRate_8K		//A1600Skip	20 
	.dw C_SampleRate_8K		//DVR520	21 
	.dw C_SampleRate_8K		//DVR4800	22 
	.dw C_SampleRate_16K		//A1800	23 
	.dw 0					//DVR1800	24 
	.dw 0					//DVR3200	25 
	.dw C_SampleRate_16K		//A1800_SKIP	26 
 
.if 0				//For 2001 Platform 
T_GetCodec_PWMProload: 
	.dw	C_Timer_Setting_16K_For_48MHz		//MS01 
	.dw	C_Timer_Setting_16K_For_48MHz		//MS02 
 
	.dw	C_Timer_Setting_16K_For_48MHz		//A1600 
	.dw	C_Timer_Setting_8K_For_48MHz		//S200 
	.dw	C_Timer_Setting_11K_For_48MHz		//S200TTS 
	.dw	C_Timer_Setting_8K_For_48MHz		//S320 
	.dw	C_Timer_Setting_11K_For_48MHz		//S320TTS 
	.dw	C_Timer_Setting_8K_For_48MHz		//S480 
	.dw	C_Timer_Setting_8K_For_48MHz		//S530 
	.dw	C_Timer_Setting_9200_For_48MHz		//S600 
	.dw	C_Timer_Setting_9200_For_48MHz		//S600TTS 
	.dw	C_Timer_Setting_8K_For_48MHz		//S720 
	.dw	C_Timer_Setting_8K_For_48MHz		//S480_2 
	.dw	0					//DVR 
	.dw	C_Timer_Setting_8K_For_48MHz		//DVR1600PLAY 
	.dw	C_Timer_Setting_8K_For_48MHz		//A4800 
	.dw	0					//MP3 
	.dw	C_Timer_Setting_11K_For_48MHz		//ETTS 
	.dw	C_Timer_Setting_8K_For_48MHz		//A1600Skip 
	.dw C_Timer_Setting_8K_For_48MHz		//DVR520 
	.dw C_Timer_Setting_8K_For_48MHz		//DVR4800 
	.dw C_Timer_Setting_16K_For_48MHz		//A1800 
	.dw 0					//DVR1800	24 
	.dw C_Timer_Setting_8K_For_48MHz		//DVR3200	25 
	.dw C_Timer_Setting_16K_For_48MHz		//A1800_SKIP 
.endif 
////////////////////////////////////////////////////////////////////// 
// Function:	F_DecodeInit_setIRQ 
// Description:	Hardware initilazation, Timer for play speed and set FIFO depth 
// Syntax:	F_DecodeInit_setIRQ 
// Destory:	R1 
// Parameter:	None 
// Return:	None 
////////////////////////////////////////////////////////////////////// 
F_DecodeInit_setIRQ: .proc 
	R1 = [R_CODEC_TYPE] 
	M_GetCodec_Priority 
	[R_DAC_OUT_FIFO_Depth] = R1 
	[R_DAC_OUT_isUpSampling] = R2 
 
	R1 = [R_CODEC_TYPE] 
	M_GetCodec_DACProload 
 
	r2 = [_SndSACM_curDACConfig] 
	cmp	r2,C_DAC2 
	jz ?L_OnlyDAC2 
.if 0					//Ready for different platform 
	[P_TimerE_Preload] = R1	//mgl 2005/3/14 
 
	R1 = 0xA060			// TimerE = SYSCLK/2 
	[P_TimerE_Ctrl] = R1 
	retf 
.else					//xiaolei add to SoundOS 2006/07/10 
	cmp	r2, C_DAC2 + C_DAC1 
	jnz ?L_OnlyDAC1 
	push r2, r3 to [sp]   	//add by benwang 20060112 
	r2 = [P_CHA_Ctrl] 	 	//add by benwang 20060112 
	r3 = [P_CHB_Ctrl] 
	r2 &= ~0x0f        		//add by benwang 20060112 
	r3 &= ~0x0f 
	r2 |= R1				//add by benwang 20060112 
	r3 |= r1 
	[P_CHA_Ctrl]=r2			//add by benwang 20060112 
	[P_CHB_Ctrl]=r3 
	pop r2, r3 from [sp]  	//add by benwang 20060112 
	retf 
?L_OnlyDAC1: 
	push r2 to [sp];   	//add by benwang 20060112 
	r2=[P_CHA_Ctrl]  	//add by benwang 20060112 
	r2&=~0x0f        	//add by benwang 20060112 
	r2 |= R1			//add by benwang 20060112 
	[P_CHA_Ctrl]=r2		//add by benwang 20060112 
	pop r2 from [sp]  	//add by benwang 20060112 
	retf 
.endif 
?L_OnlyDAC2: 
.if 0					//Ready for different plarform 
	[P_TimerF_Preload] = R1;	//mgl 2005/11/17 
   	R1 = 0xA060			// TimerE = SYSCLK/2 
   	[P_TimerF_Ctrl] = R1 
	RETF; 
.else 
	push r2 to [sp];   	//add by benwang 20060112 
	r2=[P_CHB_Ctrl]  	//add by benwang 20060112 
	r2&=~0x0f        	//add by benwang 20060112 
	r2 |= R1			//add by benwang 20060112 
	[P_CHB_Ctrl]=r2		//add by benwang 20060112 
	pop r2 from [sp]  	//add by benwang 20060112 
	retf 
.endif 
 
.endp 
 
//================================================================== 
 
////////////////////////////////////////////////////////////////////// 
//====================== Snd multi data to FIFO....===== 
//M_SACM_Gain: .MACRO Reg1 
//Reg1=R4,Reg2=R3 
//====================================================== 
M_SACM_Gain: .MACRO Reg1,Reg2 
 
.ifdef C_DAC_Gain2 
//*****  Gain2    R4 = R4 LSL 1; 	//change volume 1016** 
	CMP Reg1,(16384-16); 
	JGE ?_chk_max#; 
	CMP Reg1,-16384; 
	JL ?_chk_min#; 
	R3 = Reg2 LSL 4 
	R4 = Reg1 ROL 1; 
//	R4 = R4 LSL 1; 
	JMP ?_Volume_end#; 
?_chk_max#: 
	R4 = (16384-16) * 2 - 1; //max 0x7FDF 
	JMP ?_Volume_end#; 
?_chk_min#: 
	R4 = (-16384) * 2; 
?_Volume_end#: 
//*****  Gain2    R4 = R4 LSL 1; 	//change volume 1016** 
 
.endif 
 
.ifdef C_DAC_Gain4 
//*****  Gain4    R4 = R4 LSL 2; 	//change volume 1016** 
	CMP R4,(8192 - 8); 
	JGE ?_chk_max#; 
	CMP R4,-8192; 
	JL ?_chk_min#; 
	R4 = R4 LSL 2; 
	JMP ?_Volume_end#; 
?_chk_max#: 
	R4 = (8192 - 8) * 4 - 1; //max 0x7FDF 
	JMP ?_Volume_end#; 
?_chk_min#: 
	R4 = (-8192) * 4; 
?_Volume_end#:												//// 
//*****  Gain4    R4 = R4 LSL 2; 	//change volume 1016** 
.endif 
 
	R4 ^= 0x8000; 
.ENDM 
 
//==================GainX2 for UpSampling======================== 
M_SACM_Gain_US: .MACRO Reg1,Reg2			//for UpSampling only 
.ifdef C_DAC_Gain2 
//*****  Gain2    R4 = R4 LSL 1; 	//change volume 1016** 
	CMP Reg1,(16384-16); 
	JGE ?_chk_max#; 
	CMP Reg1,-16384; 
	JL ?_chk_min#; 
	R3 = Reg2 LSL 4 
	R4 = Reg1 ROL 1; 
	JMP ?_Volume_end#; 
?_chk_max#: 
	R4 = (16384-16) * 2 - 1; 
	JMP ?_Volume_end#; 
?_chk_min#: 
	R4 = (-16384) * 2; 
?_Volume_end#: 
//*****  Gain2    R4 = R4 LSL 1; 	//change volume 1016** 
.endif 
 
.ifdef C_DAC_Gain4 
//*****  Gain4    R4 = R4 LSL 2; 	//change volume 1016** 
	CMP R4,(8192 - 8); 
	JGE ?_chk_max#; 
	CMP R4,-8192; 
	JL ?_chk_min#; 
	R4 = R4 LSL 2; 
	JMP ?_Volume_end#; 
?_chk_max#: 
	R4 = (8192 - 8) * 4 - 1; 
	JMP ?_Volume_end#; 
?_chk_min#: 
	R4 = (-8192) * 4; 
?_Volume_end#:												//// 
//*****  Gain4    R4 = R4 LSL 2; 	//change volume 1016** 
.endif 
.ENDM 
 
////////////////////////////////////////////////////////////////////// 
//M_sFIFO1and2_MultiUS: .MACRO Depth 
//================================================================ 
//===================Filter UpSampling xiaolei remove to here===== 
//================================================================ 
 
//Send the datas to FIFO,the input parament is R4 
M_SendDataToFIFO:.macro 
	push r3 to [sp] 
	R3 = [R_SACM_Play_Flag] 
	test R3,C_SACM_ENABLE_DAC1 
	jnz ?L_has_DAC1 
	goto ?L_no_DAC1 
?L_has_DAC1: 
	test R3,C_SACM_ENABLE_DAC2 
	jz ?L_has_DAC1_no_DAC2 
 
?L_has_DAC1_has_DAC2:  //==== Running with loop unrolling 
	M_SendDataFIFO1and2 R4 
	jmp ?L_FIFO_finish 
 
?L_has_DAC1_no_DAC2:   //==== Running with loop unrolling 
	M_SendDataFIFO1 R4 
	jmp ?L_FIFO_finish 
 
?L_no_DAC1: 
	test R3,C_SACM_ENABLE_DAC2 
	jz ?L_no_DAC1_no_DAC2 
 
?L_no_DAC1_has_DAC2:   //==== Running with loop unrolling 
	M_SendDataFIFO2 R4 
	jmp ?L_FIFO_finish 
 
?L_no_DAC1_no_DAC2:    //==== Running 
	//=== skip all calculation.. 
	M_SendDataFIFONO1NO2 R4 
?L_FIFO_finish: 
	pop r3 from [sp] 
.endm 
//Send the data to CHA 
M_SendDataFIFO1:.macro data 
	[P_CHA_Data] = data 
.endm 
//Send the data to CHB 
M_SendDataFIFO2:.macro data 
	[P_CHB_Data] = data 
.endm 
//Send the data to CHA&CHB 
M_SendDataFIFO1and2:.macro data 
	[P_CHA_Data] = data 
.ifdef C_SYSTEM_SPL162002 
	[P_CHB_Data] = data 
.else	//For 162002 Platform 
	[P_CHA_Data] = data 
.endif 
.endm 
//Send the data to NOCHANLE 
M_SendDataFIFONO1NO2:.macro data 
 
.endm 
 
////////////////////////////////////////////////////////////////////// 
//M_XXXX_sFIFO1and2_MultiUS: .MACRO //Depth	//The input depth can be more than one 
.ifdef C_SND_UPSAMPLE_16KHZ 
.public F_FIFO1and2_MultiUS16KHz	//xiaolei modify to a function 2006/06/03 
F_FIFO1and2_MultiUS16KHz: .proc 
	push R1, R5 to [sp] 
	R1 = [R_DAC_OUT_FIFO_Depth]//Depth						//the data end to FIFO xiaolei add 
?L_SendDataCycle: 
	R5 = [DAC_16K_FLAG]//0 1 
	R4 = R5 + 1 
	R4 = R4 & 1 
	[DAC_16K_FLAG] = R4 
	R5 = R5 LSL 4 
	R5 = R5 LSL 1 
	R5 += OFILTER_COEF_16_SA 
	R5 -= [OFILTER_BUF_PTR] 
	R2 = OFILTER_BUF 
	MR = [R2]*[R5],ss,16	//added by zgq on 2005/03/14 
	R3 = R3 LSL 4			//del by zgq on 20060603 
	R4 = R4 ROL 2			//del by zgq on 20060603 
	M_SACM_Gain_US R4,R3 
.ifdef test_s200 
	push r1, r2 to [SP]; 
	R1 = [addr_h]; 
	r2 = [addr_l]; 
 
	ds = r1; 
	D:[R2++] = R4; 
	[addr_l] = r2; 
	r1 = ds; 
	[addr_h] = r1; 
 
	POP R1, R2 FROM [SP]; 
.endif 
	R4 ^= 0x8000 
	M_SendDataToFIFO 
	R2 = [DAC_16K_FLAG] 
	JE ?L_NormalSend 
	goto ?L_FirstEnd 
?L_NormalSend: 
//Send the real data in DAC_OUT_Buffer 
	R2 = [R_SACM_DAC_Out_PTR_Play] 
    R3 = [R2++] 
    R4 = [R_SACM_Play_Gain] 
	MR = R4 * R3, us;				//added by zgq on 2005/03/14 
	R5 = [OFILTER_BUF_PTR];			//added by zgq on 2005/03/14 
	R3 = R5 + OFILTER_BUF;			//added by zgq on 2005/03/14 
	R5 = R5 + 1;					//added by zgq on 2005/03/14 
	R5 = R5 & 15;					//added by zgq on 2005/03/14 
	[OFILTER_BUF_PTR] = R5;    		//added by zgq on 2005/03/14 
	[R3] = R4;						//added by zgq on 2005/03/14 
	[R_SACM_DAC_Out_PTR_Play] = R2 
?L_FirstEnd: 
	R1 -= 1							//xiaolei add 2006/06/03 
	jz ?L_SendDataEnd 
	goto ?L_SendDataCycle 
?L_SendDataEnd: 
	pop r1, r5 from [sp] 
	retf 
.endp 
.endif		//End of C_SND_UPSAMPLE_16KHZ definition 
 
.ifdef C_SND_UPSAMPLE_32KHZ 
.public F_FIFO1and2_MultiUS32KHz	//xiaolei add the  function 2006/06/04 
F_FIFO1and2_MultiUS32KHz:.proc 
.comment @ 
//Add for A1800 only	xiaolei add 2006/07/05 
	R4 = [R_CODEC_TYPE] 
	cmp R4, C_CODEC_A1800 
	jnz ?A1800_UseOnly 
//only for A1800		xiaolei add end 2006/07/05 
@ 
	push R1, R5 to [sp] 
	R1 = [R_DAC_OUT_FIFO_Depth]//Depth						//the data end to FIFO xiaolei add 
?L_SendDataCycle: 
	R5 = [DAC_32K_FLAG]//0 1 2 3 
	R4 = R5 + 1 
	R4 = R4 & 3 
	[DAC_32K_FLAG] = R4 
	R5 = R5 LSL 4 
	R5 += OFILTER_COEF_32_SA 
	R5 -= [OFILTER_BUF_PTR] 
	R2 = OFILTER_BUF 
 
	MR = [R2]*[R5],ss,8		//added by zgq on 2005/03/14 
	R3 = R3 LSL 4			//del by zgq on 20060603 
	R4 = R4 ROL 3			//del by zgq on 20060603 
	M_SACM_Gain_US R4,R3		//xiaolei add 2006/06/05 
.ifdef test_s200 
	push r1, r2 to [SP]; 
	R1 = [addr_h]; 
	r2 = [addr_l]; 
 
	ds = r1; 
	D:[R2++] = R4; 
	[addr_l] = r2; 
	r1 = ds; 
	[addr_h] = r1; 
 
	POP R1, R2 FROM [SP]; 
.endif 
	R4 ^= 0x8000 
	M_SendDataToFIFO 
	R2 = [DAC_32K_FLAG] 
	JZ ?L_NormalSend 
	goto ?L_FirstEnd 
?L_NormalSend: 
//Send the real data in DAC_OUT_Buffer 
	R2 = [R_SACM_DAC_Out_PTR_Play] 
    R3 = [R2++] 
    R4 = [R_SACM_Play_Gain] 
	MR = R4 * R3, us;				//added by zgq on 2005/03/14 
	R5 = [OFILTER_BUF_PTR];			//added by zgq on 2005/03/14 
	R3 = R5 + OFILTER_BUF;			//added by zgq on 2005/03/14 
	R5 = R5 + 1;					//added by zgq on 2005/03/14 
	R5 = R5 & 7;					//added by zgq on 2005/03/14 
	[OFILTER_BUF_PTR] = R5;    		//added by zgq on 2005/03/14 
	[R3] = R4;						//added by zgq on 2005/03/14 
	[R_SACM_DAC_Out_PTR_Play] = R2	//xiaolei remove the position here 
?L_FirstEnd: 
	R1 -= 1							//xiaolei add 2006/06/03 
	jz ?L_SendDataEnd 
	goto ?L_SendDataCycle 
?L_SendDataEnd: 
	pop r1, r5 from [sp]			//xiaolei add 2006/06/03 
	retf 
//=============================================== 
//To A1800, the frequency need to be upto X4 
.comment @ 
?A1800_UseOnly: 
	push R1, R5 to [sp] 
	R1 = [R_DAC_OUT_FIFO_Depth]//Depth						//the data end to FIFO xiaolei add 
?L_SendDataCycle1: 
	R5 = [DAC_16K_FLAG]//0 1 
	R4 = R5 + 1 
	R4 = R4 & 1 
	[DAC_16K_FLAG] = R4 
	R5 = R5 LSL 4 
	R5 = R5 LSL 1 
	R5 += OFILTER_COEF_16_SA 
	R5 -= [OFILTER_BUF_PTR] 
	R2 = OFILTER_BUF 
	MR = [R2]*[R5],ss,16		//added by zgq on 2005/03/14 
	R3 = R3 LSL 4			//del by zgq on 20060603 
	R4 = R4 ROL 2			//del by zgq on 20060603 
	M_SACM_Gain_US R4,R3 
.ifdef test_s200 
	push r1, r2 to [SP]; 
	R1 = [addr_h]; 
	r2 = [addr_l]; 
 
	ds = r1; 
	D:[R2++] = R4; 
	[addr_l] = r2; 
	r1 = ds; 
	[addr_h] = r1; 
 
	POP R1, R2 FROM [SP]; 
.endif 
	R4 ^= 0x8000 
	M_SendDataToFIFO 
	R2 = [DAC_16K_FLAG] 
	JE ?L_NormalSend1 
	goto ?L_FirstEnd1 
?L_NormalSend1: 
//Send the real data in DAC_OUT_Buffer 
	R2 = [R_SACM_DAC_Out_PTR_Play] 
    R3 = [R2++] 
    R4 = [R_SACM_Play_Gain] 
	MR = R4 * R3, us;				//added by zgq on 2005/03/14 
	R5 = [OFILTER_BUF_PTR];			//added by zgq on 2005/03/14 
	R3 = R5 + OFILTER_BUF;			//added by zgq on 2005/03/14 
	R5 = R5 + 1;					//added by zgq on 2005/03/14 
	R5 = R5 & 15;					//added by zgq on 2005/03/14 
	[OFILTER_BUF_PTR] = R5;    		//added by zgq on 2005/03/14 
	[R3] = R4;						//added by zgq on 2005/03/14 
	[R_SACM_DAC_Out_PTR_Play] = R2 
?L_FirstEnd1: 
	R1 -= 1							//xiaolei add 2006/06/03 
	jz ?L_SendDataEnd1 
	goto ?L_SendDataCycle1 
?L_SendDataEnd1: 
	pop r1, r5 from [sp] 
	retf 
//A1800 only 
@ 
//===================================================== 
.endp 
.endif 
////////////////////////////////////////////////////////////////////// 
// Function:	M_SACM_SendFIFO 
// Description:	send data to DAC1 and DAC2 from library 
// Author:	cfwei 20040421 
// Syntax:	M_SACM_SendFIFO* 
// Destory:	R3,R4 
// Parameter:	R1=[R_SACM_Play_Gain], R2=[R_SACM_DAC_Out_PTR_Play], R3=[R_SACM_Play_Flag] 
// Return:	R2= new [R_SACM_DAC_Out_PTR_Play] 
//////////////////////////////////////////////////////// 
M_SACM_SendFIFO1and2: .MACRO depth 
//	R5 = depth + R2;			//== FIFO count=depth. 
 
?M_SACM_SendFIFO1and2_loop#:	//== Running with loop unrolling 
	R3 = [R2++]; 
.ifdef dumpdacdata 
	push r1,r2 to [sp] 
	r1 = [temptest_h] 
	ds = r1 
	r2 = [temptest_l] 
	ds:[r2++] = r3 
	[temptest_l] = r2 
	r1 = ds 
	[temptest_h] = r1 
	pop r1,r2 from [sp] 
.endif 
	MR = R1 * R3, us; 
////////////////////////////////////// 
	M_SACM_Gain R4,R3 
////////////////////////////////////// 
	[P_CHA_Data]=R4; 
.if 0						//For 162001 Platform use only 
	[P_CHB_Data]=R4; 
.else 
	[P_CHA_Data]=R4; 
.endif 
 
	R5 -= 1; 
//	cmp R2,R5; 
	jnz  ?M_SACM_SendFIFO1and2_loop#; 
.ENDM 
 
M_SACM_SendFIFO1and2MP3: .MACRO depth 
 
?M_SACM_SendFIFO1and2_MP3:	//== Running with loop unrolling 
	R3 = [R2++]; 
	MR = R1 * R3, us; 
////////////////////////////////////// 
//	M_SACM_Gain R4,R3 
	R4 ^= 0x8000; 
////////////////////////////////////// 
	[P_CHA_Data]=R4; 
////////////////////////////////////// 
	R3 = [R2++]; 
	MR = R1 * R3, us; 
////////////////////////////////////// 
//	M_SACM_Gain R4,R3 
	R4 ^= 0x8000; 
	[P_CHA_Data]=R4; 
 
	R5 -= 1; 
	jnz  ?M_SACM_SendFIFO1and2_MP3; 
	[R_Right_ChannelData] = R4 
	[R_Left_ChannelData] = R4 
.ENDM 
 
//=================================================== 
//xiaolei add for S200 Play 2006/08/17 
M_SACM_SendFIFO1and2S200: .MACRO depth 
//	R5 = depth + R2;			//== FIFO count=depth. 
 
?M_SACM_SendFIFO1and2_S200:	//== Running with loop unrolling 
	R3 = [R2++]; 
	MR = R1 * R3, us; 
////////////////////////////////////// 
	//M_SACM_Gain R4,R3 
	r3=r3 lsl 4 
 
	CMP R4, (16384-4); 
	JGE ?_chk_max_S200; 
	CMP R4, -16384; 
	JL ?_chk_min_S200; 
	R4 = R4 RoL 1; 
	JMP ?_Volume_end_S200; 
?_chk_max_S200: 
	R4 = (16384 - 4) * 2 - 1; 
	JMP ?_Volume_end_S200; 
?_chk_min_S200: 
	R4 = (-16384) * 2; 
?_Volume_end_S200: 
	r4 ^= 0x8000; 
////////////////////////////////////// 
	[P_CHA_Data]=R4; 
.if 0						//For 162001 Platform use only 
	[P_CHB_Data]=R4; 
.else 
	[P_CHA_Data]=R4; 
.endif 
 
	R5 -= 1; 
//	cmp R2,R5; 
	jnz  ?M_SACM_SendFIFO1and2_S200; 
.ENDM 
//===================================================== 
 
////////////////////////////////////////////////////////////////////// 
//.define dumpdacdata 
.ifdef dumpdacdata 
	.external temptest_l, temptest_h 
.endif 
 
////////////////////////////////////////////////////////////////////// 
M_SACM_SendFIFO1: .MACRO depth 
	R5 = depth + R2;		//=== FIFO count=depth. 
 
?M_SACM_SendFIFO1_loop#:		//=== Running with loop unrolling 
 
	R3 = [R2++]; 
 
//************************************* 
.ifdef dumpdacdata 
	push r1,r2 to [sp] 
	r1 = [temptest_h] 
	ds = r1 
	r2 = [temptest_l] 
	ds:[r2++] = r3 
	[temptest_l] = r2 
	r1 = ds 
	[temptest_h] = r1 
	pop r1,r2 from [sp] 
.endif 
//************************************* 
 
	MR = R1 * R3, us; 
 
////////////////////////////////////// 
	M_SACM_Gain R4,R3	//mgl 2005/03/29 
//////////////////////////////////////// 
//	R4=R4+0x0020; 
//	R4=R4^0x8000;		//mgl 2005/03/29 
/////////////////////////////////////// 
	[P_CHA_Data]=R4; 
 
	cmp R2,R5; 
	jnz  ?M_SACM_SendFIFO1_loop#; 
.ENDM 
 
////////////////////////////////////////////////////////////////////// 
M_SACM_SendFIFO2: .MACRO depth 
	R5 = depth + R2;		//=== FIFO count=depth. 
 
?M_SACM_SendFIFO2_loop#:		//=== Running with loop unrolling 
	R3 = [R2++]; 
	MR = R1 * R3, us; 
////////////////////////////////////// 
	M_SACM_Gain R4,R3	//mgl 2005/03/29 
//////////////////////////////////////// 
//	R4=R4+0x0020; 
//	R4=R4^0x8000;		//mgl 2005/03/29 
/////////////////////////////////////// 
	[P_CHB_Data]=R4; 
 
	cmp R2,R5; 
	jnz  ?M_SACM_SendFIFO2_loop#; 
.ENDM 
 
////////////////////////////////////////////////////////////////////// 
M_SACM_SendNOFIFO: .MACRO arg1 
	R2 += arg1; 
.ENDM 
 
////////////////////////////////////////////////////////////////////// 
// Function:	M_SACM_SendFIFO 
// Description:	send data to DAC1 from library 
// Author:	cfwei 20040421 
// Syntax:	M_SACM_SendFIFO* 
// Destory:	R3,R4 
// Parameter:	R1=[R_SACM_Play_Gain], R2=[R_SACM_DAC_Out_PTR_Play], R3=[R_SACM_Play_Flag] 
// Return:	R2= new [R_SACM_DAC_Out_PTR_Play] 
////////////////////////////////////////////////////////////////////// 
M_SACM_SendFIFO_noGain: .MACRO depth 
	R5 = depth + R2;			//=== FIFO count=depth. 
 
?M_SACM_SendFIFO_noGain_loop#:		//=== Running with loop unrolling 
	R3 = [R2++]; 
	MR = R1 * R3, us; 
//////////////////////////////////////// 
//	R4=R4+0x0020;		//mgl 2005/03/29 for SPL162001 
	R4=R4^0x8000; 
/////////////////////////////////////// 
	[P_CHA_Data]=R4; 
	[P_CHB_Data]=R4; 
 
	cmp R2,R5; 
	jnz  ?M_SACM_SendFIFO_noGain_loop#; 
.ENDM 
 
////////////////////////////////////////////////////////////////////// 
// Function:	F_SACM_SendDACMulti 
// Description:	send data to DAC 
// Syntax:	F_SACM_SendDACMulti 
// Destory:	R1 
// Parameter:	in: R3= [R_SACM_Play_Flag] 
// Return:	out: R2 as new R_SACM_DAC_Out_PTR_Play 
////////////////////////////////////////////////////////////////////// 
F_SACM_SendDACMulti: .proc 
//====== fill data to FIFO begin ====== 
	R2 = [R_DAC_OUT_isUpSampling]; 
	jz ?_doNormalSampling 
	goto L_doUpSampling					//xiaolei test end 2006/09/09 
?_doNormalSampling: 
//====== rewriten by cfwei 20040416 begin ================ 
	R2 = [R_SACM_DAC_Out_PTR_Play]; 
	R5 = [R_DAC_OUT_FIFO_Depth] 
	R1 = [R_CODEC_TYPE] 
	cmp R1, C_CODEC_MP3		//Here wait to be modified for the high effection 
	je ?L_MP3UseOnly 
	goto ?L_NotS200MP3 
	//jne ?L_NotS200MP3 
//=========================================================================== 
?L_MP3UseOnly:					//MP3 use the DAC1 and DAC2 when playing 
//.comment @					//xiaolei add for MP3 Playing noise 
.ifdef MP3_DECODE_EFFECT 
	r1 = [R_Decode_Finish_A] 
	jnz	?MP3_DAC_conti 
	R5 = [R_DAC_OUT_FIFO_Depth] 
?MP3_Mute_Conti: 
	r1 = [R_Right_ChannelData] 
	[P_CHA_Data] = r1 
	r1=[R_Left_ChannelData] 
	[P_CHA_Data] = r1 
	R5 -= 1 
	jnz ?MP3_Mute_Conti 
	retf 
?MP3_DAC_conti: 
.endif 
//@ 
.ifdef C_SND_MP3_SETVOLMUME 
	R1 = [R_SACM_Play_MP3_Gain] 
.else 
	R1 = [R_SACM_Play_Gain]; 
.endif 
	M_SACM_SendFIFO1and2MP3 R5; 
	retf						//MP3 Reduce Interrupt time 2006/09/09 
?L_NotS200MP3: 
//=========================================================================== 
	R1 = [R_SACM_Play_Gain]; 
	test R3,C_SACM_ENABLE_DAC1; 
	jnz ?NS_has_DAC1 
	goto ?NS_no_DAC1; 
?NS_has_DAC1: 
	test R3,C_SACM_ENABLE_DAC2; 
	jz ?NS_has_DAC1_no_DAC2; 
 
?NS_has_DAC1_has_DAC2:  //==== Running with loop unrolling 
	M_SACM_SendFIFO1and2 R5; 
	retf 
 
?NS_has_DAC1_no_DAC2:   //==== Running with loop unrolling 
	M_SACM_SendFIFO1 R5; 
	retf 
 
?NS_no_DAC1: 
	test R3,C_SACM_ENABLE_DAC2; 
	jz ?NS_no_DAC1_no_DAC2; 
 
?NS_no_DAC1_has_DAC2:   //==== Running with loop unrolling 
	M_SACM_SendFIFO2 R5; 
	retf 
 
?NS_no_DAC1_no_DAC2:    //==== Running 
	//=== skip all calculation.. 
	M_SACM_SendNOFIFO R5; 
	retf 
//======== rewriten by cfwei 20040729 end =================== 
L_doUpSampling: 
	cmp R2,1 
	jz ?_doMultiUpSampling 
	//goto ?_doSingleUpSampling 
	goto ?_doNormal_noGain 
?_doMultiUpSampling: 
.ifdef C_SND_UPSAMPLE_16KHZ 
	call F_FIFO1and2_MultiUS16KHz //xiaolei modify to a function 2006/06/03 
.else 
	.ifdef C_SND_UPSAMPLE_32KHZ 
		call F_FIFO1and2_MultiUS32KHz 
	.endif 
.endif	//C_SND_UPSAMPLE_16KHZ end 
	R2 = [R_SACM_DAC_Out_PTR_Play] 
	goto L_sFIFO_finish 
 
?_doNormal_noGain: 
	R2 = [R_SACM_DAC_Out_PTR_Play]; 
	R1 = [R_SACM_Play_Gain]; 
	R5 = [R_DAC_OUT_FIFO_Depth] 
	M_SACM_SendFIFO_noGain R5; 
//======== rewriten by cfwei 20050106 end ================== 
L_sFIFO_finish: 
	retf 
//====== fill data to FIFO end ====== 
.endp 
 
.ifdef C_SND_CTTS_SUPPORT			//For CTTS PCM Datas Play 
 
.external _pPCMWriteBuffer 
.external _pPCMReadLength 
.external _pPCMWriteLength 
.external _PCMBufferSize 
.external _CTTS_EndFlag 
M_SACM_SendPCMFIFO1and2: .macro 
?L_SendData12: 
	R3 = DS:[R2++] 
	MR = R1 * R3, us; 
	M_SACM_Gain R4,R3 
	[P_CHA_Data] = R4; 
	[P_CHA_Data] = R4; 
	[R_DAC_ReservedData] = R4 
	R5 -= 1 
	jnz ?L_SendData12 
.endm 
 
M_SACM_SendPCMFIFO1: .macro 
?L_SendData1: 
	R4 = DS:[R2++] 
	R3 = DS:[R2++] 
	MR = R1 * R3, us; 
	M_SACM_Gain R4,R3 
	[P_CHA_Data]=R4; 
	[R_DAC_ReservedData] = R4 
	R5 -= 1 
	jnz ?L_SendData1 
.endm 
 
M_SACM_SendPCMFIFO2: .macro 
?L_SendData2: 
	R4 = DS:[R2++] 
	R3 = DS:[R2++] 
	MR = R1 * R3, us; 
	M_SACM_Gain R4,R3 
	[P_CHA_Data]=R4; 
	[R_DAC_ReservedData] = R4 
	R5 -= 1 
	jnz ?L_SendData2 
.endm 
 
.public F_SendPCMData 
F_SendPCMData: .proc 
	R2 = sr 
	push R2 to [sp] 
	R1 = [_pPCMReadLength] 
	R3 = [_CTTS_EndFlag] 
	cmp R3, 1 
	jne ?L_NormalRoute 
	R3 = [_pPCMWriteLength] 
	cmp R1, R3 
	jne ?L_NormalRoute 
	R1 = 1							//Send data over 
	goto ?L_DataSendOver 
?L_NormalRoute: 
	R3 = [_pPCMWriteLength] 
	cmp R1, R3 
	jne ?L_NormalContinue 
	R5 = [R_DAC_OUT_FIFO_Depth]		//Get the depth 
	R4 = [R_SACM_Play_Flag]; 
	test R4,C_SACM_ENABLE_DAC1; 
	jnz ?NS_has_DAC1_Mute 
	jmp ?NS_no_DAC1_Mute; 
?NS_has_DAC1_Mute: 
	test R4,C_SACM_ENABLE_DAC2; 
	jz ?NS_has_DAC1_no_DAC2_Mute; 
?NS_has_DAC1_has_DAC2_Mute:  //==== Running with loop unrolling 
?L_12: 
	R4 = [R_DAC_ReservedData] 
	[P_CHA_Data] = R4; 
	[P_CHA_Data] = R4; 
	R5 -= 1 
	jnz ?L_12 
	R1 = 0 
	goto ?L_DataSendOver 
?NS_has_DAC1_no_DAC2_Mute:   //==== Running with loop unrolling 
?L_1: 
	R4 = [R_DAC_ReservedData] 
	[P_CHA_Data] = R4; 
	R5 -= 1 
	jnz ?L_1 
	R1 = 0 
	goto ?L_DataSendOver 
?NS_no_DAC1_Mute: 
	test R4,C_SACM_ENABLE_DAC2; 
	jz ?NS_no_DAC1_no_DAC2_Mute; 
?NS_no_DAC1_has_DAC2_Mute:   //==== Running with loop unrolling 
?L_2: 
	R4 = [R_DAC_ReservedData] 
	[P_CHA_Data] = R4; 
	R5 -= 1 
	jnz ?L_2 
	R1 = 0 
?NS_no_DAC1_no_DAC2_Mute: 
	goto ?L_DataSendOver 
?L_NormalContinue: 
	R2 = [_pPCMWriteBuffer] 
	R2 += R1						//Offset for DS Carry 
	R2 = [_pPCMWriteBuffer + 1] 
	R2 += 0, Carry 
	DS = R2							//DS 
	R2 = [_pPCMWriteBuffer] 
	R2 += R1						//Offset 
	R5 = [R_DAC_OUT_FIFO_Depth]		//Get the depth 
	R1 += R5						//The New Length 
	R3 = [_PCMBufferSize] 
	cmp R1, R3 
	jb ?L_SetNewLength 
	R1 = 0						//说明该次是本句话的最后一句播放 
?L_SetNewLength: 
	[_pPCMReadLength] = R1 
	R4 = [R_SACM_Play_Flag]; 
	R1 = [R_SACM_Play_Gain]; 
	test R4,C_SACM_ENABLE_DAC1; 
	jnz ?NS_has_DAC1 
	goto ?NS_no_DAC1; 
?NS_has_DAC1: 
	test R4,C_SACM_ENABLE_DAC2; 
	jz ?NS_has_DAC1_no_DAC2; 
 
?NS_has_DAC1_has_DAC2:  //==== Running with loop unrolling 
	M_SACM_SendPCMFIFO1and2; 
	R1 = 0 
	jmp ?L_DataSendOver 
 
?NS_has_DAC1_no_DAC2:   //==== Running with loop unrolling 
	M_SACM_SendPCMFIFO1; 
	R1 = 0 
	jmp ?L_DataSendOver 
 
?NS_no_DAC1: 
	test R4,C_SACM_ENABLE_DAC2; 
	jz ?NS_no_DAC1_no_DAC2; 
 
?NS_no_DAC1_has_DAC2:   //==== Running with loop unrolling 
	M_SACM_SendPCMFIFO2; 
	R1 = 0 
	jmp ?L_DataSendOver 
 
?NS_no_DAC1_no_DAC2: 
?L_DataSendOver: 
	pop R2 from [sp] 
	sr = R2 
	retf 
.endp 
 
.endif		//End of C_SND_CTTS_SUPPORT definition 
//============================================================ 
//Function:	F_SP_SACM_MP3_SetSampleRate 
//Describ:	Set the SampleRate of the MP3 play 
//============================================================ 
.ifdef C_SND_MP3_SUPPORT 
 
.external R_MP3_Sf_ind				//added by benwang 20060111 
 
.public F_SP_SACM_MP3_SetSampleRate	//added by benwang 20060111 
F_SP_SACM_MP3_SetSampleRate:		//added by benwang 20060111 
	push r3,r4 to [sp];			//added by benwang 20060111 
	r3 = [R_MP3_Sf_ind];		//added by benwang 20060111 
.ifdef NANDBOOT_NOTEXT 
	r4 = seg T_MP3_DAC_Timer 
	ds = r4 
	r4 = offset T_MP3_DAC_Timer 
	r3 += r4 
	r3 = ds:[r3] 
.else 
	r3 += T_MP3_DAC_Timer;		//added by benwang 20060111 
	r3=[r3] 
.endif 
	r4=[P_CHA_Ctrl] 
	r4&=~0x0f 
	r4|=r3 
	[P_CHA_Ctrl]=r4 
 
	//r3 = [r3];					//added by benwang 20060111 
	//r3 = r3 asr 1;				//added by benwang 20060111 
	//[P_TimerE_Preload] = r3		//added by benwang 20060111 
	pop r3,r4 from [sp];			//added by benwang 20060111 
	retf; 
.endif 
 
//================================================================== 
//Add LPF table in .TEXT section 
.ifdef NANDBOOT_NOTEXT 
	//code 
.else 
	SACM_Text:	.section .TEXT 
.endif 
OFILTER_COEF_EA:// define  for 16KHz DAC 
//.dw 0xFF15,0x0155,0xFE1C,0x02AC,0xFC22,0x0600,0xF4B4,0x3993,0x1312,0xF815,0x04C1,0xFCCE,0x023E,0xFE69,0x011D,0xFF40 
//.dw 0xFF15,0x0155,0xFE1C,0x02AC,0xFC22,0x0600,0xF4B4,0x3993,0x1312,0xF815,0x04C1,0xFCCE,0x023E,0xFE69,0x011D,0xFF40 
//.dw 0xFF40,0x011D,0xFE69,0x023E,0xFCCE,0x04C1,0xF815,0x1312,0x3993,0xF4B4,0x0600,0xFC22,0x02AC,0xFE1C,0x0155,0xFF15 
//.dw 0xFF40,0x011D,0xFE69,0x023E,0xFCCE,0x04C1,0xF815,0x1312,0x3993,0xF4B4,0x0600,0xFC22,0x02AC,0xFE1C,0x0155,0xFF15 
//.define OFILTER_COEF_SA (OFILTER_COEF_EA+16) 
.dw -2048,12288, 6144,0 
.dw -2048,12288, 6144,0 
.dw     0,    0,16384,0 
.dw     0,    0,16384,0 
.define OFILTER_COEF_SA (OFILTER_COEF_EA+4) 
 
.ifdef C_SND_UPSAMPLE_16KHZ 
// define  for 16KHz DAC 
OFILTER_COEF_16_EA:		//64	xiaolei add the new code form guangqi 2006/06/03 
	.dw 0xFF15,0x0155,0xFE1C,0x02AC,0xFC22,0x0600,0xF4B4,0x3993,0x1312,0xF815,0x04C1,0xFCCE,0x023E,0xFE69,0x011D,0xFF40 
	.dw 0xFF15,0x0155,0xFE1C,0x02AC,0xFC22,0x0600,0xF4B4,0x3993,0x1312,0xF815,0x04C1,0xFCCE,0x023E,0xFE69,0x011D,0xFF40 
	.dw 0xFF40,0x011D,0xFE69,0x023E,0xFCCE,0x04C1,0xF815,0x1312,0x3993,0xF4B4,0x0600,0xFC22,0x02AC,0xFE1C,0x0155,0xFF15 
	.dw 0xFF40,0x011D,0xFE69,0x023E,0xFCCE,0x04C1,0xF815,0x1312,0x3993,0xF4B4,0x0600,0xFC22,0x02AC,0xFE1C,0x0155,0xFF15 
.define OFILTER_COEF_16_SA (OFILTER_COEF_16_EA + 16) 
.endif	//end C_SND_UPSAMPLE_16KHZ definition 
 
.ifdef C_SND_UPSAMPLE_32KHZ		//xiaolei add 2006/06/04 for 32KHz UpSampling 
OFILTER_COEF_32_EA:// define  for 32KHz DAC 
	.dw 0xFFCC, 0x00DD, 0xFD25, 0x1F33, 0x03F9, 0xFED3, 0x004E, 0xFFEB 
	.dw 0xFFCC, 0x00DD, 0xFD25, 0x1F33, 0x03F9, 0xFED3, 0x004E, 0xFFEB 
	.dw 0xFFAC, 0x0183, 0xFAE7, 0x18A2, 0x0E3A, 0xFC32, 0x0111, 0xFFC4 
	.dw 0xFFAC, 0x0183, 0xFAE7, 0x18A2, 0x0E3A, 0xFC32, 0x0111, 0xFFC4 
	.dw 0xFFC4, 0x0111, 0xFC32, 0x0E3A, 0x18A2, 0xFAE7, 0x0183, 0xFFAC 
	.dw 0xFFC4, 0x0111, 0xFC32, 0x0E3A, 0x18A2, 0xFAE7, 0x0183, 0xFFAC 
	.dw 0xFFEB, 0x004E, 0xFED3, 0x03F9, 0x1F33, 0xFD25, 0x00DD, 0xFFCC 
	.dw 0xFFEB, 0x004E, 0xFED3, 0x03F9, 0x1F33, 0xFD25, 0x00DD, 0xFFCC 
.define OFILTER_COEF_32_SA (OFILTER_COEF_32_EA + 8) 
.endif	//End of C_SND_UPSAMPLE_32KHZ definition 
 
.ifdef C_SND_MP3_SUPPORT 
T_MP3_DAC_Timer:  //{ 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 }; 
.dw  C_MP3_sf_44K1, 	C_MP3_sf_48K, 	C_MP3_sf_32K 
.dw  C_MP3_sf_22K05, 	C_MP3_sf_24K,	C_MP3_sf_16K 
.dw  C_MP3_sf_11K025,	C_MP3_sf_12K,	C_MP3_sf_8K 
.endif	//C_SND_MP3_SUPPORT end 
//==================================================================