	
ASSEMBLERKURS - LEKTION 25: Spritemultiplexing (Version 1: Stand: 09/2024)

Autor: Göran Strack
					

Wenn Sprites auf dem Bildschirm angezeigt werden, werden die Spritebilddaten
dafür aus ihren Spritebuffer-Registern zur Videoausgabe übertragen. Mit 
Spritebuffer sind die beiden 16 Bit Sprite Data Register gemeint die jedes
Sprite hat, also bei den 8 Sprites die 8x SPRxDATA und 8x SPRxDATB Register
(mit x=0 bis 7).
Die Daten gelangen dabei über den Datenbus über Schreibzugriffe in diese 
Register. Dabei können zwei Möglichkeiten des Datentransfers bei drei 
unterschiedlichen Quellen unterschieden werden. 

Quelle					/ Datentransfer				/ Modus
1. über Sprite-Hardware	- nur Sprite DMA		   ("automatischer Modus")  
2. über Copper-Move		- mit oder ohne Sprite DMA ("halbautomatischer Modus")
3. über CPU				- mit oder ohne Sprite DMA ("manueller Modus")

Wobei im Fall über die Sprite-Hardware der Datentransfer zwischen Chip-Speicher
und den Sprite-Data-Registern grundsätzlich nur über Sprite-DMA erfolgt. Im 
Falle über Copper-Move Befehle oder CPU wäre eine Datenübertragung zu den 
Sprite-Data-Registern über Sprite-DMA oder durch direktes Schreiben in die
Sprite-Data-Register SPRxDATA und SPRxDATB möglich. 

Der Nachteil der CPU ist aber hierbei eindeutig die Synchronisation mit der
aktuellen Elektronenstrahlposition und scheidet dadurch eigentlich als 
Möglichkeit aus.

Damit die Sprite-Bitebenendaten auf dem Bildschirm angezeigt werden muss:
- Sprite DMA: Im Falle von Sprite-DMA das Sprite durch eine gültige Position
              gestartet und noch nicht wieder beendet wurden sein.
			  SPRxPOS, SPRxCTL
- ohne Sprite DMA: Im Fall ohne Sprite-DMA werden Sprite-Bitebenendaten auf
              dem Bildschirm angezeigt wenn das Sprite durch Schreiben in
			  SPRxDATA aktiviert wurde. Es kann beendet werden durch 
			  Schreiben in SPRxCTL. Dies wird auch als 'rearmen' bezeichnet.

Dazu gleich mehr:

********************************************************************************
*  Lektion 7 Wiederholung - Sprite-Basiswissen - zur Erinnerung				   *
*              																   *
********************************************************************************

In Lektion 7 wurde bereits ausführlich das Thema der Sprites behandelt und in 
Beispielen demonstriert. In dieser Lektion über Sprites soll es um erweitertes
Wissen in Bezug auf Sprites gehen, und zwar speziell um Themen wie:
- Spritemultiplexing
- Bildschirmpositionen
- Sprites ohne Bitplane DMA
- Interlace Sprites
- DMA-Einschränkungen
- ...
 
und dazu einige ergänzende Erklärungen liefern.

Nur nochmal zur Erinnerung eine kleine Zusammenfassung des Sprite-Basiswissens
welches in Lektion 7 bzw. Lektion 15 (AGA) ausführlich vermittelt wurde:

- 8 Sprites (in Spritepaaren 0,1 2,3 4,5 6,7)
- teilen sich die Farbregister Color16 bis Color32
- z.B. Spritepaar 0,1 - 3 Farben und 1 transparent von Color16,17,18,19
- Sprite 2 Planes (16 Bit breit)
- Spritehöhe: theoretisch: 512 Pixel (9 Bit) 
- Sprites sind immer lowres auch wenn Bildschirm in hires, interlace, HAM, EHB
- pro Kanal:
- zwei Spritepointer		SPRxPTH und SPRxPTL
- zwei Spritecontrolwörter	SPRxPOS und SPRxCTL
- zwei Spritedatenwörter	SPRxDATA und SPRxDATB
- im attached mode: 
- Bit 7 des ungeraden Sprites setzen
- dann 15 Farben und 1 transparent von Color16 bis 31
- Priorität von Sprite 0 nach Sprite 7, wenn übereinader
- Spritekollisionen mit Sprite/Sprite oder Sprite Bitebene kontrollierbar
  ... noch einfügen
- Sprite/ Playfield Priorität über BPLCON2
 1. spritepriority in groups of two 0,1 2,3 4,5 6,7 
    (sprite 0,1 in front (higher priority), sprite 6,7 behind)
 2. single- or dual-playfield?
 2a) single-playfield 1-6 bitplanes use only bits PF2P2-0
 2b) dual-playfield 2*(1-3 bitplanes) use PF2P2-0 and PF1P2-0
 3. dual-playfield: playfield 1 - bitplanes 1,3,5 and 
                    playfield 2 - bitplanes 2,4,6
 4. P2PRI if set - set playfield 2 higher priority over playfield 1
 5.
PF2(1)P2-0=0 (000) p-s-s-s-s ; p-playfield, s-sprite
PF2(1)P2-0=1 (001) s-p-s-s-s
PF2(1)P2-0=2 (010) s-s-p-s-s
PF2(1)P2-0=3 (011) s-s-s-p-s
PF2(1)P2-0=4 (100) s-s-s-s-p
- AGA-Sprites bieten darüber hinaus weitere Möglichkeiten
 ... noch einfügen

Im Adressbereich der Hardware-Register von $dff000 bis $dff1ff sind die Sprite-
adressen von $dff120 bis $dff17e für die Sprites reserviert und zwar:
$dff120 bis $dff13e für SPRxPTH/ SPRxPTHL (Spritepointer high/low)
$dff140 bis $dff17e für SPRxPOS/ SPRxCTL/ SPRxDATA/ SPRxDATB
(vert,horiz start pos data, position and control data, image data register A,B)

*******************************************************************************
*  Variante: 1 - über Sprite-DMA		("automatischer Modus")				  *
*              																  *
*******************************************************************************

Erfolgt das Schreiben der Spritedaten über die Sprite-Hardware in die Sprite-
Data Register erfolgt die Datenübertragung grundsätzlich über Sprite-DMA.
Dazu müssen die Spritepointer auf den Beginn der Sprites gesetzt werden und die
ersten beiden Wörter müssen die beiden Steuerwörter SPRxPOS und SPRxCTL sein 
bzw. die Daten auf die die Spritepointer zeigen werden beim ersten Lesevorgang
automatisch als Steuerwörter interpretiert.
Der erste Sprite-DMA Zugriff erfolgt bei PAL in Zeile $19 (25) und bei NTSC in
Zeile $14 (20) und dient der Vorbereitung oder Einrichtung der Spritehardware.
Daraus erklärt sich auch warum Zeile $1a (PAL) die erste Zeile ist in der 
überhaupt Sprites angezeigt werden können. 
Sprites werden auch nur angezeigt wenn der Elektronenstrahl noch nicht die 
vertikale Startposition überschritten hat. Deswegen werden Nullsprites 
gewöhnlich auf den Startwert 0,0 gesetzt damit sie nicht zufällig 
herumgeistern.
Nachdem Spriteende welches sich aus der Startposition und der Höhe des Sprites
ergibt und im zweiten Steuerwort als vertikale Endposition angegeben wird, 
liest die Sprite-Hardware über Sprite-DMA automatisch nochmals mindestens zwei
Wörter und diese werden wieder als Steuerwörter interpretiert. Das Sprite kann
nun durch 0,0 beendet werden oder durch neue Spritepositionsdaten an einer 
anderen Position wiederholt angezeigt werden. 
Man setzt gewöhnlich 0,0 aber es könnte auch dc.w $00xx,00xx sein, da nur die
vertikalen Positionswerte des Sprites im Bezug zur aktuellen 
Elektronenstrahlposition überprüft werden und dadurch das Sprite data fetch 
starten bzw. beenden.

Ganz grundsätzlich wird ein Sprite gestartet, wenn die aktuelle Strahlposition 
kleiner oder gleich der vertikalen Startposition des Sprites ist und die 
angegebene Position erreicht wird und ein Sprite wird beendet wenn die 
vertikale Stoppposition welche in SPRxCTL (im zweiten Steuerwort) angegeben 
wurde erreicht wurde und es anschließend auf das Wertepaar 0,0 trifft bzw. die 
Position die in diesem Wertepaar steht bereits überschritten wurde. Selbst wenn
bereits vor dem eigentlichen Ende des Sprites das Register SPRxCTL mit einer
vertikalen Stoppposition beschrieben wird, wäre darauf zu achten, dass das 
darauffolgende Wertepaar nicht zu einem erneuten Start an einer anderen
Position führt.

Die Hardware führt nach dem Spriteende immer noch mindestens zwei Sprite-DMA
Lesevorgänge aus!!!

Vertikales Spritemultiplexing mit Sprite-DMA hat den Vorteil einer sehr 
geringen CPU- und Copper-Belastung, da nur eine große Spritestruktur im
Chip-RAM angelegt werden muss und der Spritepointer darauf ausgerichtet sein
muss. In der Spritestruktur selbst werden dann bis auf das Ende des Sprites mit
dem Wertepaar 0,0 die Steuerwörter mit neuen Positionswerten an einigen Stellen
zwischen den Sprite(bild)daten vorgehalten.
Nachteil dieser Methode ist, dass zwischen den Sprites immer eine Leerzeile
bestehen bleibt, bedingt durch das Lesen der Steuerwörter des Sprites.

Ein Beispiel für vertikales Spritemultiplexing dieser Art haben wir in 
Listing7t1.s usw. gesehen.


*******************************************************************************
*  Variante: 2 - über Copper-Move		("halbautomatischer Modus")			  *
*																			  *
*******************************************************************************

**** Grundlagen ****
===============================================================================

Bei der Variante des Anzeigens des Sprites durch Schreiben in die Steuerwörter
SPRxPOS über Copper-Move Befehle wird der Spritepointer zu Beginn sofort auf 
die Spritebilddaten gesetzt und nicht auf die Steuerwörter. Und sofern die oben
genannte Bedingung erfüllt ist, dass die Strahlposition noch nicht die in 
SPRxPOS angegebene Position überschritten hat, wird das Sprite mit Erreichen 
der Position gestartet und angezeigt. 
Und angezeigt wird dann das was zu diesem Zeitpunkt in den SPRxDATA und 
SPRxDATB-Registern steht. Der Inhalt muss also bereits zuvor in diese Register
übertragen wurden sein, entweder durch Sprite-DMA, durch Copper-Move oder durch
die CPU. Im Falle von Sprite DMA ist also auch noch das richtige Timing für
einen Bilddatenabruf zu beachten. 
Nach dem Ende des Sprites sollten unnötige Sprite DMA Abrufe vermieden werden
um einerseits Slots zu sparen, aber auch um ggf. herumgeisterne Sprites zu
vermeiden. Dafür wird das vertikale Spriteende in SPRxCTL angegeben und mit dem
Erreichen des Endes muss im folgenden Datenabruf wieder das bekannte Steuerwort
0,0 stehen um auch das Sprite Data Fetch zu beenden.

Sprite DMA Abrufe lassen sich gut im WinUAE-Debugger im visuellen DMA-Debugger
beobachten z.B. als durchgezogene Linien falls Sprite DMA nicht beendet wurde.

Um also ein Sprite schon eher zu beenden kann die vertikale Stoppposition in
SPRxCTL geändert werden, aber Sprite DMA Abrufe enden erst wenn das folgende
Steuerwort das Wertepaar 0,0 ist.

Ein erstes Beispiel wie ein Sprite über Copper-Move an einer Position 
angezeigt werden kann ist in Listing25a.s zu sehen. 

Das Listing25a2.s zeigt, das nach dem Ende in SPRxCTL nochmals ein Sprite-DMA
Abruf erfolgt und das diese Daten dann als Steuerwörter interpretiert werden.

Im Beispiel Listing25a3.s wird nochmals darauf hingewiesen wann der 
Spritepointer von der Hardware geändert wird. Daraus ergibt sich auch warum
manuelle Schreibvorgänge erst nach Zeile PAL 25/ NTSC 20 durchzuführen sind.


**** vertikales Spritemultiplexing ****
===============================================================================

Beim vertikalen Spritemultiplexing über den Copper müssen die Spritepointer 
wieder zurückgesetzt werden, da sie von der Hardware automatisch bei der Anzeige
erhöht werden. Es bietet sich an nur in SPRxPTL zu schreiben da SPRxPTH zu
Beginn der Copperliste gesetzt, konstant bleibt.

Sprite-DMA erfolgt an den Rasterslot-Positionen: (DMA-Buszyklen)
D.h.
S0 - 25,27  $19, $1B	
S1 - 29,31  $1D, $1F	
S2 - 33,35  $21  $23
S3 - 37,39  $25  $27
S4 - 41,43  $29  $2B
S5 - 45,47  $2D	 $2F
S6 - 49,51  $31  $33
S7 - 53,55  $35  $37 

 [18  24]  [19  25]  [1A  26]  [1B  27]  [1C  28]  [1D  29]  [1E  30]  [1F  31]
           SPR0 140            SPR0 142            SPR1 148            SPR1 14A
               03C0                7C3E                03C0                7C3E
           0006A584            0006A586            0006A5AC            0006A5AE
 85AAEE00  85AAF000  85AAF200  85AAF400  85AAF600  85AAF800  85AAFA00  85AAFC00

 [20  32]  [21  33]  [22  34]  [23  35]  [24  36]  [25  37]  [26  38]  [27  39]
           SPR2 150            SPR2 152            SPR3 158            SPR3 15A
               03C0                7C3E  (             03C0                7C3E
           0006A5D4            0006A5D6            0006A5FC            0006A5FE
 85AAFE00  85AB0000  85AB0200  85AB0400  85AB0600  85AB0800  85AB0A00  85AB0C00

 [28  40]  [29  41]  [2A  42]  [2B  43]  [2C  44]  [2D  45]  [2E  46]  [2F  47]
           SPR4 160            SPR4 162            SPR5 168            SPR5 16A
               03C0                7C3E                03C0                7C3E
           0006A624            0006A626            0006A64C            0006A64E
 85AB0E00  85AB1000  85AB1200  85AB1400  85AB1600  85AB1800  85AB1A00  85AB1C00

 [30  48]  [31  49]  [32  50]  [33  51]  [34  52]  [35  53]  [36  54]  [37  55]
           SPR6 170            SPR6 172            SPR7 178            SPR7 17A
               03C0                7C3E                03C0                7C3E
           0006A674            0006A676            0006A69C            0006A69E
 85AB1E00  85AB2000  85AB2200  85AB2400  85AB2600  85AB2800  85AB2A00  85AB2C00

Abbildung zeigt: Sprite-DMA Slots der 8 Sprites
 
Damit der Datafetch für den Spritekanal erfolgen kann muss in SPRxPOS vor dem
Erreichen des Slots eine neue gültige Position geschrieben werden und damit dann
auch die richtigen Spritedaten geholt werden muss auch zu diesem Zeitpunkt der
Spritepointer richtig eingestellt sein.
Daher bietet es sich an die Register in der folgenden Reihenfolge zu laden: 
SPRxPTL und dann SPRxPOS. Dann ist zum Zeitpunkt des Starts des Sprites auch der
Spritepointer richtig eingestellt.

Das Copper-Wait und die Copper-Moves müssen nun so erfolgen das dies rechtzeitig
vor dem Sprite-Datafetch erfolgt, spätestens jedoch hier:

	dc.w $vvhh,$fffe	; $vv09 (laut Test)	besser jedoch $vv07 für Sprite 0
	dc.w $0120,$hi-a	; hi-pointer address 
	dc.w $0122,$lo-a	; low-pointer address 
	dc.w $0140,$vshs	; 

wait: dc.w vv07,$fffe (spätestes wait mit drei folgenden copper-moves)
wait: dc.w vv(07+2*n),$fffe	(n-Spritenummer)					 

>v $2c
Line: 2C  44 HPOS 00   0:
 [00   0]  [01   1]  [02   2]  [03   3]  [04   4]  [05   5]  [06   6]  [07   7]
                               RFS0 03C            RFS1 1FE            RFS2 1FE
                                     *=                  *F

 993C6800  993C6A00  993C6C00  993C6E00  993C7000  993C7200  993C7400  993C7600

 [08   8]  [09   9]  [0A  10]  [0B  11]  [0C  12]  [0D  13]  [0E  14]  [0F  15]
           RFS3 1FE                      COP  08C            COP  120
                     W                       0120                0006
                                         0006A55C            0006A55E
 993C7800  993C7A00  993C7C00  993C7E00  993C8000  993C8200  993C8400  993C8600

 [10  16]  [11  17]  [12  18]  [13  19]  [14  20]  [15  21]  [16  22]  [17  23]
 COP  08C            COP  122            COP  08C            COP  140
     0122                AD30                0140                2C40
 0006A560            0006A562            0006A564            0006A566
 993C8800  993C8A00  993C8C00  993C8E00  993C9000  993C9200  993C9400  993C9600

 [18  24]  [19  25]  [1A  26]  [1B  27]  [1C  28]  [1D  29]  [1E  30]  [1F  31]
 COP  08C  SPR0 140  COP  08C  SPR0 142
     3901      0000      FFFE      8C31
 0006A568  0006AD30  0006A568  0006AD32
 993C9800  993C9A00  993C9C00  993C9E00  993CA000  993CA200  993CA400  993CA600

Abbildung zeigt: SPR0POS Einstellung vor Sprite-DMA Slots (im Test iO) 

>v$2c
Line: 2C  44 HPOS 00   0:
[00   0]  [01   1]  [02   2]  [03   3]  [04   4]  [05   5]  [06   6]  [07   7]
							RFS0 03C            RFS1 1FE            RFS2 1FE
									*=                  *F

22426600  22426800  22426A00  22426C00  22426E00  22427000  22427200  22427400

[08   8]  [09   9]  [0A  10]  [0B  11]  [0C  12]  [0D  13]  [0E  14]  [0F  15]
		RFS3 1FE                                          COP  08C
										W                       0120
															0006A55C
22427600  22427800  22427A00  22427C00  22427E00  22428000  22428200  22428400

[10  16]  [11  17]  [12  18]  [13  19]  [14  20]  [15  21]  [16  22]  [17  23]
COP  120            COP  08C            COP  122            COP  08C
	0006                0122                AD30                0140
0006A55E            0006A560            0006A562            0006A564
22428600  22428800  22428A00  22428C00  22428E00  22429000  22429200  22429400

[18  24]  [19  25]  [1A  26]  [1B  27]  [1C  28]  [1D  29]  [1E  30]  [1F  31]
COP  140            COP  08C            COP  08C
	2C40                3901                FFFE
0006A566            0006A568            0006A568
22429600  22429800  22429A00  22429C00  22429E00  2242A000  2242A200  2242A400

Abbildung zeigt: SPR0POS Einstellung vor Sprite-DMA Slots (im Test nicht iO)
; für dc.w $vv11,$fffe - hier reicht die Zeit nicht aus - obwohl davor 
 
Erfolgt die Änderung nachdem die DMA-Sprite Slots bereits passiert wurden wird
der Sprite data fetch erst in der nächsten Zeile ausgeführt und das Sprite
beginnt eine Zeile tiefer als gewollt. Aufgrund der feststehenden vertikalen 
Endposition endet das Sprite an der vorgesehenen Stelle wodurch die letzte 
Zeile des Sprites nicht angezeigt wird.

z.B. Das Sprite startet erst in der nächsten Zeile:
	move.l	#$2cb1fffe,d0		; wait			
	move.l	#$01402cd0,d1		; SPR0POS

Das vertikale Spritemultiplexing ohne Leerzeile zeigt Listing25b.s

Im Beispiel Listing25b2.s wird vertikales Spritemultiplexing über die gesamte
Bildschirmhöhe gezeigt.

Und im  Beispiel Listing25b3.s wird vertikales Spritemultiplexing über die gesamte
Bildschirmhöhe gezeigt wobei das Sprite Data Fetch für jeweils eine Zeile 
unterbrochen wird.


**** horizontales Spritemultiplexing ****
===============================================================================	

Beim horizontalen Spritemultiplexing muss als erstes ebenfalls die Bedingung
der vertikalen und horizontalen Startposition des Sprites bezogen auf die 
aktuelle Elektronenstrahlposition erfüllt sein.
Die Daten werden über Sprite-DMA nur einmal geholt können aber horizontal 
mehrfach angezeigt werden. Dafür müssen an den entsprechenden Stellen durch
den Copper, bpsw. durch eine Copper-Move Folge um im Raster von jeweils 
16 Pixeln zu bleiben bzw. durch Copper Waits und anschließendem Copper Move
die neuen SPRxPOS Werte in jeder Zeile des Sprites geschrieben werden.
Nur für das letzte Sprite in dieser Anordnung, wie für das alleinstehende
Sprite üblich, braucht dies nur für den Spritebeginn erfolgen.

Es müssen also keine Spritezeiger in der Copperliste verändert werden. Die
Hardware übernimmt das. Es ermittelt die entsprechenden Plane-Paar Wörter aus
der bekannten vertikalen Spritestartposition und der aktuellen vertikalen 
Elektronenstrahlposition. Ein Verändern der Spritepointer ist natürlich möglich
und würde dann auf andere Spritedaten zeigen.

Da zwei Copper Move zusammen 16 Pixel ergeben ließen sich so z.B. im Abstand
von 16 Pixeln Spritepaare im Attached Mode horizontal wiederholen.
Bedingt durch die Dauer von 16 Pixeln für einen Copper Wait sind horizontale
Wiederholungen nur alle 32 Pixel möglich. 
(Copper Wait+Copper Move = 16 Pixel + 8 Pixel=24 Pixel)

Hinweis: bis 4 Bitebenen:
Copper-Move benötigt	8 Pixel lowres
Copper-wait benötigt	16 Pixel lowres
Bei der Verwendung von mehr als 4 Bitebenen würde es die Möglichkeiten weiter 
einschränken.

Horizontales Spritemultiplexing hat also den Nachtteil einer größeren
Copper-Belastung pro Zeile.

Beispiele für das horizontale Spritemultiplexing zeigen Listing25c.s bis
Listing25c3.s.

Bei dynamischen vertikalen und horizontalen Spritemultimplexing muss auch immer
die Copperliste geändert werden. Hier empfiehlt es sich dann mit zwei 
Copperlisten zu arbeiten und zwar eine die gerade angezeigt wird und die andere
an der Veränderungen vorgenommen werden.
Denkbar wäre aber auch Copper-Interrupts einzusetzen um Copperlistebereiche,
die bereits überschritten wurden für das nächste Bild zu ändern, wenn es
zeitlich passt.

*******************************************************************************
*  Variante: 3 - über CPU bzw. Copper ("manueller Modus")					  *
*																			  *
*******************************************************************************

Als letzte Option gibt es noch die Möglichkeit die Spritedaten durch Ändern der
Bilddaten in SPRxDATA und SPRxDATB durch die CPU oder Copper direkt 
vorzunehmen. Dabei geht es also um die Anzeige von Spritedaten ohne Verwendung
von Sprite-DMA. Dies kann z.B. erreicht werden durch deaktivieren von 
Sprite-DMA während die Werte direkt in SPRxDATA und SPRxDATB geladen werden 
und das Sprite dadurch angezeigt wird.

Das Auslösen der Anzeige erfolgt dabei durch ein Schreiben in das Register 
SPRxDATA und ein Schreiben eines beliebigen Wertes in SPRxCTL beendet die 
Anzeige. Die vertikale Position VSTART kann dabei den Wert '0' haben, denn 
sie wird für die Aktivierung des Sprites nicht verwendet.

	dc.w	$140,$0080		; SPR0POS - nur Horizontale Position

Werden die Daten im Spritebuffer nicht geändert, werden sie sooft auf dem
Bildschirm ausgegeben bis das Sprite beendet wird. Dies ist z.B. interessant
für vertikale Säuleneffekte.

Diesen Effekt hatten wir in Listing7y1.s und Listing7y1.s gesehen.

Also:
	dc.w	$4007,$fffe		; Warte auf Zeile $40
	dc.w	$140,$0080		; SPR0POS - Horizontale Position
	dc.w	$142,$0000		; SPR0CTL - hier benötigt für z.B. Attached-Bit 
	dc.w	$146,$0e70		; SPR0DATB
	dc.w	$144,$03c0		; SPR0DATA - aktiviert Sprite

	dc.w	$6007,$fffe		; Warte auf Zeile $60
	dc.w	$142,$000		; SPR0CTL - "deaktiviert" den Sprite
	
Da die Daten in den Registern gewisserweise festgeschrieben sind, wird jede
Zeile das gleiche Muster angezeigt. Um in einer Zeile eine Änderung der Daten
zu erreichen, wäre eine Synchronisation mit der Zeile erforderlich um dann eine
gezielte Änderung der Daten vorzunehmen. Dies ist praktischweise am Besten mit
dem Copper möglich in dem dann in der Copperliste die SPRxDATA-und SPRxDATB-
Register mit den neuen Daten geladen werden.

Auch mit dieser Variante ist das mehrmalige Anzeigen horizontal nebeneinander
möglich. Ein Beispiel hierfür zeigte Listing7y3.s, Listing7y4.s und
Listing7y5.s.

SPRxPOS und SPRxCTL sind die zwei Steuerwörter am Anfang der Spritedefinition
mit den Angaben zur horizontalen und vertikalen Anfangsposition, sowie der Höhe.
Die Sprite-Bitplanedaten werden in die Register SPRxDATA und SPRxDATB geladen,
was normalerweise durch DMA erfolgt. Aus diesen Registern werden die Daten dann
über die Viedologik zur Anzeige gebracht.

*******************************************************************************
*  Spritemultiplexing mit Copperloops 										  *
*																			  *
*******************************************************************************

Den Vorteil, aber auch die Schwierigkeiten bei der Verwendung von 
Copperschleifen im Zusammenhang mit horizontalen und vertikalen
Spritemultiplexing zeigen die Beispiele Listing25d.s bis Listing25d3.s


*******************************************************************************
*  Sprite anzeigen ohne Bitplane DMA										  *
*																			  *
*******************************************************************************

Tatsächlich ist es möglich Sprites auch ohne Bitplane DMA anzuzeigen. Wie,
das zeigt das Beispiel Listing25e.s.


*******************************************************************************
*  Sprites in interlace														  *
*																			  *
*******************************************************************************

Wie es möglich ist Sprites auch in interlace anzuzeigen, zeigt: Listing25f.s.


*******************************************************************************
*  Overscan und Sprites (DDFSTRT)  											  *
*																			  *
*******************************************************************************

Bisher wurden immer nur funktionierende Sprite-Beispiele gezeigt, aber was man
auch im Hinterkopf haben sollte sind Sprite-Bitplane DMA Konflikte. Man hat
vielleicht schon mal gehört, dass wenn man horizontales Bitplanescrolling haben
möchte den DDFSTRT 16Pixel früher also bei $30 einstellen soll und das man 
dadurch das Sprites 7 verliert, weil Bitplane DMA Vorrang vor Sprite-DMA hat,
aber in diesem Zusammenhang gibt es auch noch einen OCS-Fehler von den man mal
gehört haben sollte. 

Mit Listing25g.s kann man die einzelnen Stufen durchspielen.

DDFSTRT $38 - keine Sprite slots werden gestohlen
DDFSTRT $30 - Sprite-DMA-Slot für Sprite 7 wird gestohlen
			- Sprite 6 beschädigt
DDFSTRT $28 - Sprite-DMA-Slot für Sprite 5 bis 7 wird gestohlen
			- Sprite 4 beschädigt
DDFSTRT $20 - Sprite-DMA-Slot für Sprite 3 bis 7 wird gestohlen
			- Sprite 2 beschädigt
DDFSTRT $18 - Sprite-DMA-Slot für Sprite 1 bis 7 wird gestohlen 
              (nur Sprite 0 bleibt)


*******************************************************************************
*  xxxxxx  																      *
*																			  *
*******************************************************************************



