
; Listing6n.s	Horizontale Scroll over meer dan 16 pixels, door gebruik
;		van BPLCON1 en de BitplanePointers.

;		RECHTER MUISKNOP OM NAAR LINKS TE SCROLLEN!.

	SECTION	CIPenCOP,CODE

Begin
	move.l	4.w,a6		; Execbase
	jsr	-$78(a6)	; Disable
	lea	GfxName(PC),a1	
	jsr	-$198(a6)	; OpenLibrary
	move.l	d0,GfxBase	;
	move.l	d0,a6
	move.l	$26(a6),OldCop	; Opslaan oude Cop

;	Pointen naar onze bitplanes

	MOVE.L	#PIC,d0		; Waarnaartoe pointen
	LEA	BPLPOINTERS,A1	; COP - Pointers
	MOVEQ	#2,D1		; Aantal Bitplanes -1 (hier 3)
				; voor de DBRA - cyclus
POINTBP:
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	swap	d0		;
	ADD.L	#40*256,d0	; + Lengte Bitplane
	addq.w	#8,a1
	dbra	d1,POINTBP

	move.l	#COPPERLIST,$dff080	; COP1LC - onze COP
	move.w	d0,$dff088		; COPJMP1 - Starten onze COP
	move.w	#0,$dff1fc		; FMODE - Deactiveert AGA
	move.w	#$c00,$dff106		; BPLCON3 - Deactiveert AGA

mouse:
	cmpi.b	#$ff,$dff006	
	bne.s	mouse
	
	btst	#2,$dff016	
	beq.s	GaLinks	

	bsr.w	Rechts		
				
	bra.s	Wacht

GaLinks:
	bsr.w	Links		; Beweegt Beeld naar links

Wacht:
	cmpi.b	#$ff,$dff006	
	beq.s	Wacht		

	btst	#6,$bfe001	
	bne.s	mouse

	move.l	OldCop(PC),$dff080	; COP1LC - Pointer naar originele
					; Copperlist
	move.w	d0,$dff088		; COPJMP1 - start 'm

	move.l	4.w,a6
	jsr	-$7e(a6)	; Enable
	move.l	GfxBase(PC),a1
	jsr	-$19e(a6)	; Closelibrary 
	rts


; DATA


GfxName:
	dc.b	"graphics.library",0,0
GfxBase:
	dc.l	0
OldCop:
	dc.l	0


; Deze routine laat het beeld naar rechts scrollen. We gebruiken daarvoor
; BPLCON1 en de bitplanepointers in de copperlist. MIJNBPCON1 is het byte
; van BPLCON1

Rechts:
	CMP.B	#$ff,MIJNBPCON1	; Zijn we bij de maximale scroll?
	BNE.s	CON1ADDA	; zo niet, scroll nog een pixel

	LEA	BPLPOINTERS,A1	; Met deze 4 aanwijzingen halen we uit de
	move.w	2(a1),d0	; Copperlist het Adres, waarnaar $dff0e0
	swap	d0		; momenteel point, en zetten die waarde
	move.w	6(a1),d0	; in d0

	subq.l	#2,d0	   ; Point 16 Bit verder naar achteren, het beeld
			   ; scrollt 16 Pixels naar Rechts
	clr.b	MIJNBPCON1 ; Wist de Hardwarescroll van BPLCON1 ($dff102)
			   ; want we hebben al 16 pixels gescrolld, en
			   ; moeten weer bij 0 beginnen.

	LEA	BPLPOINTERS,A1	; Pointer in de COPPERLIST
	MOVEQ	#2,D1		; Aantal Bitplanes -1 (hier 3)

POINTBP2:
	move.w	d0,6(a1)    
	swap	d0	    
	move.w	d0,2(a1)    
	swap	d0	    
	ADD.L	#40*256,d0  
	addq.w	#8,a1	    
	dbra	d1,POINTBP2 
	rts

CON1ADDA:
	add.b	#$11,MIJNBPCON1 ; scroll 1 Pixel naar voren
	rts

;	Routine, die naar Links scrollt, identiek aan de vorige:

LINKS:
	TST.B	MIJNBPCON1	; Zijn we bij de minimale scroll (00)?
	BNE.s	CON1SUBBA	; Zi niet, scroll nog een pixel

	LEA	BPLPOINTERS,A1	; Met deze 4 aanwijzingen halen we uit de
	move.w	2(a1),d0	; Copperlist het Adres, waarnaar $dff0e0
	swap	d0		; momenteel point, en zetten die waarde
	move.w	6(a1),d0	; in d0
	
	addq.l	#2,d0		; point 16 Bit verder naar voren, het beeld
				; scrollt 16 Pixels naar Links
	move.b	#$FF,MIJNBPCON1	; Hardwarescroll op 00 (BPLCON1, $dff102)


	LEA	BPLPOINTERS,A1	; Pointer in de COPPERLIST
	MOVEQ	#2,D1		; Aantal Bitplanes -1 (hier 3)
POINTBP3:
	move.w	d0,6(a1)    
	swap	d0	    
	move.w	d0,2(a1)    
	swap	d0	    
	ADD.L	#40*256,d0  ; + Lengte Bitplane 
	addq.w	#8,a1	    
	dbra	d1,POINTBP3 
	rts

CON1SUBBA:
	sub.b	#$11,MIJNBPCON1 ; scroll 1 Pixel naar achteren
	rts



	SECTION GRAPHIC,DATA_C

COPPERLIST:
	; Sprites uit...
	dc.w	$120,$0000,$122,$0000,$124,$0000,$126,$0000,$128,$0000 
	dc.w	$12a,$0000,$12c,$0000,$12e,$0000,$130,$0000,$132,$0000
	dc.w	$134,$0000,$136,$0000,$138,$0000,$13a,$0000,$13c,$0000
	dc.w	$13e,$0000

	dc.w	$8E,$2c81	; DiwStrt (Registers met Normaalwaarden)
	dc.w	$90,$2cc1	; DiwStop
	dc.w	$92,$0038	; DdfStart
	dc.w	$94,$00d0	; DdfStop
	dc.w	$102		; BplCon1
	dc.b	0	      	; hoogwaardig Byte van $dff102, niet 
				; gebruikt
MIJNBPCON1:
	dc.b	0		; laagwaardig Byte van $dff102, wel gebruikt
	
	dc.w	$104,0		; BplCon2
	dc.w	$108,0		; Bpl1Mod
	dc.w	$10a,0		; Bpl2Mod
	
		    ; 5432109876543210
	dc.w	$100,%0011001000000000  ; Bits 12 +13 aan! (3 = %011)

BPLPOINTERS:
	dc.w $e0,$0000,$e2,$0000	;1e Bitplane
	dc.w $e4,$0000,$e6,$0000	;2e Bitplane
	dc.w $e8,$0000,$ea,$0000	;3e Bitplane

	dc.w	$0180,$000	; Color0
	dc.w	$0182,$475	; Color1
	dc.w	$0184,$fff	; Color2
	dc.w	$0186,$ccc	; Color3
	dc.w	$0188,$999	; Color4
	dc.w	$018a,$232	; Color5
	dc.w	$018c,$777	; Color6
	dc.w	$018e,$444	; Color7
 
	dc.w	$FFFF,$FFFE	; Einde van de Copperlist
	
	dcb.b	80*40,0 ; Stuk geheugen 'wissen'

PIC:
	incbin	"amiga.320*256*3"	; Plaatje in Raw

	dcb.b	40,0			; Zie boven...


	end

Vreselijk he? Dat neven-effect aan de linkerkant. Om dit te verhelpen hoeft
u echter geen ingenieur te zijn. Gewoon twee dingetjes veranderen. 
Natuurlijk eerst de verklaring over het waarom en hoe:
De DMA-kanalen worden niet over de beweging van het beeld geïnformeerd,
en zijn daardoor dus onvoorbereid (en te laat) om de eerste 16 pixels bij
te werken. Wat we daar tegen kunnen doen? Niets.
Niets? hoor ik u denken.. Nee,niets. Maar hoe doen al die spellen dat dan?
Ik zal het uitleggen: We onttrekken dit lelijke effect gewoon aan het oog, 
en we zien niets meer (maar het is er wel nog!).
Hoe? Weet u nog DIWSTART en DIWSTOP? Deze bepalen de grootte van het beeld
waarop we de pixels tonen. Het is dan ook logisch als we het videobeeld
gewoon 16 pixels meer naar rechts laten beginnen het probleem wordt 
opgelost:

	dc.w	$8E,$2c91	; DiwStrt ($81+16=$91)

Probeert u deze instructie maar eens, en zie het verschil! Maar ook als dit
probleem is verholpen krijgen we weer een ander: We hebben nog maar 304 
pixels tot onze beschikking i.p.v. 320. En dan is alles ook nog verschoven!
Maar de Registers DDFSTART en DDFSTOP komen te hulp: Deze registers gaan
over de grootte van het videobeeld, maar op een andere manier. DIWSTART en
DIWSTOP maken een stuk zwart zoals hier te zien is:

	#####################
	#####################
	#####		#####
	#####	Beeld	#####
	#####		#####
	#####		#####
	#####		#####
	#####		#####
	#####		#####
	#####################
	#####################

DFFSTART en DFFSTOP zijn anders: hiermee veranderen we de werkelijke Lengte
van een lijn; als we b.v. de lijn 16 pixels langer maken, en dus daarmee
het beeld 'opblazen' tot 336 pixels per lijn (dus 42 bytes per lijn i.p.v
40 bytes per lijn) dan moeten we dus ook 42 bytes verwerken. De OVERSCAN
mode die de over de normale 320x256 of 640x256 resoluties heen gaat doet dit
ook op deze manier. Hierbij wordt het beeld dan ook met DIWSTART en DIWSTOP
'vergroot'.

Terug nar ons probleem: We moeten opletten dat deze fout die 16 pixels breed
is buiten het zichtsveld valt. We moeten met een DFFSTART het beeld 16 
pixels meer naar rechts beginnen, en hem ook 16 pixels verder laten eindigen
en de waarden van DIWSTART/DIWSTOP gelijk laten. Daardoor zullen we altijd
320x256 pixels zien, maar het werkelijke scherm is 336 pixels breed, en de
fout 'gebeurt' buiten het scherm. Het beeld wordt daardoor 42 bytes breed,
en dus moeten we deze 2 bytes ( 16 pixels ) voor elke lijn per FRAME
uitlijnen.
Hoe doen we dit, aan het einde van elke lijn 2 bytes terug te gaan, om een
lijn correct te tonen? Kortom dat we de 2 bytes 'opheffen'? Als we de
Modulo 2 lager maken! In ons geval moeten we dan de volgende veranderingen
aanbrengen: 

	dc.w	$92,$30		; DDFSTART = $30 (Beeldscherm start
				; 16 Pixels vroeger, en verbreedt zich
				; dus tot 42 Bytes Per lijn; 336 Pixels
				; Breedte, maar de DIWSTART "verstopt"
				; deze eerste 16 Pixels met de fout.


	dc.w	$108,-2		; MODULO = -2, We moeten de eerste 16
	dc.w	$10a,-2		; Pixels "overslaan", als we ze twee maal
				; laten lezen.


Breng deze veranderingen aan, en zet DIWSTART weer terug:

	dc.w $8E,$2c81 ; DiwStrt

Nu is de scroll PERFECT. Het enige nadeel van deze methode is dat op deze
manier Sprite7, (dus de laatste) verdwijnt.

P.S.: Als u een beetje wilt spoineren, wat de fout buiten het beeld doet,
en OF hij nog bestaat, dan laat u DIWSTART 16 pixels eerder beginnen:

	dc.w	$8E,$2c71	; DiwStrt

De fout is er nog!! Maar nu ziet niemand 'm.

Heeft u gezien hoe makkelijk we deze 'fout' kunnen verbeteren? Gewoon dus
DDFSTART 16 pixels eerder laten beginnen (bij $30) en 2 van de MODULO 
aftrekken.