
	.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,#0x92		@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
	