
; Listing27f2.s	=> Kopie Listing11m2.s - Verwenden von Level 2 Interrupt ($68) zum Lesen von
; gedrückten Tastencodes auf der Tastatur.
; In diesem Fall dekodieren wir auch den Leseknopf
; Umwandlung in das entsprechende ASCII-Zeichen.

	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	%1000001110000000	; GRAPHIC,Bitplane und DMA aktivieren

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

Start:
	move.l	#Bitplane,d0		; in d0 setzen wir die Adresse der Bitplane
	lea	Bplpointers,a1			; Bitplanepointer
	move.w	d0,6(a1)			; Kopiere das niedrige word der Bitplaneadresse
	swap	d0					; tauscht die 2 Wörter von d0 (z.B.: 1234 > 3412)
	move.w	d0,2(a1)			; Kopiere das hohe word der Bitplaneadresse

	move.l	BaseVBR(pc),a0		; In a0 der Wert des VBR

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

	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Bitplane, 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 - aktivieren nur VERTB
										; per Level 3 und Level 2
Mouse:
	btst	#6,$bfe001
	bne.s	Mouse

	bsr.w	mt_end				; Ende der Wiederholung!
	rts							; Exit

	even

*****************************************************************************
*	INTERRUPT-Routine $68 (Level 2) - Tastaturverwaltung
*****************************************************************************

;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!							

	bsr.s	ConvertChar			; Konvertiere das Zeichen in ASCII

; 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			; Register vom stack nehmen
	rte

*****************************************************************************
*	INTERRUPT-Routine  $6c (Level 3) -  VERTB und COPER benutzt.			*
*****************************************************************************

;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 dem Copper einstellen, um es bei einer bestimmten 
			; Videozeile zu erzeugen.
			; Fordern Sie es 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.s	PrintChar			; Zeichen drucken
	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 - Anfoderung löschen BLIT,VERTB und COPER
	rte							; Ende vom Interrupt COPER/BLIT/VERTB


*****************************************************************************
; SubRoutine, die das Zeichen nach ASCII konvertiert
*****************************************************************************

ConvertChar:
	movem.l	d1-d2/a0,-(sp)

; data Received bit : 6 5 4 3 2 1 0 7
; Bit 7 ist 1, wenn die Taste losgelassen wird

	not.b	d0					; invertieren
	lsr.b	#1,d0				; und nach rechts verschieben
	bcs.b	KeyUp				; wird Taste losgelassen, ist Carry=1

	cmp.b	#$60,d0				; left shift - von $60 bis $67 sind die Modifier-Tasten
	blo.b	ToAscii				; es handelt sich um normale Tasten
	bset	d0,ControlKey		; setzt in ControlKey das entsprechende Bit 0 bis 7
	bra.b	Exit

KeyUp:							; Taste wird losgelassen
	cmp.b	#$60,d0				; von $60 bis $67 sind die Modifier-Tasten
	blo.b	Exit				; normale Tasten werden beim Loslassen ignoriert
	bclr	d0,ControlKey		; setzt das Bit in ControlKey zurück, wenn eine 
								; Modifier-Taste losgelassen wurde
	bra.b	Exit

;			bit	7 6     5 4     3    2     1 0
;              Amiga    Alt   Ctrl  caps  shift
;               r l     r l         lock   r l

ToAscii:
	move.b	ControlKey(pc),d1	; Modifier-Stati in d1
	beq.b	GetChar				; wenn keine Modifier-Taste gedrückt wurde
	move.b	d1,d2				; Kopie
	and.b	#%00000111,d1		; nur linke und rechte Shift-Taste sowie Caps-Lock	
	beq.b	TstAlt				; ansonsten springe zu TstAlt
	add.w	#$68,d0				; Offset für Großbuchstaben 
	bra.b	GetChar				; Zeichen lesen
TstAlt:
	and.b	#%00110000,d2		; Bit 4 und 5 - linke und rechte Alt-Taste gedrückt?
;	beq	....
	add.w	#$68*2,d0			; Offset für Bereich Alt-Tasten
GetChar:
	lea	Raw2Ascii(pc),a0		; Basis-Adresse Tabelle Zeichen
	move.b	(a0,d0.w),d0		; das entsprechende Zeichen aus der Tabelle lesen	
	move.b	d0,AsciiChar		; Wert speichern
	clr.b	Received			; Die Daten sind fertig!
Exit:
	movem.l	(sp)+,d1-d2/a0
	rts

*****************************************************************************

PrintChar:
	tst.b	Received			; Daten erhalten?
	bne.s	NotPressed
	st.b	Received
	moveq	#0,d0
	move.b	AsciiChar(pc),d0
	cmp.b	#-1,d0
	beq.b	NotValid	; es war ein Sonderzeichen wie z.B. Hilfe-Taste etc.
	bsr.s	Print		; Andernfalls wird das Zeichen auf dem Bildschirm gedruckt
NotValid:
NotPressed:
	rts

ControlKey:		dc.b	0		; verwaltet alle Modifier-Stati (Shift, Alt, etc.)
AsciiChar:		dc.b	0
Received: 		dc.b	-1
LineCounter:	dc.b	0

	even

*****************************************************************************
; Druck Routine Charakter in d0
*****************************************************************************

Print:
	movem.l	a2-a3,-(sp)

	sub.b	#$20,d0				; ZÄHLE 32 VOM ASCII-WERT DES BUCHSTABEN WEG
								; SOMIT VERWANDELN WIR Z.B. DAS LEERZEICHEN
								; (Das $20 entspricht), IN $00, DAS
								; AUSRUFUNGSZEICHEN ($21) IN $01...
	lsl.w	#3,d0				; MULTIPLIZIERE DIE ERHALTENE ZAHL MIT 8,
								; da die Charakter ja 8 Pixel hoch sind
	move.l	d0,a2
	add.l	#Font,a2			; FINDE DEN GEWÜNSCHTEN BUCHSTABEN IM FONT...

	cmp.b	#80,LineCounter		; 80 gedruckte Zeichen?
	bne.s	NoEnd
	add.l	#80*7,PointerBitplane	
	clr.b	LineCounter
NoEnd:
	move.l	PointerBitplane(pc),a3 ; Adresse Ziel-Bitplane in a3

								; DRUCKE DEN BUCHSTABEN ZEILE FÜR ZEILE
	move.b	(a2)+,(a3)			; Drucke Zeile 1 des Zeichens
	move.b	(a2)+,80(a3)		; Drucke Zeile  2  " "
	move.b	(a2)+,80*2(a3)		; Drucke Zeile  3  " "
	move.b	(a2)+,80*3(a3)		; Drucke Zeile  4  " "
	move.b	(a2)+,80*4(a3)		; Drucke Zeile  5  " "
	move.b	(a2)+,80*5(a3)		; Drucke Zeile  6  " "
	move.b	(a2)+,80*6(a3)		; Drucke Zeile  7  " "
	move.b	(a2)+,80*7(a3)		; Drucke Zeile  8  " "

	addq.l	#1,PointerBitplane	; wir rücken 8 Bits vor (NÄCHSTES ZEICHEN)
	addq.b	#1,LineCounter

	movem.l	(sp)+,a2-a3
	rts

PointerBitplane:
	dc.l	Bitplane


; ASCII-Konvertierungstabelle. Leicht bearbeitbar für die Tastatur
; Italienisch oder andere.

Raw2Ascii:
	dc.b	'`'
	dc.b	'1'
	dc.b	'2'
	dc.b	'3'
	dc.b	'4'
	dc.b	'5'
	dc.b	'6'
	dc.b	'7'
	dc.b	'8'
	dc.b	'9'
	dc.b	'0'
	dc.b	'-'
	dc.b	'='
	dc.b	'\'
	dc.b	-1	; <<<<<<<<<<<<<<
	dc.b	'0'	; Tastenfeld numerisch
	dc.b	'q'
	dc.b	'w'
	dc.b	'e'
	dc.b	'r'
	dc.b	't'
	dc.b	'y'
	dc.b	'u'
	dc.b	'i'
	dc.b	'o'
	dc.b	'p'
	dc.b	'['
	dc.b	']'
	dc.b	-1	; <<<<<<<<<<<<<<<<<
	dc.b	'1'
	dc.b	'2'
	dc.b	'3'
	dc.b	'a'
	dc.b	's'
	dc.b	'd'
	dc.b	'f'
	dc.b	'g'
	dc.b	'h'
	dc.b	'j'
	dc.b	'k'
	dc.b	'l'
	dc.b	';'
	dc.b    39
	dc.b	-1	; not used
	dc.b	-1	; <<<<<<<<<<<<<<<<<<<<
	dc.b	'4'
	dc.b	'5'
	dc.b	'6'
	dc.b	'<'
	dc.b	'z'
	dc.b	'x'
	dc.b	'c'
	dc.b	'v'
	dc.b	'b'
	dc.b	'n'
	dc.b	'm'
	dc.b	','
	dc.b	'.'
	dc.b	'/'
	dc.b	-1	; <<<<<<<<<<<<<<<<<<
	dc.b	'.'
	dc.b	'7'
	dc.b	'8'
	dc.b	'9'
	dc.b	' '	; space
	dc.b	-1	; back space
	dc.b	-1	; tab
	dc.b	-1	; return	Tastenfeld
	dc.b	-1	; return
	dc.b	-1	; esc
	dc.b	-1	; del
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; <<<<<<<<<
	dc.b	'-'
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; up
	dc.b	-1	; down
	dc.b	-1	; dx
	dc.b	-1	; sx
	dc.b	-1	; f1
	dc.b	-1	; f2
	dc.b	-1	; f3
	dc.b	-1	; f4
	dc.b	-1	; f5
	dc.b	-1	; f6
	dc.b	-1	; f7
	dc.b	-1	; f8
	dc.b	-1	; f9
	dc.b	-1	; f10
	dc.b	'('
	dc.b	')'
	dc.b	'/'
	dc.b	'*'
	dc.b	'+'
	dc.b	-1	; help
	dc.b	-1	; lshift
	dc.b	-1	; rshift
	dc.b	-1	; caps lock
	dc.b	-1	; ctrl
	dc.b	-1	; lalt
	dc.b	-1	; ralt
	dc.b	-1	; lamiga
	dc.b	-1	; ramiga

	dc.b	'~'	; shift-tati
	dc.b	'!'
	dc.b	'@'
	dc.b	'#'
	dc.b	'$'
	dc.b	'%'
	dc.b	'^'
	dc.b	'&'
	dc.b	'*'
	dc.b	'('
	dc.b	')'
	dc.b	'_'
	dc.b	'+'
	dc.b	'|'
	dc.b	-1	; <<<<<<<<<<<<<<
	dc.b	'0'	; Tastenfeld numerisch
	dc.b	'Q'
	dc.b	'W'
	dc.b	'E'
	dc.b	'R'
	dc.b	'T'
	dc.b	'Y'
	dc.b	'U'
	dc.b	'I'
	dc.b	'O'
	dc.b	'P'
	dc.b	'{'
	dc.b	'}'
	dc.b	-1	; <<<<<<<<<<<<<<<<<
	dc.b	'1'	; Tastenfeld
	dc.b	'2'	; Tastenfeld
	dc.b	'3'	; Tastenfeld
	dc.b	'A'
	dc.b	'S'
	dc.b	'D'
	dc.b	'F'
	dc.b	'G'
	dc.b	'H'
	dc.b	'J'
	dc.b	'K'
	dc.b	'L'
	dc.b	':'
	dc.b    '"'
	dc.b	-1	; not used
	dc.b	-1	; <<<<<<<<<<<<<<<<<<<<
	dc.b	'4'	; Tastenfeld
	dc.b	'5'	; Tastenfeld
	dc.b	'6'	; Tastenfeld
	dc.b	'>'
	dc.b	'Z'
	dc.b	'X'
	dc.b	'C'
	dc.b	'V'
	dc.b	'B'
	dc.b	'N'
	dc.b	'M'
	dc.b	'<'
	dc.b	'>'
	dc.b	'?'
	dc.b	-1	; <<<<<<<<<<<<<<<<<<
	dc.b	'.'	; Tastenfeld
	dc.b	'7'	; Tastenfeld
	dc.b	'8'	; Tastenfeld
	dc.b	'9'	; Tastenfeld
	dc.b	' '	; space
	dc.b	-1	; back space
	dc.b	-1	; tab
	dc.b	-1	; return Tastenfeld
	dc.b	-1	; return
	dc.b	-1	; esc
	dc.b	-1	; del
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; <<<<<<<<<
	dc.b	'-'
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; up
	dc.b	-1	; down
	dc.b	-1	; dx
	dc.b	-1	; sx
	dc.b	-1	; f1
	dc.b	-1	; f2
	dc.b	-1	; f3
	dc.b	-1	; f4
	dc.b	-1	; f5
	dc.b	-1	; f6
	dc.b	-1	; f7
	dc.b	-1	; f8
	dc.b	-1	; f9
	dc.b	-1	; f10
	dc.b	'('
	dc.b	')'
	dc.b	'/'
	dc.b	'*'
	dc.b	'+'
	dc.b	-1	; help
	dc.b	-1	; lshift
	dc.b	-1	; rshift
	dc.b	-1	; caps lock
	dc.b	-1	; ctrl
	dc.b	-1	; lalt
	dc.b	-1	; ralt
	dc.b	-1	; lamiga
	dc.b	-1	; ramiga

	dc.b	'`'	;alt-tasten
	dc.b	'¹'
	dc.b	'²'
	dc.b	'³'
	dc.b	'¢'
	dc.b	'¼'
	dc.b	'½'
	dc.b	'¾'
	dc.b	'·'
	dc.b	'«'
	dc.b	'»'
	dc.b	'-'
	dc.b	'='
	dc.b	'\'
	dc.b	-1	; <<<<<<<<<<<<<<
	dc.b	'0'	; Tastenfeld numerico
	dc.b	'å'
	dc.b	'°'
	dc.b	'©'
	dc.b	'®'
	dc.b	'þ'
	dc.b	'¤'
	dc.b	'µ'
	dc.b	'¡'
	dc.b	'ø'
	dc.b	'¶'
	dc.b	'['
	dc.b	']'
	dc.b	-1	; <<<<<<<<<<<<<<<<<
	dc.b	'1'	; Tastenfeld
	dc.b	'2'	; Tastenfeld
	dc.b	'3'	; Tastenfeld
	dc.b	'æ'
	dc.b	'ß'
	dc.b	'ð'
	dc.b	''
	dc.b	''
	dc.b	''
	dc.b	''
	dc.b	''
	dc.b	'£'
	dc.b	';'
	dc.b    39
	dc.b	'ù'	 ;not used
	dc.b	-1	; <<<<<<<<<<<<<<<<<<<<
	dc.b	'4'	; Tastenfeld
	dc.b	'5'	; Tastenfeld
	dc.b	'6'	; Tastenfeld
	dc.b	'<'
	dc.b	'±'
	dc.b	'×'
	dc.b	'ç'
	dc.b	'ª'
	dc.b	'º'
	dc.b	'­'
	dc.b	'¸'
	dc.b	','
	dc.b	'.'
	dc.b	'/'
	dc.b	-1	; <<<<<<<<<<<<<<<<<<
	dc.b	'.'	; Tastenfeld
	dc.b	'7'	; Tastenfeld
	dc.b	'8'	; Tastenfeld
	dc.b	'9'	; Tastenfeld
	dc.b	' '	; space
	dc.b	-1	; back space
	dc.b	-1	; tab
	dc.b	-1	; return	Tastenfeld
	dc.b	-1	; return
	dc.b	'›'	; esc
	dc.b	-1	; del
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; <<<<<<<<<
	dc.b	'-'
	dc.b	-1	; <<<<<<<<<
	dc.b	-1	; up
	dc.b	-1	; down
	dc.b	-1	; dx
	dc.b	-1	; sx
	dc.b	-1	; f1
	dc.b	-1	; f2
	dc.b	-1	; f3
	dc.b	-1	; f4
	dc.b	-1	; f5
	dc.b	-1	; f6
	dc.b	-1	; f7
	dc.b	-1	; f8
	dc.b	-1	; f9
	dc.b	-1	; f10
	dc.b	'['
	dc.b	']'
	dc.b	'/'
	dc.b	'*'
	dc.b	'+'
	dc.b	-1	; help
	dc.b	-1	; lshift
	dc.b	-1	; rshift
	dc.b	-1	; caps lock
	dc.b	-1	; ctrl
	dc.b	-1	; lalt
	dc.b	-1	; ralt
	dc.b	-1	; lamiga
	dc.b	-1	; ramiga

	even

;	Die Schriftzeichen 8x8.

Font:
	incbin	"/Sources/nice.fnt"

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

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$8e,$2c81			; DIWSTRT	(Register mit normalen Werten)
	dc.w	$90,$2cc1			; DIWSTOP
	dc.w	$92,$003c			; DDFSTRT HIRES
	dc.w	$94,$00d4			; DDFSTOP HIRES
	dc.w	$102,0				; BPLCON1
	dc.w	$104,0				; BPLCON2
	dc.w	$108,0				; BPL1MOD \ INTERLACE: modulo = Länge Zeile!
	dc.w	$10a,0				; BPL2MOD / um sie zu überspringen (gerade oder ungerade)

				; 5432109876543210
	dc.w	$100,%1001001000000000	; 1 Bitplane, HIRES 640x256

Bplpointers:
	dc.w	$e0,$0000,$e2,$0000	; erste Bitplane

	dc.w	$180,$226			; COLOR00 - Hintergrund
	dc.w	$182,$0c0			; COLOR01 - erste Bitplane Position normal,
								; der Teil, der oben "hervorsteht".

	dc.w	$ffff,$fffe			; Ende Copperlist

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

mt_data:
	dc.l	mt_data1

mt_data1:
	incbin	"/Sources/mod.fairlight"

;********************************************************************
;	Bitplane
;********************************************************************
	
	SECTION	LEEREPLANE,BSS_C

Bitplane:
	ds.b	80*320

	end

Sie könnten sich ein Dienstprogramm, oder ein Programm erstellen, für das 
eine Eingabe des Namens oder anderer Daten erforderlich ist, oder Ihnen
antwortet, als wäre es eine Person... wenn sie wollen!
