
; Listing9h3.s		Wir lassen ein Bild erscheinen
; immer eine Pixelspalte gleichzeitig 
; rechte Taste um den Blitt zu starten, links um zu beenden.

	SECTION	BLIT,CODE

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

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

			;5432109876543210
DMASET	EQU	%1000001111000000	; Bitplane, Copper, Blitter DMA ; $83C0


Start:
	move.l	#Bitplane,d0		; Zeiger auf das Bild
	lea	Bplpointers,a1			; Bitplanepointer
	moveq	#3-1,d1				; Anzahl 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 Bitplane !!!!!
	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"

Mouse1:
	btst	#2,$dff016			; rechte Maustaste gedrückt?
	bne.s	Mouse1				; Wenn nicht, gehe zurück zu Mouse1:

	bsr.s	Show				; Routine ausführen

Mouse2:
	btst	#6,$bfe001			; linke Maustaste gedrückt?
	bne.s	Mouse2				; Wenn nicht, gehe zurück zu Mouse2:

	rts


; ************************ DIE ROUTINE, DIE DIE FIGUR ZEIGT *******************

;	     .øØØØØØø.
;	     |¤¯_ _¬¤|
;	    _|___ ___|_
;	   (_| (·T.) l_)
;	    /  ¯(_)¯  \
;	   /____ _ ____\
;	  //    Y Y    \\
;	 //__/\_____/\__\\ xCz
;	(_________________)

Show:
; Anfangswerte von Zeigern

	lea	Picture,a0				; zeigt auf den Anfang der Figur
	lea	Bitplane,a1				; zeigt auf den Anfang der ersten Bitebene

	moveq	#20-1,d7			; alle Wort- "Spalten" ausführen
								; Der Bildschirm ist 20 Wörter breit
								; Es gibt 20 Spalten.

MakeAllWords:
	moveq	#16-1,d6			; 16 Pixel für jedes Wort.
	move.w	#%1000000000000000,d0	; Wert der Maske am Anfang von
								; interner Schleife. Wir übergeben nur das
								; Pixel ganz links vom Wort.
DoOneWord:
; warte auf Vblank, um jeweils eine Pixelspalte pro Frame zu zeichnen

WaitWblank:
	cmp.b	#$ff,$dff006		; VHPOSR - warte auf die Zeile 255
	bne.s	WaitWblank
WarteY:
	cmp.b	#$ff,$dff006		; VHPOSR - noch Zeile 255 ?
	beq.s	WarteY

	moveq	#3-1,d5				; wiederhole es für jede Ebene

	move.l	a0,a2				; Kopiere die Zeiger auf 2 andere Register
	move.l	a1,a3				; Dies liegt an der inneren Schleife
								; das zeichnet die verschiedenen Ebenen
								; Wechsel von einer Bitplane zur anderen 
								; Ziel.

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

	move.l	#$09f00000,$40(a5)	; BLTCON0 und BLTCON1 - Kopie von A nach D
	move.w	#$ffff,$44(a5)		; BLTAFWM - alle Bits übergeben
	move.w	d0,$46(a5)			; Wert der Maske in das BLTALWM Register laden

								; Lade die Zeiger
	move.l	a2,$50(a5)			; BLTAPT
	move.l	a3,$54(a5)			; BLTDPT

; Sowohl für die Quelle als auch für das Ziel blitten wir ein Wort auf einen 
; 20 Wörter breiten Bildschirm. Also hat das Modulo den Wert 2 * (20-1) = 38 = $26.
; Da die 2 Register aufeinanderfolgende Adressen haben, braucht man nur eine
; Anweisung anstatt 2 zu verwenden:

	move.l #$00260026,$64(a5)	; BLTAMOD und BLTDMOD 

; wir blitten ein 256 Zeilen hohes Wort "Spalte" (den ganzen Bildschirm)

	move.w	#(256*64)+1,$58(a5)	; BLTSIZE
								; 256 Zeilen Höhe
								; Breite 1 Word

	lea	40*256(a2),a2			; zeigt auf die nächste Quellenebene
	lea	40*256(a3),a3			; zeigt auf die nächste Zielebene

	dbra	d5,DoOnePlane		; für alle Ebenen wiederholen

	asr.w	#1,d0				; die Maske für den nächsten Blitt vorbereiten

	dbra	d6,DoOneWord		; für alle Pixel wiederholen 
	
	addq.w	#2,a0				; auf das nächste Wort zeigen
	addq.w	#2,a1				; auf das nächste Wort zeigen
	
	dbra	d7,MakeAllWords		; für alle Wörter wiederholen 

	btst	#6,$02(a5)			; DMACONR - warte auf das Ende des Blitters
WaitBlit2:
	btst	#6,$02(a5)
	bne.s	WaitBlit2

	rts

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

	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 GLEICHEM 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

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

Picture:
	incbin	"/Sources/amiga.raw"
								; Hier laden wir die Figur ein			
								; mit KEFCON konvertiert.

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

	SECTION	LEEREPLANE,BSS_C

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

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

In diesem Beispiel sehen wir einen neuen Effekt dank einer Maske. Wir 
zeichnen ein Bild auf dem Bildschirm immer eine Spalte von Pixeln zu einem
Zeitpunkt beginnend von links. In der Praxis müssen wir vom Bild immer eine 
"Spalte" von Pixeln zu einer Zeit auf dem Bildschirm kopieren. Die minimale 
Breite eines Blitts ist jedoch ein Wort, d.h. 16 Pixel. Wenn wir also 
einfache Kopien machen, könnten wir nur Gruppen von 16 Pixeln kopieren. Zum
Glück gibt es jedoch Masken. Indem man ein Wort breit blittet, gelten beide
Masken für den Blitt. Für uns reicht jedoch eine, zum Beispiel BLTALWM 
(Es wäre aber das Gleiche, wenn wir BLTAFWM verwenden.)
Der Trick ist folgender:
Wir kopieren die gleiche Spalte von 1 Wort 16 Mal, jedes Mal an der gleichen 
Stelle des Bildschirms und jedes Mal ändern wir die Maske, um eine zusätzliche
Pixelspalte zu zeigen.
In der Praxis machen wir die Kopie zum ersten Mal mit der Maske die den Wert
%10000000.00000000 hat, um nur die erste Pixelspalte anzuzeigen.
Der zweite Blitt befindet sich dann in derselben Position wie der vorherige
überschreibt aber, was wir beim ersten Mal gezeichnet haben. Als Maske benutzen 
wir den Wert %11000000.00000000. Sie sehen also nur die ersten beiden Spalten
von Pixeln. Das dritte Mal benutzen wir als Maske %11100000.00000000 und 
zeichnen die ersten 3 Spalten von Pixeln und so weiter. Das 16. Mal benutzen 
wir als Maske %11111111.11111111, um alle 16 Pixelspalten zu zeichnen, die die
Wortspalte ausmachen. 
An diesem Punkt Zeichnen wir wieder vom Anfang. Also verschieben wir die erste
Pixelspalte zur nächsten Wortspalte, ein Wort nach rechts, sowohl in der Quelle
als auch im Ziel und beginnen mit der Maske mit dem Wert %10000000.00000000 von
vorne. Weil unsere Blitts nur ein Wort breit sind, werden die vorherigen 
Wortspalten nicht überschrieben. Deshalb bleiben sie gezeichnet.
Beachten Sie, wie sie die Maskenwerte erhalten. Am Anfang setzen sie den 
Startwert (%10000000.00000000) in das Register d0. Dieses Register wird nach
BLTALWM kopiert, so dass der erste Blitt nur in der ersten Pixelspalte passiert.
Nach dem Blitt wird ein ASR #1,d0 ausgeführt. Wie Sie wissen, verschiebt diese
Anweisung den Inhalt des Registers d0 nach rechts. Außerdem (im Gegensatz zu
LSR) bewahrt es das Zeichen, das Bit ganz links (das ist das Vorzeichenbit) bei
der Verschiebung. In diesem Fall ist das Vorzeichenbit 1, also kommt ganz links
eine 1. Auf diese Weise nimmt das Register d0 den Wert %11000000.00000000 an.
Dieser Wert wird als eine Maske für den zweiten Blitt verwendet und dann wird
der nächste ASR durchgeführt was d0 auf den Wert %11100000.00000000 bringt.
Dieser Vorgang wird wiederholt. Bei jeder Iteration werden alle Werte der Maske 
generiert. Weitere Erläuterungen zu ASR finden Sie in der Lektion 68000-2.TXT.