; $VER: Future13.library 2.11
;

	INCDIR	"Includes3.0:Include3.0/"
	INCLUDE	"Exec/Types.i"
	INCLUDE	"Own/SystemBases.i"
	INCLUDE	"Own/SystemStructures.i"
	INCLUDE	"Own/SystemOffsets.i"
	INCLUDE	"Own/AccessiblePlayer.i"


VERSION		=	2
REVISION	=	11

TRUE		=	-1
FALSE		=	0

; Library Data

LN_Name		=	10
LN_Type		=	8
NT_Library	=	9

LIBB_Summing	=	0
LIBB_Changed	=	1
LIBB_SumUsed	=	2
LIBB_DelExp	=	3

LIBF_Summing	=	1<<LIBB_Summing
LIBF_Changed	=	1<<LIBB_Changed
LIBF_SumUsed	=	1<<LIBB_SumUsed
LIBF_DelExp	=	1<<LIBB_DelExp

; Macros

INBYTE	MACRO
	dc.b	%11100000,0
	dc.w	\1
	dc.b	\2,0
	ENDM

INWORD	MACRO
	dc.b	%11010000,0
	dc.w	\1,\2
	ENDM

INLONG	MACRO
	dc.b	%11000000,0
	dc.w	\1
	dc.l	\2
	ENDM

; Library Base Structure

	STRUCTURE LibraryStruct,0
	STRUCT	LIB_Node,14
	UBYTE	LIB_Flags
	UBYTE	LIB_Pad
	UWORD	LIB_NegSize
	UWORD	LIB_PosSize
	UWORD	LIB_Version
	UWORD	LIB_Revision
	APTR	LIB_IDString
	ULONG	LIB_Sum
	UWORD	LIB_OpenCnt

	LONG	LIB_SegList
	LABEL	LibraryStruct_SIZEOF


	SECTION	Future13.library,CODE

START	moveq	#0,d0
	rts
;------------------------------------------------------------------------------
LIBNAME	dc.b	"apFuture13.library",0

LIBID	dc.b	"Future13.library 2.11 (13-November-1994)",0
	even
;------------------------------------------------------------------------------
; ROMTAG Structure
;

ROMTAG	dc.w	$4afc			;ROMTAG Indentifier
	dc.l	romtag
	dc.l	slut
	dc.b	$80			;Flags
	dc.b	version
	dc.b	$09			;Type Of Module
	dc.b	$00			;Initialization Priority
	dc.l	libname
	dc.l	libid
	dc.l	autinit			;Pointer To AUTOINIT Table
;------------------------------------------------------------------------------
; AUTOINIT Table
;

AUTINIT	dc.l	LibraryStruct_SIZEOF	;Size Of Structure AFTER Base Address
	dc.l	vector			;Pointer To Vector Table
	dc.l	inittab			;Pointer To Init Structure
	dc.l	init			;Pointer To Init Routine
;------------------------------------------------------------------------------
; Init Table
;

INITTAB	INBYTE	LN_Type,NT_Library
	INBYTE	LIB_Flags,LIBF_SumUsed!LIBF_Changed
	INWORD	LIB_Version,version
	INWORD	LIB_Revision,revision
	INLONG	LN_Name,libname
	INLONG	LIB_IDString,libid
	dc.l	0
;------------------------------------------------------------------------------
; Vector Table
;

VECTOR	dc.w	-1
	dc.w	opnlib-vector,clslib-vector,expunge-vector,extfunc-vector
	dc.w	FC_GetTags-vector
	dc.w	-1
;------------------------------------------------------------------------------
; Init Routine
;

INIT	movem.l	d1-d7/a0-a6,-(sp)
	move.l	d0,a4			;Base Address
	move.l	a0,LIB_SegList(a4)

	move.l	a4,d0
	movem.l	(sp)+,d1-d7/a0-a6
	rts
;------------------------------------------------------------------------------
; Offset  -6: Open Library
;

OPNLIB	addq.w	#1,LIB_OpenCnt(a6)
	bclr	#LIBB_DelExp,LIB_Flags(a6)
	move.l	a6,d0
	rts
;------------------------------------------------------------------------------
; Offset -12: Close Library
;

CLSLIB	moveq	#0,d0
	subq.w	#1,LIB_OpenCnt(a6)
	bne.b	clslibo
	btst	#LIBB_DelExp,LIB_Flags(a6)
	bne.b	expunge
CLSLIBO	rts
;------------------------------------------------------------------------------
; Offset -18: Expunge
;

EXPUNGE	movem.l	d1-d7/a0-a6,-(sp)
	move.l	a6,a4
	tst.w	LIB_OpenCnt(a4)
	beq.b	exp1
	bset	#LIBB_DelExp,LIB_Flags(a4)
	moveq	#0,d0
	bra.b	expungo

EXP1	move.l	4.w,a6
	move.l	LIB_SegList(a4),d2
	move.l	a4,a1
	jsr	Remove(a6)

	move.l	a4,a1
	moveq	#0,d0
	move.w	LIB_NegSize(a4),d0
	sub.l	d0,a1
	add.w	LIB_PosSize(a4),d0
	jsr	FreeMem(a6)
	move.l	d2,d0

EXPUNGO	movem.l	(sp)+,d1-d7/a0-a6
	rts
;------------------------------------------------------------------------------
; Offset -24: ExtFunc
;

EXTFUNC	moveq	#0,d0
	rts
;------------------------------------------------------------------------------
;******************************************************************************
;* Future Composer 1.0-1.3 Player
;******************************************************************************
;------------------------------------------------------------------------------
	STRUCTURE Future13Struct,0
	APTR	F13_Global
	APTR	F13_SEQPoint
	APTR	F13_PATPoint
	APTR	F13_FRQPoint
	APTR	F13_VOLPoint
	UWORD	F13_OnOff
	UWORD	F13_ActChan
	WORD	F13_ReSpCnt
	WORD	F13_RepSpd
	WORD	F13_SpdTemp
	UWORD	F13_AudTemp
	STRUCT	F13_PerVol,16
	STRUCT	F13_V1Data,64
	STRUCT	F13_Offset1,2
	STRUCT	F13_SSize1,2
	STRUCT	F13_Start1,6
	STRUCT	F13_V2Data,64
	STRUCT	F13_Offset2,2
	STRUCT	F13_SSize2,2
	STRUCT	F13_Start2,6
	STRUCT	F13_V3Data,64
	STRUCT	F13_Offset3,2
	STRUCT	F13_SSize3,2
	STRUCT	F13_Start3,6
	STRUCT	F13_V4Data,64
	STRUCT	F13_Offset4,2
	STRUCT	F13_SSize4,2
	STRUCT	F13_Start4,6
	STRUCT	F13_SoundInfo,10*10+47*10
	LABEL	Future13Struct_SIZEOF
;------------------------------------------------------------------------------
; Offset -30: GetTags
;
; IN :	Nothing
;
; OUT:	A0 = Pointer To A TagList
;

FC_GetTags
	lea	FC_Tags(pc),a0
	rts

FC_Tags	dc.l	APT_RequestVersion,2
	dc.l	APT_EarlyCheck,FC_TestModule

	dc.l	APT_InitPlayer,FC_InitPlayer
	dc.l	APT_EndPlayer,FC_EndPlayer
	dc.l	APT_InitSound,FC_InitSound
	dc.l	APT_EndSound,FC_EndSound
	dc.l	APT_Interrupt,FC_PlayModule

	dc.l	APT_PlayerName,fcname
	dc.l	APT_Description,fcdes

	dc.l	APT_Volume,TRUE
	dc.l	APT_Pause,TRUE

	dc.l	APT_GetSongLength,FC_GetSongLength

	dc.l	APT_GetSongPos,FC_GetSongPos
	dc.l	APT_Rewind,FC_Rewind
	dc.l	APT_Forward,FC_Forward
	dc.l	APT_ChangeChannel,FC_ChangeChannel
	dc.l	TAG_END

FCNAME	dc.b	"Future Composer 1.0-1.3",0
FCDES	dc.b	"Original player by SuperSero.",10
	dc.b	"Adapted by Tax.",10,10
	dc.b	"This player can play all modules",10
	dc.b	"made with Future Composer 1.0 to",10
	dc.b	"1.3.",0
	even
;------------------------------------------------------------------------------
; TestModule
;
; IN :	Nothing
;
; OUT:	D0 = Success (0=Unknown, 1=Ok, 2=Error)
;

FC_TestModule
	movem.l	d1-d2/a0/a4-a5,-(sp)

	subq.l	#4,sp
	moveq	#0,d1
	moveq	#4,d2
	move.l	sp,a0
	move.l	APG_CheckLoad(a5),a4
	jsr	(a4)			;Load One Longword
	move.l	(sp)+,d1
	tst.l	d0
	beq.b	.tsmod1

	moveq	#1,d0			;Ok
	cmp.l	#"SMOD",d1
	beq.b	.tsmodo
	moveq	#0,d0			;Unknown
	bra.b	.tsmodo

.TSMOD1	moveq	#2,d0			;Error
.TSMODO	movem.l	(sp)+,d1-d2/a0/a4-a5
	rts
;------------------------------------------------------------------------------
; InitPlayer
;
; IN :	A1 = Address
;
; OUT:	D1 = Success (0=Error)
;

FC_InitPlayer
	movem.l	d0/a0,-(sp)
	move.l	APG_AllocChannels(a5),a0
	jsr	(a0)
	move.l	d0,d1
	movem.l	(sp)+,d0/a0
	rts
;------------------------------------------------------------------------------
; EndPlayer
;
; IN :	A1 = Address
;
; OUT:	Nothing
;

FC_EndPlayer
	move.l	a0,-(sp)
	move.l	APG_FreeChannels(a5),a0
	jsr	(a0)
	move.l	(sp)+,a0
	rts
;------------------------------------------------------------------------------
; InitSound
;
; IN :	A1 = Address
;
; OUT:	Nothing
;

FC_InitSound
	movem.l	d0-d3/d6-d7/a0-a6,-(sp)

	lea	FC_DataArea,a5
	move.w	#1,F13_OnOff(a5)
	bset	#1,$bfe001		;Turn Filter Off

	lea	100(a1),a0
	move.l	a0,F13_SEQPoint(a5)
	move.l	a1,a0
	add.l	8(a1),a0
	move.l	a0,F13_PATPoint(a5)
	move.l	a1,a0
	add.l	16(a1),a0
	move.l	a0,F13_FRQPoint(a5)
	move.l	a1,a0
	add.l	24(a1),a0
	move.l	a0,F13_VOLPoint(a5)
	move.l	4(a1),d0
	divu	#13,d0

	lea	F13_SoundInfo(a5),a2
	moveq	#1,d2
	moveq	#10-1,d1
.INIMO1	clr.l	(a2)
	addq.l	#6,a2
	move.l	d2,(a2)+
	dbra	d1,.inimo1

	moveq	#0,d2
	moveq	#$10,d3
	moveq	#$08,d7
	moveq	#32-1,d1
.INIMO2	move.l	d2,(a2)+
	move.w	d3,(a2)+
	move.l	d3,(a2)+
	add.l	#$20,d2
	dbra	d1,.inimo2

	moveq	#8-1,d1
.INIMO3	move.l	d2,(a2)+
	move.w	d7,(a2)+
	move.l	d7,(a2)+
	add.l	#$10,d2
	dbra	d1,.inimo3

	move.l	d2,(a2)+
	move.w	d3,(a2)+
	move.l	d3,(a2)+
	add.l	#$20,d2
	move.l	d2,(a2)+
	move.w	d7,(a2)+
	move.l	d7,(a2)+
	add.l	#$10,d2
	REPT	2
	move.l	d2,(a2)+
	move.w	d3,(a2)+
	move.l	d3,(a2)+
	add.l	#$20,d2
	ENDR
	REPT	2
	move.l	d2,(a2)+
	move.w	d7,(a2)+
	move.l	d7,(a2)+
	add.l	#$10,d2
	ENDR
	move.l	d2,(a2)+
	move.w	#$18,(a2)+
	move.l	#$18,(a2)

	lea	40(a1),a0
	lea	F13_SoundInfo+4(a5),a2
	moveq	#10-1,d1
.INIMO4	move.w	(a0)+,(a2)+
	move.l	(a0)+,(a2)+
	addq.l	#4,a2
	dbra	d1,.inimo4

	moveq	#0,d2
	move.l	a1,d1
	add.l	32(a1),d1
	sub.l	#WAVEFORMS,d1
	lea	F13_SoundInfo(a5),a0
	move.l	d1,(a0)+
	moveq	#9-1,d3
.INIMO5	move.w	(a0),d2
	add.l	d2,d1
	add.l	d2,d1
	addq.l	#6,a0
	move.l	d1,(a0)+
	dbra	d3,.inimo5

	move.l	F13_SEQpoint(a5),a0
	moveq	#0,d2
	move.b	12(a0),d2		;Get replay speed
	bne.b	.inimo6
	moveq	#3,d2			;Set default speed

.INIMO6	move.w d2,F13_ReSpCnt(a5)	;Init repspeed counter
	move.w d2,F13_RepSpd(a5)

	clr.w	F13_AudTemp(a5)
	clr.w	F13_SpdTemp(a5)
	move.w	#$000f,$dff096		;Disable audio DMA
	move.w	#$0780,$dff09a		;Disable audio IRQ
	moveq	#0,d7
	mulu	#13,d0

	lea	F13_V1data(a5),a0	;Point to 1st voice data area
	lea	SILENT(pc),a1
	lea	o4a0c8(pc),a2
	moveq	#4-1,d6			;Number of soundchannels-1
.INIMO7	move.l	a1,10(a0)
	move.l	a1,18(a0)
	clr.l	14(a0)
	clr.b	45(a0)
	clr.b	47(a0)
	clr.w	8(a0)
	clr.l	48(a0)
	move.b	#$01,23(a0)
	move.b	#$01,24(a0)
	clr.b	25(a0)
	clr.l	26(a0)
	clr.w	30(a0)
	moveq	#$00,d3
	move.w	(a2)+,d1
	move.w	(a2)+,d3
	divu	#$0003,d3
	move.b	d3,32(a0)
	mulu	#$0003,d3
	and.l	#$00ff,d3
	and.l	#$00ff,d1
	add.l	#$dff0a0,d1
	move.l	d1,a6
	move.l	#$0000,(a6)
	move.w	#$0100,4(a6)
	move.w	#$0000,6(a6)
	move.w	#$0000,8(a6)
	move.l	d1,60(a0)
	clr.w	64(a0)
	move.l	F13_SEQPoint(a5),(a0)
	move.l	F13_SEQPoint(a5),52(a0)
	add.l	d0,52(a0)
	add.l	d3,52(a0)
	add.l	d7,(a0)
	add.l	d3,(a0)
	move.w	#$000d,6(a0)
	move.l	(a0),a3
	move.b	(a3),d1
	andi.l	#$00ff,d1
	lsl.w	#6,d1
	move.l	F13_PATPoint(a5),a4
	adda.l	d1,a4
	move.l	a4,34(a0)
	clr.l	38(a0)
	move.b	#$01,33(a0)
	move.b	#$02,42(a0)
	move.b	1(a3),44(a0)
	move.b	2(a3),22(a0)
	clr.b	43(a0)
	clr.b	45(a0)
	clr.w	56(a0)
	adda.w	#$004a,a0		;Point to next voice's data area
	dbra	d6,.inimo7

	movem.l	(sp)+,d0-d3/d6-d7/a0-a6
	rts
;------------------------------------------------------------------------------
; EndSound
;
; IN :	A1 = Address
;
; OUT:	Nothing
;

FC_EndSound
	move.l	d0,-(sp)
	clr.w	FC_DataArea+F13_OnOff
	moveq	#0,d0
	move.w	d0,$dff0a8
	move.w	d0,$dff0b8
	move.w	d0,$dff0c8
	move.w	d0,$dff0d8
	move.w	#$000f,$dff096
	move.l	(sp)+,d0
	rts
;------------------------------------------------------------------------------
; GetSongLength
;
; IN :	A1 = Address
;
; OUT:	D1 = Length
;

FC_GetSongLength
	move.l	4(a1),d1
	divu	#13,d1			;Song Length
	rts
;------------------------------------------------------------------------------
; GetSongPos
;
; IN :	A1 = Address
;
; OUT:	D1 = Position (0-x)
;

FC_GetSongPos
	move.l	a0,-(sp)
	lea	FC_DataArea+F13_V1Data,a0
	moveq	#0,d1
	move.w	6(a0),d1
	divu	#13,d1
	subq.w	#1,d1
	move.l	(sp)+,a0
	rts
;------------------------------------------------------------------------------
; Rewind
;
; IN :	A1 = Address
;
; OUT:	D1 = New Position
;

FC_Rewind
	movem.l	d0/d2/a0-a1,-(sp)

	bsr.b	FC_GetSongPos
	tst.w	d1
	bmi.b	fforwao
	beq.b	fforwao
	subq.w	#1,d1
	bra.b	fforwa1
;------------------------------------------------------------------------------
; Forward
;
; IN :	A1 = Address
;
; OUT:	D1 = New Position
;

FC_Forward
	movem.l	d0/d2/a0-a1,-(sp)

	bsr.b	FC_GetSongLength
	move.w	d1,d0

	bsr.b	FC_GetSongPos
	addq.w	#1,d1
	cmp.w	d0,d1
	blt.b	fforwa1
	moveq	#0,d1

FFORWA1	move.w	d1,d2
	mulu	#13,d2
	moveq	#64,d0
	lea	FC_DataArea,a0

	lea	F13_V1Data(a0),a1
	move.w	d0,40(a1)		;Reset Pattern Pos
	move.w	d2,6(a1)		;Set Song Position
	lea	F13_V2Data(a0),a1
	move.w	d0,40(a1)		;Reset Pattern Pos
	move.w	d2,6(a1)		;Set Song Position
	lea	F13_V3Data(a0),a1
	move.w	d0,40(a1)		;Reset Pattern Pos
	move.w	d2,6(a1)		;Set Song Position
	lea	F13_V4Data(a0),a1
	move.w	d0,40(a1)		;Reset Pattern Pos
	move.w	d2,6(a1)		;Set Song Position

FFORWAO	movem.l	(sp)+,d0/d2/a0-a1
	rts
;------------------------------------------------------------------------------
; ChangeChannel
;
; IN :	A1 = Address
;	D1 = Channel (0-3)
;	D2 = State (0=Off 1=On)
;
; OUT:	Nothing
;

FC_ChangeChannel
	movem.l	d0-d4/a0,-(sp)

	moveq	#0,d3
	moveq	#-1,d4
	bclr	d1,d4
	tst.b	d2
	beq.b	.chgch1
	bset	d1,d3

.CHGCH1	lea	FC_DataArea,a0
	move.w	F13_ActChan(a0),d0
	and.w	d4,d0
	or.w	d3,d0
	move.w	d0,F13_ActChan(a0)

	movem.l	(sp)+,d0-d4/a0
	rts
;------------------------------------------------------------------------------
SILENT	dc.w	$0100,$0000,$0000,$00e1
o4a0c8	dc.l	$00000000,$00100003,$00200006,$00300009
PERIODS	dc.w	$06b0,$0650,$05f4,$05a0,$054c,$0500,$04b8,$0474
	dc.w	$0434,$03f8,$03c0,$038a,$0358,$0328,$02fa,$02d0
	dc.w	$02a6,$0280,$025c,$023a,$021a,$01fc,$01e0,$01c5
	dc.w	$01ac,$0194,$017d,$0168,$0153,$0140,$012e,$011d
	dc.w	$010d,$00fe,$00f0,$00e2,$00d6,$00ca,$00be,$00b4
	dc.w	$00aa,$00a0,$0097,$008f,$0087,$007f,$0078,$0071
	dc.w	$0071,$0071,$0071,$0071,$0071,$0071,$0071,$0071
	dc.w	$0071,$0071,$0071,$0071,$0d60,$0ca0,$0be8,$0b40
	dc.w	$0a98,$0a00,$0970,$08e8,$0868,$07f0,$0780,$0714
	dc.w	$1ac0,$1940,$17d0,$1680,$1530,$1400,$12e0,$11d0
	dc.w	$10d0,$0fe0,$0f00,$0e28
;------------------------------------------------------------------------------
	SECTION	PlayRoutine,CODE_C

; PlayModule
;
; IN :	A1 = Address
;	D1 = VBlank/Cia (0=CIA)
;
; OUT:	Nothing
;

FC_PlayModule
	movem.l	d0-d7/a0-a6,-(sp)
	lea	FC_DataArea,a4
	move.l	a5,F13_Global(a4)
	bsr.b	play
	movem.l	(sp)+,d0-d7/a0-a6
	rts

PLAY	lea	F13_PerVol(a4),a6
	tst.w	F13_OnOff(a4)
	bne.b	music_on
	rts

music_on
	subq.w	#1,F13_ReSpCnt(a4)	;Decrease replayspeed counter
	bne.b	nonewnote
	move.w	F13_RepSpd(a4),F13_ReSpCnt(a4);Restore replayspeed counter
	lea	F13_V1Data(a4),a0	;Point to voice1 data area
	bsr.w	new_note
	lea	F13_V2Data(a4),a0	;Point to voice2 data area
	bsr.w	new_note
	lea	F13_V3Data(a4),a0	;Point to voice3 data area
	bsr.w	new_note
	lea	F13_V4Data(a4),a0	;Point to voice4 data area
	bsr.w	new_note

nonewnote
	clr.w	F13_AudTemp(a4)
	lea	F13_V1Data(a4),a0
	bsr.w	effects
	move.w	d0,(a6)+
	move.w	d1,(a6)+
	lea	F13_V2Data(a4),a0
	bsr.w	effects
	move.w	d0,(a6)+
	move.w	d1,(a6)+
	lea	F13_V3Data(a4),a0
	bsr.w	effects
	move.w	d0,(a6)+
	move.w	d1,(a6)+
	lea	F13_V4Data(a4),a0
	bsr.w	effects
	move.w	d0,(a6)+
	move.w	d1,(a6)+
	lea	F13_PerVol(a4),a6
	move.w	F13_AudTemp(a4),d0
	and.w	F13_ActChan(a4),d0
	ori.w	#$8000,d0		;Set/clr bit = 1
	move.w	d0,-(a7)
	moveq	#0,d1
	move.l	F13_Start1(a4),d2	;Get samplepointers
	move.w	F13_Offset1(a4),d1	;Get offset
	add.l	d1,d2			;Add offset
	move.l	F13_Start2(a4),d3
	move.w	F13_Offset2(a4),d1
	add.l	d1,d3
	move.l	F13_Start3(a4),d4
	move.w	F13_Offset3(a4),d1
	add.l	d1,d4
	move.l	F13_Start4(a4),d5
	move.w	F13_Offset4(a4),d1
	add.l	d1,d5
	move.w	F13_SSize1(a4),d0	;Get sound lengths
	move.w	F13_SSize2(a4),d1
	move.w	F13_SSize3(a4),d6
	move.w	F13_SSize4(a4),d7
	move.w	(a7)+,$dff096		;Enable audio DMA

chan1	lea	F13_V1Data(a4),a0
	tst.w	72(a0)
	beq.b	chan2
	subq.w	#1,72(a0)
	cmpi.w	#1,72(a0)
	bne.b	chan2
	clr.w	72(a0)
	btst	#0,F13_ActChan+1(a4)
	beq.b	chan2
	move.l	d2,$dff0a0		;Set soundstart
	move.w	d0,$dff0a4		;Set soundlength

chan2	lea	F13_V2Data(a4),a0
	tst.w	72(a0)
	beq.b	chan3
	subq.w	#1,72(a0)
	cmpi.w	#1,72(a0)
	bne.b	chan3
	clr.w	72(a0)
	btst	#1,F13_ActChan+1(a4)
	beq.b	chan3
	move.l	d3,$dff0b0
	move.w	d1,$dff0b4

chan3	lea	F13_V3Data(a4),a0
	tst.w	72(a0)
	beq.b	chan4
	subq.w	#1,72(a0)
	cmpi.w	#1,72(a0)
	bne.b	chan4
	clr.w	72(a0)
	btst	#2,F13_ActChan+1(a4)
	beq.b	chan4
	move.l	d4,$dff0c0
	move.w	d6,$dff0c4

chan4	lea	F13_V4Data(a4),a0
	tst.w	72(a0)
	beq.b	setpervol
	subq.w	#1,72(a0)
	cmpi.w	#1,72(a0)
	bne.b	setpervol
	clr.w	72(a0)
	btst	#3,F13_ActChan+1(a4)
	beq.b	setpervol
	move.l	d5,$dff0d0
	move.w	d7,$dff0d4

setpervol
	move.l	F13_Global(a4),a0
	move.l	APG_CalcVolume(a0),a0
	lea	$dff0a6,a5
	move.w	F13_ActChan(a4),d7

	moveq	#0,d0
	move.w	(a6),d2
	addq.l	#4,a6
	btst	#0,d7
	beq.b	.skip1
	move.w	d2,(a5)			;Set period
	move.w	-2(a6),d0		;Get Volume
	jsr	(a0)
.SKIP1	move.w	d0,2(a5)		;Set volume

	moveq	#0,d0
	move.w	(a6),d2
	addq.l	#4,a6
	btst	#1,d7
	beq.b	.skip2
	move.w	d2,16(a5)		;Set period
	move.w	-2(a6),d0		;Get Volume
	jsr	(a0)
.SKIP2	move.w	d0,18(a5)		;Set volume

	moveq	#0,d0
	move.w	(a6),d2
	addq.l	#4,a6
	btst	#2,d7
	beq.b	.skip3
	move.w	d2,32(a5)		;Set period
	move.w	-2(a6),d0		;Get Volume
	jsr	(a0)
.SKIP3	move.w	d0,34(a5)		;Set volume

	moveq	#0,d0
	move.w	(a6),d2
	addq.l	#4,a6
	btst	#3,d7
	beq.b	.skip4
	move.w	d2,48(a5)		;Set period
	move.w	-2(a6),d0		;Get Volume
	jsr	(a0)
.SKIP4	move.w	d0,50(a5)		;Set volume
	rts

new_note
	moveq	#0,d5
	move.l	34(a0),a1
	adda.w	40(a0),a1
	cmp.w	#64,40(a0)
	bne.b	samepat
	move.l	FC_DataArea+F13_Global,a2
	move.l	APG_SendMsg(a2),a2
	move.w	#MSG_NextPos,d2
	jsr	(a2)			;Send NextPos Message
	move.l	(a0),a2
	adda.w	6(a0),a2		;Point to next sequence row
	cmpa.l	52(a0),a2		;Is it the end?
	bne.b	notend
	move.l	FC_DataArea+F13_Global,a2
	move.l	APG_SendMsg(a2),a2
	move.w	#MSG_NextMod,d2
	jsr	(a2)			;Send NextMod Message
	move.w	d5,6(a0)
	move.l	(a0),a2			;Point to first sequence

notend	moveq	#1,d1
	addq.b	#1,F13_SpdTemp(a4)
	cmpi.b	#5,F13_SpdTemp(a4)
	bne.b	nonewspd
	move.b	d1,F13_SpdTemp(a4)
	move.b	12(a2),d1		;Get new replay speed
	beq.b	nonewspd
	move.w	d1,F13_ReSpCnt(a4)	;store in counter
	move.w	d1,F13_RepSpd(a4)

nonewspd
	move.b	(a2),d1			;Pattern to play
	move.b	1(a2),44(a0)		;Transpose value
	move.b	2(a2),22(a0)		;Soundtranspose value

	move.w	d5,40(a0)
	lsl.w	#6,d1
	add.l	F13_PATPoint(a4),d1	;Get pattern pointer
	move.l	d1,34(a0)
	addi.w	#$000d,6(a0)
	move.l	d1,a1

samepat	move.b	1(a1),d1		;Get info byte
	move.b	(a1)+,d0		;Get note
	bne.b	ww1
	andi.w	#%11000000,d1
	beq.b	noport
	bra.b	ww11

ww1	move.w	d5,56(a0)
ww11	move.b	d5,47(a0)
	move.b	(a1),31(a0)

		;31(a0) = PORTAMENTO/INSTR. info
			;Bit 7 = portamento on
			;Bit 6 = portamento off
			;Bit 5-0 = instrument number
		;47(a0) = portamento value
			;Bit 7-5 = always zero
			;Bit 4 = up/down
			;Bit 3-0 = value
t_porton
	btst	#7,d1
	beq.b	noport
	move.b	2(a1),47(a0)	
noport	andi.w	#$007f,d0
	beq.b	nextnote
	move.b	d0,8(a0)
	move.b	(a1),9(a0)
	move.b	32(a0),d2
	moveq	#0,d3
	bset	d2,d3
	or.w	d3,F13_AudTemp(a4)
	move.w	d3,$dff096
	move.b	(a1),d1
	andi.w	#$003f,d1		;Max 64 instruments
	add.b	22(a0),d1
	move.l	F13_VOLPoint(a4),a2
	lsl.w	#6,d1
	adda.w	d1,a2
	move.w	d5,16(a0)
	move.b	(a2),23(a0)
	move.b	(a2)+,24(a0)
	move.b	(a2)+,d1
	andi.w	#$00ff,d1
	move.b	(a2)+,27(a0)
	move.b	#$40,46(a0)
	move.b	(a2)+,d0
	move.b	d0,28(a0)
	move.b	d0,29(a0)
	move.b	(a2)+,30(a0)
	move.l	a2,10(a0)
	move.l	F13_FRQPoint(a4),a2
	lsl.w	#6,d1
	adda.w	d1,a2
	move.l	a2,18(a0)
	move.w	d5,50(a0)
	move.b	d5,26(a0)
	move.b	d5,25(a0)
nextnote
	addq.w	#2,40(a0)
	rts

effects	moveq	#0,d7
testsustain
	tst.b	26(a0)			;Is sustain counter = 0
	beq.b	sustzero
	subq.b	#1,26(a0)		;if no, decrease counter
	bra.w	VOLUfx

sustzero				;Next part of effect sequence
	move.l	18(a0),a1		;can be executed now.
	adda.w	50(a0),a1
testeffects
	cmpi.b	#$e1,(a1)		;E1 = end of FREQseq sequence
	beq.w	VOLUfx
	cmpi.b	#$e0,(a1)		;E0 = loop to other part of sequence
	bne.b	testnewsound
	move.b	1(a1),d0		;loop to start of sequence + 1(a1)
	andi.w	#$003f,d0
	move.w	d0,50(a0)
	move.l	18(a0),a1
	adda.w	d0,a1
testnewsound
	move.l	a4,-(sp)
	cmpi.b	#$e2,(a1)		;E2 = set waveform
	bne.b	o49c64
	moveq	#0,d0
	moveq	#0,d1
	move.b	32(a0),d1
	bset	d1,d0
	or.w	d0,F13_AudTemp(a4)
	move.w	d0,$dff096
	move.b	1(a1),d0
	andi.w	#$00ff,d0
	lea	F13_SoundInfo(a4),a4
	add.w	d0,d0
	move.w	d0,d1
	add.w	d1,d1
	add.w	d1,d1
	add.w	d1,d0
	adda.w	d0,a4
	move.l	60(a0),a3
	move.l	(a4),d1
	add.l	#WAVEFORMS,d1
	move.l	d1,(a3)
	move.l	d1,68(a0)
	move.w	4(a4),4(a3)
	move.l	6(a4),64(a0)
	swap	d1
	move.w	#$0003,72(a0)
	tst.w	d1
	bne.b	o49c52
	move.w	#$0002,72(a0)
o49c52	clr.w	16(a0)
	move.b	#$01,23(a0)
	addq.w	#2,50(a0)
	move.l	(sp)+,a4
	bra.w	o49d02

o49c64	cmpi.b	#$e4,(a1)
	bne.b	testpatjmp
	move.b	1(a1),d0
	andi.w	#$00ff,d0
	lea	F13_SoundInfo(a4),a4
	add.w	d0,d0
	move.w	d0,d1
	add.w	d1,d1
	add.w	d1,d1
	add.w	d1,d0
	adda.w	d0,a4
	move.l	60(a0),a3
	move.l	(a4),d1
	add.l	#WAVEFORMS,d1
	move.l	d1,(a3)
	move.l	d1,68(a0)
	move.w	4(a4),4(a3)
	move.l	6(a4),64(a0)

	swap	d1
	move.w	#$0003,72(a0)
	tst.w	d1
	bne.b	o49cae
	move.w	#$0002,72(a0)
o49cae	addq.w	#2,50(a0)
	move.l	(sp)+,a4
	bra.b	o49d02

testpatjmp
	move.l	(sp)+,a4
	cmpi.b	#$e7,(a1)
	bne.b	testnewsustain
	move.b	1(a1),d0
	andi.w	#$00ff,d0
	lsl.w	#6,d0
	move.l	F13_FRQPoint(a4),a1
	adda.w	d0,a1
	move.l	a1,18(a0)
	move.w	d7,50(a0)
	bra.w	testeffects

testnewsustain
	cmpi.b	#$e8,(a1)		;E8 = set sustain time
	bne.b	o49cea
	move.b	1(a1),26(a0)
	addq.w	#2,50(a0)
	bra.w	testsustain

o49cea	cmpi.b	#$e3,(a1)
	bne.b	o49d02
	addq.w	#3,50(a0)
	move.b	1(a1),27(a0)
	move.b	2(a1),28(a0)

o49d02	move.l	18(a0),a1
	adda.w	50(a0),a1
	move.b	(a1),43(a0)
	addq.w	#1,50(a0)

VOLUfx	tst.b	25(a0)
	beq.b	o49d1e
	subq.b	#1,25(a0)
	bra.b	o49d70

o49d1e	subq.b	#1,23(a0)
	bne.b	o49d70
	move.b	24(a0),23(a0)

o49d2a	move.l	10(a0),a1
	adda.w	16(a0),a1
	move.b	(a1),d0
	cmpi.b	#$e8,d0
	bne.b	o49d4a
	addq.w	#2,16(a0)
	move.b	1(a1),25(a0)
	bra.b	VOLUfx

o49d4a	cmpi.b	#$e1,d0
	beq.b	o49d70
	cmpi.b	#$e0,d0
	bne.b	o49d68
	move.b	1(a1),d0
	andi.l	#$003f,d0
	subq.b	#5,d0
	move.w	d0,16(a0)
	bra.b	o49d2a

o49d68	move.b	(a1),45(a0)
	addq.w	#1,16(a0)
o49d70	move.b	43(a0),d0
	bmi.b	o49d7e
	add.b	8(a0),d0
	add.b	44(a0),d0
o49d7e	andi.w	#$007f,d0
	lea	PERIODS,a1
	add.w	d0,d0
	move.w	d0,d1
	adda.w	d0,a1
	move.w	(a1),d0
	move.b	46(a0),d7
	tst.b	30(a0)
	beq.b	o49d9e
	subq.b	#1,30(a0)
	bra.b	o49df4

o49d9e	move.b	d1,d5
	move.b	28(a0),d4
	add.b	d4,d4
	move.b	29(a0),d1
	tst.b	d7
	bpl.b	o49db4
	btst	#0,d7
	bne.b	o49dda
o49db4	btst	#5,d7
	bne.b	o49dc8
	sub.b	27(a0),d1
	bcc.b	o49dd6
	bset	#5,d7
	moveq	#0,d1
	bra.b	o49dd6

o49dc8	add.b	27(a0),d1
	cmp.b	d4,d1
	bcs.b	o49dd6
	bclr	#5,d7
	move.b	d4,d1
o49dd6	move.b	d1,29(a0)
o49dda	lsr.b	#1,d4
	sub.b	d4,d1
	bcc.b	o49de4
	subi.w	#$0100,d1
o49de4	addi.b	#$a0,d5
	bcs.b	o49df2
o49dea	add.w	d1,d1
	addi.b	#$18,d5
	bcc.b	o49dea
o49df2	add.w	d1,d0
o49df4	eori.b	#$01,d7
	move.b	d7,46(a0)

; DO THE PORTAMENTO THING
	moveq	#0,d1
	move.b	47(a0),d1		;get portavalue
	beq.b	a56d0			;0=no portamento
	cmpi.b	#$1f,d1
	bls.b	portaup
portadown
	andi.w	#$1f,d1
	neg.w	d1
portaup	sub.w	d1,56(a0)
a56d0	add.w	56(a0),d0
o49e3e	cmpi.w	#$0070,d0
	bhi.b	nn1
	move.w	#$0071,d0
nn1	cmpi.w	#$06b0,d0
	bls.b	nn2
	move.w	#$06b0,d0
nn2	moveq	#0,d1
	move.b	45(a0),d1
	rts
;------------------------------------------------------------------------------
	SECTION	WaveForms,DATA_C

WAVEFORMS
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $3f37,$2f27,$1f17,$0f07,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c037,$2f27,$1f17,$0f07,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$2f27,$1f17,$0f07,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b027,$1f17,$0f07,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$1f17,$0f07,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a017,$0f07,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$0f07,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9007,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$ff07,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$8007,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$8088,$0f17,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$8088,$9017,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$8088,$9098,$1f27,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$8088,$9098,$a027,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$8088,$9098,$a0a8,$2f37
	dc.w $c0c0,$d0d8,$e0e8,$f0f8,$00f8,$f0e8,$e0d8,$d0c8
	dc.w $c0b8,$b0a8,$a098,$9088,$8088,$9098,$a0a8,$b037
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $817f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$817f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$817f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$817f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$8181,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$8181,$817f,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$8181,$8181,$7f7f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$8181,$8181,$817f,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$7f7f,$7f7f
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$8181,$8181
	dc.w $8181,$8181,$8181,$8181,$8181,$8181,$817f,$7f7f
	dc.w $8080,$8080,$8080,$8080,$8080,$8080,$8080,$8080
	dc.w $8080,$8080,$8080,$8080,$8080,$8080,$8080,$7f7f
	dc.w $8080,$8080,$8080,$8080,$8080,$8080,$8080,$8080
	dc.w $8080,$8080,$8080,$8080,$8080,$8080,$8080,$807f
	dc.w $8080,$8080,$8080,$8080,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$8080,$8080,$807f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$8080,$8080,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$8080,$807f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$8080,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$807f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f,$7f7f
	dc.w $8080,$9098,$a0a8,$b0b8,$c0c8,$d0d8,$e0e8,$f0f8
	dc.w $0008,$1018,$2028,$3038,$4048,$5058,$6068,$707f
	dc.w $8080,$a0b0,$c0d0,$e0f0,$0010,$2030,$4050,$6070
	dc.w $4545,$797d,$7a77,$7066,$6158,$534d,$2c20,$1812
	dc.w $04db,$d3cd,$c6bc,$b5ae,$a8a3,$9d99,$938e,$8b8a
	dc.w $4545,$797d,$7a77,$7066,$5b4b,$4337,$2c20,$1812
	dc.w $04f8,$e8db,$cfc6,$beb0,$a8a4,$9e9a,$9594,$8d83
	dc.w $0000,$4060,$7f60,$4020,$00e0,$c0a0,$80a0,$c0e0
	dc.w $0000,$4060,$7f60,$4020,$00e0,$c0a0,$80a0,$c0e0
	dc.w $8080,$9098,$a0a8,$b0b8,$c0c8,$d0d8,$e0e8,$f0f8
	dc.w $0008,$1018,$2028,$3038,$4048,$5058,$6068,$707f
	dc.w $8080,$a0b0,$c0d0,$e0f0,$0010,$2030,$4050,$6070
;------------------------------------------------------------------------------
	SECTION	DataArea,BSS

FC_DataArea
	ds.b	Future13Struct_SIZEOF
;------------------------------------------------------------------------------
SLUT
