
; Listing25f.s		Sprite in interlace 

	SECTION	ROCK'NROLL,CODE

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

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

			;5432109876543210
DMASET	EQU	%1000001110100000	; nur Copper und Bitplane DMA

WaitDisk	EQU	30

SCRBYTES	= 80				; Anzahl der Bytes für jede horizontale Zeile.
								; Daraus berechnen wir die Bildschirmbreite,
								; Multiplizieren von Bytes mit 8: normaler Bildschirm 320/8 = 40
								; z.B. 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		= 2					; 2 = HighRes (640*xxx) / 1 = LowRes (320*xxx)
SCR_LACE	= 1					; 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:
	move.l	#Bitplane,d0		; wohin pointen
	lea	Bplpointers1,a1			; COP-Pointer
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)	

	move.l	#Bitplane+80,d0		; wohin pointen
	lea	Bplpointers2,a1			; COP-Pointer
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	
	move.l	#Copperlist1,d0		; wohin pointen
	lea	CopPtr2,a1				; COP-Pointer
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	move.l	#Copperlist2,d0		; wohin pointen
	lea	CopPtr1,a1				; COP-Pointer
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
		
	move.l	#MeinSprite1,d0		; Adresse des Sprite in d0
	lea	SpritePointers1,a1		; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	move.l	#MeinSprite2,d0		; Adresse des Sprite in d0
	lea	SpritePointers2,a1		; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	
	move.l	#MeinSprite,d0		; Adresse des Sprite in d0
	lea	SpritePointers1+8,a1	; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	move.l	#MeinSprite,d0		; Adresse des Sprite in d0
	lea	SpritePointers2+8,a1	; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	bsr InitCopper				; Copperlist vorbereiten
	bsr LaceInt					; LOF-Bit testen und Copperpointer eintragen

	lea	$dff000,a5				; Custom Register Base in a5		
	move.w	#DMASET,$96(a5)		; DMACON - aktivieren bitplane, copper	
	move.l	#Copperlist1,$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			; Maus gedrückt?
	bne.s	Mouse

	rts
	

******************************************************************************
* Diese Routine bereitet den Interlace Sprite vor							 *
******************************************************************************

InitCopper:
	move.l	#$2c01fffe,d0		; 1. wait			
	move.l	#$01402c40,d1		; SPR0POS V=$2c, H=$40 
	move.l	#$01423300,d2		; SPR0CTL V=$39, H=0	$2c+13=$39
	move.l	#MeinSprite1+4,d3	; Adresse des Sprite in d0 auf Spritedaten!
								; nicht auf die Steuerwörter!		
	lea	CopperSprite1,a0		; Anfang des Spritebereichs in der Copperlist 
	move.l	d0,(a0)+			; setzt das erste wait	
;---------------
; Spritepointer setzen in Copperlist
	move.w	#$0120,(a0)+		; SPR0PTH
	swap d3	
	move.w	d3,(a0)+			; hi-Anteil Adresse eintragen
	move.w  #$0122,(a0)+		; SPR0PTL
	swap d3			
	move.w	d3,(a0)+			; low-Anteil Adresse eintragen
;----------------
    move.l	d1,(a0)+			; SPR0POS
	move.l	d2,(a0)+			; SPR0CTL

	move.l	#$fffffffe,(a0)		; Ende der Copperlist1
;-------------------------------
InitCopper2:
	move.l	#$2c01fffe,d0		; 1. wait			
	move.l	#$01402c40,d1		; SPR0POS V=$2c, H=$40 
	move.l	#$01423300,d2		; SPR0CTL V=$39, H=0	$2c+13=$39

	move.l	#MeinSprite2+4,d3	; Adresse des Sprite in d0 auf Spritedaten!
								; nicht auf die Steuerwörter!		
	lea	CopperSprite2,a0		; Anfang des Spritebereichs in der Copperlist 
	move.l	d0,(a0)+			; setzt das erste wait	
;---------------
; Spritepointer setzen in Copperlist
	move.w	#$0120,(a0)+		; SPR0PTH
	swap d3	
	move.w	d3,(a0)+			; hi-Anteil Adresse eintragen
	move.w  #$0122,(a0)+		; SPR0PTL
	swap d3			
	move.w	d3,(a0)+			; low-Anteil Adresse eintragen
;----------------
    move.l	d1,(a0)+			; SPR0POS
	move.l	d2,(a0)+			; SPR0CTL

	move.l	#$fffffffe,(a0)		; Ende der Copperlist2
	rts
	

******************************************************************************
* INTERLACE ROUTINE - Test Bit LOF (Long Frame) um zu wissen, ob Sie		 *
* gerade oder ungerade Zeilen anzeigen und entsprechend wechseln müssen.	 *
******************************************************************************

LaceInt:
	btst.b	#15-8,4(a5)			; VPOSR LOF bit?
	beq.s	MakeOdd				; wenn ja, zeigen Sie auf ungerade Zeilen
	
	move.l	#Copperlist1,$80(a5)	; Zeiger Copperlist
	rts

MakeOdd:
	move.l	#Copperlist2,$80(a5)	; Zeiger Copperlist
	rts
	
******************************************************************************

	SECTION	GRAPHIC,DATA_C
	
Copperlist1:
Bplpointers1:
	dc.w	$e0,0,$e2,0		; erste Bitplane

SpritePointers1:
	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

CopPtr1:
	dc.w 	$80,$0,$82,$0	; COP1LC auf Copperlist2 setzen 

	dc.w	$8e,DIWS		; DIWSTRT
	dc.w	$90,DIWST		; DIWSTOP
	dc.w	$92,DDFS		; DDFSTRT
	dc.w	$94,DDFST		; DDFSTOP

	dc.w	$102,0			; BPLCON1
	dc.w	$104,$24		; BPLCON2
	dc.w	$108,80			; BPL1MOD \ INTERLACE: modulo = Länge Zeile!
	dc.w	$10a,80			; BPL2MOD / um sie zu überspringen (die geraden)

				; 5432109876543210
;	dc.w	$100,%1001001000000100	; 1 bitplane, HIRES LACE 640x512
;							; Beachten Sie das Bit 2 Set für LACE!!

	dc.w	$100,BPLC0		; BPLCON0 -> lassen Sie es uns automatisch berechnen!
	
	dc.w	$180,$226		; COLOR00 - Hintergrund
	dc.w	$182,$0b0		; COLOR01 - plane 1 Position normal, und
							; der "klebende" Teil an der Spitze.

    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

CopperSprite1:
	dcb.l	10,0			; Raum für den Interlace Sprite	 
	dc.w 	$ffff,$fffe		; Ende Copperlist
	
;------------------------------------------------------------

Copperlist2:
Bplpointers2:
	dc.w	$e0,0,$e2,0		; erste Bitplane+80
SpritePointers2:
	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

CopPtr2:
	dc.w 	$80,$0,$82,$0	; COP1LC auf Copperlist1 setzen 

	dc.w	$8e,DIWS		; DIWSTRT
	dc.w	$90,DIWST		; DIWSTOP
	dc.w	$92,DDFS		; DDFSTRT
	dc.w	$94,DDFST		; DDFSTOP

	dc.w	$102,0			; BPLCON1
	dc.w	$104,$24		; BPLCON2
	dc.w	$108,80			; BPL1MOD \ INTERLACE: modulo = Länge Zeile!
	dc.w	$10a,80			; BPL2MOD / um sie zu überspringen (die geraden)

				; 5432109876543210
;	dc.w	$100,%1001001000000100	; 1 bitplane, HIRES LACE 640x512
;							; Beachten Sie das Bit 2 Set für LACE!!

	dc.w	$100,BPLC0		; BPLCON0 -> lassen Sie es uns automatisch berechnen!
	
	dc.w	$180,$226		; COLOR00 - Hintergrund
	dc.w	$182,$0b0		; COLOR01 - plane 1 Position normal, und
							; der "klebende" Teil an der Spitze.

    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

CopperSprite2:
	dcb.l	10,0			; Raum für den Interlace Sprite
	dc.w	$ffff,$fffe		; Ende 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 $a0	; 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.


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

MeinSprite1:		; Länge 13 Zeilen
Vstart1:
	dc.b $60	; Vertikale Anfangsposition des Sprite (von $2c bis $f2)
Hstart1:
	dc.b $d0	; Horizontale Anfangsposition des Sprite (von $40 bis $d8)
Vstop1:
	dc.b $67	; $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.


MeinSprite2:		; Länge 13 Zeilen
Vstart2:
	dc.b $60	; Vertikale Anfangsposition des Sprite (von $2c bis $f2)
Hstart2:
	dc.b $d0	; Horizontale Anfangsposition des Sprite (von $40 bis $d8)
Vstop2:
	dc.b $66	; $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	SCRBYTES*SCR_H		; 80*512 eine bitplane Hires int. 640x512

	end


Erklärung:

Normalerweise werden Sprites immer in lowres angezeigt auch wenn der Bildschirm
in interlace eingestellt ist.
Es ist allerdings möglich auch Sprites in interlace anzuzeigen. Dazu ist es
notwendig die Spritebilddaten in zwei Sprites zu trennen, wobei jede zweite
Zeile übersprungen wird. Die Spritehöhe muss auch auf die Anzahl der Zeilen
eingestellt werden. Sie reduziert sich in jedem Fall um die Hälfte.
Und die Anzeige des Sprites erfolgt durch den Wechsel der Copperlisten wobei
in den Copperlisten die entsprechenden Spritepointer zuvor eingestellt werden
müssen.
