
; Listing27c4.s
; Timer A des CIAB zur Zeitmessung verwendet
; ausgehend von einer festen Startzeile ist das Ende variabel
; es wird die Ausführungszeit in Rasterzeilen auf dem Bildschirm ausgeben
; rechte Maustaste bewegt das Ende, linke Maustaste beendet

	SECTION CIA,CODE

Start:
	move.l	4.w,a6				; Execbase in a6
	jsr	-$78(a6)				; Disable - verhindert Interrupts
	lea	GfxName(PC),a1			; Libname
	jsr	-$198(a6)				; OldOpenLibrary
	move.l	d0,GfxBase
	move.l	d0,a6
	move.l	$26(a6),OldCop		; wir speichern die alte Copperlist

	move.l	#Bitplane,d0		; Adresse des Bitplane in d0
	lea	Bplpointers,a1			; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	lea	$dff000,a5				; Custom Register Base in a5
	move.l	#Copperlist,$80(a5)	; Zeiger Copperlist	
	move.w	#0,$1fc(a5)			; AGA "deaktivieren"
	move.w	#$c00,$106(a5)		; AGA "deaktivieren"
	move.w	#$11,$10c(a5)		; AGA "deaktivieren"
	
Init:
	move.w	#$100,d4			; Y-Position add
	bsr	CiaInit					; CIA Zeitmessung vorbereiten
	
WarteY:
	move.l	4(a5),d0			; $dff004 - VPOSR/VHPOSR
	andi.l	#$1ff00,d0			; wirkt sich nur auf die Bits der vertikalen Zeile aus
	cmpi.l	Y1Wert,d0			; warte auf Zeile Y1Wert
	bne.s	WarteY

	move.w  #$f00,$180(a5)		; rot - signalisiert CIA Start
	move.b  #$11,$e00(a4)		; CRA - Force Load und Start timer!!	
								; Timer is running now, do the test

WarteY2:
	move.l	4(a5),d0			; $dff004 - VPOSR/VHPOSR
	andi.l	#$1ff00,d0			; wirkt sich nur auf die Bits der vertikalen Zeile aus				
	cmpi.l	Y2Wert,d0			; warte auf Zeile Y2Wert
	bne.s	WarteY2

	bclr    #0,$e00(a4)			; CRA - Stop timer!!
	move.w  #$0f0,$180(a5)		; grün - signalisiert CIA Stop

	moveq   #0,d6				; und Ergebnis sichern
	moveq   #0,d7
	move.b  $400(a4),d6			; TALO 
	move.b  $500(a4),d7			; TAHI 
	asl.w   #8,d7
	or.w    d7,d6				; Ergebnis in d6 
								; 1 tick = 1,409683 µs PAL
								; 1 tick = 1,396825 µs NTSC
								; 1 Rasterzeile ~ 63,5µs  
								; 1 Rasterzeile ~ 45 ticks
	moveq	#-1,d0
	sub.w	d6,d0
	and.l	#$0000ffff,d0
	divu.w	#45,d0				; 1 Rasterzeil = 45 ticks
						
; das Programm an dieser Stelle warten lassen um mit dem Debugger den Wert in
; d6 (ticks) und in d5 Anzahl Rasterzeilen auszulesen 

	bsr Zeit					; Anzahl Rasterzeilen ausgeben	
	move.w #$000,$180(a5)		; schwarz - Routine Zeit beendet
	
	btst	#2,$dff016			; rechte Maustaste gedrückt?
	bne.s	Mouse				

	bsr.w	BewegeY2			; die untere Warteposition ermitteln

Mouse:
	btst	#6,$bfe001			; linke Maustaste gedrückt?
	bne	WarteY	
	
Exit:
	move.b	OldCiaaCra,$e00(a4)		; CRA wiederherstellen
	move.b  #%01111111,$d00(a4)		; ICR - alles aus
	move.b	OldCiaaIcr,$d00(a4)		; ICR wiederherstellen

	move.l	OldCop(PC),$dff080		; Pointen auf die SystemCOP
	move.w	d0,$dff088				; Starten die alte SystemCOP

	move.l	4.w,a6
	jsr	-$7e(a6)					; Enable
	move.l	GfxBase(PC),a1
	jsr	-$19e(a6)					; Closelibrary
	rts

;	Daten
GfxName:
	dc.b	"graphics.library",0,0
GfxBase:
	dc.l	0
OldCop:
	dc.l	0
OldCiaaCra:
	dc.b	0
OldCiaaIcr:	
	dc.b	0
Y1Wert:
	dc.l	$2c00	; Startwert (fest)
Y2Wert:
	dc.l	$5000	; Startwert (variabel)

*******************************************************************************
* In dieser Routine wird der CIA-B Timer A voreingestellt			          *
*******************************************************************************

CiaInit:
	lea		$bfd000,a4				; CIA-B base
	
	move.b	$d00(a4),d0				; ICR
	or.b	#$80,d0
	move.b	d0,OldCiaaIcr			; ICR - alten ICR-Wert speichern
	move.b  #%01111111,$d00(a4)		; ICR - alle CIA interrupts	löschen

	move.b	$e00(a4),d0				; CRA
	move.b	d0,OldCiaaCra
	and.b   #%11000000,d0           ; Bits 6 und 7 bleiben erhalten
	or.b    #%00001000,d0           ; One-Shot mode
	move.b  d0,$e00(a4)				; CRA
	    
	move.b  #$ff,$400(a4)			; TALO - Setzen Sie das Low-Byte der Zeit
    move.b  #$ff,$500(a4)			; TAHI - das Schreiben in Timer Hi startet den Timer	
	;bclr    #0,$e00(a4)			; CRA - Stop timer!! 
	rts
	
*******************************************************************************
* In dieser Routine wird die untere Warteposition Y2Wert ermittelt            *
*******************************************************************************

BewegeY2:	
	move.l	Y2Wert,d0		; aktuellen Y2 Wert holen
	add.l d4,d0				; um eine Zeile erhöhen bzw. verringern
	
	cmp.l #$12500,d0		; untere Grenze - bottom check - sind wir unten?	
	bne Ok1					; 				
	neg.l d4				; Richtungsumkehr 1 wird -1
Ok1:
	cmp.l #$2e00,d0			; obere Grenze - sind wir oben? ; 
	bne Ok2					; 
	neg.l d4				; Richtungsumkehr 1 wird -1
Ok2:		
	move.l d0,Y2Wert		; aktuellen Wert speichern
	rts

*******************************************************************************
* In dieser Routine wird die untere Warteposition Y2Wert ermittelt            *
*******************************************************************************
	
Zeit: 
	movem.l d0-d2/a0-a3,-(sp)
;--- Zeile ermitteln ---------
	;move.w #$45,d0					; zu Testzwecken - den festen Wert $45 = 69 ausgeben
_timeDisplayCounter:
	and.l #$0000FFFF,d0
	moveq #0,d1
	moveq #3-1,d2
_timeLoopNumber:
	divu #10,d0						; => d0=remainder:quotient of the division of d0 coded on 32 bits
	swap d0
	add.b #$30-$20,d0				; ASCII code for "0" minus the first character offset in font8 ($20)
	move.b d0,d1
	lsl.l #8,d1
	clr.w d0
	swap d0
	dbf d2,_timeLoopNumber
	
	divu #10,d0						; => d0=remainder:quotient of the division of d0 coded on 32 bits
	swap d0
	add.b #$30-$20,d0				; ASCII code for "0" minus the first character offset in font8 ($20)
	move.b d0,d1

									; => d1 : d1 : sequence of 4 ASCII offsets in the font for the 4
									; characters to display, but in reverse order (ex: 123 => "3210")
									
;--- Zeichen drucken ---------
	;move.l #$11191210,d1			; Zeichen  0291
	lea font8,a0					; Adresse Font 8x8 Pixel			
	lea Bitplane,a1					; Startadresse Bitplane
	moveq #4-1,d0					; Anzahl der Zeichen
_timeLoopDisplay:					; Label Schleife
	clr.w d2	
	move.b d1,d2					; zu druckendes Zeichen in d2 kopieren
	lsl.w #3,d2						; *8, weil Zeichen 8x8 Pixel hat um zu Überspringen
	lea (a0,d2.w),a2				; das entsprechende Zeichen im Font finden (Anfangsadresse)
	move.l a1,a3					; Adresse Bitplane kopieren
	moveq #8-1,d2					; Schleife über 8 Zeilen des Zeichens
_timeLoopDisplayChar:				; Label Schleife Charakter
	move.b (a2)+,(a3)				; Zeichen nach Bitplane kopieren		
	lea 320>>3(a3),a3				; 320>>3=$28 = 40Bytes --> nächste Zeile
	dbf d2,_timeLoopDisplayChar
	lea 1(a1),a1					; 1 Byte vor in Bitplane
	lsr.l #8,d1						; in d1 stehen 4 Werte, den nächsten Wert auswählen
	dbf d0,_timeLoopDisplay

	movem.l (sp)+,d0-d2/a0-a3
	rts

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

	SECTION GRAPHIC,DATA_C

Copperlist:
SpritePointers:
	dc.w	$120,0,$122,0,$124,0,$126,0,$128,0 ; Sprites
	dc.w	$12a,0,$12c,0,$12e,0,$130,0,$132,0
	dc.w	$134,0,$136,0,$138,0,$13a,0,$13c,0
	dc.w	$13e,0
	
	dc.w	$8e,$2c81	; DiwStrt
	dc.w	$90,$2cc1	; DiwStop	
	dc.w	$92,$38		; DdfStart
	dc.w	$94,$d0		; DdfStop
	dc.w	$102,0		; BplCon1
	dc.w	$104,0		; BplCon2
	dc.w	$108,0		; Bpl1Mod
	dc.w	$10a,0		; Bpl2Mod

				; 5432109876543210
	dc.w	$100,%0001001000000000  ; Bit 12 an!! 1 Bitplane Lowres	

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

	dc.w	$180,$00f	; Color0	; Hintergrund Schwarz
	dc.w	$182,$0f0	; Color1	; Farbe 1 der Bitplane
							
	dc.w	$ffff,$fffe	; Ende der Copperlist

Font8:		
	incbin "/Sources/font8.fnt"

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

	SECTION LEEREPLANE,BSS_C	

Bitplane:
	ds.b	40*256			; Bitplane auf 0 Lowres
	
	end