//==========================================================================
// File Name   : SACM_A1800_API.asm
// Description : API for users to develope project
// Written by  : Ray Cheng
// Last modified date:
//              2005/12/26
// Note: 
//==========================================================================
//**************************************************************************
// Header File Included Area
//**************************************************************************
.include SACM.inc				// Virtual port, virtual constants
.include SACM_A1800_Decode.inc	// Function declarations
.include SACM_A1800_Constant.inc	// PlayFlag Definitions 

//**************************************************************************
// Contant Defintion Area
//**************************************************************************
.define C_DAC_FIR_Type0_API		0x00	// no up-sampling
.define C_DAC_FIR_Type1_API		0x01	// 2X up-sampling, no filter
.define C_DAC_FIR_Type2_API		0x02	// 2X up-sampling, simple filter
.define C_DAC_FIR_Type3_API		0x04	// 2X up-sampling, complex filter

.define C_ADC_FIR_Type0_API		0x00	// no up-sampling
.define C_ADC_FIR_Type1_API		0x01	// 2X up-sampling
.define C_ADC_FIR_Type2_API		0x02	// 4X up-sampling

//**************************************************************************
// Variable Publication Area
//**************************************************************************
.public R_SACM_A1800_ISR_Flag

//**************************************************************************
// Function Call Publication Area
//**************************************************************************
.public  _SACM_A1800_Initial
.public F_SACM_A1800_Initial
//.public  _SACM_A1800_Rec
//.public F_SACM_A1800_Rec
.public  _SACM_A1800_Play
.public F_SACM_A1800_Play
.public  _SACM_A1800_Stop
.public F_SACM_A1800_Stop
.public  _SACM_A1800_Volume
.public F_SACM_A1800_Volume
.public  _SACM_A1800_Status
.public F_SACM_A1800_Status
.public  _SACM_A1800_Pause
.public F_SACM_A1800_Pause
.public  _SACM_A1800_Resume
.public F_SACM_A1800_Resume
.public  _SACM_A1800_DA_FIRType
.public F_SACM_A1800_DA_FIRType
//.public  _SACM_A1800_AD_FIRType
//.public F_SACM_A1800_AD_FIRType
.public  _SACM_A1800_ServiceLoop
.public F_SACM_A1800_ServiceLoop
.public F_ISR_Service_SACM_A1800

.public  _SACM_A1800_Play_Con			// 2007.01.12 Ray
.public F_SACM_A1800_Play_Con			// 2007.01.12 Ray
.public  _SACM_A1800_Check_Con			// 2007.01.12 Ray
.public F_SACM_A1800_Check_Con			// 2007.01.12 Ray

//**************************************************************************
// External Function Declaration
//**************************************************************************
.external F_SACM_A1800_GetStartAddr_Con

//**************************************************************************
// External Table Declaration
//**************************************************************************
.external T_SACM_A1800_SpeechTable

//**************************************************************************
// RAM Definition Area
//**************************************************************************
OVERLAP_A1800_API_BLOCK:	.section	.ORAM
R_DAC_FIR_Buffer:			.dw 16	dup(?)	// DAC up-sample filter buffer
R_DAC_FIR_Buffer_Ptr:		.dw 0
R_DAC_16K_Flag:				.dw 0
R_DAC_FIR_Type:				.dw	0			// 0: T_OFILTER_COEF_SA; 1: T_OFILTER_COEF_SA2
//R_ADC_FIR_Type:				.dw 0
// ADC 32KHz to 8K downsample filter buffer
//R_ADC_FIR_Buffer:			.dw 32	dup(0)	// ADC down-sample filter buffer
//R_ADC_FIR_Buffer_Ptr:		.dw 0
R_SACM_A1800_ISR_Flag:	.dw 0
R_ShiftStore:				.dw 0
R_ShiftStore_ServiceLoop:	.dw 0
R_DAC_Data:					.dw 0

//*****************************************************************************
// Table Definition Area
//*****************************************************************************
.TEXT
T_OFILTER_COEF_EA:	// define for 16KHz DAC
.dw -2048, 12288,  6144, 0
.dw -2048, 12288,  6144, 0
.dw     0,     0, 16384, 0
.dw     0,     0, 16384, 0
.define T_OFILTER_COEF_SA (T_OFILTER_COEF_EA + 4)

T_OFILTER_COEF_EA2:	// 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 T_OFILTER_COEF_SA2 (T_OFILTER_COEF_EA2 + 16)

//T_LPF32_COEF_EA:	// define for 32K Hz ADC
//.dw    26,   222,   279,   -81,  -394,   -30,   508,   155,  -656,  -331,   886,   638, -1342, -1395,  2937,  8000
//.dw  8000,  2937, -1395, -1342,   638,   886,  -331,  -656,   155,   508,   -30,  -394,   -81,   279,   222,    26
//.dw    26,   222,   279,   -81,  -394,   -30,   508,   155,  -656,  -331,   886,   638, -1342, -1395,  2937,  8000
//.dw  8000,  2937, -1395, -1342,   638,   886,  -331,  -656,   155,   508,   -30,  -394,   -81,   279,   222,    26
//.define T_LPF32_COEF_SA (T_LPF32_COEF_EA + 32)
//
//.define T_LPF32_COEF_EA2	T_LPF32_COEF_EA
//.define T_LPF32_COEF_SA2	T_LPF32_COEF_SA
//
.comment @
T_LPF32_COEF_EA:// define  for 16KHz ADC
.dw 0xFF40, 0xFF15, 0x011D, 0x0155, 0xFE69, 0xFE1C, 0x023E, 0x02AC, 0xFCCE, 0xFC22, 0x04C1, 0x0600, 0xF815, 0xF4B4, 0x1312, 0x3993
.dw 0x3993, 0x1312, 0xF4B4, 0xF815, 0x0600, 0x04C1, 0xFC22, 0xFCCE, 0x02AC, 0x023E, 0xFE1C, 0xFE69, 0x0155, 0x011D, 0xFF15, 0xFF40
.dw 0xFF40, 0xFF15, 0x011D, 0x0155, 0xFE69, 0xFE1C, 0x023E, 0x02AC, 0xFCCE, 0xFC22, 0x04C1, 0x0600, 0xF815, 0xF4B4, 0x1312, 0x3993
.dw 0x3993, 0x1312, 0xF4B4, 0xF815, 0x0600, 0x04C1, 0xFC22, 0xFCCE, 0x02AC, 0x023E, 0xFE1C, 0xFE69, 0x0155, 0x011D, 0xFF15, 0xFF40
.define T_LPF32_COEF_SA (T_LPF32_COEF_EA + 32)

T_LPF32_COEF_EA2:		// define  for 32KHz ADC
.dw 0xFFEB, 0xFFC4, 0xFFAC, 0xFFCC, 0x004E, 0x0111, 0x0183, 0x00DD, 0xFED3, 0xFC32, 0xFAE7, 0xFD25, 0x03F9, 0x0E3A, 0x18A2, 0x1F33
.dw 0x1F33, 0x18A2, 0x0E3A, 0x03F9, 0xFD25, 0xFAE7, 0xFC32, 0xFED3, 0x00DD, 0x0183, 0x0111, 0x004E, 0xFFCC, 0xFFAC, 0xFFC4, 0xFFEB
.dw 0xFFEB, 0xFFC4, 0xFFAC, 0xFFCC, 0x004E, 0x0111, 0x0183, 0x00DD, 0xFED3, 0xFC32, 0xFAE7, 0xFD25, 0x03F9, 0x0E3A, 0x18A2, 0x1F33
.dw 0x1F33, 0x18A2, 0x0E3A, 0x03F9, 0xFD25, 0xFAE7, 0xFC32, 0xFED3, 0x00DD, 0x0183, 0x0111, 0x004E, 0xFFCC, 0xFFAC, 0xFFC4, 0xFFEB
.define T_LPF32_COEF_SA2 (T_LPF32_COEF_EA2 + 32)
@
TB_SerialNo:
//.dw 0x4153, 0x5333, 0x4341, 0x564D, 0x3034;	// (100)	SA3SACMV40
.dw 0x5553, 0x504E, 0x554C, 0x2E53;				// SUNPLUS.
.dw 0x0762, 0x0615, 0x0603, 0x0654, 0x0630, 0x0642, 0x0603, 0x0615;

TB_EncryptionCode:
//.dw 0x02A5, 0xFD5B;
.dw 0x03F1, 0xFC0F;

.code
T_DummyData:
.dw 0x2020, 0x6172, 0x6379, 0x6568, 0x676E, 0x2020; // "  raycheng  "

.code
.comment @
//Sunplus SACM A1800 Library    Ver 41a  Release  2006-09-18
.DW  0x1FD7,0x1FE7,0x79D7,0x3DE7,0x288F,0xB5C5,0x5E68,0x8601
.DW  0xC6A4,0x5E86,0x3E0B,0x3A4A,0x72CD,0xD3BD,0xB50B,0x972D
.DW  0x9AC2,0xBA83,0xECE0,0xFC86,0xFC0B,0xC2C2,0x6649,0xBEA4
.DW  0x76E0,0xBE91,0xF40B,0xF40B,0xF165,0x5686,0xBE2C,0xF423
.DW  0xB583,0x760B,0xB50B,0x5B45,0x79A9,0xC6A9,0x76E0,0x3EA9
.DW  0x1F0B,0x790B,0xB543,0xB503,0xFCA4,0x9CBB,0x3D03,0x6CC2
.DW  0x4486,0x7C13,0xD35F

//Sunplus SACM A1800 Library    Ver 41a Release  2006-12-06
.DW  0xD3D7,0xD3E7,0x28E7,0xB5D7,0x3D8F,0x97C5,0x97A1,0x9779
.DW  0x9701,0x3D39,0xB5A1,0x3E0B,0xF1C5,0x72CD,0x5BBD,0xF42D
.DW  0x1F65,0x9745,0x7C2C,0xECE0,0xFC2C,0xFC0B,0xC299,0x7949
.DW  0xD341,0xD389,0xD341,0x7991,0x5B0B,0xF40B,0x1F0B,0x9AE0
.DW  0x5641,0xF10B,0xF123,0x7C89,0xF10B,0xF145,0xD3A9,0xB539
.DW  0x5689,0x3EA9,0x970B,0xF4C2,0xBC4A,0xFC03,0x9C4A,0x4483
.DW  0xBCBB,0xFC63,0x5B5F

//Sunplus SACM A1800 Library    Ver 41a Release  2006-12-15
.DW  0x282C,0x180E,0x28E7,0x288F,0x3AA1,0x8601,0xC60E,0x5EC1
.DW  0xF468,0x3A8D,0xB5CD,0x420E,0xF4C2,0xD265,0xBA83,0xB513
.DW  0x7903,0xFCE0,0xF43D,0x1F99,0xB549,0x9741,0x764A,0xBE4A
.DW  0x6E86,0xF44A,0xF44A,0xF40E,0xF44A,0x9AA9,0xBE0E,0xF423
.DW  0x7C89,0x3D0B,0x7945,0xD3A9,0xB539,0x5689,0x97C1,0x5BA9
.DW  0xB50B,0xF443,0xFC0E,0xFCA4,0x9C2C,0x4483,0xBC4A,0x4483
.DW  0x5C5F

//Sunplus SACM A1800 Library    Ver 41b Beta01  2007-02-27
.DW  0xD3D7,0x3DE7,0x1FD7,0x180E,0x280E,0x70C5,0x5BA1,0x8601
.DW  0xC686,0x5EC1,0x3D0B,0x3A86,0x72CD,0x420B,0xF12D,0x9A45
.DW  0x3D83,0xEC03,0xFC0B,0xC299,0xB641,0x7641,0x7991,0x5B0B
.DW  0xD30B,0x5B0B,0xF42C,0x9A0E,0x5641,0xF40E,0xDC2C,0x7C49
.DW  0xF44D,0xD3A9,0xDE4A,0x7603,0x7C4A,0xF468,0xF4A4,0xBC4A
.DW  0xFC4A,0xFC86,0x1CBB,0x9703,0xB543,0x44C2,0xBC68,0x1C86
.DW  0xA00F

//Sunplus SACM A1800 Library    Ver 41b Beta02  2007-10-03
.DW  0xD3D7,0xD3E7,0x28E7,0x288F,0x3AA1,0x8601,0xC6A1,0xD3C1
.DW  0x5B0B,0x3A86,0x72CD,0x42E0,0xF4E0,0x7283,0xEC03,0xFCE0
.DW  0xF43D,0x9799,0xB641,0x760E,0xBE91,0x790B,0x790B,0xD30B
.DW  0xF465,0x5641,0xF40E,0xDCA4,0x7C4A,0xB60B,0xB2A9,0xDE89
.DW  0xFC4A,0xBC0B,0xF443,0xFCC2,0xFC4A,0x1CA4,0x4483,0xFCC2
.DW  0x4403,0x3CC2,0xA00F

//Sunplus SACM A1800 Library    Ver 41b Release  2009-03-09
.DW  0x2886,0x18A4,0x2868,0x18D7,0x5B8F,0x3A2C,0x5E79,0xB501
.DW  0xC6A1,0x3E0B,0xD3C5,0x3D8D,0x97CD,0x420B,0x5B8D,0xD383
.DW  0xEC03,0x1F03,0xF42C,0xC299,0xF149,0xBE89,0x9741,0xF191
.DW  0xF42C,0xF40B,0xF4C2,0x9AA9,0x3D41,0x970B,0xD323,0xF183
.DW  0x3D49,0xF10B,0x9745,0x5639,0x79A9,0x76C1,0x79A9,0xF40B
.DW  0x7943,0x5B03,0xFC93,0xD3BB,0xB503,0x3CC2,0x4403,0x6C4A
.DW  0xA00F

//Generalplus SACM A1800_ReduceRAM  Ver 4.1.0  2010-08-12
.DW  0xF1D7,0x79E7,0x1FD7,0x184A,0x280E,0x70A4,0x1286,0x5679
.DW  0x56E0,0xBE4A,0x76A4,0xC686,0xFE68,0xC62C,0x5EC1,0xF4A4
.DW  0x3A86,0x72CD,0x42C2,0xF48D,0x7C0E,0xEC03,0xFCF5,0x5B45
.DW  0x5BA9,0xD6A1,0xD3C9,0x5BA9,0xB545,0xF18D,0x424A,0xF4A4
.DW  0xF4C2,0x9AA4,0x5641,0xB50B,0x9723,0x8483,0x977B,0xFCA4
.DW  0xF468,0xF443,0xFC83,0xFCBB,0xFC13,0x440E,0x7CE0,0xBC5F

//Generalplus SACM A1800_ReduceRAM  Ver 4.1.1  2010-10-28
.DW  0xF1D7,0xF1E7,0xB5D7,0x182C,0x28E0,0x70ED,0x79A9,0xD379
.DW  0xF1A9,0x7941,0x5B89,0xC6C2,0xFE68,0xC6A1,0x3DC1,0xF468
.DW  0x3A8D,0x1FCD,0x420B,0x7286,0x7C13,0xFC2C,0xFCE0,0x0A45
.DW  0xB5A9,0x9729,0x79A1,0x1FC9,0x56C2,0xBA8D,0x97BD,0xF4E0
.DW  0xF465,0x5641,0xF423,0xB57B,0xD383,0x797B,0x7983,0xF40B
.DW  0xBC03,0x5B83,0xFCE0,0x44A4,0x7C03,0x1FBB,0x5B43,0x5B13
.DW  0xA00F
@

//Generalplus SACM A1800_ReduceRAM  Ver 4.1.2  2011-10-05
.DW  0x5BD7,0x3DE7,0x28A4,0x18A4,0x288F,0x1268,0x560E,0x86A9
.DW  0x3D41,0x7639,0x1F01,0xC686,0x5EC2,0x3EE0,0xF44A,0x3AE0
.DW  0x720E,0x3268,0x42A4,0xF468,0x7283,0xEC0E,0xFCC2,0xFCF5
.DW  0xD345,0x56E0,0xD6A1,0xB5C9,0x562C,0xBA4A,0x72BD,0xF40B
.DW  0xF165,0x3DA9,0xB541,0xF486,0xDCA4,0x84A4,0x7C7B,0x9743
.DW  0xF40B,0x7943,0xFC83,0x9783,0xD3BB,0xF183,0xB503,0x3DBB
.DW  0xF103,0x97A3,0xA00F

//**************************************************************************
// CODE Definition Area
//**************************************************************************
SACM_A1800_ROM_BLOCK:	.section	.CODE
//****************************************************************
// Function    : F_SACM_A1800_Initial
// Description : initialize flags and hardware
// Destory     : R1
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Initial: .proc
F_SACM_A1800_Initial:
	push R1 to [SP];
	R1 = 0x0000;
	[R_SACM_A1800_Play_Flag] = R1;

	R1 = 0xFFFF;							// 2007.01.12 Ray
	[R_A1800_NextIndex] = R1;							// 2007.01.12 Ray

	R1 = 0;
	[R_SACM_A1800_ISR_Flag] = R1;
//	R1 = C_DAC_FIR_Type2_API;
	R1 = C_DAC_FIR_Type0_API;
	[R_DAC_FIR_Type] = R1;
//	R1 = C_ADC_FIR_Type2_API;
//	R1 = C_ADC_FIR_Type0_API;
//	[R_ADC_FIR_Type] = R1;

	R1 = 0x4000;							// default volume
	[R_SACM_A1800_Play_Gain] = R1;
	R1 = 4;									// default 16 KHz

	call F_SACM_A1800_Init_;				// call HW initial
	pop R1 from [SP];
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_DA_FIRType
// Description : Set digital filter type
// Destory     : R1
// Parameter   : R1: DAC FIR type
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_DA_FIRType: .proc
	R1 = SP + 3;
	R1 = [R1];
F_SACM_A1800_DA_FIRType:
	R1 &= 0x0003;
	cmp R1, 0x0003;
	jne ?L_SetFIR_Type;
	R1 = C_DAC_FIR_Type3_API;
?L_SetFIR_Type:
	[R_DAC_FIR_Type] = R1;
	R1 = R1;								// for jz
	jz ?L_DA_No_FIR;
	call F_SACM_A1800_DAC_Timer_X2;		// set timer for playback
	jmp ?L_DA_FIRType_End;
?L_DA_No_FIR:
	call F_SACM_A1800_DAC_Timer_X1;		// set timer for playback
?L_DA_FIRType_End:
	retf;
	.endp

.comment @
//****************************************************************
// Function    : F_SACM_A1800_AD_FIRType
// Description : Set digital filter type
// Destory     : R1
// Parameter   : R1: ADC FIR type
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_AD_FIRType: .proc
	R1 = SP + 3;
	R1 = [R1];
F_SACM_A1800_AD_FIRType:
	[R_ADC_FIR_Type] = R1;
	R1 = R1;								// for jz
	jz ?L_AD_No_FIR;
	test R1, C_ADC_FIR_Type1_API;
	jnz ?L_ADC_X2;
	call F_SACM_A1800_ADC_Timer_X4;		// set timer for recording
	jmp ?L_AD_FIRType_End;
?L_ADC_X2:
	call F_SACM_A1800_ADC_Timer_X2;		// set timer for recording
	jmp ?L_AD_FIRType_End;
?L_AD_No_FIR:
	call F_SACM_A1800_ADC_Timer_X1;		// set timer for recording
?L_AD_FIRType_End:
	retf;
	.endp
@
//****************************************************************
// Function    : F_SACM_A1800_Play
// Description : Play speech from T_SACM_A1800_SpeechTable in resource.asm
// Destory     : R1, R2, R3, R4, R5
// Parameter   : R1: Speech index:  -1             : Mamual mode
//                                   0 ~ max index : Auto mode
//               R2: Channel: 1: DAC1 enable
//                            2: DAC2 enable
//                            3: DAC1, 2 enable
//               R3: 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      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Play: .proc
	R3 = SP + 3;
	R1 = [R3++];								// speech index
	R2 = [R3++];								// DAC channel
	R3 = [R3];								// ramp up/down setting
F_SACM_A1800_Play:
	push R5 to [SP];						// C function call must protect R5
	push R1, R3 to [SP];
	call F_Check_Encryption;				// encryption
	cmp R1, 0x00;
	jne ?L_StartPlay;
	pop R1, R3 from [SP];
	pc = ?L_Play_End;							// encryption check fail
?L_StartPlay:									// encryption check pass
	R4 = 0;
	[R_SACM_A1800_ISR_Flag] = R4;
	[R_SACM_A1800_Play_Flag] = R4;
	
	R1 = [R_DAC_FIR_Type];
	jnz ?L_DA_FIR;
	call F_SACM_A1800_DAC_Timer_X1;		// set timer for playback
	jmp ?L_SetTimer_End;
?L_DA_FIR:
	call F_SACM_A1800_DAC_Timer_X2;		// set timer for playback
?L_SetTimer_End:
	pop R1, R3 from [SP];
	R4 = C_SACM_A1800_PLAY;

	test R2, 0x0001;						// check DAC1 enable
	jz ?L_Branch_0;

	R4 |= C_SACM_A1800_ENABLE_DAC1;		// DAC1 enable

?L_Branch_0:
   	test R2, 0x0002;						// check DAC2 enable
   	jz ?L_Branch_1;

   	R4 |= C_SACM_A1800_ENABLE_DAC2;		// DAC2 enable

?L_Branch_1:
   	test R3, 0x0001;						// check ramp up
   	jz ?L_Branch_2;

   	R4 |= C_SACM_A1800_RAMP_UP_ENABLE;
   	test R4, C_SACM_A1800_ENABLE_DAC1;
   	jz ?L_Branch_3;

	call F_SP_RampUpDAC1;					// ramp up DAC1

?L_Branch_3:
   	test R4, C_SACM_A1800_ENABLE_DAC2;
   	jz ?L_Branch_2;

	call F_SP_RampUpDAC2;					// ramp up DAC2

?L_Branch_2: 
   	test R3, 0x0002;						// check ramp down
   	jz ?L_Branch_4;

   	R4 |= C_SACM_A1800_RAMP_DN_ENABLE;

?L_Branch_4:
	cmp R1, -1;								// check Auto mode or Manual mode
   	je ?L_Manual_Mode;						// R1 = -1 : Manual mode, otherwise : Auto mode

   	R4 |= C_SACM_A1800_AUTO;				// Auto mode

?L_Branch_5:
   	[R_SACM_A1800_Play_Flag] = R4;
	R3 = R1;								// R1 = speech index
	// 2007.10.03 Ray
	R2 = seg T_SACM_A1800_SpeechTable;		// 2007.10.03 Ray
	R1 += T_SACM_A1800_SpeechTable;			// get speech data address
	R2 += 0, carry;
	R2 = R2 lsl 4;
	R2 = R2 lsl 4;
	R2 = R2 lsl 2;
	SR &= 0x03FF;
	SR |= R2;
	R1 = D:[R1];
	// 2007.10.03 Ray End
	R2 = [R1++];
	[R_SACM_A1800_Resouce_BS] = R2;		// speech data address low word
	R1 = [R1];
	R1 = R1 lsl 4;
	R1 = R1 lsl 4;
	R1 = R1 lsl 2;
	[R_SACM_A1800_Resouce_DS] = R1;		// speech data address high word
	R1 = R3;

	R1 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;
	[R_SACM_A1800_Decode_In_PTR] = R1;	// set Decode_In buffer pointer to end

	call F_SACM_A1800_Decode_Get_BS_Auto;	// get speech data (Auto mode)
	jmp ?L_DecodeInit;

?L_Manual_Mode:								// Manual mode
	[R_SACM_A1800_Play_Flag] = R4;
	R1 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;
	[R_SACM_A1800_Decode_In_PTR] = R1;	// set Decode_In buffer pointer to end
	call F_SACM_A1800_System_Get_BS_Manual;	// get speech data (Manual mode)

?L_DecodeInit:
//	chimc added 20101028 -----------------------------------------------------------
	R1 = [R_SACM_A1800_Decode_In_Buffer + 2];
	jz ?L_Stop_A1800
	cmp R1, 0xffff;
	je ?L_Stop_A1800
	jmp ?L_DecodeInit1
	
?L_Stop_A1800:	
	call F_SACM_A1800_Stop;
	jmp ?L_Play_End
	
?L_DecodeInit1:
//	chimc added end ----------------------------------------------------------------

   	call F_SACM_A1800_Decode_Initial_BS;	// initial decode counter and calculate file length
	R4 = [R_SACM_A1800_Play_Flag];
	test R4, C_SACM_A1800_AUTO;
	jnz ?L_AutoGetBS2;

	call F_SACM_A1800_System_Get_BS_Manual;	// get 2 words data for Manual mode
	jmp ?L_DecodeInProcess;

?L_AutoGetBS2:
	call F_SACM_A1800_Decode_Get_BS_Auto;	// get 2 words data for Auto mode

?L_DecodeInProcess:
	call F_SACM_A1800_Decode_Initial_Process;	// initial kernel

	R1 = 0x0000;
	R2 = R_SACM_A1800_DAC_Out_Buffer;		// clear DAC_OUT buffer
	R3 = R2 + C_DECODE_OUT_LENGTH;

?L_Loop_0:
	[R2++] = R1;
	cmp R2, R3;
	jne ?L_Loop_0;

	R1 = R_DAC_FIR_Buffer;
	R2 = 0;
	[R_DAC_16K_Flag] = R2;
	[R_DAC_FIR_Buffer_Ptr] = R2;
?L_ClearBuffer_Loop:						// clear DAC_FIR buffer
	[R1++] = R2;
	cmp R1, R_DAC_FIR_Buffer + 16;
	jne ?L_ClearBuffer_Loop;

	R1 = R_SACM_A1800_DAC_Out_Buffer;
	[R_SACM_A1800_DAC_Out_PTR_Play] = R1;	// initial Play pointer
	R1 = R_SACM_A1800_DAC_Out_Buffer + C_DECODE_OUT_LENGTH;
	[R_SACM_A1800_DAC_Out_PTR_Decode] = R1;	// initial DAC_OUT buffer pointer
	R1 = [R_SACM_A1800_Play_Flag];
	R1 |= (C_SACM_A1800_DECODE_WORK + C_SACM_A1800_DECODE_ODD + C_SACM_A1800_FIQ_SOUND + C_SACM_A1800_FIQ_EVEN);
	[R_SACM_A1800_Play_Flag] = R1;		// set play flag

	R1 = 1;
	[R_SACM_A1800_ISR_Flag] = R1;			// enable background service loop

	R1 = -1;								// 2007.01.12 Ray
	[R_A1800_NextIndex] = R1;						// 2007.01.12 Ray

	call F_SACM_A1800_StartPlay;			// 2007.10.03 Ray
?L_Play_End:
	pop R5 from [SP];
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Play_Con
// Description : Play speech from T_SACM_A1800_SpeechTable in resource.asm
// Destory     : R1, R2, R3, R4, R5
// Parameter   : R1: Speech index:
//               R2: Channel: 1: DAC1 enable
//                            2: DAC2 enable
//                            3: DAC1, 2 enable
//               R3: 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
//               R4: Mode: 0: manual mode
//                         1: auto mode
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Play_Con: .proc   	
	R3 = SP + 3;
	R1 = [R3++];
	R2 = [R3++];
	R3 = [R3];
F_SACM_A1800_Play_Con:
	R4 = [R_SACM_A1800_Play_Flag];
	test R4, C_SACM_A1800_PLAY;   // Check if playing
    jz ?L_Continue_play;

	R4 = [R_A1800_NextIndex]; 
	cmp R4, -1;
	jne ?L_Exit;
//	[R_A1800_NextIndex] = R1;
	R4 = 0;
	[R_SACM_A1800_Play_Next_Flag] = R4;
	test R2, 0x0001;
	jz ?L_CheckDAC2;
	R4 |= C_SACM_A1800_ENABLE_DAC1;
?L_CheckDAC2:
	test R2, 0x0002;
	jz ?L_CheckRampUp;
	R4 |= C_SACM_A1800_ENABLE_DAC2;
?L_CheckRampUp:
	test R3, 0x0001;
	jz ?L_CheckRampDn;
	R4 |= C_SACM_A1800_RAMP_UP_ENABLE;
?L_CheckRampDn:
	test R3, 0x0002;
	jz ?L_CheckMode;
	R4 |= C_SACM_A1800_RAMP_DN_ENABLE;
?L_CheckMode:
//	test R4, 0x0001;
//	jz ?L_UpdateFlag;
	cmp R1, -1;
	jne ?L_Auto_Mode;
	R1 = -2;
	jmp ?L_UpdateFlag;
?L_Auto_Mode:
	R4 |= C_SACM_A1800_AUTO;
?L_UpdateFlag:
	[R_SACM_A1800_Play_Next_Flag] = R4;
	[R_A1800_NextIndex] = R1;
?L_Exit:
//	pop R5 from [SP];
	retf;

?L_Continue_play:
	push R1, R4 to [SP];
	call F_SACM_A1800_GetStartAddr_Con;
	pop R1, R4 from [SP];

	call F_SACM_A1800_Play;
?L_Play_End:
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Check_Con
// Description : Get queue buffer
// Destory     : R1
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Check_Con: .proc
F_SACM_A1800_Check_Con:
	R1 = [R_A1800_NextIndex];
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Stop
// Description : Stop Playback
// Destory     : R1
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Stop: .proc
F_SACM_A1800_Stop:
.comment @
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_CODEC_MODE;		// check codec mode, encode or decode
	je L_SACM_DECODE_STOP;
L_SACM_ENCODE_STOP:							// encoding stop
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_PLAY;			// check recording
	jz ?L_Branch_0;
	R1 |= C_SACM_A1800_STOP;				// set STOP flag

	test R1, C_SACM_A1800_RAMP_DN_ENABLE;	// check ramp down setting
	jz ?L_Branch_0;

	test R1, C_SACM_A1800_ENABLE_DAC1;	// check DAC1 enable
	jz ?L_Branch_1;

	call F_SP_RampDnDAC1;					// ramp down DAC1

?L_Branch_1:
	test R1, C_SACM_A1800_ENABLE_DAC2;	// check DAC2 enable
	jz ?L_Branch_0;

	call F_SP_RampDnDAC2;					// ramp down DAC2

?L_Branch_0:
	[R_SACM_A1800_Play_Flag] = R1;		// update play flag
	R1 = 0x0000;
	[R_SACM_A1800_ISR_Flag] = R1;
	retf;
@
L_SACM_DECODE_STOP:							// decoding stop
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_PLAY;			// check playing
	jz ?L_Branch_0;

	R1 &= ~C_SACM_A1800_FIQ_SOUND;		// clear FIQ_SOUND flag
	[R_SACM_A1800_Play_Flag] = R1;

	test R1, C_SACM_A1800_RAMP_DN_ENABLE;	// check ramp down setting
	jz ?L_Branch_0;

	test R1, C_SACM_A1800_ENABLE_DAC1;	// check DAC1 enable
	jz ?L_Branch_1;

	call F_SP_RampDnDAC1;					// ramp down DAC1

?L_Branch_1:
	test R1, C_SACM_A1800_ENABLE_DAC2;	// check DAC2 enable
	jz ?L_Branch_0;

	call F_SP_RampDnDAC2;					// ramp down DAC2

?L_Branch_0:
	R1 = 0x0000;
	[R_SACM_A1800_Play_Flag] = R1;		// clear play flag
	[R_SACM_A1800_ISR_Flag] = R1;

   	R1 = 0x0000;							// 2007.01.12 Ray
   	[R_SACM_A1800_Play_Next_Flag] = R1;		// 2007.01.12 Ray
   	R1 = -1;								// 2007.01.12 Ray
   	[R_A1800_NextIndex] = R1;							// 2007.01.12 Ray

	call F_SACM_A1800_EndPlay;			// for users implement
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Volume
// Description : Set speech volume
// Destory     : R1
// Parameter   : R1: volume gain
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Volume: .proc
	R1 = SP + 3;
	R1 = [R1];								// volume index
F_SACM_A1800_Volume:
//	R1 += T_SACM_A1800_Volume_Level;		// loop up volume table
//	R1 = [R1];
	[R_SACM_A1800_Play_Gain] = R1;		// set volume gain
	retf
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Status
// Description : Get library status
// Destory     : R1
// Parameter   : None
// Return      : R1: [R_SACM_A1800_Play_Flag]
// Note        : None
//****************************************************************
 _SACM_A1800_Status: .proc
F_SACM_A1800_Status:
	R1 = [R_SACM_A1800_Play_Flag];		// return play flag
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_ServiceLoop
// Description : decode bit stream
// Destory     : R1, R2, R3, R4
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_ServiceLoop: .proc
F_SACM_A1800_ServiceLoop:
	push R1, R5 to [SP];

L_SACM_Decode_ServiceLoop:					// playing
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_DECODE_WORK;  	// check if Decode_Out buffer empty
	jnz ?L_Check_Play;
	pop R1, R5 from [SP];
	retf;
	
?L_Check_Play:
	test R1, C_SACM_A1800_PLAY;				// check playing
	jnz ?L_Check_Pause;
	pop R1, R5 from [SP];
	retf;

?L_Check_Pause:
	test R1, C_SACM_A1800_PAUSE;			// check pause
	jz ?L_Continue_1;
	pop R1, R5 from [SP];
	retf;

?L_Continue_1:								// one of Decode_Out buffer empty
	R2 = 0;
	R2 = R2 rol 4;
	[R_ShiftStore_ServiceLoop] = R2;		// Save 4-bit Shift Buffer

	R2 = 0x0000;
	[R_SACM_A1800_ISR_Flag] = R2;
	R1 &= ~C_SACM_A1800_DECODE_WORK;
	[R_SACM_A1800_Play_Flag] = R1;		// clear decode work flag

	call F_SACM_A1800_Decode_Process;		// decode one frame data
	R2 = R_SACM_A1800_DAC_Out_Buffer;
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_DECODE_ODD;		// check Decode_Out buffer 0
	jnz ?L_Branch_0;

	R2 += C_DECODE_OUT_LENGTH;				// set Decode_Out buffer pointer to buffer1
//	R2 = R_SACM_A1800_DAC_Out_Buffer + C_DECODE_OUT_LENGTH;
//	jmp ?L_Branch_1;

?L_Branch_0:
//	R2 = R_SACM_A1800_DAC_Out_Buffer + 0;

//?L_Branch_1:
	[R_SACM_A1800_DAC_Out_PTR_Decode] = R2;	// set Decode_Out pointer
	R1 ^= C_SACM_A1800_DECODE_ODD;		// change Decode_Out buffer
	[R_SACM_A1800_Play_Flag] = R1;
	test R1, C_SACM_A1800_DECODE_END;		// check decode end
	jnz ?L_Branch_2;
											// decoding does not finish
	test R1, C_SACM_A1800_AUTO;			// check auto mode
	jnz ?L_AutoGetBS;

	call F_SACM_A1800_System_Get_BS_Manual;	// get bit stream for manual mode
	jmp ?L_Branch_2

?L_AutoGetBS:
	call F_SACM_A1800_Decode_Get_BS_Auto;	// get bit stream for auto mode

?L_Branch_2:
	R2 = [R_ShiftStore_ServiceLoop];
	R2 = R2 lsr 4;							// Retore 4-bit Shift Buffer

	R2 = 0x0001;
	[R_SACM_A1800_ISR_Flag] = R2;
	pop R1, R5 from [SP];
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Pause
// Description : Pause speech
// Destory     : R1
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Pause: .proc
F_SACM_A1800_Pause:
	push R1 to [SP];
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_PLAY;			// check recording/playing
	jz ?L_Branch_0;

	R1 |=  C_SACM_A1800_PAUSE;			// set PAUSE flag
	R1 &= ~C_SACM_A1800_FIQ_SOUND;		// clear FIQ_SOUND flag
	[R_SACM_A1800_Play_Flag] = R1;

?L_Branch_0:
	pop R1 from [SP];
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Resume
// Description : Resume speech 
// Destory     : R1
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
 _SACM_A1800_Resume: .proc
F_SACM_A1800_Resume:
	push R1 to [SP];
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_PAUSE;			// check paused
	jz ?L_Branch_0;

	R1 &= ~C_SACM_A1800_PAUSE;			// clear PAUSE flag
	R1 |=  C_SACM_A1800_FIQ_SOUND;		// set FIQ_SOUND flag
	[R_SACM_A1800_Play_Flag] = R1;

?L_Branch_0:
	pop R1 from [SP];
	retf;
.endp

//****************************************************************
// Function    : F_ISR_Service_SACM_A1800
// Description : Get PCM data from buffer and send to DAC
// Destory     : R1, R2, R3, R4, R5
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
.text
F_ISR_Service_SACM_A1800:
	push R2,R5 to [SP];
	
	R1 = 0;
	R1 = R1 rol 4;
	[R_ShiftStore] = R1;					// Save 4-bit Shift Buffer

.comment @
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_CODEC_MODE;		// check codec mode, encode or decode
	je L_FIQ_Decode;
//	goto L_FIQ_Encode;
	pc = L_FIQ_Encode;
@

L_FIQ_Decode:								// playing
	R1 = [R_SACM_A1800_Play_Flag];
	test R1, C_SACM_A1800_FIQ_SOUND;		// check sound output
	jne ?L_Branch_0;
//	goto ?L_FIQ_Decode_End;
	pc = ?L_FIQ_Decode_End;

?L_Branch_0:
	R3 = [R_DAC_FIR_Type];
	jz ?L_INT_8K;
//FIQ_16K:
	R5 = [R_DAC_16K_Flag];
	R4 = R5 + 1;
	R4 = R4 & 1;
	[R_DAC_16K_Flag] = R4;					// change IRQ flag
	R4 = [R_DAC_Data];
	test R3, C_DAC_FIR_Type1_API;
	jnz ?L_CheckVolumeBound;
	test R3, C_DAC_FIR_Type2_API;				// check DAC FIR type
	jz ?L_FIR2_1;
	R5 = R5 lsl 3;
	R5 += T_OFILTER_COEF_SA;				// DAC simple filter
	jmp ?L_Set_COEF_SA;
?L_FIR2_1:
	R5 = R5 lsl 4;
	R5 = R5 lsl 1;
	R5 += T_OFILTER_COEF_SA2;				// DAC complex filter
?L_Set_COEF_SA:
	R5 -= [R_DAC_FIR_Buffer_Ptr];			// find DAC FIR coefficient start address
	R2 = R_DAC_FIR_Buffer;
	test R3, C_DAC_FIR_Type2_API;
	jz ?L_FIR2_2;							// check DAC FIR type
	MR = [R2] * [R5], ss,4;					// DAC simple filter
	jmp ?L_Adjust_Gain;
?L_FIR2_2:
	MR = [R2] * [R5], ss, 16;				// DAC complex filter
?L_Adjust_Gain:
	R3 = R3 lsl 4;
	R4 = R4 rol 2;

?L_CheckVolumeBound:
	cmp R4, (8192 - 8);						// volume limitation
//	cmp R4, (16384 - 16);
	jge ?L_CheckVolumeUpperBound;
	cmp R4, -8192;
//	cmp R4, -16384;
	jl ?L_CheckVolumeLowerBound;
	R4 = R4 lsl 2;
//	R4 = R4 lsl 1;
	jmp ?L_VolumeLimit_End;
?L_CheckVolumeUpperBound:
	R4 = (8192 - 8) * 4 - 1;				// max 0x7FDF
//	R4 = (16384 - 16) * 2 - 1;				// max 0x7FDF
	jmp ?L_VolumeLimit_End;
?L_CheckVolumeLowerBound:
	R4 = (-8192) * 4;
//	R4 = (-16384) * 2;
?L_VolumeLimit_End:
	test R1, C_SACM_A1800_ENABLE_DAC1;	// check DAC1 enable
	jz ?L_DAC2Check;
	push R1, R5 to [SP];							// 2007.10.03 Ray
	call F_SACM_A1800_SendDAC1;			// send data to DAC1
	pop R1, R5 from [SP];							// 2007.10.03 Ray

?L_DAC2Check:
	test R1, C_SACM_A1800_ENABLE_DAC2;	// check DAC2 enable
	jz ?L_NoDAC;
	push R1, R5 to [SP];							// 2007.10.03 Ray
	call F_SACM_A1800_SendDAC2;			// send data to DAC2
	pop R1, R5 from [SP];							// 2007.10.03 Ray

?L_NoDAC:
	R2 = [R_DAC_16K_Flag];
	jz ?L_INT_8K;							// check 8K interrupt
//	goto ?L_FIQ_Decode_End;
	pc = ?L_FIQ_Decode_End;

?L_INT_8K:									// 8K Hz interrupt
//FIQ_8K:
	R2 = [R_SACM_A1800_DAC_Out_PTR_Play];
	R3 = [R2++];							// get data from DAC_OUT buffer
	R4 = [R_SACM_A1800_Play_Gain];		// volume gain
	MR = R4 * R3, us;
	[R_DAC_Data] = R4;

	R3 = [R_DAC_FIR_Type];
	jz ?SendDAC_8K;

	R5 = [R_DAC_FIR_Buffer_Ptr];
	R3 = R5 + R_DAC_FIR_Buffer;
	R5 += 1;
	push R3 to [SP];
	R3 = [R_DAC_FIR_Type];
	test R3, C_DAC_FIR_Type2_API;				// check DAC FIR type
	jz ?L_FIR2_3;
	R5 = R5 & 3;							// DAC simple filter
	jmp ?L_Update_Ptr;
?L_FIR2_3:
	R5 = R5 & 15;							// DAC complex filter
?L_Update_Ptr:
	pop R3 from [SP];
	[R_DAC_FIR_Buffer_Ptr] = R5;
	[R3] = R4;
	jmp ?L_NoDAC_8K;

?SendDAC_8K:
//*****  added by Ray 2004.03.16
	cmp R4, (8192-8);
	jge ?L_CheckVolumeUpperBound_8K;
	cmp R4, -8192;
	jl ?L_CheckVolumeLowerBound_8K;
	R4 = R4 lsl 2;
	jmp ?L_VolumeLimit_End_8K;
?L_CheckVolumeUpperBound_8K:
	R4 = (8192 - 8) * 4 - 1; //max 0x7FDF
	jmp ?L_VolumeLimit_End_8K;
?L_CheckVolumeLowerBound_8K:
	R4 = (-8192) * 4;
?L_VolumeLimit_End_8K:

	test R1, C_SACM_A1800_ENABLE_DAC1;
	jz ?L_DAC2Check_8K;
	push R1, R5 to [SP];							// 2007.10.03 Ray
	call F_SACM_A1800_SendDAC1;
	pop R1, R5 from [SP];							// 2007.10.03 Ray

?L_DAC2Check_8K:
	test R1, C_SACM_A1800_ENABLE_DAC2;
	jz ?L_NoDAC_8K;
	push R1, R5 to [SP];							// 2007.10.03 Ray
	call F_SACM_A1800_SendDAC2;
	pop R1, R5 from [SP];							// 2007.10.03 Ray

?L_NoDAC_8K:
	R3 = R_SACM_A1800_DAC_Out_Buffer + C_DECODE_OUT_LENGTH;
	R4 = R3;								// buffer 1 start address
	test R1, C_SACM_A1800_FIQ_EVEN;		// check play buffer
	jnz ?L_CheckPointerEnd;
	R3 += C_DECODE_OUT_LENGTH;				// buffer 1 end address, EVEN = '0'
	R4 -= C_DECODE_OUT_LENGTH;				// buffer 0 start address
?L_CheckPointerEnd:
	cmp R2, R3;								// check if Play pointer point to buffer end
	je ?L_Switch_DAC_Out_Buffer;
	[R_SACM_A1800_DAC_Out_PTR_Play] = R2;	// Play pointer does not point to buffer end
	jmp ?L_FIQ_Decode_End;
	
?L_Switch_DAC_Out_Buffer:					// switch Play buffer
	test R1, C_SACM_A1800_DECODE_END;		// check decode end
	jnz ?L_Play_End;
	R1 |= C_SACM_A1800_DECODE_WORK;		// not play end, set DECODE_WORK flag
	R1 ^= C_SACM_A1800_FIQ_EVEN;			// switch play buffer
	[R_SACM_A1800_Play_Flag] = R1;
	[R_SACM_A1800_DAC_Out_PTR_Play] = R4;	// update new Play pointer
	jmp ?L_FIQ_Decode_End;

?L_Play_End:								// play end
	call F_SACM_A1800_Stop;				// stop
//	call F_SACM_A1800_EndPlay;			// for users implement
?L_FIQ_Decode_End:
	R1 = [R_ShiftStore];
	R1 = R1 lsr 4;							// Retore 4-bit Shift Buffer
	R1 = [R_SACM_A1800_ISR_Flag];
	pop R2,R5 from [SP];
	retf;

.comment @
L_FIQ_Encode:								// recording
	test R1, C_SACM_A1800_FIQ_SOUND;		// check recording continue
	jne ?L_Branch_0;
//	goto ?L_FIQ_Encode_End;
	pc = ?L_FIQ_Encode_End;

?L_Branch_0:								// 32K Hz sample rae
//	push R1 to [SP];
	call F_SACM_A1800_GetADC;				// get data from ADC
	R4 ^= 0x8000;							// change to signed data
//	R3 = R1;
//	pop R1 from [SP];

	test R1, C_SACM_A1800_REC_Mon_ON;		// check monitor on
	jz ?L_REC_NoMon;
//	R4 = R3;
	call F_SACM_A1800_SendDAC1;			// send ADC data to DAC1
	call F_SACM_A1800_SendDAC2;			// send ADC data to DAC2
?L_REC_NoMon:
	R4 -= R4 asr 3;							// all AD signal decay 1/8, why?

	R2 = [R_ADC_FIR_Type];
	jz ?L_WriteDataToBuffer;
	R3 = [R_ADC_FIR_Buffer_Ptr];
	R5 = R3 + R_ADC_FIR_Buffer;				// ADC FIR buffer start address
	R3 += 1;
	R3 = R3 & 31;
	[R_ADC_FIR_Buffer_Ptr] = R3;

	[R5] = R4;
//	test R2, C_ADC_FIR_Type1_API;
//	jz ?L_FIR_Type2;
	R5 = R3 & 0x0001;
//	jmp ?L_Check_8K;
//?L_FIR_Type2:
//	R5 = R4 & 0x0003;						// check 8K Hz interrupt
//?L_Check_8K:
//	cmp R5, 0x0000;
	je ?L_AD_8K_OUT;
	jmp ?L_FIQ_Encode_End;

?L_AD_8K_OUT:								// 8K Hz interrupt
	push R1 to [SP];
	R1 = R_ADC_FIR_Buffer;
//	R2 = [R_ADC_FIR_Type];
//	test R2, C_ADC_FIR_Type1_API;
//	jz ?L_FIR_Type2_2;
	R2 = T_LPF32_COEF_SA;
//	jmp ?L_Find_Coeff_Start;
//?L_FIR_Type2_2:
//	R2 = T_LPF32_COEF_SA2;
?L_Find_Coeff_Start:
	R2 -= [R_ADC_FIR_Buffer_Ptr];			// find ADC FIR coefficient start address
	MR = [R1] * [R2], ss, 16;
	R5 = R4;
	MR = [R1] * [R2], ss, 16;
	R4 += R5;
	R4 = R4 lsl 1;							// R3: downsampling PCM data
	pop R1 from [SP];
?L_WriteDataToBuffer:
	R2 = [R_SACM_A1800_ADC_In_PTR_Rec];
	[R2++] = R4;							// write PCM data to ADC_In buffer

	R3 = R_SACM_A1800_ADC_In_Buffer + C_ENCODE_IN_LENGTH;
	R4 = R3;								// ADC_In buffer 1 start address
	test R1, C_SACM_A1800_FIQ_EVEN;		// check ADC_In buffer 0/1
	jnz ?L_CheckPointerEnd;
	R3 += C_ENCODE_IN_LENGTH;				// buffer 1 end address, EVEN = '0'
	R4 -= C_ENCODE_IN_LENGTH;				// buffer 0 start
?L_CheckPointerEnd:
	cmp R2, R3;								// check if ADC_In buffer pointer point to buffer end
	je ?L_Switch_DAC_Out_Buffer;
	[R_SACM_A1800_ADC_In_PTR_Rec] = R2;	// ADC_In buffer pointer does not point to buffer end
	jmp ?L_FIQ_Encode_End;

?L_Switch_DAC_Out_Buffer:					// switch ADC_In buffer
	test R1, C_SACM_A1800_DECODE_END;		// check encode end
	jnz ?L_Record_End;
	R1 |= C_SACM_A1800_DECODE_WORK;		// encode does not finish, set DECODE_WORK flag
	R1 ^= C_SACM_A1800_FIQ_EVEN;			// change ADC_In buffer
	[R_SACM_A1800_Play_Flag] = R1;
	[R_SACM_A1800_ADC_In_PTR_Rec] = R4;	// update ADC_In buffer pointer
	jmp ?L_FIQ_Encode_End;

?L_Record_End:								// encoding finish
	call F_SACM_A1800_Stop;				// stop
?L_FIQ_Encode_End:
	R1 = [R_ShiftStore];
	R1 = R1 lsr 4;							// Retore 4-bit Shift Buffer
	R1 = [R_SACM_A1800_ISR_Flag];
	pop R2,R5 from [SP];
	retf;
@
//****************************************************************
// Function    : F_Check_Encryption
// Description : Check encryption
// Destory     : R1, R2, R3, R4, R5
// Parameter   : None
// Return      : R1: 0: encryption check fail
//                   1: encryption check pass
// Note        : None
//****************************************************************
.code
F_Check_Encryption:
	push R2, R5 to [SP];
	R1 = TB_SerialNo;			// (100)	TB_Encryption
	SR &= (~0xFC00);
	R2 = 4;
?L_Fisrt_CheckSN_Loop:
	R3 = D:[R1++];
	R4 = R3 & 0x00FF;
	R5 = 0x100;
	R5 -= R4;
	R4 = R5 lsl 3;
	R5 += R4;
	push R5 to [SP];
	R3 = R3 lsr 4;
	R3 = R3 lsr 4;
	R4 = R3 & 0x00FF;
	R5 = 0x100;
	R5 -= R4;
	R4 = R5 lsl 3;
	R5 += R4;
	push R5 to [SP];
	R2 -= 1;
	jnz ?L_Fisrt_CheckSN_Loop;

	R1 = TB_SerialNo + 4;
	R2 = 8;
?L_Second_CheckSN_Loop:
	R3 = D:[R1++];
	pop R5 from [SP];
	cmp R3, R5;
	jnz ?L_Encryption_Fault;
	R2 -= 1;
	jnz ?L_Second_CheckSN_Loop;

	R1 = TB_SerialNo;			// (100)	TB_Encryption
	R2 = 12;
	R4 = 0;
?L_CheckSN_Loop:
	R3 = D:[R1++];
	R5 = R3 & 0x00FF;
	R4 += R5;
	R3 = R3 lsr 4;
	R3 = R3 lsr 4;
	R5 = R3 & 0x00FF;
	R4 += R5;
	R2 -= 1;
	jnz ?L_CheckSN_Loop;

	R1 = TB_EncryptionCode;
	R3 = D:[R1++];
	cmp R4, R3;
	jnz ?L_Encryption_Fault;
	R4 = D:[R1];
	R2 = R3;
	R2 += R4;
	jnz ?L_Encryption_Fault;
	MR = R3 * R4, ss;
//	cmp R3, 0x01A7;
	cmp R3, 0x771F;
	jnz ?L_Encryption_Fault;			// (100)	TB_Encryption
	R1 = 1;
	jmp ?Check_Encryption_End;
?L_Encryption_Fault:
	R1 = 0;
?Check_Encryption_End:
	pop R2, R5 from [SP];
	retf;
