
; Listing27f.s	=> Kopie Listing11m1.s - Verwendung des Level 2 Interrupts ($68) zum Lesen des
; Tastencodes der gedrückten Taste auf der Tastatur.
; Drücken sie die Leertaste, um rauszugehen (zum Verlassen)

	SECTION	INTERRUPT,CODE

;	include	"DaWorkBench.s"	; entferne das; vor dem Speichern mit "wo"

*****************************************************************************
	include	"/Sources/startup2.s"	; speichern Interrupt, DMA und so weiter.
*****************************************************************************


; Mit DMASET entscheiden wir, welche DMA-Kanäle geöffnet und welche
; geschlossen werden sollen

			;5432109876543210
DMASET	equ	%1000001010000000	; Copper DMA aktivieren

WAITDISK	equ	30				; 50-150 zur Rettung (je nach Fall)

Start:
	move.l	BaseVBR(pc),a0	    ; in a0 ist der Wert des VBR

	move.l	#MyInt68KeyB,$68(a0)	; Tastaturroutine Int. Level 2
	move.l	#MyInt6c,$6c(a0)	; meine Routine Int. Level 3

			; 76543210
	move.b	#%01111111,$bfed01	; CIAAICR - deaktiviere alle CIA-IRQs
	move.b	#%10001000,$bfed01	; CIAAICR - aktiviere nur den SP CIA IRQ

	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Copper
	move.l	#Copperlist,$80(a5)	; Zeiger Copperlist
	move.w	d0,$88(a5)			; Start Copperlist
	move.w	#0,$1fc(a5)			; AGA "deaktivieren"
	move.w	#$c00,$106(a5)		; AGA "deaktivieren"
	move.w	#$11,$10c(a5)		; AGA "deaktivieren"

	movem.l	d0-d7/a0-a6,-(sp)
	bsr.w	mt_init				; Musik Routine initialisieren
	movem.l	(sp)+,d0-d7/a0-a6

			; 5432109876543210
	move.w	#%1100000000101000,$9a(a5)   ; INTENA - nur VERTB aktivieren 
										 ; von Level 3 und Level 2

WaitSpace:
	move.b	ActualKey(pc),d0	; Holen Sie sich den Code der letzten gedrückten Taste.
	move.b	d0,Color00+1		; Legen Sie den Code des aktuellen Zeichens als
								; Color00 ab ... zum Testen ..
	cmp.b	#$40,d0				; LEERTASTE GEDRÜCKT?
	bne.s	WaitSpace

	bsr.w	mt_end				; Ende der Wiederholung!
	move.b	#%10011111,$bfed01	; CIAAICR - wiederherstellen CIA IRQ
	rts							; Exit

; Variable, in der das aktuelle Zeichen gespeichert wird

ActualKey:
	dc.b	0

	even

*****************************************************************************
*	INTERRUPTROUTINE $68 (Level 2) - Tastatur-Verwaltung
*****************************************************************************

;03	PORTS	2 ($68)	Input/Output Port und Timer, verbunden mit INT2-Leitung

MyInt68KeyB:					; $68
	movem.l d0/a0,-(sp)			; speichern der Register auf dem Stack
	lea	$dff000,a0				; Register Custom Base für Offset

	move.b	$bfed01,d0			; CIAA ICR - in d0 (durch Lesen von ICR, verursachen wir
								; auch seine Nullsetzung, so ist der Interrupt
								; "gelöscht" wie in INTREQ).
	btst.l	#7,d0				; Bit IR, (Interrupt CIA), zurückgesetzt?
	beq.s	NoKey				; wenn ja, beenden
	btst.l	#3,d0				; Bit SP, (Interrupt der Tastatur), zurückgesetzt?
	beq.s	NoKey				; wenn ja, beenden

	move.w	$1c(a0),d0			; INTENAR in d0
	btst.l	#14,d0				; Bit Master der Aktivierung zurückgesetzt?
	beq.s	NoKey				; wenn ja, Interrupt ist nicht aktiv!
	and.w	$1e(a0),d0			; INREQR - in d0 bleiben nur die Bits gesetzt
								; welche sowohl in INTENA als auch in INTREQ gesetzt sind
								; um sicher zu sein, dass wenn der Interrupt
								; auftritt, auch aktiviert ist.
	btst.l	#3,d0				; INTREQR - PORTS?
	beq.w	NoKey				; Wenn nicht, dann beenden!

; Wenn wir nach den Kontrollen hier sind, heißt das, dass wir das Zeichen übernehmen müssen!

	moveq	#0,d0
	move.b	$bfec01,d0			; CIAA SDR (Serial Data Register - verbunden
								; mit der Tastatur - enthält das vom Tastaturchip
								; gesendete Byte) WIR LESEN DAS ZEICHEN!

; wir haben den Char in d0, wir "arbeiten" daran...

	not.b	d0					; wir passen den Wert durch Invertieren der Bits an
	ror.b	#1,d0				; und kehren zur Sequenz 76543210 zurück
	move.b	d0,ActualKey		; speichern des Zeichens

; Jetzt müssen wir der Tastatur mitteilen, dass wir die Daten aufgenommen haben!

	bset.b	#6,$bfee01			; CIAA CRA - SP ($bfec01) Ausgang, 
								; senken der KDAT-Zeile, um zu bestätigen
								; das wir den Charakter erhalten haben.

	st.b	$bfec01				; $ff in $bfec01 - Ich habe die Daten erhalten!

; Hier müssen wir eine Routine einstellen, die 90 Mikrosekunden wartet, weil die
; KDAT-Leitung genügend Zeit haben muss, um von allen Arten von Tastaturen 
; "verstanden" zu werden. Sie können beispielsweise auf 3 oder 4 Rasterzeilen warten.

	moveq	#4-1,d0				; Anzahl der zu wartenden Zeilen = 4 (in der Praxis 3 weitere)
								; und der Bruchteil, in dem wir uns gerade befinden
WaitLines:
	move.b	6(a0),d1			; $dff006 - aktuelle vertikale Zeile in d1
StepLine:
	cmp.b	6(a0),d1			; sind wir immer noch auf der gleichen Zeile?
	beq.s	StepLine			; wenn ja, warte
	dbra	d0,WaitLines		; "erwartete" Zeile, warte d0-1 Zeilen

; Nachdem wir gewartet haben, können wir $bfec01 im Eingabemodus melden ...

	bclr.b	#6,$bfee01			; CIAA CRA - sp (bfec01) erneut eingeben.

NoKey:		; 3210
	move.w	#%1000,$9c(a0)		; INTREQ Anfrage entfernen, int ausgeführt!
	movem.l (sp)+,d0/a0			; wiederherstellen der Register vom Stack
	rte

*****************************************************************************
*	INTERRUPTROUTINE $6c (Level 3) - benutzte VERTB und COPER			    *
*****************************************************************************

;06	BLIT	3 ($6c)	Wenn der Blitter einen Blitt beendet hat, wird es auf 1 gesetzt
;05	VERTB	3 ($6c)	Wird jedes Mal generiert, wenn der Elektronenstrahl die
			; Zeile 00 erreicht, d.h. bei jedem Beginn des vertikalen Austastens.
;04	COPER	3 ($6c)	Sie können es mit Copper einstellen, um es zu einem bestimmten 
			; Zeitpunkt (Videozeile) zu erzeugen
			; Fordern Sie ihn einfach nach einer gewissen Wartezeit an.

MyInt6c:
	btst.b	#5,$dff01f			; INTREQR - ist Bit 5, VERTB zurückgesetzt?
	beq.s	NoIntVertb			; Wenn ja, ist es kein "echter" VERTB Interrupt!
	movem.l	d0-d7/a0-a6,-(sp)	; Register speichern auf dem Stack
	bsr.w	mt_music			; Musik spielen
	movem.l	(sp)+,d0-d7/a0-a6	; Register vom Stack nehmen
NoIntVertb:
NoIntCoper:
NoBlit:		 ;6543210
	move.w	#%1110000,$dff09c	; INTREQ - Löschen Flag BLIT,VERTB und COPER
	rte							; Ende vom Interrupt COPER/BLIT/VERTB

*****************************************************************************
;	Wiederholungsroutine protracker/soundtracker/noisetracker
;
	include	"/Sources/music.s"
*****************************************************************************

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$100,$200			; BPLCON0 - keine Bitplanes
	dc.w	$180
Color00:
	dc.w	$000				; COLOR00 - es wird in Abhängigkeit der Taste geändert
	dc.w	$ffff,$fffe			; Ende Copperlist

*****************************************************************************
;				MUSIK
*****************************************************************************

mt_data:
	dc.l	mt_data1

mt_data1:
	incbin	"/Sources/mod.fairlight"

	end

Wenn das Byte des Tastaturcodes in COLOR00 eingegeben wird, können sie die
Tatsache erkennen, das wenn eine Taste gedrückt ist, ist Bit 7 zurückgesetzt,
während wenn die Taste losgelassen wird das Bit gesetzt ist. D.h. wenn sie eine
Taste drücken ist die Farbe dunkler, als wenn sie losgelassen wird, weil das 
hohe Bit von Grün gelöscht wird.

Taste gedrückt		- Bit 7 = 0	-> Farbe dunkler
Taste losgelassen	- Bit 7 = 1	    