;
;	Copperlist Example 3.
;
;	Written for OZAmiga by Chris Leathley.
;
;	move 2 copper lines up and down the screen
;



;
;	Branch offsets into the Amiga's rom kernal librarys (exec)
;
Forbid		=	-132		; turn off Multitasking
Permit		=	-138		; turn it back on again
CloseLibrary	=	-414		; open a library (from ram or disk)
OpenLibrary	=	-552		; close an opened library


; --------------------------------------------------------------------------

; a68k code
	SECTION	code,CODE,CHIP			; make sure in chip memory

; devpac code
;	SECTION	code,CODE_C			; make sure in chip memory

; --------------------------------------------------------------------------


;	program starts here
;
START:		clr.l	$0			; clear address 0

		move.l	$4,a6			; turn off multitasking
		jsr	Forbid(a6)

.wait_vb	cmp.b	#$FF,$00DFF006		; wait for vb to change
		bne.s	.wait_vb

		move.l	#THIRDCOPPER,$00DFF080	; insert new copperlist
		move.w	#$8280,$00DFF096	; use new control bits


;	wait for user to press the left mouse button and then exit program
;
MAIN_LOOP:	cmp.b	#$FF,$00DFF006		; wait for vertical blank
		bne.s	MAIN_LOOP

		move.w	#$0F00,$00DFF180

		bsr	MOVE_BAR

		move.w	#$0000,$00DFF180

;
;	when you the program you will off course notice the white line moving
;	up and down.  The bottom red line (about a quarter of the width of the
;	screen) is the time taken up by the MOVE_BAR routine.
;
;	The cmp.b #$FF,$00DFF006 only checks the vertical position and not the
;	horizontal.  Since our program is so fast it gets executed twice per
;	frame (vertical blank).  when the program exits the first time is will
;	check the mouse button, if not pressed it will wait for the "VB".  as
;	it is still on line #$FF then it checks out ok and runs the program
;	again.
;
;	to over come this, we put in a slight delay, to make sure when it does
;	the VB test again it isn't on the same line.
;
		move.w	#256,d0			; count down from 256 to 0
.delay		sub.w	#1,d0
		bne	.delay

;	try commenting the "bne" out, the line will move twice as fast now


		btst	#$06,$00BFE001		; left mouse button ?
		bne.s	MAIN_LOOP		; no? do it all again


;	program finished, exit back to dos
;
EXIT:		move.l	$4,a6			; exec pointer
		lea	GFX_NAME,a1		; library name
		moveq	#0,d0			; library version
		jsr	OpenLibrary(a6)		; open graphics library

		move.l	d0,a1			; d0 has pointer to library
		move.l	$0026(a1),$00DFF080	; restore original copperlist

		jsr	CloseLibrary(a6)	; close graphics library

		jsr	Permit(a6)		; turn back on multitasking
		moveq	#0,d0			; no errors
		rts				; return of amiga dos



;
;	This little routine will cycle the silver bar around on it's self
;
;	There are 15 colours in that bar, but we must only move 14 colours
;	up one position.  The first colour is saved before it is over
;	written then it's put in the last position when all the moves have
;	been done.
;
;	WHITE_BAR:	dc.w	$8009,$FFFE,$0180,$0FFF
;				0, 1, 2, 3, 4, 5, 6, 7, 8 (byte count)
;
MOVE_BAR:	lea	WHITE_BAR,a0		; copper list entry we want to
						; modify

		tst.b	DIRECTION		; are we going up or down?
		beq.s	.down			; if DIRECTION = 0 then we want
						; to go down

; the "	tst.b	DIRECTION " can also be written as " cmp.b   #$00,DIRECTION "


.up		move.b	CURRENT_Y,d0		; get current vertical wait pos
		move.b	d0,(a0)			; put it in the vwait section
						; only

		add.b	#$01,d0			; next vertical line
		move.b	d0,8(a0)		; put that in the next wait
						; position.

;	we must do two lines or the white bar will look like its growing
;	taller and shorter.  Try commenting out the two above lines in both
;	up and down routines.
;

		sub.b	#$01,CURRENT_Y		; next line going up

		cmp.b	#$30,CURRENT_Y		; have we reached the top
						; position?
		bne.s	.up.return		; if not then exit this program

		not.b	DIRECTION		; if so? then flip the state of
						; our direction flag.
						; ($FF will become $00)

.up.return	rts				; return to MAIN_LOOP


.down		move.b	CURRENT_Y,d0		; same as about but the line is
		move.b	d0,(a0)			; moving down.
		add.b	#$01,d0
		move.b	d0,8(a0)
		add.b	#$01,CURRENT_Y
		cmp.b	#$F0,CURRENT_Y		; $F0 is the maximum vertical
		bne.s	.up.return		; position we are using.
		not.b	DIRECTION
.down.return	rts



CURRENT_Y	dc.b	$80			; start vertical position
DIRECTION	dc.b	$00			; $00 = down, $FF = up
		EVEN



; --------------------------------------------------------------------------



;	graphics library name
;
GFX_NAME:	dc.b	'graphics.library',0
		EVEN


;
;	our third copperlist program
;
;	puts a single white line on the screen
;
THIRDCOPPER:	dc.w	$0180,$0000		; screen starts off black

		dc.w	$0100,$0000		; turn off bitplane display

WHITE_BAR:	dc.w	$F009,$FFFE,$0180,$0FFF	; white bar
		dc.w	$F109,$FFFE,$0180,$0000

		dc.w	$FFFF,$FFFE		; end of copper list
						; start vertical blank


; --------------------------------------------------------------------------


	END					; end of program



