//==========================================================================
// File Name   : SACM_A1800_Decode.asm
// Description : call kernel functions to decode or encode
// Written by  : Ray Cheng
// Last modified date:
//              2005/12/26
// Note: 
//==========================================================================
//**************************************************************************
// Header File Included Area
//**************************************************************************
.include SACM_A1800_Constant.inc

//**************************************************************************
// Contant Defintion Area
//**************************************************************************
.define Remove_DC	1

//**************************************************************************
// Variable Publication Area
//**************************************************************************
//.public A1800_BITRATE
.public R_SACM_A1800_Play_Flag

//**************************************************************************
// Function Call Publication Area
//**************************************************************************
.public F_SACM_A1800_Decode_Initial_BS
.public F_SACM_A1800_Decode_Initial_Process
.public F_SACM_A1800_Decode_Process
//.public F_SACM_A1800_Encode_Initial_BS
//.public F_SACM_A1800_Encode_Initial_Process
//.public F_SACM_A1800_Encode_Process

//.public F_SACM_A1800_Encode_Finish_Process

.public F_SACM_A1800_Decode_Get_BS_Auto
.public F_SACM_A1800_System_Get_BS_Manual
//.public F_SACM_A1800_System_Put_BS_Manual
//.public F_A1800_Set_BitRate

//**************************************************************************
// External Function Declaration
//**************************************************************************
.external F_USER_A1800_GetData
//.external F_USER_A1800_WriteData
//.external F_SACM_A1800_EndPlay

.comment @
.external __f_r083_ac8_encode_init
.external __f_r083_ac8_encode
.external __f_r083_ac8_decode_init
.external __f_r083_ac8_decode
@
.external F_A1800_Dec_Init
//.external F_Siren7_Dec_Init
//.external F_A1800_Enc_Init
//.external F_Siren7_Enc_Init
//.external A1800_Rec_Endp
//.external F_A1800_Enc_Main
//.external F_A1800_Encode
//.external F_Siren7_Enc_Main
//.external F_A1800_Dec_Main
.external F_A1800_Decode
//.external F_Siren7_Dec_Main
//.external F_SACM_A1800_BITRATE

.comment @
.external A1800_Play_Init					// for ending code enable
//.external A1800_Play_Init_Dis_EndingCode		// for ending code disable
.external A1800_Rec_Init
//.external A1800_Rec_Endp
.external A1800_Rec_Proc
.external A1800_Play_Proc
@
.external F_SACM_A1800_GetStartAddr_Con
.external F_EventInit                            //Add by Gary	2016.02.23

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


//**************************************************************************
// External Variable Declaration
//**************************************************************************
.external R_Event_Tag_Cunt                                 	// Added by Allen on 2014.05.09
.external R_SACM_A1800_Event_Flag						  	//Add by Gary	2016.02.23

//**************************************************************************
// RAM Definition Area
//**************************************************************************
.IRAM
R_SACM_A1800_Play_Flag:    .dw 1    dup(0)

.RAM
OVERLAP_A1800_RAM_BLOCK:	.section	.ORAM
.var decvar_Hbufx
.var n_xfct3
.var temp_l_xfct3
.var temp_h_xfct3
decvar_Hbufy: .dw 2 DUP(?)

//__buf_r083_ac8_codec_save: .dw 128 dup(?)
//.var A1800_BITRATE

.include SACM_A1800_Decode_RAM.inc

//*****************************************************************************
// Table Definition Area
//*****************************************************************************
.comment @
.TEXT
T_A1800_DataRate_Table:
.dw 7200//,   7200/50
.dw 9600//,   9600/50
.dw 12000//, 12000/50
.dw 14400//, 14400/50
.dw 16000//, 16000/50
.dw 20000//, 20000/50
.dw 24000//, 24000/50
.dw 32000//, 32000/50
@

//**************************************************************************
// CODE Definition Area
//**************************************************************************
SACM_A1800_DECODE_ROM_BLOCK:	.section	.CODE

//****************************************************************
// Function    : F_SACM_A1800_Decode_Get_BS_Auto
// Description : Get bit stream for auto mode decoding
// Destory     : R1, R2, R3, R4
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
F_SACM_A1800_Decode_Get_BS_Auto: .proc
	R1 = [R_SACM_A1800_Decode_In_PTR];
	cmp R1, R_SACM_A1800_Decode_In_Buffer;	// check Decode_In buffer start
	je ?L_Branch_0;

	cmp R1, R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;	// check Decode_In buffer end
	jl ?L_Branch_1;

	R1 = R_SACM_A1800_Decode_In_Buffer;
	[R_SACM_A1800_Decode_In_PTR] = R1;	// reset Decode_In buffer pointer
	jmp ?L_Branch_2;

?L_Branch_1:
	R2 = R_SACM_A1800_Decode_In_Buffer;
	R3 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;

?L_Loop_0:
	R4 = [R1++];							// shift data to the beginning of Decode_In buffer
	[R2++] = R4;
	cmp R1, R3;
	jne ?L_Loop_0;

	[R_SACM_A1800_Decode_In_PTR] = R2;	// update pointer

?L_Branch_2:
	R2 = [R_SACM_A1800_Resouce_BS];
	R3 = [R_SACM_A1800_Resouce_DS];
	R4 = [R_SACM_A1800_Decode_In_PTR];
	R5 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;

?L_Loop_1:
	SR &= (~0xFC00);
//	SR |= [R_SACM_A1800_Resouce_DS];
	SR |= R3;
	R1 = D:[R2++];							// copy data to Decode_In buffer from ROM area
	[R4++] = R1;
	cmp R2, 0x0000;
	jne ?L_Branch_3;

//	R3 = [R_SACM_A1800_Resouce_DS];		// if data cross bank
	R3 += 0x0400;
//	[R_SACM_A1800_Resouce_DS] = R3;

?L_Branch_3:
	cmp R4, R5;
	jne ?L_Loop_1;

	[R_SACM_A1800_Resouce_BS] = R2;
	[R_SACM_A1800_Resouce_DS] = R3;
	R1 = R_SACM_A1800_Decode_In_Buffer;
	[R_SACM_A1800_Decode_In_PTR] = R1;

?L_Branch_0:
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Decode_Initial_BS
// Description : Initialize bit stream for decoding
// Destory     : R1, R2, R3
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
F_SACM_A1800_Decode_Initial_BS: .proc
	R1 = [R_SACM_A1800_Decode_In_PTR];
	R2 = [R1++];							// data length low word
	R3 = [R1++];							// data length high word
	[R_SACM_A1800_Decode_In_PTR] = R1;
// added by Ray 2006.03.20	
	cmp R3, 0xFFFF;							// if file length is 0xFFFF, 0xFFFF, always play until stop command
	jne ?L_CountByWord;
	cmp R2, 0xFFFF;
	jne ?L_CountByWord;
	jmp ?L_Set_Decode_Length;
?L_CountByWord:
	R1 = R3 lsr 4;
	R2 = R2 ror 1;
	R3 = R3 lsr 1;
?L_Set_Decode_Length:
	[R_SACM_A1800_Decode_Length_L] = R2;	// data length count by word
	[R_SACM_A1800_Decode_Length_H] = R3;	// data length count by word

//	R1 = [R_SACM_A1800_Decode_In_PTR];
//	R3 = [R1++];		
//	R4 = [R1++];
//	call F_SACM_A1800_BITRATE;
//	[R_SACM_A1800_Decode_In_PTR] = R1;   //added by wgp 20060607

	R1 = 0x0000;
	[R_SACM_A1800_Decode_Count_L] = R1;	// reset decode counter
	[R_SACM_A1800_Decode_Count_H] = R1;	// reset decode counter
	[R_SACM_A1800_DECODE_IN_LENGTH] = R1;
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Decode_Initial_Process
// Description : Initialize decode process
// Destory     : None
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
F_SACM_A1800_Decode_Initial_Process: .proc
	R1 = 0;
	[R_SACM_A1800_DECODE_IN_LENGTH] = R1;
	call F_A1800_Dec_Init;
//	call F_Siren7_Dec_Init;
	retf;
	.endp

//****************************************************************
// Function    : F_SACM_A1800_Decode_Process
// Description : Execute decode process
// Destory     : R1, R2, R3, R4
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
F_SACM_A1800_Decode_Process: .proc
	R1 = [R_SACM_A1800_Decode_Count_L];
	R2 = [R_SACM_A1800_Decode_Count_H];
	R1 += [R_SACM_A1800_DECODE_IN_LENGTH];
	R2 += 0, carry;
	[R_SACM_A1800_Decode_Count_L] = R1;
	[R_SACM_A1800_Decode_Count_H] = R2;
	R3 = [R_SACM_A1800_Decode_Length_L];
	R4 = [R_SACM_A1800_Decode_Length_H];
	cmp R2, R4;								// check if decode counter equals decode length
	jb ?L_Branch_0;
	cmp R1, R3;
	jb ?L_Branch_0;
// added by Ray 2006.03.20	
	cmp R4, 0xFFFF;						// if file length is 0xFFFF, 0xFFFF, always play until stop command
	jne ?L_Cecode_End;
	cmp R3, 0xFFFF;
	jne ?L_Cecode_End;
	jmp ?L_Branch_0;

?L_Cecode_End:
?L_CheckQueue:
	R1 = [R_A1800_NextIndex]
	cmp R1, -1;
	je ?L_QueueBufferEmpty;
	call F_ReInitial;
	jmp ?L_Branch_0;
// 2007.01.12 Ray end

?L_QueueBufferEmpty:
	R1 = [R_SACM_A1800_Play_Flag];		// decode counter equals decode length
	R1 |= C_SACM_A1800_DECODE_END;		// set DECODE_END flag
	[R_SACM_A1800_Play_Flag] = R1;

//	call F_SACM_A1800_EndPlay;			// defined in sacm.asm
	retf;

?L_Branch_0:
	R1 = [R_SACM_A1800_Decode_In_PTR];
	[R_SACM_A1800_DECODE_IN_LENGTH] = R1;	

	R1 = [R_SACM_A1800_DAC_Out_PTR_Decode];//added by zgq on 20051222
	[R_SACM_A1800_Decode_Out_PTR] = R1;	//added by zgq on 20051222

//	call F_A1800_Dec_Main;
	call F_A1800_Decode;    
    cmp R1, 0x0001;                                        // Added by Allen on 2014.05.09
    jnz ?L_NoEvent;                                        // Added by Allen on 2014.05.09
	R2 = [R_Event_Tag_Cunt];                               // Added by Allen on 2014.05.09
	R2 += 1;                                               // Added by Allen on 2014.05.09
	[R_Event_Tag_Cunt] = R2;                               // Added by Allen on 2014.05.09
    
?L_NoEvent:    
	R1 = [R_SACM_A1800_Decode_In_PTR];
	R1 -= [R_SACM_A1800_DECODE_IN_LENGTH];
	[R_SACM_A1800_DECODE_IN_LENGTH] = R1;
.comment @
	R1 = [R_SACM_A1800_DAC_Out_PTR_Decode];
	R2 = [R_SACM_A1800_Decode_In_PTR];
	R3 = __buf_r083_ac8_codec_save;
	call __f_r083_ac8_decode;
	R2 = [R_SACM_A1800_DAC_Out_PTR_Decode];
	R2 += 256;
	[R_SACM_A1800_DAC_Out_PTR_Decode] = R2;
	R2 = [R_SACM_A1800_Decode_In_PTR];
	R2 += R1;
	[R_SACM_A1800_Decode_In_PTR] = R2;
//	[R_SACM_A1800_DECODE_OUT_LENGTH]=R1;
	[R_SACM_A1800_DECODE_IN_LENGTH]=R1;
@
.comment @
	R1 = [R_SACM_A1800_Decode_In_PTR];	// decode counter does not equal decode length
	[R_SACM_A1800_DECODE_IN_LENGTH] = R1;
	call A1800_Play_Proc;					// decode one frame data
	R1 = [R_SACM_A1800_Decode_In_PTR];
	R1 -= [R_SACM_A1800_DECODE_IN_LENGTH];
	[R_SACM_A1800_DECODE_IN_LENGTH] = R1;	// calculate decode length
@
	retf;
	.endp

//****************************************************************
// Function    : F_ReInitial
// Description : re-initial
// Destory     : R1, R2, R3, R4
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
F_ReInitial: 
//	R1 = 1; //2004/10/14
//	[R_SACM_A1800_New_Flag] = R1; //2004/10/14
	R4 = 0;							//Add by Gary	2016.02.23
	[R_Event_Tag_Cunt] = R4;		//Add by Gary	2016.02.23

	R1 = [R_SACM_A1800_Play_Next_Flag];
	R4 = [R_SACM_A1800_Play_Flag];
	R4 &= ~(C_SACM_A1800_RAMP_DN_ENABLE | C_SACM_A1800_RAMP_UP_ENABLE | C_SACM_A1800_ENABLE_DAC1 | C_SACM_A1800_ENABLE_DAC2 | C_SACM_A1800_AUTO)
	test R1, C_SACM_A1800_RAMP_DN_ENABLE;
	jz ?CheckRampUp;
	R4 |= C_SACM_A1800_RAMP_DN_ENABLE;
?CheckRampUp:
	test R1, C_SACM_A1800_RAMP_UP_ENABLE;
	jz ?CheckDAC1;
	R4 |= C_SACM_A1800_RAMP_UP_ENABLE;
?CheckDAC1:
	test R1, C_SACM_A1800_ENABLE_DAC1;
	jz ?CheckDAC2;
	R4 |= C_SACM_A1800_ENABLE_DAC1;
?CheckDAC2:
	test R1, C_SACM_A1800_ENABLE_DAC2;
	jz ?CheckMode;
	R4 |= C_SACM_A1800_ENABLE_DAC2;
?CheckMode:
	test R1, C_SACM_A1800_AUTO;
	jz ?UpdateFlag;
	R4 |= C_SACM_A1800_AUTO;

	R3 = [R_SACM_A1800_Event_Flag];               //Add by Gary	2016.02.23
	R3 &= ~C_EXT_EVENT_FLAG;                      //Add by Gary	2016.02.23
	[R_SACM_A1800_Event_Flag] = R3;               //Clear external event flag, Add by Gary	2016.02.23	
?UpdateFlag:
	[R_SACM_A1800_Play_Flag] = R4;
//	cmp R1, C_Manual;         // Auto/ Manual
//   	JE ?L_Manual_Mode //?L_Branch_5;
	test R4, C_SACM_A1800_AUTO;
	jz ?L_Manual_Mode;

?L_Branch_5: 
	R1 = [R_A1800_NextIndex]; //2004/10/12
	R1 += T_SACM_A1800_SpeechTable
	R1 = [R1];
	R2 = [R1 ++];
	[R_SACM_A1800_Resouce_BS] = R2;
	R1 = [R1];
	R1 = R1 LSL 4;
	R1 = R1 LSL 4;
	R1 = R1 LSL 2;
	[R_SACM_A1800_Resouce_DS] = R1;

	push R1 to [SP];                              //Add by Gary	2016.02.23
	push R2 to [SP];                              //Add by Gary	2016.02.23

	R1 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;
	[R_SACM_A1800_Decode_In_PTR] = R1;	 
	 
    call F_SACM_A1800_Decode_Get_BS_Auto;
    jmp  ?L_DecodeInit;
    
    // Get bit stream  	

   //MANUAL_MODE 
?L_Manual_Mode:
	R1 = [R_SACM_A1800_Event_Flag];              //Add by Gary	2016.02.23
	R1 |= C_EXT_EVENT_FLAG;                      //Add by Gary	2016.02.23
	[R_SACM_A1800_Event_Flag] = R1;              // Set external event flag,Add by Gary	2016.02.23

	R1 = [R_A1800_NextIndex]; //2004/10/12
	R1 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;
	[R_SACM_A1800_Decode_In_PTR] = R1;	 	
	call F_SACM_A1800_GetStartAddr_Con;
	push R1,R2 to [SP];              			//Add by Gary	2016.02.23
	call F_SACM_A1800_System_Get_BS_Manual;

    // Start Decode 
?L_AutoGetBS1:
//AUTO_MODE


?L_DecodeInit:
    pop R1, R2 from [SP];                        //Add by Gary	2016.02.23
    R3 = [R_SACM_A1800_Decode_In_Buffer];        //Add by Gary	2016.02.23
    R4 = [R_SACM_A1800_Decode_In_Buffer + 1];    //Add by Gary	2016.02.23
	call F_EventInit;				             //Add by Gary	2016.02.23

   	call F_SACM_A1800_Decode_Initial_BS;
//	R1 = [R_SACM_A1800_Play_Next_Flag];   
//	cmp R1, C_Manual;         // Auto/ Manual
//   	jne ?L_AutoGetBS2;
	R4 = [R_SACM_A1800_Play_Flag];
	test R4, C_SACM_A1800_AUTO;
	jnz ?L_AutoGetBS2;
   
   //MANUAL_MODE 
	call F_SACM_A1800_System_Get_BS_Manual;
    jmp ?L_DecodeInProcess;
	 
    
?L_AutoGetBS2:    
   //AUTO_MODE
   	call F_SACM_A1800_Decode_Get_BS_Auto;
?L_DecodeInProcess:
	call F_SACM_A1800_Decode_Initial_Process;
		
	R1 = -1;
	[R_A1800_NextIndex] = R1;

	// tracker
	R1 = [R_SACM_A1800_Decode_Count_L];
// 	R2 = [R_SACM_A1800_Decode_Count_H];
 	R1 += [R_SACM_A1800_DECODE_IN_LENGTH];
//	R2 += 0, carry;
 	[R_SACM_A1800_Decode_Count_L] = R1;
//	[R_SACM_A1800_Decode_Count_H] = R2;           
	// end tracker
	
	retf;

//****************************************************************
// Function    : F_SACM_A1800_System_Get_BS_Manual
// Description : Get bit stream for manual mode
// Destory     : R1, R2, R3, R4
// Parameter   : None
// Return      : None
// Note        : None
//****************************************************************
F_SACM_A1800_System_Get_BS_Manual: .proc
	R1 = [R_SACM_A1800_Decode_In_PTR];
	cmp R1, R_SACM_A1800_Decode_In_Buffer;	// check Decode_In buffer start
	je ?L_Branch_0;

	cmp R1, R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;	// check Decode_In buffer end
	jl ?L_Branch_1;

	R1 = R_SACM_A1800_Decode_In_Buffer;	// reset decode in buffer pointer
	[R_SACM_A1800_Decode_In_PTR] = R1;
	jmp ?L_Branch_2;

?L_Branch_1:
	R2 = R_SACM_A1800_Decode_In_Buffer;
	R3 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;

?L_Loop_0:									// shift data to the beginning of Decode_In buffer
	R4 = [R1++];
	[R2++] = R4;
	cmp R1, R3;
	jne ?L_Loop_0;

	[R_SACM_A1800_Decode_In_PTR] = R2;	// update Decode_In pointer

?L_Branch_2:
	R1 = [R_SACM_A1800_Decode_In_PTR];
	R2 = R_SACM_A1800_Decode_In_Buffer + C_DECODE_IN_LENGTH;
	R2 -= R1;

	call F_USER_A1800_GetData;			// get data from external memory and fill to Encode_In buffer
	R1 = R_SACM_A1800_Decode_In_Buffer;
	[R_SACM_A1800_Decode_In_PTR] = R1;
?L_Branch_0:
	retf;
	.endp

