;---------------T

DEBUG	equ	0

	incdir	includes:
	include	misc/AYPlayer.i
	include	misc/mine.i
	incdir	''

	ifne	DEBUG

	lea	song(pc),a0
	bsr.w	initsound
	bsr.w	interrupt
	rts

song	dc.b	0,1,2,3
	dc.w	0
	dc.b	0;,0
	incbin	dh2:deliay/tmp/soundtrackersongs.003
	endc

* ST11 (SoundTracker 1.1) AY Player, (C) 1995 Patrik Rak - Raxoft

* 1 Initial version

	STRUCTURE	STRC_Song,0
	UBYTE	ams_assignA	;0-3 specifies, what amiga channel will be
	UBYTE	ams_assignB	;assigned to each ay channel (A-C, noise)
	UBYTE	ams_assignC
	UBYTE	ams_assignN
	WORD	ams_fadeoffset	;precise fade specification
	UWORD	ams_fadelen	;how long to fade (not supported by DT so far)
				;set to zero for neverending song
	;and so on...

; The Player itself.

dd
	AYPLAYERHEADER	ST11
	dc.b	12+1		;custom ayfreq transpose
	ifeq	DEBUG
AYbase	ds.l	1		;where ay registers should be "outed"
	else
AYbase	dc.l	ay		;where ay registers should be "outed"
	endc
	ifeq	DEBUG
AYass	ds.l	1		;where ay channel assignment should be copied
	else
AYass	dc.l	ay
	endc
AYfreq	ds.l	1		;from where we take AY frequencies
	dc.w	0		;initplayer
	dc.w	0		;endplayer
	dc.w	initsound-*
	dc.w	0		;endsound
	dc.w	interrupt-*
	dc.w	nextpatt-*
	dc.w	prevpatt-*
	dc.b	'SoundTracker (Polish) 1.0',0
	dc.b	'(C) 19?? ?',0
	dc.b	'(C) 1995 Patrik Rak - Raxoft',0
	even

initsound	moveq	#0,d1			;clear variables
	lea	vars,a1
	moveq	#(data-vars)/2-1,d0
.fill	move.w	d1,(a1)+
	dbra	d0,.fill

	move.l	AYass(pc),a2		;feed PlayAY
	move.l	(a0)+,(a2)		;with channel assignement

	move.w	(a0)+,d2		;gate fadeoffset

	move.w	(a0)+,songfade-data(a1)	;store fadelen

	move.l	a0,(a1)+	;data

	move.w	#$0101,(a1)+	;curdelay & curpattlen

	addq.l	#4,a1

	move.b	#1,(a1)+
	move.b	(patcount,a0),d4
	addq.b	#1,d4
	move.b	d4,(a1)+

	moveq	#0,d0
	move.b	(delay,a0),d0			;delay
	moveq	#0,d3
	move.b	(pattlen,a0),d3
	mulu	d0,d3			;pattlen in VBIs...

	move.w	d3,(a1)+	;vbipattlen
	move.w	d2,(a1)+	;fadeofset

.count	mulu	d3,d4
	add	d2,d4
	move.w	d4,(a1)		;songlen
	rts

	rts


nextpatt	lea	currpatcount,a6
	moveq	#1,d0
	cmp.b	(a6),d0
	bne.b	dopatterns
	rts

prevpatt	lea	currpatcount,a6
	move.w	(a6),d0
	cmp.b	(a6),d0
	beq.b	return
	addq.b	#2,(a6)
	subq.l	#4,position-currpatcount(a6)
dopatterns	move.w	#$101,curdelay-currpatcount(a6)
	tst.l	songlen-currpatcount(a6)
	beq.b	return
	move.b	(a6),d0
	subq.b	#1,d0
	addq.l	#2,a6
	mulu	(a6)+,d0
	add	(a6)+,d0
	move	d0,(a6)
return	rts

interrupt	lea	ay,a6	;base
	lea	data-ay(a6),a0
	move.l	(a0)+,a5	;data
	moveq	#0,d6		;use d6 as obsl1 in original
	subq.b	#1,(a0)
	bne.b	.samenote
	moveq	#-1,d6		;signal new tones
	move.b	delay-xy(a5),(a0)+
	subq.b	#1,(a0)
	bne.b	.samenote
	move.b	pattlen-xy(a5),(a0)+
	move.l	(a0)+,a1
	subq.b	#1,(a0)+
	bne.b	.notend
	move.b	(a0),-(a0)
	lea	patpointers-xy(a5),a1
.notend	moveq	#0,d0
	move.b	(a1)+,d0
	mulu	#3*192,d0
	lea	(patterns-3*192-xy,a5),a0
	add.l	d0,a0
	move.l	a0,ch1-ay(a6)
	addq.l	#3,a0
	move.l	a0,ch2-ay(a6)
	addq.l	#3,a0
	move.l	a0,ch3-ay(a6)
	move.b	(a1)+,transpose+1-ay(a6)
	move.l	a1,position-ay(a6)
.samenote	lea	ch1-ay(a6),a2
	move.l	a6,a3			;lea	freqa-ay(a6),a3
	lea	vola-ay(a6),a4
	moveq	#0,d5
	st	strobe-ay(a6)	;all off
.loop	bsr.b	obsluha
	lea	chlen(a2),a2
	addq.l	#2,a3
	addq.l	#1,a4
	addq.b	#1,d5
	cmp.b	#3,d5
	bne.b	.loop
	move.l	AYbase(pc),a1
	moveq	#11-1,d0
.outy	move.b	(a6)+,(a1)+
	dbra	d0,.outy
	move.b	(a6)+,d0
	beq.b	.done
	move.b	(a6)+,(a1)+
	move.b	(a6),(a1)+
	move.b	d0,(a1)
.done	lea	songlen-volc-1(a4),a0
	moveq	#0,d0
	tst.w	(a0)
	beq.b	.exit
	subq.w	#1,(a0)+
	bne.b	.exit
	move.w	(a0),d0
.exit	rts

;a2 channel, a3 freq, a4 volume, d5 how much rotate strobe
;a5 data, a6 ay

obsluha	tst	d6		;new tones?
	beq.b	.same
	bsr.w	newtone
	add.l	#3*3,(a2)		;step to next tone
	bra.b	.cont
.same	bsr.w	sametone
.cont	moveq	#0,d2
	move.b	smp(a2),d2	;sample number
	beq.w	.envel0

	moveq	#0,d3
	move.b	(pos,a2),d3
	subq	#1,d2
	mulu	#130,d2
	move.l	a5,a0		;lea	(samples,a5),a0
	add	d2,a0
	move.l	a0,d2
	lea	(64,a0),a0
	add	d3,a0
	add	d3,a0

.cont2	move.w	(a0),d4
	ror.w	#8,d4
	bclr	#4+8,d4
	bne.b	.noneg
	neg	d4
.noneg	add.w	d4,d4
	add.w	d4,d4
	add.w	d4,d4


	moveq	#0,d0
	move.b	orn(a2),d0
	lsl	#5,d0
	add	d3,d0
	lea	(ornaments,a5),a0
	add	d0,a0

	move.w	transpose-ay(a6),d0
	add.b	(a0),d0
	add.b	tone(a2),d0
	add.w	d0,d0
	move.l	AYfreq(pc),a0
	add.w	d0,a0
	add.w	(a0),d4
	move.w	d4,(a3)		;freq

	move.l	d2,a0
	add	d3,a0
	move.b	(a0),d4
	beq.b	.envel0
	lea	(32,a0),a0
	move.b	(a0),d3
	move.b	d3,d2
	moveq	#-2,d0		;strobe for tone on
	add.b	d2,d2		;noise off?
	bcs.b	.nonoise
	moveq	#-10,d0		;strobe for tone and noise on
	and.b	#31,d3
	move.b	d3,noise-ay(a6)	;noise
.nonoise	add.b	d2,d2
	bcc.b	.toneon
	addq.b	#1,d0		;turn the tone off
.toneon	rol.b	d5,d0
	and.b	d0,strobe-ay(a6)
	and.b	#16,(a4)	;keep just previous env on flag!!!
	or.b	d4,(a4)		;vol
.envel0	rts

octtab	dc.b	9,11,0,2,4,5,7
	even

newtone	move.l	(a2),a0
	moveq	#0,d0
	move.b	(a0)+,d0
	move	#$f0,d1
	and	d0,d1
	beq.b	sametone
	cmp	#$f0,d1
	beq.b	silentqm
	lsr	#4,d1
	move.b	(octtab-1,pc,d1),d1
	btst	#3,d0
	beq.b	.nois
	addq	#1,d1
.nois	and	#7,d0
	mulu	#12,d0
	add	d1,d0
	move.b	d0,(tone,a2)
	move.b	(a0)+,d0
	move.b	(a0)+,d2
	
	moveq	#15,d1
	and.b	d0,d1
	lea	smpmem(a2),a0
	lsr.b	#4,d0
	bne.b	.newsmpl
	move.b	(a0),d0
.newsmpl	move.b	d0,(a0)+
	move.b	d0,(a0)+
	clr.b	(a0)+
	move.b	#32,(a0)+
	mulu	#130,d0		;samply jsou cislovany od 1
	move.w	(-2,a5,d0),(a0)	;takze tohle skace na zac. dalsiho

	moveq	#%01111101,d0
	btst	d1,d0
	bne.b	.exit
	clr.b	orn(a2)
	clr.b	(a4)
	cmp.b	#1,d1
	beq.b	.exit
	cmp.b	#15,d1
	bne.b	.env
	and	d1,d2
	move.b	d2,orn(a2)
	rts

.env	move.b	#16,(a4)
	move.b	d1,envtype-ay(a6)
	move.b	d2,envfreq-ay(a6)	;fill only lower byte
.exit	rts

silentqm	clr.b	smpmem(a2)
silent	clr.b	smp(a2)
	clr.b	(a4)
	;rts

sametone	addq.b	#1,pos(a2)
	and.b	#31,pos(a2)
	subq.b	#1,len(a2)
	bne.b	.exit
	move.b	rpos(a2),d0
	beq.b	silent
	subq.b	#1,d0
	move.b	d0,pos(a2)
	move.b	rlen(a2),len(a2)
	addq.b	#1,len(a2)
.exit	rts

	section	variables,bss
vars
ay
freqa	ds.w	1
freqb	ds.w	1
freqc	ds.w	1
noise	ds.b	1
strobe	ds.b	1
vola	ds.b	1
volb	ds.b	1
volc	ds.b	1
envtype	ds.b	1		;note that these two
envfreq	ds.w	1		;lines are swapped!!!

	rsreset
strm	rs.l	1		;Position in pattern stream
tone	rs.b	1		;Current tone
orn	rs.b	1		;Ornament number (tone slides)
smpmem	rs.b	1		;sample nr (same as smp, but this remains intact)
smp	rs.b	1		;Current sample nr (freq slides, env & noise)
pos	rs.b	1		;Position in sample/ornament
len	rs.b	1		;Sample/orn length remaining to loop test
rpos	rs.b	1		;If, then where start repeating sample/orn
rlen	rs.b	1		;What len use when looping
chlen	rs.b	0

ch1	ds.b	chlen
ch2	ds.b	chlen
ch3	ds.b	chlen

data	ds.l	1		;song data

curdelay	ds.b	1
curpattlen	ds.b	1
position	ds.l	1
currpatcount	ds.b	1
patcountpl1	ds.b	1
vbipattlen	ds.w	1
fadeoffset	ds.w	1
songlen	ds.w	1
songfade	ds.w	1
transpose	ds.w	1
varsend
varslen	equ	*-vars

	rsreset
xy	rs.b	0
samples	rs.b	15*(32*2+32+32+1+1)
patpointers	rs.b	256*(1+1)
patcount	rs.b	1
ornaments	rs.b	16*32
unknown	rs.b	32	;(ornaments off?)
delay	rs.b	1
pattlen	rs.b	1
patterns	rs.b	3*(64*(1+1+1));*x

