;**********************************
;* OKTALYZER V1.1 REPLAYER SOURCE *
;*  BY A.SANDER  ONLY 4 CHANNELS  *
;**********************************
p:	bsr.s	rs_init
	bmi.s	rs_error
rs_left:btst	#6,$bfe001
	bne.s	rs_left
	bsr.l	rs_exit
	moveq	#0,d0
	rts
rs_error:moveq	#100,d0
	rts
;
rs_init:lea	rs_song,a5
	cmp.l	#'OKTA',(a5)
	bne.l	rs_error2
	addq.l #4,a5
	cmp.l	#'SONG',(a5)
	bne.l	rs_error2
	addq.l #4,a5
	move.l	a5,a0
	lea	rs_cmformat(pc),a1
	bsr.l	rs_search
	lea	rs_channelmodes(pc),a0
	tst.l	(a0)+
	bne.l	rs_error2
	tst.l	(a0)+
	bne.l	rs_error2
	move.l	a5,a0
	lea	rs_extformat(pc),a1
	bsr.l	rs_search
	move.l	a5,a0
	bsr.l	rs_getpatts
	move.l	a5,a0
	bsr.l	rs_getsamples
	clr.w	rs_pointer
	bsr.l	rs_gettrkpos
	sub.l	#16,rs_trkpos
	subq.w	#1,rs_patty
	move.l	#$40404040,rs_vol
	clr.w	rs_filter
	move.w	rs_speed(pc),rs_actspeed
	clr.w	rs_actcyc
	move.w	#-1,rs_nextpt
	lea	rs_pbuffs(pc),a0
	moveq	#15,d0
rs_loop4:	clr.l	(a0)+
	dbf	d0,rs_loop4
	lea	rs_pattline(pc),a0
	moveq	#3,d0
rs_loop5:	clr.l	(a0)+
	dbf	d0,rs_loop5
	move.w	#$ff,$dff09e
	move.l	$6c.w,rs_oldint+2
	move.l	#rs_int,$6c.w
	move.w	#$c020,$dff09a
	moveq	#0,d0
	rts
rs_error2:moveq	#-1,d0
	rts
* format search ***********************
;a0:fpt
;a1:format list
rs_search:	move.l	a0,a2
	move.l	(a1)+,d0
	beq.s	rs_ex
rs_loop:cmp.l	#rs_songend,a2
	beq.s	rs_ex
	cmp.l	(a2)+,d0
	bne.s	rs_next
	move.l	(a1)+,d0
	cmp.l	(a2)+,d0
	ble.s	rs_nocorrect
	move.l	-4(a2),d0
rs_nocorrect:	move.l	(a1)+,a3
rs_copy:	subq.l	#1,d0
	bmi.s	rs_search
	move.b	(a2)+,(a3)+
	bra.s	rs_copy
rs_next:	add.l	(a2)+,a2
	bra.s	rs_loop
rs_ex:		rts
rs_getpatts:	lea	rs_pattpts(pc),a1
	move.l	#'PBOD',d0
rs_loop2:	cmp.l	#rs_songend,a0
	beq.s	rs_ready
	movem.l	(a0)+,d1-d2
	cmp.l	d0,d1
	beq.s	rs_got
	add.l	d2,a0
	bra.s	rs_loop2
rs_got:		move.l	a0,(a1)+
	add.l	d2,a0
	bra.s	rs_loop2
rs_ready:	rts
rs_getsamples:	lea	rs_samplepts(pc),a1
	lea	rs_samples(pc),a2
	move.l	#'SBOD',d0
rs_loop2a:	cmp.l	#rs_songend,a0
	beq.s	rs_sready
	movem.l	(a0)+,d1-d2
	cmp.l	d0,d1
	beq.s	rs_gots
	add.l	d2,a0
	bra.s	rs_loop2a
rs_gots:	tst.l	20(a2)
	bne.s	rs_setsample
	lea	32(a2),a2
	clr.l	(a1)+
	bra.s	rs_gots
rs_setsample:	move.l	a0,(a1)+
	lea	32(a2),a2
	add.l	d2,a0
	bra.s	rs_loop2a
rs_sready:	rts
;
rs_exit:move.w	#$4000,$dff09a
	move.l	rs_oldint+2(pc),$6c.w
	move.w	#$c000,$dff09a
	lea	$dff000,a6
	moveq	#0,d0
	move.w	#$f,$96(a6)
	move.w	d0,$a8(a6)
	move.w	d0,$b8(a6)
	move.w	d0,$c8(a6)
	move.w	d0,$d8(a6)
	rts
rs_int:	btst	#5,$dff01f
	beq.s	rs_oldint
	movem.l	d0-d7/a0-a6,-(sp)
	bsr.s	rs_rh
	movem.l	(sp)+,d0-d7/a0-a6
rs_oldint:	jmp	0
rs_rh:	bsr.l	rs_p4
	addq.w	#1,rs_actcyc
	move.w	rs_actspeed(pc),d0
	cmp.w	rs_actcyc(pc),d0
	ble.s	rs_addcyc
	rts
rs_addcyc:clr.w	rs_actcyc
	moveq	#16,d0
	add.l	d0,rs_trkpos
	addq.w	#1,rs_patty
	bsr.l	rs_getppatt
	tst.w	rs_nextpt
	bpl.s	rs_pattend
	cmp.w	rs_patty(pc),d0
	bgt.s	rs_nonew
rs_pattend:	clr.w	rs_patty
	tst.w	rs_nextpt
	bmi.s	rs_nonextpt
	move.w	rs_nextpt(pc),rs_pointer
	bra.s	rs_newpos
rs_nonextpt:	addq.w	#1,rs_pointer
rs_newpos:move.w rs_pointer(pc),d0
	cmp.w	rs_len(pc),d0
	bne.s	rs_nonewinit
	clr.w	rs_pointer
	move.w	rs_speed(pc),rs_actspeed
rs_nonewinit:	bsr.l	rs_gettrkpos
rs_nonew:	move.l	rs_trkpos(pc),a0
	lea	rs_pattline(pc),a1
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.w	#-1,rs_nextpt
	rts
rs_p4:	tst.w	rs_actcyc
	bne.s	rs_effects
	bsr.s	rs_set
	tst.w	d4
	beq.s	rs_effects
	bsr.l	rs_dma
	bsr.l	rs_setperiods
	or.w	#$8000,d4
	move.w	d4,$dff096
	bsr.l	rs_dma
	bsr.l	rs_action
rs_effects:	bsr.l	rs_effect
	lea	rs_vol(pc),a0
	lea	$dff0a9,a1
	move.b	(a0)+,(a1)
	move.b	(a0)+,$10(a1)
	move.b	(a0)+,$20(a1)
	move.b	(a0)+,$30(a1)
	tst.b	rs_filter
	beq.s	rs_blink
	bclr	#1,$bfe001
	rts
rs_blink:bset	#1,$bfe001
	rts
rs_set:	lea	rs_samplepts(pc),a0
	lea	rs_pattline(pc),a2
	lea	rs_pbuffs(pc),a3
	lea	$dff0a0,a4
	lea	rs_periods(pc),a6
	moveq	#0,d4
	moveq	#1,d5
	moveq	#3,d7
rs_ploop:	bsr.s	rs_set4
	addq.w	#4,a2
	lea	16(a3),a3
	lea	$10(a4),a4
	add.w	d5,d5
	dbf	d7,rs_ploop
	rts
rs_set4:	moveq	#0,d3
	move.b	(a2),d3
	beq.l	rs_noset
	subq.w	#1,d3
	moveq	#0,d0
	move.b	1(a2),d0
	add.w	d0,d0
	add.w	d0,d0
	move.l	(a0,d0.w),d2
	beq.l	rs_noset
	lsl.w	#3,d0
	lea	rs_samples(pc),a1
	add.w	d0,a1
	tst.w	30(a1)
	beq.l	rs_noset
	move.l	20(a1),d1
	lsr.l	#1,d1
	tst.w	d1
	beq.l	rs_noset
	move.w	#124,6(a4)
	lsl.w	#7,d5
	move.w	d5,$dff09a
	lsr.w	#7,d5
	move.w	d5,$dff096
	or.w	d5,d4
	move.l	d2,(a4)
	move.w	d3,12(a3)
	add.w	d3,d3
	move.w	(a6,d3.w),14(a3)
	move.l	a0,-(sp)
	lea	rs_vol(pc),a0
	moveq	#0,d0
	move.b	rs_volum1(pc,d7.w),d0
	move.b	29(a1),(a0,d0.w)
	move.l	(sp)+,a0
	tst.w	26(a1)
	beq.s	rs_norep
	tst.w	24(a1)
	bne.s	rs_realrep
	move.w	26(a1),4(a4)
	clr.l	(a3)
	clr.w	4(a3)
	moveq	#0,d0
	move.w	26(a1),d0
	add.l	d0,d0
	add.l	d0,d2
	move.l	d2,6(a3)
	move.l	20(a1),d1
	sub.l	d0,d1
	lsr.l	#1,d1
	move.w	d1,10(a3)
	rts
rs_volum1:	dc.b	3,2,1,0
rs_realrep:	move.w	24(a1),4(a4)
	moveq	#0,d0
	move.w	24(a1),d0
	add.l	d0,d0
	add.l	d2,d0
	move.l	d0,(a3)
	move.w	26(a1),4(a3)
	moveq	#0,d0
	move.w	24(a1),d0
	add.w	26(a1),d0
	add.l	d0,d0
	add.l	d0,d2
	move.l	d2,6(a3)
	move.l	20(a1),d1
	sub.l	d0,d1
	lsr.l	#1,d1
	move.w	d1,10(a3)
	rts
rs_norep:	move.w	d1,4(a4)
	moveq	#2,d0
	move.l	d0,(a3)
	move.w	#1,4(a3)
	clr.l	6(a3)
	clr.w	10(a3)
rs_noset:	rts
rs_setperiods:	lea	rs_pbuffs(pc),a3
	lea	$dff000,a4
	btst	#0,d4
	beq.s	rs_notc1
	move.w	14(a3),$a6(a4)
rs_notc1:	btst	#1,d4
	beq.s	rs_notc2
	move.w	30(a3),$b6(a4)
rs_notc2:	btst	#2,d4
	beq.s	rs_notc3
	move.w	36(a3),$c6(a4)
rs_notc3:	btst	#3,d4
	beq.s	rs_notc4
	move.w	62(a3),$d6(a4)
rs_notc4:	rts
rs_action:	lea	rs_pbuffs(pc),a3
	lea	$dff0a0,a4
	moveq	#3,d7
rs_aloop:move.l	(a3),d0
	beq.s	rs_nopt
	move.l	d0,(a4)
	clr.l	(a3)
rs_nopt:move.w	4(a3),d0
	beq.s	rs_nolen
	move.w	d0,4(a4)
	clr.w	4(a3)
rs_nolen:lea	16(a3),a3
	lea	$10(a4),a4
	dbf	d7,rs_aloop
	rts
rs_effect:	lea p(pc),a1
	lea	rs_pattline(pc),a2
	lea	rs_pbuffs(pc),a3
	lea	$dff0a0,a4
	lea	rs_periods(pc),a6
	moveq	#1,d5
	moveq	#3,d7
rs_eloop:bsr.s	rs_doeff
	addq.w	#4,a2
	lea	$10(a3),a3
	lea	$10(a4),a4
	add.w	d5,d5
	dbf	d7,rs_eloop
	rts
rs_doeff:	moveq	#0,d0
	move.b	2(a2),d0
	add.w	d0,d0
	moveq	#0,d1
	move.b	3(a2),d1
	move.w	rs_effecttab(pc,d0.w),d0
	beq.s	rs_noeff
	bmi.s	rs_1eff
	jsr	(a1,d0.w)
	bra.s	rs_noeff
rs_effecttab:	dc.w	0,rs_portd-p,rs_portu-p,0,0,0
	dc.w	0,0,0,0,rs_arp-p,rs_arp2-p
	dc.w	0,rs_slided-p,0,p-rs_filt,0,p-rs_slideu
	dc.w	0,0,0,p-rs_slided,0,0
	dc.w	0,p-rs_posjmp,0,p-rs_release,p-rs_cspeed,0
	dc.w	rs_slideu-p,rs_volume-p,0,0,0,0
rs_1eff:	tst.w	rs_actcyc
	bne.s	rs_noeff
	neg.w	d0
	jsr	(a1,d0.w)
rs_noeff:	rts
rs_portd:	sub.w	d1,14(a3)
	bpl.s	rs_pdok
	move.w	#113,14(a3)
rs_pdok:	move.w	14(a3),6(a4)
	rts
rs_portu:	add.w	d1,14(a3)
	bpl.s	rs_puok
	move.w	#113,14(a3)
rs_puok:	move.w	14(a3),6(a4)
	rts
rs_arp:		move.w	12(a3),d2
	move.w	rs_actcyc(pc),d0
	move.b	rs_divtab(pc,d0.w),d0
	bne.s	rs_val1
	and.w	#$f0,d1		;runter
	lsr.w	#4,d1
	sub.w	d1,d2
	bra.s	rs_setarp
rs_divtab:	dc.b	0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2
rs_val1:	subq.b	#1,d0
	bne.s	rs_val2
	move.w	d2,8(a4)
	bra.s	rs_setarp
rs_val2:	and.w	#$0f,d1
	add.w	d1,d2
	bra.s	rs_setarp
rs_arp2:	move.w	12(a3),d2
	move.w	rs_actcyc(pc),d0
	and.w	#3,d0
	bne.s	rs_val3
	bra.s	rs_setarp
rs_val3:	subq.b	#1,d0
	bne.s	rs_val4
	and.w	#$f,d1
	add.w	d1,d2
	bra.s	rs_setarp
rs_val4:	subq.b	#1,d0
	beq.s	rs_setarp
	and.w	#$f0,d1
	lsr.w	#4,d1
	sub.w	d1,d2
rs_setarp:	tst.w	d2
	bpl.s	rs_arpok1
	moveq	#0,d2
rs_arpok1:	cmp.w	#35,d2
	ble.s	rs_arpok2
	moveq	#35,d2
rs_arpok2:	add.w	d2,d2
	move.w	(a6,d2.w),d0
	move.w	d0,6(a4)
	move.w	d0,14(a3)
	rts
rs_slided:	move.w	12(a3),d2
	sub.w	d1,d2
	move.w	d2,12(a3)
	bra.s	rs_setarp
rs_slideu:	move.w	12(a3),d2
	add.w	d1,d2
	move.w	d2,12(a3)
	bra.s	rs_setarp
rs_cspeed:	tst.b	d1
	beq.s	rs_nochange
	and.w	#$f,D1
	move.w	d1,rs_actspeed
rs_nochange:	rts
rs_filt:	tst.b	d1
	sne	rs_filter
	rts
rs_volume:move.l a0,-(sp)
	lea	rs_vol(pc),a0
	moveq	#0,d0
	move.b	volum2(pc,d7.w),d0
	add.w	d0,a0
	cmp.w	#$40,d1
	bgt.s	rs_4567
	move.b	d1,(a0)
rs_vex:	move.l	(sp)+,a0
	rts
volum2:		dc.b	3,2,1,0
rs_4567:sub.b	#$40,d1
	cmp.b	#$10,d1
	blt.s	rs_4
	sub.b	#$10,d1
	cmp.b	#$10,d1
	blt.s	rs_5
	sub.b	#$10,d1
	cmp.b	#$10,d1
	blt.s	rs_6
	sub.b	#$10,d1
	cmp.b	#$10,d1
	blt.s	rs_7
	bra.s	rs_vex
rs_6:	tst.w	rs_actcyc
	bne.s	rs_vex
rs_4:	sub.b	d1,(a0)
	bpl.s	rs_vex
	clr.b	(a0)
	bra.s	rs_vex
rs_7:	tst.w	rs_actcyc
	bne.s	rs_vex
rs_5:	add.b	d1,(a0)
	cmp.b	#$40,(a0)
	ble.s	rs_vex
	move.b	#$40,(a0)
	bra.s	rs_vex
rs_release:	tst.l	6(a3)
	beq.s	rs_rex
	tst.w	10(a3)
	beq.s	rs_rex
	move.w	d5,d0
	lsl.w	#7,d0
	move.w	d0,$dff09a
	move.l	6(a3),(a4)
	move.w	10(a3),4(a4)
	clr.l	6(a3)
	clr.w	10(a3)
	move.w	d0,$dff09c
	or.w	#$8000,d0
	move.w	d0,$dff09a
rs_rex:		rts
rs_posjmp:	move.w	d1,d0
	and.w	#$f,d0
	lsr.w	#4,d1
	mulu	#10,d1
	add.w	d1,d0
	cmp.w	rs_len(pc),d0
	bge.s	rs_nojmp
	move.w	d0,rs_nextpt
rs_nojmp:rts
rs_gettrkpos:	lea	rs_patterns(pc),a0
	add.w	rs_pointer(pc),a0
	moveq	#0,d0
	move.b	(a0),d0
	bsr.s	rs_getpattern
	move.l	a0,rs_trkpos
	clr.w	rs_patty
	rts
rs_getppatt:	lea	rs_patterns(pc),a0
	add.w	rs_pointer(pc),a0
	moveq	#0,d0
	move.b	(a0),d0
rs_getpattern:	lea	rs_pattpts(pc),a0
	add.w	d0,d0
	add.w	d0,d0
	move.l	(a0,d0.w),a0
	move.w	(a0)+,d0
	rts
rs_dma:	movem.w	d0-d1,-(sp)
	move.w	#4,d1
rs_nextline:	move.b	$dff006,d0
rs_waitline:	cmp.b	$dff006,d0
	beq.s	rs_waitline
	dbf	d1,rs_nextline
	movem.w	(sp)+,d0-d1
	rts
rs_cmformat:	dc.l	'CMOD',8,rs_channelmodes
rs_extformat:	dc.l	'SAMP',36*32,rs_samples
	dc.l	'SPEE',2,rs_speed
	dc.l	'PLEN',2,rs_len
	dc.l	'PATT',128,rs_patterns,0
rs_channelmodes:ds.w	4
rs_samples:	ds.b	36*32
rs_speed:	dc.w	6
rs_len:		dc.w	1
rs_patterns:	ds.b	128
rs_pattpts:	ds.l	64
rs_samplepts:	ds.l	36
rs_patty:	ds.w	1
rs_trkpos:	ds.l	1
rs_pbuffs:	ds.l	16
rs_pattline:	ds.l	4
rs_actspeed:	ds.w	1
rs_actcyc:	ds.w	1
rs_nextpt:	ds.w	1
rs_pointer:	ds.w	1
rs_vol:		ds.l	1
rs_filter:	ds.w	1
rs_oldaud:	ds.l	1
rs_periods:	dc.w	$358,$328,$2FA,$2D0,$2A6,$280,$25C,$23A,$21A
		dc.w	$1FC,$1E0,$1C5,$1AC,$194,$17D,$168,$153,$140
		dc.w	$12E,$11D,$10D,$FE,$F0,$E2,$D6,$CA,$BE
		dc.w	$B4,$AA,$A0,$97,$8F,$87,$7F,$78,$71
xx=30999
rs_song:blk.b xx
rs_songend:
>extern "songname",rs_song,xx
