
; Listing24c.s  Copper-Zebra - Copperloops mit maskierten waits

	SECTION	COPPER,CODE

	incdir	"/Sources/include/"
	include	MVstartup.s			; Startup Code: Nimmt
								; Systemprüfung vor und Aufruf
								; durch Platzieren der START-Routine: 
								; A5=$DFF000

			;5432109876543210
DMASET	equ	%1000001010000000	; copper DMA


Start:
	move	#DMASET,dmacon(a5)
	move.l	#Copperlist,cop1lc(a5)

	move.l	#CopLoop1,d0
	move	d0,CopPtr1+6
	swap	d0
	move	d0,CopPtr1+2

	move.l	#CopLoop2,d0
	move	d0,CopPtr2+6
	swap	d0
	move	d0,CopPtr2+2

	move.l	#CopLoop3,d0
	move	d0,CopPtr3+6
	swap	d0
	move	d0,CopPtr3+2

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

	rts

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

	SECTION	MY_COPPER,CODE_C

Copperlist:

CopPtr1:
	dc.w	$84,0,$86,0
	
CopLoop1:	
	dc.w	$0007,$9ffe
	dc.w	$180,$000
	dc.w	$1007,$9ffe	 
	dc.w	$180,$fff
	dc.w	$1fe1,$9ffe
	
	dc.w	$8007,$ffff
	dc.w	$8a,0

CopPtr2:
	dc.w	$84,0,$86,0	

CopLoop2:		
	dc.w	$8007,$9ffe			
	dc.w	$180,$000
	dc.w	$9007,$9ffe	 
	dc.w	$180,$fff
	dc.w	$9fd7,$9ffe	
	dc.w	$ffdd,$ffff		
	dc.w	$8a,0	
		
CopPtr3:
	dc.w	$84,0,$86,0
	
CopLoop3:		
	dc.w	$0007,$9ffe
	dc.w	$180,$000
	dc.w	$1007,$9ffe	 
	dc.w	$180,$fff
	dc.w	$1fe1,$9ffe

	dc.w	$3007,$ffff
	dc.w	$8a,0
	
	dc.w	$ffff,$fffe

	end


Erklärung:

Ohne ein Hilfsprogramm, das einen die "zugehörigen" Waitpositionen zu einem
maskierten Wait berechnet und im besten Fall visuell ausgibt ist man bei diesem
Thema förmlich aufgeschmissen. Denn man muss genau wissen was bei Verwendung 
dieser Waits passiert. Aus diesem Grund hatte ich mir ein Hilfsprogramm
geschrieben.

Durch probieren habe ich ein interessantes maskiertes Wait gefunden:

	dc.w	$0007,$9ffe

--- all vertical waitpositions ---
00   00000000   dec= 0
20   00100000   dec= 32
40   01000000   dec= 64
60   01100000   dec= 96

Damit entspricht das Wait	dc.w $0007,$9ffe, den Waits:
dc.w	$0007,$fffe
dc.w	$2007,$fffe
dc.w	$4007,$fffe
dc.w	$6007,$fffe

Ab der Zeile $80 bis $ff ändert sich lediglich folgendes: $8007,$9ffe
dc.w	$8007,$fffe
dc.w	$a007,$fffe
dc.w	$c007,$fffe
dc.w	$e007,$fffe

und danach ab Zeile $100 bis zum Ende des Frames noch einmal: $0007,$9ffe
dc.w	$0007,$fffe
dc.w	$2007,$fffe
dc.w	$4007,$fffe

Das zwingt uns wieder den Bildschirm in drei Zonen zu unterteilen:
Zone 1: $0 bis $7f
Zone 2: $80 bis $ff
Zone 3: $100 bis $139	(313)

Die Copperliste startet bei jedem Frame automatisch von der Adresse auf die der
Copperpointer 1 zeigt. In der Copperliste selbst gibt es drei Copperschleifen.
Dafür wird vor Eintritt in eine Zone der Copperpointer2 mit der "Rücksprung-
adresse" geladen. Danach folgen die maskierten Waits mit anschließendem 
Farbwechsel und der Bereichs-Skip. Solange der Elektronenstrahl die angegebene
Position des Skips noch nicht überschritten hat, wird der folgende Copperbefehl
nicht übersprungen. Da es sich hierbei um den COPJMP2 ($8a) handelt erfolgt also
ein Rücksprung an den Start der Zone und das maskierte Wait wird an seiner
nächsten Position warten.

	dc.w	$0007,$9ffe
	dc.w	$180,$000
	dc.w	$1007,$9ffe	 
	dc.w	$180,$fff
	dc.w	$1fe1,$9ffe

	dc.w	$8007,$ffff
	dc.w	$8a,0

Es bietet sich an das Basiswait mit dem ersten Wait der möglichen Waits zu wählen.
Das folgende Wait $1007,$9ffe folgt diesem entsprechend 10 Zeilen später. 
Da dc.w	$2007,$fffe das nächstfolgende Wait dieses maskierten Waits entspricht 
ist das letzte frei gewählte Wait eine Zeile zuvor und zwar hier: 
dc.w	$1fhh,$9ffe
Um unnötige Copperzyklen zu vermeiden wird ein Wait kurz vor dem Skip platziert.

Das wären die Grundregeln. Wichtig bleibt zu verstehen, dass z.B.

	dc.w	$4007,$9ffe
	dc.w	$180,$000
	dc.w	$5007,$9ffe	 
	dc.w	$180,$fff
	dc.w	$5fe1,$9ffe

	dc.w	$8007,$ffff
	dc.w	$8a,0

oder:

	dc.w	$6007,$9ffe
	dc.w	$180,$000
	dc.w	$1007,$9ffe	 
	dc.w	$180,$fff
	dc.w	$7fe1,$9ffe

	dc.w	$8007,$ffff
	dc.w	$8a,0

genau das gleiche macht!

Ab Zeile $80 übernimmt die zweite Copperschleife mit dem Unterschied:
	dc.w	$8007,$9ffe

Der Wechsel zwischen dem Bereich $ff und $100 hält eine Schwierigkeit für uns 
parat, weil wir das Bit9 nicht auswerten können.

Durch Tests setzen wir das Skip genau an das Ende von Zeile $ff und zwar durch
ein Wait.

	dc.w	$9fd7,$9ffe	
	dc.w	$ffdd,$ffff

Wenn der Skip den folgenden Befehl überspringt dann hat auch der 
Elektronenstrahl den Bereich über $100 (also wieder ab $00) erreicht und das
nächste wait: dc.w	$0007,$9ffe wird wieder gültig. Ausserdem werden durch diese
Massnahme keine Copperzyklen verschwendet.
