www.pudn.com > OS.rar > SACM_API.asm, change:2007-01-22,size:91225b


////////////////////////////////////////////////////////////////////////////////////////// 
// Progarm:	decoding algorithm template V1.0 
// Writen by:	Samsung 
// Modified by:	Arthur 
// Last modified date: 
//		2003/02/27: First version, API proposal 
// Written by Sam Sung, 2003/01/28 
// 
//Note: 
// 1. Naming rule for assembly 
//      R_: RAM 
//      L_: Label 
//      F_: Function 
//      C_: Constant 
//      T_: Table 
// 2. This file includes APIs for user to develope project. 
//    It is to be prepared by design deptartment. 
////////////////////////////////////////////////////////////////////////////////////////// 
 
//============================================= 
.define SND_CB_RECEND 
.define SND_CB_RECFULL 
 
//============================================= 
// Function declarations 
.include .\system\GPL162002_Far\include\system\GPL162002.inc 
.include ..\Include\sacm.inc				// hardware set 
.include ..\Include\SACM_Constant.inc		// PlayFlag Definitions 
.include ..\Include\Snd_ArithmConfig.inc	// define compiler config const 
.include ..\Include\Ram_External.inc		// var declarations 
.include ..\Include\Reuse_Memory.inc		// all reuse RAM variables 
.include ..\Include\SACM_Decode.inc			// Function declarations 
.include ..\Include\SACM_Speed.inc			// Speed Function declarations 
 
.ifdef C_SND_DVR_SUPPORT 
	.external F_USER_DVR1600_EndRecord		//added by benwang 01.02 
	.external F_USER_DVR1600_GetData     	// in sacm_user.asm 
	.external F_USER_DVR1600_WriteData 
.endif 
 
.ifdef C_2002_CODE_ICA 
	.external R_BITRATE 
.endif 
 
.ifdef C_SND_MP3_SUPPORT 
	.external _R_MPEGBitRate; 
	.external _R_SampleRate; 
	.external _gCurSecondTime; 
	 
	.external _Snd_MP3_Status 
	.external _MediaPlayer_PlayAB 
	.external _PlayNextFile 
	.external _ulFrame_Count_MP3 
 
.endif		//End of C_SND_MP3_SUPPORT definition 
 
.external F_USER_GetData			//xiaolei modify 
.external F_SACM_GetADC_More 
//---------------------------------------- 
// Playback Functions(Assembly)/ APIs (C) 
//------------------------------------------ 
.public _SACM_Initial 
.public _SACM_Play 
.public _SACM_Middle_Play		//guili 2005.11.1 
.PUBLIC _SACM_EnableDAC		//guili 2005.11.3 
.public _SACM_Stop 
.public _SACM_DECODE_End_STOP		//guili 2005.11.1 
.public _SACM_Volume 
.public _SACM_Status 
.public _SACM_Pause 
.public _SACM_Resume 
//.public _SACM_ServiceLoop	//removed cfwei 20050103 
.public _SACM_DECODE_ServiceLoop 
.public _SACM_Speed 
.public _SACM_Pitch0 
.public _SACM_Pitch1 
.public _SACM_Voice 
.public _SACM_Pitch 
.public _SACM_Spectrum 
.public _SACM_Codec 
 
.ifdef C_SND_DVR_SUPPORT //=================== 
	.public _SACM_Rec 
	.public F_SACM_Rec 
	.public _SACM_ENCODE_ServiceLoop 
	.public F_ISR_Service_SACM_Encode 
 
	.public _SACM_Encode_Stop_Process	//guili 2005.12.06 
	.public F_SACM_Encode_Stop_Process	//guili 2005.12.06 
.endif // C_SND_DVR_SUPPORT ================== 
 
.ifdef C_SND_S200TTS_SUPPORT 
	.external F_SACM_S200TTS_Decode_Init_BS 
	//.external F_SACM_LRC_Decode_Initial_BS 
.endif	//end of C_SND_S200TTS_SUPPORT definition 
 
.public F_SACM_Initial 
.public F_SACM_Init 
.public F_SACM_Play 
.public F_SACM_Stop 
.public F_SACM_Volume 
.public F_SACM_Status 
.public F_SACM_Pause 
.public F_SACM_Resume 
.public F_SACM_Speed 
.public _SACM_Get_Speed 
 
.ifdef C_SND_DVR1800_SUPPORT 
	.public F_SACM_DVR1800_BITRATE 
	.public _SACM_DVR1800_BITRATE 
//.else 
//	.ifdef C_SND_A1800_SUPPORT 
//		.public F_SACM_DVR1800_BITRATE 
//		.public _SACM_DVR1800_BITRATE 
//	.endif 
.endif 
 
//.public F_SACM_ServiceLoop //removed cfwei 20050103 
//.public F_SACM_ServiceLoop_ISR 
//.public F_ISR_Service_SACM_Speed_FG 
.public F_ISR_Service_SACM_Decode 
 
//*********************************************************** 
.external _Snd_onAmpOn 
.external _Snd_onAmpOff 
//.external _Snd_onRecEnd 
.external _Snd_onRecStop 
.external _Snd_onRecFull 
 
//======================================================== 
.ifdef C_SND_ETTS_SUPPORT 
	.external _CheckETTSStatus 
.endif 
 
//======================================================== 
.ifdef C_SND_CTTS_SUPPORT 
	.external _Snd_TTS_IsPlaying 
	.external _Snd_CTTS_IsPlaying 
	.define C_CTTSETTS_PLAYING 	2 
	.define C_CTTS_PLAYING		2 
.endif 
	.external _SACM_Decode_Length_L 
 
//======================================================== 
.ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
	.external _SACM_A1600_ModeCode 
	.external _ulFrame_Count 
.else 
	.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
		.external _SACM_Decode_Length_L 
		.external _SACM_Decode_Length_H 
		.external _SACM_A1800_ModeCode 
		.external _ulFrame_Count 
	.endif 
.endif 
//======================================================== 
 
//memory 
.external _SndSACM_curPlayID 
.external _SndSACM_curDACConfig 
 
.external R_F_SACM_Stop_Var 
 
.external OFILTER_BUF			//added by benwang 0322 
.external OFILTER_BUF_PTR		//added by benwang 0322 
 
.ifdef C_SND_UPSAMPLE_16KHZ 
	.external DAC_16K_FLAG		//added by benwang 0322 
.endif	//end C_SND_UPSAMPLE_16KHZ 
 
.ifdef C_SND_UPSAMPLE_32KHZ 
	.external DAC_32K_FLAG			//xiaolei add 2006/06/05 
.endif		//end C_SND_UPSAMPLE_32KHZ 
 
.external AD_CBUF			//added by benwang 0322 
.external AD_BUF_PTR			//added by benwang 0322 
.external R_ISR_16K			//added by zgq 2005/03 
.external R_SPEED_MAX_PITCH_LENGTH	//added by zgq 2005/03 
.external R_SPEED_PITCH_STEP		//added by zgq 2005/03 
 
OVERLAP_RAM_SACM_API:	.SECTION	.ORAM //added by benwang 01.04 
	.public REC_STATUS			//added by benwang 01.04 
	.var PLAY_STATUS 			//added by benwang 01.04 
	.var REC_STATUS				//added by benwang 01.04 
.ifdef C_SND_DVR_SUPPORT 
	.public _SACM_Encode_Length_L	//add by cfwei20041210 
 
	.var _SACM_Encode_Length_L 	//add by cfwei20041210 
	.var _SACM_Encode_Length_H 	//add by cfwei20041210 
.endif 
 
//*********************************************************** 
//.define dumpdacdata 
.ifdef dumpdacdata 
     .ram 
     .public temptest_l, temptest_h 
     .var temptest_l, temptest_h 
.endif 
 
//======================================================== 
 
//==================================================================================== 
.ifdef C_SND_MP3_SUPPORT 
.var Temp1 //20060605 
.var Temp2 //20060605 
.var Temp3 //20060605 
.var Temp4 //20060605 
.comment @ 
	.public R_MP3_SKIP_DATA_L, R_MP3_SKIP_DATA_H 
	.var R_MP3_SKIP_DATA_L, R_MP3_SKIP_DATA_H 
//@ 
.ifdef C_SND_MP3_SETVOLMUME 
	.public R_SACM_Play_MP3_Gain 
 
	.var R_SACM_Play_MP3_Gain 
.endif 
 
.external	R_MP3_Decode_Count_L, R_MP3_Decode_Count_H 
.external	Mp3_FrameCount_L, Mp3_FrameCount_H 
.external	MP3_TimeInfo 
.external	MP3_FS 
.external	MP3_BR 
 
.endif	//End of C_SND_MP3_SUPPORT definition 
//================================================================================== 
SACM_ROM_BLOCK:  .SECTION        .CODE 
.dw 0xE9B6,0x2020,0xCFB0,0xD0B3,0xB720,0x2073,0x40A4,0xF4B8,0x3120,0x2039,0xB9B8 
 
//============================================================== 
//		common APIs for encode + decode 
//============================================================== 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Initial 
// Description:	Kernel initialization and calls HW initial 
// Syntax:	SACM_Initial 
// 
// Parameter:	optional 
// Return:	optional 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Initial: .proc 
F_SACM_Initial: 
	push R1,R2 to [sp]; 
 
	fir_mov off; 
	fraction off 
 
.ifdef dumpdacdata 
	r1 = 0 
	[temptest_l] = r1 
	r1 = 0x28 
	[temptest_h] = r1 
.endif 
 
	R1 = 0x0000; 
	[R_SACM_Play_Flag] = R1; 
//	[R_Decode_Finish]=r1				//add by jacky 2006.02.15	xiaolei add OS 
	R1 = 0x4000; 
	[R_SACM_Play_Gain] = R1; 
 
.ifdef C_SND_DVR_SUPPORT 
	R1 = 0x0000; 
	[PLAY_STATUS] = R1;			//added by cfwei20050113 
	[REC_STATUS] = R1;			// add by cfwei 20050113 
	[_SACM_Encode_Length_H] = R1;	//added by cfwei20050113 
	R1 = 0x8000; 
	[_SACM_Encode_Length_L] = R1;	//added by cfwei20050113 
 
	R1 = 0x0000; 
	[R_ADC_Channel] = R1;			// added by benwang 01.02 
 
	R1 = 5;					//added by benwang 01.02, default 24 KHz 
	[BITRATE] = R1; 
.endif // C_SND_DVR_SUPPORT 
 
	R1 = 12; 
	[R_SACM_SpeedIndex] = R1; 		//debugged by benwang 
 
	R1 = C_CODEC_A1600;			//benwang modified 
	[R_CODEC_TYPE] = R1;			//benwang 12.16 
	R1 = 0					//add by zgq 2005/03/14 
	[R_SACM_ISR_Flag]=R1;		//benwang 
 
	R1 = 0x0002;				//added by benwang start 12.16 
	[R_SACM_Play_Pitch0] = R1; 
	[R_SACM_Play_Pitch1] = R1; 
	[R_SACM_Play_Voice] = R1;		//added by benwang end 12.16 
 
.ifdef C_SND_S320_SUPPORT			//female 
	r1 = 12; 				//for S320 2005/03/31 
	[R_SACM_Play_Pitch] = R1; 		//for S320 2005/03/31 
	[R_SACM_Play_Spectrum] = R1; 		//for S320 2005/03/31 
.endif 
 
	R1 = 0;  				//cfwei 20040722 for 005ROM 
	[R_ISR_16K] = R1;			//0-->8k, 1-->16k //added by benwang 01.09 
 
	//added by benwang start 01.08 
	R1 = 128 ; //temp modified by benwang 2004/04/06, 8KHz 
	[R_SPEED_MAX_PITCH_LENGTH] = R1; 
	R1 = 6 ; 
	[R_SPEED_PITCH_STEP] = R1; 
	//added by benwang end 01.08 
 
	//------------------------------- 
.ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
	r1 = 0					//guili 2005.09.03 for A1600 tiaobo 
	[_ulFrame_Count] = r1 
	[_ulFrame_Count+1] = r1 
.else 
	.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
		r1 = 0					//guili 2005.09.03 for A1600 tiaobo 
		[_ulFrame_Count] = r1 
		[_ulFrame_Count+1] = r1 
	.endif 
.endif 
 
.ifdef C_SND_MP3_SUPPORT 
	r1 = 0 
	[_ulFrame_Count_MP3] = r1 
	[_ulFrame_Count_MP3 + 1] = r1 
.endif 
	//------------------------------- 
 
	// HW initial				//because nothing do in it 
	//call F_SACM_Decode_Initial_DAC;	// call kernal initial	//removed by cfwei 200404021 
	//call F_SACM_Speed_Init;		// call HW initial	//removed by cfwei 200404021 
	//call F_SACM_Init; 
	pop R1,R2 from [sp] 
	retf; 
.endp 
 
//////////////////////////////////////////////////////// 
// Function: F_SACM_Init 
// Description: Hardware initilazation DAC 
// Destory   : 
// Parameter : None 
// Return    : None 
// Please note that users can not destroy R5 while 
//        Define this function call 
//////////////////////////////////////////////////////// 
//xiaolei add 2006/08/02 according to the pure project named as 001code, the Algrithem project 
F_SACM_Init: //add by benwang 20060111 
	push	r1,r5 to [sp] 
	FIR_MOV OFF; 
	 
	r1=0x8600 
	r1|=C_SampleRate_22_05K 
	[P_CHA_Ctrl]=r1 
 
	r1 = 0x1000 
	[P_CHB_Ctrl] = r1		//Set Sample Rate CHB be the same with CHA, monochrome 
 
   	r1 = 0x0100 
   	[P_CHA_FIFO]=r1			// Setup CHA FIFO Empty Interrupt Level 
 
   	r1 = 0x0100 
   	[P_CHB_FIFO]=r1			// Setup CHB FIFO Empty Interrupt Level 
 
////////////////////////////// 
	r1=0x01 
	[P_DAC_Ctrl]=r1 
	r1=0x0001 
	[P_DAC_IIS_Ctrl]=r1 
 
	r1=0x0100 
	[P_DAC_Effect_Ctrl]=r1 
///////////////////////////// 
//======================For MP3 Different EQ Mode===================== 
//.comment # 
L_EQ_Parameter: 
wait?: 
		r1=[P_DAC_ACCREQ] 
		jpl	wait? 
		r1=32					//write EQ/AC parameter 
		r5=0x4000 
EQ_loop?: 
		r4=0 
		[P_DAC_ACCDINL]=r4 
		[P_DAC_ACCDINH]=r4 
		[P_DAC_ACCREQ]=r5 
wait1?: 
		r4=[P_DAC_ACCREQ] 
		jpl	wait1? 
		r5+=1 
		r1-=1 
		jnz	EQ_loop? 
 
		r1=13					//write EQ/AC parameter 
		r3=offset T_EQ_COEF 
		r4=seg16 T_EQ_COEF 
		ds=r4 
		r5=0x4020 
EQ_loop1?: 
		r4=ds:[r3++] 
		[P_DAC_ACCDINL]=r4 
		r4=ds:[r3++] 
		[P_DAC_ACCDINH]=r4 
		[P_DAC_ACCREQ]=r5 
wait2?: 
		r4=[P_DAC_ACCREQ] 
		jpl	wait2? 
		r5+=1 
		r1-=1 
		jnz	EQ_loop1? 
//# 
 
.comment @ 
		r1=13					//write EQ/AC parameter 
		r3=offset T_EQ_COEF 
		r4=seg16 T_EQ_COEF 
		ds=r4 
		r5=0x4020 
EQ_loop1?:		 
		r4=ds:[r3++] 
		[P_DAC_ACCDINL]=r4 
		r4=ds:[r3++] 
		[P_DAC_ACCDINH]=r4 
		[P_DAC_ACCREQ]=r5 
wait2?:	 
		r4=[P_DAC_ACCREQ] 
		jpl	wait2? 
		r5+=1 
		r1-=1 
		jnz	EQ_loop1?	 
		 
	 
		r8=7					//write EQ/AC parameter 
		r2=0 
EQ_loop2?:	 
		r3=offset T_EQ_Mode		//live EQ mode 
		r4=seg16 T_EQ_Mode 
		r3+=r2 
		r4+=0,carry 
		ds=r4 
		r1=ds:[r3++] 
		r3=offset T_EQ_GAIN 
		r4=seg16 T_EQ_GAIN	 
		r1=r1 lsl 1 
		r3+=r1 
		r4+=0,carry 
		ds=r4 
		r4=ds:[r3++] 
		[P_DAC_ACCDINL]=r4 
		r4=ds:[r3++] 
		[P_DAC_ACCDINH]=r4 
		r5=r2+0x4040 
		[P_DAC_ACCREQ]=r5 
wait3?:	 
		r4=[P_DAC_ACCREQ] 
		jpl	wait3? 
		r2+=1 
		r8-=1 
		jnz	EQ_loop2?	 
		r1=0x1100 
		[P_DAC_Effect_Ctrl]=r1 
//@ 
//==================For MP3 Different EQ OK add 2006/08/31 end========== 
	r1=0x1000 
wait4?: 
	r1-=1 
	jnz	wait4? 
 
	r1=0x03 
	[P_HPAMP_Ctrl]=r1 
 
	pop	r1,r5 from [sp] 
	retf 
 
//////////////////////////////////////////////////////// 
// Function: F_MP3_EQMode 
// Description: Set MP3 EQ mode 
//               
// Syntax  : F_MP3_EQMode 
// Destory: R1 
// Parameter : EQ type 
// Return    : None 
//////////////////////////////////////////////////////// 
.public	_MP3_EQMode 
_MP3_EQMode: 
	push bp to [sp] 
	bp=sp+1 
	r1=[bp+3] 
	call	F_MP3_EQMode 
	pop	bp from [sp] 
	retf 
 
 
F_MP3_EQMode: 
	r2=0x0100 
	[P_DAC_Effect_Ctrl]=r2 
 
	r2=7 
	mr=r1*r2, us 
	r1=offset T_EQ_Mode 
	r2=seg16 T_EQ_Mode 
	r1+=r3				//r2:r1 is EQ mode address 
	r2+=0,carry			// 
	 
	r9=7					//write EQ/AC parameter 
	r8=0 
	r1+=r8 
	r2+=0,carry 
EQ_loop2?:		 
	ds=r2	 
	r5=ds:[r1++] 
	r2=ds 
	r3=offset T_EQ_GAIN 
	r4=seg16 T_EQ_GAIN 
	r5=r5 lsl 1 
	r3+=r5 
	r4+=0,carry 
	ds=r4 
	r4=ds:[r3++] 
	[P_DAC_ACCDINL]=r4 
	r4=ds:[r3++] 
	[P_DAC_ACCDINH]=r4 
	r4=r8+0x4040 
	[P_DAC_ACCREQ]=r4 
wait3?:	 
	r4=[P_DAC_ACCREQ] 
	jpl	wait3? 
	r8+=1 
	r9-=1 
	jnz	EQ_loop2?	 
	r1=0x1100 
	[P_DAC_Effect_Ctrl]=r1 
	retf 
 
//==============The Table for MP3 EQ Setting Used======================== 
T_EQ_COEF: 
	.dd	0x3F2AEC,0x80DB59,0x3DCDD8,0x825E4A,0x3AA52B, 0x86676F 
	.dd	0x311BE2,0x978040,0x2150F8,0xC4C1F1,0x086CFE,0x1BB754,0xC0D513		 
		 
T_EQ_GAIN: 
	.dd	0x0809BC,0x0904D1,0x0A1E89,0x0B5AA1,0x0CBD4B,0x0E4B3B,0x1009B9,0x11FEB3 
	.dd	0x1430CD,0x16A77D,0x196B23,0x1C8520,0x200000,0x23E793,0x28491E,0x2D3382 
	.dd	0x32B772,0x38E7AA,0x3FD930,0x47A39A,0x50615F,0x5A3031,0x653161,0x718A50 
	.dd	0x7F64F0 
 
 
T_EQ_Mode: 
	.dw	12,12,12,12,12,12,12	// 0. reset 
	.dw	15,14,11,9 ,14,16,16	// 1. Rock 
	.dw	12,12,12,13,11,10,10	// 2. Classical 
	.dw	10,13,15,14,10, 9, 9	// 3. Pop 
	.dw	12,12,13,14,13,14,15	// 4. Jazz 
	.dw	11,12,13,12,13,14,14	// 5. Folk 
	.dw	15,13,11,11,13,15,15	// 6. Disco	 
	.dw	12,12,11,12,14,14,12	// 7. Reggae	 
	.dw	15,15,13, 9, 8,10,16	// 8. Solf Rock		 
	.dw	14,13,12,12,12,13,13	// 9. New Age 
//======================================================================= 
//xiaolei add end for Init the Channel and the DAC at prior. 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Stop 
// Description:	Stop Playback 
// Syntax:	void SACM_Stop(void) 
// Parameter:	N/A 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Stop: .proc 
F_SACM_Stop: 
//.comment @ 
.ifdef MP3_DECODE_EFFECT 
	r1 = 0; 
	[R_Decode_Finish]=r1 
.endif 
//@ 
	R1 = [R_SACM_Play_Flag] 
//---------------------------------------- 
.ifdef C_SND_DVR_SUPPORT //=================== 
	test R1, C_SACM_CODEC_MODE 
	JE _SACM_DECODE_STOP 
 
_SACM_ENCODE_STOP: 
	R1 = [R_SACM_Play_Flag] 
   	test R1, C_SACM_PLAY 
   	jz ?_Branch_0 
 
	R1 |= C_SACM_STOP 
 
?_Branch_0: 
	[R_SACM_Play_Flag] = R1 
 
   	retf 
.endif //ifdef C_SND_DVR_SUPPORT =============== 
 
//---------------------------------------- 
_SACM_DECODE_STOP: 
   	//R1 = [R_SACM_Play_Flag]; //removed by cfwei20040513 
   	test R1, C_SACM_PLAY 
   	jz ?_Branch_0 
.comment $ 
//xiaolei remove the code 2006/08/22 
	push r1,r4 to [sp] 
	call _Snd_onAmpOff		//cfwei20041209 
	pop r1,r4 from [sp] 
$ 
//---------------------------------------- 
// Clear Interrupt Service Flag 
//---------------------------------------- 
	R1 &= ~C_SACM_FIQ_SOUND 
	[R_SACM_Play_Flag] = R1 
 
//---------------------------------------- 
//Added by Anson 2004/1/29 
//      Clear Disable Channel FIFO Empty Interupt 
//      Latch FIFO data to DAC/PWM after writing to control reg 
//---------------------------------------- 
        r1 = [R_SACM_Play_Flag] 
        test r1,C_SACM_ENABLE_DAC1									 //% 
        jz L_EndDACA?											  		 //% 
	call	F_SACM_CHA_PlayInterrupt_Disable 
L_EndDACA?:															  	 //% 
        r1 = [R_SACM_Play_Flag]								     //% 
	test r1,C_SACM_ENABLE_DAC2						 //% 
        jz L_EndDACB?								   //% 
	call	F_SACM_CHB_PlayInterrupt_Disable 
L_EndDACB?: 
										  //% 
//---------------------------------------- 
// Added by Anson 2004/1/29 
//       Wait FIFO empty at this time 
//---------------------------------------- 
//	INT   FIQ,IRQ 		//remarked by cfwei 
//xiaolei remove here 2006/08/22 for When Play S200, the Time Delay in AmpOff is too long 
	push r1,r4 to [sp] 
	call _Snd_onAmpOff		//cfwei20041209 
	pop r1,r4 from [sp] 
//xiaolei add end 2006/08/22 
 
        r1 = [R_SACM_Play_Flag] 
        test r1,C_SACM_ENABLE_DAC1 
        jz L_EndCheckDACA? 
	call	F_SACM_CHA_WaitFIFOEmpty 
L_EndCheckDACA?: 
        r1 = [R_SACM_Play_Flag] 
	test r1,C_SACM_ENABLE_DAC2 
        jz L_EndCheckDACB? 
	call	F_SACM_CHB_WaitFIFOEmpty 
L_EndCheckDACB?: 
//---------------------------------------- 
	r1 = [R_SACM_Play_Flag]								     //% 
	test R1, C_SACM_RAMP_DN_ENABLE 
	jz ?_Branch_0 
 
	test R1, C_SACM_ENABLE_DAC1 
	jz ?_Branch_1 
 
	call F_SACM_RampDnDAC1 
 
?_Branch_1: 
	test R1, C_SACM_ENABLE_DAC2 
	jz ?_Branch_0 
 
	call F_SACM_RampDnDAC2 
 
?_Branch_0: 
        r1 = [R_SACM_Play_Flag] 
        test r1,C_SACM_ENABLE_DAC1 
        jz L_EndDisableDAC1? 
	call F_SACM_DisableDAC1 	//cfwei20041209 
L_EndDisableDAC1?: 
        r1 = [R_SACM_Play_Flag] 
        test r1,C_SACM_ENABLE_DAC2 
        jz L_EndDisableDAC2? 
	call F_SACM_DisableDAC2 	//cfwei20041209 
L_EndDisableDAC2?: 
	call F_SACM_DisableAudioTimer	//cfwei20050101 
 
   	R1 = 0x0000 
   	[R_SACM_Play_Flag] = R1 
//.comment @ 
.ifdef MP3_DECODE_EFFECT 
   	r1 = 1 
	[R_Decode_Finish]=r1 
.endif 
//@ 
.ifdef C_SND_DVR_SUPPORT //=================== 
   	R1 = [PLAY_STATUS]		//added by benwang 01.04 
   	cmp R1, 0			//added by benwang 01.04 
   	jne ?_CheckEnd			//added by benwang 01.04 
   	R1 = 0				//added by benwang 01.04 
   	[REC_STATUS] = R1		//added by benwang 01.04 
?_CheckEnd:   //added by benwang 01.04 
	R1 = 0 
	[PLAY_STATUS] = R1 
.endif //ifdef C_SND_DVR_SUPPORT ============== 
	//------------------------------- 
.ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
	r1 = 0				//guili 2005.09.03 for A1600 tiaobo 
	[_ulFrame_Count] = r1 
	[_ulFrame_Count+1] = r1 
.else 
	.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
		r1 = 0				//guili 2005.09.03 for A1600 tiaobo 
		[_ulFrame_Count] = r1 
		[_ulFrame_Count+1] = r1 
	.endif 
.endif 
	//------------------------------- 
   	retf 
.endp 
 
 
//////////////////////////////////////////////////////// 
_SACM_DECODE_End_STOP:			//guili 2005.11.1 
	push r1,r4 to [sp] 
	call _Snd_onAmpOff		//cfwei20041209 
	pop r1,r4 from [sp] 
 
//---------------------------------------- 
//Added by Anson 2004/1/29 
//      Clear Disable Channel FIFO Empty Interupt 
//      Latch FIFO data to DAC/PWM after writing to control reg 
//---------------------------------------- 
	r1 = [_SndSACM_curDACConfig] 
	test r1,C_DAC1 
	jz L_EndDACA?											  		 //% 
	call	F_SACM_CHA_PlayInterrupt_Disable 
L_EndDACA?:															  	 //% 
	r1 = [_SndSACM_curDACConfig]								     //% 
	test r1,C_DAC2									  	 //% 
	jz L_EndDACB?											  	     //% 
	call	F_SACM_CHB_PlayInterrupt_Disable 
L_EndDACB?: 
																  //% 
//---------------------------------------- 
// Added by Anson 2004/1/29 
//       Wait FIFO empty at this time 
//---------------------------------------- 
//	INT   FIQ,IRQ 		//remarked by cfwei 
        r1 = [_SndSACM_curDACConfig] 
        test r1,C_DAC1 
        jz L_EndCheckDACA? 
	call	F_SACM_CHA_WaitFIFOEmpty 
L_EndCheckDACA?: 
        r1 = [_SndSACM_curDACConfig] 
	test r1,C_DAC2 
        jz L_EndCheckDACB? 
	call	F_SACM_CHB_WaitFIFOEmpty 
L_EndCheckDACB?: 
//---------------------------------------- 
	r1 = [_SndSACM_curDACConfig] 
	test R1, C_DAC1; 
	jz ?_Branch_0; 
	call F_SACM_RampDnDAC1; 
 
?_Branch_0: 
	r1 = [_SndSACM_curDACConfig] 
	test R1, C_DAC2; 
	jz ?_Branch_1; 
	call F_SACM_RampDnDAC2; 
 
?_Branch_1: 
//---------------------------------------- 
        r1 = [_SndSACM_curDACConfig] 
        test r1,C_DAC1 
        jz L_EndDisableDAC1? 
	call F_SACM_DisableDAC1; 	//cfwei20041209 
 
L_EndDisableDAC1?: 
        r1 = [_SndSACM_curDACConfig] 
        test r1,C_DAC2 
        jz L_EndDisableDAC2? 
	call F_SACM_DisableDAC2; 	//cfwei20041209 
 
L_EndDisableDAC2?: 
//---------------------------------------- 
	call F_SACM_DisableAudioTimer;	//cfwei20050101 
 
   	R1 = 0x0000; 
   	[R_SACM_Play_Flag] = R1; 
 
.ifdef C_SND_DVR_SUPPORT //=================== 
   	R1 = [PLAY_STATUS];		//added by benwang 01.04 
   	cmp R1, 0;			//added by benwang 01.04 
   	jne ?_CheckEnd;			//added by benwang 01.04 
   	R1 = 0;				//added by benwang 01.04 
   	[REC_STATUS] = R1;		//added by benwang 01.04 
?_CheckEnd:   //added by benwang 01.04 
	R1 = 0 
	[PLAY_STATUS] = R1 
.endif //ifdef C_SND_DVR_SUPPORT ============== 
 
	//------------------------------- 
.ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
	r1 = 0				//guili 2005.09.03 for A1600 tiaobo 
	[_ulFrame_Count] = r1 
	[_ulFrame_Count+1] = r1 
.else 
	.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
		r1 = 0 
		[_ulFrame_Count] = r1 
		[_ulFrame_Count+1] = r1 
	.endif 
.endif 
	//------------------------------- 
   	retf; 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Stop 
// Description:	Stop Playback 
// Syntax:	void SACM_Stop(void) 
// Parameter:	N/A 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
.public _SACM_Middle_Stop 
_SACM_Middle_Stop: .proc 
F_SACM_Middle_Stop: 
	R1 = [R_SACM_Play_Flag]; 
 
//---------------------------------------- 
_SACM_DECODE_Middle_STOP: 
   	//R1 = [R_SACM_Play_Flag]; //removed by cfwei20040513 
   	test R1, C_SACM_PLAY; 
   	jz ?_Branch_0; 
 
//---------------------------------------- 
// Clear Interrupt Service Flag 
//---------------------------------------- 
	R1 &= ~C_SACM_FIQ_SOUND; 
	[R_SACM_Play_Flag] = R1; 
 
//---------------------------------------- 
//Added by Anson 2004/1/29 
//      Clear Disable Channel FIFO Empty Interupt 
//      Latch FIFO data to DAC/PWM after writing to control reg 
//---------------------------------------- 
        r1 = [R_SACM_Play_Flag] 
        test r1,C_SACM_ENABLE_DAC1									 //% 
        jz L_EndDACA?											  		 //% 
	call	F_SACM_CHA_PlayInterrupt_Disable 
L_EndDACA?:															  	 //% 
        r1 = [R_SACM_Play_Flag]								     //% 
	test r1,C_SACM_ENABLE_DAC2									  	 //% 
        jz L_EndDACB?											  	     //% 
	call	F_SACM_CHB_PlayInterrupt_Disable 
L_EndDACB?: 
																  //% 
//---------------------------------------- 
// Added by Anson 2004/1/29 
//       Wait FIFO empty at this time 
//---------------------------------------- 
	//INT   FIQ,IRQ 		//remarked by cfwei 
        r1 = [R_SACM_Play_Flag] 
        test r1,C_SACM_ENABLE_DAC1 
        jz L_EndCheckDACA? 
	call	F_SACM_CHA_WaitFIFOEmpty 
L_EndCheckDACA?: 
        r1 = [R_SACM_Play_Flag] 
	test r1,C_SACM_ENABLE_DAC2 
        jz L_EndCheckDACB? 
	call	F_SACM_CHB_WaitFIFOEmpty 
L_EndCheckDACB?: 
?_Branch_0: 
	call F_SACM_DisableAudioTimer;	//cfwei20050101 
//---------------------------------------- 
 
   	R1 = 0x0000; 
   	[R_SACM_Play_Flag] = R1; 
 
.ifdef C_SND_DVR_SUPPORT //=================== 
   	R1 = [PLAY_STATUS];		//added by benwang 01.04 
   	cmp R1, 0;			//added by benwang 01.04 
   	jne ?_CheckEnd;			//added by benwang 01.04 
   	R1 = 0;				//added by benwang 01.04 
   	[REC_STATUS] = R1;		//added by benwang 01.04 
?_CheckEnd:   //added by benwang 01.04 
	R1 = 0 
	[PLAY_STATUS] = R1 
.endif //ifdef C_SND_DVR_SUPPORT ============= 
 
	//------------------------------- 
.ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
	r1 = 0				//guili 2005.09.03 for A1600 tiaobo 
	[_ulFrame_Count] = r1 
	[_ulFrame_Count+1] = r1 
.else 
	.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
		r1 = 0				//guili 2005.09.03 for A1600 tiaobo 
		[_ulFrame_Count] = r1 
		[_ulFrame_Count+1] = r1 
	.endif 
.endif 
	//------------------------------- 
   	retf; 
.endp 
 
.ifdef C_SND_CTTS_SUPPORT 
.public _SACM_Middle_StopTTS 
_SACM_Middle_StopTTS: .proc 
	R1 = [R_SACM_Play_Flag]; 
    test r1,C_SACM_ENABLE_DAC1									 //% 
    jz L_EndDACA?											  		 //% 
	call	F_SACM_CHA_PlayInterrupt_Disable 
L_EndDACA?:															  	 //% 
    r1 = [R_SACM_Play_Flag]								     //% 
	test r1,C_SACM_ENABLE_DAC2									  	 //% 
    jz L_EndDACB?											  	     //% 
	call	F_SACM_CHB_PlayInterrupt_Disable 
L_EndDACB?: 
														  //% 
    r1 = [R_SACM_Play_Flag] 
    test r1,C_SACM_ENABLE_DAC1 
    jz L_EndCheckDACA? 
	call	F_SACM_CHA_WaitFIFOEmpty 
L_EndCheckDACA?: 
    r1 = [R_SACM_Play_Flag] 
	test r1,C_SACM_ENABLE_DAC2 
    jz L_EndCheckDACB? 
	call	F_SACM_CHB_WaitFIFOEmpty 
L_EndCheckDACB?: 
?_Branch_0: 
	call F_SACM_DisableAudioTimer;	//cfwei20050101 
//---------------------------------------- 
   	R1 = 0x0000; 
   	[R_SACM_Play_Flag] = R1; 
	retf 
.endp 
.endif		//End of C_SND_CTTS_SUPPORT 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Pause 
// Description:	Pause speech 
// Syntax:	void SACM_Pause(); 
// Parameter:	N/A 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Pause: .proc 
F_SACM_Pause: 
	push R1 to[sp]; 
	push R2 to[sp];			//guili 2005.10.19 
 
	R1 = [R_SACM_Play_Flag]; 
//------------------------------------------- 
//guili 2005.10.19 for DVR pause resume 
.ifdef C_SND_DVR_SUPPORT //=================== 
	test R1, C_SACM_CODEC_MODE; 
	JE _SACM_DECODE_PAUSE; 
 
_SACM_ENCODE_PAUSE: 
	R1 = [R_SACM_Play_Flag]; 
   	test R1, C_SACM_PLAY; 
   	jz ?_Branch_1; 
 
	R2 = 0x8000 
	[P_TimerC_Ctrl] = R2		// Stop TimerC Int 
 
	R2 = [P_ADC_Setup] 
	R2 = R2 & (~0x00c4)		// Stop Auto Sample and Mic and stop auto sample mode 
	[P_ADC_Setup] = R2		// not disable ADC for save time to setup ADC reference voltage 
					// and other module perhaps is using ADC,so must not disable.. 
 
	R1 |= C_SACM_PAUSE; 
 
?_Branch_1: 
	[R_SACM_Play_Flag] = R1; 
 
	pop R2 from [sp] 
	pop R1 from [sp] 
   	retf; 
.endif //ifdef C_SND_DVR_SUPPORT =============== 
 
_SACM_DECODE_PAUSE: 
//guili 2005.10.19 for DVR pause resume end 
//------------------------------------------- 
 
	test R1, C_SACM_PLAY; 
	jz ?_Branch_0; 
 
      //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
      //%%%       Clear Disable Channel FIFO Empty Interupt             % 
      //%%%       Latch FIFO data to DAC/PWM after writing to control reg % 
      //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
	test R1,C_SACM_ENABLE_DAC1 
	jz L_EndDACA? 
	call  F_SACM_CHA_PlayInterrupt_Disable 
L_EndDACA?: 
	R1 = [R_SACM_Play_Flag] 
	test R1,C_SACM_ENABLE_DAC2 
	jz L_EndDACB? 
	call  F_SACM_CHB_PlayInterrupt_Disable 
L_EndDACB?: 
	//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
 
	R1 = [R_SACM_Play_Flag]; 
	//R1 ^= (C_SACM_PLAY + C_SACM_PAUSE); 
	R1 |= C_SACM_PAUSE; 
	R1 &= ~C_SACM_FIQ_SOUND; 
	[R_SACM_Play_Flag] = R1; 
 
?_Branch_0: 
	pop R2 from [sp]			//guili 2005.10.19 
	pop R1 from [SP]; 
   	retf; 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Resume 
// Description:	Resume speech 
// Syntax:	void SACM_Resume(); 
// Parameter:	N/A 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Resume: .proc 
F_SACM_Resume: 
	push R1 to[sp]; 
	push R2 to[sp];				//guili 2005.10.19 
 
	R1 = [R_SACM_Play_Flag]; 
 
//------------------------------------------- 
//guili 2005.10.19 for DVR pause resume 
.ifdef C_SND_DVR_SUPPORT //=================== 
	test R1, C_SACM_CODEC_MODE; 
	JE _SACM_DECODE_RESUME; 
 
_SACM_ENCODE_RESUME: 
	R1 = [R_SACM_Play_Flag]; 
   	test R1, C_SACM_PAUSE; 
   	jz ?_Branch_1; 
 
	call F_SACM_DVR1600_ADC_Timer_Init 
 
	r2 = [P_ADC_Setup]			// added by guili 2005/08/18 
	//r2 =0xE0C0				// added by Anson 2005/3/1 
	r2 |= 0xE0C0				// added by guili 2005/08/18 
	[P_ADC_Setup] = r2;			//SYSCLK/512, Auto Sampling, Mic Enable, TimeE 
	r2 = 0xC010				// FIFO Full Level Define 
	[P_ASADC_Ctrl] = r2 
 
	r2 = [P_ADC_Setup]			//Start Auto Sample 
	r2 = r2 | 0x0004 
	[P_ADC_Setup] = r2 
 
	R1 &= ~C_SACM_PAUSE; 
	R1 |= C_SACM_FIQ_SOUND 
 
?_Branch_1: 
	[R_SACM_Play_Flag] = R1; 
 
	pop R2 from [sp] 
	pop R1 from [sp] 
   	retf; 
.endif //ifdef C_SND_DVR_SUPPORT =============== 
 
_SACM_DECODE_RESUME: 
//guili 2005.10.19 for DVR pause resume end 
//------------------------------------------- 
 
	test R1, C_SACM_PAUSE; 
	jz ?_Branch_0; 
 
	//R1 ^= (C_SACM_PLAY + C_SACM_PAUSE); 
	R1 &= ~C_SACM_PAUSE; 
	R1 |=  C_SACM_FIQ_SOUND; 
	[R_SACM_Play_Flag] = R1; 
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
	R1 = [R_SACM_Play_Flag]; 
	test r1,C_SACM_ENABLE_DAC1 
	jz L_EndDACA? 
	call  F_SACM_CHA_PlayInterrupt_Enable 
L_EndDACA?: 
	r1 = [R_SACM_Play_Flag] 
	test r1,C_SACM_ENABLE_DAC2 
	jz L_EndDACB? 
	call  F_SACM_CHB_PlayInterrupt_Enable 
L_EndDACB?: 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
 
?_Branch_0: 
	pop R2 from [sp];			//guili 2005.10.19 
	pop R1 from [sp]; 
   	retf; 
.endp 
 
 
//============================================================== 
//		Start APIs( Play , Rec ) 
//============================================================== 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Play 
// Description:	Play speech from T_SACM_SpeechTable in resource.asm 
// Syntax:	void SACM_Play(int SpeechIndex,int Channel,int Ramp_Set); 
// Parameter: 
//  	Speech index:	-1		: Mamual mode 
//                     0 - max index	: Auto mode 
// 
//	Channel: 	1		: DAC1 on 
//			2		: DAC2 on 
//			3		: DAC1,2 on 
//	Ramp_Set:	0: Ramp Up disable/Ramp Dn disable 
//			1: Ramp Up enable/Ramp Dn disable 
//			2: Ramp Up disable/Ramp Dn enable 
//			3: Ramp Up enable/Ramp Dn enable 
// Return:	N/A 
// Destory:	R1,R2,R3 
//////////////////////////////////////////////////////// 
_SACM_Play: .proc 
   	push BP to [SP]; 
 
   	R1 = 0;			//*benwang modified 
	[R_SACM_ISR_Flag] = R1;//* 
 
	BP = SP + 1; 
   	R1 = [BP + 3]; 
   	R2 = [BP + 4]; 
   	R3 = [BP + 5]; 
 
	push R1, R2 to [SP]; 
	R1 = 1;			//added by benwang 01.04 
	[PLAY_STATUS] = R1;	//added by benwang 01.04 
   	call F_SACM_Stop; 
   	R1 = 0;			//added by benwang 01.04 
   	[PLAY_STATUS] = R1; 
   	pop R1, R2 from [SP];	//added by benwang 01.04 
 
	call F_SACM_Play 
 
	pop BP from [SP]; 
	retf 
 
//**************************************************************** 
// Function:	_SACM_Middle_Play 
// Syntax:	void SACM_Middle_Play(void); 
// Input: 
//		R1 = SpeechIndex 
//		R2 = DAC 
//		R3 = Ramp 
// 
// Output:	N/A 
// Destory:	R1~R3 
//**************************************************************** 
_SACM_Middle_Play: 
   	push BP to [SP]; 
 
   	R1 = 0;				//*benwang modified 
	[R_SACM_ISR_Flag] = R1; 
 
   	R1 = 0;				//added by benwang 01.04 
   	[PLAY_STATUS] = R1; 
 
	R4=0				// added by cfwei 20041112 
	[REC_STATUS]=R4		// added by cfwei 20041112 
 
	R4 = C_SACM_PLAY; 
	R1 = [_SndSACM_curDACConfig] 
	R1 &= 0x0003 
	cmp R1,C_DAC1 
	jnz ?L_SkipDAC1 
//	call F_SACM_EnableDAC1; 
	R4 |= C_SACM_ENABLE_DAC1; 
	jmp ?L_SkipDAC 
 
?L_SkipDAC1: 
	cmp R1,(C_DAC1+C_DAC2) 
	jnz ?L_SkipDAC12 
//	call F_SACM_EnableDAC1; 
	R4 |= C_SACM_ENABLE_DAC1; 
//	call F_SACM_EnableDAC2; 
	R4 |= C_SACM_ENABLE_DAC2; 
	jmp ?L_SkipDAC 
 
?L_SkipDAC12: 
//	call F_SACM_EnableDAC2_Only; 
	R4 |= C_SACM_ENABLE_DAC2; 
	jmp ?L_SkipDAC 
 
?L_SkipDAC: 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	R4 |= C_SACM_RAMP_DN_ENABLE; 
	goto L_Manual_Mode 
 
//======================================================================= 
//xiaolei add for PCM Data Play for KT CTTS:			2006/10/18 
.public _SACM_Middle_PlayPCM 
_SACM_Middle_PlayPCM: 
	push BP to [SP]; 
 
   	R1 = 0;				//*benwang modified 
	[R_SACM_ISR_Flag] = R1; 
 
   	R1 = 0;				//added by benwang 01.04 
   	[PLAY_STATUS] = R1; 
 
	R4=0				// added by cfwei 20041112 
	[REC_STATUS]=R4		// added by cfwei 20041112 
 
	R4 = C_SACM_PLAY; 
	R1 = [_SndSACM_curDACConfig] 
	R1 &= 0x0003 
	cmp R1,C_DAC1 
	jnz ?L_SkipDAC1 
	R4 |= C_SACM_ENABLE_DAC1; 
	jmp ?L_SkipDAC 
 
?L_SkipDAC1: 
	cmp R1,(C_DAC1+C_DAC2) 
	jnz ?L_SkipDAC12 
	R4 |= C_SACM_ENABLE_DAC1; 
	R4 |= C_SACM_ENABLE_DAC2; 
	jmp ?L_SkipDAC 
 
?L_SkipDAC12: 
	R4 |= C_SACM_ENABLE_DAC2; 
	jmp ?L_SkipDAC 
 
?L_SkipDAC: 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	R4 |= C_SACM_RAMP_DN_ENABLE; 
	 
	[R_SACM_Play_Flag] = R4 
	call F_DecodeInit_setIRQ 
 
//--------------------------------------------- 
	push r1,r4 to [sp]; 
.ifdef C_SND_CTTS_ETTS_SUPPORT 
	r1 = [_Snd_TTS_IsPlaying]	//guili 2005.11.2 
	cmp r1, C_CTTSETTS_PLAYING		//guili 2005.11.2 
	jz ?L_SkipAmpOn					//guili 2005.11.2 
.endif 
.ifdef C_SND_CTTS_SUPPORT 
	r1 = [_Snd_CTTS_IsPlaying]	//guili 2005.11.2 
	cmp r1, C_CTTS_PLAYING		//guili 2005.11.2 
	jz ?L_SkipAmpOn			//guili 2005.11.2 
.endif 
	call _Snd_onAmpOn;		//cfwei20041209 
?L_SkipAmpOn:				//guili 2005.11.2 
	pop r1,r4 from [sp] 
//--------------------------------------------- 
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
	r1 = [R_SACM_Play_Flag] 
    test r1,C_SACM_ENABLE_DAC1		//enable cha,b interrupt 
    jz L_EndDACA?											  		  //% 
	call	F_SACM_CHA_PlayInterrupt_Enable 
L_EndDACA?:															  	  //% 
	r1 = [R_SACM_Play_Flag] 
	test r1,C_SACM_ENABLE_DAC2											  //% 
    jz L_EndDACB?											  	      //% 
	call	F_SACM_CHB_PlayInterrupt_Enable 
L_EndDACB?: 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
	R1 = 1			 		 	//benwang modified 
	[R_SACM_ISR_Flag]=R1		//benwang 
 
	pop bp from [sp]		// by arthur 
	retf 
//==================================================================== 
 
//**************************************************************** 
// SACM_EnableDAC(int Channel,int Ramp_Set); 
//**************************************************************** 
_SACM_EnableDAC: 
 
	R3 = SP+3 
	R2 = [R3++] 
	R3 = [R3] 
	 
	call F_SACM_Init; 
	 
	R4 = 0 
	[R_SACM_Play_Flag] = R4 
//--------------------------------------------- 
//do with DAC 
//--------------------------------------------- 
//====================================================================== 
//xiaolei exchange the Enable_DAC and the RampUp_DAC position 2006/06/14 
//=====================Improve the Speech Result======================== 
	r2 = r2 & 0x0003 
	cmp R2, 0x0001;					//DAC1 = 0x0001 
	jnz ?L_Branch_0; 
//DAC1 only: 
	test R3, 0x0001; 
	jz ?L_DAC1_NoRmpUp 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	call F_SACM_RampUpDAC1; 
?L_DAC1_NoRmpUp: 
	call F_SACM_EnableDAC1;		//cfwei20041209 
	R4 |= C_SACM_ENABLE_DAC1; 
	jmp ?L_Branch_1; 
 
//DAC1 and DAC2 both: 
?L_Branch_0: 
	cmp R2, 0x0001+0x0002;		// DAC2 = 0x0002 
	jnz ?L_Branch_01; 
 
	test R3, 0x0001; 
	jz ?L_DAC1and2_NoRmpUp 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	call F_SACM_RampUpDAC1; 
	call F_SACM_RampUpDAC2;		//The same to Ramp Up 1 
?L_DAC1and2_NoRmpUp: 
	call F_SACM_EnableDAC1;		//cfwei20041209 
	R4 |= C_SACM_ENABLE_DAC1; 
	call F_SACM_EnableDAC2;		//cfwei20041209 
	R4 |= C_SACM_ENABLE_DAC2; 
 
	jmp ?L_Branch_1; 
//only DAC2: 
?L_Branch_01: 
	cmp R2, 0x0002; 
	jnz ?L_Branch_1 
	test R3, 0x0001; 
	jz ?L_DAC2_NoRmpUp 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	call F_SACM_RampUpDAC2; 
?L_DAC2_NoRmpUp: 
	call F_SACM_EnableDAC2_Only; 
	R4 |= C_SACM_ENABLE_DAC2; 
 
?L_Branch_1: 
?L_Branch_2: 
	test R3, 0x0002;		// Ramp_Dn = 0x0002 
	jz ?L_Branch_4; 
 
	R4 |= C_SACM_RAMP_DN_ENABLE; 
 
?L_Branch_4: 
	[R_SACM_Play_Flag] = R4 
	retf 
 
//**************************************************************** 
// Function:	F_SACM_Play 
// Syntax:	call F_SACM_Play; (in assembly domain) 
// Input: 
//		R1 = SpeechIndex 
//		R2 = DAC 
//		R3 = Ramp 
// 
// Output:	N/A 
// Destory:	R1~R3 
//**************************************************************** 
F_SACM_Play: 
	//push R4 to [sp];		// by arthur guili 2005.11.1 
   	push bp to [sp];		// guili 2005.11.1 
	call F_SACM_Init;		//xiaolei add 2006/08/07	xiaolei delete 2006/08/29 
//--------------------------------------------- 
	R4=0				// added by cfwei 20041112 
	[REC_STATUS]=R4			// added by cfwei 20041112 
 
	R4 = C_SACM_PLAY; 
 
//--------------------------------------------- 
//do with DAC 
//--------------------------------------------- 
//====================================================================== 
//xiaolei exchange the Enable_DAC and the RampUp_DAC position 2006/06/14 
//=====================Improve the Speech Result======================== 
	r2 = r2 & 0x0003 
	cmp R2, 0x0001;					//DAC1 = 0x0001 
	jnz ?L_Branch_0; 
 
//DAC1 only: 
	test R3, 0x0001; 
	jz ?L_DAC1_NoRmpUp 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	call F_SACM_RampUpDAC1; 
?L_DAC1_NoRmpUp: 
	call F_SACM_EnableDAC1;		//cfwei20041209 
	R4 |= C_SACM_ENABLE_DAC1; 
	jmp ?L_Branch_1; 
 
//DAC1 and DAC2 both: 
?L_Branch_0: 
	cmp R2, 0x0001+0x0002;		// DAC2 = 0x0002 
	jnz ?L_Branch_01; 
 
	test R3, 0x0001; 
	jz ?L_DAC1and2_NoRmpUp 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	call F_SACM_RampUpDAC1; 
	call F_SACM_RampUpDAC2;		//The same to Ramp Up 1 
?L_DAC1and2_NoRmpUp: 
	call F_SACM_EnableDAC1;		//cfwei20041209 
	R4 |= C_SACM_ENABLE_DAC1; 
	call F_SACM_EnableDAC2;		//cfwei20041209 
	R4 |= C_SACM_ENABLE_DAC2; 
 
	jmp ?L_Branch_1; 
//only DAC2: 
?L_Branch_01: 
	cmp R2, 0x0002; 
	jnz ?L_Branch_1 
	test R3, 0x0001; 
	jz ?L_DAC2_NoRmpUp 
	R4 |= C_SACM_RAMP_UP_ENABLE; 
	call F_SACM_RampUpDAC2; 
?L_DAC2_NoRmpUp: 
	call F_SACM_EnableDAC2_Only; 
	R4 |= C_SACM_ENABLE_DAC2; 
 
?L_Branch_1: 
?L_Branch_2: 
 
	test R3, 0x0002;		// Ramp_Dn = 0x0002 
	jz ?L_Branch_4; 
 
	R4 |= C_SACM_RAMP_DN_ENABLE; 
 
//--------------------------------------------- 
//get 128(126)words res to decode in buffer (and TTS init) 
//--------------------------------------------- 
?L_Branch_4: 
	r2 = [R_CODEC_TYPE] 
.ifdef C_SND_MP3_SUPPORT 
	cmp r2, C_CODEC_MP3 
	jne ?L_NotMP3 
	R2 = 1024; 
	[R_DECODE_IN_LENGTH] = R2 
	jmp ?L_PlayContinue 
?L_NotMP3: 
.endif 
.ifdef C_SND_A128_SUPPORT 
	cmp R2, C_CODEC_A128 
	jne ?L_NotA128 
	R2 = 1024;				     	//add by benwang 20060221							 
	[R_DECODE_IN_LENGTH] = R2; 
	jmp ?L_PlayContinue 
.endif 
?L_NotA128: 
 
.ifdef C_2002_CODE_ICA 
	R2 = 160; 
.else 
	R2 = 256; 
.endif 
	[R_DECODE_IN_LENGTH] = R2; 
 
?L_PlayContinue: 
	cmp R1, -1			// Auto/ Manual 
	JE L_Manual_Mode		//guili 2005.11.1 
 
	R4 |= C_SACM_AUTO; 
 
?L_Branch_5: 
	[R_SACM_Play_Flag] = R4; 
 	R3 = R1; 
	//R1 += T_SACM_S480_SpeechTable	//????? 
.ifdef C_SND_A1600_SUPPORT 
	//wait to be modified			//xiaolei 2006/03/08 
	R1 += T_SACM_A1600_SpeechTable	//????? 
.endif 
	R1 = [R1]; 
	R2 = [R1 ++]; 
	[R_SACM_Resouce_BS] = R2; 
	R1 = [R1]; 
	R1 = R1 LSL 4; 
	R1 = R1 LSL 4; 
	R1 = R1 LSL 2; 
	[R_SACM_Resouce_DS] = R1; 
	R1 = R3; 
 
	//R1 = R_SACM_Decode_In_Buffer + C_DECODE_IN_LENGTH; 
	R1 = [R_DECODE_IN_LENGTH] 
	R1 += R_SACM_Decode_In_Buffer 
	[R_SACM_Decode_In_PTR] = R1; 
 
	call F_SACM_Decode_Get_BS_Auto; 
	//jmp  ?L_DecodeInit;			//guili 2005.11.1 
	jmp L_DecodeInit			//guili 2005.11.1 
 
//============================================================ 
//MANUAL_MODE 
L_Manual_Mode:					//guili 2005.11.1 
	[R_SACM_Play_Flag] = R4; 
	//R1 = R_SACM_Decode_In_Buffer + C_DECODE_IN_LENGTH; 
	R1 = [R_DECODE_IN_LENGTH] 
	R1 += R_SACM_Decode_In_Buffer 
	[R_SACM_Decode_In_PTR] = R1; 
 
//----------- added by benwang start 12.16 
	R1 = [R_CODEC_TYPE]; 
.ifdef C_SND_S200TTS_SUPPORT 
	cmp R1 ,C_CODEC_S200TTS;		//mgl 2005/03/14 
	//cmp R1 ,C_CODEC_S600TTS;		//mgl 2005/03/14 
	//JNE ?_NOT_TTS; 
	JNE ?_NOT_S200TTS; 
	call F_SACM_TTS200_System_Get_SAC_Manual 
	call F_SACM_TTS200_System_Get_BS_Initial 
	call F_SACM_TTS200_System_Get_BS_Manual 
	JMP ?_Get_BS_END 
?_NOT_S200TTS:					//for S320TTS zgq 2005/03/23 
.endif 
.ifdef	C_SND_S600TTS_SUPPORT 
	cmp R1 ,C_CODEC_S600TTS;		//mgl 2005/03/14 
	JNE ?_NOT_S600TTS; 
	call F_SACM_TTS600_System_Get_SAC_Manual; 
	call F_SACM_TTS600_System_Get_BS_Initial; 
	call F_SACM_TTS600_System_Get_BS_Manual; 
	JMP ?_Get_BS_END 
?_NOT_S600TTS: 
.endif 
.ifdef C_SND_S320TTS_SUPPORT 
	cmp R1, C_CODEC_S320TTS 		//2005/03/31 
	jne ?_NOT_TTS 
	.ifdef TTS320FAT				//xiaolei add 
		call F_TTS320_System_Get_SAC_ManualFAT 
	.else 
		call F_TTS320_System_Get_SAC_Manual 
	.endif 
.ifdef C_SND_S320TTS_PREFETCH_SUPPORT 
	call F_SACM_TTS320_System_Get_BS_Initial 
	call F_SACM_TTS320_System_Get_BS_Manual 
.endif 
	jmp ?_Get_BS_END 			//2005/03/31 
?_NOT_TTS: 
.endif 
.ifdef C_SND_ETTS_SUPPORT 
	cmp R1, C_CODEC_ETTS 
	je ?_Get_BS_END 
.endif 
 
//The Normal Algrithem: 
	call F_SACM_System_Get_BS_Manual 
 
?_Get_BS_END: 
.ifdef C_SND_A1600_SUPPORT				//2005.10.18 guili added for A1600 skip play 
.ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
	R1 = [R_CODEC_TYPE] 
	cmp R1,C_CODEC_A1600_Skip 
	jnz ?_Get_BS_END1 
	R1 = R_SACM_Decode_In_Buffer 
	R2 = [_SACM_Decode_Length_L] 
	[R1++] = R2 
	R2 = [_SACM_Decode_Length_L + 1] 
	[R1++] = R2 
	R2 = [_SACM_A1600_ModeCode] 
	[R1] = R2 
?_Get_BS_END1: 
.endif 
.endif							//2005.10.18 added end 
 
.ifdef C_SND_A1800_SUPPORT				//2005.10.18 xiaolei added for A1800 skip play 
.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
	R1 = [R_CODEC_TYPE] 
	cmp R1,C_CODEC_A1800_SKIP 
	jnz ?_Get_BS_END2 
	R1 = R_SACM_Decode_In_Buffer 
	R2 = [_SACM_Decode_Length_L] 
	[R1++] = R2 
	R2 = [_SACM_Decode_Length_H] 
	[R1++] = R2 
	R2 = [_SACM_A1800_ModeCode] 
	[R1] = R2 
?_Get_BS_END2: 
.endif 
.endif							//2005.10.18 added end 
 
//------------added by benwang end 12.16 
 
//--------------------------------------------- 
//init FIFO depth and init TimerE 
//--------------------------------------------- 
	// Start Decode 
L_DecodeInit:				//guili 2005.11.1 
?L_DecodeInit: 
	call F_DecodeInit_setIRQ	//cfwei 20050106 add 
 
//--------------------------------------------- 
//init length and count Var 
//--------------------------------------------- 
	//----------------- added by benwang start 12.16 
	R1 = [R_CODEC_TYPE]; 
 
.ifdef C_SND_S200TTS_SUPPORT 
	cmp R1 ,C_CODEC_S200TTS		//mgl 2005/03/14 
	jne ?L_NormalAlg 
	call F_SACM_Decode_Initial_BS 
//	call F_SACM_LRC_Decode_Initial_BS 
	jmp ?_Continue_0 
.endif 
.ifdef C_SND_S600TTS_SUPPORT 
	cmp R1 ,C_CODEC_S600TTS		//mgl 2005/03/14 
	jne ?L_NormalAlg 
	call F_SACM_TTS600_Decode_Initial_BS 
	jmp ?_Continue_0 
.endif 
.ifdef C_SND_S320TTS_SUPPORT 
	cmp R1, C_CODEC_S320TTS; 	//2005/03/31 
	jne ?L_NormalAlg 
	.ifdef TTS320FAT 
		call F_SACM_TTS320_Decode_Initial_BSFAT;	//xiaolei add 2006/03/02 
	.else 
		call F_SACM_TTS320_Decode_Initial_BS; 		//2005/03/31 
	.endif 
	jmp ?_Continue_0 
.endif 
.ifdef C_SND_ETTS_SUPPORT 
	cmp R1, C_CODEC_ETTS; 
	je ?_Continue_0 
.endif 
?L_NormalAlg: 
 
//The Normal Algrithem: 
	call F_SACM_Decode_Initial_BS 
	jmp ?_Continue_0 
//Normal Algrithem 
 
//--------------------------------------------- 
//supplement datas to Decode_In_Buffer(2 words or 0(TTS)) 
//because get length used 2 words 
//--------------------------------------------- 
?_Continue_0: 
	R4 = [R_SACM_Play_Flag]; 
	test R4, C_SACM_AUTO;		// Ramp_Dn = 0x0002 
   	//jnz ?L_AutoGetBS2; 
   	jz ?L_Manual_Mode2 
 
//?L_AutoGetBS2: 
// AUTO_MODE 
  	call F_SACM_Decode_Get_BS_Auto; 
	jmp ?L_DecodeInProcess; 
 
?L_Manual_Mode2: 
//MANUAL_MODE 
//------------------ added by benwang start 12.16 
	R1 = [R_CODEC_TYPE] 
 
.ifdef C_SND_S200TTS_SUPPORT 
	cmp R1 ,C_CODEC_S200TTS;		//for S200TTS 2005/03/23 
	JNE ?_NOT_S200TTS_2; 
	call F_SACM_TTS200_System_Get_BS_Manual; 
	JMP ?L_DecodeInProcess; 
?_NOT_S200TTS_2: 
.endif 
.ifdef	C_SND_S600TTS_SUPPORT 
	cmp R1 ,C_CODEC_S600TTS;		//for S200TTS 2005/03/23 
	JNE ?_NOT_S600TTS_2; 
	call F_SACM_TTS600_System_Get_BS_Manual;		 
	JMP ?L_DecodeInProcess; 
?_NOT_S600TTS_2: 
.endif 
.ifdef C_SND_S320TTS_SUPPORT 
	cmp R1, C_CODEC_S320TTS; 		//2005/03/31 
	jne ?_NOT_TTS_2; 			//2005/03/31 
	.ifdef TTS320FAT 
		call F_TTS320_System_Get_BS_ManualFAT;//2005/03/31 
	.else 
		call F_TTS320_System_Get_BS_Manual; 
	.endif 
	jmp ?L_DecodeInProcess; 			//2005/03/31 
?_NOT_TTS_2: 
.endif 
.ifdef C_SND_ETTS_SUPPORT 
	cmp R1, C_CODEC_ETTS; 
	je ?L_DecodeInProcess; 
.endif 
 
//Normal Algrithem: 
	call F_SACM_System_Get_BS_Manual; 
 
//--------------------------------------------- 
//call kernel decode init API and Speed Init(if need) 
//--------------------------------------------- 
?L_DecodeInProcess: 
	r1 = fr 
	push r1 to [sp] 
	call F_SACM_Decode_Initial_Process; 
	pop r1 from [sp] 
	fr = r1 
 
	R1 = [R_CODEC_TYPE]; 
//The Arithmetic which can NOT be speedcontroled  
.ifdef C_SND_S200_SUPPORT 
	cmp R1 ,C_CODEC_S200 
	je ?_Branch_6 
.endif 
.ifdef C_SND_S200TTS_SUPPORT 
	cmp R1 ,C_CODEC_S200TTS 
	je ?_Branch_6 
.endif 
.ifdef C_SND_MS01_SUPPORT 
	cmp R1 ,C_CODEC_MS01; 
	je ?_Branch_6 
.endif 
.ifdef C_SND_MS02_SUPPORT 
	cmp R1 ,C_CODEC_MS02; 		//added by benwang 2004/06/08 
	je ?_Branch_6 			//added by benwang 2004/06/08 
.endif 
.ifdef C_SND_S320_SUPPORT 
	cmp R1, C_CODEC_S320; 		//added by zgq 2005/03/31 
	je ?_Branch_6			//added by zgq 2005/03/31 
.endif 
.ifdef C_SND_S320TTS_SUPPORT 
	cmp R1, C_CODEC_S320TTS;	//added by zgq 2005/03/31 
	je ?_Branch_6			//added by zgq 2005/03/31 
.endif 
.ifdef C_SND_A4800_SUPPORT 
	cmp R1, C_CODEC_A4800 
	je ?_Branch_6 
.endif 
.ifdef C_SND_ETTS_SUPPORT 
	cmp R1, C_CODEC_ETTS 
	je ?_Branch_6 
.endif 
.ifdef C_SND_DVR4800_SUPPORT 
	cmp R1, C_CODEC_DVR4800 
	je ?_Branch_6 
.endif 
//The Arithmetic which can NOT be speedcontroled End 
//The Arithmetic which Can be speedcontroled 
.ifndef C_SND_S480720_SPEEDCONTROL_SUPPORT 
	.ifdef C_SND_S480_SUPPORT		//nospeed control 
		cmp R1, C_CODEC_S480 
		je ?_Branch_6 
	.endif 
	.ifdef C_SND_S720_SUPPORT 
		cmp R1, C_CODEC_S720 
		je ?_Branch_6 
	.endif 
.else 
	.ifdef C_SND_S480_SUPPORT		//have speed control 
		cmp R1, C_CODEC_S480 
		je ?L_SpeedControl_Label 
	.endif 
	.ifdef C_SND_S720_SUPPORT 
		cmp R1, C_CODEC_S720 
		je ?L_SpeedControl_Label 
	.endif 
.endif		//end of C_SND_S480720_SPEEDCONTROL_SUPPORT 
.ifdef C_SND_A1800_SPEEDCONTROL_SUPPORT 
	.ifdef C_SND_A1800_SUPPORT 
		cmp R1, C_CODEC_A1800 
		je ?L_SpeedControl_Label 
	.endif	//C_SND_A1800_SUPPORT end 
	.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
		cmp R1, C_CODEC_A1800_SKIP 
		je ?L_SpeedControl_Label 
	.endif	//C_SND_A1800_SKIPPLAY_SUPPORT end 
.else 
	.ifdef C_SND_A1800_SUPPORT 
		cmp R1, C_CODEC_A1800 
		je ?_Branch_6 
	.endif	//C_SND_A1800_SUPPORT end 
	.ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
		cmp R1, C_CODEC_A1800_SKIP 
		je ?_Branch_6 
	.endif	//C_SND_A1800_SKIPPLAY_SUPPORT end 
.endif		//end of C_SND_A1800_SPEEDCONTROL_SUPPORT 
.ifndef C_SND_DVR520_SPEEDCONTROL_SUPPORT 
	cmp R1, C_CODEC_DVR520 
	je ?_Branch_6 
.else 
	cmp R1, C_CODEC_DVR520 
	je ?L_SpeedControl_Label 
.endif 
.ifndef C_SND_A3200_SPEEDCONTROL_SUPPORT 
	cmp R1, C_CODEC_A3200 
	je ?_Branch_6 
.else 
	cmp R1, C_CODEC_A3200 
	je ?L_SpeedControl_Label 
.endif 
//For MP3 speedcontrol 
.ifndef C_SND_MP3_SPEEDCONTROL_SUPPORT 
	.ifdef C_SND_MP3_SUPPORT 
		cmp R1, C_CODEC_MP3 
		je ?_Branch_6 
	.endif	//C_SND_MP3_SUPPORT end 
.else 
	.ifdef C_SND_MP3_SUPPORT 
		cmp R1, C_CODEC_MP3 
		je ?L_SpeedControl_Label 
	.endif	//C_SND_MP3_SUPPORT end 
.endif	//C_SND_MP3_SPEEDCONTROL_SUPPORT end 
//The Arithmetic which Can be speedcontroled End 
 
?L_SpeedControl_Label: 
.ifdef	C_SpeedControl			//xiaolei add for speed control 
	r1 = R_SACM_Decode_Out_Buffer 
	[R_SACM_Decode_Out_PTR] = r1 
	push r3,r4 to [sp]						//xiaolei modify for 2002 platform speed control 
	r3=0x2e 
	r4=0x01 
	call mr 
	pop	r3,r4 from [sp] 
//	call F_SACM_XXXX_Speed_Initial			//xiaolei delete for the new project 2006/07/14 
.endif 
 
//--------------------------------------------- 
//clear DAC_Out_Buffer, Ptr, Flag 
//--------------------------------------------- 
?_Branch_6: 
	R1 = 0x0000; 
	R2 = R_SACM_DAC_Out_Buffer; 
	R3 = R2 + [R_DAC_OUT_LENGTH]; 
	R3 += [R_DAC_OUT_LENGTH]; 
?_Loop_0: 
	[R2++] = R1; 
	cmp R2, R3; 
	jne ?_Loop_0; 
 
	R1=0; 
.ifdef C_SND_UPSAMPLE_16KHZ 
	[DAC_16K_FLAG]=R1; 
.endif	//End C_SND_UPSAMPLE_16KHZ 
.ifdef C_SND_UPSAMPLE_32KHZ 
	[DAC_32K_FLAG]=R1; 
.endif	//End C_SND_UPSAMPLE_32KHZ 
	[OFILTER_BUF_PTR]=R1; 
	[OFILTER_BUF+0]=R1; 
	[OFILTER_BUF+1]=R1; 
	[OFILTER_BUF+2]=R1; 
	[OFILTER_BUF+3]=R1; 
//xiaolei add for S200 UpSampling 2006/06/03 
	[OFILTER_BUF + 4] = R1; 
	[OFILTER_BUF + 5] = R1; 
	[OFILTER_BUF + 6] = R1; 
	[OFILTER_BUF + 7] = R1; 
	[OFILTER_BUF + 8] = R1; 
	[OFILTER_BUF + 9] = R1; 
	[OFILTER_BUF + 10] = R1; 
	[OFILTER_BUF + 11] = R1; 
	[OFILTER_BUF + 12] = R1; 
	[OFILTER_BUF + 13] = R1; 
	[OFILTER_BUF + 14] = R1; 
	[OFILTER_BUF + 15] = R1; 
//xiaolei add end 2006/06/03 
 
	R1 = R_SACM_DAC_Out_Buffer 
	[R_SACM_DAC_Out_PTR_Play] = R1 
	R1 = R_SACM_DAC_Out_Buffer 
	R1 += [R_DAC_OUT_LENGTH] 
	[R_SACM_DAC_Out_PTR_Decode] = R1 
	R1 = [R_SACM_Play_Flag] 
	R1 |= (C_SACM_DECODE_WORK + C_SACM_DECODE_ODD + C_SACM_FIQ_SOUND + C_SACM_FIQ_EVEN) 
	[R_SACM_Play_Flag] = R1 
 
//--------------------------------------------- 
	push r1,r4 to [sp]; 
//xiaolei add 2006/08/08 
//.comment #					//xiaolei add for MP3 noise 
.ifdef MP3_DECODE_EFFECT 
	r1 = 1 
	[R_Decode_Finish_A] = r1 
	[R_Decode_Finish] = r1		//add by jacky 2006.02.15 
.endif 
//# 
//xiaolei add end 
.ifdef C_SND_CTTS_ETTS_SUPPORT 
	r1 = [_Snd_TTS_IsPlaying]	//guili 2005.11.2 
	cmp r1, C_CTTSETTS_PLAYING	//guili 2005.11.2 
	jz ?L_SkipAmpOn			//guili 2005.11.2 
.endif 
.ifdef C_SND_CTTS_SUPPORT 
	r1 = [_Snd_CTTS_IsPlaying]	//guili 2005.11.2 
	cmp r1, C_CTTS_PLAYING		//guili 2005.11.2 
	jz ?L_SkipAmpOn			//guili 2005.11.2 
.endif 
	call _Snd_onAmpOn;		//cfwei20041209 
?L_SkipAmpOn:				//guili 2005.11.2 
	pop r1,r4 from [sp] 
 
//--------------------------------------------- 
//  enable cha,b interrupt 
//--------------------------------------------- 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
//	r1 = [R_SACM_Play_Flag]		//add by Anson  2004/1/29			 	//% 
.comment # 
	r4 = r1 
    test r1,C_SACM_ENABLE_DAC1		//enable cha,b interrupt 
    jz L_EndDACA?											  		  //% 
	call	F_SACM_CHA_PlayInterrupt_Enable 
L_EndDACA?:															  	  //% 
//	r1 = [R_SACM_Play_Flag]											      //% 
	r1 = r4 
	test r1,C_SACM_ENABLE_DAC2											  //% 
    jz L_EndDACB?											  	      //% 
	call	F_SACM_CHB_PlayInterrupt_Enable 
L_EndDACB?: 
//#		因为先打开A的中断时对于非常短的MP3文件会很快的解码完毕,而后立即调用了PlayNextFile 
//		交换AudioA和AudioB的中断打开位置 
	r4 = r1 
	test r1,C_SACM_ENABLE_DAC2											  //% 
    jz L_EndDACB?										  	      //% 
	call	F_SACM_CHB_PlayInterrupt_Enable 
L_EndDACB?: 
//	r1 = [R_SACM_Play_Flag]											      //% 
	r1 = r4 
	test r1,C_SACM_ENABLE_DAC1		//enable cha,b interrupt 
    jz L_EndDACA?											  		  //% 
	call	F_SACM_CHA_PlayInterrupt_Enable 
L_EndDACA?: 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
 
	R1 = 1			  		//benwang modified 
	[R_SACM_ISR_Flag]=R1	//benwang 
.comment #					//xiaolei add for MP3 noise 
	fraction off 
	r1=fr 
	[R_SACM_FR_Flag]=r1 
//# 
	pop bp from [sp]		// by arthur 
	retf 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Rec 
// Description:	Record from Mic or line in 
// Syntax:	void SACM_Rec(int RecMonitorOff,int ADCChannel,int Bitrate); 
// Parameter: 
//		RecMonitor: 
//			1		: RecMonitorOn  (ADC-->DAC) 
//			0 - max index	: RecMonitorOff (ADC) 
// 
//		ADC Channel: 
//			0  :	Microphone 
//			1-6:	Line in 
//		Bitrate: 
//			0:	10 Kbps 
//			1:	12 Kbps 
//			2:	14 Kbps 
//			3:	16 Kbps 
//			4:	20 Kbps 
//			5:	24 Kbps 
// Return:	N/A 
// Destory:	R1,R2,R3 
//////////////////////////////////////////////////////// 
.ifdef C_SND_DVR_SUPPORT //=================== 
//.public _SACM_DVR1600_Rec	// RceMonitorOff, ADC, bit rate 
_SACM_Rec: .proc 		// RceMonitorOff, ADC, bit rate 
   	push BP to [SP]; 
 
	call F_SACM_DisableADC 
 
   	R1 = 0; 		//*benwang modified //added by benwang 01.04 
	[R_SACM_ISR_Flag] = R1;//* 
 
   	R1 = 1; 		//added by benwang 01.04 
   	[REC_STATUS] = R1;	//added by benwang 01.04 
   	[PLAY_STATUS] = R1;	//added by benwang 01.04 
   	BP = SP + 1; 
   	R1 = [BP + 3];		// RceMonitorOff 
   	R2 = [BP + 4];		// ADC Channel 
   	R3 = [BP + 5];		// Bitrate 
 
	call F_SACM_Rec 
 
	pop BP from [SP] 
   	retf 
   	 
.external addr_l 
F_SACM_Rec:		// R1=RceMonitorOff, R2=ADC, R3=bit rate 
	//[R_ADC_Channel] = R2; 
	//[R_BIT_RATE] = R3; 
	[BITRATE] = R3; 
	//[File_Index]=R1; 
	push R1, R2 to [SP]; 
	R1 = R2;//[R_ADC_Channel]; 
	 
	push r1 to [sp] 
	r1 = 0 
	[addr_l] = r1 
	pop r1 from [sp] 
	 
	call F_SACM_Stop 
	call F_SACM_DVR1600_ADC_Timer_Init //???added by benwang 01.02 
 
   	pop R1, R2 from [SP] 
 
	//R4=0; 
	R4 = C_SACM_PLAY; 
 
.ifdef DVR_REC_MONINTER 
	cmp R1,1; 			//Record Monitor on 
	jne ?L_NoRecMon; 
	call F_SACM_ADC_MoniterON	//added by chengye 2006/8/31 
	R4 |= C_SACM_REC_Mon_ON 
	 
//delete by chengye 2006/8/31	 
//	R4 |= C_SACM_REC_Mon_ON		 
//	call F_SACM_EnableDAC1		//cfwei20041209 
//	call F_SACM_EnableDAC2 
//  	call F_SACM_RampUpDAC1 
//  	call F_SACM_RampUpDAC2 
// 
//	call F_DecodeInit_setIRQ 
// 
//	push r1,r4 to [sp] 
//  	call _Snd_onAmpOn		//cfwei20041209 
//	pop r1,r4 from [sp] 
//delete by chengye 2006/8/31 
	 
?L_NoRecMon: 
.endif 
 
?_Branch_4: 
	R4 |= C_SACM_CODEC_MODE  // Encode mode --> Recording 
   	[R_SACM_Play_Flag] = R4 //?_Branch_4 result 
// Resouce Proc 
 
	call F_Reset_File_Access 
 
	R1 = R_SACM_Encode_Out_Buffer 
	[R_SACM_Encode_Out_PTR] = R1 
 
   	call F_SACM_Encode_Initial_BS 
	call F_SACM_Encode_Initial_Process	//call kernel API 
 
	R1 = 0x0000; 
	R2 = R_SACM_ADC_In_Buffer; 
	R3 = [R_ADC_IN_LENGTH]			//xiaolei modify "C_ADC_IN_LENGTH" to "R_ADC_IN_LENGTH" 
	R3 += R2 
	//R3 = R2 + C_ADC_IN_LENGTH; 
 
?_Loop_0: 
	[R2++] = R1 
	cmp R2, R3 
	jne ?_Loop_0 
 
	R1 = R_SACM_ADC_In_Buffer 
	[R_SACM_ADC_In_PTR_Rec] = R1 
 
	R1 = [R_SACM_Play_Flag] 
	R1 |= ( C_SACM_DECODE_ODD + C_SACM_FIQ_SOUND + C_SACM_FIQ_EVEN) 
	[R_SACM_Play_Flag] = R1 
 
	call F_SP_SwitchChannel 
	 
	R1 = 1//benwang modified 
	[R_SACM_ISR_Flag]=R1//benwang 
 
   	retf 
.endp 
.endif // C_SND_DVR_SUPPORT ===================== 
 
 
//============================================================== 
//		ServiceLoop API( Encode + Decode ) 
//============================================================== 
//////////////////////////////////////////////////////// 
// Function:	_SACM_ServiceLoop 
// Description:	decode bit stream 
// Syntax: 
//		C:   void SACM_ServiceLoop(void); 
// 		ASM: call F_SACM_ServiceLoop; 
// Parameter:	N/A 
// Return:	N/A 
// Destory:	R1,R2,R3; 
//////////////////////////////////////////////////////// 
 
 
//================================================================ 
.ifdef C_SND_DVR_SUPPORT 
_SACM_ENCODE_ServiceLoop:	 .proc 
	R1 = [R_SACM_Play_Flag] 
	test R1, C_SACM_PLAY	// Check if playing 
	jnz ?_Continue_0 
	retf 
 
?_Continue_0: 
	test R1, C_SACM_DECODE_WORK // Check if decoding 
	jnz ?_Continue_1 
	retf 
 
?_Continue_1: 
	R1 &= ~C_SACM_DECODE_WORK 
	[R_SACM_Play_Flag] = R1 
 
//	FRACTION OFF 
//	FIR_MOV OFF		//2005/03/31,because kernal need FIR_MOV OFF 
	call F_SACM_Encode_Process 
 
	R1 = [R_SACM_Play_Flag] 
	R1 ^= C_SACM_DECODE_ODD 
	[R_SACM_Play_Flag] = R1 
 
//====== Chech if we exceed maximum size ============// 
	R4 = [R_SACM_Encode_Count_H] 
	R3 = [R_SACM_Encode_Count_L] 
	CMP R4,[R_SACM_Encode_Length_H]	//add cfwei20041210 
	JB ?_Length_Enough			//add cfwei20041210 
	CMP R3,[R_SACM_Encode_Length_L]	//add cfwei20041210 
	JBE ?_Length_Enough			//add cfwei20041210 
 
?_Length_not_Enough:				//throw away current frame 
	R3 -= C_ENCODE_OUT_LENGTH 
	R4 -= 0,carry 
	[R_SACM_Encode_Count_L] = R3 
	[R_SACM_Encode_Count_H] = R4 
 
	R1 = [R_SACM_Encode_Out_PTR] 
	R1 -= C_ENCODE_OUT_LENGTH 
	[R_SACM_Encode_Out_PTR] = R1 
 
	//============ force encoding to Stop 
	R1 = [R_SACM_Play_Flag] 
	R1 &= ~C_SACM_FIQ_SOUND	// Disable FIQ_SOUND Flag 
	R1 |= C_SACM_DECODE_END	// Set CODEC_END Flag 
	[R_SACM_Play_Flag] = R1 
 
.ifdef SND_CB_RECFULL 
	call _Snd_onRecFull 
.endif 
 
   	//JMP ?_Finish_Process;		//guili 2005.12.06 
   	JMP _Finish_Process		//guili 2005.12.06 
 
//====== end of Chech File Size =====================// 
 
?_Length_Enough: 
	push r3,r4 to [sp]	//added by mgl 2005/04/12 
		call F_SACM_System_Put_BS_Manual 
	pop r3,r4 from [sp]	//added by mgl 2005/04/12 
 
//====== Chech if write success (diskfull?) ==========// 
	cmp r1,0 
	jz ?_DataWriteSuccess 
 
	//============ force encoding to Stop ? 
	R1 = [R_SACM_Play_Flag] 
	R1 &= ~C_SACM_FIQ_SOUND// Disable FIQ_SOUND Flag 
	R1 |= C_SACM_DECODE_END // Set CODEC_END Flag 
	[R_SACM_Play_Flag] = R1 
 
.ifdef SND_CB_RECFULL 
//	call _Snd_onRecFull		//delete by chengye 2006/11/10 
.endif 
   	//JMP ?_Finish_Process;		//guili 2005.12.06 
   	JMP _Finish_Process		//guili 2005.12.06 
 
 
?_DataWriteSuccess: 
//====== Chech if decoding ends ======================// 
	R1=[R_SACM_Play_Flag] 
	test R1, C_SACM_STOP 
	jz _Branch_2				//guili 2005.12.06 
 
//====== End Recording, close file ===================// 
F_SACM_Encode_Stop_Process: 
_SACM_Encode_Stop_Process:			//guili 2005.12.06 for DVR pause->stop bug 
	call F_SACM_Encode_Finish_Process 
	call F_SACM_System_Put_BS_Manual 
	R1=0x0000 
	[R_SACM_Play_Flag] = R1			//Reset the Flag 
 
_Finish_Process:				//guili 2005.12.06 
	R1 = [R_SACM_Decode_Count_L] 
	R2 = [R_SACM_Decode_Count_H] 
	R1 = R1 LSL 4 
	R2 = R2 ROL 1 
	R1 = [R_SACM_Decode_Count_L] 
	R1 = R1 LSL 1 
 
	push R8, R15 to [sp] 
	call F_USER_DVR1600_EndRecord //return file length R1:Low,R2:High 
	pop R8, R15 from [sp] 
 
	call F_SACM_DisableADC 
 
.ifdef DVR_REC_MONINTER 
	test R1,C_SACM_REC_Mon_ON 
   	jz _Branch_0			//guili 2005.12.06 
 
	push r1,r4 to [sp] 
	call _Snd_onAmpOff	//cfwei20041209 
	pop r1,r4 from [sp] 
 
	test R1, C_SACM_RAMP_DN_ENABLE 
   	jz _Branch_0			//guili 2005.12.06 
 
   	test R1, C_SACM_ENABLE_DAC1 
	jz _Branch_1			//guili 2005.12.06 
 
	call F_SACM_RampDnDAC1 
 
_Branch_1:				//guili 2005.12.06 
   	test R1, C_SACM_ENABLE_DAC2 
   	jz _Branch_0;			//guili 2005.12.06 
 
 	call F_SACM_RampDnDAC2 
 
_Branch_0:				//guili 2005.12.06 
	call F_SACM_DisableDAC1 //cfwei20041209 
	call F_SACM_DisableDAC2 //cfwei20041209 
.endif 
 
	.ifdef SND_CB_RECEND 
//		call _Snd_onRecStop 
	.endif 
//	R1 = 0								//delete by chengye 2006/9/22 
//	[_SndSACM_curPlayID] = R1 // decoding end. 
 
// Finish_Process												// 
//**************************************************************// 
?_Branch_2:				//guili 2005.12.06 
_Branch_2:				//guili 2005.12.06 
	retf 
	.endp 
.endif //==C_SND_DVR_SUPPORT======= 
 
 
//================================================================ 
_SACM_DECODE_ServiceLoop: .proc 
	//push R1,R5 to [sp]; 
	R1 = [R_SACM_Play_Flag] 
	test R1, C_SACM_PLAY  // Check if playing 
	jnz ?L_Check_Pause 
	retf 
 
?L_Check_Pause: 
	test R1, C_SACM_PAUSE   	    // Check if playing 
	jz ?_Continue_0 
	retf 
 
?_Continue_0: 
	test R1, C_SACM_DECODE_WORK   // Check if decoding 
	jnz ?_Continue_1 
	retf 
 
?_Continue_1: // Decoding 
	R1 &= ~C_SACM_DECODE_WORK 
	[R_SACM_Play_Flag] = R1 
//.comment @ 
.ifdef MP3_DECODE_EFFECT 
	r1 = 0 
	[R_Decode_Finish]=r1				//add by jacky 2006.02.15 
.endif 
//@ 
	R1 = [R_CODEC_TYPE] 
.ifdef C_SND_S200_SUPPORT		//The speed of the following codecs 
	cmp R1, C_CODEC_S200		//cannot be changed 
	je ?_Branch3 
.endif 
.ifdef C_SND_S200TTS_SUPPORT 
	cmp R1, C_CODEC_S200TTS 
	je ?_Branch3 
.endif 
.ifdef C_SND_S320_SUPPORT 
	cmp R1, C_CODEC_S320	//added by zgq 2005/03/31 
	je ?_Branch3			//added by zgq 2005/03/31 
.endif 
.ifdef C_SND_S320TTS_SUPPORT 
	cmp R1, C_CODEC_S320TTS//added by zgq 2005/03/31 
	je ?_Branch3 			//added by zgq 2005/03/31 
.endif 
.ifdef C_SND_MS01_SUPPORT 
	cmp R1, C_CODEC_MS01 
	je ?_Branch3 
.endif 
.ifdef C_SND_MS02_SUPPORT 
	cmp R1, C_CODEC_MS02	//added by zgq 2005/03/04 
	je ?_Branch3			//added by zgq 2005/03/04 
.endif 
.ifdef C_SND_A4800_SUPPORT 
	cmp R1, C_CODEC_A4800 
	jne ?L_NOTA4800 
	fir_mov off 
	.ifdef C_SND_A4800_SPEEDCONTROL_SUPPORT 
		push r3,r4 to [sp] 
		r3=0x30					//xiaolei modify for 2002 platform 2006/07/14 
		r4=0x01 
		call mr 
		pop	r3,r4 from [sp] 
	.else									//added by zgq on 20051220 
		call F_SACM_Decode_Process			//added by zgq on 20051220 
	.endif									//added by zgq on 20051220 
		jmp ?_Continue_2 
?L_NOTA4800: 
.endif 
.ifdef C_SND_DVR4800_SUPPORT	//add new xiaolei 2006/04/04 
	cmp R1, C_CODEC_DVR4800 
	je ?_Branch3 
.endif 
.ifdef C_SND_ETTS_SUPPORT 
	cmp R1, C_CODEC_ETTS 
	je ?_Branch3 
.endif 
.ifdef C_SND_MP3_SUPPORT 
	cmp R1, C_CODEC_MP3 
	je ?_Branch4 
.endif 
.ifdef C_SND_DVR520_SUPPORT	//xiaolei add DVR520 2006/04/01 
	cmp R1, C_CODEC_DVR520 
	jne ?L_NOTDVR520 
	fir_mov off 
	.ifdef C_SND_DVR520_SPEEDCONTROL_SUPPORT 
		push r3,r4 to [sp]					//xiaolei modify for 2002 platform 2006/07/14 
		r3=0x30 
		r4=0x01 
		call mr 
		pop	r3,r4 from [sp] 
		//call F_SACM_XXXX_Speed_Process		//added by zgq on 20051220 
	.else									//added by zgq on 20051220 
		call F_SACM_Decode_Process			//added by zgq on 20051220 
	.endif									//added by zgq on 20051220 
		jmp ?_Continue_2 
?L_NOTDVR520: 
.endif//end define C_SND_DVR520_SUPPORT 
.ifdef C_SND_A1800_SUPPORT	//xiaolei add A2400 2006/04/01 
	cmp R1, C_CODEC_A1800 
	jne ?L_NOTA1800 
//	fir_mov off 
	.ifdef C_SND_A1800_SPEEDCONTROL_SUPPORT 
		push r3,r4 to [sp] 
		r3=0x30					//xiaolei modify for 2002 platform 2006/07/14 
		r4=0x01 
		call mr 
		pop	r3,r4 from [sp] 
		//call F_SACM_XXXX_Speed_Process	//added by zgq on 20051220 
	.else									//added by zgq on 20051220 
		call F_SACM_Decode_Process			//added by zgq on 20051220 
	.endif									//added by zgq on 20051220 
		jmp ?_Continue_2 
?L_NOTA1800: 
.endif//end define C_SND_A1800_SUPPORT 
.ifdef C_SND_A3200_SUPPORT	//xiaolei add A3200 2006/07/04 
	cmp R1, C_CODEC_A3200 
	jne ?L_NOTA3200 
//	fir_mov off 
	.ifdef C_SND_A3200_SPEEDCONTROL_SUPPORT 
		push r3,r4 to [sp] 
		r3=0x30					//xiaolei modify for 2002 platform 2006/07/14 
		r4=0x01 
		call mr 
		pop	r3,r4 from [sp] 
		//call F_SACM_XXXX_Speed_Process		//added by zgq on 20051220 
	.else									//added by zgq on 20051220 
		call F_SACM_Decode_Process			//added by zgq on 20051220 
	.endif									//added by zgq on 20051220 
		jmp ?_Continue_2 
?L_NOTA3200: 
.endif//end define C_SND_A3200_SUPPORT 
.ifdef C_SND_A1800_SKIPPLAY_SUPPORT	//xiaolei add DVR520 2006/04/01 
	cmp R1, C_CODEC_A1800_SKIP 
	jne ?L_NOTA1800SKIP 
//	fir_mov off 
	.ifdef C_SND_A1800_SPEEDCONTROL_SUPPORT 
		push r3,r4 to [sp] 
		r3=0x30					//xiaolei modify for 2002 platform 2006/07/14 
		r4=0x01 
		call mr 
		pop	r3,r4 from [sp] 
		//call F_SACM_XXXX_Speed_Process		//added by zgq on 20051220 
	.else									//added by zgq on 20051220 
		call F_SACM_Decode_Process			//added by zgq on 20051220 
	.endif									//added by zgq on 20051220 
		jmp ?_Continue_2 
?L_NOTA1800SKIP: 
.endif//end define C_SND_A1800_SKIPPLAY_SUPPORT 
.ifndef C_SND_S480720_SPEEDCONTROL_SUPPORT 
	.ifdef C_SND_S480_SUPPORT 
		cmp R1, C_CODEC_S480 
		jne ?_Branch3_ 
		 
		fir_mov off 
		r1 = [R_SACM_DAC_Out_PTR_Decode] 
		[R_SACM_S4872_Decode_Out_PTR] = r1 
		call F_SACM_Decode_Process 
		 
		jmp ?_Continue_2 
	?_Branch3_: 
	.endif//end define C_SND_S480_SUPPORT 
	.ifdef C_SND_S720_SUPPORT 
		cmp R1, C_CODEC_S720 
		jne ?_Branch3_1 
		 
		fir_mov off 
		r1 = [R_SACM_DAC_Out_PTR_Decode] 
		[R_SACM_S4872_Decode_Out_PTR] = r1 
		call F_SACM_Decode_Process 
		 
		jmp ?_Continue_2 
	?_Branch3_1: 
	.endif//end define C_SND_S720_SUPPORT 
.else 
	.ifdef C_SND_S480_SUPPORT 
		cmp R1, C_CODEC_S480 
		jne ?_Branch3_2 
		 
		r1 = R_SACM_Decode_Out_Buffer		//added by zgq on 20050715 
		[R_SACM_Decode_Out_PTR] = r1 
		fir_mov off 
		r2 = fr 
		push r2,r4 to [sp] 
		r3=0x30					//xiaolei modify for 2002 platform 2006/07/14 
		r4=0x01 
		call mr 
		pop	r2,r4 from [sp] 
		fr = r2 
		//call F_SACM_XXXX_Speed_Process 
		jmp ?_Continue_2 
	?_Branch3_2: 
	.endif//end define C_SND_S480_SUPPORT 
	.ifdef C_SND_S720_SUPPORT 
		cmp R1, C_CODEC_S720 
		jne ?_Branch3_3 
			r1 = R_SACM_S4872_Decode_Out_Buffer		//added by zgq on 20050715 
			[R_SACM_S4872_Decode_Out_PTR] = r1 
			push r3,r4 to [sp] 
			r3=0x30					//xiaolei modify for 2002 platform 2006/07/14 
			r4=0x01 
			call mr 
			pop	r3,r4 from [sp] 
			//call F_SACM_XXXX_Speed_Process 
		jmp ?_Continue_2 
	?_Branch3_3: 
	.endif	//end of definition of C_SND_S720_SUPPORT 
.endif//end define C_SND_S480720_SPEEDCONTROL_SUPPORT 
 
.ifdef	C_SpeedControl			//xiaolei add for speed control 
	fir_mov off 
	r1 = R_SACM_Decode_Out_Buffer		//added by zgq on 20050715 
	[R_SACM_Decode_Out_PTR] = r1 
	push r3,r4 to [sp] 
	r3=0x30					//xiaolei modify for 2002 platform 2006/07/14 
	r4=0x01 
	call mr 
	pop	r3,r4 from [sp] 
	//call F_SACM_XXXX_Speed_Process 
	jmp ?_Continue_2 
.endif 
 
?_Branch3: 
	fir_mov off 
	fraction off		//for S320/S320TTS 
?_Branch4: 
	call F_SACM_Decode_Process 
 
?_Continue_2: 
 
//.comment @								//xiaolei remove to the Uper 2006/11/28 
.ifdef MP3_DECODE_EFFECT 
	r1 = 1 
	[R_Decode_Finish]=r1				//add by jacky 2006.02.15 
.endif 
//@ 
 
	R1 = [R_SACM_Play_Flag] 
	test R1, C_SACM_DECODE_ODD 
	jnz ?L_Branch_0 
 
	//R2 = R_SACM_DAC_Out_Buffer+C_DAC_OUT_LENGTH; 
	R2 = R_SACM_DAC_Out_Buffer//benwang 
	R2 += [R_DAC_OUT_LENGTH]			//本次Decode在第一个Buffer里面 
//================================== 
//Play的指针在Buffer add 2007/01/16 
	R3 = [R_SACM_DAC_Out_PTR_Play] 
	cmp R3, R2 
	jae ?L_NormalDecode 
	R1 ^= C_SACM_FIQ_EVEN 
?L_NormalDecode: 
//================================== 
	jmp ?L_Branch_1 
 
?L_Branch_0: 
	R2 = R_SACM_DAC_Out_Buffer + 0 
//================================== 
//Play的指针在Buffer add 2007/01/16 
	R3 = [R_SACM_DAC_Out_PTR_Play] 
	R4 = [R_SACM_DAC_Out_PTR_Decode]	//0x930 
	cmp R3, R4 
	jbe ?L_NormalDecode1 
	R1 ^= C_SACM_FIQ_EVEN 
?L_NormalDecode1: 
//================================== 
 
?L_Branch_1: 
	[R_SACM_DAC_Out_PTR_Decode] = R2 
	R1 ^= C_SACM_DECODE_ODD 
	[R_SACM_Play_Flag] = R1 
	test R1, C_SACM_DECODE_END 
//	jnz ?L_Branch_2 
	jnz ?L_Branch_2_1 
 
	test R1, C_SACM_AUTO // Ramp_Dn = 0x0002 
   	//jnz ?L_AutoGetBS 
   	jz ?L_ManualGetBS 
 
?L_AutoGetBS: 
	// AUTO MODE 
	call F_SACM_Decode_Get_BS_Auto 
	JMP ?L_Branch_2 
 
?L_ManualGetBS: 
	//MANUAL_MODE 
	//************************added by benwang start 03.01.2004 
	R1 = [R_CODEC_TYPE] 
//	cmp R1 ,C_CODEC_S600TTS;		//mgl 2005/03/14 
.ifdef C_SND_S200TTS_SUPPORT 
	cmp R1 ,C_CODEC_S200TTS		//mgl 2005/03/14 
	JNE ?_NOT_S200TTS			//mgl 2005/03/14 
	call F_SACM_TTS200_System_Get_BS_Manual//mgl 2005/04/18 
	JMP ?L_Branch_2			//mgl 2005/03/14 
?_NOT_S200TTS: 					//2005/03/31 
.endif 
 
.ifdef C_SND_S320TTS_SUPPORT 
	cmp R1 ,C_CODEC_S320TTS 		//2005/03/31 
	jne ?_NOT_TTS 			//2005/03/31 
	.ifdef TTS320FAT 
		call F_TTS320_System_Get_BS_ManualFAT //2005/03/31 
	.else 
		call F_TTS320_System_Get_BS_Manual 
	.endif 
	jmp ?L_Branch_2 			//2005/03/31 
?_NOT_TTS: 
.endif 
 
.ifdef C_SND_ETTS_SUPPORT 
	cmp R1, C_CODEC_ETTS 
	je ?L_Branch_2 
.endif 
	//unOSSemPost _Snd_MP3TaskSem 
	call F_SACM_System_Get_BS_Manual 
 
	JMP ?L_Branch_2 
	//*************************added by benwang end 03.01.2004 
 
	//call F_SACM_System_Get_BS_Manual; //benwang 03.01.2004 
	//jmp ?L_Branch_2 //del by benwang 03.01.2004 
?L_Branch_2_1: 
//xiaolei add for MP3 PlayList at the BackPlatform: 
.ifdef C_SND_MP3_SUPPORT 
	R1 = [R_CODEC_TYPE] 
	cmp R1, C_CODEC_MP3 
	jnz ?L_DecodeEnd 
	R1 = [_Snd_MP3_Status] 
	cmp R1, 3 
	jnz ?L_NextFile 
	R1 = [R_SACM_Play_Flag] 
	R1 ^= C_SACM_DECODE_END 
	[R_SACM_Play_Flag]=R1 
	call _MediaPlayer_PlayAB 
	jmp ?L_DecodeEnd 
?L_NextFile: 
//	R1 = 2; 
//	[_Snd_MP3_Status] = R1;						//Just the flag of the Getting Datas in 2 Pri Task 
	call _PlayNextFile 
?L_DecodeEnd: 
.endif 
//xiaolei add end 2006/09/12 
?L_Branch_2: 
	retf 
.endp 
//============================================================== 
 
//============================================================== 
//		APIs called by ISR( encode + decode ) 
//============================================================== 
//************************************************************** 
// Function:	F_ISR_Service_SACM_Speed 
// Input:	N/A 
// Output:	R1=1 means Buffer switch, otherwise R1=0 
// Registers used : R1,R5 
// Syntax: 
// 	call F_ISR_Service_SACM_Speed; (in assembly domain) 
//**************************************************************** 
//F_ISR_Service_SACM_Speed_FG: 
 	//push R1, R5 to [SP];	//== removed by cfwei 20040420 
 
	// Add other general service functions here 
 	//R1 = [R_SACM_Play_Flag]; 
	//test R1,C_SACM_CODEC_MODE; 
	//JE _FIQ_Decode; 
	//goto _FIQ_Encode; 
 
 
//============================================================= 
//_FIQ_Decode: 
F_ISR_Service_SACM_Decode: 
 	R3 = [R_SACM_Play_Flag]; 
	test R3, C_SACM_FIQ_SOUND; 
 	jne ?_Branch_0; 
 
	// not playing 
  	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1=0; //== cfwei 20040420 
	retf; 
 
?_Branch_0: 
	call F_SACM_SendDACMulti	//fill data to FIFO begin 
 
 	R1 = [R_SACM_Play_Flag]; 
	test R1, C_SACM_FIQ_EVEN; 
	jnz ?No_Branch 
	goto ?_Branch_1 
	//jz ?_Branch_1; 
?No_Branch: 
 
	R3 = [R_DAC_OUT_LENGTH]; 
	R3 += R_SACM_DAC_Out_Buffer; 
	CMP R2, R3; 
	jae ?L_Branch_2Conti 
	goto ?_Branch_2 
	//jne ?_Branch_2; 
?L_Branch_2Conti: 
.ifdef C_SND_ETTS_SUPPORT 
	r4 = [R_CODEC_TYPE] 
	cmp r4,C_CODEC_ETTS 
	jnz ?L_NotETTS 
 
	push r1,r4 to [sp] 
	call _CheckETTSStatus		//1: not Stop,0:Stop 
	r4 = r1 
	pop r1,r3 from [sp] 
	sp += 1 
	cmp r4,0 
	jnz ?_Branch_3ETTS; 
	jmp ?L_ETTSStop 
?L_NotETTS: 
.endif 
 
	test R1, C_SACM_DECODE_END; 
	jz ?_Branch_3; 
 
.ifdef C_SND_ETTS_SUPPORT 
?L_ETTSStop: 
.endif 
 
.ifdef C_SND_CTTS_SUPPORT 
	r2 = [_Snd_TTS_IsPlaying] 
	cmp r2, C_CTTSETTS_PLAYING 
	je ?_Branch_6 
	r2 = [_Snd_CTTS_IsPlaying] 
	cmp r2, C_CTTS_PLAYING 
	je ?_Branch_6 
.endif 
	call R_F_SACM_Stop_Var 
//	call F_SACM_Stop;							//xiaolei modify 2006/08/05 
//	call F_SACM_EndPlay // in sacm.asm			//xiaolei delete 2006/08/05 
 
.ifdef C_SND_CTTS_SUPPORT 
	jmp ?_Branch_7 
?_Branch_6: 
	call _SACM_Middle_Stop 
?_Branch_7: 
.endif 
  	R1=2; 			//== cfwei 20040420 
	retf; 
 
?_Branch_3: 
.if 1				//xiaolei add for MP3 noise 2006/11/19 
.ifdef MP3_DECODE_EFFECT 
	r3 = [R_Decode_Finish]		//== 1表示解码完毕 
	jnz	?switch 
	r3 = 0 
	[R_Decode_Finish_A] = r3 
	jmp	?_Branch_2				//add by jacky 2006.02.16 
?switch: 
.endif 
.endif 
?_Branch_3ETTS: 
	R1 |= C_SACM_DECODE_WORK; 
	R1 ^= C_SACM_FIQ_EVEN; 
	[R_SACM_Play_Flag] = R1; 
 
//Get One DAC_OUT_Length Buffer Data 
.ifdef C_SND_MP3_SUPPORT 
	R1 = [R_CODEC_TYPE] 
	cmp R1, C_CODEC_MP3 
	jne ?L_NotMP3Continue 
	R1 = [Mp3_FrameCount_L]; //20060605 
 	R3 = [Mp3_FrameCount_H]; //20060605 
	R1 += 1;				 //20060605 
	R3 += 0, carry;		     //20060605 
 	[Mp3_FrameCount_L] = R1; //20060605 
	[Mp3_FrameCount_H] = R3; //20060605 
?L_NotMP3Continue: 
.endif 
//Get End 
 
.if 1				//xiaolei add for MP3 noise 2006/11/19 
.ifdef MP3_DECODE_EFFECT 
	r3 = 1 
	[R_Decode_Finish_A] = r3 
.endif 
.endif 
 
	[R_SACM_DAC_Out_PTR_Play] = R2; //== cfwei 20040420 
  	R1 = 1;	//== cfwei 20040420 
	retf;	//== cfwei 20040420 
 
?_Branch_2: 
	[R_SACM_DAC_Out_PTR_Play] = R2; 
  	R1 = 0;	//== cfwei 20040420 
	retf; 
 
?_Branch_1: 
	R3 = [R_DAC_OUT_LENGTH]; 
	R3 = R3 LSL 1; 
	R3 += R_SACM_DAC_Out_Buffer; 
	CMP R2, R3; 
	jae ?_Branch_4Conti 
 	goto ?_Branch_4 
 	//jne ?_Branch_4; 
?_Branch_4Conti: 
.ifdef C_SND_ETTS_SUPPORT 
	r4 = [R_CODEC_TYPE] 
	cmp r4,C_CODEC_ETTS 
	jnz ?L_NotETTS1 
 
	push r1,r4 to [sp] 
	call _CheckETTSStatus		//1: not Stop,0:Stop 
	r4 = r1 
	pop r1,r3 from [sp] 
	sp += 1 
	cmp r4,0 
	jnz ?_Branch_5ETTS; 
	jmp ?L_ETTSStop1 
 
?L_NotETTS1: 
.endif 
 
	test R1, C_SACM_DECODE_END; 
	jz ?_Branch_5; 
 
.ifdef C_SND_ETTS_SUPPORT 
?L_ETTSStop1: 
.endif 
 
.ifdef C_SND_CTTS_SUPPORT 
	r2 = [_Snd_TTS_IsPlaying] 
	cmp r2,C_CTTSETTS_PLAYING 
	je ?_Branch_8 
	r2 = [_Snd_CTTS_IsPlaying] 
	cmp r2,C_CTTS_PLAYING 
	je ?_Branch_8 
.endif 
	call R_F_SACM_Stop_Var; 
	//call F_SACM_Stop; 
	//call F_SACM_EndPlay // in sacm.asm 
.ifdef C_SND_CTTS_SUPPORT 
	jmp ?_Branch_9 
?_Branch_8: 
	call _SACM_Middle_Stop 
?_Branch_9: 
.endif 
  	R1=2;	//== cfwei 20040420 
	retf; 
 
?_Branch_5: 
.if 1				//xiaolei add for MP3 noise 2006/11/19 
.ifdef MP3_DECODE_EFFECT 
	r3=[R_Decode_Finish]		//add by jacky 2006.02.16 
	jnz	?switch1				//add by jacky 2006.02.16 
	r3 = 0 
	[R_Decode_Finish_A]=r3 
	R2 -= 0x10 
	jmp	?_Branch_4				//add by jacky 2006.02.16 
?switch1: 
.endif 
.endif 
?_Branch_5ETTS: 
	R1 |= C_SACM_DECODE_WORK; 
	R1 ^= C_SACM_FIQ_EVEN; 
	[R_SACM_Play_Flag] = R1; 
 
//Get One DAC_OUT_Length Buffer Data 
.ifdef C_SND_MP3_SUPPORT 
	R1 = [R_CODEC_TYPE] 
	cmp R1, C_CODEC_MP3 
	jne ?L_NotMP3Continue1 
	R1 = [Mp3_FrameCount_L]; //20060605 
 	R3 = [Mp3_FrameCount_H]; //20060605 
	R1 += 1;				 //20060605 
	R3 += 0, carry;		     //20060605 
 	[Mp3_FrameCount_L] = R1; //20060605 
	[Mp3_FrameCount_H] = R3; //20060605 
?L_NotMP3Continue1: 
.endif 
//Get End 
 
	R2 = R_SACM_DAC_Out_Buffer; 
.if 1				//xiaolei add for MP3 noise 2006/11/19 
.ifdef MP3_DECODE_EFFECT 
	r3 = 1 
	[R_Decode_Finish_A] = r3 
.endif 
.endif 
 
 
	[R_SACM_DAC_Out_PTR_Play] = R2; //== cfwei 20040420 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1 = 1;	//== cfwei 20040420 
	retf	//== cfwei 20040420 
 
?_Branch_4: 
	[R_SACM_DAC_Out_PTR_Play] = R2; 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1 = 0; //== cfwei 20040420 
	retf 
 
//========================================================= 
.ifdef C_SND_DVR_SUPPORT 
//_FIQ_Encode: 
F_ISR_Service_SACM_Encode: 
 	R1 = [R_SACM_Play_Flag]; 
	test R1, C_SACM_FIQ_SOUND; 
 	jne ?_Branch_0; 
 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1 = 0;	//== cfwei 20040420 
  	retf; 
 
?_Branch_0://8KHZ 
	//push R1 to[sp]; 
	//R1 = [R_ADC_Channel]; 
//====================================== 
//xiaolei modify FIFO depth to 4 or more 
//.if 0 
.ifdef C_SYSTEM_SPL162001		//modify by chengye 2006/8/31 
	call F_SACM_GetADC; 
	R3 = R1; 
 
.ifdef DVR_REC_MONINTER 
	r1=[R_SACM_Play_Flag] 
	test R1,C_SACM_REC_Mon_ON; 
	jz ?L_REC_NoMon; 
	[P_CHA_Data] = R3;   //recmonitor???    //ywang 2004/01/09 
	//[P_CHB_Data] = R3; //recmonitor???	//ywang 2004/01/09 
.endif 
 
?L_REC_NoMon: 
	R3^=0x8000; 
//	R3-=R3 ASR 3; 
 
	R2 = [R_SACM_ADC_In_PTR_Rec]; 
	[R2++]=R3; 
.else 
	R2 = [R_SACM_ADC_In_PTR_Rec]; 
	call F_SACM_GetADC_More; 
.endif 
//======================xiaolei modify end 
//======================================== 
	r1=[R_SACM_Play_Flag] 
	test R1, C_SACM_FIQ_EVEN; 
	jz ?_Branch_1; 
 
?_Continue_0: 
	//cmp R2, R_SACM_ADC_In_Buffer + C_ENCODE_IN_LENGTH; 
	r3=[R_ADC_IN_LENGTH] 
	R3 += R_SACM_ADC_In_Buffer 
	cmp R2, r3 
	jne ?_Branch_2; 
 
	test R1, C_SACM_DECODE_END; 
	jz ?_Branch_3; 
 
	call F_SACM_Stop; 
 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1=2;	//== cfwei 20040420 
	retf; 
 
?_Branch_3: 
	R1 |= C_SACM_DECODE_WORK; 
	R1 ^= C_SACM_FIQ_EVEN; 
	[R_SACM_Play_Flag] = R1; 
 
	[R_SACM_ADC_In_PTR_Rec] = R2; //== cfwei 20040420 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1=1;	//== cfwei 20040420 
	retf;	//== cfwei 20040420 
 
?_Branch_2: 
	[R_SACM_ADC_In_PTR_Rec] = R2; 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1=0;	//== cfwei 20040420 
	retf; 
 
?_Branch_1: 
	nop; 
 
?_Continue_1: 
//	cmp R2, R_SACM_ADC_In_Buffer + 2 * C_ENCODE_IN_LENGTH; 
	R3 = [R_ADC_IN_LENGTH];			//zgq 2005/03 
	R3 = R3 LSL 1;				//zgq 2005/03 
	R3 += R_SACM_DAC_Out_Buffer;	//zgq 2005/03 
	CMP R2, R3; 				//zgq 2005/03 
 	jne ?_Branch_4; 
 
	test R1, C_SACM_DECODE_END; 
	jz ?_Branch_5; 
 
	call F_SACM_Stop; 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1=2;	//== cfwei 20040420 
	retf; 
 
?_Branch_5: 
	R1 |= C_SACM_DECODE_WORK; 
	R1 ^= C_SACM_FIQ_EVEN; 
	[R_SACM_Play_Flag] = R1; 
	R2 = R_SACM_ADC_In_Buffer; 
 
	[R_SACM_ADC_In_PTR_Rec] = R2; //== cfwei 20040420 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1=1;	//== cfwei 20040420 
	retf;	//== cfwei 20040420 
 
?_Branch_4: 
	[R_SACM_ADC_In_PTR_Rec] = R2; 
	//pop R1, R5 from [SP]; //== removed by cfwei 20040420 
  	R1=0;	//== cfwei 20040420 
	retf; 
 
//////////////////////////////////////////////////////// 
F_Reset_File_Access: 
	//R1=0x0001;  				//removed cfwei20041210 
	R1 = [_SACM_Encode_Length_H];	//cfwei20041210 
	[R_SACM_Encode_Length_H]=R1;	//Set File Size 
	//R1=0xFFFF;  				//removed cfwei20041210 
	R1 = [_SACM_Encode_Length_L];	//cfwei20041210 
	[R_SACM_Encode_Length_L]=R1;	//Set File Size 
	RETF; 
.endif //C_SND_DVR_SUPPORT ========================== 
 
//For CTTS PCM Data Play: 
.external F_SendPCMData 
 
.public F_ISR_Service_PCM 
F_ISR_Service_PCM: .proc 
//	call F_SendPCMData 
	retf 
.comment @ 
	R3 = [_TTSDataBufferFalg] 
	cmp R3, 1 
	je ?L_SecondBuffer 
	R3 = [_pPCMReadBuffer + 1]				//比较高位 
	R4 = [_Snd_CTTSLocalMemory + 1]//0x26 
	R5 = [_PCMBufferSize] 
	R5 += [_Snd_CTTSLocalMemory] 
	R4 += 0, Carry 
	cmp R3, R4 
	jb ?L_Continue 
	R3 = [_pPCMReadBuffer]					//比较低位 
	R4 = [_Snd_CTTSLocalMemory] 
	R4 += [_PCMBufferSize] 
	cmp R3, R4 
	jb ?L_Continue 
	R1 = [_Snd_CTTSLocalMemory] 
	[_pPCMReadBuffer] = R1 
	R1 = [_Snd_CTTSLocalMemory + 1] 
	[_pPCMReadBuffer + 1] = R1 
	jmp ?L_Continue 
?L_SecondBuffer: 
	R3 = [_pPCMReadBuffer + 1]				//比较高位 
	R4 = [_Snd_CTTSLocalMemory1 + 1]//0x26 
	R5 = [_PCMBufferSize] 
	R5 += [_Snd_CTTSLocalMemory1] 
	R4 += 0, Carry 
	cmp R3, R4 
	jb ?L_Continue 
	R3 = [_pPCMReadBuffer]					//比较低位 
	R4 = [_Snd_CTTSLocalMemory1] 
	R4 += [_PCMBufferSize] 
	cmp R3, R4 
	jb ?L_Continue 
	R1 = [_Snd_CTTSLocalMemory1] 
	[_pPCMReadBuffer] = R1 
	R1 = [_Snd_CTTSLocalMemory1 + 1] 
	[_pPCMReadBuffer + 1] = R1 
?L_Continue: 
	call F_SendPCMData 
	R3 = [_pPCMReadLength] 
	R4 = [_pPCMWriteLength] 
	cmp R3, R4 
	jb ?L_Return 
	R1 = 1 
	jmp ?L_Exit 
?L_Return: 
	R1 = 0 
//	jmp ?L_Exit 
?L_Exit: 
	retf 
//@ 
.endp 
 
//====================================================== 
//		parameter set and get 
//====================================================== 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Status 
// Description:	Get playback status 
// Syntax:	void SACM_Status(void); 
// 
// Parameter:	N/A 
// Return:	R1 = [R_SACM_Play_Flag]  , pls refer to 
//		SACM_Constant for detailed definition 
//		[b0] = C_SACM_PLAY  	0x0001 
//		[b1] = C_SACM_RECORD	0x0002 
//		[b2] = C_SACM_PAUSE  0x0004 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Status: .proc 
F_SACM_Status: 
	R1 = [R_SACM_Play_Flag] 
   	retf; 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Volume 
// Description:	Set speech volume 
// Syntax:	void SACM_Volume(int volume index); 
// Parameter:	volume index: {0..15(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Volume: .proc 
	R1 = SP + 3; 
	R1 = [R1]; 
	call F_SACM_Volume; 
	retf; 
.endp 
 
//For MP3 Playing 出现杂音, 表现为不实时, 这时需要将中断里的音量增益拿掉, 
//但需要单独设置MP3的音量: 
.ifdef C_SND_MP3_SUPPORT 
.ifdef C_SND_MP3_SETVOLMUME 
 
.public _SACM_MP3Volume 
//////////////////////////////////////////////////////// 
// Function:	_SACM_MP3Volume 
// Description:	Set speech volume 
// Syntax:	void SACM_MP3Volume(int volume index); 
// Parameter:	volume index: {0..15(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_MP3Volume: .proc 
	R1 = SP + 3; 
	R1 = [R1]; 
.ifdef NANDBOOT_NOTEXT 
	R2 = seg T_SACM_Volume_Level 
	DS = R2; 
	R2 = offset T_SACM_Volume_Level 
	R1 += R2 
	R1 = DS:[R1] 
.else 
	R1 += T_SACM_Volume_Level; 
	R1 = [R1]; 
.endif 
	[R_SACM_Play_MP3_Gain] = R1; 
	retf 
.endp 
 
.endif		//End of C_SND_MP3_SETVOLMUME definition 
.endif		//End of C_SND_MP3_SUPPORT definition 
//**************************************************************** 
// Function:	F_SACM_Volume 
// Syntax:	call F_SACM_Volume; (in assembly domain) 
// Input:	R1 = VolumeIndex 
// Output:	N/A 
// Destory:	R1 
//**************************************************************** 
F_SACM_Volume: 
.ifdef NANDBOOT_NOTEXT 
	R2 = seg T_SACM_Volume_Level 
	DS = R2; 
	R2 = offset T_SACM_Volume_Level 
	R1 += R2 
	R1 = DS:[R1] 
.else 
	R1 += T_SACM_Volume_Level; 
	R1 = [R1]; 
.endif 
	[R_SACM_Play_Gain] = R1; 
	retf 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Speed 
// Description:	Set speech speed 
// Syntax:	void SACM_A2000_Speed(int Speed_index); 
// 
// Parameter:	Speed index: {-12..12(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Speed: .proc 
	R1 = SP + 3; 
	R1 = [R1]; 
	call F_SACM_Speed; 
	retf; 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Speed 
// Description:	Set speech speed 
// Syntax:	void SACM_A2000_Speed(int Speed_index); 
// 
// Parameter:	Speed index: {-12..12(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
F_SACM_Speed: 
	R1 += 12; 
   	[R_SACM_SpeedIndex] = R1; 
	retf 
 
//////////////////////////////////////////////////////// 
_SACM_Get_Speed: 
   	R1 = [R_SACM_SpeedIndex]; 
	retf 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Pitch0 
// Description:	Set speech Pitch0 
// Syntax:	void _SACM_Pitch0(int Pitch0Index); 
// Parameter:	Pitch0Index : {0-4(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Pitch0: .proc 
   	R1 = SP + 3; 
   	R1 = [R1]; 
	[R_SACM_Play_Pitch0] = R1; 
   	retf; 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Pitch1 
// Description:	Set speech Pitch1 
// Syntax:	void _SACM_Pitch1(int Pitch1Index); 
// 
// Parameter:	Pitch1Index : {0-4(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Pitch1: .proc 
   	R1 = SP + 3; 
   	R1 = [R1]; 
	[R_SACM_Play_Pitch1] = R1; 
   	retf; 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Pitch 
// Description:	Set speech Pitch 
// Syntax:	void _SACM_Pitch(int PitchIndex); 
// 
// Parameter:	PitchIndex 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
//added by zgq 2005/03/31 
_SACM_Pitch: .proc 
   	R1 = SP + 3; 
   	R1 = [R1]; 
	[R_SACM_Play_Pitch] = R1; 
   	retf; 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Spectrum 
// Description:	Set speech Spectrum 
// Syntax:	void _SACM_Spectrum(int SpectrumIndex); 
// 
// Parameter:	SpectrumIndex 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Spectrum: .proc 
   	R1 = SP + 3; 
   	R1 = [R1]; 
	[R_SACM_Play_Spectrum] = R1; 
   	retf; 
.endp 
//added by zgq 2005/03/31 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Voice 
// Description:	Set speech Voice 
// Syntax:	void _SACM_Voice(int VoiceIndex); 
// Parameter:	VoiceIndex : {0-4(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Voice: .proc 
   	R1 = SP + 3; 
   	R1 = [R1]; 
	[R_SACM_Play_Voice] = R1; 
   	retf; 
.endp 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_Codec 
// Description:	Set speech Codec type 
// Syntax:	void _SACM_Codec(int CodecIndex); 
// Parameter:	CodecIndex : {0-5(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
_SACM_Codec: .proc 
   	R1 = SP + 3; 
   	R1 = [R1]; 
	[R_CODEC_TYPE] = R1; 
   	retf; 
.endp 
 
.ifdef C_SND_MP3_SUPPORT 
//Get the SampleRate and the BitRate 
.public _SACM_MP3_SetFS 
_SACM_MP3_SetFS: .proc 
		push r1,r5 to [sp] 
		call F_SACM_Decode_Initial_BS; 
		R1 = 1024; 
		[R_DECODE_IN_LENGTH] = R1;		 
		//R1 = [R_DECODE_IN_LENGTH]; 							 //add by benwang 20060209 
		R1 += R_SACM_Decode_In_Buffer; 						 //add by benwang 20060209 
		[R_SACM_Decode_In_PTR] = R1; 
	     
	    r1 =  fr 
	    push r1 to [sp] 
		call  F_SACM_Decode_Initial_Process; 
		pop r1 from [sp] 
		fr = r1 
 
		R1 = 0 
Dec_Loop?: 
		push R1 to [sp] 
 
	 	R1 = [R_SACM_Decode_Count_L]; 
	 	R2 = [R_SACM_Decode_Count_H]; 
		R1 += [R_SACM_DECODE_IN_LENGTH]; 
		R2 += 0, carry; 
	 	[R_SACM_Decode_Count_L] = R1; 
		[R_SACM_Decode_Count_H] = R2; 
	 	R3 = [R_SACM_Decode_Length_L]; 
	 	R4 = [R_SACM_Decode_Length_H]; 
		CMP R2,R4; 
	    JB _Branch_0?; 
	    CMP R1,R3; 
	    JB _Branch_0?; 
 
		pop r1 from [sp] 
Dec_Error?: 
		pop	r1,r5 from [sp] 
		R1 = 1; //Get_BR_FS fail 
		jmp _End?; 
 
_Branch_0?: 
		call F_SACM_System_Get_BS_Manual; //must call get_BS before _MP3_Get_BR_FS_Psuedo 20060118 
		R1 = [R_SACM_Decode_In_PTR]; 
	    [R_SACM_DECODE_IN_LENGTH] = R1;		 
 
		///////////////////////////// 
		push r3,r4 to [sp] 
		r3=0x24 
		r4=0x01 
		call mr 
		pop r4,r5 from [sp] 
		//call _MP3_Get_BR_FS_Psuedo; //add by benwang to test this function //20060118 
									//	Output:	r1--0(success) or 1(fail) 
									//			r2--sampling rate(in Hz) 
									//			r3--bitrate(in Kbps) 
									//	Reg used: 
									//	Note:If a valid header can't be found in one dec_in_buf,then return error 
		//////////////////////////////////////// 
//		r4 = [CFrame_layer] 
		r4 = [0x1ec1]; 
		cmp r4, 2 
		jne ?_layer_3; 
		r4 = 2304; 
		jmp ?_end; 
?_layer_3: 
		r4 = 1152; 
?_end: 
		[R_DAC_OUT_LENGTH] = r4; 
 
		R4 = [R_SACM_Decode_In_PTR]; 
		R4 -= [R_SACM_DECODE_IN_LENGTH]; 
		[R_SACM_DECODE_IN_LENGTH] = R4; 
 
		cmp R1, 0 
		je Dec_NotLoop? 
		pop R1 from [sp] 
		R1 += 1 
		cmp R1, 100 
		jae Dec_Error? 
		jmp Dec_Loop? 
//		jne Dec_Loop?; 
Dec_NotLoop?: 
		pop r1 from [sp] 
 
//		[_Snd_MP3_Status] = R1; 
		r4=[R_SACM_Decode_Count_L] 
		[_ulFrame_Count_MP3] = r4 
		[R_MP3_Decode_Count_L]=r4 
		r4=[R_SACM_Decode_Count_H] 
		[_ulFrame_Count_MP3 + 1] = r4 
		[R_MP3_Decode_Count_H]=r4 
 
		[MP3_FS] = R2; 
		[MP3_BR] = R3; 
		[_R_SampleRate] = R2			//xiaolei add for MP3 SampleRate & BitRate 
		[_R_MPEGBitRate] = R3 
		 
		pop	r1,r5 from [sp] 
		R1 = 0; //Get_BR_FS success 
_End?: 
		retf; 
.endp 
 
.public F_SACM_MP3_Get_Time 
.public _SACM_MP3_Get_Time 
F_SACM_MP3_Get_Time:.proc 
_SACM_MP3_Get_Time: 
	R1 = [Mp3_FrameCount_L]; 
	R2 = [R_DAC_OUT_LENGTH]; 
	R2 = R2 asr 1; 
	MR = R1 * R2,uu; 
	[Temp1] = R4; 
	[Temp2] = R3; //Sample_L 
 
	R1 = [Mp3_FrameCount_H]; 
	MR = R1 * R2,uu; 
	R3 += [Temp1]; 
	R4 += 0, carry; 
	[Temp1] = R3; //Sample_H 
 
//将快进快退的数据加上: 
.comment # 
	R1 = [Temp2]				//Sample_L 
	R2 = [Temp1]				//Sample_H 
	R3 = [R_MP3_SKIP_DATA_L]	//Skip Low 
	R4 = [R_MP3_SKIP_DATA_H]	//skip high 
	R1 += R3 
	R2 += R4, Carry 
	[Temp2] = R1 
	[Temp1] = R2 
//# 
//xiaolei 加快进快退数据结束 2006/11/30 
	 
	r1 = [MP3_FS];           //sampling rate(Hz)	 
	cmp R1, 44100; 
	jne ?_Endof44100; 
	R1 = 0; 
	jmp ?_End; 
?_Endof44100: 
	cmp R1, 48000; 
	jne ?_Endof48000; 
	R1 = 1; 
	jmp ?_End; 
?_Endof48000: 
	cmp R1, 32000; 
	jne ?_Endof32000; 
	R1 = 2; 
	jmp ?_End; 
?_Endof32000: 
	cmp R1, 22050; 
	jne ?_Endof22050; 
	R1 = 3; 
	jmp ?_End; 
?_Endof22050: 
	cmp R1, 24000; 
	jne ?_Endof24000; 
	R1 = 4; 
	jmp ?_End; 
?_Endof24000: 
	cmp R1, 16000; 
	jne ?_Endof16000; 
	R1 = 5; 
	jmp ?_End; 
?_Endof16000: 
	cmp R1, 11025; 
	jne ?_Endof11025; 
	R1 = 6; 
	jmp ?_End; 
?_Endof11025: 
	cmp R1, 12000; 
	jne ?_Endof12000; 
	R1 = 7; 
	jmp ?_End; 
?_Endof12000: 
	cmp R1, 8000; 
	jne ?_End; 
	R1 = 8; 
?_End:	 
 
.ifdef NANDBOOT_NOTEXT 
	R2 = seg T_MP3Fs_Table 
	DS = R2 
	R1 += offset T_MP3Fs_Table; 
	R1 = DS:[R1]; 
.else 
	R1 += T_MP3Fs_Table; 
	R1 = [R1]; 
.endif 
	R2 = [Temp2]; //Sample_L 
	MR = R2 * R1, uu; 
	[Temp3] = R4; 
	//[Temp4] = R3; 
	R2 = [Temp1]; //Sample_H 
	MR = R2 * R1, uu; 
	R3 += [Temp3]; 
	R4 += 0, carry; 
	 
	R1 = 11; 
	R3 = R3 LSR R1; 
	MR |= R4 ASR R1; 
	[MP3_TimeInfo] = r3; 
	[_gCurSecondTime] = r3 
	retf; 
//20060605 
.endp		//20060525 
 
//Add 2007/01/11 for Get Current MP3 Frame had played 
//得到MP3已播放的FrameNumber: 
.public _GetMP3FrameCount 
_GetMP3FrameCount: 
	r1 = [Mp3_FrameCount_L] 
	r2 = [Mp3_FrameCount_H] 
	retf 
 
//重新设置MP3播放的FrameNumber: 
.public _SetMP3FrameCount 
_SetMP3FrameCount: 
	push r1, r2 to [sp] 
	r1 = sp + 5 
	r2 = [r1++]				//Get the low value of the input parament 
	r1 = [r1]				//Get the High value of the input parament 
	[Mp3_FrameCount_L] = r2 
	[Mp3_FrameCount_H] = r1 
	pop r1, r2 from [sp] 
	retf 
.endif		//End of C_SND_MP3_SUPPORT definition 
 
 
//////////////////////////////////////////////////////// 
// Function:	_SACM_DVR520_VADTHR 
// Description:	Set some paraments for DVR520 play, The 
// paraments identifies the degree of the disturb sound 
// Syntax:	void _SACM_Codec(int CodecIndex); 
// Parameter:	CodecIndex : {0-5(max)} 
// Return:	N/A 
// Destory:	R1 
//////////////////////////////////////////////////////// 
//begin added by zgq on 20051220 
.ifdef C_SND_DVR520_SUPPORT 
.external F_SetVADTHR //add by benwang 20051221 
 
_SACM_DVR520_VADTHR: .proc 
   	R1 = SP + 3 
   	R1 = [R1] 
    call F_SACM_DVR520_VADTHR 
   	retf 
F_SACM_DVR520_VADTHR: 
	call F_SetVADTHR //add by benwang 20051221 
	retf 
.endp 
.endif 
//end added by zgq on 20051220 
 
.ifdef C_SND_DVR1800_SUPPORT 
_SACM_DVR1800_BITRATE: .proc 
	push BP to [SP] 
   	BP = SP + 1 
   	R3 = [BP + 3] // BitRate 
.ifdef C_2002_CODE_ICA 
   	R4 = [BP + 4] // Number of Bit per Frame 
.endif 
    call F_SACM_DVR1800_BITRATE 
    pop BP from [sp] 
   	retf 
F_SACM_DVR1800_BITRATE: 
	[R_BITRATE] = R3 
.ifdef C_2002_CODE_ICA 
	[R_BITSOFEACHFRAME] = R4 
.endif 
	retf 
.endp 
//.else 
//	.ifdef C_SND_A1800_SUPPORT 
//	_SACM_DVR1800_BITRATE: .proc 
//		push BP to [SP] 
//	   	BP = SP + 1 
//	   	R3 = [BP + 3] // BitRate 
//   		R4 = [BP + 4] // Number of Bit per Frame 
//		call F_SACM_DVR1800_BITRATE 
//	    pop BP from [sp] 
//   		retf 
//	F_SACM_DVR1800_BITRATE: 
//		[R_BITRATE] = R3 
//		[R_BITSOFEACHFRAME] = R4 
//		retf 
//	.endp 
//	.endif	//end C_SND_A1800_SUPPORT 
.endif	//end C_SND_DVR1800_SUPPORT 
 
//////////////////////////////////////////////////////// 
// Volume Table 
//SACMTextSection:	.SECTION	.TEXT ,	.ADDR = START_ADDR + CELP_LENGTH + S200_LENGTH +A1600_LENGTH + FFT64_LENGTH + MS01_LENGTH 
// cfwei removed 20040721 
.ifdef NANDBOOT_NOTEXT 
	//.code 
.else 
	SACMTextSection:	.SECTION	.TEXT 
.endif 
T_SACM_Volume_Level: 
	.dw	0x0000, 0x0250, 0x0500, 0x1000 
	.dw	0x1500, 0x2000, 0x2500, 0x3000 
	.dw	0x3500, 0x4000, 0x5000, 0x6500 
	//.dw	0x7d00, 0x9c00, 0xc400, 0xf500 
	.dw	0x7d00, 0x9c00, 0xc400, 0xe000  //reduce vol15, cfwei 20050110 
 
T_MP3Fs_Table: 
	.dw	0x0be3 // 1/44100 * 2^(12) * 2^(15) 
	.dw	0x0aec // 1/48000 * 2^(12) * 2^(15) 
	.dw	0x1062 // 1/32000 * 2^(12) * 2^(15) 
	.dw	0x17c6 // 1/22050 * 2^(12) * 2^(15) 
	.dw	0x15D8 // 1/24000 * 2^(12) * 2^(15) 
	.dw	0x20c4 // 1/16000 * 2^(12) * 2^(15) 
	.dw	0x2f80 // 1/11025 * 2^(12) * 2^(15) 
	.dw	0x2BB0 // 1/12000 * 2^(12) * 2^(15) 
	.dw	0x4189 // 1/8000  * 2^(12) * 2^(15) 
.public	F_SACM_ADC_MoniterON 
F_SACM_ADC_MoniterON: 
		push	r1 to [sp] 
		r1=[P_HPAMP_Ctrl]		//mic output direct 
		r1|=0x08 
		r1&=~0x02				//left channel on 
		[P_HPAMP_Ctrl]=r1 
		r1=[P_CHA_Ctrl] 
		r1|=0x2000 
		[P_CHA_Ctrl]=r1 
		pop	r1 from [sp] 
		retf