*******************************************************************************
* ProRunner Module Convertor 2.3
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Release	: 0.1 $
* $Revision	: 2.3 $
* $Date		: 1st-Oct-94 $
*
* $Author(s)	: Written by 2-Cool/EX4! (In MC680x0 Assembly under Asm-One)
* $Note(s)	: Position Independacy off a4 - (WARNING: DON`T TRASH A4!)
*		: Execbase Ptr is cached so that if running in fastmem access
*		: to execbase ptr is faster.
*
* $Purpose	: This program is a replacement utility for ProRunner 2.0
*		: originally by Cosmos of Sanity. The original pro-runner
*		: converter had a non-aga intro attached to the from of it
*		: of which its copperlist corrupted on AGA machines.. also
*		: no use of file-requesters meant the utility was a pain in
*		: the ass to use.. you had to enter the full filename and
*		: path evertime you wanted to convert a module.. This util
*		: replaces the original and provides a far nice framework
*		: based around the ASL-File requester this utility lets you
*		: use requesters instead.. much easier and speeds up conversion
*******************************************************************************
AbsExecBase	=	4			/* Execbase Definition */
SUCCESS		=	0			/* result return codes... */
VAR_ERROR	=	1			/* memory alloction failcode */
CSI		=	$1b
CLS		macro
		dc.b	CSI,'c',LF
		endm
_LVORawIOInit	=	-$1F8
		
*-------------- Definition Includes...

		incdir	_include:
		include	exec/exec.i
		include	"include:exec/funcdef.i"
		include	intuition/intuition.i
		include	graphics/videocontrol.i
		include	libraries/asl.i
		include	libraries/gadtools.i
		include	libraries/dos_lib.i
		include	libraries/intuition_lib.i
		include	libraries/graphics_lib.i
		include	libraries/exec_lib.i
		include	libraries/asl_lib.i
		include	libraries/icon_lib.i
		include	libraries/diskfont_lib.i
		include	libraries/gadtools_lib.i
		include	libraries/wb_lib.i
		include	libraries/rexxsyslib_lib.i
		include	libraries/utility_lib.i
		include	libraries/dosextens.i
		include	utility/tagitem.i
		include	dos/datetime.i
		include	libraries/reqtools.i
		
*-------------- Definition of Main Variables (Public) Block...

		STRUCTURE VarsBlock,0

		APTR	_ExecBase			/* ExecBase base */
		APTR	_DOSBase			/* DOS lib base */
		APTR	_DOSOutput			/* DOS output base */
		APTR	_ArgPtr				/* CLI Args ptr */
		ULONG	_ArgLen				/* CLI Args length */
		APTR	_AslBase			/* Asl lib base */
		APTR	_Asl_Request			/* Requester struct */
		APTR	_PrtfBase			/* Printf fmstr base */

		APTR	ProgBuff			/* ptr to progbuffer */
		APTR	ProgHandle			/* ptr to filehandle */
		ULONG	ProgSize			/* length file */
		APTR	FilePath.arg			/* argstream pathptr */
		STRUCT	_PathBuffer,712			/* path buffer */

		ULONG	PackedSize			/* Packed Buff size */
		ULONG	ProLength
		APTR	DestNamePtr

		UWORD	maxraster
		UWORD	medraster
		UWORD	oldint

		UBYTE	playmode
		UBYTE	waspacked

		STRUCT	TempBuffer,1080			/* size of PT-Header */

		LABEL	vars_SIZEOF

*-------------- Definition of Macros...

PUSH		macro
		movem.l	\1,-(sp)
		endm
PULL		macro
		movem.l	(sp)+,\1
		endm
PUSHW		macro
		movem.w	\1,-(sp)
		endm
PULLW		macro
		movem.w	(sp)+,\1
		endm
PUSHR		macro
		move.l	\1,-(sp)
		endm
PULLR		macro
		move.l	(sp)+,\1
		endm
CALL		macro
		jsr	_LVO\1(a6)
		endm
CALLJ		macro
		jmp	_LVO\1(a6)
		endm
CALLREL		macro
		move.l	\2(a4),a6
		CALL	\1
		endm
		
*******************************************************************************
*-------------- Allocate our Variables (RS.) Area

ProgStart:	move.l	a0,a5
		move.l	d0,d5

		move.l	#vars_SIZEOF,d0		;length for our variables
		move.l	#MEMF_PUBLIC+MEMF_CLEAR,d1 ;we want public mem, cleared
		move.l	(AbsExecBase).w,a6	;get SysBase
		CALL	AllocMem		;allocate it...
		move.l	d0,a4			;ptr to our RS.Variables base
		bne.s	RSValid			;did the alloc fail, if so exit
		moveq	#VAR_ERROR,d0		;Memory allocation fail code
		rts				;exit to dos...

*-------------- Place Version String here so it can be quickly found.

Version:	dc.b	"$VER: ProRunner v2.3 (Oct-94)",0
		even

*-------------- From here a4 points to our variables area (DON`T DESTROY A4!)

RSValid:	move.l	a6,(a4)			;cache execptr in Public so if
						;we are in fastmem were faster
		move.l	a5,_ArgPtr(a4)
		move.l	d5,_ArgLen(a4)
		clr.b	-1(a5,d5.w)		;null terminate arg string..

*-------------- Open DOS Library

		moveq	#36,d0			;set lib version
  		lea	Dosname(pc),a1		;lib name in a1
  		CALL	OpenLibrary		;try to open library
  		move.l	d0,_DOSBase(a4)		;store lib base
  		beq.w	ShutDown		;cleanup and quit if fail

*-------------- Get DOS Output

		move.l	d0,a6			;get dosbase
		CALL	Output			;get output base
		move.l	d0,_DOSOutput(a4)	;save outputbase

*-------------- Open ASL Library

		move.l	(a4),a6			;get execbase
		moveq	#36,d0			;set lib version
  		lea	Aslname(pc),a1		;lib name in a1
  		CALL	OpenLibrary		;try to open library
  		move.l	d0,_AslBase(a4)		;store lib base
  		beq.w	ASLError		;cleanup and quit if fail

*-------------- Allocate ASL Requester

		move.l	d0,a6			;get asl base in a6
		moveq	#ASL_FileRequest,d0	;requester type
		lea	MainTags(pc),a0		;taglist
		CALL	AllocAslRequest		;allocate asl request struct
		move.l	d0,_Asl_Request(a4)	;save request struct
  		beq.w	AllocError		;show 'out of memory' msg

*-------------- Initialise 'printf' routines...

		bsr.w	_PrintInit		;initialise printf memory
  		beq.w	AllocError		;show 'out of memory' msg

*-------------- Program starts here

		lea	About.Txt(pc),a0		;format string
		bsr.w	PutStr

*-------------- Show usage message or request a filename?

		sf	playmode(a4)		;default noplaying...

		move.l	_ArgPtr(a4),a0
chkname:	cmp.b	#"?",(a0)
		beq.w	show_usage
		cmp.b	#"-",(a0)
		beq.s	check_opts
		cmp.b	#LF,(a0)
		beq.w	no_filename
		tst.b	(a0)
		beq.w	no_filename
		bra.w	ShowFName

check_opts	cmp.b	#"p",1(a0)
		bne.s	no_play
		move.b	#1,playmode(a4)		;playmode #1
		addq.l	#3,a0			;filename
		bra	chkname

no_play:	cmp.b	#"m",1(a0)
		bne.s	no_play2
		move.b	#2,playmode(a4)		;playmode #1
		addq.l	#3,a0			;filename
		bra	chkname
		
no_play2:	cmp.b	#" ",2(a0)		;bad template?
		bne.s	show_usage
		cmp.b	#"s",1(a0)		;save source-code?
		bne.s	no_save_source

		move.l	a0,a1
		lea	src.Txt(pc),a0		;format string
		bsr.w	PutStr
		lea	3(a1),a0			;filename
		lea	src-$3fff(pc),a1
		lea	$3fff(a1),a1
		move.l	#srclen,d0
SaveIt		bsr	SaveMem2File
		lea	Done.Txt(pc),a0		;format string
		tst.l	d0
		beq.s	saveokay
		lea	ErrorSave.txt(pc),a0
saveokay	bsr.w	PutStr
		bra.w	ShutExit

no_save_source:	cmp.b	#"d",1(a0)		;save documentation?
		bne.s	no_save_docs

		move.l	a0,a1
		lea	docs.Txt(pc),a0		;format string
		bsr.w	PutStr
		lea	3(a1),a0			;filename
		lea	docs(pc),a1
		move.l	#docslen,d0
		bra	SaveIt

no_save_docs:
show_usage:	lea	Args.Txt(pc),a0		;format string
		bsr.w	PutStr
		bra.w	ShutDown
	
*-------------- Example ASL Requester 'LOAD'

no_filename:	lea	Select.Txt(pc),a0	;format string
		bsr.w	PutStr

;-------------- Example ASL Requester 'LOAD'

		lea	LoadTags(pc),a1		;address of taglist
		lea	LoadText(pc),a2		;ptr to requester hail text
		bsr.w	RequestASL
		beq.w	NoName			;load 'express failed'
	
ShowFName:	move.l	a0,a1
		clr.l	DestNamePtr(a4)

scan_dest:	tst.b	(a1)
		beq.s	no_dest
		cmp.b	#LF,(a1)
		beq.s	no_dest
		cmp.b	#" ",(a1)+
		bne.s	scan_dest
		tst.b	-(a1)
		sf.b	(a1)+
got_it:		move.l	a1,DestNamePtr(a4)
no_dest
		move.l	a0,-(sp)
		lea	FilePath.arg(a4),a1	;arguments stream
		move.l	a0,(a1)			;pathname into arg stream
		lea	FilePath.fmt(pc),a0	;format string
		bsr.w	printf
		move.l	(sp)+,a0		;a0=filename ptr

*-------------- Load DOS file into buffer

		bsr.w	LoadDOSFile
		cmp.b	#-2,d0
		beq.w	LoadFailedMem		;load 'express failed'
		cmp.b	#-1,d0
		beq.w	LoadNotFound

*-------------- Now do the processing bits here...

		move.l	ProgBuff(a4),a0		
		move.l	ProgSize(a4),d0
		bsr	ProcessData
		beq.s	dosave			;was it successful?

		lea	ErrorType.txt(pc),a0
		bsr	PutStr
		bra.s	ShutDown
		
*-------------- Example ASL Requester 'SAVE'

dosave:
*-------------- have we already got a destination name??

		move.l	DestNamePtr(a4),a0
		move.l	a0,d0
		bne.s	no_destn2

*-------------- if not prompt for one with file-requester
		
		lea	SaveTags(pc),a1		;address of taglist
		lea	SaveText(pc),a2		;ptr to requester hail text
		bsr.w	RequestASL
		beq.w	NoName
no_destn2:
;-------------- at this point 'a0' = filename...

*-------------- save as Pro-Tracker??
		tst.b	waspacked(a4)		;unpack save or normal save??
		beq.s	no_pr_save

;-------------- its protracker conversion save...

		move.l	a0,a1			;a1.l=filename

		move.l	a0,-(sp)
		move.l	ProgBuff(a4),a0		;a0.l=buffer..
		bsr	ConvertPR
		move.l	(sp)+,a0

no_pr_save	move.l	a0,-(sp)
		lea	Done.Txt(pc),a0		;format string
		bsr.w	PutStr
		move.l	(sp)+,a0

		move.l	a0,-(sp)
		lea	FilePath.arg(a4),a1	;arguments stream
		move.l	a0,(a1)			;pathname into arg stream
		lea	FilePath2.fmt(pc),a0	;format string
		bsr.w	printf
		move.l	(sp)+,a0		;a1=name of file to save


*-------------- save as Pro-Tracker or Pro-Runner??

		tst.b	waspacked(a4)		;unpack save or normal save??
		bne.s	no_normal_save

;-------------- its prorunner...
		move.l	ProgBuff(a4),a1
		move.l	PackedSize(a4),d0
		bsr	SaveMem2File
		cmp.b	#1,d0
		beq.b	SaveError

		lea	SaveOkay.Txt(pc),a0
		bsr	PutStr
no_normal_save


*-------------- Program ends here

*******************************************************************************
* Shutdown() - Free all allocated resources & exit program
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Frees all previously allocated resources, sanity checks are made so only
* allocated memory/open libraries will be removed.
*******************************************************************************

ShutDown:	bsr.w	FreeDOSFile

*-------------- Free 'printf' memory

ShutExit:	bsr.w	_PrintClose		;free printf memory

*-------------- Free Allocated ASL File-Requester

		move.l	_Asl_Request(a4),d0	;get request struct
		beq.s	FreeASL	
		move.l	d0,a0
		move.l	_AslBase(a4),a6
		CALL	FreeAslRequest

*-------------- Free ASL Library

FreeASL:	move.l	(a4),a6			;get execbase
		move.l	_AslBase(a4),d0		;asl lib base in a1
		beq.s	FreeDOS
		move.l	d0,a1
 		CALL	CloseLibrary		;close asl

*-------------- Free DOS Library

FreeDOS:	move.l	_DOSBase(a4),d0		;dos lib base in a1
		beq.s	RSFreeMem
		move.l	d0,a1
 	 	CALL	CloseLibrary		;close intuition
		clr.l	_DOSBase(a4)		;clear out base
		
*-------------- Free RS Variables Area

RSFreeMem:	move.l	a4,a1			;ptr to our RS.Variables base
		move.l	#vars_SIZEOF,d0		;no. of bytes to free
		move.l	(a4),a6			;get execbase
		CALL	FreeMem			;free the memory

		moveq	#SUCCESS,d0		;no return code
		rts				;exit...

AllocError:	lea	ErrorAlloc.txt(pc),a0
		bra.s	showmsg
LoadFailedMem	lea	ErrorMem.txt(pc),a0
		bra.s	showmsg
LoadNotFound	lea	ErrorLoad.txt(pc),a0
		bra.s	showmsg
SaveError	lea	ErrorSave.txt(pc),a0
		bra.s	showmsg
ASLError	lea	ErrorASL.txt(pc),a0
		bra.s	showmsg
NoName		lea	NoName.txt(pc),a0
showmsg		bsr.w	PutStr
		bra.s	ShutDown

*******************************************************************************
* Pro-Runner Module Convertor
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
*******************************************************************************

ProcessData:	sf.b	waspacked(a4)
		cmp.l	#'SNT!',(a0)
		beq.s	is_packed

		lea	LengthPT.Txt(pc),a0
		bsr	PutStr			;d0.l = Original Length
		bsr	H2A

		move.l	ProgBuff(a4),a0		
		move.l	ProgSize(a4),d0
		cmp.l	#1088,d0		;file too small..
		blt.w	reloc_error
		cmp.l	#'M.K.',$438(a0)
		bne.w	reloc_error
						
		move.l	a4,-(sp)
		bsr.w	pr_Pack
		move.l	(sp)+,a4
		move.l	d0,PackedSize(a4)

		lea	PakLength.Txt(pc),a0
		bsr	PutStr			;d0.l = Original Length
		bsr	H2A

		move.l	ProgSize(a4),d0
		sub.l	PackedSize(a4),d0	;d0.l= gain in bytes.

		lea	Gained.Txt(pc),a0
		bsr	PutStr			;d0.l = Gained bytes
		bsr	H2A
		bra.s	wasnt_packed
		
is_packed:	lea	LengthPR.Txt(pc),a0
		bsr	PutStr			;d0.l = Original Length
		bsr	H2A
		st.b	waspacked(a4)

wasnt_packed:	tst.b	playmode(a4)
		beq.s	no_playtest

		cmp.b	#2,playmode(a4)
		beq.s	not_multi

		lea	both5secs.Txt(pc),a0	;format string
		bsr.w	PutStr

		bsr	PlayTest
		moveq	#0,d1			;operation successful
		rts


not_multi:	lea	both.Txt(pc),a0		;format string
		bsr.w	PutStr

		bsr	PlayTest2

		lea	Min.Txt(pc),a0
		bsr	PutStr			;d0.l = Original Length
		moveq	#0,d0
		move.w	medraster(a4),d0
		bsr	H2A

		lea	Max.Txt(pc),a0
		bsr	PutStr			;d0.l = Original Length
		moveq	#0,d0
		move.w	maxraster(a4),d0
		bsr	H2A

		lea	Done.Txt(pc),a0		;format string
		bsr.w	PutStr

no_playtest:
		moveq	#0,d1			;operation successful
		rts
not_pr
reloc_error:	moveq	#-1,d1
		rts

pr_Pack:	lea	pr_Module(pc),a1
		move.l	a0,(a1)

		move.l	d0,pr_OldLength-pr_Module(a1)
		moveq	#0,d0
		move.b	$3B6(a0),d0
		move.w	d0,pr_Wd3-pr_Module(a1)

		lea	$3B8(a0),a1
		moveq	#$7F,d0
		moveq	#0,d1
cn1a:		move.b	(a1)+,d2
		cmp.b	d1,d2
		bls.s	cn1b
		move.b	d2,d1
cn1b:		dbra	d0,cn1a

		move.l	a0,-(sp)
		lea	pr_Wd2(pc),a0
		move.w	d1,(a0)			;!!!!!!!!!!!!!!!!!!
		move.l	(sp)+,a0

		lea	$43C(a0),a1
		lea	(a0),a2
		add.l	pr_OldLength(pc),a2
		moveq	#0,d0
		move.w	pr_Wd2(pc),d0
		addq.w	#1,d0
		lsl.l	#8,d0
		lsl.l	#2,d0
		add.l	d0,a1
		sub.l	a1,a2

		move.l	a0,-(sp)
		lea	pr_pr_r3(pc),a0
		move.l	a2,(a0)			;!!!!!!!!!!!!!!!!!!
		move.l	(sp)+,a0

		lea	pr_dabuf(pc),a2
		moveq	#$7F,d0
		subq.w	#1,d0
		moveq	#0,d7
		moveq	#1,d6
cn3b:		lea	$3B8(a0),a1
		move.w	pr_Wd3(pc),d1
		subq.w	#1,d1
		moveq	#0,d5
cn3c:		cmp.b	(a1)+,d7
		bne.s	cn3d
		move.b	d6,0(a2,d7.w)
		addq.w	#1,d5
cn3d:		dbra	d1,cn3c
		tst.w	d5
		beq.s	cn3e
		addq.w	#1,d6
cn3e:		addq.w	#1,d7
		dbra	d0,cn3b

		lea	pr_dabuf(pc),a1
		moveq	#0,d1
		moveq	#$7F,d0
cn4b:		move.b	(a1)+,d2
		cmp.b	d1,d2
		bls.s	cn4c
		move.b	d2,d1
cn4c:		dbra	d0,cn4b
		subq.w	#1,d1

		move.l	a0,-(sp)
		lea	pr_Wd1(pc),a0
		move.w	d1,(a0)			;!!!!!!!!
		move.l	(sp)+,a0

		lea	$3B8(a0),a1
		lea	pr_dabuf(pc),a2
		lea	pr_dabuf3(pc),a3
		move.w	pr_Wd3(pc),d0
		subq.w	#1,d0
		moveq	#0,d1
cn5b:		move.b	(a1)+,d1
		move.b	0(a2,d1.w),d1
		subq.w	#1,d1
		move.b	d1,(a3)+
		dbra	d0,cn5b

cn6:		lea	$3B8(a0),a1
		move.b	$3B8(a0),$438(a0)
		lea	pr_Buf1(pc),a2
		move.w	pr_Wd3(pc),d0
		subq.w	#1,d0
		moveq	#0,d1
cn6b:		moveq	#0,d2
		move.b	(a1)+,d2
		lsl.l	#8,d2
		lsl.l	#2,d2
		lea	$43E(a0),a3
		add.l	d2,a3
		move.l	d1,d2
		lsl.l	#4,d2
		add.l	d2,a3
		move.w	d1,d2
		neg.w	d2
		add.w	#$40,d2
		lsl.w	#2,d2
		subq.w	#1,d2
cn6c:		moveq	#15,d3
		and.b	(a3),d3
		cmp.b	#13,d3
		beq.s	cn6f
cn6d:		addq.l	#4,a3
		dbra	d2,cn6c
		bra.s	cn6e
cn6f:		moveq	#0,d3
		move.b	1(a3),d3
		beq.s	cn6d
		moveq	#15,d4
		and.b	d3,d4
		lsr.b	#4,d3
		mulu	#10,d3
		add.w	d4,d3
		move.b	d3,1(a3)
		move.w	d3,(a2)
		move.w	d3,d1
cn6e:		addq.l	#2,a2
		dbra	d0,cn6b

		lea	$3B9(a0),a1
		lea	$43C(a0),a2
		lea	pr_Buf1(pc),a3
		moveq	#$7F,d0
cn7a:		moveq	#0,d1
		move.b	(a1)+,d1
		moveq	#0,d2
		move.w	(a3)+,d2
		tst.w	d2
		beq.s	cn7b
		lsl.l	#8,d1
		lsl.l	#2,d1
		move.l	a2,a4
		add.l	d1,a4
		lsl.l	#4,d2
		add.l	d2,a4
		move.b	#$80,d7
		or.b	d7,(a4)
		or.b	d7,4(a4)
		or.b	d7,8(a4)
		or.b	d7,12(a4)
cn7b:		dbra	d0,cn7a

		bsr.w	cn8

		lea	(a0),a6
		move.l	#'SNT!',(a6)+
		addq.l	#4,a6

		lea	$14(a0),a1
		moveq	#$16,d1
		moveq	#$1E,d0
cnn9b:		add.l	d1,a1
		move.l	(a1)+,(a6)+
		move.l	(a1)+,(a6)+
		dbra	d0,cnn9b
		move.w	(a1)+,(a6)+
		lea	pr_dabuf3(pc),a1
		moveq	#$1F,d0
cnn9c:		move.l	(a1)+,(a6)+
		dbra	d0,cnn9c

		lea	pr_Buf1(pc),a1
		lea	pr_ln2(pc),a2
		lea	$3B9(a0),a3
		moveq	#$7F,d0
cnn10b:		clr.w	(a6)+
		moveq	#0,d1
		move.b	(a3)+,d1
		move.w	(a1)+,d2
		tst.w	d2
		beq.s	cnn10e
		add.w	d1,d1
		move.w	0(a2,d1.w),d1
		lea	$43C(a0),a4
		add.l	d1,a4
		move.l	a4,a5
		lsl.w	#2,d2
		subq.w	#1,d2
cnn10c:		tst.b	(a4)+
		bmi.s	cnn10d
		addq.l	#2,a4
cnn10d:		dbra	d2,cnn10c
		sub.l	a5,a4
		move.w	a4,-2(a6)
cnn10e:		dbra	d0,cnn10b

		lea	(a6),a2
		moveq	#$3F,d0
cnn11c:		clr.w	(a6)+
		dbra	d0,cnn11c

		lea	pr_dabuf(pc),a4
		lea	pr_ln2(pc),a3
		moveq	#0,d3
		moveq	#$40,d0
cnn12b:		tst.b	(a4)
		beq.s	cnn12f
		move.w	d3,d2
		add.w	d2,d2
		sub.l	a1,a1
		move.w	0(a3,d2.w),a1
		add.l	a0,a1
		lea	$43C(a1),a1
		move.l	a6,a5
		sub.l	a0,a5
		lea	-$302(a5),a5
		move.w	a5,(a2)+
		move.w	#$FF,d1
cnn12c:		btst	#7,(a1)
		beq.s	cnn12d
		move.b	(a1)+,(a6)+
		bra.s	cnn12e

cnn12d:		move.b	(a1)+,(a6)+
		move.b	(a1)+,(a6)+
		move.b	(a1)+,(a6)+
cnn12e:		dbra	d1,cnn12c
cnn12f:		addq.l	#1,d3
		addq.l	#1,a4
		dbra	d0,cnn12b

		move.l	a6,a1
		suba.l	a0,a1
		move.l	a1,4(a0)
		move.l	pr_pr_r3(pc),d0
		lea	$43C(a0),a1
		moveq	#0,d1
		move.w	pr_Wd2(pc),d1
		addq.w	#1,d1
		lsl.l	#8,d1
		lsl.l	#2,d1
		add.l	d1,a1
cnn13b:		move.l	(a1)+,(a6)+
		subq.l	#4,d0
		bgt.s	cnn13b

		move.l	a6,a4
		sub.l	a0,a4
		move.l	a4,d0
		rts

cn8:		lea	$43C(a0),a1
		lea	(a1),a2
		lea	pr_ln1(pc),a6
		lea	pr_ln2(pc),a3
		moveq	#0,d0
		move.w	pr_Wd2(pc),d0
cn8b:		move.l	a2,a4
		sub.l	a0,a4
		lea	-$43C(a4),a4
		move.w	a4,(a3)+
		moveq	#$3F,d6
		moveq	#-1,d1
		move.l	d1,(a6)
		move.l	d1,4(a6)
		move.l	d1,8(a6)
		move.l	d1,12(a6)
cn8c:		moveq	#3,d5
cn8d:		tst.l	(a1)
		bmi.s	cn8f
		bne.s	cn8e
		clr.l	(a1)+
		move.b	#$80,(a2)+
		dbra	d5,cn8d
		dbra	d6,cn8c
		dbra	d0,cn8b
		rts
cn8e:		move.l	d5,d1
		lsl.l	#2,d1
		move.l	0(a6,d1.w),d2
		cmp.l	(a1),d2
		bne.s	cn8f
		clr.l	(a1)+
		move.b	#$C0,(a2)+
		dbra	d5,cn8d
		dbra	d6,cn8c
		dbra	d0,cn8b
		rts

cn8f:		move.l	(a1),0(a6,d1.w)
		move.w	(a1),d1
		and.w	#$FFF,d1
		move.b	(a1),d2
		move.b	2(a1),d3
		lsr.b	#4,d3
		and.b	#$70,d2
		or.b	d3,d2
		move.w	2(a1),d3
		and.w	#$FFF,d3
		clr.l	(a1)+
		moveq	#0,d4
		tst.w	d1
		beq.s	cn8h
		lea	pr_periods(pc),a4
cn8g:		addq.w	#1,d4
		cmp.w	(a4)+,d1
		bne.s	cn8g
cn8h:		lsl.b	#1,d4
		move.b	d4,(a2)
		move.b	d2,d1
		and.b	#1,d1
		or.b	d1,(a2)
		bclr	#0,d2
		lsl.b	#3,d2
		or.b	d2,1(a2)
		move.w	d3,d1
		lsr.w	#8,d1
		or.b	d1,1(a2)
		move.b	d3,2(a2)
		addq.l	#3,a2
		dbra	d5,cn8d
		dbra	d6,cn8c
		dbra	d0,cn8b
		rts		
H2A:		lea	Value.txt(pc),a0
Hex2ASCIIDec:	lea	hextable(pc),a1
		move.b	#"0",d6			; constant
		move.b	#" ",d5			; replace leading 0's
		moveq	#9-1,d4
ccloop		move.l	(a1)+,d1
		cmp.l	d1,d0
		bcs.s	get3
 		move.w	#32-1,d3
		moveq	#0,d2
get1		add.l	d0,d0
		roxl.l	#1,d2
		cmp.l	d1,d2
		bcs.s	get2
		sub.l	d1,d2
		addq.l	#1,d0
get2		dbra	d3,get1
		add.b	d6,d0
		move.b	d0,(a0)+
		move.l	d2,d0
		move.b	d6,d5
		bra.s	get4

get3		move.b	d5,(a0)+
get4		dbra	d4,ccloop
 		add.b	d6,d0
		move.b	d0,(a0)+
		lea	Value.txt(pc),a0
.getstart	cmp.b	#" ",(a0)+
		beq.s	.getstart
		tst.b	-(a0)
		bsr	PutStr
		lea	LFs.Txt(pc),a0
		bra	PutStr

hextable	dc.l	1000000000
		dc.l	100000000
		dc.l	10000000
		dc.l	1000000
		dc.l	100000
		dc.l	10000
		dc.l	1000
		dc.l	100
		dc.l	10
		dc.l	1
		dc.l	0

*******************************************************************************
* PutStr
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Sends a ascii text string to current console output
* 
* $Inputs:	a0.l = String ptr (null terminated)
*******************************************************************************

PutStr:		movem.l	d0-d7/a1-a6,-(sp)
		move.l	a0,d2
		moveq	#-1,d3			;d4=0
.getlen2	addq.l	#1,d3			;increase string length by 1
		tst.b	(a0)+			;increase position
		bne.s	.getlen2		;nope not found, so keep on

		move.l	_DOSOutput(a4),d1
		move.l	_DOSBase(a4),a6
		jsr	_LVOWrite(a6)		;print error msg to cli
		movem.l	(sp)+,d0-d7/a1-a6
		rts
		
*******************************************************************************
* RequestASL <NON MODIFIABLE>
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Prompts user to select a filename using the ASL Requester
*
* $Inputs	: a1.l=Requester Tag Structure (PTR)
*		: a2.l=Requester Hail Text-String (PTR)
* $Outputs	: a0.l=Pathname of selected file, or Points to ZERO if failed
*		: d0.b=Flags 0,cancelled, -1,selected
*
* $SR-Flags	: Z-Flag Set if requester cancelled.
*******************************************************************************

RequestASL:	move.l	a2,4(a1)		;hail textptr into tag struct
		move.l	_Asl_Request(a4),a0	;address of requester struc
		move.l	_AslBase(a4),a6		;get asl base
		CALL	AslRequest		;do request
		tst.l	d0			;test d0
		beq.s	cancelled		;branch if cancelled

		lea	_PathBuffer(a4),a5
		move.l	_Asl_Request(a4),a0	;address of requester struc
		move.l	rf_Dir(a0),a1		;get dir string
		move.l	a5,a2			;get output buffer
		move.l	#256,d0			;set max size
copy		move.b	(a1)+,(a2)+		;copy bytes
		dbeq	d0,copy			;until end of string or buffer
	
		move.l	a5,d1			;get dir name (copy)
		move.l	rf_File(a0),d2		;get file name
		move.l	#456,d3			;size of buffer
		move.l	_DOSBase(a4),a6		;get dos base
		CALL	AddPart			;create full pathname
		tst.l	d0			;test for overflow
		beq.s	cancelled		;branch on error
	
		moveq	#-1,d0			;initialise count
		move.l	a5,a0			;address of buffer	
checksize:	addq.w	#1,d0			;decrement counter
		tst.b	0(a0,d0.w)		;test for zero terminator
		bne.s	checksize		;branch if not found
	
		cmpi.w	#137,d0			;is count too large
		ble.s	sizeok			;branch if not
		sub.w	#137,d0			;subtract count from numchars
		add.w	d0,a0			;add to buff adr so eostr shown
sizeok		st.b	d0			;d0=$FF.b (Clear Z-Flag)
		rts

cancelled	suba.l	a0,a0			;no filename, clear ptr
		sf.b	d0			;d0=$00.b (Set Z-Flag)
		rts

*****************************************************************************
* PrintInit( )
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Inputs:	None.
* $Outputs:	d0.l=0 if failed.. 
*
* Initializes further usage of Print( ) function.
* Gets output handle, calls AllocMem() for 127 byte output buffer, and
* RawIOInit().  Preserves all registers used.  This should be placed
* in your "opening" routine before any printf() calls.
* D0 will contain a non-zero value ( Z = 0 ) if AllocMem() was successful,
* otherwise D0 = 0 ( Z = 1 ) on return if failure.
*
* ( If PrintInit() fails, you don't need to quit.  Print( ) and can tell that 
* the allocation failed and will return without doing anything. )
******************************************************************************

_PrintInit:	PUSH	d0/d1/a0/a1/a6			;store regs on stack
		clr.l	_PrtfBase(a4)
		moveq	#127,d0				;127 bytes
		move.l	#(MEMF_PUBLIC+MEMF_CLEAR),d1	;of cleared public mem
		move.l	(a4),a6				;get execbase
		CALL	AllocMem			;allocate
		move.l	d0,_PrtfBase(a4)
		CALL	RawIOInit			;do a raw IO init

_NoPrintInit:	PULL	d0/d1/a0/a1/a6			;restore regs off stack
		tst.l	_PrtfBase(a4)
		rts

******************************************************************************
* PrintClose( )
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
*
* If AllocMem() from PrintInit( ) was successful, this does a FreeMem()
* freeing the 127 byte output buffer.  Preserves all registers used.
* This should be placed in your "closing" routine after last printf() call.
******************************************************************************

_PrintClose:	PUSH	d0/d1/a0/a1/a6

		tst.l	_PrtfBase(a4)
		beq.s	_NoPrintClose
		move.l	_PrtfBase(a4),a1
		moveq	#127,d0
		move.l	(a4),a6		;get execbase
		CALL	FreeMem		;free raw io memory

_NoPrintClose:	PULL	d0/d1/a0/a1/a6
		rts

******************************************************************************
* Usage:  printf( FormatString DataStream )
*                   A0            A1
*
* Performs "C" language like formatting of the data stream. Where % formatting
* cmd`s are found in FormatString, they're replaced with the corresponding 
* element in the DataStream.
*
* Printf() outputs the results to the current output handle, usually the CLI.
********************************************************************************

printf:		tst.l	_PrtfBase(a4)
		beq.s	_NoPrint

		PUSH	d0-d3/a0-a3/a6

		lea	PrintChar(pc),a2
		move.l	_PrtfBase(a4),a3
		move.l	(a4),a6			;get execbase
		CALL	RawDoFmt

		move.l	_DOSBase(a4),a6
		move.l	_DOSOutput(a4),d1
		move.l	_PrtfBase(a4),d2
		move.l	d2,a3
		moveq	#-1,d3
.getlen		addq.l	#1,d3
		tst.b	(a3)+
		bne.s	.getlen
		CALL	Write

		PULL	d0-d3/a0-a3/a6
_NoPrint:	rts

PrintChar:	move.b	d0,(a3)+
		rts

*******************************************************************************
* _LoadDOSFile :- Loads an AmigaDOS file from any device into memory
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 (.L)	= Filename
*
* OUTPUTS:	d0 (.L) = Result Code (0=File Ok,-1=Load Failed!)	
*		d1 (.L) = Length
*******************************************************************************
	
LoadDOSFile:	movem.l	d2-d7/a0-a6,-(sp)
		clr.l	ProgHandle(a4)
		clr.l	ProgBuff(a4)
		clr.l	ProgSize(a4)

;-------------- Open file
		move.l	a0,d1			;get filename
		move.l	#MODE_OLDFILE,d2
		move.l	_DOSBase(a4),a6
		jsr	_LVOOpen(a6)		;open file
		move.l	d0,ProgHandle(a4)
		beq.s	NotFound

;-------------- Get Length of file

		move.l	d0,d5			;ProgHandle
		move.l	d5,d1			;file handle
		moveq	#0,d2
		moveq	#1,d3
		move.l	_DOSBase(a4),a6
		jsr	_LVOSeek(a6)		;seek start of file
		move.l	d5,d1			;file handle
		moveq	#0,d2
		moveq	#-1,d3
		jsr	_LVOSeek(a6)		;seek end of file
		move.l	d0,ProgSize(a4)

;-------------- Allocate Memory for file

		move.l	4.w,a6			;get execbase
		move.l	#MEMF_PUBLIC,d1		;we want public mem
		CALL	AllocMem		;allocate it...
		move.l	d0,ProgBuff(a4)		;save base
		beq.b	TooBig			;fail?

;-------------- Load in whole file
				
		move.l	ProgHandle(a4),d1
		move.l	d0,d2
		move.l	ProgSize(a4),d3
		move.l	_DOSBase(a4),a6
		jsr	_LVORead(a6)		;read file

;-------------- Close file

CloseFile:	move.l	ProgHandle(a4),d1
		jsr	_LVOClose(a6)		;close file

		move.l	ProgSize(a4),d1	;d1=ProgSize
		move.l	ProgBuff(a4),a1		

		movem.l	(sp)+,d2-d7/a0-a6
		moveq	#0,d0			;resultcode (okay)
		rts

NotFound:	movem.l	(sp)+,d2-d7/a0-a6
		move.b	#-1,d0			;file not found error-code
		rts

TooBig:
		move.l	ProgHandle(a4),d1
		move.l	_DOSBase(a4),a6
		jsr	_LVOClose(a6)		;close file
		movem.l	(sp)+,d2-d7/a0-a6
		move.b	#-2,d0			;file too big error-code
NotAlloc	rts

;-------------- Free Memory for DOSFile

FreeDOSFile:	move.l	(AbsExecBase).w,a6	;get execbase
		move.l	ProgBuff(a4),d0		;ptr to our RS.Variables base
		move.l	d0,a1
		beq.s	NotAlloc
		move.l	ProgSize(a4),d0		;no. of Bytes to free
		beq.s	NotAlloc
		jmp	_LVOFreeMem(a6)		;free the memory

*******************************************************************************
* SaveMem2File
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Inputs:	a0.l	= Filename
*		a1.l	= Mem Address
*		d0.l	= Save Length
*
* $Outputs:	d0.l	= 0 - success
*		d0.l	= 1 - failure
*******************************************************************************

SaveMem2File:	movem.l	d2-d7/a0-a6,-(sp)
		move.l	a0,d1			;filename
		move.l	a1,d5			;progbuffer
		move.l	d0,d6			;proglength
		move.l	#MODE_NEWFILE,d2
		move.l	_DOSBase(a4),a6
		jsr	_LVOOpen(a6)
		move.l	d0,d7
		beq.b	_SaveError
		move.l	d7,d1			;fh...
		move.l	d5,d2			;adr
		move.l	d6,d3			;length
		jsr	_LVOWrite(a6)		;write file
		move.l	d7,d1
		jsr	_LVOClose(a6)		;close file
		movem.l	(sp)+,d2-d7/a0-a6
		moveq	#0,d0
		rts
_SaveError:	movem.l	(sp)+,d2-d7/a0-a6
remcode		moveq	#1,d0
		rts

WriteFile:	movem.l	d0-d2/a0-a2/a4,-(sp)
		move.l	DestFilePt(pc),d1
		move.l	a1,d2
		move.l	d0,d3
		move.l	DTArea(pc),a4
		add.l	d3,ProLength(a4)
		move.l	_DOSBase(a4),a6
		CALL	Write
		movem.l	(sp)+,d0-d2/a0-a2/a4
		rts

Write4Bytes:	movem.l	d0-d2/a0-a2/a4,-(sp)
		move.l	DestFilePt(pc),d1
		lea	FourBytes(pc),a1
		move.l	a1,d2
		moveq	#4,d3
		move.l	DTArea(pc),a4
		add.l	d3,ProLength(a4)
		move.l	_DOSBase(a4),a6
		CALL	Write
		movem.l	(sp)+,d0-d2/a0-a2/a4
		rts


*******************************************************************************
* ProRunner to ProTracker Conversion...
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Inputs:	a0.l = Ptr to Packed Pro-Runner module to convert..
*		a1.l = Ptr to Filename..
*
* $Outputs:	d4.l = +0  (Successful)
*		       -1 (Aborted Saving)
*******************************************************************************

ConvertPR:	lea	DTArea(pc),a2
		move.l	a4,(a2)			;save DT Area
		clr.l	ProLength(a4)		;current size of PT-Module..

		move.l	a1,-(sp)
		move.l	a0,-(sp)
		move.l	a1,d1			;filename..
		move.l	#MODE_NEWFILE,d2
		move.l	_DOSBase(a4),a6
		CALL	Open
		lea	DestFilePt(pc),a0
		move.l	d0,(a0)
		beq.s	NoFilename

		move.l	(sp)+,a0		;a0=module memptr..
		move.l	(sp)+,a1		;a1=module filename
		
		lea	DTArea(pc),a2
		move.l	a4,(a2)		
		lea	TempBufferPt(pc),a2
		lea	TempBuffer(a4),a3
		move.l	a3,(a2)

		bsr	ConvertIt		;convert the module..

		move.l	DTArea(pc),a4

		move.l	DestFilePt(pc),d1
		move.l	_DOSBase(a4),a6
		CALL	Close			;close file

		move.l	ProLength(a4),d0	;d0.l = Unpacked Length
		lea	Unsize.Txt(pc),a0
		bsr	PutStr
		bsr	H2A

		move.l	ProLength(a4),d0
		sub.l	ProgSize(a4),d0		;d0.l = Lost bytes
		lea	Loss.Txt(pc),a0
		bsr	PutStr
		bra	H2A

NoFilename:	move.l	(sp)+,a0
		move.w	#$f0f,$dff180
		rts

DTArea:		dc.l	0
TempBufferPt:	dc.l	0

*******************************************************************************
* ProRunner to ProTracker Conversion...
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Inputs:	a0.l = Ptr to Packed Pro-Runner module to convert..
* $Outputs:	d4.l = 0  (Successful)
*		       -1 (Aborted Saving)
*******************************************************************************

ConvertIt:	cmp.l	#'SNT.',$43C(a0)	;ProRunner Method 1?
		beq.s	ProRun1
		cmp.l	#'SNT!',(a0)		;ProRunner-Method 2?
		beq	ProRun2
		rts

*-------------- SNT. Method 1

ProRun1:	moveq	#30,d0
		moveq	#0,d2
		lea	$14(a0),a2
pr1_1:		moveq	#0,d1
		move.w	$16(a2),d1
		lsl.l	#1,d1
		add.l	d1,d2
		lea	$1E(a2),a2
		dbra	d0,pr1_1
		move.b	$3B6(a0),d0
		move.l	#'M.K.',$43C(a0)
		lea	$3B8(a0),a2
		moveq	#0,d7
		moveq	#127,d1
pr1_2:		cmp.b	(a2)+,d7
		bcc.s	pr1_3

		move.b	-1(a2),d7
pr1_3:		dbra	d1,pr1_2
		addq.w	#1,d7
		mulu	#1024,d7
		lea	$43C(a0),a2
		lea	0(a2,d7.l),a1
pr1_4:		moveq	#0,d0
		move.b	(a2),d0
		and.b	#15,d0
		lsl.w	#4,d0
		add.b	d0,2(a2)
		moveq	#0,d0
		move.b	1(a2),d0
		add.w	d0,d0
		lea	PeriodTable(pc),a3
		move.w	0(a3,d0.l),d0
		move.w	(a2),d1
		and.w	#$F000,d1
		add.w	d0,d1
		move.w	d1,(a2)
		btst	#7,$BFE001
		beq	Aborted

		lea	4(a2),a2
		cmp.l	a2,a1
		bgt.s	pr1_4

		lea	0(a1,d2.l),a1
		sub.l	a0,a1
		move.l	a1,d0

;-------------- d0.l=Unpacked Length
		move.l	a0,a1
		bsr	WriteFile
		moveq	#0,d4
		rts

*-------------- SNT! Packed Method 2 Depacker

ProRun2:
*-------------- a1.l = full filepath
skipdrive:	move.l	a1,a3			;filename..
.skip1:		tst.b	(a1)
		beq.s	skipdir
		cmp.b	#":",(a1)+
		bne.s	.skip1

skipdir:	move.l	a3,a1
.skip2		tst.b	(a1)
		beq.s	skipmodext
		cmp.b	#"/",(a1)+
		bne.s	.skip2

skipmodext	move.l	a3,a1
skip3		tst.b	(a1)
		beq.s	skipped
		cmp.l	#"mod.",(a1)
		beq.s	isfound
		tst.b	(a1)+
		bra.s	skip3
isfound		tst.l	(a1)+
		bra.s	got_modname

skipped		move.l	a3,a1

got_modname:
		move.l	a1,a3

*-------------- a3.l = name of Pro-Tracker module... 
*		(without devices, directories or .mod extension)

		lea	FourBytes(pc),a1
		move.l	4(a0),a5
		add.l	a0,a5

		move.l	TempBufferPt(pc),a4
		move.b	#127,951(a4)

		moveq	#-1,d0
copyname:	addq.l	#1,d0
		cmp.b	#18,d0
		beq.s	limit
		move.b	(a3,d0.l),(a4,d0.l)
		bne.s	copyname
limit
		moveq	#30,d0
		moveq	#0,d1
		moveq	#0,d2
		lea	$14(a4),a3
samplenames:	moveq	#21,d4
		moveq	#" ",d3
.bytename:	move.b	d3,(a3,d4.l)
		dbra	d4,.bytename

		lea	$16(a3),a3
		move.l	8(a0,d1.l),(a3)+
		move.l	12(a0,d1.l),(a3)+
		moveq	#0,d3
		move.w	8(a0,d1.l),d3
		add.l	d3,d3
		add.l	d3,d2
		addq.w	#8,d1
		dbra	d0,samplenames

		lea	$100(a0),a2
		lea	$3B6(a4),a3
		move.w	(a2)+,(a3)+
		moveq	#0,d7
		moveq	#127,d1
cp2:		move.b	(a2),(a3)+
		cmp.b	(a2)+,d7
		bcc.s	cp3

		move.b	-1(a2),d7
cp3:		dbra	d1,cp2

*-------------- Write Pro-Tracker Header

		movem.l	d0-d7/a0-a6,-(sp)
		move.l	TempBufferPt(pc),a1
		move.l	#1080,d0
		bsr	WriteFile
		movem.l	(sp)+,d0-d7/a0-a6

*-------------- Write PT-Header..

		move.l	#'M.K.',(a1)
		bsr	Write4Bytes


		lea	$282(a0),a6
		lea	$302(a0),a4
pr2_2:		move.l	#$FF,d6
		move.l	TempBufferPt(pc),a1
		moveq	#0,d0
		move.w	(a6)+,d0
		lea	0(a4,d0.l),a2
pr2_3:		moveq	#0,d0
		move.b	(a2),d0
		bpl.s	pr2_5

		btst	#6,d0
		beq.s	pr2_4

		move.l	-$10(a1),(a1)+
		addq.w	#1,a2
		bra.s	pr2_6

pr2_4:		clr.l	(a1)+
		addq.w	#1,a2
		bra.s	pr2_6

pr2_5:		lsr.b	#1,d0
		and.b	#$3F,d0
		lea	PeriodTable(pc),a3
		add.w	d0,d0
		move.w	0(a3,d0.l),(a1)+
		moveq	#0,d0
		move.b	(a2),d0
		and.b	#1,d0
		moveq	#0,d1
		move.b	1(a2),d1
		lsr.b	#3,d1
		bclr	#0,d1
		or.b	d1,d0
		move.l	d0,d1
		and.b	#$F0,d1
		add.b	d1,-2(a1)
		and.b	#15,d0
		lsl.b	#4,d0
		move.b	d0,(a1)
		moveq	#15,d0
		and.b	1(a2),d0
		add.b	d0,(a1)+
		move.b	2(a2),(a1)+
		addq.w	#3,a2
pr2_6:		btst	#7,$BFE001
		beq.s	Aborted
		dbra	d6,pr2_3

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

		move.l	d7,d0
		addq.w	#1,d7			;d7.l= pattern counter...

;d0.l = Current pattern number..

*-------------- Save Converted pattern...

		move.l	TempBufferPt(pc),a1
		move.l	#$400,d0
		bsr	WriteFile
		movem.l	(sp)+,d0-d7/a0-a6

		btst	#7,$BFE001
		beq.s	Aborted
		dbra	d7,pr2_2

;d2.l = Sampledata size
		move.l	d2,d0
*-------------- Save Sample data

		move.l	a5,a1
		bsr	WriteFile

		moveq	#0,d4			;conversion successful..
		rts

Aborted:	moveq	#-1,d4			;conversion aborted!
		rts

FourBytes:	dc.l	0
DestFilePt:	dc.l	0

PeriodTable:	dc.w	0
		dc.w	$358
		dc.w	$328
		dc.w	$2FA
		dc.w	$2D0
		dc.w	$2A6
		dc.w	$280
		dc.w	$25C
		dc.w	$23A
		dc.w	$21A
		dc.w	$1FC
		dc.w	$1E0
		dc.w	$1C5
		dc.w	$1AC
		dc.w	$194
		dc.w	$17D
		dc.w	$168
		dc.w	$153
		dc.w	$140
		dc.w	$12E
		dc.w	$11D
		dc.w	$10D
		dc.w	$FE
		dc.w	$F0
		dc.w	$E2
		dc.w	$D6
		dc.w	$CA
		dc.w	$BE
		dc.w	$B4
		dc.w	$AA
		dc.w	$A0
		dc.w	$97
		dc.w	$8F
		dc.w	$87
		dc.w	$7F
		dc.w	$78
		dc.w	$71

*******************************************************************************

MainTags:	dc.l	ASL_Height,200				;height
		dc.l	ASL_Width,340				;width
		dc.l	TAG_DONE				;end of taglist

LoadTags:	dc.l	ASL_Hail,0				;loadtext ptr
		dc.l	ASL_FuncFlags,FILF_PATGAD
		dc.l	TAG_DONE				;end of taglist

SaveTags:	dc.l	ASL_Hail,0				;savetext ptr
		dc.l	ASL_FuncFlags,FILF_SAVE+FILF_PATGAD
		dc.l	TAG_DONE				;end of taglist

******************************************************************************
* String & Data Variable definitions

LoadText:	dc.b	'Load Module..',0
		even
SaveText:	dc.b	'Save Module..',0
		even
Aslname:	dc.b	'asl.library',0				;asl lib name
		even
Dosname:	dc.b	'dos.library',0				;dos lib name
		even
About.Txt:	CLS	; clear screen
		dc.b	CSI,'[0m',CSI,'[1mProRunner v2.3',CSI,'[0m ',CSI,'[3m',CSI,'[33m(For Conversion of ProTracker Modules to ProRunner & Back!) ',CSI,'[0m',LF
		dc.b	CSI,'[0mCopyright EX4 İ 1994. All Rights Are Reserved.',LF
		dc.b	'Written & Developed by 2-Cool/EX4!',LF,LF
		dc.b	0
		even
Select.Txt:	dc.b	'Please Select ProTracker Module to convert...',LF,LF
		dc.b	0
		even
ErrorType.txt	dc.b	$a,'Error: This is not a ProTracker Module!',$a,$a,0
		even
ErrorAlloc.txt	dc.b	$a,'Error: Out of Memory!',$a,0
		even
ErrorMem.txt	dc.b	$a,'Error: Not enough memory to load file!',$a,0
		even
ErrorASL.txt	dc.b	$a,'Error: The "asl.library" v36+ is required!',$a,$a,0
		even
ErrorLoad.txt	dc.b	$a,'Error: Cannot open file!',$a,$a,0
		even
ErrorSave.txt	dc.b	$a,'Error: Cannot save file!',$a,$a,0
		even
NoName.txt	dc.b	"You didn`t select a valid filename!",LF,LF
		dc.b	0
src.Txt:	dc.b	'Saving ProRunner Replayer Source-code...',LF,0
		even
docs.Txt:	dc.b	'Saving ProRunner Replayer Documentation...',LF,0
		even
both.Txt:	dc.b	LF,'Note: Please hold both mouse-buttons down to stop play-testing Module...',LF,0
		even
both5secs.Txt:	dc.b	LF,'Note: Please hold both mouse-buttons down for 5 seconds to stop playing...',LF,0
		even
FilePath.fmt	dc.b	"Attempting to Load '%s'...",LF,LF
		dc.b	0
		even
LengthPT.Txt:	dc.b	'Conversion Mode    : ProTracker Module -> ProRunner',LF
		dc.b	'Original Length    : ',0
LengthPR.Txt:	dc.b	'Conversion Mode    : ProRunner Module -> ProTracker',LF
		dc.b	'Original Length    : ',0
PakLength.Txt:	dc.b	'Packed Length      : ',0
Gained.Txt:	dc.b	LF,'Gained Bytes       : ',0
		even
Unsize.Txt:	dc.b	'Unpacked Length    : ',0
Loss.Txt:	dc.b	LF,'Lost Bytes !       : ',0
		even
Min.Txt:	dc.b	LF,'Average Rasters    : ',0
Max.Txt:	dc.b	'Maximum Rasters    : ',0

FilePath2.fmt	dc.b	"Attempting to Save '%s'..."
LFs.Txt:	dc.b	LF
		dc.b	0
		even
SaveOkay.Txt:	dc.b	'Saved, Operation was successful!',LF,LF,0
Value.txt:	ds.b	16
		even
Done.Txt:	dc.b	LF
		dc.b	'Done.',LF
		dc.b	0
		even
Args.Txt:	dc.b	'Usage   : ',CSI,'[32mProRunner ',CSI,'[31m<-opts> <source> <destination>',LF
		dc.b	LF
		dc.b	'Options : "',CSI,'[32m-s',CSI,'[31m"	 Save Pro-Runner replayer source..',LF
		dc.b	'	: "',CSI,'[32m-d',CSI,'[31m"	 Save Pro-Runner documentation..',LF
		dc.b	'	: "',CSI,'[32m-p',CSI,'[31m"	 Play any PT/PR-Module (multitasking)',LF
		dc.b	'	: "',CSI,'[32m-m',CSI,'[31m"	 Play & Measure Rasters of a PT/PR-Module (non-multitasking)',LF,LF
		
		dc.b	'Example : ',CSI,'[32mProRunner ',CSI,'[31mdf0:mod.test',LF
		dc.b	'        : ',CSI,'[32mProRunner ',CSI,'[31m-s work:ProRunner.asm',LF
		dc.b	'        : ',CSI,'[32mProRunner ',CSI,'[31m-d work:ProRunner.doc',LF
		dc.b	'        : ',CSI,'[32mProRunner ',CSI,'[31m-p df0:mod.test',LF
		dc.b	'        : ',CSI,'[32mProRunner ',CSI,'[31m-m df0:mod.test',LF
		dc.b	LF
		dc.b	'NB	: The play-testing modes plays either ProRunner or ProTracker modules',LF
		dc.b	'        : This is to test if it "plays" correctly in the new ProRunner format',LF
		dc.b	'        : before you proceed. If you let it play long enough using the "-m"',LF
		dc.b	'        : option it will report the max & min number of rasters needed.',LF,LF

		dc.b	'You will be prompted with the asl file-requester to select a ProTracker',LF
		dc.b	'module file to convert to ProRunner if you specify no filename(s).',LF,LF
		dc.b	0

pr_ln1:		ds.l	4
pr_flag1:	ds.b	138
pr_dabuf3:	ds.b	130
pr_dabuf:	ds.b	130
pr_ln2:		ds.b	128
pr_Wd1:		ds.w	1
pr_Wd2:		ds.w	1
pr_Wd3:		ds.w	1
pr_Long1:	ds.l	1
pr_OldLength:	ds.l	1
pr_Module:	ds.l	1
pr_pr_r3:	ds.l	1
pr_Buf1:	ds.l	$40
		even

docs:		incbin	work:ProRun.docs
docsend		even

***************
* TESTPROGRAM *
***************
PlayTest2:	lea	pr_module(pc),a0
		move.l	ProgBuff(a4),(a0)	
		move.l	a4,-(sp)
		bsr.w	pr_init
		move.l	(sp)+,a4

		move.l	_ExecBase(a4),a6
		jsr	-132(a6)		;forbid()

main:		cmp.b	#160,$dff006
		bne.s	main
main2:		cmp.b	#161,$dff006
		bls.s	main2

		move.w	#$f00,$dff180
		move.l	a4,-(sp)
		bsr.w	pr_music
		move.l	(sp)+,a4
		move.w	#$4,$dff180

		moveq.l	#0,d0
		move.b	$dff006,d0
		sub.w	#162,d0
		move.w	medraster(a4),d1
		add.w	d0,d1
		lsr.w	#1,d1
		move.w	d1,medraster(a4)

		cmp.w	maxraster(a4),d0
		bls.s	main3
		move.w	d0,maxraster(a4)
main3:		btst	#6,$bfe001
		bne.s	main

		move.l	a4,-(sp)
		bsr.w	pr_end	
		move.l	(sp)+,a4

		move.l	_ExecBase(a4),a6
		jmp	-138(a6)		;permit()





PlayTest:	lea	pr_module(pc),a0
		move.l	ProgBuff(a4),(a0)	
		move.l	a4,-(sp)
		bsr.w	pr_init
		move.l	(sp)+,a4

*-------------- Install Vertical Blank Interrupt Functions ----

		moveq	#5,d0
		lea	vbintserver(pc),a1
		lea	vbint(pc),a0
		move.l	a0,18(a1)		
		move.l	4.w,a6
		jsr	-168(a6)		;addintserver

no_out		move.l	_DOSBase(a4),a6
		moveq	#50,d1
		CALL	Delay

		btst	#2,$dff016		;RMB
		bne.s	no_out
		btst	#6,$bfe001		;LMB
		bne.s	no_out

*-------------- give user 4 seconds of holding before aborting..

		moveq	#50,d1
		CALL	Delay

		btst	#2,$dff016		;RMB
		bne.s	no_out
		btst	#6,$bfe001		;LMB
		bne.s	no_out

		
		lea	pr_musicfadedirection(pc),a0	; Now fading out...
		move.w	#-1,(a0)
main6:		lea	pr_musicfadect(pc),a0
		tst.w	(a0)
		bne.s	main6

*-------------- Remove OS Interrupt

		moveq	#5,d0
		lea	vbintserver(pc),a1
		move.l	4.w,a6
		jsr	-174(a6)		;remintserver

		move.l	a4,-(sp)
		bsr.w	pr_end	
		move.l	(sp)+,a4
		rts


vbint		movem.l	d0-d7/a0-a6,-(sp)
		bsr.w	pr_music
		movem.l	(sp)+,d0-d7/a0-a6
		rts

vbintserver	dc.l 0,0
		dc.b 2,0			; type, priority
		dc.l 0				;vbintname
		dc.l 0,0




*****************************************
*					*
* PRORUNNER V2.0			*
* --------------			*
* CODED BY COSMOS OF SANITY IN 1992	*
*					*
*****************************************
*					*
* Supporting the following effects:	*
*					*
*	- Running with 68010/20/30/40	*
*	- Using VBR-register		*
*	- Packed/Normal PT-Moduleformat	*
*	- Fade Sound in/out		*
*	- Variable Musicfadespeed	*
*	- Variable Interrupt-timing	*
*	- Finetune			*
*	- Normal play or Arpeggio	*
*	- Slide Frequenz up		*
*	- Slide	Frequenz down		*
*	- Tone Portamento		*
*	- Vibrato			*
*	- Tone Portamento+Volume Slide	*
*	- Vibrato + Volume Slide	*
*	- Tremolo			*
*	- Set SampleOffset		*
*	- Volume Slide			*
*	- Position Jump			*
*	- Set Volume			*
*	- Pattern Break			*
*	- Set Speed			*
* - E-Commands:				*
*	- Set Filter			*
*	- Fine Slide Up			*
*	- Fine Slide Down		*
*	- Glissando Control		*
*	- Set Vibrato Waveform		*
*	- Set Finetune			*
*	- Set Loop / Jump to Loop	*
*	- Set Tremolo Waveform		*
*	- Retrig Note			*
*	- Fine VolumeSlide Up		*
*	- Fine VolumeSlide Down		*
*	- NoteCut			*
*	- NoteDelay			*
*	- PatternDelay			*
*	- FunkRepeat			*
*					*
*****************************************

YES				EQU	1
NO				EQU	0
INCLUDEFADINGROUTINE		EQU	YES
PACKEDSONGFORMAT		EQU	YES
FADINGSTEPS			EQU	6	; ( 0< FADINGSTEPS <9 )
MAXVOLUME			EQU	2^FADINGSTEPS
INTERRUPTTIME			EQU	$180

SAMPLELENGTHOFFSET		EQU	4
SAMPLEVOLUMEOFFSET		EQU	6
SAMPLEREPEATPOINTOFFSET		EQU	8
SAMPLEWITHLOOP			EQU	12
SAMPLEREPEATLENGTHOFFSET	EQU	14
SAMPLEFINETUNEOFFSET		EQU	16

* Init-Routine *******************************************************

pr_init:
	lea	pr_framecounter(pc),a6
	move.w	#$7fff,pr_oldledvalue-pr_framecounter(a6)
	move.l	pr_module(pc),a0
	cmp.l	#0,a0
	bne.s	pr_init1
	rts
pr_init1:
	IFEQ	PACKEDSONGFORMAT-YES
	cmp.l	#'SNT!',(a0)
	beq.s	pr_init2
	ELSE
	cmp.l	#'M.K.',1080(a0)
	beq.s	pr_init2
	cmp.l	#'SNT.',1080(a0)
	beq.s	pr_init2
	ENDC
	rts
pr_init2:
	IFEQ	PACKEDSONGFORMAT-YES
	lea	8(a0),a1
	ELSE
	lea	20(a0),a1
	ENDC
	lea	pr_Sampleinfos(pc),a2
	moveq.l	#32,d7
	moveq	#30,d0
pr_init3:
	IFNE	PACKEDSONGFORMAT-YES
	lea	22(a1),a1		; Samplenamen überspringen
	ENDC
	move.w	(a1)+,SAMPLELENGTHOFFSET(a2)	; Samplelength in Words
	lea	pr_periods(pc),a3
	moveq	#$f,d2
	and.b	(a1)+,d2		; Finetuning
	mulu.w	#36*2,d2
	add.l	d2,a3
	move.l	a3,SAMPLEFINETUNEOFFSET(a2)
	moveq	#0,d1
	move.b	(a1)+,d1
	move.w	d1,SAMPLEVOLUMEOFFSET(a2)	; Volume
	moveq.l	#0,d1
	move.w	(a1)+,d1		; Repeatpoint in Bytes
	add.l	d1,d1
	move.l	d1,SAMPLEREPEATPOINTOFFSET(a2)
	move.w	(a1)+,d1
	clr.w	SAMPLEWITHLOOP(a2)
	cmp.w	#1,d1
	bls.s	pr_init3_2
	addq.w	#1,SAMPLEWITHLOOP(a2)
pr_init3_2:
	move.w	d1,SAMPLEREPEATLENGTHOFFSET(a2)	; Repeatlength
	add.l	d7,a2
	dbf	d0,pr_init3

	moveq	#0,d0
	IFEQ	PACKEDSONGFORMAT-YES
	move.b	256(a0),d0
	ELSE
	move.b	950(a0),d0		; Number of patterns
	ENDC
	subq.w	#1,d0
	move.w	d0,pr_highestpattern-pr_framecounter(a6)
	moveq.l	#0,d1
	lea	pr_Patternpositions(pc),a3
	IFEQ	PACKEDSONGFORMAT-YES
	lea	258(a0),a1		; 1.Patternpos
	lea	770(a0),a2		; 1.Patterndata
	lea	642(a0),a4		; 1.Patternoffset
pr_init4:
	moveq.l	#0,d2
	move.b	(a1)+,d2
	add.w	d2,d2
	move.w	(a4,d2.w),d2
	add.l	a2,d2
	move.l	d2,(a3)+
	dbf	d0,pr_init4
	ELSE
	lea	952(a0),a1		; 1. Patternpos
	lea	1084(a0),a2		; 1. Patterndata
pr_init4:
	move.b	(a1)+,d2		; x. Patternpos
	moveq.l	#0,d3
	move.b	d2,d3
	mulu.w	#1024,d3
	add.l	a2,d3
	move.l	d3,(a3)+
	dbf	d0,pr_init4
	ENDC

	IFEQ	PACKEDSONGFORMAT-YES
	move.l	4(a0),d2
	add.l	a0,d2
	ELSE
	lea	952(a0),a1
	moveq.l	#0,d1
	moveq	#127,d0
pr_init4_1:
	move.b	(a1)+,d2
	cmp.b	d1,d2			; Highest Pattern ?
	bls.s	pr_init4_2
	move.b	d2,d1
pr_init4_2:
	dbf	d0,pr_init4_1
	addq.w	#1,d1
	move.l	a0,d2
	mulu.w	#1024,d1		; Highest Pattern * 1024 Bytes
	add.l	#1084,d2
	add.l	d1,d2
	ENDC
	lea	pr_Sampleinfos(pc),a3
	lea	pr_Sampleinfos+SAMPLELENGTHOFFSET(pc),a2
	moveq.l	#32,d7
	move.l	d2,(a3)
	moveq	#29,d0
pr_init4_3:
	move.l	(a3),d1
	add.l	d7,a3
	moveq.l	#0,d2
	move.w	(a2),d2
	add.l	d7,a2
	add.l	d2,d2
	add.l	d2,d1
	move.l	d1,(a3)
	dbf	d0,pr_init4_3

	lea	pr_Sampleinfos(pc),a2
	lea	pr_Sampleinfos+SAMPLEREPEATPOINTOFFSET(pc),a3
	moveq.l	#32,d7
	moveq	#30,d0
pr_init4_4:
	move.l	(a2),d1
	add.l	d1,(a3)
	add.l	d7,a2
	add.l	d7,a3
	dbf	d0,pr_init4_4
	
	IFNE	PACKEDSONGFORMAT-YES
	
	cmp.l	#'SNT.',1080(a0)
	beq.s	pr_init7
	
	lea	1084(a0),a1
	move.l	pr_Sampleinfos(pc),a2
	move.b	#$f0,d6
	move.w	#$fff,d7
pr_init5:
	move.b	(a1),d0
	move.b	2(a1),d1
	move.w	(a1),d2
	and.w	d7,2(a1)
	and.w	d7,d2
	
	and.b	d6,d0
	lsr.b	#4,d1
	or.b	d1,d0
	move.b	d0,(a1)
	
	tst.w	d2
	beq.s	pr_init5_3
	lea	pr_periods(pc),a4
	moveq	#0,d1
pr_init5_2:
	addq.w	#1,d1
	cmp.w	(a4)+,d2
	bne.s	pr_init5_2
	move.b	d1,1(a1)
pr_init5_3:
	cmp.b	#$d,2(a1)
	bne.s	pr_init5_4

	moveq	#0,d1
	move.b	3(a1),d1
	moveq	#$f,d2
	and.w	d1,d2
	lsr.w	#4,d1
	mulu.w	#10,d1
	add.w	d2,d1
	cmp.b	#63,d1
	bls.s	pr_init5_3_2
	moveq	#63,d1
pr_init5_3_2:
	move.b	d1,3(a1)
pr_init5_4:
	addq.l	#4,a1
	cmp.l	a2,a1
	blt.s	pr_init5	

	move.l	#'SNT.',1080(a0)

	ENDC
	
pr_init7:
	lea	pr_Arpeggiofastlist(pc),a2
	lea	pr_Arpeggiofastlistperiods(pc),a1
	lea	35*2(a1),a1		; to the end of list...
	moveq	#0,d0
	moveq	#35,d1
	move.w	#999,d2
	moveq	#0,d6
pr_init8:
	move.w	-(a1),d7
	addq.w	#1,d6
pr_init8_2:
	cmp.w	d7,d0
	blt.s	pr_init8_4
	subq.w	#1,d1
	tst.b	d1
	bne.s	pr_init8
pr_init8_3:
	move.b	d1,(a2)+
	dbf	d2,pr_init8_3
	bra.s	pr_init8_5	
pr_init8_4:
	move.b	d1,(a2)+
	addq.w	#1,d0
	dbf	d2,pr_init8_2
pr_init8_5:

	lea	pr_Channel0(pc),a1
	move.w	#1,pr_Channel1-pr_Channel0(a1)
	move.w	#1,pr_Channel2-pr_Channel0(a1)
	move.w	#1,pr_Channel3-pr_Channel0(a1)
	move.w	#1,(a1)+
	moveq	#(pr_Channel1-pr_Channel0)/2-2,d0
pr_init9_2:
	clr.w	pr_Channel1-pr_Channel0(a1)
	clr.w	pr_Channel2-pr_Channel0(a1)
	clr.w	pr_Channel3-pr_Channel0(a1)
	clr.w	(a1)+
	dbf	d0,pr_init9_2

	lea	pr_fastperiodlist(pc),a1
	lea	pr_periods(pc),a2
	move.l	a2,(a1)
	moveq.l	#36*2,d1
	moveq	#14,d0
pr_init9_3:
	move.l	(a1)+,d2
	add.l	d1,d2
	move.l	d2,(a1)
	dbf	d0,pr_init9_3
		
	lea	pr_Arpeggiofastdivisionlist(pc),a1
	moveq	#0,d1
	move.w	#$ff,d0
pr_init9_4:
	move.b	d1,(a1)+
	subq.b	#1,d1
	bpl.s	pr_init9_4_2
	moveq	#2,d1
pr_init9_4_2:
	dbf	d0,pr_init9_4
	
	move.w	#6,pr_speed-pr_framecounter(a6)
	move.w	pr_speed(pc),(a6)
	clr.w	pr_Patternct-pr_framecounter(a6)
	move.w	pr_highestpattern(pc),d0
	move.w	pr_startposition(pc),d1
	blt.s	pr_init9_5
	cmp.w	d0,d1
	bls.s	pr_init9_5_2
pr_init9_5:
	clr.w	pr_startposition-pr_framecounter(a6)
pr_init9_5_2:
	move.w	pr_startposition(pc),pr_currentpattern-pr_framecounter(a6)
	
	lea	pr_Patternpositions(pc),a3
	move.l	a3,d0
	moveq.l	#0,d1
	move.w	pr_startposition(pc),d1
	lsl.l	#2,d1
	add.l	d1,d0
	move.l	d0,pr_Patternpt-pr_framecounter(a6)
	move.l	pr_Patternpt(pc),a5
	move.l	(a5),pr_Currentposition-pr_framecounter(a6)
	
	lea	$dff000,a5
	lea	$bfd000,a0
	move.w	#$2000,d0
	move.w	d0,$9a(a5)
	move.w	d0,$9c(a5)
	
	lea	pr_int(pc),a1
	move.l	pr_Vectorbasept(pc),a3
	move.l	a1,$78(a3)

	move.b	#$7f,$d00(a0)
	move.b	#$08,$e00(a0)
	move.w	#INTERRUPTTIME,d0
	move.b	d0,$400(a0)
	lsr.w	#8,d0
	move.b	d0,$500(a0)
pr_init10:
	btst	#0,$bfdd00
	beq.s	pr_init10
	move.b	#$81,$d00(a0)
	move.w	#$2000,$9c(a5)
	move.w	#$a000,$9a(a5)
	move.w	#$f,$96(a5)
	move.w	#$8000,pr_dmacon-pr_framecounter(a6)
	clr.w	$a8(a5)
	clr.w	$b8(a5)
	clr.w	$c8(a5)
	clr.w	$d8(a5)
	moveq	#0,d0
	move.b	$bfe001,d0
	move.w	d0,pr_oldledvalue-pr_framecounter(a6)
	bset	#1,$bfe001
	rts

* End-Routine *********************************************************

pr_end:
	lea	$dff000,a5
	move.w	#$f,$96(a5)
	clr.w	$a8(a5)
	clr.w	$b8(a5)
	clr.w	$c8(a5)
	clr.w	$d8(a5)
	move.w	#$2000,$9a(a5)
	move.w	pr_oldledvalue(pc),d0
	cmp.w	#$7fff,d0
	beq.s	pr_end3
	btst	#1,d0
	beq.s	pr_end2
	bset	#1,$bfe001
	rts
pr_end2:
	bclr	#1,$bfe001
pr_end3:
	rts

* Music-Fading ********************************************************

	IFEQ	INCLUDEFADINGROUTINE-YES
pr_fademusic:	macro
	lea	pr_musicfadect(pc),a0
	move.w	pr_musicfadedirection(pc),d0
	add.w	d0,(a0)
	cmp.w	#MAXVOLUME,(a0)
	bls.s	pr_fademusicend
	bgt.s	pr_fademusictoohigh
	clr.w	(a0)
	clr.w	pr_musicfadedirection-pr_musicfadect(a0)
	rts
pr_fademusictoohigh:
	move.w	#MAXVOLUME,(a0)
	clr.w	pr_musicfadedirection-pr_musicfadect(a0)
pr_fademusicend:
	endm

pr_musicfadect:		dc.w	MAXVOLUME
pr_musicfadedirection:	dc.w	0
	ENDC
	
* MACROS **************************************************************

pr_playchannel:	macro				; do not change: d7,a2-a6
		moveq	#0,d2
		moveq	#0,d0
		moveq	#0,d1
		IFEQ	PACKEDSONGFORMAT-YES
		move.b	(a6),d6
		bpl.s	.pr_playchannel1
		btst	#6,d6
		bne.s	.pr_playchannel0
		subq.l	#2,a6
		clr.w	4(a4)
		bra.s	.pr_playchannelend
.pr_playchannel0:		
		subq.l	#2,a6
		move.b	56(a4),d0
		move.b	57(a4),d1
		move.b	58(a4),d2
		move.w	58(a4),4(a4)
		bra.s	.pr_playchanneljump		
.pr_playchannel1:
		moveq	#$f,d0
		and.b	1(a6),d0
		move.b	d0,4(a4)
		move.b	d0,d2
		move.b	2(a6),5(a4)
		move.w	4(a4),58(a4)
		
		moveq	#1,d0
		and.b	(a6),d0
		move.b	1(a6),d1
		lsr.b	#3,d1
		bclr	#0,d1
		or.b	d1,d0
		move.b	d0,56(a4)		

		move.b	(a6),d1
		lsr.b	#1,d1
		move.b	d1,57(a4)
		ELSE
		move.w	2(a6),4(a4)
		move.b	2(a6),d2
		move.b	(a6),d0
		move.b	1(a6),d1
		ENDC
.pr_playchanneljump:
		add.w	d2,d2
		lea	pr_playchannellist(pc),a0
		move.w	(a0,d2.w),d2
		jsr	(a0,d2.w)
.pr_playchannelend:
		IFEQ	PACKEDSONGFORMAT-YES
		addq.l	#3,a6
		ELSE
		addq.l	#4,a6
		ENDC
		endm

pr_checkchannel:	macro			; do not change: d7,a2-a6
		bsr.w	pr_checkfunkrepeat
		moveq	#0,d0
		move.b	4(a4),d0
		add.b	d0,d0
		lea	pr_Effectchecklist(pc),a0
		move.w	(a0,d0.w),d0
		jsr	(a0,d0.w)
		endm
		
pr_copyplayvalues:	macro
		tst.w	pr_commandnotedelay-pr_framecounter(a2)
		bne.s	.pr_copyplayvalues2
		move.w	2(a4),6(a3)
.pr_copyplayvalues2:
		IFEQ	INCLUDEFADINGROUTINE-YES
		move.w	12(a4),d0
		mulu.w	pr_musicfadect-pr_framecounter(a2),d0
 		lsr.l	#FADINGSTEPS,d0
		move.w	d0,8(a3)
		ELSE
		move.w	12(a4),8(a3)
		ENDC
		endm

* Music-Routine *******************************************************

pr_music:
	IFEQ	INCLUDEFADINGROUTINE-YES
	pr_fademusic
	ENDC
	lea	$dff000,a5

	lea	pr_framecounter(pc),a2
	subq.w	#1,(a2)
	beq.s	pr_music2
	bra.w	pr_checkeffects
pr_music2:
	cmp.b	#1,pr_patterndelaytime-pr_framecounter+1(a2)
	blt.s	pr_music2_2
	bsr.w	pr_checkeffects
	bra.w	pr_music2_9
pr_music2_2:
	move.l	pr_Currentposition(pc),a6
	lea	pr_Channel0(pc),a4
	lea	$a0(a5),a3
	moveq	#1,d7
	pr_playchannel
	pr_copyplayvalues
pr_music2_3:	
	lea	pr_Channel1(pc),a4
	lea	$b0(a5),a3
	moveq	#2,d7
	pr_playchannel
	pr_copyplayvalues
pr_music2_4:
	lea	pr_Channel2(pc),a4
	lea	$c0(a5),a3
	moveq	#4,d7
	pr_playchannel
	pr_copyplayvalues
pr_music2_5:
	lea	pr_Channel3(pc),a4
	lea	$d0(a5),a3
	moveq	#8,d7
	pr_playchannel
	pr_copyplayvalues
	
	lea	pr_int(pc),a0
	move.l	pr_Vectorbasept(pc),a1
	move.l	a0,$78(a1)
	move.b	#$19,$bfde00

pr_music2_9:
	move.w	pr_speed(pc),(a2)
	tst.w	pr_patternhasbeenbreaked-pr_framecounter(a2)
	bne.s	pr_music3
	tst.w	pr_patterndelaytime-pr_framecounter(a2)
	beq.s	pr_music3_1
	subq.w	#1,pr_patterndelaytime-pr_framecounter(a2)
	beq.s	pr_music3_1
	bra.s	pr_nonextpattern
pr_music3:
	clr.w	pr_patternhasbeenbreaked-pr_framecounter(a2)
	tst.w	pr_patterndelaytime-pr_framecounter(a2)
	beq.s	pr_music3_1
	subq.w	#1,pr_patterndelaytime-pr_framecounter(a2)
pr_music3_1:
	lea	pr_Patternct(pc),a1
	tst.w	pr_dontcalcnewposition-pr_framecounter(a2)
	bne.s	pr_music3_2
	move.l	a6,pr_Currentposition-pr_framecounter(a2)
	addq.w	#1,(a1)
pr_music3_2:
	clr.w	pr_dontcalcnewposition-pr_framecounter(a2)
	moveq.l	#64,d1
	cmp.w	(a1),d1
	bgt.s	pr_nonextpattern
	sub.w	d1,(a1)
	lea	pr_currentpattern(pc),a0
	move.w	(a1),d1
	beq.s	pr_music3_3
	IFEQ	PACKEDSONGFORMAT-YES
	move.l	pr_module(pc),a1
	lea	386(a1),a1
	move.w	(a0),d1
	add.w	d1,d1
	move.w	(a1,d1.w),d1
	ELSE
	lsl.w	#4,d1
	ENDC
pr_music3_3:
	addq.l	#4,pr_Patternpt-pr_framecounter(a2)
	addq.w	#1,(a0)
	move.w	(a0),d0
	cmp.w	pr_highestpattern-pr_framecounter(a2),d0
	bls.s	pr_nohighestpattern
	lea	pr_Patternpositions(pc),a1
	move.l	a1,pr_Patternpt-pr_framecounter(a2)
	clr.w	(a0)
pr_nohighestpattern:
	move.l	pr_Patternpt-pr_framecounter(a2),a6
	move.l	(a6),d0
	add.l	d1,d0
	move.l	d0,pr_Currentposition-pr_framecounter(a2)
pr_nonextpattern:
	rts

	
pr_int:
	tst.b	$bfdd00
	move.b	#$19,$bfde00
	move.w	pr_dmacon(pc),$dff096
	move.w	#$2000,$dff09c
	move.l	a0,-(sp)
	move.l	pr_Vectorbasept(pc),a0
	add.l	#pr_int2-pr_int,$78(a0)
	move.l	(sp)+,a0
	rte

pr_int2:
	tst.b	$bfdd00
	movem.l	a5-a6,-(sp)
	lea	$dff000,a5
	lea	pr_Channel0+6(pc),a6
	move.l	(a6),$a0(a5)
	move.w	4(a6),$a4(a5)
	move.l	pr_Channel1-pr_Channel0(a6),$b0(a5)
	move.w	4+pr_Channel1-pr_Channel0(a6),$b4(a5)
	move.l	pr_Channel2-pr_Channel0(a6),$c0(a5)
	move.w	4+pr_Channel2-pr_Channel0(a6),$c4(a5)
	move.l	pr_Channel3-pr_Channel0(a6),$d0(a5)
	move.w	4+pr_Channel3-pr_Channel0(a6),$d4(a5)
	move.w	#$2000,$9c(a5)
	move.l	pr_Vectorbasept(pc),a6
	move.l	pr_old78(pc),$78(a6)
	movem.l	(sp)+,a5-a6
	rte
		
pr_playchannellist:
	dc.w	pr_playnormalchannel-pr_playchannellist		; 0
	dc.w	pr_playnormalchannel-pr_playchannellist		; 1
	dc.w	pr_playnormalchannel-pr_playchannellist		; 2
	dc.w	pr_playtpchannel-pr_playchannellist		; 3
	dc.w	pr_playnormalchannel-pr_playchannellist		; 4
	dc.w	pr_playtpchannel-pr_playchannellist		; 5
	dc.w	pr_playnormalchannel-pr_playchannellist		; 6
	dc.w	pr_playnormalchannel-pr_playchannellist		; 7
	dc.w	pr_playnormalchannel-pr_playchannellist		; 8
	dc.w	pr_playsochannel-pr_playchannellist		; 9
	dc.w	pr_playnormalchannel-pr_playchannellist		; A
	dc.w	pr_playnormalchannel-pr_playchannellist		; B
	dc.w	pr_playnormalchannel-pr_playchannellist		; C
	dc.w	pr_playnormalchannel-pr_playchannellist		; D
	dc.w	pr_playnormalchannel-pr_playchannellist		; E
	dc.w	pr_playnormalchannel-pr_playchannellist		; F
	
* KANAL NORMAL SPIELEN ************************************************

pr_playnormalchannel:
	lea	pr_Sampleinfos(pc),a0
	lea	(a0),a1
	lea	SAMPLEFINETUNEOFFSET(a1),a1
	clr.w	pr_commandnotedelay-pr_framecounter(a2)
	moveq	#-1,d4
	lsl.w	#4,d4
	and.w	4(a4),d4
	cmp.w	#$ed0,d4
	bne.s	pr_playnormalsamplenotedelay
	addq.w	#1,pr_commandnotedelay-pr_framecounter(a2)
pr_playnormalsamplenotedelay:
	tst.b	d0
	beq.w	pr_playnormalnonewsample	; Irgendein Sample ?
	move.w	d0,(a4)				; Trage Samplenummer ein
	tst.b	d1
	bne.s	pr_playnormalsample
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	addq.l	#6,a0
	move.w	(a0)+,12(a4)
	move.l	(a0)+,d2
	move.l	d2,6(a4)
	tst.w	(a0)+
	beq.s	pr_playnormalchannel2
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playnormalchannel2:
	move.w	(a0)+,10(a4)
	bra.w	pr_playnormalnonewperiod
pr_playnormalsample:
	or.w	d7,pr_dmacon-pr_framecounter(a2)
	tst.w	pr_commandnotedelay-pr_framecounter(a2)
	beq.w	pr_playnormalsamplenoedcom
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	move.w	6(a0),12(a4)
	move.l	8(a0),6(a4)
	move.w	14(a0),10(a4)
	bra.s	pr_playnormalnewperiod
pr_playnormalsamplenoedcom:
	move.w	d7,$96(a5)
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	move.l	(a0)+,(a3)		; Setze Samplestart
	move.w	(a0)+,4(a3)		; Setze Audiodatenlänge
	move.w	(a0)+,12(a4)		; Setze Samplelautstärke
	move.l	(a0)+,d2
	move.l	d2,6(a4)		; Samplerepeatpoint eintragen
	tst.w	(a0)+
	beq.s	pr_playnormalsample2
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playnormalsample2:
	move.w	(a0)+,10(a4)		; Samplerepeatlength eintragen
	bra.s	pr_playnormalnewperiod
pr_playnormalnonewsample:
	clr.l	14(a4)
	tst.b	d1
	beq.s	pr_playnormalnonewperiod	; Irgend ne neue Frequenz ?
	move.w	(a4),d0			; Alte Samplenummer holen
	or.w	d7,pr_dmacon-pr_framecounter(a2)
	tst.w	pr_commandnotedelay-pr_framecounter(a2)
	bne.s	pr_playnormalnewperiod
	move.w	d7,$96(a5)
pr_playnormalnonewsamplenoedcom:
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	move.l	(a0)+,(a3)		; Setze Samplestart
	move.w	(a0)+,4(a3)		; Setze Audiodatenlänge
	addq.l	#2,a0
	move.l	(a0)+,d2
	move.l	d2,6(a4)		; Samplerepeatpoint eintragen
	tst.w	(a0)+
	beq.s	pr_playnormalnonewsample2
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playnormalnonewsample2:
	move.w	(a0)+,10(a4)		; Samplerepeatlength eintragen
pr_playnormalnewperiod:
	subq.b	#1,d1
	add.b	d1,d1
	move.w	(a4),d0
	subq.b	#1,d0
	lsl.w	#5,d0
	move.l	(a1,d0.w),a1
	move.w	(a1,d1.w),2(a4)		; Frequenz eintragen
pr_playnormalnonewperiod:
	bra.w	pr_playeffect

* KANAL MIT OFFSET SPIELEN *********************************************

pr_playsochannel:
	lea	pr_Sampleinfos(pc),a0
	lea	(a0),a1
	lea	SAMPLEFINETUNEOFFSET(a1),a1
	tst.b	d0
	beq.w	pr_playsononewsample	; Irgendein Sample ?
	move.w	d0,(a4)				; Trage Samplenummer ein
	tst.b	d1
	bne.s	pr_playsosample
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	addq.l	#6,a0
	move.w	(a0)+,12(a4)
	move.l	(a0)+,d2
	move.l	d2,6(a4)
	tst.w	(a0)+
	beq.s	pr_playsochannel2
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playsochannel2:
	move.w	(a0)+,10(a4)
	bra.w	pr_playsononewperiod
pr_playsosample:
	move.w	d7,$96(a5)
	or.w	d7,pr_dmacon-pr_framecounter(a2)
	moveq.l	#0,d6
	move.b	5(a4),d6
	lsl.w	#7,d6
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	move.l	(a0)+,d2
	move.w	(a0)+,d3
	cmp.w	d3,d6
	bge.s	pr_playsosample2
	sub.w	d6,d3
	add.l	d6,d6
	add.l	d6,d2
	move.l	d2,(a3)			; Setze Samplestart
	move.w	d3,4(a3)		; Setze Audiodatenlänge
	move.w	(a0)+,12(a4)		; Setze Samplelautstärke
	move.l	(a0)+,d2
	move.l	d2,6(a4)		; Samplerepeatpoint eintragen
	tst.w	(a0)+
	beq.s	pr_playsosample1
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playsosample1:
	move.w	(a0)+,10(a4)		; Samplerepeatlength eintragen
	bra.w	pr_playsonewperiod
pr_playsosample2:
	move.w	(a0)+,12(a4)
	move.l	(a0),(a3)
	move.w	4(a0),4(a3)
	move.l	(a0)+,d2
	move.l	d2,6(a4)
	tst.w	(a0)+
	beq.s	pr_playsosample4
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playsosample4:
	move.w	(a0)+,10(a4)
	bra.s	pr_playsonewperiod
pr_playsononewsample:
	clr.l	14(a4)
	tst.b	d1
	beq.b	pr_playsononewperiod	; Irgend ne neue Frequenz ?
	move.w	(a4),d0			; Alte Samplenummer holen
	move.w	d7,$96(a5)
	or.w	d7,pr_dmacon-pr_framecounter(a2)
	moveq.l	#0,d6
	move.b	5(a4),d6
	lsl.w	#7,d6
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	move.l	(a0)+,d2
	move.w	(a0)+,d3
	cmp.w	d3,d6
	bge.s	pr_playsosample3
	sub.w	d6,d3
	add.l	d6,d6
	add.l	d6,d2
	move.l	d2,(a3)			; Setze Samplestart
	move.w	d3,4(a3)		; Setze Audiodatenlänge
	addq.l	#2,a0
	move.l	(a0)+,d2
	move.l	d2,6(a4)		; Samplerepeatpoint eintragen
	tst.w	(a0)+
	beq.s	pr_playsononewsample2
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playsononewsample2:
	move.w	(a0)+,10(a4)		; Samplerepeatlength eintragen
	bra.s	pr_playsonewperiod
pr_playsosample3:
	addq.l	#2,a0
	move.l	(a0),(a3)
	move.w	4(a0),4(a3)
	move.l	(a0)+,d2
	move.l	d2,6(a4)
	tst.w	(a0)+
	beq.s	pr_playsosample5
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playsosample5:
	move.w	(a0)+,10(a4)
	bra.w	pr_playsonewperiod
pr_playsonewperiod:
	subq.w	#1,d1
	add.b	d1,d1
	move.w	(a4),d0
	subq.b	#1,d0
	lsl.w	#5,d0
	move.l	(a1,d0.w),a1
	move.w	(a1,d1.w),2(a4)		; Frequenz eintragen
pr_playsononewperiod:
	bra.b	pr_playeffect

* Kanal spielen mit TONE PORTAMENTO **********************************

pr_playtpchannel:
	lea	pr_Sampleinfos(pc),a0
	lea	(a0),a1
	lea	SAMPLEFINETUNEOFFSET(a1),a1
	tst.b	d0
	beq.s	pr_playtpnonewsample	; Irgendein Sample ?
	move.w	d0,(a4)			; Trage Samplenummer ein
	subq.b	#1,d0
	lsl.l	#5,d0
	add.l	d0,a0
	addq.l	#6,a0
	move.w	(a0)+,12(a4)		; Lautstärke eintragen
	move.l	(a0)+,d2
	move.l	d2,6(a4)		; Repeatpoint eintragen
	tst.w	(a0)+
	beq.s	pr_playtpchannel2
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_playtpchannel2:
	move.w	(a0)+,10(a4)		; Repeatlength eintragen
pr_playtpnonewsample:
	tst.b	d1
	beq.s	pr_playtpnonewperiod	; Irgend ne neue Frequenz ?
pr_playtpnewperiod:
	move.w	2(a4),14(a4)
	subq.w	#1,d1
	add.b	d1,d1
	move.w	(a4),d0
	subq.b	#1,d0
	lsl.w	#5,d0
	move.l	(a1,d0.w),a1
	move.w	(a1,d1.w),d2
	move.w	d2,16(a4)		; Frequenz eintragen
	bra.s	pr_playtpallowed
pr_playtpnonewperiod:
	tst.w	16(a4)
	bne.s	pr_playtpallowed
	clr.w	14(a4)
	clr.l	26(a4)
pr_playtpallowed:
	bra.w	pr_playeffect

pr_playeffect:
	bsr.w	pr_checkfunkrepeat
	moveq	#0,d0
	move.b	4(a4),d0
	add.b	d0,d0
	lea	pr_normaleffectlist(pc),a0
	move.w	(a0,d0.w),d0
	jmp	(a0,d0.w)
pr_playnoeffect:
	rts

pr_normaleffectlist:
	dc.w	pr_playnoeffect-pr_normaleffectlist		; 0
	dc.w	pr_playnoeffect-pr_normaleffectlist		; 1
	dc.w	pr_playnoeffect-pr_normaleffectlist		; 2
	dc.w	pr_preptoneportamento-pr_normaleffectlist	; 3
	dc.w	pr_prepvibrato-pr_normaleffectlist		; 4
	dc.w	pr_playnoeffect-pr_normaleffectlist		; 5
	dc.w	pr_prepvibandvolslide-pr_normaleffectlist	; 6
	dc.w	pr_preptremolo-pr_normaleffectlist		; 7
	dc.w	pr_playnoeffect-pr_normaleffectlist		; 8
	dc.w	pr_playnoeffect-pr_normaleffectlist		; 9
	dc.w	pr_playnoeffect-pr_normaleffectlist		; A
	dc.w	pr_jumptopattern-pr_normaleffectlist		; B
	dc.w	pr_newvolume-pr_normaleffectlist		; C
	dc.w	pr_patternbreak-pr_normaleffectlist		; D
	dc.w	pr_play_e_command-pr_normaleffectlist		; E
	dc.w	pr_newspeed-pr_normaleffectlist			; F

pr_play_e_command:
	moveq	#0,d0
	move.b	5(a4),d0
	lsr.b	#3,d0
	bclr	#0,d0
	lea	pr_e_commandeffectlist(pc),a0
	move.w	(a0,d0.w),d0
	jmp	(a0,d0.w)
	
pr_e_commandeffectlist:
	dc.w	pr_setfilter-pr_e_commandeffectlist		; 0
	dc.w	pr_fineslideup-pr_e_commandeffectlist		; 1
	dc.w	pr_fineslidedown-pr_e_commandeffectlist		; 2
	dc.w	pr_setglissandocontrol-pr_e_commandeffectlist	; 3
	dc.w	pr_setvibratowaveform-pr_e_commandeffectlist	; 4
	dc.w	pr_playfinetune-pr_e_commandeffectlist		; 5
	dc.w	pr_jumptoloop-pr_e_commandeffectlist		; 6
	dc.w	pr_settremolowaveform-pr_e_commandeffectlist	; 7
	dc.w	pr_playnoeffect-pr_e_commandeffectlist		; 8
	dc.w	pr_prepretrignote-pr_e_commandeffectlist	; 9
	dc.w	pr_finevolumeslideup-pr_e_commandeffectlist	; A
	dc.w	pr_finevolumeslidedown-pr_e_commandeffectlist	; B
	dc.w	pr_prepnotecut-pr_e_commandeffectlist		; C
	dc.w	pr_prepnotedelay-pr_e_commandeffectlist		; D
	dc.w	pr_preppatterndelay-pr_e_commandeffectlist	; E
	dc.w	pr_prepfunkrepeat-pr_e_commandeffectlist	; F

pr_preppatterndelay:
	cmp.b	#1,pr_patterndelaytime-pr_framecounter+1(a2)
	bge.s	pr_preppatterndelayend
	moveq	#$f,d0
	and.b	5(a4),d0
	addq.b	#1,d0
	move.b	d0,pr_patterndelaytime-pr_framecounter+1(a2)
pr_preppatterndelayend:
	rts

pr_setvibratowaveform:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	d0,50(a4)
	rts

pr_settremolowaveform:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	d0,52(a4)
	rts

pr_setglissandocontrol:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	d0,48(a4)
	rts

pr_playfinetune:
	moveq	#$f,d0
	and.b	5(a4),d0
	lsl.w	#2,d0
	lea	pr_fastperiodlist(pc),a0
	move.l	(a0,d0.w),a0
	moveq	#0,d1
	IFEQ	PACKEDSONGFORMAT-YES
	move.b	(a6),d1
	lsr.b	#1,d1
	ELSE
	move.b	1(a6),d1
	ENDC
	beq.s	pr_playfinetuneend
	subq.b	#1,d1
	add.w	d1,d1
	move.w	(a0,d1.w),2(a4)		; Frequenz eintragen
pr_playfinetuneend:
	rts
	
pr_jumptoloop:
	moveq	#$f,d0
	and.b	5(a4),d0
	beq.s	pr_prepjumptoloop
	addq.b	#1,47(a4)
	cmp.b	47(a4),d0
	blt.s	pr_jumptoloopend
	moveq.l	#0,d0
	move.w	44(a4),d0
	move.w	d0,pr_Patternct-pr_framecounter(a2)
	move.l	pr_Patternpt(pc),a0
	move.l	(a0),d5
	IFEQ	PACKEDSONGFORMAT-YES
	moveq.l	#0,d0
	move.w	60(a4),d0
	ELSE
	lsl.l	#4,d0
	ENDIF
	add.l	d0,d5
	move.l	d5,pr_Currentposition-pr_framecounter(a2)
	addq.w	#1,pr_dontcalcnewposition-pr_framecounter(a2)
	rts
pr_jumptoloopend:
	clr.w	46(a4)
	rts
pr_prepjumptoloop:
	tst.w	46(a4)
	bne.s	pr_prepjumptoloopend
	move.w	pr_Patternct-pr_framecounter(a2),44(a4)
	IFEQ	PACKEDSONGFORMAT-YES
	move.l	pr_Currentposition(pc),d0
	move.l	pr_Patternpt(pc),a1
	sub.l	(a1),d0
	move.w	d0,60(a4)
	ENDC
	clr.w	46(a4)
pr_prepjumptoloopend:
	rts

pr_prepnotedelay:
	IFEQ	PACKEDSONGFORMAT-YES
	tst.b	57(a4)
	ELSE
	tst.b	1(a6)
	ENDC
	beq.s	pr_prepnotedelayend2

	moveq	#$f,d0
	and.b	5(a4),d0
	bne.s	pr_prepnotedelay2
	move.w	#$fff,18(a4)
	bra.w	pr_checknotedelay2
pr_prepnotedelay2:
	move.w	d7,d0
	not.b	d0
	and.b	d0,pr_dmacon-pr_framecounter+1(a2)
	clr.w	18(a4)
	rts
pr_prepnotedelayend2:
	move.w	#$fff,18(a4)
	rts

pr_prepretrignote:
	clr.w	18(a4)
	IFEQ	PACKEDSONGFORMAT-YES
	tst.b	56(a4)
	ELSE
	tst.w	(a6)
	ENDC
	bne.s	pr_prepretrignoteend
	bra.w	pr_checkretrignote2	
pr_prepretrignoteend:
	rts

pr_prepnotecut:
	clr.w	18(a4)
	moveq	#$f,d0
	and.b	5(a4),d0
	tst.b	d0
	bne.s	pr_prepnotecutend
	clr.w	12(a4)
pr_prepnotecutend:
	rts
	
pr_finevolumeslideup:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	12(a4),d1
	add.w	d0,d1
	moveq	#64,d0
	cmp.w	d0,d1
	bls.s	pr_finevolumeslideup2
	move.w	d0,d1
pr_finevolumeslideup2:
	move.w	d1,12(a4)
	rts

pr_finevolumeslidedown:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	12(a4),d1
	sub.w	d0,d1
	bpl.s	pr_finevolumeslidedown2
	moveq	#0,d1
pr_finevolumeslidedown2:
	move.w	d1,12(a4)
	rts

pr_fineslideup:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	2(a4),d1
	sub.w	d0,d1
	cmp.w	#108,d1
	bge.s	pr_fineslideup2
	move.w	#108,d1
pr_fineslideup2:
	move.w	d1,2(a4)
	rts

pr_fineslidedown:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	2(a4),d1
	add.w	d0,d1
	cmp.w	#907,d1
	bls.s	pr_fineslidedown2
	move.w	#907,d1
pr_fineslidedown2:
	move.w	d1,2(a4)
	rts

pr_setfilter:
	btst	#0,5(a4)
	beq.s	pr_setfilteron
pr_setfilteroff:
	bset	#1,$bfe001
	rts
pr_setfilteron:
	bclr	#1,$bfe001
	rts

pr_prepvibandvolslide:
	cmp.b	#1,pr_speed-pr_framecounter+1(a2)
	beq.s	pr_prepvibandvolslide2
	IFEQ	PACKEDSONGFORMAT-YES
	move.b	(a6),d1
	lsr.b	#1,d1
	ELSE
	tst.b	1(a6)
	ENDC
	beq.s	pr_prepvibandvolslide2
	clr.w	18(a4)
pr_prepvibandvolslide2:
	rts

pr_preptoneportamento:
	tst.b	5(a4)
	beq.s	pr_preptoneportamento2
	move.w	4(a4),22(a4)
pr_preptoneportamento2:
	rts

pr_prepvibrato:
	cmp.b	#1,pr_speed-pr_framecounter+1(a2)
	beq.s	pr_prepvibrato2
	IFEQ	PACKEDSONGFORMAT-YES
	move.b	(a6),d1
	lsr.b	#1,d1
	ELSE
	tst.b	1(a6)
	ENDC
	beq.s	pr_prepvibrato0
	clr.w	18(a4)
pr_prepvibrato0:
	move.b	5(a4),d0
	move.b	d0,d1
	lsr.b	#4,d1
	beq.s	pr_prepvibrato1
	move.b	d1,24(a4)
pr_prepvibrato1:
	and.b	#$f,d0
	beq.s	pr_prepvibrato2
	move.b	d0,25(a4)
pr_prepvibrato2:
	rts

pr_preptremolo:
	cmp.b	#1,pr_speed-pr_framecounter+1(a2)
	beq.s	pr_preptremolo2
	IFEQ	PACKEDSONGFORMAT-YES
	move.b	(a6),d1
	lsr.b	#1,d1
	ELSE
	tst.b	1(a6)
	ENDC
	beq.s	pr_preptremolo0
	clr.w	18(a4)
pr_preptremolo0:
	move.w	12(a4),20(a4)
	move.b	5(a4),d0
	move.b	d0,d1
	lsr.b	#4,d1
	beq.s	pr_preptremolo1
	move.b	d1,30(a4)
pr_preptremolo1:
	and.b	#$f,d0
	beq.s	pr_preptremolo2
	move.b	d0,31(a4)
pr_preptremolo2:
	rts

pr_newvolume:
	move.b	5(a4),d0
	cmp.b	#64,d0
	bls.s	pr_newvolumeend
	moveq	#64,d0
pr_newvolumeend:
	move.b	d0,13(a4)
	rts

pr_newspeed:
	move.b	5(a4),d0
	tst.b	d0
	bne.s	pr_newspeed2
	moveq	#1,d0
pr_newspeed2:
	move.b	d0,pr_speed-pr_framecounter+1(a2)
	rts

pr_patternbreak:
	moveq	#0,d0
	move.b	5(a4),d0
	add.w	#64,d0
	move.w	d0,pr_Patternct-pr_framecounter(a2)
	addq.w	#1,pr_patternhasbeenbreaked-pr_framecounter(a2)
	addq.w	#1,pr_dontcalcnewposition-pr_framecounter(a2)
	rts
		
pr_jumptopattern:
	moveq.l	#0,d0
	move.b	5(a4),d0
	subq.b	#1,d0
	bpl.s	pr_playjumptopattern2
	move.w	#128,d0
pr_playjumptopattern2:
	move.b	d0,pr_currentpattern-pr_framecounter+1(a2)
	lsl.l	#2,d0
	lea	pr_Patternpositions(pc),a0
	add.l	a0,d0
	move.l	d0,pr_Patternpt-pr_framecounter(a2)
	move.w	#64,pr_Patternct-pr_framecounter(a2)
	addq.w	#1,pr_patternhasbeenbreaked-pr_framecounter(a2)
	addq.w	#1,pr_dontcalcnewposition-pr_framecounter(a2)
	rts

* Control FX every frame **********************************************

pr_checkeffects:
	moveq	#1,d7
	lea	$a0(a5),a3
	lea	pr_Channel0(pc),a4
	move.w	12(a4),54(a4)
	pr_checkchannel
	IFEQ	INCLUDEFADINGROUTINE-YES
	move.w	54(a4),d0
	mulu.w	pr_musicfadect-pr_framecounter(a2),d0
	lsr.l	#FADINGSTEPS,d0
	move.w	d0,8(a3)
	ELSE
	move.w	54(a4),8(a3)
	ENDC
	
	moveq	#2,d7
	lea	$b0(a5),a3
	lea	pr_Channel1(pc),a4
	move.w	12(a4),54(a4)
	pr_checkchannel
	IFEQ	INCLUDEFADINGROUTINE-YES
	move.w	54(a4),d0
	mulu.w	pr_musicfadect-pr_framecounter(a2),d0
	lsr.l	#FADINGSTEPS,d0
	move.w	d0,8(a3)
	ELSE
	move.w	54(a4),8(a3)
	ENDC

	moveq	#4,d7
	lea	$c0(a5),a3
	lea	pr_Channel2(pc),a4
	move.w	12(a4),54(a4)
	pr_checkchannel
	IFEQ	INCLUDEFADINGROUTINE-YES
	move.w	54(a4),d0
	mulu.w	pr_musicfadect-pr_framecounter(a2),d0
	lsr.l	#FADINGSTEPS,d0
	move.w	d0,8(a3)
	ELSE
	move.w	54(a4),8(a3)
	ENDC

	moveq	#8,d7
	lea	$d0(a5),a3
	lea	pr_Channel3(pc),a4
	move.w	12(a4),54(a4)
	pr_checkchannel
	IFEQ	INCLUDEFADINGROUTINE-YES
	move.w	54(a4),d0
	mulu.w	pr_musicfadect-pr_framecounter(a2),d0
	lsr.l	#FADINGSTEPS,d0
	move.w	d0,8(a3)
	ELSE
	move.w	54(a4),8(a3)
	ENDC

	lea	pr_int(pc),a0
	move.l	pr_Vectorbasept(pc),a1
	move.l	a0,$78(a1)
	move.b	#$19,$bfde00
	rts

***********************************************************************

pr_checknotchannel:
	rts

pr_check_e_commands
	moveq	#0,d0
	move.b	5(a4),d0
	lsr.b	#3,d0
	bclr	#0,d0
	lea	pr_E_Command_checklist(pc),a0
	move.w	(a0,d0.w),d0
	jmp	(a0,d0.w)
	
pr_Effectchecklist:
	dc.w	pr_checkarpeggio-pr_Effectchecklist		; 0
	dc.w	pr_checkperiodslideup-pr_Effectchecklist	; 1
	dc.w	pr_checkperiodslidedown-pr_Effectchecklist	; 2
	dc.w	pr_checktoneportamento-pr_Effectchecklist	; 3
	dc.w	pr_checkvibrato-pr_Effectchecklist		; 4
	dc.w	pr_checktpandvolslide-pr_Effectchecklist	; 5
	dc.w	pr_checkvibandvolslide-pr_Effectchecklist	; 6
	dc.w	pr_checktremolo-pr_Effectchecklist		; 7
	dc.w	pr_checknotchannel-pr_Effectchecklist		; 8
	dc.w	pr_checknotchannel-pr_Effectchecklist		; 9
	dc.w	pr_checkvolumeslide-pr_Effectchecklist		; A
	dc.w	pr_checknotchannel-pr_Effectchecklist		; B
	dc.w	pr_checknotchannel-pr_Effectchecklist		; C
	dc.w	pr_checknotchannel-pr_Effectchecklist		; D
	dc.w	pr_check_e_commands-pr_Effectchecklist		; E
	dc.w	pr_checknotchannel-pr_Effectchecklist		; F

pr_E_Command_checklist:
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 0
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 1
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 2
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 3
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 4
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 5
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 6
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 7
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; 8
	dc.w	pr_checkretrignote-pr_E_Command_checklist	; 9
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; A
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; B
	dc.w	pr_checknotecut-pr_E_Command_checklist		; C
	dc.w	pr_checknotedelay-pr_E_Command_checklist	; D
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; E
	dc.w	pr_checknotchannel-pr_E_Command_checklist	; F

pr_prepfunkrepeat:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.b	d0,33(a4)
	tst.b	d0
	bne.s	pr_checkfunkrepeat
	rts
pr_checkfunkrepeat:
	move.w	32(a4),d0
	beq.s	pr_checkfunkrepeatend
	lea	pr_FunkTable(pc),a0
	move.b	(a0,d0.w),d0
	move.b	35(a4),d1
	add.b	d0,d1
	bmi.s	pr_checkfunkrepeat2
	move.b	d1,35(a4)
	rts
pr_checkfunkrepeat2:
	clr.b	35(a4)

	move.l	36(a4),d0
	beq.s	pr_checkfunkrepeatend
	move.l	d0,d2
	moveq.l	#0,d1
	move.w	10(a4),d1
	add.l	d1,d0
	add.l	d1,d0
	move.l	40(a4),a0
	addq.l	#1,a0
	cmp.l	d0,a0
	blo.s	pr_checkfunkrepeatok
	move.l	d2,a0
pr_checkfunkrepeatok:
	move.l	a0,40(a4)
	moveq	#-1,d0
	sub.b	(a0),d0
	move.b	d0,(a0)
pr_checkfunkrepeatend:
	rts

pr_checknotedelay:
	move.w	18(a4),d1
	addq.w	#1,d1
	cmp.w	d0,d1
	bne.s	pr_checknotedelayend
pr_checknotedelay2:
	move.w	d7,$96(a5)
	or.w	d7,pr_dmacon-pr_framecounter(a2)
	moveq.l	#0,d0
	move.w	(a4),d0
	subq.w	#1,d0
	lsl.w	#5,d0
	lea	pr_Sampleinfos(pc),a0
	add.l	d0,a0
	move.w	2(a4),6(a3)
	move.l	(a0)+,(a3)		; Setze Samplestart
	move.w	(a0)+,4(a3)		; Setze Audiodatenlänge
	addq.l	#2,a0
	move.l	(a0)+,d2
	move.l	d2,6(a4)		; Samplerepeatpoint eintragen
	tst.w	(a0)+
	beq.s	pr_checknotedelay3
	move.l	d2,36(a4)
	move.l	d2,40(a4)
pr_checknotedelay3:
	move.w	(a0)+,10(a4)		; Samplerepeatlength eintragen
pr_checknotedelayend:
	move.w	d1,18(a4)
	rts

pr_checkretrignote:
	moveq	#$f,d0
	and.b	5(a4),d0
	move.w	18(a4),d1
	addq.w	#1,d1
	cmp.w	d0,d1
	bne.s	pr_checkretrignoteend
pr_checkretrignote2:
	moveq	#0,d1
	move.w	d7,$96(a5)
	or.w	d7,pr_dmacon-pr_framecounter(a2)
	move.w	(a4),d0
	subq.w	#1,d0
	lsl.w	#5,d0
	lea	pr_Sampleinfos(pc),a0
	move.l	(a0,d0.w),(a3)
	move.w	4(a0,d0.w),4(a3)
pr_checkretrignoteend:
	move.w	d1,18(a4)
	rts

pr_checknotecut:
	moveq	#$f,d0
	and.b	5(a4),d0
	addq.w	#1,18(a4)
	move.w	18(a4),d1
	cmp.w	d0,d1
	blt.s	pr_checknotecutend
	clr.w	12(a4)
	clr.w	54(a4)
pr_checknotecutend:
	rts

pr_checkarpeggio:
	tst.b	5(a4)
	bne.s	pr_checkarpeggio0
	rts
pr_checkarpeggio0:
	move.w	(a2),d0
	lea	pr_Arpeggiofastdivisionlist(pc),a1
	move.b	(a1,d0.w),d0
	beq.s	pr_checkarpeggio2
	cmp.b	#2,d0
	beq.s	pr_checkarpeggio1
	moveq	#0,d0
	move.b	5(a4),d0
	lsr.b	#4,d0
	bra.s	pr_checkarpeggio3
pr_checkarpeggio2:
	move.w	2(a4),6(a3)
	rts
pr_checkarpeggio1:
	moveq	#$f,d0
	and.b	5(a4),d0
pr_checkarpeggio3:
	asl.w	#1,d0
	move.w	(a4),d1
	lsl.w	#5,d1
	lea	pr_Sampleinfos+SAMPLEFINETUNEOFFSET(pc),a0
	move.l	(a0,d1.w),a0
	move.w	2(a4),d1
	lea	pr_Arpeggiofastlist(pc),a1
	moveq.l	#0,d2
	move.b	(a1,d1.w),d2
	add.b	d2,d2
	add.l	d2,a0
	moveq	#36,d7
pr_checkarpeggioloop:
	cmp.w	(a0)+,d1
	bhs.s	pr_checkarpeggio4
	dbf	d7,pr_checkarpeggioloop
	rts
pr_checkarpeggio4:
	subq.l	#2,a0
	move.w	(a0,d0.w),6(a3)
	rts

pr_checktpandvolslide:
	bsr.w	pr_checkvolumeslide
	moveq	#0,d2
	move.b	23(a4),d2
	move.w	26(a4),d0
	move.w	28(a4),d1
	bsr.s	pr_checktoneportamento2
	move.w	14(a4),26(a4)
	rts
	
pr_checktoneportamento:
	moveq	#0,d2
	move.b	5(a4),d2
	bne.s	pr_checktoneportamento1
	move.b	23(a4),d2
pr_checktoneportamento1:
	move.w	14(a4),d0
	move.w	16(a4),d1
pr_checktoneportamento2:
	cmp.w	d0,d1
	bgt.s	pr_checktoneportamentoplus
	blt.s	pr_checktoneportamentominus
	cmp.w	#1,(a2)
	beq.s	pr_savetpvalues
	rts
pr_checktoneportamentoplus:
	add.w	d2,d0
	cmp.w	d0,d1
	bgt.s	pr_checktoneportamentoend
	move.w	d1,d0
	move.w	d1,14(a4)
	move.w	d1,2(a4)
	tst.w	48(a4)
	bne.s	pr_checktoneportamentoglissando
	move.w	d1,6(a3)
	cmp.w	#1,(a2)
	beq.s	pr_savetpvalues
	rts
pr_checktoneportamentominus:
	sub.w	d2,d0
	cmp.w	d0,d1
	blt.s	pr_checktoneportamentoend
	move.w	d1,d0
	move.w	d1,14(a4)
	move.w	d1,2(a4)
	tst.w	48(a4)
	bne.s	pr_checktoneportamentoglissando
	move.w	d1,6(a3)
	cmp.w	#1,(a2)
	beq.s	pr_savetpvalues
	rts
pr_checktoneportamentoend:
	move.w	d0,14(a4)
	move.w	d0,2(a4)
	tst.w	48(a4)
	bne.s	pr_checktoneportamentoglissando
	move.w	d0,6(a3)
	cmp.w	#1,(a2)
	beq.s	pr_savetpvalues
	rts	
pr_savetpvalues:
	move.l	14(a4),26(a4)
	rts
pr_checktoneportamentoglissando:
	move.w	(a4),d1
	lsl.w	#5,d1
	lea	pr_Sampleinfos+SAMPLEFINETUNEOFFSET(pc),a0
	move.l	(a0,d1.w),a0
	lea	pr_Arpeggiofastlist(pc),a1
	moveq.l	#0,d2
	move.b	(a1,d0.w),d2
	add.w	d2,d2
	add.l	d2,a0
	moveq	#0,d3
	moveq	#36*2,d1
pr_checktoneportamentoglissop:
	cmp.w	(a0,d3.w),d0
	bhs.s	pr_checktoneportamentoglissando2
	addq.w	#2,d3
	cmp.w	d1,d3
	blo.s	pr_checktoneportamentoglissop
	moveq	#35*2,d3
pr_checktoneportamentoglissando2:
	move.w	(a0,d3.w),6(a3)
	cmp.w	#1,(a2)
	beq.s	pr_savetpvalues
	rts

pr_checkvolumeslide:
	moveq	#0,d0
	move.b	5(a4),d0
	move.w	d0,d1
	lsr.b	#4,d1
	beq.s	pr_checkvolumeslidedown
	move.w	12(a4),d2
	add.w	d1,d2
	bmi.s	pr_checkvolumeslide0
	moveq	#64,d0
	cmp.w	d0,d2
	bgt.s	pr_checkvolumeslide64
	move.w	d2,12(a4)
	move.w	d2,54(a4)
	rts
pr_checkvolumeslidedown:	
	and.b	#$f,d0
	move.w	12(a4),d2
	sub.w	d0,d2
	bmi.s	pr_checkvolumeslide0
	moveq	#64,d0
	cmp.w	d0,d2
	bgt.s	pr_checkvolumeslide64
	move.w	d2,12(a4)
	move.w	d2,54(a4)
	rts
pr_checkvolumeslide64:
	move.w	d0,12(a4)
	move.w	d0,54(a4)
	rts
pr_checkvolumeslide0:
	clr.w	12(a4)
	clr.w	54(a4)
	rts
	
pr_checkperiodslidedown:
	moveq	#0,d0
	move.b	5(a4),d0
	add.w	d0,2(a4)
	cmp.w	#907,2(a4)
	bls.s	pr_checkperiodslidedown2
	move.w	#907,2(a4)
pr_checkperiodslidedown2:
	move.w	2(a4),6(a3)
	rts

pr_checkperiodslideup:
	moveq	#0,d0
	move.b	5(a4),d0
	sub.w	d0,2(a4)
	cmp.w	#108,2(a4)
	bge.s	pr_checkperiodslideup2
	move.w	#108,2(a4)
pr_checkperiodslideup2:
	move.w	2(a4),6(a3)
	rts

pr_checkvibandvolslide:
	bsr.w	pr_checkvolumeslide
	moveq.l	#0,d0
	moveq.l	#0,d1
	move.b	25(a4),d0
	move.b	24(a4),d1
	bra.s	pr_checkvibrato4

pr_checkvibrato:
	moveq.l	#0,d0
	moveq.l	#0,d1
	move.b	5(a4),d0	; Tiefe
pr_checkvibrato2:
	move.w	d0,d1		; Geschwindigkeit
	and.w	#$f,d0
	bne.s	pr_checkvibrato3
	move.b	25(a4),d0
pr_checkvibrato3:
	lsr.b	#4,d1
	bne.s	pr_checkvibrato4
	move.b	24(a4),d1
pr_checkvibrato4:
	move.w	18(a4),d2	;Position
	lsr.w	#2,d2
	and.w	#$1f,d2
	move.w	50(a4),d3
	beq.s	pr_checkvibratosine
	btst	#0,d3
	bne.s	pr_checkvibratorampdown
	move.b	#255,d3
	bra.s	pr_checkvibratoset
pr_checkvibratorampdown:
	lsl.b	#3,d2
	tst.b	19(a4)
	bmi.s	pr_checkvibratorampdown2
	move.b	#255,d3
	sub.b	d2,d3
	bra.s	pr_checkvibratoset
pr_checkvibratorampdown2:
	move.b	d2,d3
	bra.s	pr_checkvibratoset
pr_checkvibratosine:
	lea	pr_VibratoTable(pc),a0
	moveq	#0,d3
	move.b	(a0,d2.w),d3
pr_checkvibratoset:
	mulu.w	d0,d3
	lsr.w	#7,d3
	move.w	2(a4),d2
	tst.b	19(a4)
	bpl.s	pr_checkvibratoneg
	add.w	d3,d2
	bra.s	pr_checkvibrato5
pr_checkvibratoneg:
	sub.w	d3,d2
pr_checkvibrato5:
	move.w	d2,6(a3)
	lsl.w	#2,d1
	add.b	d1,19(a4)
	rts

pr_checktremolo:
	moveq	#0,d0
	moveq.l	#0,d1
	move.b	5(a4),d0	; Tiefe
pr_checktremolo2:
	move.w	d0,d1		; Geschwindigkeit
	and.w	#$f,d0
	bne.s	pr_checktremolo3
	move.b	31(a4),d0
pr_checktremolo3:
	lsr.b	#4,d1
	bne.s	pr_checktremolo4
	move.b	30(a4),d1
pr_checktremolo4:
	move.w	18(a4),d2	;Position
	lsr.w	#2,d2
	and.w	#$1f,d2
	move.w	52(a4),d3
	beq.s	pr_checktremolosine
	btst	#0,d3
	bne.s	pr_checktremolorampdown
	move.b	#255,d3
	bra.s	pr_checktremoloset
pr_checktremolorampdown:
	lsl.b	#3,d2
	tst.b	19(a4)
	bmi.s	pr_checktremolorampdown2
	move.b	#255,d3
	sub.b	d2,d3
	bra.s	pr_checktremoloset
pr_checktremolorampdown2:
	move.b	d2,d3
	bra.s	pr_checktremoloset
pr_checktremolosine:
	lea	pr_VibratoTable(pc),a0
	moveq	#0,d3
	move.b	(a0,d2.w),d3
pr_checktremoloset:
	mulu.w	d0,d3
	lsr.w	#6,d3
	move.w	20(a4),d2
	tst.b	19(a4)
	bpl.s	pr_checktremoloneg
	add.w	d3,d2
	moveq	#64,d4
	cmp.w	d4,d2
	bls.s	pr_checktremolo5
	move.w	d4,d2
	bra.s	pr_checktremolo5
pr_checktremoloneg:
	sub.w	d3,d2
	bpl.s	pr_checktremolo5
	moveq	#0,d2
pr_checktremolo5:
	move.w	d2,54(a4)
	lsl.w	#2,d1
	add.b	d1,19(a4)
	rts

pr_VibratoTable:	
	dc.b	0,24,49,74,97,120,141,161
	dc.b	180,197,212,224,235,244,250,253
	dc.b	255,253,250,244,235,224,212,197
	dc.b	180,161,141,120,97,74,49,24
pr_FunkTable:
	dc.b	0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128
	even
	
* Variables ***********************************************************

pr_module:			dc.l	0
pr_startposition:		dc.w	0
pr_speed:			dc.w	6
pr_highestpattern:		dc.w	0
pr_currentpattern:		dc.w	0
pr_framecounter:		dc.w	0
pr_patterndelaytime:		dc.w	0
pr_patternhasbeenbreaked:	dc.w	0
pr_Patternpositions:		ds.l	128
pr_Patternpt:			dc.l	0
pr_Currentposition:		dc.l	0
pr_Patternct:			dc.w	0
pr_oldledvalue:			dc.w	0
pr_dontcalcnewposition:		dc.w	0
pr_commandnotedelay:		dc.w	0
pr_old78:			dc.l	0
pr_Vectorbasept:		dc.l	0
pr_Channel0:			dc.w	1
				ds.w	30
pr_Channel1:			dc.w	1
				ds.w	30
pr_Channel2:			dc.w	1
				ds.w	30
pr_Channel3:			dc.w	1
				ds.w	30
pr_dmacon:			dc.w	$8000

pr_Arpeggiofastlist:		ds.b	1000
pr_Arpeggiofastdivisionlist:	ds.b	$100
pr_fastperiodlist:		ds.l	16
pr_Sampleinfos:			ds.b	32*32

pr_periods:
; Tuning 0, Normal
	dc.w	856,808,762,720,678,640,604,570,538,508,480,453
	dc.w	428,404,381,360,339,320,302,285,269,254,240,226
	dc.w	214,202,190,180,170,160,151,143,135,127,120,113
; Tuning 1
	dc.w	850,802,757,715,674,637,601,567,535,505,477,450
	dc.w	425,401,379,357,337,318,300,284,268,253,239,225
	dc.w	213,201,189,179,169,159,150,142,134,126,119,113
; Tuning 2
	dc.w	844,796,752,709,670,632,597,563,532,502,474,447
	dc.w	422,398,376,355,335,316,298,282,266,251,237,224
	dc.w	211,199,188,177,167,158,149,141,133,125,118,112
; Tuning 3
	dc.w	838,791,746,704,665,628,592,559,528,498,470,444
	dc.w	419,395,373,352,332,314,296,280,264,249,235,222
	dc.w	209,198,187,176,166,157,148,140,132,125,118,111
; Tuning 4
	dc.w	832,785,741,699,660,623,588,555,524,495,467,441
	dc.w	416,392,370,350,330,312,294,278,262,247,233,220
	dc.w	208,196,185,175,165,156,147,139,131,124,117,110
; Tuning 5
	dc.w	826,779,736,694,655,619,584,551,520,491,463,437
	dc.w	413,390,368,347,328,309,292,276,260,245,232,219
	dc.w	206,195,184,174,164,155,146,138,130,123,116,109
; Tuning 6
	dc.w	820,774,730,689,651,614,580,547,516,487,460,434
	dc.w	410,387,365,345,325,307,290,274,258,244,230,217
	dc.w	205,193,183,172,163,154,145,137,129,122,115,109
pr_Arpeggiofastlistperiods:
; Tuning 7
	dc.w	814,768,725,684,646,610,575,543,513,484,457,431
	dc.w	407,384,363,342,323,305,288,272,256,242,228,216
	dc.w	204,192,181,171,161,152,144,136,128,121,114,108
; Tuning -8
	dc.w	907,856,808,762,720,678,640,604,570,538,508,480
	dc.w	453,428,404,381,360,339,320,302,285,269,254,240
	dc.w	226,214,202,190,180,170,160,151,143,135,127,120
; Tuning -7
	dc.w	900,850,802,757,715,675,636,601,567,535,505,477
	dc.w	450,425,401,379,357,337,318,300,284,268,253,238
	dc.w	225,212,200,189,179,169,159,150,142,134,126,119
; Tuning -6
	dc.w	894,844,796,752,709,670,632,597,563,532,502,474
	dc.w	447,422,398,376,355,335,316,298,282,266,251,237
	dc.w	223,211,199,188,177,167,158,149,141,133,125,118
; Tuning -5
	dc.w	887,838,791,746,704,665,628,592,559,528,498,470
	dc.w	444,419,395,373,352,332,314,296,280,264,249,235
	dc.w	222,209,198,187,176,166,157,148,140,132,125,118
; Tuning -4
	dc.w	881,832,785,741,699,660,623,588,555,524,494,467
	dc.w	441,416,392,370,350,330,312,294,278,262,247,233
	dc.w	220,208,196,185,175,165,156,147,139,131,123,117
; Tuning -3
	dc.w	875,826,779,736,694,655,619,584,551,520,491,463
	dc.w	437,413,390,368,347,328,309,292,276,260,245,232
	dc.w	219,206,195,184,174,164,155,146,138,130,123,116
; Tuning -2
	dc.w	868,820,774,730,689,651,614,580,547,516,487,460
	dc.w	434,410,387,365,345,325,307,290,274,258,244,230
	dc.w	217,205,193,183,172,163,154,145,137,129,122,115
; Tuning -1
	dc.w	862,814,768,725,684,646,610,575,543,513,484,457
	dc.w	431,407,384,363,342,323,305,288,272,256,242,228
	dc.w	216,203,192,181,171,161,152,144,136,128,121,114
		even
src:		incbin	work:ProRun.src
srcend		even

docslen		=	docsend-docs
srclen		=	srcend-src
