
; Listing25b2.s		vertikaler Spritemultimplex mit wait und SPRxPOS
; mit Copper-Move ("halbautomatischer Modus") über die gesamte Höhe

	SECTION ROCK'NROLL,CODE

Start:
	move.l	4.w,a6				; Execbase in a6
	jsr	-$78(a6)				; Disable - verhindert Interrupts
	lea	GfxName(PC),a1			; Libname
	jsr	-$198(a6)				; OldOpenLibrary
	move.l	d0,GfxBase
	move.l	d0,a6
	move.l	$26(a6),OldCop		; wir speichern die alte COP

	move.l	#Bitplane,d0		; Zeiger auf die "leere" Bitplane
	lea	Bplpointers,a1			; Bitplanepointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	
	bsr InitCopper				; Copperlist vorbereiten

	lea	$dff000,a5				; Custom Register Base in a5
	move.l	#Copperlist,$80(a5)	; Zeiger Copperlist
	move.w	#0,$1fc(a5)			; AGA "deaktivieren"
	move.w	#$c00,$106(a5)		; AGA "deaktivieren"
	move.w	#$11,$10c(a5)		; AGA "deaktivieren"

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

	move.l	OldCop(PC),$dff080	; Pointen auf die alte System Copperlist
	move.l	4.w,a6
	jsr	-$7e(a6)				; Enable
	move.l	GfxBase(PC),a1
	jsr	-$19e(a6)				; Closelibrary
	rts

;	Daten

GfxName:
	dc.b	"graphics.library",0,0

GfxBase:
	dc.l	0

OldCop:
	dc.l	0

*******************************************************************************
* Diese Routine erstellt den vertikalen Spritemultiplex in der Copperliste    *
*******************************************************************************

InitCopper:
	move.l	#$1a01fffe,d0		; 1. wait			
	move.l	#$01401a40,d1		; SPR0POS V=$1a, H=$40 
	move.l	#$01422700,d2		; SPR0CTL V=$27, H=0	$1a+13=$27
	move.l	#MeinSprite+4,d3	; Adresse des Sprite in d3 auf Spritedaten!
								; nicht auf die Steuerwörter!
	move.w	#$0122,d4			; SPR0PTL
	move.l	#$0d000000,d5		; 13 Zeilen		
								
	lea	CopperSprite,a0			; Anfang des Spritebereichs in der Copperlist 	
;-------------------------------
; wir erlauben uns das Risiko... und schreiben SPR0PTH nicht jedesmal neu
	move.w	#$0120,(a0)+		; SPR0PTH
	swap d3
	move.w	d3,(a0)+			; hi-Anteil Adresse eintragen
	swap d3

	moveq #2,d6					; die Schleife 2x durchlaufen
	moveq #18-1,d7				; $1a+17*13=247 = $f701 letzte wait vor $ff
CopLoop:
	move.l	d0,(a0)+			; setzt das wait	
	move.w  d4,(a0)+			; SPR0PTL			
	move.w	d3,(a0)+			; low-Anteil Adresse eintragen
    move.l	d1,(a0)+			; SPR0POS
	;move.l	d2,(a0)+			; SPR0CTL
;----------------
	add.l d5,d0					; nächstes wait vorbereiten
	swap d5
	add.w d5,d1					; nächstes SPR0POS vorbereiten
	add.w d5,d2					; nächstes SPR0CTL vorbereiten
	swap d5						; für nächsten Durchlauf vorbereiten
	dbf d7,CopLoop
	subq.b	#1,d6
	beq.s	DoNotStartAgain		; wenn 0 dann sind wir fertig	
	move.l	#$ffdffffe,(a0)+	; unter Zeile 255	
	moveq #4-1,d7				; 19*13=256
	bra CopLoop
DoNotStartAgain:	
	move.l	#$fffffffe,(a0)		; Ende der Copperlist
	rts

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

	SECTION GRAPHIC,DATA_C

Copperlist:
SpritePointers:
	dc.w	$120,0,$122,0,$124,0,$126,0,$128,0 ; Sprite
	dc.w	$12a,0,$12c,0,$12e,0,$130,0,$132,0
	dc.w	$134,0,$136,0,$138,0,$13a,0,$13c,0
	dc.w	$13e,0

	dc.w	$8e,$1a81		; DIWSTRT
	dc.w	$90,$3891		; DIWSTOP
	dc.w	$92,$38			; DDFSTRT
	dc.w	$94,$40			; DDFSTOP
	dc.w	$102,0			; BPLCON1
	dc.w	$104,0			; BPLCON2
	dc.w	$108,0			; BPL1MOD
	dc.w	$10a,0			; BPL2MOD

				; 5432109876543210
	dc.w	$100,%0001001000000000  ; Bit 12 an!! 1 Bitplane Lowres

Bplpointers:
	dc.w	$e0,0,$e2,0		; erste Bitplane

	dc.w	$180,$000		; COLOR00	; Hintergrund Schwarz
	dc.w	$182,$123		; COLOR01	; Farbe 1 der Bitplane, die
							; in diesem Fall leer ist,
							; und deswegen nicht erscheint

	dc.w	$1a2,$f00		; COLOR17, oder COLOR1 des Sprite0 - rot
	dc.w	$1a4,$0f0		; COLOR18, oder COLOR2 des Sprite0 - grün
	dc.w	$1a6,$ff0		; COLOR19, oder COLOR3 des Sprite0 - gelb

CopperSprite:
	dcb.w	2*(1+18*3+1+4*3+1),0	; 1*2 + 18*3*2 + 1*2 + 4*3*2 + 1*2
	dc.w	$ffff,$fffe		; Ende der Copperlist


; ************ Hier ist der Sprite: NATÜRLICH muß er in CHIP RAM sein! ************

MeinSprite:		; Länge 13 Zeilen
Vstart:
	dc.b $60	; Vertikale Anfangsposition des Sprite (von $2c bis $f2)
Hstart:
	dc.b $d0	; Horizontale Anfangsposition des Sprite (von $40 bis $d8)
Vstop:
	dc.b $6d	; $60+13=$6d - Vertikale Endposition des Sprite
	dc.b $00
 dc.w	%0000000000000000,%1000110000110001 ; Binäres Format für ev. Änderungen
 dc.w	%0000000000000000,%0000011001100000
 dc.w	%0000000000000000,%0000001001000000
 dc.w	%0000000110000000,%0011000110001100 ; binär 00=Color 0 (durchsichtig)
 dc.w	%0000011111100000,%0110011111100110 ; binär 10=Color 1 (rot)
 dc.w	%0000011111100000,%1100100110010011 ; binär 01=Color 2 (grün)
 dc.w	%0000110110110000,%1111100110011111 ; binär 11=Color 3 (gelb)
 dc.w	%0000011111100000,%0000011111100000
 dc.w	%0000011111100000,%0001111001111000
 dc.w	%0000001111000000,%0011101111011100
 dc.w	%0000000110000000,%0011000110001100
 dc.w	%0000000000000000,%1111000000001111
 dc.w	%0000000000000000,%1111000000001111
 dc.w	0,0	; 2 word auf NULL definieren das Ende des Sprite.

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

	SECTION LEEREPLANE,BSS_C	

Bitplane:
	ds.b	40*256				; Bitplane auf 0 Lowres

	end


Erklärung:

In diesem Beispiel zeigen wir vertikales Spritemultiplexing über die gesamte
Höhe des Videoanzeige von Zeile $1a bis $138.
Der Spritezeiger muss jeweils vor Beginn zurückgesetzt werden ansonsten folgen
die Sprites ohne Lücke untereinander. SPR0CTL braucht nicht verwendet werden,
da das Sprite data fetch zu keinem Zeitpunkt unterbrochen wird und mit der 
letzten Zeile automatisch endet.

