
; Listing17c.s = plasma1.s
; Plasma1.s	Plasma 0-Bitplanes
; linke Taste zum Beenden

	SECTION	PLASMA,CODE

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

*****************************************************************************
	incdir ""
	include	"/Sources/startup2.s"		; speichern Copperlist etc.
*****************************************************************************

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

WaitDisk	equ	10

WidthPlasma	equ	30				; Plasmabreite ausgedrückt
								; als Anzahl der Gruppen von 8 Pixeln

BytesPerLine	equ	(WidthPlasma+2)*4	; Anzahl der belegten Bytes
								; in der Copperliste von jeder Zeile
								; des Plasmas: jede 
								; Copper Anweisung belegt 4 Bytes

HighPlasma	equ	100				; Plasmahöhe ausgedrückt
								; als Anzahl der Zeilen

NewLine	equ	4					; Wert hinzufügen zum Index in der
								; SinTab zwischen einer Zeile und einer anderen
								; Es kann zum Erhalten von verschiedener Plasmen 
								; variiert werden, aber es MUSS IMMER GERADE SEIN !!

NewFrame	equ	6				; Wert abziehen vom Index in der
								; SinTab zwischen einem Frame und einem anderen
								; Es kann zum Erhalten von verschiedener Plasmen 
								; variiert werden, aber es MUSS IMMER GERADE SEIN !!

Start:
	lea	$dff000,a5				; Custom Register Base in a5

	bsr.s	InitPlasma			; initialisiert die Copperlist

; Initialisieren der Blitter-Register

	btst	#6,2(a5)
WaitBlitInit:
	btst	#6,2(a5)			; auf den Blitter warten
	bne.s	WaitBlitInit

	move.l	#$09f00000,$40(a5)	; BLTCON0/1 - Kopie normal
	moveq	#-1,d0				; d0 = $FFFFFFFF
	move.l	d0,$44(a5)			; BLTAFWM/BLTALWM

mod_A	set	0					; modulo Kanal A
mod_D	set	BytesPerLine-2		; modulo Kanal D: geht zur nächsten Zeile
	move.l	#mod_A<<16+mod_D,$64(a5)	; modulo Register laden

	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"

; Initialisieren der anderen Hardwareregister

	move.w	#$000,$180(a5)		; COLOR00 - schwarz
	move.w	#$0200,$100(a5)		; BPLCON0 - keine Bitplanes aktiviert

Mouse:
	move.l	#$1ff00,d1			; Bits durch UND auswählen
	move.l	#$13000,d2			; warte auf Zeile $130 (304)
WaitY1:
	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 $130 (304)
	bne.s	WaitY1

	bsr	DoPlasma

	btst	#6,$bfe001			; Maus gedrückt?
	bne.w	Mouse

	rts

;****************************************************************************
; Diese Routine initialisiert die Copperliste, die das Plasma erzeugt. System
; WAIT Anweisungen und die erste Hälfte des COPPERMOVE. Am Ende der Zeile
; des Plasmas wird ein letzter COPPERMOVE eingefügt, der die Farbe
; schwarz in COLOR00 lädt.
;****************************************************************************

InitPlasma:
	lea	Plasma,a0				; Adresse Plasma
	move.l	#$6051fffe,d0		; lädt die erste wait-Anweisung in d0.
								; warte in Zeile $60 und in horizontaler 
								; Position $50
	move.w	#$180,d1			; setzt die erste Hälfte einer Anweisung in d1
								; "Copper move" in COLOR00 (=$dff180)

	moveq	#HighPlasma-1,d3	; Schleife für jede Zeile
InitLoop1:
	move.l	d0,(a0)+			; schreibt die WAIT
	add.l	#$01000000,d0		; Wait ändern, um in der
								; nächsten Zeile zu warten

	moveq	#WidthPlasma,d2		; Schleifen über die gesamte Breite
								; von Plasma + einmal für
								; den letzten "Copper move" setzt
								; schwarz als Hintergrund zurück

InitLoop2:
	move.w	d1,(a0)+			; schreibt den ersten Teil des
								; "Copper move"
	addq.l	#2,a0				; Platz für den zweiten Teil
								; des "Copper move"
								; (dann gefüllt durch Routine DoPlasma)
	dbra	d2,InitLoop2
	dbra	d3,InitLoop1
	
	rts


;****************************************************************************
; Diese Routine macht das Plasma. Sie macht jeweils eine Schleife von Blitts
; bei denen es eine "Spalte" des Plasmas schreibt, das heißt, es schreibt
; die Farben in die COPPERMOVES-Spalte.
; Die Farben die in jede Spalte geschrieben werden, werden aus einer Tabelle
; gelesen; beginnend mit einer Adresse, die je nach Versatz von Spalte zu Spalte
; variiert basierend auf einen Offset, der aus einer anderen Tabelle gelesen wird.
; Weiterhin variieren die Offsets zwischen einem Frame und einem anderen
; um den Effekt der Bewegung zu realisieren.
;****************************************************************************

DoPlasma:
	lea	Color,a0				; Adresse Farbe
	lea	SinTab,a3				; Adresse Tabelle offsets
	lea	Plasma+6,a1				; Adresse erstes word der ersten
								; Spalte des Plasmas

	move.w	Index(pc),d0		; liest den Startindex vom
								; vorherigen Frame
	sub.w	#NewFrame,d0		; den Index in der Tabelle
								; aus dem vorherigen Frame ändern 
	and.w	#$00ff,d0			; hält den Index im Bereich
								; 0 - 255 (Versatz in einer Tabelle von
								; 128 Wörter)
	move.w	d0,Index			; speichert den Startindex für
								; das nächste Bild

	move.w	#HighPlasma<<6+1,d3	; Größe Blitt
								; Breite 1 word, Höhe gesamtes Plasma

	moveq	#WidthPlasma-1,d2	; Schleifen über die gesamte Breite
PlasmaLoop:						; Anfang loop Blitt

	move.w	(a3,d0.w),d1		; liest Offset aus der Tabelle

	lea	(a0,d1.w),a2			; Startadresse = Adr. Farben
								; mehr Offset

	btst	#6,2(a5)
WaitBlit:
	btst	#6,2(a5)			; auf den Blitter warten 
	bne.s	WaitBlit

	move.l	a2,$50(a5)			; BLTAPT - Adresse Quelle
	move.l	a1,$54(a5)			; BLTDPT - Adresse Ziel
	move.w	d3,$58(a5)			; BLTSIZE

	addq.w	#4,a1				; zeigt auf die nächste Spalte von
								; "Copper moves" in der Copperlist

	add.w	#NewLine,d0			; den Index in der Tabelle
								; für die nächste Zeile ändern 

	and.w	#$00ff,d0			; hält den Index im Bereich
								; 0 - 255 (offset in einer Tabelle mit
								; 128 words)
	
	dbra	d2,PlasmaLoop
	rts


; Diese Variable enthält den Indexwert für die erste Spalte

Index:	dc.w	0

; Diese Tabelle enthält die Offsets für die Startadresse in der
; Farbtabelle
SinTab:
	dc.w	$0034,$0036,$0038,$003a,$003c,$0040,$0042,$0044,$0046,$0048
	dc.w	$004a,$004c,$004e,$0050,$0052,$0054,$0056,$0058,$005a,$005a
	dc.w	$005c,$005e,$005e,$0060,$0060,$0062,$0062,$0062,$0064,$0064
	dc.w	$0064,$0064,$0064,$0064,$0064,$0064,$0062,$0062,$0062,$0060
	dc.w	$0060,$005e,$005e,$005c,$005a,$005a,$0058,$0056,$0054,$0052
	dc.w	$0050,$004e,$004c,$004a,$0048,$0046,$0044,$0042,$0040,$003c
	dc.w	$003a,$0038,$0036,$0034,$0030,$002e,$002c,$002a,$0028,$0024
	dc.w	$0022,$0020,$001e,$001c,$001a,$0018,$0016,$0014,$0012,$0010
	dc.w	$000e,$000c,$000a,$000a,$0008,$0006,$0006,$0004,$0004,$0002
	dc.w	$0002,$0002,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
	dc.w	$0002,$0002,$0002,$0004,$0004,$0006,$0006,$0008,$000a,$000a
	dc.w	$000c,$000e,$0010,$0012,$0014,$0016,$0018,$001a,$001c,$001e
	dc.w	$0020,$0022,$0024,$0028,$002a,$002c,$002e,$0030
EndSinTab:

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

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$4007,$fffe			; warte auf Zeile $40
	dc.w	$0180,$c00			; color0
	dc.w	$4407,$fffe			; warte auf Zeile $44
	dc.w	$0180,$000			; color0

; Hier bleibt etwas Platz für das Stück Copperliste, dass das Plasma erzeugt.
; Dieser Raum wird von den Routinen die den Effekt erstellen ausgefüllt.

Plasma:
	dcb.b	HighPlasma*BytesPerLine,0

	dc.w	$e007,$fffe			; warte auf Zeile $e0
	dc.w	$0180,$c00			; color0
	dc.w	$e407,$fffe			; warte auf Zeile $e4
	dc.w	$0180,$000			; color0

	dc.w	$ffff,$fffe			; Ende der Copperlist


;****************************************************************************
; Hier ist die Farbtabelle, die in das Plasma geschrieben wird.
; Es müssen genügend Farben vorhanden sein, um die Adresse des Starts
; lesen zu können. In diesem Beispiel kann die Startadresse von 
; der "Farbe" (erste Farbe) bis "Farbe + 100" (50. Farbe) abweichen, weil
; 100 der maximale Offset ist, der in der "SinTab" enthalten ist.
; Wenn HighPlasma = 100 ist, bedeutet dies, dass jeder Blitt 100 Farben liest.
; Insgesamt müssen also 150 Farben vorhanden sein.
;****************************************************************************

Color:
	dc.w	$100,$200,$300,$400,$500,$600,$700
	dc.w	$800,$900,$a00,$b00,$c00,$d00,$e00,$f00

	dc.w	$f00,$e00,$d00,$c00,$b00,$a00,$900,$800
	dc.w	$700,$600,$500,$400,$300,$200

	dc.w	$002,$003,$004,$005,$006,$007
	dc.w	$008,$009,$00a,$00b,$00c,$00d,$00e,$00f

	dc.w	$00e,$01d,$02d,$03d,$04d,$05d,$06d,$07d,$08d,$09d	; blau grün
	dc.w	$0ad,$0bd,$0cd,$0dd,$0ed,$0fd,$0fd,$0ed,$0dd,$0cd
	dc.w	$0bd,$0ad,$09d,$08d,$07d,$06d,$05d,$04d,$03d,$02d
	dc.w	$01d,$00e

	dc.w	$00e,$01d,$02c,$03b,$04a,$059,$068,$077,$086,$095	; blau grün
	dc.w	$0a4,$0b3,$0c2,$0d1,$0e0


	dc.w	$0f0,$0e0,$0d0,$0c0,$0b0,$0a0,$090,$080
	dc.w	$070,$060,$050,$040,$030,$020,$010

	dc.w	$010,$020,$030,$040,$050,$060,$070
	dc.w	$080,$090,$0a0,$0b0,$0c0,$0d0,$0e0,$0f0

	dc.w	$1f0,$2f0,$3f0,$4f0,$5f0,$6f0,$7f0,$8f0
	dc.w	$9f0,$af0,$bf0,$cf0,$df0,$ef0,$ff0

	dc.w	$ff0,$ee0,$dd0,$cc0,$bb0,$aa0,$990,$880
	dc.w	$770,$660,$550,$440,$330,$220,$110

	end

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

In diesem Beispiel haben wir eine Plasma-0-Bitebene.
Der Effekt basiert auf einer Copperliste, die von der Routine "InitPlasma"
erstellt wird. Das Stück funktioniert so: Für jede Zeile auf dem Bildschirm
werden eine Reihe von "Copper moves" ausgeführt, die den Wert von COLOR00
ändern. Der letzte "Copper move" setzt den Wert von $000 (schwarz) wieder in
COLOR00. Dadurch wird eine rechteckige Tabelle mit "Copper moves" erstellt.
Die Anzahl der "Copper moves" die in jeder Zeile vorhanden sind (mit Ausnahme
der letzten, welche den Hintergrund auf schwarz setzt) entspricht dem Wert des
Parameters "WidthPlasma". Die Anzahl der Zeilen, die das Plasma bilden, 
entspricht dem Parameter "HighPlasma". Insgesamt haben wir also eine Reihe von
"Copper moves" (immer ohne diejenigen, die schwarz ersetzen) gleich
WidthPlasma * HighPlasma. Die Routine "InitPlasma" schreibt keine Farben
die durch diese "Copper moves" geladen würden (dh es werden nicht die zweiten
Wörter geschrieben).
Diese Aufgabe bleibt der Routine "DoPlasma" überlassen, die in jedem frame
ausgeführt wird, und die jedes Mal unterschiedliche Werte in die zweiten Wörter
von "Copper move" schreibt. Das Schreiben erfolgt über eine Blitter Schleife.
Jeder Blitt füllt eine "Spalte" mit "Copper moves". Zum Beispiel der erste 
Blitt schreibt jeweils das zweite Wort der ersten "Copper moves" von jeder 
Zeile. Die Farbwerte werden aus einer Tabelle gelesen. Bei jeder Iteration
werden die Farben von einer anderen Position aus der Tabelle gelesen. Auch
zwischen einem Frame und einem anderen wird die Startposition geändert. Alle
Variationen der Position erfolgen auf der Grundlage von Tabellen und können
durch Einwirken auf die 2 Parameter "NewLine" und "NewFrame"variiert
werden. Beachten Sie, dass die Routine durch die Initialisierung aller 
Register des Blitters zu Beginn des Programms optimiert wurde.