
; Listing17c3.s = plasma3.s
; Plasma3.s	Plasma RGB mit 0-Bitplanes
; rechte Taste zum Aktivieren der Welligkeit, linke Taste zum Beenden

	SECTION	PLASMA,CODE

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

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

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

WaitDisk	equ	10

WidthPlasma	equ	48				; Plasmabreite ausgedrückt
								; als Anzahl der Gruppen von 8 Pixeln
								; das Plasma ist größer als der Bildschirm

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	190				; Plasmahöhe ausgedrückt
								; als Anzahl der Zeilen

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

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

NewLineG	equ	2				; wie "NewLineR" aber für Komponente G
NewFrameG	equ	8				; wie "NewFrameR" aber für Komponente G

NewLineB	equ	8				; wie "NewLineR" aber für Komponente B
NewFrameB	equ	4				; wie "NewFrameR" aber für Komponente B

NewLineO	equ	4				; wie "NewLineR" aber für Oszillation
NewFrameO	equ	2				; wie "NewFrameR" aber für Oszillation


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

	bsr	InitPlasma				; initialisiert die Copperlist

; Blitter Register initialisieren

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

	move.l	#$4ffe8000,$40(a5)	; BLTCON0/1 - D=A+B+C
								; shift A = 4 pixel
								; shift B = 8 pixel
					
	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

; modulo Kanäle B und C = 0

	moveq	#0,d0
	move.l	d0,$60(a5)			; schreibt BLTBMOD und BLTCMOD

; Hardware-Register initialisieren

	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Bitplane, Copper
	move.l	#Copperlist1,$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	#$000,$180(a5)		; COLOR00 - schwarz
	move.w	#$0200,$100(a5)		; BPLCON0 - keine Bitplanes aktiviert

; erste Schleife: ohne horizontalen Schwung

Mouse1:
	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	SwapClists			; Copperlist austauschen

	bsr	DoPlasma				; Routine Plasma

	btst	#2,$dff016			; rechte Maustaste gedrückt?
	bne.s	Mouse1

; zweite Schleife: mit horizontalem Schwung

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

	bsr	SwapClists				; Copperlist austauschen

	bsr	DoHoriz					; horizontaler Swing-Effekt
	bsr	DoPlasma

	btst	#6,$bfe001			; Maus gedrückt?
	bne.s	Mouse2

	rts

;****************************************************************************
; Diese Routine realisiert den horizontalen Schwingeffekt.
; Der Effekt wird durch Ändern der horizontalen Position auf jeder Linie erreicht
; des Beginns des Plasmas, das ist die horizontale Position des beginnenden WAIT
; der Linie. Die Positionswerte werden aus einer Tabelle gelesen.
;****************************************************************************

DoHoriz:
	lea	HorizTab(pc),a0			; Adresse Tabelle Oszillation
	move.l	DrawClist(pc),a1	; Adresse Copperlist schreiben
	addq.w	#1,a1				; Adresse zweites Byte des ersten
								; Wortes des Waits
; liest und ändert den Index

	move.w	IndexO(pc),d4		; liest den Startindex vom
								; vorherigen frame
	sub.w	#NewFrameO,d4		; Ändern des Index in der Tabelle
								; aus dem vorherigen Frame
	and.w	#$007f,d4			; hält den Index im Bereich
								; 0 - 127 (Offset in einer Tabelle von
								; 128 Byte)
	move.w	d4,IndexO			; speichert den Startindex für
								; den nächsten frame

	move.w	#HighPlasma-1,d3		; Schleife für jede Reihe
HorizLoop:
	move.b	0(a0,d4.w),d0		; Oszillationswert ablesen
	or.b	#$01,d0				; Bit 0 auf 1 setzen (notwendig
								; für WAIT-Anweisung)
	move.b	d0,(a1)				; schreibt die horizontale Position
								; von WAIT in der Copperliste

	lea	BytesPerLine(a1),a1		; zeigt auf die nächste Zeile
								; in der Copperliste
; Index für nächste Zeile bearbeiten

	add.w	#NewLineO,d4		; Ändern Sie den Index in der Tabelle
								; für die nächste Zeile

	and.w	#$007f,d4			; hält den Index im Bereich
								; 0 - 127 (Offset in einer Tabelle von
								; 128 Byte)
	dbra	d3,HorizLoop
	rts

;****************************************************************************
; Diese Routine realisiert den "double buffer" zwischen den Copperlisten.
; In der Praxis beginnt es, wo es gezeichnet wird, und visualisiert
; es durch Kopieren der Adresse in COP1LC. Tauschen Sie die Variablen so aus,
; dass im folgenden frame auf der anderen Copperlist gezeichnet wird. 
;****************************************************************************

SwapClists:
	move.l	DrawClist(pc),d0	; Adresse clist auf dem es geschrieben steht
	move.l	ViewClist(pc),DrawClist	; austauschen clists
	move.l	d0,ViewClist

	move.l	d0,$80(a5)			; kopiere die Adresse der Copperlist
								; in COP1LC damit es
								; im nächsten Frame angezeigt wird
	rts


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

InitPlasma:
	lea	Copperlist1,a0			; Adresse Copperlist 1
	lea	Copperlist2,a1			; Adresse Copperlist 2
	move.l	#$3025fffe,d0		; lädt die erste wait-Anweisung in d0.
								; warte auf Zeile $30 und Position
								; horizontal $24
	move.w	#$180,d1			; setzt die erste Hälfte einer Anweisung in d1
								; "Copper move" in COLOR00 (= $dff180)

	move.w	#HighPlasma-1,d3	; Schleife für jede Zeile
InitLoop1:
	move.l	d0,(a0)+			; schreibt das WAIT - (clist 1)
	move.l	d0,(a1)+			; schreibt das WAIT - (clist 2)
	add.l	#$01000000,d0		; WAIT ändern, um in
								; der folgenden Zeile zu warten

	moveq	#WidthPlasma,d2		; Schleife über die gesamte Breite
								; von Plasma + einmal pro
								; der letzte "Copper move" setzt
								; schwarz als Hintergrund zurück

InitLoop2:
	move.w	d1,(a0)+			; schreibt den ersten Teil des
								; "Copper move" - clist 1
	addq.w	#2,a0				; Platz für den zweiten Teil
								; des "Copper move" - clist 1

	move.w	d1,(a1)+			; schreibt den ersten Teil des
								; "Copper move" - clist 2
	addq.w	#2,a1				; Platz für den zweiten Teil
								; des "Copper move" - clist 2

	dbra	d2,InitLoop2
	dbra	d3,InitLoop1
	rts

;****************************************************************************
; Diese Routine macht das Plasma. Es macht jeweils eine Schleife von Blitts
; bei denen es eine "Zeile" des Plasmas schreibt, das heißt, es schreibt
; die Farben in die COPPERMOVES-Spalte.
; Die in jeder Spalte geschriebenen Farben werden aus einer Tabelle gelesen,
; beginnend mit einer Adresse, die von einer Spalte zur anderen variiert,
; basierend auf Offsets aus einer anderen Tabelle lesen.
; Auch zwischen einem frame und einem anderen variieren die Offsets um
; den Effekt der Bewegung zu realisieren.
;****************************************************************************

DoPlasma:
	lea	Color,a0				; Adresse Farben
	lea	SinTab,a6				; Adresse Tabelle offsets
	move.l	DrawClist(pc),a1	; Adresse Copperlist schreiben
	addq.w	#6,a1				; Adresse erstes Wort der ersten
								; Plasmasäule
; liest und ändert den Index der Komponente R

	move.w	IndexR(pc),d4		; liest den Startindex vom
								; vorherigen frame
	sub.w	#NewFrameR,d4		; den Index in der Tabelle
								; aus dem vorherigen Frame ändern
	and.w	#$00ff,d4			; hält den Index im Bereich
								; 0 - 255 (Offset in einer Tabelle von
								; 128 words)
	move.w	d4,IndexR			; speichert den Startindex für
								; das nächste Bild
; liest und ändert den Index der Komponente G

	move.w	IndexG(pc),d5		; liest den Startindex vom
								; vorherigen Frame
	sub.w	#NewFrameG,d5		; den Index in der Tabelle
								; aus dem vorherigen Frame ändern
	and.w	#$00ff,d5			; hält den Index im Bereich
								; 0 - 255 (Offset in einer Tabelle von
								; 128 words)
	move.w	d5,IndexG			; speichert den Startindex für
								; das nächste Bild
; liest und ändert den Index der Komponente B

	move.w	IndexB(pc),d6		; liest den Startindex vom
								; vorherigen Frame
	sub.w	#NewFrameB,d6		; den Index in der Tabelle
								; aus dem vorherigen Frame ändern
	and.w	#$00ff,d6			; hält den Index im Bereich
								; 0 - 255 (Offset in einer Tabelle von
								; 128 words)
	move.w	d6,IndexB			; 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	; Schleife über die gesamte Breite
PlasmaLoop:						; Startschleife Blitt

; Startadresse der Komponente R berechnen

	move.w	(a6,d4.w),d1		; liest Offset aus der Tabelle

	lea	(a0,d1.w),a2			; Startadresse = Farben
								; mehr Offset
; Startadresse der Komponente G berechnen

	move.w	(a6,d5.w),d1		; liest Offset aus der Tabelle

	lea	(a0,d1.w),a3			; Startadresse = Farben
								; mehr Offset
; Startadresse der Komponente B berechnen

	move.w	(a6,d6.w),d1		; liest Offset aus der Tabelle

	lea	(a0,d1.w),a4			; Startadresse = Farben
								; mehr Offset
	btst	#6,2(a5)
WaitBlit:
	btst	#6,2(a5)			; auf den Blitter warten
	bne.s	WaitBlit

	move.l	a2,$48(a5)			; BLTCPT - Adresse Quelle R
	move.l	a3,$50(a5)			; BLTAPT - Adresse Quelle G
	move.l	a4,$4c(a5)			; BLTBPT - Adresse Quelle B
	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 Copperliste
; Ändern Index Komponente R für die nächste Zeile

	add.w	#NewLineR,d4		; Ändern des Index in der Tabelle
								; für die nächste Zeile

	and.w	#$00ff,d4			; hält den Index im Bereich
								; 0 - 255 (Offset in einer Tabelle von
								; 128 Wörter)
; Ändern Index Komponente G für die nächste Zeile

	add.w	#NewLineG,d5		; Ändern des Index in der Tabelle
								; für die nächste Zeile
	
	and.w	#$00ff,d5			; hält den Index im Bereich
								; 0 - 255 (Offset in einer Tabelle von
								; 128 Wörter)

; Ändern Index Komponente B für die nächste Zeile

	add.w	#NewLineB,d6		; Ändern des Index in der Tabelle
								; für die nächste Zeile

	and.w	#$00ff,d6			; hält den Index im Bereich
								; 0 - 255 (Offset in einer Tabelle von
								; 128 Wörter)
	dbra	d2,PlasmaLoop
	rts


; Diese 2 Variablen enthalten die Adressen der 2 Copperlisten

ViewClist:	dc.l	Copperlist1	; Adresse clist Visualisierung
DrawClist:	dc.l	Copperlist2	; Adresse clist Zeichnen

; Diese Variable enthält den Wert des Index in der Tabelle von
; Schwingungen (horizontale Positionen der WAITs)

IndexO:	dc.w	0

; Diese Tabelle enthält die Werte der Schwingungen (horizontale Positionen
; von WAIT)

HorizTab:
	dc.b	$2c,$2c,$2c,$2e,$2e,$2e,$2e,$2e,$30,$30,$30,$30,$30,$30,$32,$32
	dc.b	$32,$32,$32,$32,$32,$32,$34,$34,$34,$34,$34,$34,$34,$34,$34,$34
	dc.b	$34,$34,$34,$34,$34,$34,$34,$34,$34,$34,$32,$32,$32,$32,$32,$32
	dc.b	$32,$32,$30,$30,$30,$30,$30,$30,$2e,$2e,$2e,$2e,$2e,$2c,$2c,$2c
	dc.b	$2c,$2c,$2c,$2a,$2a,$2a,$2a,$2a,$28,$28,$28,$28,$28,$28,$26,$26
	dc.b	$26,$26,$26,$26,$26,$26,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
	dc.b	$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$26,$26,$26,$26,$26,$26
	dc.b	$26,$26,$28,$28,$28,$28,$28,$28,$2a,$2a,$2a,$2a,$2a,$2c,$2c,$2c

; Diese Variablen enthalten die Indexwerte für die erste Spalte

IndexR:	dc.w	0
IndexG:	dc.w	0
IndexB:	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

; Wir haben 2 copperlists 

Copperlist1:

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

	dcb.b	HighPlasma*BytesPerLine,0
	dc.w	$ffff,$fffe			; Ende Copperlist

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

Copperlist2:

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

	dcb.b	HighPlasma*BytesPerLine,0

	dc.w	$ffff,$fffe			; Ende 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 = 190 ist, bedeutet dies, dass jeder Blitt 190 Farben liest.
; Insgesamt müssen also 240 Farben vorhanden sein.
;****************************************************************************

Color:
	dc.w	$0f00,$0f00,$0e00,$0e00,$0e00,$0d00,$0d00,$0d00
	dc.w	$0c00,$0c00,$0c00,$0b00,$0b00,$0b00,$0a00,$0a00,$0a00
	dc.w	$0900,$0900,$0900,$0800,$0800,$0800,$0700,$0700,$0700
	dc.w	$0600,$0600,$0600,$0500,$0500,$0500,$0400,$0400,$0400
	dc.w	$0300,$0300,$0300,$0200,$0200,$0200,$0100,$0100,$0100
	dcb.w	18,0
	dc.w	$0100,$0100,$0100,$0100,$0200,$0200,$0200,$0200
	dc.w	$0300,$0300,$0300,$0300,$0400,$0400,$0400,$0400
	dc.w	$0500,$0500,$0500,$0500,$0600,$0600,$0600,$0600
	dc.w	$0700,$0700,$0700,$0700,$0800,$0800,$0800,$0800
	dc.w	$0900,$0900,$0900,$0900,$0a00,$0a00,$0a00,$0a00
	dc.w	$0b00,$0b00,$0b00,$0b00,$0c00,$0c00,$0c00,$0c00
	dc.w	$0d00,$0d00,$0d00,$0d00,$0e00,$0e00,$0e00,$0e00
	dc.w	$0f00,$0f00,$0f00,$0f00

	dc.w	$0f00,$0f00,$0f00,$0f00,$0e00,$0e00,$0e00,$0e00
	dc.w	$0d00,$0d00,$0d00,$0d00,$0c00,$0c00,$0c00,$0c00
	dc.w	$0b00,$0b00,$0b00,$0b00,$0a00,$0a00,$0a00,$0a00
	dc.w	$0900,$0900,$0900,$0800,$0800,$0800,$0800
	dc.w	$0700,$0700,$0700,$0700,$0600,$0600,$0600,$0600
	dc.w	$0500,$0500,$0500,$0500,$0400,$0400,$0400,$0400
	dc.w	$0300,$0300,$0300,$0300,$0200,$0200,$0200,$0200
	dc.w	$0100,$0100,$0100
	dcb.w	18,0
	dc.w	$0100,$0100,$0100,$0200,$0200,$0200,$0300,$0300,$0300
	dc.w	$0400,$0400,$0400,$0500,$0500,$0500,$0600,$0600,$0600
	dc.w	$0700,$0700,$0700,$0800,$0800,$0900,$0900,$0900
	dc.w	$0a00,$0a00,$0a00,$0b00,$0b00,$0b00,$0c00,$0c00,$0c00
	dc.w	$0d00,$0d00,$0d00,$0e00,$0e00,$0e00,$0f00

	end

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

In diesem Beispiel wird ein RGB-Plasma pro Spalte hergestellt (d.h. die Farben)
werden spaltenweise in die Copperliste eingefügt (geblittet), zu der wir eine
horizontale Schwingung hinzufügen. Bei Ausführen des Programms ist der
Schwingeffekt nicht aktiv. Durch Drücken der rechten Taste wird es aktiviert.
Um die Schwingung zu realisieren, benötigt man ein Plasma, das größer als der
Bildschirm ist, wodurch es nur teilweise sichtbar ist. Durch Variation der
Startposition von jeder Zeile (dh die horizontale Position des WAIT am Anfang
der Zeile), können Sie verschiedene Bereiche des Plasmas zeigen. Im Programm
ist jeder Zeile eine andere Startposition zugeordnet, die aus einer Sinus-
Tabelle gelesen wird. Das Lesen von der Tabelle erfolgt auf die gleiche Weise
wie für Tabellen der Komponenten R, G, B. 
Die Indizes, denen sie ausgesetzt sind, können durch Änderung der Parameter 
die am Anfang des Listings stehen, variiert werden. Dieser Effekt hat eine
gute visuelle Wiedergabe bei den "NewRigaX" -Parametern der Komponenten
R, G, B niedrige Werte annehmen. Durch Erhöhen dieser Werte (zB 20) Die
Grenzen dieses Effekts sind hervorgehoben. Speziell die horizontale Welligkeit
erfolgt in Schritten von 4 Pixeln, der minimalen Auflösung des WAITs. Wir
werden später sehen, wie man weniger gezackte Wellen erreicht.

