; ------------ Sinscroller -------------
; For the CJ Assembler Lesson
; (c) 1990 Doctor Mabuse
; the Alpha Flight
; (o) 1990 (optimized 1990) by D.I.S.C - Coders
; (e) English corrected by D.I.S.C. - editors
; --------- Important Infos !! ---------
; As usual get the font calles "data"			; called
; with the -y- command. As you can see,
; the routine is preset as a two pixel
; sinus scroller. It's no problem to
; change it into a one pixel profi-
; scroller but beware of the raster.
; The flickering green shows where the
; raster line has arrived when the
; routine has fnished. When it's at the			; finished
; bottom of the screen you have lost.
; To remove it look for the move in the
; interrupt.
; For changing into a 1 or 4 pixel
; sinus (depending on the available
; raster time) look for the marked
; positions in the routine. You must
; change the blitter mask and at a 
; second place the shift value of
; the blitter mask. When you make a
; One pixel sinus or even with a two
; pixel one you will notice that the
; scroller is scrambled at the right
; end. In this case the routine didn't			; didn't-hasn't
; already finished when the raster line
; reached this point. To avoid it you
; must work with double buffering. Make
; two screens. One for blitting and the
; other for beeing displayed. Every			; being
; interupt you swap them, it's very
; easy. Also you must make a longer
; sinus wave. The sinus is peridically			; periodical
; and you must add another 256 degree
; turn for the new 160 positions.
; Try it and good luck!
;            Yours         DRM
; ------------- Nachladen --------------
>extern "data7",$60000
jmp		$50000
org		$50000
load		$50000
; -------------- Offsets ---------------
vbeampos=	-384
openlibrary= 	-408
closelibrary= 	-414
forbid= 	-132
permit= 	-138
execbase= 	$04
; --------------------------------------
start:
movem.l 	d0-d7/a0-a6,-(a7)	; Save registers
; --------------------------------------
; ------- Graphics Libary oeffnen ------
move.l		execbase,a6
lea		gfxname,a1 	
jsr		openlibrary(a6)
beq		end
move.l		d0,gfxbase
; -------- Prepare Sinus Table ---------
lea		sin(pc),a0
ll:
move.w		(a0),d1
muls		#30,d1			; Amplitude of the sinus wave!!
asr.l		#8,d1
muls		#44,d1
add.l		#$61000+[140*44],d1	; Middle line of sinus wave
move.w		d1,(a0)+
cmp.l		#send,a0
bne.s		ll
; ----------- Clear screen -------------
moveq		#10,d1
sy:
lea		$60fd0,a0
move.w		#$1000,d0
sz:
clr.l		(a0)+
dbf		d0,sz
dbf		d1,sy
; --------------------------------------
move.l		execbase,a6
jsr		forbid(a6)
; ---- Eigene Copperliste einsetzen ----
move.l		gfxbase(pc),a0
lea		$32(a0),a0
lea		$dff000,a5
move.l		#0,$40(a5)
move.w		#$0080,$96(a5)
move.l		(a0),oldcopper
move.l		#newcopper,(a0)
move.w		#$8080,$96(a5)
; --------- Change IRQ vector ----------
move.l		$6c,oldirq
move.l		#newirq,$6c
; ------- Main program Waitloop --------
main:
btst		#6,$bfe001
bne.s		main
; --------------------------------------
move.l		oldirq(pc),$6c
; --------- close GFX-Library ----------
move.l		execbase,a6
move.l		gfxbase,a1
jsr		closelibrary(a6)
; ----- write old Copperlist back  -----
move.l		gfxbase(pc),a0
lea		$32(a0),a0
move.w		#$0080,$96(a5)
move.l		oldcopper(pc),(a0)
move.w		#$8080,$96(a5)
; ------ reactiveate Multitasking ------
move.l		execbase,a6
jsr		permit(a6)
; --------------- Exit -----------------
movem.l		(a7)+,d0-d7/a0-a6
end:
rts
; --------------------------------------
; --------------------------------------
newirq:					; Our interrupt
movem.l		d0-d7/a0-a6,-(sp)	; Save registers
moveq		#2,d5
moveq		#6,d6
; --------------------------------------
cmp.b		#$7f,$bfec01		; Check space key
beq		i0
bsr.s		ppppp1
i0:
bsr		copy
move.w		#$320,$180(a5)		; Set backgroundcolour. Remove
					; when you want it. It shows when
					; the blitterroutine has
					; finished. When this mark comes
					; into the area of the sinus
					; this will be spoiled. Then you
					; must use double buffering.
; --------------------------------------
movem.l		(sp)+,d0-d7/a0-a6	; IRQ End
dc.w		$4ef9
oldirq:
dc.l		0
; --------------------------------------
ppppp1:
move.l		#$61000,$50(a5)
move.l		#$60ffe,$54(a5)
clr.l		$64(a5)
move.l		#$ffff0fff,$44(a5)
move.w		#$e9f0,$40(a5)
move.w		#[14*1]*64+$16,$58(a5)
; --------------------------------------
add.w		d5,srr
cmpi.w		#18,srr
bcs.s		no
clr.w		srr
bsr.s		print1			; neues zeichen ausgeben
no:
rts
srr:	dc.w	0
sxx:	dc.l	msg
; --------------------------------------
print1:
moveq		#0,d0
moveq		#0,d1
move.l		sxx(pc),a0
move.b		(a0),d0
sub.b		#32,d0
bpl.s		nnm
moveq		#16,d0
nnm:
move.b		d0,d1
divu		#20,d1
move.w		d1,d2
swap		d1
move.w		d1,d3
add.w		d3,d3
mulu		#14*40,d2
add.w		d2,d3
moveq		#6,d0
swap		d0
add.w		d3,d0
move.l		d0,$50(a5)
move.l		#$61028,$54(a5)		; Blit Source
move.l		#$0026002a,$64(a5)	; Modulo
move.w		#$ffff,$46(a5)		; Maske
move.w		#$09f0,$40(a5)		; Modus
move.w		#13*1,d0		; Hoehe
asl.w		d6,d0
addq.w		#1,d0			; Breite
move.w		d0,$58(a5)		; Start
addq.l		#1,sxx			; naechstes Zeichen
cmp.l		#ende,sxx
bcs.s		eee
move.l		#msg,sxx
eee:
rts
; ----------- Sinuskopieren ------------
copy:
					; Clear sinus area. Take care
move.l	#$61000+[108*44],$54(a5)	; that you clear the right
move.l	#$00040004,$64(a5)		; area. And clear enought but
move.l	#$0000ffff,$44(a5)		; not more than necessary.
move.l	#$01000000,$40(a5)
move.w	#[76*1]*64+$14,$58(a5)		; Size of clearing
; --------------------------------------
addq.w		#3,cx			; This counter lets your sinus
cmpi.w		#256*2,cx		; wave move with the set speed
bcs.s		cno
clr.w		cx
cno:
move.l		#$61000,d1
moveq		#$6,d3
swap		d3
moveq		#0,d4
lea		sin(pc),a0
move.w		cx(pc),d0
and		#$fffe,d0
lea		(a0,d0.w),a0
clend:					; Wait
btst		d6,$dff002
bne.s		clend
move.l		#$002a002a,$60(a5)	; Modulo Values for Blitter
move.l		#$002a002a,$64(a5)
move.w		#-1,$46(a5)		; Second Mask Word must be filled
move.l		#$0b5a0000,$40(a5)

move.w		#13*64+1,d0
lea		$50(a5),a1
lea		$48(a5),a2
lea		$54(a5),a3
lea		$44(a5),a4
lea		$58(a5),a6
cn1:					; Extern loop: For getting all
					; 20 words of one line
move.w		#$c000,d2		; Set blit mask. For one (four)
					; pixel sinus set to $8000
					; ($f000)
cn2:					; Intern loop: Copies from your
					; word one, two or four bits
					; together in 16, 8 or 4 steps.

move.w		(a0),d3			; Endadress of Sinus List
add.w		d4,d3
move.l		d1,(a1)			; A
move.l		d3,(a2)			; C
move.l		d3,(a3)			; D
move.w		d2,(a4)			; Set Mask
move.w		d0,(a6)

lea		(a0,d5.w),a0
lsr.w		d5,d2			; Shift Blitter mask left for
					; copying the other bits of
					; this word. For one (four)
					; pixel scroller set to 1 (4)!
bne		cn2
add.l		d5,d1
add.l		d5,d4
cmpi.l		#$28,d4
bne.s		cn1
rts
; ---------------- Datas ---------------
cx:	dc.w	0
sin:					; Sinusnumbers. This sinus table
					; has 256 degrees. Important! In
					; the Init part a routine 
					; multiplicates a values with
					; the size of one screen line
					; and adds the base adress!!!!
DC.W	$0100,$0100,$0100,$00FF,$00FF,$00FE,$00FD,$00FC
DC.W	$00FB,$00FA,$00F8,$00F7,$00F5,$00F3,$00F1,$00EF
DC.W	$00ED,$00EA,$00E7,$00E5,$00E2,$00DF,$00DC,$00D8
DC.W	$00D5,$00D1,$00CE,$00CA,$00C6,$00C2,$00BE,$00B9
DC.W	$00B5,$00B1,$00AC,$00A7,$00A2,$009D,$0098,$0093
DC.W	$008E,$0089,$0084,$007E,$0079,$0073,$006D,$0068
DC.W	$0062,$005C,$0056,$0050,$004A,$0044,$003E,$0038
DC.W	$0032,$002C,$0026,$001F,$0019,$0013,$000D,$0006
DC.W	$0000,$FFFA,$FFF3,$FFED,$FFE7,$FFE1,$FFDA,$FFD4
DC.W	$FFCE,$FFC8,$FFC2,$FFBC,$FFB6,$FFB0,$FFAA,$FFA4
DC.W	$FF9E,$FF98,$FF93,$FF8D,$FF87,$FF82,$FF7C,$FF77
DC.W	$FF72,$FF6D,$FF67,$FF62,$FF5E,$FF59,$FF54,$FF4F
DC.W	$FF4B,$FF47,$FF42,$FF3E,$FF3A,$FF36,$FF32,$FF2F
DC.W	$FF2B,$FF28,$FF24,$FF21,$FF1E,$FF1B,$FF19,$FF16
DC.W	$FF13,$FF11,$FF0F,$FF0D,$FF0B,$FF09,$FF08,$FF06
DC.W	$FF05,$FF04,$FF03,$FF02,$FF01,$FF01,$FF00,$FF00
DC.W	$FF00,$FF00,$FF00,$FF01,$FF01,$FF02,$FF03,$FF04
DC.W	$FF05,$FF06,$FF08,$FF09,$FF0B,$FF0D,$FF0F,$FF11
DC.W	$FF13,$FF16,$FF19,$FF1B,$FF1E,$FF21,$FF24,$FF28
DC.W	$FF2B,$FF2F,$FF32,$FF36,$FF3A,$FF3E,$FF42,$FF47
DC.W	$FF4B,$FF4F,$FF54,$FF59,$FF5E,$FF63,$FF68,$FF6D
DC.W	$FF72,$FF77,$FF7C,$FF82,$FF87,$FF8D,$FF93,$FF98
DC.W	$FF9E,$FFA4,$FFAA,$FFB0,$FFB6,$FFBC,$FFC2,$FFC8
DC.W	$FFCE,$FFD4,$FFDA,$FFE1,$FFE7,$FFED,$FFF3,$FFFA
DC.W	$0000,$0006,$000D,$0013,$0019,$001F,$0026,$002C
DC.W	$0032,$0038,$003E,$0044,$004A,$0050,$0056,$005C
DC.W	$0062,$0068,$006D,$0073,$0079,$007E,$0084,$0089
DC.W	$008E,$0093,$0099,$009E,$00A2,$00A7,$00AC,$00B1
DC.W	$00B5,$00B9,$00BE,$00C2,$00C6,$00CA,$00CE,$00D1
DC.W	$00D5,$00D8,$00DC,$00DF,$00E2,$00E5,$00E7,$00EA
DC.W	$00ED,$00EF,$00F1,$00F3,$00F5,$00F7,$00F8,$00FA
DC.W	$00FB,$00FC,$00FD,$00FE,$00FF,$00FF,$0100,$0100
DC.W	$0100,$0100,$0100,$00FF,$00FF,$00FE,$00FD,$00FC
DC.W	$00FB,$00FA,$00F8,$00F7,$00F5,$00F3,$00F1,$00EF
DC.W	$00ED,$00EA,$00E7,$00E5,$00E2,$00DF,$00DC,$00D8
DC.W	$00D5,$00D1,$00CE,$00CA,$00C6,$00C2,$00BE,$00B9
DC.W	$00B5,$00B1,$00AC,$00A7,$00A2,$009D,$0098,$0093
DC.W	$008E,$0089,$0084,$007E,$0079,$0073,$006D,$0068
DC.W	$0062,$005C,$0056,$0050,$004A,$0044,$003E,$0038
DC.W	$0032,$002C,$0026,$001F,$0019,$0013,$000D,$0006
DC.W	$0000,$FFFA,$FFF3,$FFED,$FFE7,$FFE1,$FFDA,$FFD4
DC.W	$FFCE,$FFC8,$FFC2,$FFBC,$FFB6,$FFB0,$FFAA,$FFA4
DC.W	$FF9E,$FF98,$FF93,$FF8D,$FF87,$FF82,$FF7C,$FF77
DC.W	$FF72,$FF6D,$FF67,$FF62,$FF5E,$FF59,$FF54,$FF4F
DC.W	$FF4B,$FF47,$FF42,$FF3E,$FF3A,$FF36,$FF32,$FF2F
DC.W	$FF2B,$FF28,$FF24,$FF21,$FF1E,$FF1B,$FF19,$FF16
DC.W	$FF13,$FF11,$FF0F,$FF0D,$FF0B,$FF09,$FF08,$FF06
DC.W	$FF05,$FF04,$FF03,$FF02,$FF01,$FF01,$FF00,$FF00
DC.W	$FF00,$FF00,$FF00,$FF01,$FF01,$FF02,$FF03,$FF04
DC.W	$FF05,$FF06,$FF08,$FF09,$FF0B,$FF0D,$FF0F,$FF11
DC.W	$FF13,$FF16,$FF19,$FF1B,$FF1E,$FF21,$FF24,$FF28
DC.W	$FF2B,$FF2F,$FF32,$FF36,$FF3A,$FF3E,$FF42,$FF47
DC.W	$FF4B,$FF4F,$FF54,$FF59,$FF5E,$FF63,$FF68,$FF6D
DC.W	$FF72,$FF77,$FF7C,$FF82,$FF87,$FF8D,$FF93,$FF98
DC.W	$FF9E,$FFA4,$FFAA,$FFB0,$FFB6,$FFBC,$FFC2,$FFC8
DC.W	$FFCE,$FFD4,$FFDA,$FFE1,$FFE7,$FFED,$FFF3,$FFFA
DC.W	$0000,$0006,$000D,$0013,$0019,$001F,$0026,$002C
DC.W	$0032,$0038,$003E,$0044,$004A,$0050,$0056,$005C
DC.W	$0062,$0068,$006D,$0073,$0079,$007E,$0084,$0089
DC.W	$008E,$0093,$0099,$009E,$00A2,$00A7,$00AC,$00B1
DC.W	$00B5,$00B9,$00BE,$00C2,$00C6,$00CA,$00CE,$00D1
DC.W	$00D5,$00D8,$00DC,$00DF,$00E2,$00E5,$00E7,$00EA
DC.W	$00ED,$00EF,$00F1,$00F3,$00F5,$00F7,$00F8,$00FA
DC.W	$00FB,$00FC,$00FD,$00FE,$00FF,$00FF,$0100,$0100
send:
; ------------ Copperliste -------------
newcopper:
dc.w 	$008e,$2881,$0090,$28c1 ; Bildschirmgrenzen 
dc.w 	$0092,$0038,$0094,$00d0 ; DataFetch Start/Stop
dc.w 	$0108,$0004,$010a,$0004	; Modulos
dc.w 	$0102,$0001,$0104,$0040 ; Control Reg. #1 u. #2
dc.w 	$0100,$2200		; Control Reg. #0

dc.w	$00e0,$0006,$00e2,$1000-44
dc.w	$00e4,$0006,$00e6,$1000

dc.w	$0180,$0211,$0182,$0980
dc.w	$0184,$0ff0,$0186,$0cb0
dc.w	$0188,$0ddd,$018a,$0bbb
dc.w	$018c,$0999,$018e,$0866

dc.w	$0120,$0000,$0122,$0000
dc.w	$0128,$0000,$012a,$0000
dc.w	$0130,$0000,$0132,$0000
dc.w	$0138,$0000,$013a,$0000

dc.w	$ffff,$fffe
; ------------- Scrolltext -------------
msg:
DC.B	"ALPHA FLIGHT PROUDLY PRESENTS ---       "
DC.B	"A MEGA PRODUCTION FROM DOCTOR MABUSE.   "
DC.B	"THE UNBEATABLE CODER  JEAH!!! "
dc.b	'OPTIMIZED BY THE D.I.S.C - TEAM !!! '
ende:
even
; ---------- Systemregister ------------
gfxbase:	dc.l 	0
oldcopper:	dc.l	0
gfxname:
dc.b 	"graphics.library",0,0
; ------ Pointer der Scrollroutine -----
