*****************************************************************************
;                         STOLEN DATA Issue #3
;                         ~~~~~~~~~~~~~~~~~~~~
;   Non-double buffered hardware scroller
;
;   Copyright ANARCHY 1990
;
;   Written on 3.6.90 by Kreator of ANARCHY
;
; Probably the most useful scroller in general use as it allows variable
; speeds, and instant scroller controllables.
;
;  General notes - At all times (unless specified) a6 points to the custom
; chip registers ($dff000) and a5 points to the list of variables.This allows
; indirect addressing modes to be used, which are much faster than absolute
; addressing and consume less memory. If these registers are needed in the
; course of a routine simply stick them on the stack, and pop them back off
; later.
*****************************************************************************

	Incdir	DF1:
	Include	Source/NewCustomReg	; Custom register label equates
	Section	Scroller,Code_c		; Assemble into chip mem if > ½ meg

TEST		= 1		; Set this if you are only testing the menu
				; as it will then return to DEVPAC

Trap_vec0	= $80
Execbase	= $4
Oldopen		= -$198
Screen		= $70000
Scrollspeed 	= 6		; Alter this for different speeds, you can
				; change the variable speed during the demo
				; for alterable speeds.

	Move.l	#Start,$80.w	; Trap vector 0
	Trap	#0		; Execute trap 0 to give full control of the
	Rts			; 68000, needs an RTE to return.

Start
	Bsr	Killsys		; Disable the operating system
	Bsr	Setup		; Setup the demo
	Bsr	Main		; Now run the main demo routines
	Bsr	Sysreturn	; Return the system to its original state
	Moveq.l	#0,d0		; No errors !! A number of people neglect to
				; do this, and that causes batch files (such
				; as the startup sequence) to bomb out.
	Rte		; Return from exception ie. to the instruction after
			; the TRAP #0 call.

*****************************************************************************
;Killsys - Disable operating system and interrupts
*****************************************************************************
Killsys
	Move.l	$4.w,a6		; Execbase vector
	Lea	Gfxname(pc),a1	; Pointer to "graphics.library" into a1
	Jsr	Oldopen(a6)	; Open this library
	Lea	Variables,a5	; Get a pointer to the variable space
	Lea	$dff000,a6	; Pointer to custom chips
	Move.l	d0,a0		; Address of the graphics library
	Move.l	38(a0),Sys_copl(a5)	; Remember the System copperlist
	Move	Intenar(a6),Int_set(a5)	; System interrupts
	Move	#$7fff,Intena(a6)	; Now switch off all interrupts
	Move.l	$6c.w,Vbl_vec(a5)	; System vertical blanking int.
	Move	Dmaconr(a6),Dma_set(a5)	; System DMA
	Move	#$7fff,Dmacon(a6)	; Clear all DMA
	Move	#$87c0,Dmacon(a6)	; Now set the required DMA channels
	Rts

Gfxname		Dc.b "graphics.library",0
	Even
*****************************************************************************
;Sysreturn - Re-enable operating system and interrupts
*****************************************************************************
Sysreturn
	Move	#$7fff,Intena(a6)	; Clear all interrupts
	Move.l	Vbl_vec(a5),$6c.w	; Restore VBL interrupt
	Move	Int_set(a5),d0
	Or	#$c000,d0
	Move	d0,Intena(a6)		; Restore system interrupts
	Move	#$7fff,Dmacon(a6)
	Move	Dma_set(a5),d0
	Or	#$8200,d0
	Move	d0,Dmacon(a6)		; Restore system DMA
	Move.l	Sys_copl(a5),Cop1lch(a6)	; Restore system copperlist
	Clr	Copjmp1(a6)
	Rts
*****************************************************************************
;Setup - Setup the menu system
*****************************************************************************
Setup

;-- Remove the sprite data (prevents sprite streaks down the screen)

	Lea	Spr0data(a6),a0
	Moveq	#7,d0
Clop
	Clr.l	(a0)
	Addq.l	#8,a0
	Dbf	d0,Clop

;-- Clear the scroll area

	Lea	Screen,a0
	Move	#$bff,d0
Clear_scroll
	Clr.l	(a0)+
	Dbf	d0,Clear_scroll

;-- Initialise some variables

	Move.l	#Scrolltext,Textpt(a5)	; Initialise the scrolltext
	Move.l	#Clstart,Cop1lch(a6)	; Init. our own copperlist
	Clr	Copjmp1(a6)
	Move	#Scrollspeed,Speed(a5)	
	Rts

*****************************************************************************
; Main - Central demo calling routine + mouse button check
*****************************************************************************
Main
	Move.l	Vposr(a6),d0
	And.l	#$1ff00,d0
	Cmp.l	#$00100,d0	; Wait for vertical position 1
	Bne.s	Main

	Bsr	Scroller	; Jump to the scroll routine
	Move	#$200,d0
.Loop
	Dbf	d0,.Loop

	Btst	#6,$bfe001	; Check the left mouse button
	Bne.s	Main

	Rts
*****************************************************************************
; Scroller - This scroller is 46 bytes across all of which are displayed
*****************************************************************************
Scroller
	Move	Count(a5),d7
	Sub	Speed(a5),d7		; Counter tells us if we need a
	Bpl	Nonewchar		; new character

	Move.l	#-1,Bltafwm(a6)
	Move.l	#$9f00000,Bltcon0(a6)	; Shift the scroll area left 2
	Clr.l	Bltamod(a6)		; pixels
	Move.l	#Screen+2,Bltapth(a6)
	Move.l	#Screen,Bltdpth(a6)	; Careful, here as the shift operation
					; obliterates the word Screen-2
	Move	#16*64+23,Bltsize(a6)	
	Bsr	Blitwait


	Move.l	Textpt(a5),a0
	Moveq	#0,d0
Read_char
	Move.b	(a0)+,d0		; Read a char. from scrolltext
	Bne.s	Not_null		; If zero, reset text pointer
	Lea	Scrolltext(pc),a0
	Bra.s	Read_char		; Read the first character
Not_null
	Cmp	#$20,d0		; Check for control codes, and convert to
	Bgt.s	Not_control	; spaces
	Moveq	#$20,d0
Not_control
	Cmp	#$5b,d0		; Lower case characters, convert to uppercase
	Blt.s	Not_lower
	Sub	#$20,d0
Not_lower
	Sub	#$20,d0
	Add	d0,d0
	Lea	Charpos(pc),a1
	Move	(a1,d0),d0
	Lea	Font(pc),a1
	Lea	(a1,d0),a1

	Move.l	a1,Bltapth(a6)	; Plot the new character
	Lea	Screen+$2c,a2	; Plot into the last position on the line
	Move.l	a2,Bltdpth(a6)
	Move.l	#$0026002c,Bltamod(a6)
	Move.l	#$09f00000,Bltcon0(a6)
	Move	#16*64+1,Bltsize(a6)
	Move.l	a0,Textpt(a5)
	Add	#16,d7
Nonewchar
	Move	d7,Count(a5)
	And	#$f,d7
	Move	d7,Pixelscroll+2
	Rts

Blitwait
	Btst	#14,Dmaconr(a6)
	Bne.s	Blitwait
	Rts

*****************************************************************************
; Copperlists
*****************************************************************************
Clstart
	Wait	0,20
	Mov	0,Color00
	Mov	$80f,Color01
	Mov	$1a64,Diwstrt
	Mov	$39d1,Diwstop
	Mov	$0028,Ddfstrt
	Mov	$00d8,Ddfstop
	Mov	0,Bplcon0
Pixelscroll
	Mov	0,Bplcon1
	Mov	0,Bplcon2
	Mov	0,Bpl1mod
	Mov	0,Bpl2mod

	Mov	0,Bpl1ptl
	Mov	7,Bpl1pth
	Wait	0,$90
	Mov	$1200,Bplcon0

	Wait	0,$a0
	Mov	0,Bplcon0

	Wait	$fe,$ff
*****************************************************************************
; Binaries
*****************************************************************************

Scrolltext
	Dc.b	"copyright anarchy 1990, coded of course by kreator"
	Dc.b	"  this scroller is probably the most useful because"
	Dc.b	" it allows variable speeds to be employed very easily"
	Dc.b	" amongst other advantages           "
	Dc.b	0
	Even

Font
	Incbin	Binary/Bubble.font	; This font was drawn by KREATOR
					; so credit me if you use it

; The following table is used to calculate a pointer to the required
; character and in general must be created by hand. Some coders advocate a
; different approach, which is to have all your characters stacked on top
; of each other and then the pointers are very easy to calculate with a
; multiply. I still prefer this method myself.

Charpos	Dc.w	$0000,$0002,$0004,$0006,$0008,$000a,$000c,$000e ; !"#$%&'
	Dc.w	$0010,$0012,$0014,$0016,$0018,$001a,$001c,$001e ;()*+,-./
	Dc.w	$0020,$0022,$0024,$0026,$0280,$0282,$0284,$0286 ;01234567
	Dc.w	$0288,$028a,$028c,$028e,$0290,$0292,$0294,$0296 ;89:;<=>?
	Dc.w	$0298,$029a,$029c,$029e,$02a0,$02a2,$02a4,$02a6 ;@ADCDEFG
	Dc.w	$0500,$0502,$0504,$0506,$0508,$050a,$050c,$050e ;HIJKLMNO
	Dc.w	$0510,$0512,$0514,$0516,$0518,$051a,$051c,$051e ;PQRSTUVW
	Dc.w	$0520,$0522,$0524,$0526                         ;XYZ[\]^_

*****************************************************************************
;   Variables
*****************************************************************************

	Rsreset
Int_set		Rs.w 1	; System interrupts
Dma_set		Rs.w 1	; System DMA channels
Sys_copl	Rs.l 1	;  ""    copperlist
Vbl_vec		Rs.l 1	;  ""    vertical blanking interrupt
Count		Rs.w 1	
Textpt		Rs.l 1	; Pointer to the scrolltext
Speed		Rs.w 1	: Scroller speed
Varisize	Rs.b 0	; Simply used to determine how much space is needed
			; for the variable list

Variables	Dcb.b Varisize	; Reserve space for the variables


