

** CODE		VERTICAL SCROLLER
** CODER	MARC.B

; this code basically scrolls the screen vertically
; in the direction of the mouse movement
; and stops when the ends of the bitmap are reached
; (because i don't know how to wrap a vertical scroller back to the start)

		
	   
*************************************
*	  SYSTEM OFFSETS	    *
*************************************

execbase	equ	4
openlibrary	equ	-408
closelibrary	equ	-414
allocmem	equ	-198
freemem		equ	-210
forbid		equ	-132
permit		equ	-138
copymem		equ	-624


**********************************
*	CODE CONSTANTS		 *
**********************************

chip		equ	2
clear		equ	$10000


***********************************
*	INCLUDE FILE		  *
***********************************

	include	source:include/hardware.i

	lea	$dff000,a5		;custom base address
	move.l	#0,screen_offset	;clear screen offset
	move.l	#0,JOYTEST(a5)		;clear mouse register


	

**********************************************************
*	OPEN GFX LIBRARY AND SAVE SYSTEM COPPER		 *
**********************************************************

	move.l	execbase,a6
	move.l	#gfxname,a1
	moveq	#0,d0
	jsr	openlibrary(a6)
	tst	d0			
	beq	the_end			
	move.l	d0,gfxbase		
	move.l	d0,a0			;put gfxbase in a0 
	move.l	38(a0),systemcopper	;save the copper address 


****************************************************
*	ALLOCATE MEMORY FOR BIT PLANES		   *
****************************************************

	move.l	execbase,a6
	move.l	#(320/8*768)*2,d0	;memory for 2 bitplanes
	move.l	#chip+clear,d1		;chip memory and wipe it
	jsr	allocmem(a6)
	tst	d0			;fail 
	beq	exit			;yep (sell the AMIGA !!!)
	move.l	d0,bitbase		;save pointer
	bsr	load_pointers		;load into copper

*****************************************************
*	    COPY SCREEN TO CHIP RAM       	    *
*****************************************************

	move.l	execbase,a6
	move.l	bitbase,a1
	lea	screen,a0
	move.l	#(320/8*768)*2,d0
	jsr	copymem(a6)
	


***************************************************************
*		START CUSTOM COPPER LIST		      *
***************************************************************	

	move.l	#copper,COP1LCH(a5)
	move.l	#0,COPJMP1(a5)
	move.l	execbase,a6
	jsr	forbid(a6)

*************************************************************
*		    MAIN CODE LOOP    			    *
*************************************************************

wait
	
	move.l	VPOSR(a5),d5	;read current beam position
	and.l	#$0001ff00,d5	;mask all but the vertical pos
	lsr.l	#8,d5		;move them over
	cmp.w	#$0106,d5	;wait for end of display
	bne	wait
	bsr	test_mouse	;check mouse
	move.b	d1,mouse_pos	;save last mouse position
	btst	#6,CIAAPRA	;test left button
	beq	clean_up	;exit if pressed
	bra	wait

**********************************************************
*			RESTORE SYSTEM 			 *
**********************************************************

clean_up
	move.l	systemcopper,COP1LCH(a5)
	move.l	#0,COPJMP1(a5)
	move.l	execbase,a6
	jsr	permit(a6)
	move.l	execbase,a6		;free bitplane memory
	move.l	#(320/8*768)*2,d0
	move.l	bitbase,a1
	jsr	freemem(a6)

exit
	move.l	gfxbase,a1		;close the graphics library
	move.l	execbase,a6
	jsr	closelibrary(a6)
	
the_end
	rts				;exit from program


*****************************************************************
*	LOAD BITPLANE POINTERS INTO COPPER LIST   	        *
*****************************************************************

load_pointers
	
	lea	copper,a0
	move.w	d0,6(a0)	;load bitplane pointers into c list
	swap	d0
	move.w	d0,2(a0)
	swap	d0
	add.l	#$7800,d0
	move.w	d0,14(a0)
	swap	d0
	move.w	d0,10(a0)
	swap d0
	rts

	
********************************************************
*		 	TEST MOUSE		       *
********************************************************

test_mouse

	
	move.w	JOY0DAT(a5),d1	;read mouse counter
	and.w	#$ff00,d1	;keep y count only
	lsr.w	#8,d1		;move into first byte
	sub.b	d1,mouse_pos	;find direction
	beq	no_scroll	;mouse not moved
	bmi	scroll_down	;mouse moved up
	bpl	scroll_up	;mouse moved down

no_scroll
	rts




***********************************************
*		SCROLL SCREEN DOWN            *
***********************************************

scroll_down

	cmp.l	#0,screen_offset	;top of bitmap ?
	beq	minimum			;yes don't scroll
	sub.l	#160,screen_offset	;no,move up 4 lines
	bra	find_address		;find new bitplane address
minimum
	rts


***********************************************
*		SCROLL SCREEN UP              *
***********************************************

scroll_up
	cmp.l	#$5000,screen_offset	;bottom of bitmap ?
	bge	maximum			;yes don't scroll
	add.l	#160,screen_offset	;no,move down 4 lines
	bra	find_address		;find new address
maximum
	rts


**************************************************
*	   CALCULATE BITPLANE ADDRESS		 *
**************************************************

find_address

	move.l	screen_offset,d2
	move.l	bitbase,d0
	add.l	d2,d0
	bra	load_pointers


***********************************************************
*		   CUSTOM COPPER LIST			  *
***********************************************************


	SECTION		copper.list,CODE_C
copper
	dc.w	BPL1PTH,0000		;next 4 blank words
	dc.w	BPL1PTL,0000		;are where we load
	dc.w	BPL2PTH,0000		;the bitplane pointers
	dc.w	BPL2PTL,0000
	dc.w	SPR0PTH,0000
	dc.w	SPR0PTL,0000		;sprite 0 pointer
	dc.w	SPR1PTH,0000
	dc.w	SPR1PTL,0000		;sprite 1 pointer
	dc.w	SPR2PTH,0000
	dc.w	SPR2PTL,0000		;sprite 2 pointer
	dc.w	SPR3PTH,0000
	dc.w	SPR3PTL,0000		;sprite 3 pointer
	dc.w	SPR4PTH,0000
	dc.w	SPR4PTL,0000		;sprite 4 pointer
	dc.w	SPR5PTH,0000
	dc.w	SPR5PTL,0000		;sprite 5 pointer
	dc.w	SPR6PTH,0000
	dc.w	SPR6PTL,0000		;sprite 6 pointer
	dc.w	SPR7PTH,0000
	dc.w	SPR7PTL,0000		;sprite 7 pointer
	dc.l 	$2b01fffe		;wait for line 43
	dc.w	DIWSTRT,$2c81		;where we start displaying
	dc.w	DIWSTOP,$2cc1		;where we stop!
	dc.w	BPLCON0,$0200		;this is for Amiga 1000 owners
	dc.w	BPLCON2,$0000		
	dc.w	DDFSTRT,$0038		;where to start the horizontal display
	dc.w	DDFSTOP,$00d0		;and where we stop
	dc.w	BPLCON1,$0000
	dc.w	BPL1MOD,$0000		;not a scroller (horizontal)
	dc.w	BPL2MOD,$0000		;so these are blank
	dc.w	COLOR00,$0000		;background colour black
	dc.w	COLOR01,$0fff		;colour 1 
	dc.w	COLOR02,$022a		;colour 2 
	dc.w	COLOR03,$0e62 		;colour 3 
	dc.w	COLOR04,$0d80
	dc.w	COLOR05,$0c70
	dc.w	COLOR06,$0c71
	dc.w	COLOR07,$0b61
	dc.w	COLOR08,$0b62
	dc.w	COLOR09,$0a52
	dc.w	COLOR10,$0a52
	dc.w	COLOR11,$0fb0
	dc.w	COLOR12,$000f
	dc.w	COLOR13,$0f00
	dc.w	COLOR14,$0f82
	dc.w	COLOR15,$0ff3
	dc.w	COLOR16,$0000
	dc.w	COLOR17,$0d80
	dc.w	COLOR18,$0b61
	dc.w	COLOR19,$0a52
	dc.w	COLOR20,$0333
	dc.w	COLOR21,$0444
	dc.w	COLOR22,$0555
	dc.w	COLOR23,$0666
	dc.w	COLOR24,$0777
	dc.w	COLOR25,$0888
	dc.w	COLOR26,$0999
	dc.w	COLOR27,$0aaa
	dc.w	COLOR28,$0ccc
	dc.w	COLOR29,$0ddd
	dc.w	COLOR30,$0eee
	dc.w	COLOR31,$06f8
	dc.l	$2c01fffe		;wait for line 44
	dc.w	BPLCON0,$2200		;turn on bit planes
	dc.l	$fffffffe		;wait for the impossible
endcopper

copperlen	equ	endcopper-copper

	
************************************************************
*			VARIABLES	 		   *
************************************************************


gfxbase		dc.l 0
bitbase		dc.l 0
systemcopper	dc.l 0
mouse_pos	dc.w 0
screen_offset	dc.l 0
gfxname		dc.b 'graphics.library',0
scroll_flag	dc.b 0

screen	incbin	graphics/scroller.bmap


end
	
