* This source is a fixed version of Turnscroll.s.  It does the same thing,
* but it has some fixes in it.  First of all, I took out all of the clr's
* to custom chip registers.  THIS IS A NO-NO!  Never do something like
* this:
*		clr.l	$dff064		; bltdmod (12 cpu cycles +16 for
*					;   addr. calc time = 28 clocks)
* This will clear the register fast, but can cause wierd effects because
* all custom chip registers are either read or write.  On a 68000, a clr
* does both a read and a write!  In the original code there are about 15
* clr's like this.  A better way is the following:
*		moveq	#0,d0		; 4 cycles
*		move.l	d0,$dff064	; 20 cycles
* Notice the total is LESS than with the clr.
*
* I also fixed the use of self modifing code.  In the original source
* the following appeared:
*		dc.w	$4ef9
* oldirq:	dc.l	0
* What he would do is take the old level three interrupt pointer and write
* it to oldirq.  This would cause it and the previous word to for this:
*		jmp	(whatever he writes here)
* Now, this works just fine, unless you have an instruction cache.  Why?
* The code is fetched while it is still like this:
*		jmp	$0
* Jumping to address 0 is not a very desirable thing to do. :^) The "correct"
* way to do this is have the following:
*		move.l	oldirq,-(sp)
*		rts
* oldirq:	dc.l	0
* Go ahead and write the old int add to old irq.  What happens now, is
* you make that you return address and "return" to that location.  This
* will work on any Amiga.
*
* Another thing that I fixed is the way he waits for the blitter to finish.
* Originally he would do this:
*
* wblit:		btst	#14,$dff02
*			bne.b	wblit
*
* First off, a btst on a memory location is a btst.b, so this is actually
* this:
*			btst.b	#6,$dff002
* Secondly, for compatability with older Agnuses (Agni? :) ) you should
* test it once, ignore that test, and do it again.  If you look at the
* function WaitBlit() in ROM, you will see something more like this:
* 			tst.b	$dff002
* wblit:		btst.b	#6,$dff002
*			bne.b	wblit
*
* The last thing that I fixed was the installation of the level 3 int.  Here
* two errors were made.  First of all was the infamous VBR.  On processors
* from a 68010 and up the interrupt vector table can be moved ANYWHERE in
* memory.  By just poking to $6c, you may not be installing an interrupt
* at all!  There is a handy register on these processors called the VBR or
* Vector Base Register.  The routine GetVBR determines if the VBR exists,
* and if it does, determines what it is.
*
* The other error in his interrupt installer is that he left interrupts
* enabled will saveing/installing/restoring the interrupt.  Bad move!  Under
* certain curcumstances if an interrupt is triggered while you are installing,
* you can end up in outer space!
***********************************************************
* Equates
***********************************************************

offset		EQU	50*34

charheight2	EQU	16		; Height of 1 char in lines
charwidth21	EQU	4		; Width of 1 char in bytes
planes2		EQU	1		; Nr of Planes
charsproline2	EQU	10		; Chars pro line
linewidth2	EQU	40		; Bytes pro line
charwidth22	EQU	charwidth21/2 	; Need this because SEKA doesn't know
					; the normal math rules...!!! 

charheight	EQU	34		; Height of 1 char in lines
charwidth	EQU	4		; Width of 1 char in bytes
planes		EQU	1		; Nr of Planes
charsproline	EQU	10		; Chars pro line
linewidth	EQU	40 		; Bytes pro line
charwidth2	EQU	charwidth/2 	; Need this because SEKA doesn't know
					; the normal math rules...!!! 

AttnFlags	EQU	296		; offset of exec base

***********************************************************

		section	thecode,code

start:		bsr.w	initcop

		movea.l	4.w,a6			; exec base
		jsr	-132(a6)		; Forbid()
		jsr	-120(a6)		; Disable()

		lea	gfxname,a1
		jsr	-408(a6)		; OldOpenLibrary
		move.l	d0,gfxbase		; save ptr to gfx base
		move.l	d0,a6
		jsr	-456(a6)		; OwnBlitter()

		lea	$dff002,a5		; custom chip base + 2
		bsr.w	waitblt			; wait for the blitter

		move.l	#newcop,$80-2(a5)	; install our copper

		move.l	a5,-(sp)
		bsr.b	GetVBR
		move.l	(sp)+,a5

		move.l	$6c(a0),oldirq		; save old level 3 int
		move.l	#newirq,$6c(a0)		; install our level 3 int

		movea.l	4.w,a6			; exec base
		jsr	-126(a6)		; Enable()

.wait:		btst.b	#6,$bfe001		; wait for the lmb
		bne.s	.wait

		movea.l	4.w,a6
		jsr	-120(a6)		; Disable()
		move.l	VectorBase,a0		; vbr
		move.l	oldirq,$6c(a0)		; reinstall the old level 3 int
		movea.l	4.w,a6
		jsr	-126(a6)		; Enable()

		move.l	gfxbase,a6		; ptr to gfxbase
		move.l	$26(a6),$80-2(a5)	; install system copper
		jsr	-462(a6)		; DisOwnBlitter()

		move.l	a6,a1
		movea.l	4.w,a6			; exec base
		jsr	-414(a6)		; CloseLibrary()
		move.w	#$8020,$96-2(a5)	; enable sprite DMA

		jmp	-138(a6)		; Permit()
		; the function Permit() will return us to the OS because we
		; didn't put a return address on the stack.  Call me nasty. :)
						
***********************************************************

GetVBR:		moveq	#0,d0			; clear
		movea.l	4.w,a6			; exec base
		btst.b	#0,AttnFlags+1(a6)	; are we at least a 68010?
		beq.b	.1			; nope.
		lea.l	vbr_exception(pc),a5	; addr of function to get VBR
		jsr	-30(a6)			; Supervisor()
.1:		move.l	d0,a0
		move.l	d0,VectorBase
		rts				; return

vbr_exception:
	; movec vbr,Xn is a priv. instr.  You must be supervisor to execute!
;		movec   vbr,d0
	; many assemblers don't know the VBR, if yours doesn't, then use this
	; line instead.
		dc.w	$4e7a $0801
		rte				; back to user state code

***********************************************************

initcop:	move.l	#offset+scrplane,d0
		move.w	d0,scrpl+6
		move.w	d0,scrpl+14
		swap	d0
		move.w	d0,scrpl+2
		move.w	d0,scrpl+10

		move.l	#scrplane2,d0
		move.w	d0,scrpl+22
		swap	d0
		move.w	d0,scrpl+18
		rts

***********************************************************

newirq:		movem.l	d0-d7/a0-a6,-(a7)
		bsr.L	scroll
		bsr.L	scrollup
		bsr.s	scroll2
		movem.l	(a7)+,d0-d7/a0-a6
		move.l	oldirq,-(sp)
		rts

***********************************************************

scroll2:	bsr	waitblt
		moveq	#-1,d0
		move.w	speed12,$40-2(a5)
		move.w	#0,$42-2(a5)
		move.l	d0,$44-2(a5)

		move.l	#plane,d0
		move.l	d0,$54-2(a5)

		add.l	speed32,d0
		move.l	d0,$50-2(a5)
		move.l	#0,$64-2(a5)
		move.w	#(charheight2*64*planes2)+25,$58-2(a5)
		bsr.L	waitblt

noscr2:		subq.b	#1,scrcount2
		beq.s	newtext2
		rts

***********************************************************

newtext2:	move.b	speed22,scrcount2
		addq.l	#1,stringpointer2
		move.l	stringpointer2,a0
		clr.w	d0
		move.b	(a0),d0
		cmpi.b	#32,d0
		bne	nspace2
		clr.w	d0
		move.w	#$0900,$40-2(a5)
		bra.s	space2
nspace2:	move.l	#font2,d1
		sub.b	#48,d0
		cmpi.b	#48,d0
		bgt.s	speedchange2
ddd2:		cmpi.b	#charsproline2,d0 
		blt.s	eerste2
		add.l	#charheight2*linewidth2*planes2,d1
		sub.b	#charsproline2,d0
		bra.s	ddd2
eerste2:	move.w	#$09f0,$40-2(a5)	;BLTCON0
space2:		mulu	#charwidth21,d0
		add.l	d1,d0
		move.l	d0,$50-2(a5)    		;SOURCE A
		move.l	#plane+46,$54-2(a5)		;DEST D
		move.w	#0,$42-2(a5)			;BLTCON1
		move.w	#linewidth2-charwidth21,$64-2(a5) ; MOD A
		move.l	#-1,$44-2(a5)			;MASK
		move.w	#50-charwidth21,$66-2(a5)	;MOD  D
		move.w	#(charheight2*planes2*64)+charwidth22,$58-2(a5)
		bsr.L	waitblt

		cmp.l	#endstring2,stringpointer2
		bne.s	notend2
		move.l	#string2,stringpointer2
notend2:	rts

***********************************************************

speedchange2:	sub.b	#49,d0
		mulu	#3,d0
		lea	speedlist,a0
		move.b	(a0,d0.w),speed12
		move.b	2(a0,d0.w),d1
		ext.w	d1
		ext.l	d1
		move.l	d1,speed32
		move.b	1(a0,d0.w),speed22
		bra.L	newtext2

scrollup:	bsr.L	waitblt
		move.l	#$09f00000,$40-2(a5)
		move.l	#$ffffffff,$44-2(a5)
		move.l	#scrplane,$54-2(a5)	;Dest
		move.l	#scrplane+50,$50-2(a5)	;Source
		move.l	#$00040004,$64-2(a5)	;Mod
		move.w	#(charheight*planes*2*64)+23,$58-2(a5)

		bsr.L	waitblt
		move.l	#$09f00000,$40-2(a5)
		move.l	#$ffffffff,$44-2(a5)
		move.l	#(34*50*2)+scrplane,$54-2(a5)	;Dest
		move.l	#scrplane,$50-2(a5)		;Source
		move.l	#0,$64-2(a5)			;No Mod
		move.w	#64+25,$58-2(a5)
		bsr.L	waitblt
		rts

***********************************************************

scroll:		move.w	speed1,$40-2(a5)
		move.w	#0,$42-2(a5)
		move.l	#$ffffff00,$44-2(a5)
		move.l	#scrplane,d0
		move.l	d0,$54-2(a5)
		add.l	speed3,d0
		move.l	d0,$50-2(a5)
		move.l	#0,$64-2(a5)
		move.w	#(2*charheight*(planes+1)*64)+25,$58-2(a5)
		bsr	waitblt
noscr:		subq.b	#1,scrcount
		beq.s	newtext
		rts

***********************************************************

newtext:	move.b	speed2,scrcount
		addq.l	#1,stringpointer
		move.l	stringpointer,a0
		clr.w	d0
		move.b	(a0),d0
		cmpi.b	#32,d0
		bne.s	nspace
		clr.w	d0
		move.w	#$0900,$40-2(a5)
		bra.s	space
nspace:		move.l	#font,d1
		sub.b	#48,d0
		cmpi.b	#48,d0
		bgt.L	speedchange
ddd:		cmpi.b	#charsproline,d0 
		blt.s	eerste
		add.l	#charheight*linewidth*planes,d1
		sub.b	#charsproline,d0
		bra.s	ddd
eerste:		move.w	#$09f0,$40-2(a5)	;BLTCON0
space:		mulu	#charwidth,d0
		add.l	d1,d0
		move.l	d0,$50-2(a5)    	;SOURCE A
		move.l	#offset+scrplane,d0
		add.l	#46,d0
		move.l	d0,$54-2(a5)		;DEST D
		move.w	#0,$42-2(a5)		;BLTCON1
		move.w	#linewidth-charwidth,$64-2(a5) ; MOD A
		move.l	#-1,$44-2(a5)		;MASK
		move.w	#50-charwidth,$66-2(a5)	;MOD  D
		move.w	#charheight*planes*64+charwidth2,$58-2(a5)
		bsr.s	waitblt

		cmp.l	#endstring,stringpointer
		bne.s	notend
		move.l	#string,stringpointer
notend:		rts

***********************************************************

waitblt:	tst.b	(a5)
.1:		btst.b	#6,(a5)
		bne.s	.1
		rts

***********************************************************

speedchange:	sub.b	#49,d0
		mulu	#3,d0
		lea	speedlist,a0
		move.b	(a0,d0.w),speed1
		move.b	2(a0,d0.w),d1
		ext.w	d1
		ext.l	d1
		move.l	d1,speed3
		move.b	1(a0,d0.w),speed2
		bra.L	newtext

***********************************************************

		section	nonchip_data,data

oldirq:		dc.l	0
oldcop:		dc.l	0
gfxbase:	dc.l	0
VectorBase:	dc.l	0

stringpointer:	dc.l	string
stringpointer2:	dc.l	string2

speed3:		dc.l		2
speed1:		dc.w		$49f0
speed2:		dc.b		8
scrcount:	dc.b		1

speed32:	dc.l	2
speed12:	dc.w	$49f0
speed22:	dc.b	8
scrcount2:	dc.b	1

speedlist:	dc.b	$09,64,0 	; Speed a
		dc.b	$f9,32,2	; Speed b
		dc.b	$e9,16,2	; Speed c
		dc.b	$c9,8,2		; Speed d
		dc.b	$89,4,2		; Speed e
		dc.b	$09,2,2		; Speed f
		dc.b	$19,32,0	; Speed g
		dc.b	$29,16,0	; Speed h
		dc.b	$49,8,0		; Speed i
		dc.b	$89,4,0		; Speed j
		dc.b	$09,2,-2	; Speed k
		dc.b	$c9,3,2		; Speed l

gfxname:	DC.B	"graphics.library",0

string:		DC.B	" dTHE TIMECIRCLE IN 1989 :::"
endstring:	DC.B	32

string2:	DC.B	" cANOTHER SOFTY SCROLLER MADE BY BRIAN "
		DC.B	"POSTMA FOR THE NEWSFLASH MAGAZINE ::: A "
		DC.B	"BIG HI TO OUR FELLOW TAIPAN MEMBERS :::"
endstring2:	DC.B	32

***********************************************************

		section	chip_data,data_c

font:		incbin	'font1.raw'
font2:		incbin	'font2.raw'

newcop:	dc.w	$0096,$0020,$0120,$0000,$0122,$0000
	dc.w	$008e,$296a,$0090,$29fa,$0092,$0028
	dc.w	$0094,$00d8,$0180,$0000,$0100,$0000
	dc.w	$0102,$0000,$0104,$0000
	dc.w	$0182,$0fff,$0108,$0004,$010a,-96

	dc.w	$018c,$0aaa,$0184,$0f00,$0186,$0fff
scrpl:	dc.w	$e0,0,$e2,0,$e4,0,$e6,0,$e8,0,$ea,0
	dc.w	$9001,$fffe,$0100,$3400
	dc.w	$9007,$fffe,$182,$88,$192,$606
	dc.w	$9107,$fffe,$182,$99
	dc.w	$9207,$fffe,$182,$aa,$192,$707
	dc.w	$9307,$fffe,$182,$bb
	dc.w	$9407,$fffe,$182,$cc,$192,$808
	dc.w	$9507,$fffe,$182,$dd
	dc.w	$9607,$fffe,$182,$ee,$192,$909
	dc.w	$9707,$fffe,$182,$ff
	dc.w	$9807,$fffe,$192,$909
	dc.w	$9901,$fffe,$184,$800,$192,1,$180,$1
	dc.w	$9a01,$fffe,$184,$900,$192,3,$180,$3
	dc.w	$9b01,$fffe,$184,$a00,$192,5,$180,$5
	dc.w	$9c01,$fffe,$184,$b00,$192,7,$180,$7
	dc.w	$9d07,$fffe,$180,$9,$192,9,$184,$c00
	dc.w	$9e07,$fffe,$180,$b,$192,$b,$184,$d00
	dc.w	$9f07,$fffe,$180,$d,$192,$d,$184,$e00
	dc.w	$a007,$fffe,$180,$f,$192,$f,$184,$f00
	dc.w	$a207,$fffe,$180,$d,$192,$d,$184,$e00
	dc.w	$a307,$fffe,$180,$b,$192,$b,$184,$d00
	dc.w	$a407,$fffe,$180,$9,$192,$9,$184,$c00
	dc.w	$a507,$fffe,$180,$7,$192,$7,$184,$b00
	dc.w	$a607,$fffe,$184,$a00,$180,$5,$192,5
	dc.w	$a707,$fffe,$184,$900,$180,$3,$192,3
	dc.w	$a807,$fffe,$184,$800,$180,$1,$192,1
	dc.w	$a907,$fffe,$180,0,$192,$909

	dc.w	$ab07,$fffe,$182,$ee,$192,$909
	dc.w	$ac07,$fffe,$182,$dd
	dc.w	$ad07,$fffe,$182,$cc,$192,$808
	dc.w	$ae07,$fffe,$182,$bb
	dc.w	$af07,$fffe,$182,$aa,$192,$707
	dc.w	$b007,$fffe,$182,$99
	dc.w	$b107,$fffe,$182,$88,$192,$606
	dc.w	$b201,$fffe,$0100,$0000
	dc.l	-2,-2		; some old chips skip the first end of clist

***********************************************************

		section	chip_bss,bss_c

		ds.b	10000
		ds.b	50
scrplane:	ds.b	50*34*2
		ds.b	50
scrplane2:	ds.b	9*50
plane:		ds.b	25*50
		ds.b	10000
		END
