
; Listing10e2.s		Löschen und Zeichnen mit Coppermonitor
; linke Taste zum Beenden.

	SECTION	BLIT,CODE

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

*****************************************************************************
	include	"/Sources/startup1.s"	; speichern Copperlist etc.
*****************************************************************************

			;5432109876543210
DMASET	equ	%1000001111000000	; Bitplane, Copper, Blitter DMA


Start:
	move.l	#Bitplane,d0		; Zeiger auf die "leere" Bitplane
	lea	Bplpointers,a1			; Bitplanepointer
	moveq	#3-1,d1				; Anzahl der Bitplanes (hier sind es 3)
PointBp:
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	swap	d0
	add.l	#40*256,d0			; + LÄNGE EINER PLANE !!!!!
	addq.w	#8,a1
	dbra	d1,PointBp

	lea	$dff000,a5				; Custom Register Base in a5
	move.w	#DMASET,$96(a5)		; DMACON - einschalten Bitplane, Copper, Blitter
	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"

	move.w	#0,ObjX
	move.w	#0,ObjY

Mouse:
	addq.w	#1,ObjY
	cmp.w	#130,ObjY
	beq.s	Ende

	move.l	#$1ff00,d1			; Bit zur Auswahl durch UND
	move.l	#$0d000,d2			; Warte auf Zeile $d0
WarteY1:
	move.l	4(a5),d0			; VPOSR und VHPOSR - $dff004/$dff006
	and.l   d1,d0				; Wählen Sie nur die Bits der vertikalen Pos.
	cmp.l   d2,d0				; Warte auf Zeile $d0
	bne.s	WarteY1

;	   \\\|||///
;	 .  =======
;	/ \| O   O |
;	\ / \`___'/
;	 #   _| |_
;	(#) (     )
;	 #\//|* *|\\
;	 #\/(  *  )/
;	 #   =====
;	 #   ( U )
;	 #   || ||
;	.#---'| |`----.
;	`#----' `-----'

	move	#$ff0,$180(a5)		; gelber Bildschirm, bis Blitter beginnt								

	bsr.s	ClearObject			; lösche den Bob

	move	#$0b0,$180(a5)		; dunkelgrüner Bildschirm, wenn der
								; Prozessor die Löschung abgeschlossen hat 
								
	bsr.s	DesignObject		; zeichne den Bob

	move	#$b00,$180(a5)		; dunkelroter Bildschirm, wenn der
								; Prozessor das Zeichnen abgeschlossen hat

	btst	#6,2(a5)
WaitBlit:
	btst	#6,2(a5)			; warte auf das Ende des Blitters
	bne.s	WaitBlit

	move.w	#$000,$180(a5)		; schwarzen Hintergrund zurücksetzen, wenn
								; der Blitter das Zeichnen abgeschlossen hat
	bra.s	Mouse

Ende:
	rts


;*****************************************************************************
; Diese Routine löscht den BOB unter Verwendung des Blitters. Die 
; Löschung wird auf dem Rechteck gemacht, das den Bob umgibt.
;****************************************************************************

ClearObject:
	lea	Bitplane,a0				; Ziel in a0
	move.w	ObjY(pc),d0			; Koordinate Y
	mulu.w	#40,d0				; Adresse berechnen: Jede Zeile besteht aus
								; 40 Bytes
	add.w	d0,a0				; zur Anfangsadresse hinzufügen

	move.w	ObjX(pc),d1			; Koordinate X
	lsr.w	#3,d1				; (entspricht einer Division durch 8)
								; Runden auf ein Vielfaches von 8 für den Zeiger
								; auf den Bildschirm, also auch auf ungerade Adressen
								; (also zu Bytes)
								; zB: eine 16 als Koordinate wird zu Byte 2
	and.w	#$fffe,d1			; Ich schließe Bit 0 aus
	add.w	d1,a0				; addieren zur Adresse der Bitebene, 
								; um die richtige Zieladresse zu finden

	moveq	#3-1,d7				; wiederhole es für jede Ebene
PlaneLoop2:
	btst	#6,2(a5)
WaitBlit3:
	btst	#6,2(a5)			; warte auf das Ende des Blitters
	bne.s	WaitBlit3

	move.w	#$0f0,$180(a5)		; Coppermonitor! grüner Bildschirm während
								; Löschung

	move.l	#$01000000,$40(a5)	; BLTCON0 und BLTCON1: Löschung
	move.w	#$0004,$66(a5)		; BLTDMOD=40-36=4
	move.l	a0,$54(a5)			; BLTDPT
	move.w	#(64*45)+18,$58(a5)	; BLTSIZE (Blitter starten!)
								; Lösche das umschließende Rechteck
								; des BOBs

	lea	40*256(a0),a0			; zeigt auf die nächste Zielebene
	dbra	d7,PlaneLoop2

	rts				

;****************************************************************************
; Diese Routine zeichnet den BOB an die in den Variablen ObjX und ObjY
; angegebenen Koordinaten
;****************************************************************************

DesignObject:
	lea	Bitplane,a0				; Ziel in a0
	move.w	ObjY(pc),d0			; Koordinate Y
	mulu.w	#40,d0				; Adresse berechnen: Jede Zeile besteht aus
								; 40 Bytes
	add.w	d0,a0				; zur Anfangsadresse hinzufügen

	move.w	ObjX(pc),d0			; Koordinate X
	move.w	d0,d1				; Kopie
	and.w	#$000f,d0			; wir wählen die ersten 4 Bits, weil sie
								; in den Shifter von Kanal A eingefügt werden
    lsl.w	#8,d0				; Die 4 Bits werden zum High-Nibble 
	lsl.w	#4,d0				; des Wortes bewegt...
	or.w	#$09f0,d0			; ... rechts, in das BLTCON0-Register einzugeben
	lsr.w	#3,d1				; (entspricht einer Division durch 8)
								; Runden auf ein Vielfaches von 8 für den Zeiger
								; auf den Bildschirm, also auch auf ungerade Adressen
								; (also zu Bytes)
								; zB: eine 16 als Koordinate wird zu Byte 2
	and.w	#$fffe,d1			; Ich schließe Bit 0 aus
	add.w	d1,a0				; addieren zur Adresse der Bitebene, 
								; um die richtige Zieladresse zu finden
	lea	Figur,a1				; Zeiger Quelle
	moveq	#3-1,d7				; wiederhole es für jede Ebene
PlaneLoop:
	btst	#6,2(a5)
WaitBlit2:
	btst	#6,2(a5)			; warte auf das Ende des Blitters
	bne.s	WaitBlit2

	move.w	#$f00,$180(a5)		; Coppermonitor! roter Bildschirm während
								; des Zeichnens

	move.l	#$ffffffff,$44(a5)	; BLTAFWM = $ffff es passiert alles
								; BLTALWM = $ffff es passiert alles

	move.w	d0,$40(a5)			; BLTCON0 (A+D)
	move.w	#$0000,$42(a5)		; BLTCON1 (ohne Spezialmodi)
	move.l	#$00000004,$64(a5)	; BLTAMOD=0
								; BLTDMOD=40-36=4 wie immer
	move.l	a1,$50(a5)			; BLTAPT (an der Quellfigur fixiert)
	move.l	a0,$54(a5)			; BLTDPT (Bildschirm)
	move.w	#(64*45)+18,$58(a5)	; BLTSIZE (Blitter starten !)

	lea	40*256(a0),a0			; zeigt auf die nächste Zielebene
	lea	2*18*45(a1),a1			; zeigt auf die nächste Quellebene
								; Jede Bitplane ist 18 Wörter breit und 
								; 45 Zeilen hoch
	dbra	d7,PlaneLoop

	rts

ObjY:		dc.w	0			; hier wird das Y des Objektes gespeichert
ObjX:		dc.w	0			; hier wird das X des Objektes gespeichert
;MouseY:	dc.b	0			; hier wird das Y der Maus gespeichert
;MouseX:	dc.b	0			; hier wird das X der Maus gespeichert

;****************************************************************************

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$8e,$2c81			; DIWSTRT
	dc.w	$90,$2cc1			; DIWSTOP
	dc.w	$92,$38				; DDFSTRT
	dc.w	$94,$d0				; DDFSTOP
	dc.w	$102,0				; BPLCON1
	dc.w	$104,0				; BPLCON2
	dc.w	$108,0				; WERT MODULO 0
	dc.w	$10a,0				; BEIDE MODULO MIT GLEICHEN WERT.

	dc.w	$100,$3200			; BPLCON0 - 3 Bitplanes lowres

Bplpointers:
	dc.w	$e0,$0000,$e2,$0000	; erste Bitplane
	dc.w	$e4,$0000,$e6,$0000
	dc.w	$e8,$0000,$ea,$0000

	dc.w	$0180,$000			; COLOR00
	dc.w	$0182,$475			; COLOR01
	dc.w	$0184,$fff			; COLOR02
	dc.w	$0186,$ccc			; COLOR03
	dc.w	$0188,$999			; COLOR04
	dc.w	$018a,$232			; COLOR05
	dc.w	$018c,$777			; COLOR06
	dc.w	$018e,$444			; COLOR07

	dc.w	$ffff,$fffe			; Ende Copperlist

;****************************************************************************

; Dies sind die Daten, aus denen die Figur des Bobs besteht.
; Der Bob ist im normalen Format, 288 Pixel breit (18 Wörter)
; 45 Zeilen hoch, 3 Bitebenen

Figur:
	incbin	"/Sources/copmon.raw"

;****************************************************************************

	SECTION	LEEREPLANE,BSS_C

Bitplane:
		ds.b	40*256			; 3 Bitplanes
		ds.b	40*256
		ds.b	40*256

	end

;****************************************************************************

In diesem Beispiel verschieben wir ein Rechteck auf dem Bildschirm, das wir 
löschen und dann neu zeichnen. Wir haben eine Reihe von verschiedenen Farben 
für das Markieren der Geschwindigkeit (der benötigten Ausführungszeit) der
Routinen, die der Blitter und der Prozessor für die Arbeit verwendet.
Wenn die Löschroutine beginnt, wird der Bildschirm grün. Jetzt sind, sowohl der
Blitter als auch der Prozessor an der Löschoperation beteiligt. Wenn der
Prozessor die Löschroutine beendet hat, ist der Blitter noch nicht mit seiner
Arbeit fertig geworden. Aber der Prozessor ist bereits frei für andere
Aufgaben. Diese Situation wird hervorgehoben, indem der Bildschirm am Ende der
Routine "ClearObject" mit einem dunkleren grün eingefärbt wird. An dieser
Stelle betritt der Prozessor die Routine "DesignObject". (während der Blitter
immer noch beschäftigt ist) Bevor der Zeichenvorgang beginnt, ist es notwendig,
auf den Blitter zu warten. Wenn der Blitter endlich fertig ist, ist der
Bildschirm rot. Nach Verlassen der Routine "DesignObject" erscheint der
Bildschirm in dunkelrot, das darauf wartet, dass der Blitter das Zeichnen 
beendet. Wenn dies geschieht, wird der Bildschirm wieder schwarz.

Beachten Sie außerdem, dass das Löschen und Kopieren (ungefähr) dieselbe 
Zeit erfordern.                                                                                                                                                                                                                                                                                                                                                                                                          ist, steht die Maus still
	