
;  Listing11l1.s - ändere COLOR00 und BPLCON1 in jeder Zeile ($dff102)

	SECTION	COPPERADVANCED,CODE

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

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

			;5432109876543210
DMASET	equ	%1000001110000000	; nur Copper und Bitplane DMA

WAITDISK	equ	30				; 50-150 zur Rettung (je nach Fall)

SCRBYTES	= 40				; Anzahl der Bytes für jede horizontale Zeile
								; Daraus berechnen wir die Bildschirmbreite,
								; multiplizieren von Bytes mit 8: normaler Bildschirm 320/8 = 40
								; zB für einen 336 Pixel breiten Bildschirm 336/8 = 42
								; Beispielbreiten:
								; 264 pixel = 33 / 272 pixel = 34 / 280 pixel = 35
								; 360 pixel = 45 / 368 pixel = 46 / 376 pixel = 47
								; ... 640 pixel = 80 / 648 pixel = 81 ...

SCR_H		= 256				; Bildschirmhöhe in Zeilen
SCR_X		= $81				; Startbildschirm, XX-Position (normal $xx81) (129)
SCR_Y		= $2c				; Startbildschirm, YY-Position (normal $2cxx) (44)
SCR_RES		= 1					; 2 = HighRes (640*xxx) / 1 = LowRes (320*xxx)
SCR_LACE	= 0					; 0 = non interlace (xxx*256) / 1 = interlace (xxx*512)
HAM			= 0					; 0 = nicht HAM / 1 = HAM
SCR_BPL		= 1					; Anzahl Bitplanes

; Parameter automatisch berechnet

SCR_W		= SCRBYTES*8		; Bildschirmbreite
SCR_SIZE	= SCRBYTES*SCR_H	; Größe des Bildschirms in Bytes 
BPLC0		= ((SCR_RES&2)<<14)+(SCR_BPL<<12)+$200+(SCR_LACE<<2)+(HAM<<11)		; BPLCON0
DIWS		= (SCR_Y<<8)+SCR_X													; DIWSTRT
DIWST		= ((SCR_Y+SCR_H/(SCR_LACE+1))&255)<<8+(SCR_X+SCR_W/SCR_RES)&255		; DIWSTOP
DDFS		= (SCR_X-(16/SCR_RES+1))/2											; DDFSTRT
DDFST		= DDFS+(8/SCR_RES)*(SCRBYTES/2-SCR_RES)								; DDFSTOP

Start:
;	 ZEIGER Bitplane

	move.l	#Bitplane,d0
	lea	Bplpointers,a1
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	lea	$dff000,a5
	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"

	move.w	#11,CouNumLoop1
	move.w	#2,Counter1
	clr.w	Counter2

Mouse:
	move.l	#$1ff00,d1			; Bit zur Auswahl durch UND
	move.l	#$12c00,d2			; warte auf Zeile $12c
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 $12c
	bne.s	WarteY1
WarteY2:
	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 $12c
	beq.s	WarteY2

	btst.b	#2,$dff016
	beq.s	NoEff
	bsr.s	Mainroutine			; färbt die Farben und rollt den BPLCON1
NoEff:
	bsr.w	PrintCharacter		; Drucken Sie jeweils ein Zeichen

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

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

; Diese Routine ist nicht optimiert. Sie könnten eine optimierte Routine erstellen,
; die eine Copperliste erstellt, die am Anfang aufgerufen wird, dann eine 
; andere welche nur die Werte von COLOR01 und BPLCON1 ändert.
; Es ist langsam, weil ein System verwendet wurde, was es noch schlimmer machte, aber
; in bestimmten Fällen kann es nützlich sein: Um durch die Tabellen zu 
; "scrollen", wird ein Puffer verwendet, in der die Tabelle selbst gedreht und
; kopiert wird. Dann werden aus dieser Tabelle die Werte wieder in die Starttabelle 
; kopiert. Aber wurde es vorher ohne den Puffer gemacht? Ja!
; Stellen Sie sich eine Routine mit vielen Tabellen vor, die Werte der verschiedenen
; Phasen der Rotation enthalten können. In diesem Fall könnten wir "vorberechnen".
; In vielen Tabellen wurden die Werte in jeder Phase gedreht ... aber vielleicht 
; würden Sie bekommen so, wenig Optimierung das wäre es nicht wert ...
; Kurz schau dir die Routine an, es ist "seltsam" und verwickelt sich wirklich 
; umsonst "alternative" Techniken zu zeigen ... (übertrieben .. das wars!).

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

;	    ______
;	  .//_____\,
;	   \\ ¦.¦ /
;	   _\\_-_/_. dA!
;	  ( /  :  \ \
;	 / /   :   \ \
;	 \,_,_,:,_,_\/`).
;	   |   |   | (//\\
;	.-./,,_|__,,\.-. \\
;	`------`-------'  `

MainRoutine:
	move.l	a5,-(sp)			; speichern a5
	subq.w	#1,Counter1			; markieren Sie diese Ausführung
	tst.w	Counter1			; 2 Frame Vergangenheit?
	bne.w	JumpRoll			; Wenn noch nicht, nicht rollen
	move.w	#2,Counter1			; beginne erneut und warte 2 Frames
	cmp.w	#15,Counter2		; letzte 15 Frames?
	beq.s	Roll2
	addq.w	#1,CouNumLoop1
	cmp.w	#30,CouNumLoop1		; sind 30 Schleifen zu tun?
	bne.s	GoARoll				; wenn noch nicht ok
	move.w	#15,Counter2		; andernfalls Counter2=15
	bra.s	GoARoll
Roll2:
	subq.w	#1,CouNumLoop1		; sub
	cmp.w	#3,CouNumLoop1		; sind wir bei 3?
	bne.s	GoARoll				; Wenn noch nicht
	clr.w	Counter2			; andernfalls wird es zurückgesetzt
GoARoll:
	lea	ColTab(pc),a0			; Tabelle mit Farben
	lea	TabBuf(pc),a1			; Puffer
	move.w	(a0)+,d0			; erste Farbe in d0
CopyColTabLoop:
	move.w	(a0)+,d1			; Nächste Farbe in d1
	cmp.w	#-2,d1				; Ende Tabelle?
	beq.s	EndTabCol			; Wenn ja, ist die Runde beendet
	move.w	d1,(a1)+			; Wenn nicht, legen Sie diese Farbe in den TabBuf
	bra.s	CopyColTabLoop

EndTabCol:
	move.w	d0,(a1)+			; Setze die erste Farbe als letzte ein
	move.w	#-2,(a1)+			; Und setzen Sie das Endezeichen der Tabelle
	lea	ColTab(pc),a0			; Farbtabelle
	lea	TabBuf(pc),a1			; Puffer
RecopyInColTabLoop:
	move.w	(a1)+,d0			; Farbe kopieren von TabBuf
	move.w	d0,(a0)+			; Legen sie es in ColTab
	cmp.w	#-2,d0				; Ende?
	bne.s	RecopyInColTabLoop
JumpRoll:
	lea	BplCon1Tab(pc),a0		; Tab mit Werten für BPLCON1
	lea	TabBuf(pc),a1			; Puffer
	move.w	(a0)+,d0			; erster Tabellenwert in d0 gespeichert
RollLoop:
	move.w	(a0)+,d1			; nächster Tabellenwert BPLCON1 nach d1
	cmp.w	#-2,d1				; Ende Tabelle?
	beq.s	EndRoll				; wenn ja springe voraus
	move.w	d1,(a1)+			; Kopieren Tabellenwert BPLCON1 nach TabBuf
	bra.s	RollLoop
EndRoll:
	move.w	d0,(a1)+			; Setze den ersten Wert als den letzten
	move.w	#-2,(a1)+			; Flag Tabellenende setzen
	lea	BplCon1Tab(pc),a0		; Tab mit Werten für BPLCON1
	lea	TabBuf(pc),a1			; Puffer
RecopyCon1:
	move.w	(a1)+,d0			; Kopieren von tabbuf
	move.w	d0,(a0)+			; nach bplcon1tab
	cmp.w	#-2,d0				; sind wir am Ende
	bne.s	RecopyCon1			; wenn noch nicht, kopiere es!
Delayed:
	lea	CopperEffect,a0

; erste Schleife, die der ntsc-Teil ist (erste $ff-Zeilen)

	move.w	#$2007,d0			; Position wait start YY=$20
	move.w	#$4007,d2			; position wait step YY=$40
	moveq	#7-1,d4				; Anzahl der jeweils $20 Schleifen.
								; $20 * 7 = $e0, + $20 initial = $100, dh
								; der gesamte NTSC-Bereich
	lea	EndColTab(pc),a1		; Ende der Farbtabelle
	lea	BplCon1Tab(pc),a2		; Tabellenwert für BPLCON1
Loop:
	move.w	CouNumLoop1(pc),d3
Main:
	move.w	(a2)+,d5			; nächster Wert BPLCON1
	cmp.w	#-2,d5				; Ende Tabelle?
	bne.s	Initd				; wenn nicht, weiter
	lea	BplCon1Tab(pc),a2		; andernfalls von vorne anfangen 
	move.w	(a2)+,d5			; nächster Wert BPLCON1
Initd:
	move.w	-(a1),d1			; Lies die Farbe und gehe zurück
	cmp.w	#-2,d1				; Ende Tabelle?
	bne.s	Initc				; Wenn noch nicht, setze die Farbe & BPLCON1
	lea	EndColTab(pc),a1		; Beginne andernfalls am Ende der Farbtabelle
	move.w	-(a1),d1			; Lies die Farbe und gehe zurück
Initc:
	move.w	d0,(a0)+			; YYXX von der Wartezeit
	move.w	#$fffe,(a0)+		; wait
	move.w	#$0180,(a0)+		; Register COLOR00
	move.w	d1,(a0)+			; Wert COLOR00
	move.w	#$0102,(a0)+		; BPLCON1
	move.w	d5,(a0)+			; Wert BPLCON1
	add.w	#$0100,d0			; eine Zeile tiefer warten
	dbra	d3,Main
Second:
	move.w	(a2)+,d5			; nächster Wert BPLCON1
	cmp.w	#-2,d5				; Ende Tabelle?
	bne.s	Doned				; wenn nicht, weiter
	lea	BplCon1Tab(pc),a2		; andernfalls von vorne anfangen
	move.w	(a2)+,d5			; nächster Wert BPLCON1
Doned:
	move.w	(a1)+,d1			; nächste Farbe
	cmp.w	#-2,d1				; Ende Tabelle?
	bne.s	Done				; Wenn noch nicht, setze die Farbe & BPLCON1
	lea	ColTab(pc),a1			; von vorne beginnen
	move.w	(a1)+,d1			; nächste Farbe in tab
Done:
	move.w	d0,(a0)+			; YYXX von der Wartezeit
	move.w	#$fffe,(a0)+		; wait
	move.w	#$0180,(a0)+		; Register COLOR00
	move.w	d1,(a0)+			; Wert COLOR00
	move.w	#$0102,(a0)+		; Register BPLCON1
	move.w	d5,(a0)+			; Wert BPLCON1
	add.w	#$0100,d0			; eine Zeile tiefer warten
	cmp.w	d2,d0				; sind wir am Ende des $20-Zeilenblocks?
	bne.s	Second	
	add.w	#$2000,d2			; bewege das neue Maximum um $20 nach unten.
	dbra	d4,Loop
	move.l	#$ffdffffe,(a0)+	; Ende Bereich ntsc

; Zweite Schleife, die den PAL-Bereich unterhalb der $ff-Zeile bildet

	move.w	#$0007,d0			; Ich fange an zu warten, in der Zeile $00 (dh 256)
	move.w	#$2007,d2			; Beende die Zeile $20 (+$ff)
	moveq	#2-1,d4				; Anzahl Schleifen
Loop2:
	move.w	CouNumLoop1(pc),d3
Main2:
	move.w	-(a1),d1			; vorherige Farbe
	cmp.w	#-2,d1				; Ende Tabelle?
	bne.s	Initc2
	lea	EndColTab(pc),a1		; Verlassen am Ende der Farbtabelle
	move.w	-(a1),d1			; vorherige Farbe
Initc2:
	move.w	d0,(a0)+			; YYXX wait
	move.w	#$fffe,(a0)+		; Wait
	move.w	#$0180,(a0)+		; Register COLOR00
	move.w	d1,(a0)+			; Wert COLOR00
	add.w	#$0100,d0			; eine Zeile tiefer warten
	dbra	d3,Main2
Second2:
	move.w	(a1)+,d1			; nächste Farbe
	cmp.w	#-2,d1				; Ende Tabelle?
	bne.s	Done2
	lea	ColTab(pc),a1			; Farbtabelle - von vorne beginnen
	move.w	(a1)+,d1			; nächste Farbe in d1
Done2:
	move.w	d0,(a0)+			; Koordinate YYXX wait
	move.w	#$fffe,(a0)+		; zweites Wort des wait
	move.w	#$0180,(a0)+		; Register COLOR00
	move.w	d1,(a0)+			; Wert COLOR00
	add.w	#$0100,d0			; eine Zeile tiefer warte
	cmp.w	d2,d0				; sind wir ganz unten? ($20-$40-$60)
	bne.s	Second2				; wenn noch nicht, bleiben
	add.w	#$2000,d2			; Stellen Sie das Maximum 20 niedriger ein
	dbra	d4,Loop2
	move.l	(sp)+,a5			; a5 wieder herstellen
	rts

CouNumLoop1:	dc.w	0		; Zähler Anzahl Loops	
Counter1:		dc.w	0		; Zähler 1
Counter2:		dc.w	0		; Zähler 2


	dc.w	-2					; Anfang tab
ColTab:
	dc.w	$000,$000,$000,$000,$000,$000,$000,$000,$000,$000,$000
	dc.w	$000,$001,$002,$003,$004,$005,$006,$007,$008,$009,$009
	dc.w	$00a,$00a,$00b,$00b,$00b,$01c,$02c,$03c,$04c,$05d,$05d
	dc.w	$06d,$06d,$07d,$07d,$07d,$08d,$08d,$08d,$09d,$09D,$09C
	dc.w	$0aA,$0aA,$0a9,$0a8,$0a7,$0a6,$0a5,$0a4,$0a3,$0b2,$0b1
	dc.w	$0b0,$1b0,$2b0,$3b0,$4b0,$5b0,$6b0,$7b0,$8b0,$9b0,$ab0
	dc.w	$bb0,$Cb0,$Db0,$db0,$db0,$db0,$db0,$da0,$da0,$d90,$d90
	dc.w	$d80,$d70,$d60,$d50,$d40,$d30,$d20,$d10,$d00,$d00,$d00
	dc.w	$c00,$b00,$a00,$900,$800,$700,$600,$500,$400,$300,$200
	dc.w	$100,$000,$000
EndColTab:
	dc.w	-2					; Ende tab

; Wertetabelle für BPLCON1. Wie Sie bemerken, verursacht es eine Welle.

	dc.w	-2					; Anfang tab
BplCon1Tab:
	dc.w	$11,$11,$11,$22,$22,$33,$44,$55,$55,$66,$66,$66,$077,$077
	dc.w	$77,$77,$77,$77,$66,$66,$66,$55,$55,$44,$33,$33,$022,$022
	dc.w	$22,$11,$11,$11,$11,$00,$00,$00,$00,$00,$00,$11,$011,$011
	dc.w	$11,$11,$22,$22,$22,$22,$33,$33,$44,$44,$55,$55,$055,$055
	dc.w	$66,$66,$66,$66,$66,$66,$77,$77,$77,$77,$77,$77,$077,$077
	dc.w	$77,$77,$66,$66,$66,$66,$66,$66,$55,$55,$55,$55,$044,$044
	dc.w	$33,$33,$33,$33,$22,$22,$22,$22,$22,$22,$11,$11,$011,$011
	dc.w	-2					; Ende tab

; In diesen Puffer werden die gedrehten Tabellen kopiert, die dann in die
; Tabellen selbst kopiert werden... eine seltsame Art zu scrollen, oder?

TabBuf:
	ds.w	128

*****************************************************************************
;			Druck-Routine
*****************************************************************************

PrintCharacter:
	movem.l	d2/a0/a2-a3,-(sp)
	move.l	PointerText(pc),a0	; Adresse des zu druckenden Textes a0
	moveq	#0,d2				; d2 löschen
	move.b	(a0)+,d2			; Nächstes Zeichen in d2
	cmp.b	#$ff,d2				; Ende des Textsignals? ($ff)
	beq.s	EndText				; Wenn ja, beenden Sie ohne zu drucken
	tst.b	d2					; Zeilenende-Signal? ($00)
	bne.s	NotEndLine			; Wenn nicht, nicht aufhören

	add.l	#40*7,PointerBitplane	; wir gehen zum Anfang
	addq.l	#1,PointerText		; erste Zeichenzeile danach
								; (überspringe die NULL)
	move.b	(a0)+,d2			; erstes Zeichen der Zeile nach
								; (überspringe die NULL)

NotEndLine:
	sub.b	#$20,d2				; ZÄHLE 32 VOM ASCII-WERT DES BUCHSTABEN WEG
								; SOMIT VERWANDELN WIR Z.B. DAS LEERZEICHEN
								; (Das $20 entspricht), IN $00, DAS
								; AUSRUFUNGSZEICHEN ($21) IN $01...
	lsl.w	#3,d2				; MULTIPLIZIERE DIE ERHALTENE ZAHL MIT 8,
								; da die Charakter ja 8 Pixel hoch sind
	move.l	d2,a2
	add.l	#Font,a2			; FINDE DEN GEWÜNSCHTEN BUCHSTABEN IM FONT...

	move.l	PointerBitplane(pc),a3 ; Adresse Ziel-Bitplane in a3

								; DRUCKE DEN BUCHSTABEN ZEILE FÜR ZEILE
	move.b	(a2)+,(a3)			; Drucke Zeile 1 des Zeichens
	move.b	(a2)+,40(a3)		; Drucke Zeile  2  " "
	move.b	(a2)+,40*2(a3)		; Drucke Zeile  3  " "
	move.b	(a2)+,40*3(a3)		; Drucke Zeile  4  " "
	move.b	(a2)+,40*4(a3)		; Drucke Zeile  5  " "
	move.b	(a2)+,40*5(a3)		; Drucke Zeile  6  " "
	move.b	(a2)+,40*6(a3)		; Drucke Zeile  7  " "
	move.b	(a2)+,40*7(a3)		; Drucke Zeile  8  " "

	addq.l	#1,PointerBitplane	; wir rücken 8 Bits vor (NÄCHSTES ZEICHEN)
	addq.l	#1,PointerText		; nächstes zu druckendes Zeichen

EndText:
	movem.l	(sp)+,d2/a0/a2-a3
	rts


PointerText:
	dc.l	Text

PointerBitplane:
	dc.l	Bitplane

;	$00 für "Zeilenende" - $ff für "Textende"

		; Anzahl der Zeichen pro Zeile: 40
Text:	     ;		  1111111111222222222233333333334
             ;   1234567890123456789012345678901234567890
	dc.b	'                                        ',0 ; 1
	dc.b	'    Questo listato cambia ad ogni       ',0 ; 2	Dieses Listing ändert mit jeder
	dc.b	'                                        ',0 ; 3
	dc.b	'    linea sia il COLOR01 ($dff184),     ',0 ; 4	Zeile COLOR01 ($dff184),
	dc.b	'                                        ',0 ; 5
	dc.b	'    che il BPLCON1 ($dff102). Notate    ',0 ; 6	sowie die BPLCON1 ($dff102). Notiz
	dc.b	'                                        ',0 ; 7
	dc.b	'    come si possano "unire" listati     ',0 ; 8	wie Sie Einträge "zusammenführen" können
	dc.b	'                                        ',0 ; 9
	dc.b	'    visti in precedenza in un solo      ',0 ; 10	zuvor in einem Effekt gesehen
	dc.b	'                                        ',0 ; 11
	dc.b	'    effetto. Si potrebbero cambiare     ',0 ; 12	Sie könnten 
	dc.b	'                                        ',0 ; 13
	dc.b	'    anche altri colori e i moduli per   ',0 ; 14   auch andere Farben und Modulo
	dc.b	'                                        ',0 ; 15
	dc.b	'    ogni linea, se avete voglia         ',0 ; 16   jede Zeile ändern, wenn Sie Lust dazu haben
	dc.b	'                                        ',0 ; 17
	dc.b	'    provate!                            ',$ff ; 18 Versuchen Sie es!

	even

; Die Font-Zeichen 8x8 (in CHIP von der CPU und nicht vom Blitter kopiert,
; so kann es auch im FAST RAM sein. In der Tat wäre es besser!

Font:
	incbin	"/Sources/nice.fnt"

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

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$8e,DIWS			; DIWSTRT	($cC81)
	dc.w	$90,DIWST			; DIWSTOP	($cc1)
	dc.w	$92,DDFS			; DDFSTRT	($38)
	dc.w	$94,DDFST			; DDFSTOP	($d0)
	dc.w	$100,BPLC0			; BPLCON0	($1200)
	dc.w	$180,$000			; COLOR00 schwarz
	dc.w	$182,$eee			; COLOR01 weiß
Bplpointers:
	dc.w	$e0,$0000			; BPL1PTH
	dc.w	$e2,$0000			; BPL1PTL
	dc.w	$102,$0				; BPLCON1
	dc.w	$104,$0				; BPLCON2
	dc.w	$108,$0				; BPL1MOD
	dc.w	$10a,$0				; BPL2MOD
		
CopperEffect:
	dcb.l	801,0				; Platz für den Effekt (Achtung! bei
								; Änderungen kann der Effekt
								; größer oder kleiner werden)
	dc.w	$ffff,$fffe			; Ende Copperlist

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

	SECTION	LEEREPLANE,BSS_C

Bitplane:
	ds.b	40*256				; eine Bitplane lowres 320x256

	end

Möglicherweise haben Sie bemerkt, dass Verwicklungen und viele seltsame 
Schleifen durch Zählern in den Routinen reguliert werden. 
Dies wird verwendet um diesen Farbeffekt zu erzeugen.
Es ist ein einfacher Bildlauf nach oben oder unten, aber "das Durcheinander"
wird durch verschiedene Passagen erzeugt.