
; Listing25c2.s		horizontales Spritemultiplexing mit wait und SPRxPOS
; über die gesamte Bildschirmzeile
; mit Copper-Move ("halbautomatischer Modus")

SPRITEKANAL equ 0				; 0 - SPR0 , 1 - SPR1 .... , 7 - SPR7

	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)

	; Pointen auf den Sprite

	move.l	#MeinSprite,d0		; Adresse des Sprite in d0
	lea	SpritePointers,a1		; Pointer in der Copperlist
	; zum Test die Spritekanalnummer ändern
	lea SPRITEKANAL*8(a1),a1	; lea SPRITEKANAL*8(a1),a1
	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 horizontalen Spritemultiplex in der Copperliste  *
*******************************************************************************

; Copper-Sprites benötigen: 
; 13*wait
; 13*23 SPR0POS
; 13*23 COP-NOP
; = 13+299+229=611.l

InitCopper:
	move.l	#$1a29fffe,d0			; wait
	move.l  #$01401a30,d1			; SPR0POS		
	moveq	#SPRITEKANAL*8,d2		; anderen Spritekanäle testen		
	swap d2
	add.l   d2,d1					; Spritekanal			
	move.l  #$01fe0000,d3			; COP-NOP

	lea CopperSprite,a0
	moveq #13-1,d6					; 13 Zeilen		
Zeile:
	moveq #23-1,d7					; 22 Anzahl Sprites horizontal nebeneinander
	move.l	d0,(a0)+				; wait
Horiz:	
	move.l	d1,(a0)+				; SPR0POS V=$1a, H=$40+8*n
	cmp.b	#0,d7
	move.l  d3,(a0)+				; Copper-NOP	
	add.b	#8,d1					; nächste horizontale Position	
	dbf d7,Horiz
	add.l #$01000000,d0				; nächste Zeile
	move.b  #$30,d1					; SPR0POS zurücksetzen
	dbf d6,Zeile
	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,$1a5c		; DIWSTRT
	dc.w	$90,$80d4		; DIWSTOP
	dc.w	$92,$20			; DDFSTRT
	dc.w	$94,$d8			; 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:
	blk.l	611,0			; Raum für das horizontale Spritemultiplexing
	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 $1a	; Vertikale Anfangsposition des Sprite (von $2c bis $f2)
Hstart:
	dc.b $00	; Horizontale Anfangsposition des Sprite (von $40 bis $d8)
Vstop:
	dc.b $27	; $1a+13=$27 - 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 demonstrieren wir das horizontale Spritemultiplexing über
den gesamten Bildschirm. Der Screen ist im Overscan eingestellt. Nur für den
Spritekanal 0 und 1 ist dies möglich. Für andere Spritekanäle verlieren wir
aufgrund des früher eingestellten DDFSTRT Sprite-DMA-Slots durch Bitplane 
DMA. Und es gibt zusätzliche Effekte mit "zerstörten" Sprites.

1.
Um andere Spritekanäle zu testen, die Variable 'SPRITEKANAL' am Anfang des
Programms einstellen: Es ändert das Programm an zwei Stellen:

lea SPRITEKANAL*8(a1),a1  ; beim Pointen auf den Sprite anpassen und

SPR0POS = $140
SPR1POS = $148
SPR2POS = $150
SPR3POS = $158
...
SPR7POS = $178

und
	move.l  #$01401a30,d1			; SPR0POS neue horizontale Startposition
	add.l   d2,d1					; Spritekanal

2. 
In dieser Anordnung wird der letzte Sprite richtig angezeigt auch wenn die
Copper-Move Befehle nicht für alle Zeilen des Sprites durchgeführt werden.
z.B.

ändern:
	moveq #1-1,d4		; nur 1 Zeilen
	moveq #23-1,d7		; 22 Anzahl Sprites horizontal nebeneinander

Das liegt daran, weil die Steuerwörter danach nicht mehr geändert werden und
die Hardware es dadurch wie ein "normales" Sprite anzeigt.

 