;
;	Bitplane Example 10.
;
;	Written for OZAmiga by Chris Leathley.
;
;	use the hi-res picture and display it on a lo-res screen, scrolling
;	it from side to side.
;
;	this display changes the data fetch start position half way down the
;	screen to illistrate how the HSCROLL register upsets a normal display
;


;
;	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)


;
;	set up bitplane address into copper list program before copper is
;	turned on
;
		move.l	#PICTURE,d0		; move "ADDRESS" of picture	
						; into d0 (longword)
		move.w	d0,BP1LO+2		; store bottom q6 bits into
						; copperlist.  $00E2l0
						; we use +2 to skip the first
						;`word (ie $00E2) and put the
						; data in the "0" word
		swap	d0			; swap upper 16 bits with
						; lower 16 bits in d0.
		move.w	d0,BP1HI+2		; store upper 16 bits


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

		move.l	#COPPERLIST,$00DFF080	; insert new copperlist
		move.w	#$8380,$00DFF096	; use new control bits
						; (turn on copper & bitplane dma)


;	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

		bsr	SCROLL_WARNING

;	put in our little delay otherwise the scroll code will execute
;	many times while the raster line is still on postion $FF

		move.w	#256,d0			; count down from 256 to 0
.delay		sub.w	#1,d0
		bne	.delay

		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



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



;
;	scroll warning bitmap (640 pixels wide) left and right in lo-res
;	(displaying only 320 pixels at a time)
;
SCROLL_WARNING:	tst.w	SCROLL_DIRECTION	; test direction flag
		bne	.right			; 0 = left, 1 = right

.left		sub.w	#1,SCROLL_VALUE		; subtract 1 from x position
		tst.w	SCROLL_VALUE		; are we at 0 yet?
		bne	.set
		move.w	#1,SCROLL_DIRECTION	; yes so now go right
		bra	.set

.right		add.w	#1,SCROLL_VALUE
		cmp.w	#320,SCROLL_VALUE	; at max right position
						; the bitplane width is 640
						; pixels but since we are
						; allready displaying 320
						; pixels we only need to scroll
						; the difference (320)
		bne	.set
		move.w	#0,SCROLL_DIRECTION	; now go left

.set		move.l	#0,d0
		move.w	SCROLL_VALUE,d0		; get x scroll value
		move.l	d0,d1			; move to a temporary regisiter
		divu	#16,d1			; calculate number of "words"
						; into bitplane pointers

		mulu	#2,d1			; convert result from bytes
						; to "words".  (bitplane pointers
						; must be a EVEN address)

		not.b	d0			; invert scroll offset
		and.w	#$000F,d0		; clip offset to range ($0 - $F)

		move.w	d0,d2			; move to temp reg.
		lsl.w	#4,d2			; shift scroll value 4 bits to
						; the left ($xF -> $F0)
		or.w	d2,d0			; mix ODD and EVEN scroll values
		move.w	d0,HSCROLL_COP+2	; put result into copperlist

		move.l	#PICTURE,d0		; base address of picture
		add.l	d1,d0			; add number of "words" onto
						; picture start address.

		move.w	d0,BP1LO+2		; set bitplane pointers
		swap	d0
		move.w	d0,BP1HI+2
		rts



SCROLL_DIRECTION	dc.w	1		; (start going right)
SCROLL_VALUE		dc.w	0


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



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



;
;	our copperlist program
;
COPPERLIST:	dc.w	$0180,$0000		; screen starts off black

		dc.w	$0120,0,$0122,0		; don't worry about this just
		dc.w	$0124,0,$0126,0		; yet as all it does is set
		dc.w	$0128,0,$012A,0		; all sprite positions to zero
		dc.w	$012C,0,$012E,0		; so no wondering sprites
		dc.w	$0130,0,$0132,0		; appear on the screen
		dc.w	$0134,0,$0136,0
		dc.w	$0138,0,$013A,0
		dc.w	$013C,0,$013E,0

BP1HI		dc.w	$00E0,0			; bitplane 1 address pointers
BP1LO		dc.w	$00E2,0

		dc.w	$100,$1200		; turn on 1 bitplane (lo-res)

HSCROLL_COP	dc.w	$102,0			; hardware scroll to be zero
		dc.w	$104,0			; bitplane - sprite priority
		dc.w	$08E,$2C81		; window start (top left)
		dc.w	$090,$2CC1		; window stop (bottom right)
						; (STANDARD PAL DISPLAY VALUES)

		dc.w	$092,$30		; bitplane DMA start (16 bits
						; 			early)
		dc.w	$094,$d0		; bitplane DMA stop
		dc.w	$108,40-2		; odd modulo (adjusted for early
						;		data fetch start)
		dc.w	$10A,40-2		; even modulo

		dc.w	$182,$FF0		; colour 1 = yellow

		dc.w	$2B09,$FFFE,$180,$F00	; red line
		dc.w	$2C09,$FFFE,$180,$000	; screen back to black

;
;	set the data fetch back to normal value (must also set bitplane modulos)
;	this will show you how the HSCROLL regisiter, shifts the picture out
;	to the left (dosn't look very nice)
;
		dc.w	$A409,$FFFE,$180,$005	; blue background
		dc.w	$092,$38		; bitplane DMA start
		dc.w	$108,40			; odd modulo
		dc.w	$10A,40			; even modulo

		dc.w	$FFDF,$FFFE		; skip NTSC vertical blank

		dc.w	$2C09,$FFFE,$180,$F00	; another red line
		dc.w	$2D09,$FFFE,$180,$000

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


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


;
;	include raw picture data into assembly code
;
PICTURE:	INCBIN	oz.warning.raw


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



	END					; end of program

