//**************************************************************************
// Header File Included Area
//**************************************************************************
.include GPL951_Body.inc
.include A1800.inc

//**************************************************************************
// Contant Defintion Area
//**************************************************************************
.define Foreground		0
.define Background		1
//.define ServiceType		Foreground
.define ServiceType		Background

//**************************************************************************
// Variable Publication Area
//**************************************************************************

//**************************************************************************
// Function Call Publication Area
//**************************************************************************
.external _VBLK_Service
.external _R_Sec
.external _F_IRQ4_Service

.public _BREAK
.public _FIQ
.public _IRQ0
.public _IRQ1
.public _IRQ2
.public _IRQ3
.public _IRQ4
.public _IRQ5
.public _IRQ6
.public _IRQ7


//**************************************************************************
// External Function Declaration
//**************************************************************************

//**************************************************************************
// RAM Definition Area
//**************************************************************************

//**************************************************************************
// CODE Definition Area
//**************************************************************************
.text
_FIQ:
	// MIDI event driver entry point
	call _F_IRQ4_Service
	reti;
		    

//****************************************************************
_BREAK:        
    push R1, R5 to [SP];

	pop R1, R5 from [SP];
	reti; 
        
_IRQ0:        
    push R1, R5 to [SP];
	r1 = [P_INT_Status1]
	test r1, (C_INT_AUDAFIFOEmpty_IF + C_INT_AUDBFIFOEmpty_IF)
	jz	_Exit_IRQ0
	test r1, C_INT_AUDAFIFOEmpty_IF
	jz	L_EndAUDA?
	r2 = [P_CHA_Ctrl];
	[P_CHA_Ctrl] = r2;				//Clear Audio CHA FIFO Empty Flag
L_EndAUDA?:
	test r1, C_INT_AUDBFIFOEmpty_IF
	jz	L_EndAUDB?
	r2 = [P_CHB_Ctrl];
	[P_CHB_Ctrl] = r2;				//Clear Audio CHB FIFO Empty Flag
	
L_EndAUDB?:		
	call F_ISR_Service_SACM_A1800;
.if ServiceType == Background
	test	r1,0x0001
	jz	_Exit_IRQ0
	r2=offset L_ForBackgroundUsage
	push R2	to [SP];		           // push PC
	push SR	to [SP];		           // push CS	
	reti

L_ForBackgroundUsage:	
	call F_SACM_A1800_ServiceLoop;	   // SACM Service Loop	
	pop R1, R5 from [SP];	
	retf;
.endif

_Exit_IRQ0:	
	pop R1, R5 from [SP];
	reti; 
        
_IRQ1:        
	push r1,r2 to [sp]
	r1=[P_INT_Status1]
	test r1,C_INT_ADCReady_IF
	jnz	L_ADCManual?
	r1=[P_INT_Status2]
	test r1,C_INT_MICADCAutoSample_IF
	jnz	L_ADCAuto?
	nop
	nop
	goto endfiq?
	
L_ADCAuto?:
	r1=[P_ASMICADC_Data]
	[P_CHA_Data]=r1
		
//	r1=[P_ASMICADC_Ctrl]
//	[P_ASMICADC_Ctrl]=r1	//clear int flag
	jmp	endfiq?	
	
L_ADCManual?:	
	r1=[P_MADC_Ctrl]
	test r1,0x030
	jnz	adcerror?
	[P_MADC_Ctrl]=r1		//clear ADC int flag
	
	r1=[P_MADC_Data]
	r1=r1 lsr 4				//adc >> 4 for IOC[11:0]
	[P_IOC_Data]=r1
	jmp	endfiq?				
	
adcerror?:
	r1|=(C_ADC_ErrFlag1+C_ADC_ErrFlag2+C_ADC_ManualStart+C_ADC_ReadyFlag)	//clear errof flag and restart convert and clear int flag	
	[P_MADC_Ctrl]=r1
	jmp	endfiq?

endfiq?:	
	pop r1,r2 from [sp]
	reti;  
        
_IRQ2:        
    push R1, R5 to [SP];

	pop R1, R5 from [SP];
	reti;         
        
_IRQ3:        
    push R1, R5 to [SP];

	pop R1, R5 from [SP];
	reti;         
        
_IRQ4:        
    push R1, R5 to [SP];

	pop R1, R5 from [SP];
	reti;  
        
_IRQ5:        
	//add your code here
	push r1, r5 to [sp]
	push r8, r15 to [sp]
	
	R1 = [P_PPU_Enable]
	test	r1, 0x1			// judge PPU Enable or not, if ppu enable, do VBLK service
	jz		L_IRQ5_End	
	call _VBLK_Service
	
L_IRQ5_End:	
	pop r8, r15 from [sp]
	pop r1, r5 from [sp]
	reti;         
        
_IRQ6:        
    push R1, R5 to [SP];

	pop R1, R5 from [SP];
	reti;         
        
_IRQ7:        
	push r1, r5 to [sp]
	r1 = [P_INT_Status2]
	test	r1, C_INT_RTC_IF
	jnz		L_CheckSec?
	
	test	r1,C_INT_TimeBaseA_IF
	jnz		L_CheckTMBA?
	jz		L_end?
	
L_CheckTMBA?:	
	r1=[P_TimeBaseA_Ctrl]
	r1|=C_TimeBaseAFlag
	[P_TimeBaseA_Ctrl]=r1
	
	r1=[P_MADC_Ctrl]		//start manual ADC convert. When convert finish wii occur ADC INT
	r1|=C_ADC_ManualStart
	[P_MADC_Ctrl]=r1	
	jz 		L_end?
	

L_CheckSec?:	
	// Judge 0x40 = 0x01 (SEC INT)
	r1 = 0x40
	[P_RTC_Addr] = r1
	CALL	L_Ready?
	r1 = 0x02				//Read
	[P_RTC_Request] = r1
	CALL	L_Ready?
	r1 = [P_RTC_ReadData]
	r4 = r1
	test r1, 0x01
	jz	L_end?
	
L_SecInt?:	
	r1 = [_R_Sec]
	r1+=1
	[_R_Sec] = r1

	// IO Toggle
//	r1 = [P_IOB_Buffer]
//	r1^=0x01
//	[P_IOB_Buffer] = r1

	// Clear SEC INT (0x40[0] write "0")		
	r1 = 0x40
	[P_RTC_Addr] = r1
	r1 = 0xFE
	[P_RTC_WriteData] = r1
	r1 = 0x01				//Write
	[P_RTC_Request] = r1
	CALL	L_Ready?
	CALL	L_CheckBusy?		

	
L_end?:
	pop r1, r5 from [sp]	
	reti;
	
	
// Check Busy Flag (0x0[4] = "1" => Busy)
L_CheckBusy?:
	CALL	L_Ready?		//Make Sure can send Serial Data
	r1 = 0x00
	[P_RTC_Addr] = r1
	
L_NotReady?:	
	r1 = 0x02				//[0]: Write Req [1]: Read Req
	[P_RTC_Request] = r1		
	CALL	L_Ready?
	r1 = [P_RTC_ReadData]
	test r1, 0x10
	jnz	L_NotReady?
	retf
	
// Check Ready Flag (P_RTC_Ready ($79F4.b0) = "1" => Ready)	
L_Ready?:
	r1 = [P_RTC_Ready]
	test r1, 0x01
	jz	L_Ready?
	retf
	reti;
