
;-------------------------------------------------------------------------
; BLOCK-SCROLLER
;-------------------------------------------------------------------------
; Programmed by Lars Haugseth 9/12-92      - PAL only -
;-------------------------------------------------------------------------
; CONSTANTS
;-------------------------------------------------------------------------

EXECBASE	= 4

CUSTOMBASE	= $DFF000		; Custom-chips register offset

OpenLibrary	= -408			; Library function offsets
CloseLibrary	= -414
VBeamPos	= -384

SW		= 44			; Width of screen in bytes
SH		= 256			; Height of screen in pixels
MX		= 32			; Maximum pages of scrolling

;-------------------------------------------------------------------------
; MACROS
;-------------------------------------------------------------------------

WRAST:	MACRO				; Wait for a specific rasterpos.
	movem.l	d0-a6,-(SP)
	move.l	GFXBASE,a6
\@1	jsr	VBeamPos(a6)
	cmp.w	#\1,d0
	bne.s	\@1
	movem.l	(SP)+,d0-a6
	ENDM

WBLIT:	MACRO				; Wait for the blitter to finish
	btst	#6,$02(a5)
	bne.s	\@1
	bra.s	\@2
\@1	nop
	nop
	btst	#6,$02(a5)
	bne.s	\@1
\@2
	ENDM

;-------------------------------------------------------------------------
; PROGRAM
;-------------------------------------------------------------------------

	SECTION	"code",code_c

STARTPROG:

	move.l	EXECBASE,a6		; Open graphics.library
	lea	GFXNAME,a1
	moveq	#0,d0
	jsr	OpenLibrary(a6)
	move.l	d0,GFXBASE
	beq	EXIT

	lea	CUSTOMBASE,a5
	move.l	GFXBASE,a6

	move.l	$26(a6),OLDCOPPERLIST	; Save copperlist
	move.w	$1C(a5),OLDINTERRUPTS	; Save enabled interrupts
	move.w	$02(a5),OLDDMACONTROL	; Save dmacontrol

	move.w	#$87E0,$96(a5)		; Enable some DMAs
	move.w	#$7FFF,$9A(a5)		; Disable all interrupts

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

INITMAP:

	lea	SCROLLMAP,a0
	moveq	#0,d7
IMAP1:	cmp.w	#320,d7
	blt.s	IMAP2
	bsr	GETRANDOM
	bra.s	IMAP3
IMAP2:	move.w	d7,d0
IMAP3:	move.w	d0,(a0)+
	addq	#1,d7
	cmp.w	#(SW*8)*MX,d7
	bne.s	IMAP1

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

INITCOPPER:				; Initialize copperlist

	lea	COLOURS,a0		; Insert palette
	lea	COP1PALETTE+2,a1
	move.w	#31,d7
ICOP1:	move.w	(a0)+,(a1)
	addq.w	#4,a1
	dbf	d7,ICOP1

	move.l	#BLANKS,d0		; Insert blank sprites
	move.w	d0,COP1SPRITES+06
	move.w	d0,COP1SPRITES+14
	move.w	d0,COP1SPRITES+22
	move.w	d0,COP1SPRITES+30
	move.w	d0,COP1SPRITES+38
	move.w	d0,COP1SPRITES+46
	move.w	d0,COP1SPRITES+54
	move.w	d0,COP1SPRITES+62
	swap	d0
	move.w	d0,COP1SPRITES+02
	move.w	d0,COP1SPRITES+10
	move.w	d0,COP1SPRITES+18
	move.w	d0,COP1SPRITES+26
	move.w	d0,COP1SPRITES+34
	move.w	d0,COP1SPRITES+42
	move.w	d0,COP1SPRITES+50
	move.w	d0,COP1SPRITES+58

	move.l	#SCROLLPLANES+(0*SW),d0	; Insert Bitplane pointers
	move.l	#SCROLLPLANES+(1*SW),d1
	move.l	#SCROLLPLANES+(2*SW),d2
	move.l	#SCROLLPLANES+(3*SW),d3
	move.l	#SCROLLPLANES+(4*SW),d4
	add.l	d5,d0
	add.l	d5,d1
	add.l	d5,d2
	add.l	d5,d3
	add.l	d5,d4
	move.w	d0,COP1PLANE1+6
	move.w	d1,COP1PLANE2+6
	move.w	d2,COP1PLANE3+6
	move.w	d3,COP1PLANE4+6
	move.w	d4,COP1PLANE5+6
	swap	d0
	swap	d1
	swap	d2
	swap	d3
	swap	d4
	move.w	d0,COP1PLANE1+2
	move.w	d1,COP1PLANE2+2
	move.w	d2,COP1PLANE3+2
	move.w	d3,COP1PLANE4+2
	move.w	d4,COP1PLANE5+2

	move.l	#COPPERLIST,$80(a5)	; Start copperlist
	clr.w	$88(a5)

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

MAINLOOP:

	WRAST	$110			; Wait for rasterpos $111
	WRAST	$111

	move.w	#$722,$180(a5)		; Scroll screen, and set
	bsr	SCROLLER		; a red background colour
	move.w	#$000,$180(a5)		; to measure time

	btst	#6,$BFE001		; Loop until LMB is pressed
	bne.s	MAINLOOP

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

EXITPROGRAM:

	move.l	EXECBASE,a6		; Close graphics.library
	move.l	GFXBASE,a1
	jsr	CloseLibrary(a6)

EXIT:	lea	CUSTOMBASE,a5		; Restore old values and exit
	or.w	#$8000,OLDDMACONTROL
	or.w	#$8000,OLDINTERRUPTS
	move.w	OLDDMACONTROL,$96(a5)
	move.w	OLDINTERRUPTS,$9A(a5)
	move.l	OLDCOPPERLIST,$80(a5)
	clr.w	$88(a5)
	moveq	#0,d0
	rts

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

GETRANDOM:

	moveq	#0,d0			; Get a 'random' byte
	moveq	#0,d1
	move.b	$DFF007,d0
	move.b	$BFD800,d1
	eor.b	d1,d0
	rts

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

SCROLLER:				; Scrolling routine

	btst	#2,$DFF016		; Skip if RMB is pressed
	beq.w	SCRLX

	move.w	SCROLLPOS,d1		; Lowest 4 bits into BPLCON1
	and.w	#15,d1
	sub.w	#15,d1
	neg	d1
	mulu	#$11,d1
	move.w	d1,COP1SCROLL+2

	move.w	SCROLLPOS,d5		; Add words to Bitplane-pointers
	lsr.w	#4,d5
	add.w	d5,d5
	and.l	#$FFFE,d5

	move.l	#SCROLLPLANES+(0*SW),d0	; Update pointers in
	move.l	#SCROLLPLANES+(1*SW),d1	; copperlist
	move.l	#SCROLLPLANES+(2*SW),d2
	move.l	#SCROLLPLANES+(3*SW),d3
	move.l	#SCROLLPLANES+(4*SW),d4
	add.l	d5,d0
	add.l	d5,d1
	add.l	d5,d2
	add.l	d5,d3
	add.l	d5,d4
	move.l	d0,COPYADR		; Store address where new
	add.l	#SW-2,COPYADR		; blocks are to copied
	move.w	d0,COP1PLANE1+6
	move.w	d1,COP1PLANE2+6
	move.w	d2,COP1PLANE3+6
	move.w	d3,COP1PLANE4+6
	move.w	d4,COP1PLANE5+6
	swap	d0
	swap	d1
	swap	d2
	swap	d3
	swap	d4
	move.w	d0,COP1PLANE1+2
	move.w	d1,COP1PLANE2+2
	move.w	d2,COP1PLANE3+2
	move.w	d3,COP1PLANE4+2
	move.w	d4,COP1PLANE5+2

	bsr	COPYBLOCK			; Copy a block at right edge

	cmp.w	#8*SW*(MX-1),SCROLLPOS		; Scroll 1 pixel left
	bge.s	SCRLX
	addq.w	#1,SCROLLPOS

SCRLX:	rts

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

COPYBLOCK:					; Copy a block onto screen

	lea	SCROLLMAP,a0			; Get block number from
	add.w	SCROLLPOS,a0			; the map
	add.w	SCROLLPOS,a0
	move.w	(a0),d0

	lea	BLOCKS,a0			; Calculate address for
	mulu	#160,d0				; the block data
	add.l	d0,a0

	move.w	SCROLLPOS,d1			; Calculate address that
	and.l	#15,d1				; the block is copied into
	mulu	#5*16*SW,d1
	move.l	COPYADR,a1
	add.l	d1,a1

	lea	CUSTOMBASE,a5			; Blit block onto screen
	WBLIT
	move.l	a0,$50(a5)			; BLTAPTR
	move.l	a1,$54(a5)			; BLTDPTR
	move.l	#$0000002A,$64(a5)		; BLTAMOD BLTDMOD
	move.l	#$09F00000,$40(a5)		; BLTCON0 BLTCON1
	move.l	#$FFFFFFFF,$44(a5)		; BLTAFWM BLTALWM
	move.w	#$1401,$58(a5)			; BLTSIZE
	WBLIT
	rts

;-------------------------------------------------------------------------
; PUBLICMEM STORAGE
;-------------------------------------------------------------------------

		SECTION "publicdata",data_c

OLDCOPPERLIST:	dc.l	0
OLDINTERRUPTS:	dc.l	0
OLDDMACONTROL:	dc.l	0

SCROLLPOS:	dc.w	0		; Scrollposition in pixels

COPYADR:	dc.l	0		; Where to copy new blocks on screen

COLOURS:	dc.w	$000,$FFF,$EEE,$DDD,$CCC,$BBC,$AAB,$99A	; Palette
		dc.w	$889,$777,$666,$555,$444,$333,$222,$111
		dc.w	$F87,$E65,$C43,$911,$800,$600,$400,$300
		dc.w	$500,$B98,$DB9,$FDC,$846,$956,$A67,$A79

SCROLLMAP:	dcb.w	(SW*8)*MX,0	; Block map

GFXBASE:	dc.l	0
GFXNAME:	dc.b	"graphics.library",0

;-------------------------------------------------------------------------
; COPPERLIST
;-------------------------------------------------------------------------

		SECTION "chipdata",data_c

COPPERLIST:	dc.w	$008E,$2C81,$0090,$2CC1	; DisplayWindow
		dc.w	$0092,$0030,$0094,$00D0	; DataFetch
		dc.w	$0108,$00B2,$010A,$00B2	; BitplaneModulo
		dc.w	$0102,$0000,$0104,$0000	; BPLCON1 & BPLCON2

COP1SPRITES:	dc.w	$0120,$0000,$0122,$0000	; Sprite pointers
		dc.w	$0124,$0000,$0126,$0000
		dc.w	$0128,$0000,$012A,$0000
		dc.w	$012C,$0000,$012E,$0000
		dc.w	$0130,$0000,$0132,$0000
		dc.w	$0134,$0000,$0136,$0000
		dc.w	$0138,$0000,$013A,$0000
		dc.w	$013C,$0000,$013E,$0000

COP1PALETTE:	dc.w	$0180,$0000,$0182,$0000	; Palette
		dc.w	$0184,$0000,$0186,$0000
		dc.w	$0188,$0000,$018A,$0000
		dc.w	$018C,$0000,$018E,$0000
		dc.w	$0190,$0000,$0192,$0000
		dc.w	$0194,$0000,$0196,$0000
		dc.w	$0198,$0000,$019A,$0000
		dc.w	$019C,$0000,$019E,$0000
		dc.w	$01A0,$0000,$01A2,$0000
		dc.w	$01A4,$0000,$01A6,$0000
		dc.w	$01A8,$0000,$01AA,$0000
		dc.w	$01AC,$0000,$01AE,$0000
		dc.w	$01B0,$0000,$01B2,$0000
		dc.w	$01B4,$0000,$01B6,$0000
		dc.w	$01B8,$0000,$01BA,$0000
		dc.w	$01BC,$0000,$01BE,$0000

COP1PLANE1:	dc.w	$00E0,$0000,$00E2,$0000	; Bitplane pointers
COP1PLANE2:	dc.w	$00E4,$0000,$00E6,$0000
COP1PLANE3:	dc.w	$00E8,$0000,$00EA,$0000
COP1PLANE4:	dc.w	$00EC,$0000,$00EE,$0000
COP1PLANE5:	dc.w	$00F0,$0000,$00F2,$0000

COP1SCROLL:	dc.w	$0102,$0000		; FineScrolling BPLCON1

		dc.w	$2C07,$FFFE,$0100,$5200	; Turn on bitplanes at line $2C

		dc.w	$FFDF,$FFFE		; Wait below line $100

		dc.w	$2C07,$FFFE,$0100,$0000	; Turn off bitplanes at $12C

		dc.w	$FFFF,$FFFE		; End copperlist

;-------------------------------------------------------------------------
; CHIPMEM STORAGE
;-------------------------------------------------------------------------

SCROLLPLANES:	dcb.b	5*SW*(SH+MX),0		; Scroll bitplanes

		incdir "source.s:"		; Where to load includes
BLOCKS:		incbin "blocks.scroll.raw"	; Block image data

BLANKS:		dc.l	0,0			; Blank sprite

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