
	.set	MAX_UPA_PI		,4

	.text
	.align	2
	.thumb	

;***********************************************************
;*
;* add_irq_th	Hänge neuen IRQ ein
;*
;* r0  = Funktionspointer
;* r1  = Type (13 mgl)
;* 
;*	0 VBlank
;*	1 HBlank
;*	2 VCount
;*	3 Timer 0
;*	4 Timer 1
;*	5 Timer 2
;*	6 Timer 3
;*	7 Serial Communication 
;*	8 DMA 0
;*	9 DMA 1
;*	A DMA 2
;*	B DMA 3
;*	C Key
;*	D Cassette
;*
;* Return r0 = (0 -> ok)

	.global		add_irq_th
	.type		add_irq_th,function

add_irq_th

	push	{r1-r3}

	ldr	r2,=irq_fkt
	mov	r3,#MAX_UPA_PI*4
	mul	r1,r1,r3
	add	r2,r2,r1
	
	mov	r3,#MAX_UPA_PI
scan_ia
	ldr	r1,[r2]
	cmp	r1,#0
	bne	iv_nnull
	str	r0,[r2]
	b	scan_ia_set
iv_nnull
	add	r2,r2,#4	
	sub	r3,r3,#1
	bne	scan_ia	
scan_ia_set

	mov	r0,r3
	pop	{r1-r3}
	bx	lr

;***********************************************************
;*
;* rem_irq_th	Lösch IRQ aus Liste
;*
;* r0  = Funktionspointer
;* r1  = Type (13 mgl)
;* 
;*	0 VBlank
;*	1 HBlank
;*	2 VCount
;*	3 Timer 0
;*	4 Timer 1
;*	5 Timer 2
;*	6 Timer 3
;*	7 Serial Communication 
;*	8 DMA 0
;*	9 DMA 1
;*	A DMA 2
;*	B DMA 3
;*	C Key
;*	D Cassette
;*

	.global		rem_irq_th
	.type		rem_irq_th,function
	
	

rem_irq_th

	push	{r0-r4}

	mov	r2,pc
	bx	r2		;zu arm
	
	.align			;wichtig da wechsel zu arm nach 2 thumb instr.
	.arm
	
	mov	r2,#$92		;IRQ Modus , IRQ Aus
	mrs	r4,CPSR		;speichere alten modus
	msr	CPSR,r2
	
	add	r2,pc,#1	;zu thumb
	bx	r2
	
	.thumb
		
		
	ldr	r2,=irq_fkt
	mov	r3,#MAX_UPA_PI*4
	mul	r1,r1,r3
	add	r2,r2,r1
	
	mov	r3,#MAX_UPA_PI
scan_ia_r
	ldr	r1,[r2]
	cmp	r1,r0
	bne	scan_ia_ni
	mov	r1,#0
	str	r1,[r2]
	b	scan_ia_swp
scan_ia_ni	
	add	r2,r2,#4	
	sub	r3,r3,#1
	bne	scan_ia_r	
scan_ia_clr
	
	mov	r2,pc		;to thumb
	bx	r2
	
	.align	
	.arm
	
	msr	CPSR,r4		;wieder zu altem modus
	
	ldmfd	sp!,{r0-r4}
	bx	lr
	
	.thumb
	
;*****
;*
;* schiebe 0 Longs rechts raus (swappe gute werte) 
;*	
;* r2 = adr
;* r3 = rest	
	
scan_ia_swp

	cmp	r3,#1		;letzte muss nicht geswapt werden
	beq	scan_ia_clr
	
	sub	r3,r3,#1
swap_lo		

	ldmia	r2!,{r1}	;dieses
	ldr	r0,[r2]		;nächstes
	cmp	r0,#0		;nächstes auch Null dann raus
	beq	scan_ia_clr
	
	sub	r2,r2,#4
	stmia	r2!,{r0}	;dieses	= nächstes
	str	r1,[r2]		;nächstes = dieses
	
	sub	r3,r3,#1
	bne	swap_lo

	b	scan_ia_clr
		

	.pool
	.section    	.ewram,"ax"	

;***********************************************************
;*
;* do_irq_th	führe IRQ aus
;*
;* r0  = REG_IE
;* 
;*	Bit 0 VBlank
;*	Bit 1 HBlank
;*	Bit 2 VCount
;*	Bit 3 Timer 0
;*	Bit 4 Timer 1
;*	Bit 5 Timer 2
;*	Bit 6 Timer 3
;*	Bit 7 Serial Communication 
;*	Bit 8 DMA 0
;*	Bit 9 DMA 1
;*	Bit A DMA 2
;*	Bit B DMA 3
;*	Bit C Key
;*	Bit D Cassette
;*


	.global		do_irq_th
	.type		do_irq_th,function

do_irq_th

	mov	r3,lr
	push	{r4,r5}
		
	adr	r1,irq_fkt-(MAX_UPA_PI*4)
scan_bit
scan_irq_back

	add	r1,r1,#MAX_UPA_PI*4
	lsr	r0,r0,#1
	bcs	scan_irq_found		;Carry = 1 -> irq gefunden
	bne	scan_bit		;keine weiteren irqs (da irq = 0) dann ende
	
scan_no_more		
		
	pop	{r4,r5}
	bx	r3

;**** r0 - r1 save, r4,r5 free

scan_irq_found

	push	{r0-r1,r3}	

	;**** run irq
	
	mov	r4,r1
		
	adr	r2,scan_ia_nii+2
	sub	r2,#1					
	mov	lr,r2
	
	mov	r5,#MAX_UPA_PI
scan_ia_ir

	ldmia	r4!,{r2}
	cmp	r2,#0
	beq	scan_ia_end		;0 -> kein weiterer mehr da sortiert
	bx	r2			;UPA (r0-r3 for free use)

scan_ia_nii

	sub	r5,r5,#1
	bne	scan_ia_ir
scan_ia_end
		
	pop	{r0-r1,r3}
	
	b	scan_irq_back


	;**** irq ram	
			
		.align	
irq_fkt		.zero	MAX_UPA_PI*4*14
irq_schutz	.byte	0

	.end
	