
; Listing6o.s	LINKS EN RECHTS-SCROLL VAN EEN PLAYFIELD, DAT
;		GROTER IS DAN HET BEELDSCHERM ZELF (HIER 640 PIXELS BREED)

;		RECHTER MUISKNOP PAUZEERT DE BEWEGING.


	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

; Let op! Om het beeld te 'centreren' moeten we 2 bytes verder naar
; 'achteren' pointen, waardoor het beeld 16 pixels naar voren gaat, omdat
; DDFSTART nu 16 pixels verder naar achteren begint (om de 'fout' uit de
; scroll te halen...).


;	Pointen naar onze bitplanes.

	MOVE.L	#BITPLANE-2,d0	
				
				
	LEA	BPLPOINTERS,A1	; COP - Pointer
	move.w	d0,6(a1)
	swap	d0		
	move.w	d0,2(a1)	

	bsr.w	Print		; Zet de text neer

	move.l	#COPPERLIST,$dff080	; COP1LC - onze COP
	move.w	d0,$dff088		; COPJMP1 - Start 'm
	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	Wacht		

	bsr.w	MEGAScroll	; Scroll het beeld...

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	


; De routine MEGASCROLLdient er alleen voor om de (al geziene) routine 
; 'Rechts:' 320 maal uit te voeren, en daarna 320 maal de routine 'Links:'.
; Om vast te houden hoe vaak we Links of Rechts hebben uitgevoerd, gebruiken
; we het Word HoeVaak, dat bij elk Frame 1 hoger wordt. Om een 640 Pixels
; groot beeld op een 320 pixels groot scherm te scrollen moet het 320 pixels
; verschoven worden:
;
; In het begin:
;	 _______________________________
;	|		|		|
;	|   Beeldscherm |		|
;	| <-   320   -> |		|
;	|		|		|
;	|<- Beeld in het geheugen 640 ->|
;	|		|		|
;	|		|		|
;	 -------------------------------
;
; En als we het 320 pixels gescrolld hebben:
;	 _______________________________
;	|		|		|
;	|		|  Beeldscherm  |
;	|		| <-  320   ->  |
;	|		|		|
;	|<- Beeld in het geheugen 640 ->|
;	|		|		|
;	|		|		|
;	 -------------------------------
;
; Met het eerste Bit van het word RechtsLinks houden we bij of we naar Links
; of naar rechts moeten scrollen. Hiervoor gebruiken we BCHG (Bit Change).
; Deze instructie kent u al uit een vorige les.


MEGAScroll:
	addq.w	#1,HoeVaak	; Signaliseer een doorloping
	cmp.w	#320,HoeVaak	; Zijn we op 320?
	bne.S	BeweegNogEens	; Zo niet, scroll verder.
	BCHG.B	#1,RechtsLinks	; Als we op 320 zijn wisselen we van 
	CLR.w	HoeVaak		; richting, en zetten "HoeVaak" op 0.
	rts

BeweegNogEens:
	BTST	#1,RechtsLinks	; Moeten we naar rechts of links gaan?
	BEQ.S	GaLinks
	bsr.s	Rechts		; Scrol een Pixel naar rechts
	rts

GaLinks:
	bsr.s	Links		; Scrol een Pixel naar links
	rts

; Dit Word telt hoe vaak we naar links/rechts zijn gegaan.

HoeVaak:
	DC.W	0

; Als Bit 1 van RechtsLinks 0 is, dan scrollt de routine naar links, anders
; (als het bit 1 is dus!) scrollt de routine naar rechts.

RechtsLinks:
	DC.W	0

; Deze routine scrollt een Bitplane naar Rechts.

Rechts:
	CMP.B	#$ff,MIJNBPCON1	; Maximale scroll?
	BNE.s	CON1ADDA	; Zo niet, scroll verder.

	LEA	BPLPOINTERS,A1	; Met deze 4 instructies halen we uit de
	move.w	2(a1),d0	; Copperlist het Adres, waarnaar $dff0e0
	swap	d0		; momenteel point en geven deze waarde in d0
	move.w	6(a1),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)

	move.w	d0,6(a1)   
	swap	d0	   
	move.w	d0,2(a1)   
	rts

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



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

LINKS:
	TST.B	MIJNBPCON1	
	BNE.s	CON1SUBBA	

	LEA	BPLPOINTERS,A1	
	move.w	2(a1),d0	
	swap	d0		
	move.w	6(a1),d0	

	addq.l	#2,d0		
				
	move.b	#$FF,MIJNBPCON1	

	move.w	d0,6(a1)    
	swap	d0	    
	move.w	d0,2(a1)    
	rts

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

;	Routine, die 8x8 Pixel grote letters print

PRINT:
	LEA	TEXT(PC),A0	
	LEA	BITPLANE,A3	
	MOVEQ	#25-1,D3	
PRINTREGEL:
	MOVEQ	#80-1,D0	

PRINTCHAR2:
	MOVEQ	#0,D2		
	MOVE.B	(A0)+,D2	
	SUB.B	#$20,D2		
				
	MULU.W	#8,D2		
				
	MOVE.L	D2,A2
	ADD.L	#FONT,A2	

	MOVE.B	(A2)+,(A3)	; Teken Lijn 1 van de letter
	MOVE.B	(A2)+,80(A3)	; Teken Lijn 2	"	"
	MOVE.B	(A2)+,80*2(A3)	; Teken Lijn 3  "	"
	MOVE.B	(A2)+,80*3(A3)	; Teken Lijn 4  "	"
	MOVE.B	(A2)+,80*4(A3)	; Teken Lijn 5  "	"
	MOVE.B	(A2)+,80*5(A3)	; Teken Lijn 6  "	"
	MOVE.B	(A2)+,80*6(A3)	; Teken Lijn 7  "	"
	MOVE.B	(A2)+,80*7(A3)	; Teken Lijn 8  "	"

	ADDQ.w	#1,A3		
	
	DBRA	D0,PRINTCHAR2	; PRINT D0 (80) TEKENS PER REGEL
 
	ADD.W	#80*7,A3	; "Return"

	DBRA	D3,PRINTREGEL	; We printen D3 regels.
	
	RTS
	

TEXT:
             ;            1111111111222222222233333333334
             ;   1234567890123456789012345678901234567890
	dc.b	'  EERSTE REGEL IN  HIRES 640  PIXEL  BRE' ; 1a \ REGEL 1
	dc.b	'EDTE!  -- -- -- Ook nog eerste regel....' ; 1b /
	dc.b	'                U kunt een HEEL LANG    ' ; 2  \ REGEL 2
	dc.b	' verhaal kwijt op dit scherm!           ' ;    /
	dc.b	'     /\  /                              ' ; 3
	dc.b	'                                        ' ;
	dc.b	'    /  \/                               ' ; 4
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 5
	dc.b	'                                        ' ;
	dc.b	'        BLA Bla BlA bLa                 ' ; 6
	dc.b	'                     Bla BLA bla BlA bLa' ;
	dc.b	'                                        ' ; 7
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 8
	dc.b	'                                        ' ;
	dc.b	'Digital Mozart is proud to present to yo' ; 9
	dc.b	'u the ASSEMBLER-cursus in 100 % DUTCH!  ' ;
	dc.b	'                                        ' ; 10
	dc.b	'                                        ' ;
	dc.b	'   1234567890 !@#$%^&*()_+|\=-[]{}      ' ; 11
	dc.b	'       TECHNISCHE ZENDTEST              ' ;
	dc.b	'                                        ' ; 12
	dc.b	'                                        ' ;
	dc.b	'     TO BE OR NOT TO BE, THAT IS THE QUE' ; 13
	dc.b	'STION... YOU ARE!                       ' ;
	dc.b	'                                        ' ; 14
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 15
	dc.b	'                                        ' ;
	dc.b	'  Heel lang geleden was er eens         ' ; 16
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 17
	dc.b	'                                        ' ;
	dc.b	'  een boze heks en die wilde            ' ; 18
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 19
	dc.b	'                                        ' ;
	dc.b	'  al jaren wraak nemen op de koning     ' ; 20
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 21
	dc.b	'                                        ' ;
	dc.b	'  maar ze had nog nooit haar kans       ' ; 22
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 23
	dc.b	'                                        ' ;
	dc.b	'  gekregen. Totdat op een dag...        ' ; 24
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 25
	dc.b	'                                        ' ;
	dc.b	'                                        ' ; 26
	dc.b	'  Bla Bla Bla Bla Bla Bla Bla Bla       ' ;


	EVEN
	
	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,$0030	; DdfStart (vanwege de Scroll aangepast)
	dc.w	$94,$00d0	; DdfStop
	dc.w	$102		; BplCon1
	dc.b	0		; hoogwaardig Byte van $dff102
MIJNBPCON1:
	dc.b	0		; laagwaardig Byte van $dff102
	dc.w	$104,0		; BplCon2
	dc.w	$108,40-2	; Bpl1Mod ( 40 voor een beeld dat 640 breed
	dc.w	$10a,40-2	; Bpl2Mod  is, -2 om DDFSTART uit te lijnen)

		    ; 5432109876543210
	dc.w	$100,%0001001000000000  ; Bits 12 aan - 1 Bitplane Lowres

BPLPOINTERS:
	dc.w $e0,$0000,$e2,$0000	;1e Bitplane

	dc.w	$0180,$103	; Color0 - Achtergrond
	dc.w	$0182,$4ff	; Color1 - TextKleur

	dc.w	$FFFF,$FFFE	; Einde van de Copperlist

;	Font...

FONT:
;	incbin	"metal.fnt"	
;	incbin	"normal.fnt"	
	incbin	"nice.fnt"	

	SECTION MIJNPLANE,BSS_C	

BITPLANE:
	ds.b	80*256	; 1 Bitplane, 640x256 breed (als Hires)

	end

In deze listing is een enkele Nieuwigheid, namelijk het scrollen van een
'plaatje' groter dan het beeldscherm zelf. Allereerst een woordje over de
modulo registers: Bij een beeldscherm in LowRes met normale DIWSTART/STOP
waarden is de modulo 40,het beeld wordt dus als 40 byte breed behandeld.
Als we echter een beeld in het geheugen hebben dat 640 pixels breed is,
zoals hier het geval is, dan moeten we de modulo veranderen. Dat het beeld
groter is dan 320 pixels breed zal de copper een worst zijn; Deze neemt
gewoon aan dat de modulo 40 is. We kunnen dit echter veranderen met de 
registers BPL1MOD en BPL2MOD. Een:

	dc.w	$108,40	 ; Bpl1Mod (40 voor een 640 Pixel breed Beeld)
	dc.w	$10a,40	 ; Bpl2Mod

is dus voldoende.
Om naar het einde van iedere 320 Pixels brede lijn (40 bytes) te springen,
om de 40 overblijvende bytes (321-640) over te slaan, en om met het 
aanwijzen van de volgende lijn te beginnen:


	 40 Bytes	 40 Bytes (Iedere keer met Modulo = 40 overslaan.)
	 _______________________________
	|		|		|
	|   Beeldscherm |		|
	| <-   320  ->  |		|
	|		|		|
	|<- Beeld in het geheugen 640 ->|
	|		|		|
	|		|		|
	 -------------------------------

Nu we het rechter deel van het plaatje van 640 pixels op een 320 pixels 
breed beeld hebben getoond, door de modulo op 40 te zetten, moeten we een
aanpassing doen als in listing6n.s, om de 'scrollfout' te verhelpen. De
eerste 16 pixels moeten 'verstopt' worden. Daarvoor laten we het beeld
16 pixels eerder beginnen, door DDFSTART te veranderen:

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

Omdat ne het beeldscherm alle 42 bytes een nieuwe lijn neemt (een soort
return), moeten we dat uitlijnen, door 2 van de modulo af te trekken:

	dc.w	$108,40-2  ; Bpl1Mod (40 voor een 640 breed Beeld, -2
	dc.w	$10a,40-2  ; Bpl2Mod om DDFSTART uit te lijnen).

In feite kan men zeggen dat en scroll van dit type 'moeilijk' is. De 
moeilijkheid ligt echter gewoon in het modulo/ddfstart/bitplane-systeem. Als
u dit begrijpt is er niet veel moeilijks aan.

Er is nog een nieuwigheid tegenover listing6n.s:

; Let op! Om het beeld te 'centreren' moeten we 2 bytes verder naar
; 'achteren' pointen, waardoor het beeld 16 pixels naar voren gaat, omdat
; DDFSTART nu 16 pixels verder naar achteren begint (om de 'fout' uit de
; scroll te halen...).


;	Pointen naar onze bitplanes.

	MOVE.L	#BITPLANE-2,d0	
				
Omdat we de eerste 16 Pixels 'verstopt' hebben, verdwijnen dus ook de eerste
twee letters van het scherm (8 pixels per letter, 2*8=16). Maar door het
verschuiven over 16 pixels zien we ook de eerste 16 pixels correct, en niet
naar links verschoven als in listing6n.s. Probeer eens de -2 van 
"Move.l#BITPLANE-2,d0" te verwijderen en zet een ";" voor de routine:

;	bsr.w	MEGAScroll

om een stilstaand beeld te krijgen. U zult zien dat de eerste 16 pixels
verdwenen zijn, en dat er aan de rechterkant 16 teveel zijn. Het plaatje
start nml. 16 pixels voor de norm. Om dat te bewijzen,'onthullen' we de 
eerste 16 pixels als volgt:

	dc.w	$8e,$2c71	; DiwStrt ($81-16=$71)

Daar zijn de 'verstopte' pixels! Zet nu weer de -2 op zijn plaats, en
verwijder de ";" voor de routine, en u zult zien hoe dat de fout er weer is!