
; Display Example 16. -- Dual Playfield Scrolling -- 

; Display is     320x256   ( 40x256x6 bytes ) in dual playfield mode.
; Playfield 1 is 320x512x3 ( 40x512x3 bytes )
; Playfield 2 is 640x256x3 ( 80x256x3 bytes )

; Bitplane Modulos = bit plane width - Display width - 2 = 80-40-2 = 38 bytes

		include		hardware.i
		include		HW_Macros.i
		include		HW_Start.i

; First, 'poke' address of playfield 1's bit planes into Copper list. Use a
;loop to do this

Main		COPBPLC		CopPlanes,pf1,(320/8)*512,3

; Now 'poke' address of playfield 2's bit planes into Copper list.

		COPBPL		CopPlanes2,pf2,(640/8)*256,3
		
; Set colours for second playfield manually

		lea		pf2+80*256*3,a0		a0->colour data
		moveq.l		#8-1,d0			num colours - 1
		lea		CopColours2,a1		a1->into Copper list
colr_loop1	move.w		(a0)+,2(a1)		copy colour
		addq.l		#4,a1			next register
		dbra		d0,colr_loop1

; Define address of Copper List

		STARTCOP	#MyCopper

; Enable bitplane and Copper DMA.

		move.w		#SETIT!DMAEN!COPEN!BPLEN,DMACON(a5)

; Install vertical blank interrupt handler and enable it.

		move.l		#NewLevel3,$6c		install
		
		move.w		#SETIT!INTEN!VERTB,INTENA(a5)

; Wait for user to press the left mouse button

mouse		btst		#6,CIAAPRA
		bne.s		mouse

; And exit.

		rts

;		************************
;		* Vert Blank Interrupt *
;		************************

; This handler first calls a routine that sets up the bit plane pointers and
;scroll values according to the value stored in 'Scroll'. Second, a routine
;is called that changes the value stored in 'Scroll'.

NewLevel3	lea		$dff000,a5		a5->hardware base

		bsr		DoScroll_H		horizontal scroll
		bsr		DoScroll_V		vertical scroll
		bsr		UpdateScroll_H		update horiz count
		
		move.w		INTREQR(a5),d0		get bits
		and.w		#VERTB!COPER!BLIT,d0
		move.w		d0,INTREQ(a5)		clear request
		rte					back to user mode

;		***************************
;		*   Scroll The Bitplane   *
;		***************************

; Uses the value stored in scroll to determine the position of the bip plane

DoScroll_H	move.l		Scroll_H,d0		num pixels to scroll
		divu		#16,d0
		
; Now high word of d0 contains scroll value in pixels and the low word the
;number of words to scroll. The number of words must be converted into the
;number of bytes:

		asl.w		#1,d0			x2

		moveq.l		#0,d1
		move.w		d0,d1			d1=num bytes
		
		swap		d0			get num bits
		moveq.l		#15,d2
		sub.w		d0,d2			make a copy
		move.w		d2,d0 
		asl.w		#4,d0
		or.w		#$f,d0

; At this point d0.w contains the scroll value and d1 the number of bytes
;to add to the start address of the bit plane data. Initialise the scroll
;value and bit plane pointers in the copper list

		move.w		d0,CopScroll+2		scroll values
		
		add.l		#pf2,d1			d1=bpl start addr
		moveq.l		#3-1,d0			bpl counter - 1
		lea		CopPlanes2,a0		a0->into Copper
StuffBpls	move.w		d1,6(a0)		low word of address
		swap		d1
		move.w		d1,2(a0)		high word of address
		swap		d1
		add.l		#80*256,d1		addr of next plane
		addq.l		#8,a0			next pointer in list
		dbra		d0,StuffBpls

		rts

;		***************************
;		*    Update Scroll Value  *
;		***************************

; Continually counts from 0 to 320 and back again. A separate routine is used
;to convert the scroll value and modify the Copper list

UpdateScroll_H	move.l		Scroll_H,d0
		move.l		direction_H,d1
		move.l		terminate_H,d2

		add.l		d1,d0		bump counter
		move.l		d0,Scroll_H	save new value
		cmp.l		d0,d2		change direction?
		bne.s		no_change	no, exit routine
		
		move.l		spare_H,terminate_H	switch dirn limits
		move.l		d2,spare_H
		neg.l		d1
		move.l		d1,direction_H	change direction

no_change	rts

;		*********************************
; 		* Scroll Playfield 1 Vertically *
;		*********************************

DoScroll_V	move.l		Counter,d0
		move.l		direction_V,d1
		move.l		terminate_V,d2

		add.l		d1,d0		bump counter
		move.l		d0,Counter	save new value
		cmp.l		d0,d2		change direction?
		bne.s		no_change_V	no, exit routine
		
		move.l		spare_V,terminate_V	switch dirn limits
		move.l		d2,spare_V
		neg.l		d1
		move.l		d1,direction_V	change direction

no_change_V	mulu		#40,d0		calculate offset
		add.l		#pf1,d0		form start address
		bsr		PutPointers	update Copper list
		rts

;		******************************
;		* Poke playfield 1 addresses *
;		*    into Copper list        *
;		******************************

; Entry		d0=start address of 1st bit planes data

PutPointers	moveq.l		#3-1,d1		number of bit planes - 1
		lea		CopPlanes,a0	a0->into Copper list

put_loop	move.w		d0,6(a0)	low word of address
		swap		d0
		move.w		d0,2(a0)	high word of address
		swap		d0
		add.l		#40*512,d0	addr of next bit plane
		addq.l		#8,a0		next pointer in Copper list
		dbra		d1,put_loop

		rts

;		***************************
;		*    Program Variables    *
;		***************************

Scroll_H	dc.l		0
direction_H	dc.l		1		1=right, -1=left
terminate_H	dc.l		320		change direction at ...
spare_H		dc.l		0

Counter		dc.l		0		offset
direction_V	dc.l		1		1=up, -1=down
terminate_V	dc.l		255		change direction at ...
spare_V		dc.l		0

;		***************************
;		*     CHIP Memory Data    *
;		***************************

;section		data custom,chip
		section		fish,data_c
		
MyCopper	CWAIT		0,38			wait for line 40

		CMOVE		DIWSTRT,$2c81		PAL -- 256 lines
		CMOVE		DIWSTOP,$2cc1
		CMOVE		DDFSTRT,$0030		LoRes + scroll
		CMOVE		DDFSTOP,$00d0
		CMOVE		BPL1MOD,-2		modulo = -2 bytes
		CMOVE		BPL2MOD,38		modulo = 38 bytes
		CMOVE		BPLCON0,$6600		6 bitplanes, DBPLF
CopScroll	CMOVE		BPLCON1,$000f		Scroll values
		CMOVE		BPLCON2,$0000		Ignore priority

CopPlanes	CMOVE		BPL1PTH,0		Bit plane pointers
		CMOVE		BPL1PTL,0		filled in by the
		CMOVE		BPL3PTH,0
		CMOVE		BPL3PTL,0
		CMOVE		BPL5PTH,0
		CMOVE		BPL5PTL,0

CopColours	CMOVE		COLOR00,$0000		The colours will be
		CMOVE		COLOR01,$0000		filled in by the
		CMOVE		COLOR02,$0000		program!
		CMOVE		COLOR03,$0000
		CMOVE		COLOR04,$0000
		CMOVE		COLOR05,$0000
		CMOVE		COLOR06,$0000
		CMOVE		COLOR07,$0000


CopPlanes2	CMOVE		BPL2PTH,0		Bit plane pointers
		CMOVE		BPL2PTL,0		filled in by the
		CMOVE		BPL4PTH,0		program!
		CMOVE		BPL4PTL,0
		CMOVE		BPL6PTH,0
		CMOVE		BPL6PTL,0

CopColours2	CMOVE		COLOR08,$0000
		CMOVE		COLOR09,$0000
		CMOVE		COLOR10,$0000
		CMOVE		COLOR11,$0000
		CMOVE		COLOR12,$0000
		CMOVE		COLOR13,$0000
		CMOVE		COLOR14,$0000
		CMOVE		COLOR15,$0000

		CEND					end of list

pf1		incbin		'pic5.bm'
pf2		incbin		'pic6.bm'

		end

		
