
;[1m[32m        ____     ___        ___     ___ ___ ___ ___ ____      ___ ___ ___[0m
;[1m[32m         /  /__//_         /__ /  //_ //__ /  //_    /  / / //_ //__//_  [0m
;[1m[32m        /  /  //__        ___//__//__/___//__//     /  /_/_//  //  \/__  [0m
;
;[1m[32m-----------------------------------------------------------------------------[0m
;          - FOR ABO'S CONTACT US AT:  BP:36 1380 REBECK BELGIUM!!...
;
;[1m[32m-----------------------------------------------------------------------------[0m
;                           - DON'T SEND ANY DISKS -
;
;[1m[32m-----------------------------------------------------------------------------[0m
;
;
;                         [33m THE LEGENDARY >> SUBSOFTWARE << IN 87/88/89/90!!...
;                         [1m[32m ---------------------------------------------------



;		*** DeCrunching and playroutine for STC ***

		bsr	stc_decrunch
		bsr	mt_init
;		...
;		MAIN PROGRAM
;		...
;		bsr	mt_music	(repeat every 1/50 seconds!)
;		....
;		....
;		bsr	mt_end
;
; You must allocate memory for decrunched module (size equal to 
; original module, size found on crunched module. See document.)
; Put address of crunched module to a0 and address of allocated memory
; to a1.
;
; Look at line #3 on a source code. As you see, you must add #8 to 
; startaddress of crunched module.


stc_decrunch:	move.l	#DeCrunchBase,a1
		move.l	a1,stc_playbase		;Start of decrunched module.
		move.l	#CrunchBase+8,a0	;DeCrunching starts 8 bytes
		lea	stc_e-3(pc),a4		;after start of crunched module
		moveq	#0,d0
		move.l	CrunchBase+4,d1		; Original size to d1.
		moveq	#8,d2
		bsr.s	stc_c
		move.b	d3,(a1)+
		subq.l	#1,d1
stc_1:		moveq	#2,d2
		bsr.s	stc_c
		beq.s	stc_2
		cmpi.w	#2,d3
		blt.s	stc_8
		bgt.s	stc_3	
		moveq	#7,d2
		bra.s	stc_4

stc_3:		moveq	#2,d2
		bsr.s	stc_c
		move.l	d3,d2
		addq.l	#3,d2
stc_4:		move.b	-1(a1),d4
stc_5:		bsr.s	stc_c
		cmp.b	0(a4,d2.w),d3
		beq.s	stc_7
		blt.s	stc_6
		or.b	5(a4,d2.w),d3
stc_6:		add.b	d3,d4
		move.b	d4,(a1)+
		subq.l	#1,d1
		bne.s	stc_5
		bra.s	stc_7

stc_2:		bsr.s	stc_d
		sub.l	d5,d1
		moveq	#8,d2
stc_2b:		bsr.s	stc_c
		move.b	d3,(a1)+
		subq.l	#1,d5
		bne.s	stc_2b

stc_7:		nop		;  <---	If you want those decrunching colours
		tst.l	d1	;this would be a perfect place...
		bne.s	stc_1	;(You can try for example 'clr.w $dff180'
		rts		;or 'ror.w #1,$dff180' or 'move.w $dff006,$dff180')

stc_8:		bsr.s	stc_d
		sub.l	d5,d1
		moveq	#8,d2
		bsr.s	stc_c
stc_9:		move.b	d3,(a1)+
		subq.l	#1,d5
		bne.s	stc_9
		bra.s	stc_7

stc_c:		move.l	(a0),d3
		tst.w	d0
		beq.s	stc_a
		lsl.l	d0,d3
stc_a:		rol.l	d2,d3
		add.w	d2,d0
		cmpi.w	#16,d0
		blt.s	stc_b
		andi.w	#$f,d0
		addq.l	#2,a0
stc_b:		move.l	#$ffff0000,d6
		rol.l	d2,d6
		and.l	#$0000ffff,d6
		and.l	d6,d3
		rts

stc_d:		moveq	#6,d2
		bsr.s	stc_c
		move.l	d3,d5
		cmpi.w	#%111000,d5
		blt.s	stc_gl2
		cmpi.w	#%111011,d5
		blt.s	stc_gl1
		moveq	#16,d2
		bsr.s	stc_c
		lsl.l	#2,d3
		move.l	d3,d5
		moveq	#2,d2
		bsr.s	stc_c
		or.l	d3,d5
		bra.s	stc_gl2
stc_gl1:	andi.w	#3,d5
		lsl.l	#8,d5
		lsl.l	#2,d5
		moveq	#10,d2
		bsr.s	stc_c
		or.l	d3,d5
stc_gl2:	addq.l	#1,d5
		rts

stc_playbase:	dc.l	0
stc_e:		dc.b	%00000100,%00001000,%00010000,%00100000,%01000000
		dc.b	%11111000,%11110000,%11100000,%11000000,%10000000
mt_erotus:	equ	28

mt_init:move.l	stc_playbase(pc),a0
	lea	$3b8(a0),a1
	moveq	#$7f,d0
	clr.l	d1
mt_loop:move.l	d1,d2
	subq.w	#1,d0
mt_lop2:move.b	(a1)+,d1
	cmp.b	d2,d1
	bgt.s	mt_loop
	dbf	d0,mt_lop2
	addq.b	#1,d2

	lea	mt_samplestarts(pc),a1
	asl.l	#8,d2
	asl.l	#2,d2
	add.l	a0,d2
	move.l	d2,a2
	lea	$43c(a2),a2
	moveq	#$1e,d0
mt_lop3:clr.l	(a2)
	move.l	a2,(a1)+
	moveq	#0,d1
	move.w	42(a0),d1
	asl.l	#1,d1
	add.l	d1,a2
	lea	$1e(a0),a0
	dbf	d0,mt_lop3

	or.b	#$2,$bfe001
	bra.s	mt_end2
mt_end:	move.w	#$f,$dff096
mt_end2:lea	$dff0a8,a0
	clr.w	(a0)
	clr.w	$10(a0)
	clr.w	$20(a0)
	clr.w	$30(a0)
	moveq	#0,d0
	rts

mt_music:
	movem.l	d0-d7/a0-a6,-(a7)
	move.l	stc_playbase(pc),a0
	lea	mt_counter(pc),a6
	addq.b	#$1,(a6)
	move.b	(a6),D0
	cmp.b	mt_speed(pc),d0
	blt	mt_nonew
	clr.b	(a6)
mt_getnew:
	lea	$c(a0),a3
	lea	$3b8(a0),a2
	lea	$43c(a0),a0
	clr.l	d0
	clr.l	d1
	move.b	mt_songpos(pc),d0
	move.b	(a2,d0.w),d1
	asl.l	#8,d1
	asl.l	#2,d1
	add.w	mt_pattpos(pc),d1
	lea	mt_dmacon(pc),a6
	clr.w	(a6)
	lea	$dff090,a5	;=$dff0a0-$10
	lea	mt_voice1(pc),a6
	bsr.s	mt_playvoice
	lea	mt_voice2(pc),a6
	bsr.s	mt_playvoice
	lea	mt_voice3(pc),a6
	bsr.s	mt_playvoice
	lea	mt_voice4(pc),a6
	bsr.s	mt_playvoice
	bra	mt_setdma

mt_playvoice:
	lea	$10(a5),a5
	move.l	(a0,d1.l),(a6)
	addq.l	#4,d1
	clr.l	d2
	move.b	$2(a6),d2
	and.b	#$f0,d2
	lsr.b	#4,d2
	move.b	(a6),d0
	and.b	#$f0,d0
	or.b	d0,d2
	beq.s	mt_setregs
	lea	mt_samplestarts(pc),a1
	move.l	d2,d4
	subq.l	#$1,d2
	asl.l	#2,d2
	mulu	#$1e,d4
	move.l	(a1,d2.l),$4(a6)
	move.w	(a3,d4.l),$8(a6)
	move.w	$2(a3,d4.l),$12(a6)
	clr.l	d3
	move.w	$4(a3,d4.l),d3
	beq.s	mt_noloop
	move.l	$4(a6),d2
	asl.w	#1,d3
	move.w	$4(a3,d4.l),d0
	add.w	$6(a3,d4.l),d0
	move.w	d0,8(a6)
	bra.s	mt_setregs0
mt_noloop:
	move.l	$4(a6),d2
mt_setregs0:
	add.l	d3,d2
	move.l	d2,$a(a6)
	move.w	$6(a3,d4.l),$e(a6)
	move.w	$12(a6),$8(a5)
mt_setregs:
	move.w	(a6),d0
	and.w	#$fff,d0
	beq.s	mt_checkcom2
	move.b	$2(a6),d0
	and.b	#$F,d0
	cmp.b	#$3,d0
	bne.s	mt_setperiod
	bsr	mt_setmyport
	bra.s	mt_checkcom2
mt_setperiod:
	move.w	(a6),$10(a6)
	and.w	#$fff,$10(a6)
	move.w	$14(a6),d0
	move.w	d0,$dff096
	clr.b	$1b(a6)
	move.l	$4(a6),(a5)
	move.w	$8(a6),$4(a5)
	move.w	$10(a6),d0
	and.w	#$fff,d0
	move.w	d0,$6(a5)
	move.w	$14(a6),d0
	lea	mt_dmacon(pc),a4
	or.w	d0,(a4)
mt_checkcom2:
	move.b	$2(a6),d0
	and.b	#$f,d0
	move.b	$3(a6),d5
	cmp.b	#$e,d0
	beq.s	mt_setfilt	;$e => SetFilter
	bgt.s	mt_setspeed	;$f => SetSpeed
	cmp.b	#$c,d0
	beq.s	mt_setvol	;$c => SetVolume
	bgt.s	mt_pattbreak	;$d => PatternBreak
	cmp.b	#$b,d0
	bne.s	mt_rts2		;$b => PositionJump
mt_posjmp:
	subq.b	#$1,d5
	lea	mt_songpos(pc),a4
	move.b	d5,(a4)
	lea	mt_break(pc),a4
	not.b	(a4)
	rts

mt_setfilt:
	and.b	#$1,d5
	asl.b	#$1,d5
	and.b	#$fd,$bfe001
	or.b	d5,$bfe001
	rts
mt_pattbreak:
	lea	mt_break(pc),a4
	not.b	(a4)
	rts
mt_setvol:
	cmp.b	#$40,d5
	ble.s	mt_vol4
	moveq	#$40,d5
mt_vol4:move.b	d5,$8(a5)
	rts
mt_setspeed:
	and.w	#$1f,d5
	beq.s	mt_rts2
	lea	mt_counter(pc),a4
	clr.b	(a4)
	lea	mt_speed(pc),a4
	move.b	d5,(a4)
mt_rts2:rts

mt_putstuff:
	move.l	$a(a6),(a5)+
	move.w	$e(a6),(a5)
	lea	-mt_erotus(a6),a6
	lea	-$14(a5),a5
	rts
mt_setdma:
	move.w	#$12c,d0
mt_wait:dbf	d0,mt_wait
	move.w	mt_dmacon(pc),d0
	or.w	#$8000,d0
	lea	$dff096,a5
	move.w	d0,(a5)
	move.w	#$12c,d0
mt_wai2:dbf	d0,mt_wai2
	lea	$dff0d0-$dff096(a5),a5
	lea	mt_voice4(pc),a6
	bsr.s	mt_putstuff
	bsr.s	mt_putstuff
	bsr.s	mt_putstuff
	bsr.s	mt_putstuff
	lea	mt_pattpos(pc),a6
	add.w	#$10,(a6)
	cmp.w	#$400,(a6)
	bne.s	mt_endr
mt_nex:	clr.w	(a6)
mt_nex2:lea	mt_break(pc),a6
	clr.b	(a6)
	lea	mt_songpos(pc),a6
	addq.b	#1,(a6)
	and.b	#$7f,(a6)
	move.b	(a6),d1
	move.l	stc_playbase(pc),a5
	cmp.b	$3b6(a5),d1
	bne.s	mt_endr
	clr.b	(a6)
mt_endr:move.b	mt_break(pc),d0
	bne.s	mt_nex2
	movem.l	(a7)+,d0-d7/a0-a6
	moveq	#0,d0
	rts

mt_setmyport:
	move.w	(a6),d2
	and.w	#$fff,d2
	move.w	d2,$18(a6)
	move.w	$10(a6),d0
	clr.b	$16(a6)
	cmp.w	d0,d2
	beq.s	mt_clrport
	bge.s	mt_rt
	move.b	#$1,$16(a6)
	rts
mt_clrport:
	clr.w	$18(a6)
mt_rt:	rts

mt_myport:
	tst.b	d0
	beq.s	mt_myslide
	move.b	d0,$17(a6)
	clr.b	$3(a6)
mt_myslide:
	tst.w	$18(a6)
	beq.s	mt_rt
	moveq	#0,d0
	move.b	$17(a6),d0
	tst.b	$16(a6)
	bne.s	mt_mysub
	add.w	d0,$10(a6)
	move.w	$18(a6),d0
	cmp.w	$10(a6),d0
	bgt.s	mt_myok
mt_my2:	move.w	$18(a6),$10(a6)
	clr.w	$18(a6)
mt_myok:move.w	$10(a6),$6(a5)
	rts
mt_mysub:
	sub.w	d0,$10(a6)
	move.w	$18(a6),d0
	cmp.w	$10(a6),d0
	blt.s	mt_myok
	bra.s	mt_my2

mt_vib:	tst.b	d0
	beq.s	mt_vi
	move.b	d0,$1a(a6)

mt_vi:	move.b	$1b(a6),d0
	lea	mt_sin(pc),a4
	lsr.w	#$2,d0
	and.w	#$1f,d0
	moveq	#0,d2
	move.b	(a4,d0.w),d2
	move.b	$1a(a6),d0
	and.w	#$f,d0
	mulu	d0,d2
	lsr.w	#$6,d2
	move.w	$10(a6),d0
	tst.b	$1b(a6)
	bmi.s	mt_vibmin
	add.w	d2,d0
	bra.s	mt_vib2
mt_vibmin:
	sub.w	d2,d0
mt_vib2:move.w	d0,$6(a5)
	move.b	$1a(a6),d0
	lsr.w	#$2,d0
	and.w	#$3c,d0
	add.b	d0,$1b(a6)
	rts

mt_nonew:
	lea	mt_voice1(pc),a6
	lea	$dff090,a5	;=$dff0a0-$10
	bsr.s	mt_checkcom
	lea	mt_voice2(pc),a6
	bsr.s	mt_checkcom
	lea	mt_voice3(pc),a6
	bsr.s	mt_checkcom
	lea	mt_voice4(pc),a6
	bsr.s	mt_checkcom
	bra	mt_endr
mt_checkcom:
	lea	$10(a5),a5
	move.w	$2(a6),d0
	and.w	#$fff,d0
	bne.s	mt_yop
	move.w	$10(a6),$6(a5)
	rts
mt_yop:	clr.l	d0
	move.b	$3(a6),d0
	move.b	$2(a6),d5
	and.b	#$f,d5
	beq	mt_arpeggio
	cmp.b	#$2,d5
	beq.s	mt_portdown	;$2 => PortamentoDown
	blt.s	mt_portup	;$1 => PortamentoUp
	cmp.b	#$4,d5
	beq	mt_vib		;$4 => Vibrato
	blt	mt_myport	;$3 => TonePortamento
	move.w	$10(a6),$6(a5)
	cmp.b	#$a,d5
	beq.s	mt_volslide
	rts

mt_volslide:
	lsr.b	#4,d0
	beq.s	mt_voldown
	add.w	d0,$12(a6)
	cmp.w	#$40,$12(a6)
	bmi.s	mt_vol2
	move.w	#$40,$12(a6)
	bra.s	mt_vol2

mt_voldown:
	move.b	$3(a6),d0
	and.b	#$f,d0
	sub.w	d0,$12(a6)
	bpl.s	mt_vol2
	clr.w	$12(a6)
mt_vol2:move.w	$12(a6),$8(a5)
	rts

mt_portup:
	sub.w	d0,$10(a6)
	move.w	$10(a6),d0
	and.w	#$fff,d0
	cmp.w	#$71,d0
	bpl.s	mt_por2
	and.w	#$f000,$10(a6)
	or.w	#$71,$10(a6)
	bra.s	mt_por2

mt_portdown:
	add.w	d0,$10(a6)
	move.w	$10(a6),d0
	and.w	#$fff,d0
	cmp.w	#$358,d0
	bmi.s	mt_por2
	and.w	#$f000,$10(a6)
	or.w	#$358,$10(a6)
mt_por2:move.w	$10(a6),d0
	and.w	#$fff,d0
	move.w	d0,$6(a5)
	rts

mt_arpeggio:
	clr.l	d5
	move.b	mt_counter(pc),d5
	divs	#$3,d5
	swap	d5
	cmp.w	#1,d5
	blt.s	mt_arp2		
	bgt.s	mt_arp1		
	lsr.b	#4,d0		
	bra.s	mt_arp3
mt_arp1:and.b	#$f,d0
mt_arp3:asl.w	#1,d0
	move.w	$10(a6),d5
	lea	mt_periods(pc),a0
	moveq	#$24,d7		
mt_arploop:
	move.w	(a0,d0.w),d2
	cmp.w	(a0)+,d5
	bge.s	mt_arp4
	dbf	d7,mt_arploop
mt_arp4:move.w	d2,$6(a5)
	rts
mt_arp2:move.w	$10(a6),d2
	bra.s	mt_arp4

mt_sin:
	dc.b $00,$18,$31,$4a,$61,$78,$8d,$a1,$b4,$c5,$d4,$e0,$eb,$f4,$fa,$fd
	dc.b $ff,$fd,$fa,$f4,$eb,$e0,$d4,$c5,$b4,$a1,$8d,$78,$61,$4a,$31,$18

mt_periods:
	dc.w $0358,$0328,$02fa,$02d0,$02a6,$0280,$025c,$023a,$021a,$01fc,$01e0
	dc.w $01c5,$01ac,$0194,$017d,$0168,$0153,$0140,$012e,$011d,$010d,$00fe
	dc.w $00f0,$00e2,$00d6,$00ca,$00be,$00b4,$00aa,$00a0,$0097,$008f,$0087
	dc.w $007f,$0078,$0071,$0000,$0000

mt_speed:	dc.b	$6
mt_songpos:	dc.b	$0
mt_pattpos:	dc.w	$0
mt_counter:	dc.b	$0

mt_break:	dc.b	$0
mt_dmacon:	dc.w	$0
mt_samplestarts:dc.l	0,0,0,0,0,0,0,0
		dc.l	0,0,0,0,0,0,0,0
		dc.l	0,0,0,0,0,0,0,0
		dc.l	0,0,0,0,0,0,0
mt_voice1:	dc.w	0,0,0,0,0,0,0,0,0,0
		dc.w	$1
		dc.w	0,0,0
mt_voice2:	dc.w	0,0,0,0,0,0,0,0,0,0
		dc.w	$2
		dc.w	0,0,0
mt_voice3:	dc.w	0,0,0,0,0,0,0,0,0,0
		dc.w	$4
		dc.w	0,0,0
mt_voice4:	dc.w	0,0,0,0,0,0,0,0,0,0
		dc.w	$8
		dc.w	0,0,0
