;**************************************************************************
;
; Filename : IRQ.ASM
; -------------------
;
; (c) 1990 by Thomas Lehmann
;
;
; Jackophone V5.00
;
;
; Interrupt Routine
;
;
;**************************************************************************

MODUL_START	set	*	; Größe des Moduls berechnen

; =========================================================================
;
; Type	: IRQ
;	: Interruptroutine
;
; Eingang	: bei Timer oder CA1 Interrupt
;
; Ausgang	: Interruptprogramme abgelaufen
;
; Register	: ------
;
; (c) by Thomas Lehmann Feb. 1990
;
; =========================================================================

irq	inc interrupt	; Merker das IRQ aktiv ist

	phx		; Register retten
	tsx		; aktuellen Stackpointer retten
	stx stk_merk

	ldx #STK_INIT	; Stack für IRQ-Prg.
	txs		; Stackpointer für IRQ-Routine setzen
	pha
	phy


	; ACIA IRQ ?
	; ----------
	jsr acia_irq	; ACIA 6551 IRQ Routine


	; Interrupt Quelle 6522 ermitteln
	; -------------------------------
	lda Via+IFR	; IRQ Flag Register

	; CA1 ? (externer Reset)
	; ----------------------
	bit #IFR_CA1	; CA1 Interrupt ?
	beq irq_1	; nein

	jmp init_stk	; Prg. Neustart


	; CB1 ? (Gebührenimpuls)
	; ----------------------
irq_1	bit #IFR_CB1	; CB1 Interrupt ?
	beq irq_2	; nein

	lda Via+IORB	; clear CB1 Interrupt
	?inc16 geb_cnt	; Anzahl Gebührenimpulse erhöhen
	smb GEB_IMP,hgeb_stat	; Impuls wurde erkannt
	bra irq_end	; IRQ Ende



	; Timer ermitteln
	; ---------------
irq_2	bit #IFR_TIM1	; Timer1 Interrupt ?
	beq time2_irq	; nein, Timer2 testen



	; ================
	; Timer1 IRQ 800uS
	; ================

	lda Via+T1C_L	; Interrupt quittieren

	; =================
	; Software Watchdog
	; =================

	jsr watchdog_i	; testen ob Hauptprg. läuft, IRQ nachtriggern

	; ======================
	; Refresh der Led-Matrix
	; ======================

	jsr led_update

	; ========================
	; Uhr Port, 100Hz abfragen
	; ========================

	lda #UHR	; Port für 100Hz Uhr Impuls, (10mS)
	bit Via_portb	; positive Flanke ?
	bne t1_irq_1	; ja, kein Impuls

	bbs UHR_FLAG,allg_stat,t1_irq_2	; negative war Flanke erkannt

	smb UHR_FLAG,allg_stat	; Flanke ist erkannt eintragen
	smb UHR_NOT,allg_stat	; Notbetrieb der Uhr ausschalten
	dec uhr_tim	; Anzahl der Impulse nachführen
	bne t1_irq_2	; Sekunde noch nicht erreicht

	inc sekunde	; Sekunde +1
	lda #UHR_TIM	; Timerwert laden
	sta uhr_tim	; Timer aufziehen
	bra t1_irq_2

t1_irq_1	rmb UHR_FLAG,allg_stat	; positive Flanke eintragen

t1_irq_2	bra irq_end



	; Timer2 testen
	; -------------
time2_irq	bit #IFR_TIM2	; Timer2 Interrupt ?
	beq irq_end	; nö, komisch wer wars denn sonst noch ???


	; ===============
	; Timer2 IRQ 10mS
	; ===============

	lda #>IRQ_TIM2	; IRQ quittieren, Timer Reload
	sta Via+T2C_H


	; ======================
	; 100mS Timer nachführen
	; ======================
	dec tim_100ms_t
	bne t2_irq	; nicht abgelaufen

	lda #10		; Anzahl der 10mS IRQ`s bis 100mS erreicht
	sta tim_100ms_t	; Timer neu starten

	; ======================================
	; 100mS Timer in der Struktur nachführen
	; ======================================

	ldx #ANZ_TIM100-1	; Anzahl der 100mS Timer laden
t2_irq100_0	lda struct_tim100,x	; Timer abgelaufen ?
	beq t2_irq100_1	; ja, nächsten Timer testen

	dec struct_tim100,x	; Timer nachführen
t2_irq100_1	dex		; nächsten Timer einstellen
	bpl t2_irq100_0	; und Timer testen


	; =====================================
	; 10mS Timer in der Struktur nachführen
	; =====================================

t2_irq	ldx #ANZ_TIM-1	; Anzahl der Timer laden
t2_irq_0	lda struct_tim,x	; Timer abgelaufen ?
	beq t2_irq_1	; ja, nächsten Timer testen

	dec struct_tim,x	; Timer nachführen
t2_irq_1	dex		; nächsten Timer einstellen
	bpl t2_irq_0	; und Timer testen


	; =========================
	; anstehende Ziffern wählen
	; =========================

	jsr wahl	; Ziffern wählen

	; ================
	; Hörtonauswertung
	; ================

	jsr tst_hton	; Hörton testen


	; ==================================
	; Blink BIT für LED`s weiterschalten
	; ==================================

	lda struct_tim+BLK_TIM_O	; Blinkfrequenz Timer für LED`s
	bne irq_end	; noch nicht abgelaufen

	lda #BLINK_TIM	; Timerwert laden
	sta struct_tim+BLK_TIM_O	; und neu starten
	asl blink_bit	; nächstes BIT einstellen
	bcc irq_end	; noch nicht alle durchlaufen, Ende
	rol blink_bit	; 1.Bit setzen, Carry=1


	; =====================
	; IRQ-Routine verlassen
	; =====================

irq_end	ply		; Register zurück
	pla
	ldx stk_merk	; Stackptr. der unterbrochenen Routine setzen
	txs		; Main Stack wieder setzen
	plx

	stz interrupt	; Merker das IRQ beendet
	cli		; Interrupt freigeben
	rti		; und verlassen




; --------------------------------------------------------------------------

HLP	set	*
_IRQ	equ	HLP-MODUL_START		; Größe des Moduls

