*****************************************************************************
**                                                                         **
** Engine: 14 Bit Amplifier                                                **
**                                                                         **
** Project: Eagleplayer 2.04                                               **
** Authors: Jan Blumenthal & Henryk Richter                                **
** Start  : 1993/01/09                                                     **
** $Header$                                                                **
**                                                                         **
*****************************************************************************
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program (See the included file COPYING);
** if not, write to the Free Software Foundation, Inc.,
** 675 Mass Ave, Cambridge, MA 02139, USA.
**
***************************************************************************** 

* added by Eagleeye
*	-> Waitpointer
*	-> Iconify beim Start
; 2.8.: Iconify Flag bei "Show" ausgetestet
	;
	;
	incdir	include:
	include	exec/exec_lib.i
	include	exec/execbase.i
	include	exec/libraries.i
	include	exec/lists.i
	include	exec/memory.i
	include	exec/types.i
 	include	intuition/intuition.i
	include	intuition/intuition_LIB.i
	include	graphics/graphics_lib.i
	include	libraries/gadtools.i
	include	libraries/gadtools_lib.i
	include	dos/dos_lib.i
	include	libraries/dos.i
	include	misc/eagleplayer.i
	include	misc/eagleplayerengine.i
	include	misc/buggsmacros.i
	;
	section	0,code_p
	;
ver		macro
		dc.b	"0.96"
		endm
StructVer	macro
		dc.w	0,96
		endm
date		macro
		dc.b	"20-May-98"
		endm
StructDate	macro
		dc.b	20,05
		dc.w	1998
		endm

userprogram =	1
debug 	=	0
test	=	0		;topaz nehmen ?
SamLEN	=	160
Numbuffers	=	64	;Anzahl der Zwischenpuffer für Echo (2^n)
NumEchos	=	3
NumChipBuffers	=	6	;Anzahl der Puffer im Chipram (wg. FFT Analyzer)

PrefsVer	=	1 ;Jedes Mal, wenn Prefs-Strukturen  geändert werden, diesen erhöhen!!
benchmark	=	0 ;Vergleich der alten "Copybuffer"-Routinen mit den neuen
CPUtest		=	0 ;Wieviel CPU-Zeit braucht der "Mixer" ?

;----------------------- Noteplayer-spezifische Infos --------------------

ASLoopF_BackLooping	EQU	0
ASLoopF_Looping		EQU	1
ASLoopB_BackLooping	EQU	1<<ASLoopF_BackLooping
ASLoopB_Looping		EQU	1<<ASLoopF_Looping

Project0Width = 367		;Windowbreite (default bei Topaz 8)
Project0Height = 182
Project0Left = 41
Project0Top = 45
ZoomWidth = 200

GD_LISTVIEW                            EQU    0
GD_Samplefreq                          EQU    1
GD_MixingSlider                        EQU    2
GD_VBoost                              EQU    3
GD_Voices                              EQU    4
GD_NumVBoost                           EQU    5
GD_ChooseEcho                          EQU    6
GD_Delay                               EQU    7
GD_Active                              EQU    8
GD_Intensity                           EQU    9
GD_Cross                               EQU    10
GD_Gadget110                           EQU    11
Project0_CNT    EQU    12

 structure	my_liststruct,0
	struct	ML_Node,ln_size
	struct	ML_Nodename,60
	Label	ML_Sizeof

 structure	EchoStuct,0
	Byte	E_Enabled			;0=aus 1=an
	Byte	E_Delay				;Delay von 1 bis "Numbuffers"
	Byte	E_Volume			;von 0 bis 4 (=50,25,12.5,6.25,3.125 %)
	Byte	E_Special			;Spezialeffekt, z.B. Cross Echo (=1)
	Label	Echo_Sizeof

 structure	Prefsblock,0
	Long	P_Mixrate
	Word	P_Vboost
	Word	P_Flags			;(Bit0=disable)
	Struct	P_Echos,Echo_Sizeof*NumEchos
	Label	P_Sizeof

 structure	my_Prefs,0
	struct	P_Blocks,P_Sizeof*32	;max. Stimmen
	Label	my_Prefs_Sizeof

;------------------------------------------------------------------------
begin
****************** Workbench Startup **********************************
	bra.w	fang
	EUSN_Identifier
	dc.l	0		;eus_next

	ifne	debug
	dc.w	-2
	else
	dc.w	0		;eus_Usernr
	endc
MyEPBase
	dc.l	0		;eus_EPBase
	dc.l	0		;eus_Freetable
	dc.l	0		;eus_Taskadr
	dc.l	0		;eus_unused1
	dc.l	0		;eus_unused2
	dc.l	SpecialJumps	;EUS_SpecialJumpTab
	dc.l	TagListe	;EUS_TagList
	dc.w	0		;eus_ticks
	dc.w	0		;eus_tickcounter
	dc.l	0		;eus_tickflags
;	dc.l	USMB_WaitPointer!USMB_KillModule!USMB_Zipwin!USMB_ChangeConfig!USMB_newsong!USMB_NewModule;eus_msgflags
	dc.l	USMB_Configuration!USMB_KillModule!USMB_Zipwin!USMB_ChangeConfig	;eus_msgflags
	dc.l	MyAnalyzername	;eus_PName
	dc.l	myBuggsname
	dc.l	myinfo
	dc.w	39		;eus_Kickstart
	dc.l	Eagleversion	;eus_EPVersion
	StructVer		;eus_version,revision
	dc.l	MyUsername	;eus_username
	dc.w	Project0left	;eus_winx
	dc.w	Project0top	;eus_winy
	dc.w	EUSB_Show!EUSB_Activate	;window opened
	dc.w	127		;pri
	dc.w	0		;flags
	dc.l	0		;EUS_Special2
	dc.l	0		;EUS_Special3

	StructDate		;EUS_Creatordate
	dc.b	0		;EUS_Priority

	dc.b	EUTY_Amplifier	;EUS_Type

	dc.w	0		;EUS_Reserved2
	dc.l	`14BT`		;EUS_Reserved3;EUS_AMIDNr
	dc.l	0		;EUS_Reserved4
	dc.l	MyUPSStruct	;EUS_Reserved5
	dc.l	0		;EUS_Reserved6

		ifne	(*-begin)-EUS_SizeOF
		Aber Hallo
		endc

TagListe:
	dc.l	EUT_EPSubItems,EP_Menu
	dc.l	EUT_SpecialinfoLNr,LNrE_SpecialInfo_14BitAmplifier
	dc.l	EUT_AttnFlags,AFF_68020
	dc.l	TAG_Done

	dc.b	"$VER: Eagleplayer_14Bit_32Voices_Amplifier "
	ver
	dc.b	" "
	date
	dc.b	0
	even
SpecialJumps
	dc.l	Checkfeatures	;AMJ_CheckFeatures, Test ob Anforderungen des Replays erfüllt werden können
	dc.l	Init	;AMJ_Init	;Übergabe der Struktur/test&Init
	dc.l	StartInt;AMJ_StartInt	;Alloc Audio & Start Int
	dc.l	Stopint	;AMJ_StopInt	;Free Audio & Stop Int
	dc.l	End	;AMJ_End	;Mem freigeben, etc.
	dc.l	Copy_AS	;AMJ_Amplifier
	dc.l	0	;AMJ_PokeAdr	;nur für Amplifier initialisieren,
	dc.l	0	;AMJ_PokeLen	;die auf die Hardware poken, wie
	dc.l	0	;AMJ_PokePer	;z.B. der Chipram Player, sonst
	dc.l	0	;AMJ_PokeVol	;auf 0 setzen, diese Jumps werden mit
	dc.l	0	;AMJ_DMAMask	;den selben Parametern aufgerufen, wie
					;die ENPP_Poke...
	dc.l	0	;AMJ_Command	;z.B. Filter
Fang
	move.l	4.w,a6

;	ifeq	V37Gadtools
	cmp.w	#39,lib_version(a6)
	bge.s	.do39
;	endc

	subq	#6,NG_Listview+6
.do39

	move.l	ex_EClockFrequency(a6),d0
	move.l	d0,d1
	add.l	d0,d0
	add.l	d0,d0
	add.l	d1,d0
	move.l	d0,Audiorate

	lea	datas,a5
	move.l	a5,a0
	move.w	#dataslen-1,d0
.clr	move.b	#0,(a0)+
	dbf	d0,.clr

	move	#-1,Currentnumvoc(a5)		;kein Modul am Spielen
	move.l	#-1,Oldint0

	bsr	LoadCalibration
	bsr	Loadconfig
	move	PrefsVersion(A5),d0
	cmp.w	#`EP`,d0
	bne	.def
	move	PrefsVersion+2(A5),d0
	cmp	#PrefsVer,d0
	beq	.useprefs
.def
	move	#Project0Left,WinPosX(a5)
	move	#Project0Top,WinPosY(a5)
	clr.l	ZoomPosX(A5)
	clr.b	Zoomstate(A5)

	move	#`EP`,Prefsversion(A5)
	move	#Prefsver,Prefsversion+2(A5)

	bsr	Makedefaults			;Default prefs setzen
.useprefs
	st	onsysfont(A5)

	moveq	#-1,d0
	jsr	_LVOallocsignal(a6)	;Signal allokieren
	move.l	d0,mysignal(a5)
	blt	NoSignal

	suba.l	A1,A1
	JSR	_LVOfindtask(A6)
	move.l	d0,mytask(a5)

	lea	dos(pc),a1
	moveq	#37,d0			;Brauchen DOS V1.2,für Message,falls
	jsr	_LVOopenlibrary(a6)	;Start von 1.2/1.3 aus
	move.l	d0,_dos(a5)
	beq	NODOS

	lea	MsgPort1(a5),a4		;MSG Port Struktur initialisieren
	bsr	MakeMsgPort
	tst.l	d0
	blt	NoPort
	move.l	a4,MsgPort(A5)

	lea	int(pc),a1
	moveq	#37,d0
	jsr	_LVOopenlibrary(a6)
	move.l	d0,intsave(a5)
	beq	NOINT

	lea	graf(pc),a1
	moveq	#37,d0
	jsr	_LVOopenlibrary(a6)
	move.l	d0,grafsave(a5)
	beq	NOGraf

	lea	gad(pc),a1
	moveq	#37,d0
	jsr	_LVOopenlibrary(a6)
	move.l	d0,gadsave(a5)
	beq	NoGadTo

	moveq	#0,d7

	bsr	sendfirstmessage	;Message an Eagleplayer senden,daß
					;der Analyzer gern mal die Struktur-
					;Adresse haben möchte
	blt	endme	;Fehler aufgetreten

	bsr	HandleActions		;Auf Usereingaben reagieren

	tst.l	d7
	blt.s	endme
	bsr	sendlastmessage
endme
	bsr	closedownwin
	bsr	closedownscreen
nopubscreen
Nogadgets
nowin
	move.l	gadsave(a5),a1
	move.l	4,a6
	jsr	_LVOcloselibrary(A6)
	clr.l	gadsave(A5)
nogadto
	move.l	grafsave(a5),a1
	move.l	4,a6
	jsr	_LVOcloselibrary(a6)
NoGraf
	move.l	intsave(a5),a1
	move.l	4,a6
	jsr	_LVOcloselibrary(a6)
noint
	move.l	4,a6
	lea	msgport1(a5),a2
	move.b	mp_sigbit(a2),d0
	ext.w	d0
	ext.l	d0
	jsr	_LVOfreesignal(a6)
NoPort
	move.l	4,a6
	move.l	_dos(a5),a1
	jsr	_LVOcloselibrary(a6)
nodos
Endprog
	move.l	mysignal(a5),d0
	move.l	4,a6
	jsr	_LVOfreesignal(a6)
NoSignal
	moveq	#0,d0
	rts

MakeMsgPort
					;Message Port initialisieren
	move.l	4.w,a6
	moveq	#-1,d0
	jsr	_LVOallocsignal(a6)	;MSG Signal zuweisen lassen
	tst.l	d0
	blt	.nosignal2		;Fehler

	move.b	#nt_msgport,ln_type(a4)
	move.b	#0,ln_pri(a4)
	move.b	#pa_signal,mp_flags(a4)
	move.b	d0,mp_sigbit(a4)

	move.l	mytask(a5),mp_sigtask(a4);mp_SigTask

	lea	mp_msglist(a4),a1
	Newlist	a1			;macro in Lists.i

	moveq	#0,d0
.nosignal2				;Fehler
	rts
********************************************************************
*                  Init & Open Window                              *
********************************************************************
Openwin
	tst.l	winhandle(A5)
	bne.w	.endme

	clr.l	port(A5)

	move.l	intsave(a5),a6
	bsr	Setupscreen		;Public Screen holen
	bne	.Endme
	bsr	SetUpWin		;Fenster öffnen
	tst.l	d0
	bne	.Endme

	bsr	drawbevel

	move.l	Winhandle(a5),a0
	move.l	wd_userport(a0),a0	;User Port
	move.l	a0,port(a5)
.endme
RTSA
	rts
DrawBevel
	move.l	gadsave(A5),a6
	move.l	winhandle(A5),a0
	move.w	wd_height(a0),d0
	cmp	offy(a5),d0
	beq.s	rtsA

	move.l  wd_RPort(a0),a2
	lea.l   IR(pc),a1
	move.l  Vi(a5),4(a1)

	move.w  #58,d0
	bsr	ComputeY
	move.w  offy(a5),d1
	add.w	d0,d1

	move.w	#358,d0
	bsr	ComputeX
	move.w	d0,d2

	move.w	#57,d0
	bsr	ComputeY
	move.w	d0,d3

	move.w  #4,d0
	bsr	ComputeX
	add.w   offx(A5),d0

	move.l  a2,a0
	jsr     _LVODrawBevelBoxA(a6)

	move.l  a2,a0
	lea.l   IR(pc),a1

	move.w  #116,d0
	bsr	ComputeY
	move.w  offy(a5),d1
	add.w	d0,d1

	move.w  #358,d0
	bsr	ComputeX
	move.w	d0,d2

	move.w  #62,d0
	bsr	ComputeY
	move.w	d0,d3

	move.w  #4,d0
	bsr	ComputeX
	add.w	offx(a5),d0
	jmp     _LVODrawBevelBoxA(a6)
ClearWin:
	move.l	winhandle(A5),a1
	move.w	wd_height(a1),d0
	cmp	offy(a5),d0
	beq.w	rtsA

	move.l	grafsave(a5),a6
	move.l	wd_rport(a1),a1
	moveq	#0,d0
	jsr	_LVOsetapen(A6)

	move.l	winhandle(A5),a1
	move.l	wd_rport(a1),a1
	moveq	#0,d0
	jsr	_LVOsetbpen(A6)

	move.l	winhandle(A5),a1
	move.l	wd_rport(a1),a1
	moveq	#1,d0			;RP_Jam2
	jsr	_LVOsetdrmd(A6)

	move.b	rp_areaptsz(a1),d4
	move.l	rp_areaptrn(a1),d5

	move.l	winhandle(A5),a1
	move.w	wd_width(A1),d2		;x2
	moveq	#0,d0
	move.b	wd_borderright(a1),d0
	sub.w	d0,d2

	move.w	wd_height(a1),d3
	moveq	#0,d0
	move.b	wd_borderbottom(a1),d0
	sub.w	d0,d3

	move.l	wd_rport(a1),a1

	move.w	offx(a5),d0		;x1
	move.w	offy(A5),d1		;y1
	jsr	_LVOrectfill(a6)

	move.l	winhandle(A5),a0
	move.l	intsave(a5),a6
	jsr	_LVOrefreshwindowframe(A6)
	rts
*************** Window & Screen freigeben *************************
Closewin
	bsr	closedownwin
	bra	closedownscreen
********************************************************************
*                  Init Message Struktur                           *
********************************************************************
Sendfirstmessage
	move.l	4,a6
	lea	Portname(pc),a1
	jsr	_LVOfindport(a6)
	tst.l	d0
	beq.s	.error

	move.l	d0,a0			;Portadresse

	move.l	msgport(a5),d3
	move.l	mytask(a5),d4
	move.l	#-1,d5
	move.w	#USclass_Newuserprg,d6

	ifne	debug

	bsr	allocmsg
	beq.s	.error
	move.l	d0,a1			;Messageadresse

	move.w	#UM_sizeof-20,mn_length(a1)
	move.b	#nt_message,ln_type(a1) ;Message-Typ
	lea	begin(pc),a2
	move.l	a2,um_result(a1)
	move.w	#-2,UM_UserNr(a1)
	move.l	#USM_Userprg,UM_Type(a1)

	move.l	d3,mn_replyport(a1)	;Portadresse,an die
						;zurückgesendet wird
	move.l	d3,UM_Userport(a1)
	move.l	d4,UM_TaskAdr(a1)
	move.l	d5,UM_Signal(a1)
	move.w	d6,UM_class(a1)

	move.l	4,a6
	jsr	_LVOputmsg(a6)

	else
	bsr	sendmess
	endc

	moveq	#0,d7
	rts
.error
	moveq	#-1,d7
	rts
*******************************************************************************
sendmess:
	bsr	allocmsg
	bne.s	.ok
	rts
.ok
	move.l	d0,a1			;Messageadresse

	move.w	#UM_sizeof-20,mn_length(a1)
	move.b	#nt_message,ln_type(a1) ;Message-Typ

	ifne	debug
	move.w	saveusernr(a5),UM_UserNr(a1)
	else
	lea	begin(pc),a2
	move.w	EUS_Usernr(A2),UM_UserNr(a1)
	endc

	move.l	#USM_Userprg,UM_Type(a1)

	move.l	d3,mn_replyport(a1)	;Portadresse,an die
						;zurückgesendet wird
	move.l	d3,UM_Userport(a1)
	move.l	d4,UM_TaskAdr(a1)
	move.l	d5,UM_Signal(a1)
	move.w	d6,UM_class(a1)

	move.l	4,a6
	jmp	_LVOputmsg(a6)
******************************************************************************
* Abschiedsgruß an Eagleplayer,der dann weiß,daß der Analyzer geendet hat    *
******************************************************************************
Sendlastmessage:
	move.l	4,a6
	lea	Portname(pc),a1	;EaglePlayer finden
	jsr	_LVOfindport(a6)
	tst.l	d0
	beq.w	.ok	;Eagleplayer hat sich schon verabschiedet

	move.l	d0,a0			;Portadresse
	move.l	msgport(a5),d3
	moveq	#0,d4
	moveq	#0,d5
	move.w	#USclass_exit,d6

	bsr	sendmess
.wait
	move.l	MSGport(a5),a0
	jsr	_LVOwaitport(a6)
	move.l	MSGport(a5),a0
	jsr	_LVOgetmsg(a6)
	tst.l	d0
	beq.s	.wait
	move.l	d0,a1
	cmp.l	#USM_Userprg,UM_Type(a1)
	beq.s	.meine
.nichtmeine
	jsr	_LVOreplymsg(a6)
	bra.s	.wait
.meine
.ok
	rts
*******************************************************************
*      Public Screen ranholen und Visual Info anfordern           *
*******************************************************************
SetupScreen
	move.l	Intsave(a5),a6
	lea	begin(pc),a0
	move.l	eus_epbase(a0),d0
	beq.s	.noep
	move.l	d0,a0
	move.l	EPG_Pubscreen(A0),d0
	move.w	EPG_Wordreserved7(A0),word7(A5)
.noep
	move.l	d0,a0
	jsr	_LVOLockPubScreen(a6)
	move.l	d0,MyPubscreen(A5)
	tst.l	d0
	beq.s	.error

	move.l	mypubscreen(A5),a0
	move.l	Gadsave(A5),a6
	suba.l	a1,a1
	jsr	_LVOGetVisualInfoA(a6)
	move.l	d0,Vi(A5)
	tst.l	d0
	beq.s	.error     
	moveq	#0,d0
	rts
.error
	moveq	#-1,d0
	rts
*******************************************************************
*      Public Screen ranholen und Visual Info anfordern           *
*******************************************************************
CloseDownScreen:
	push	all

	move.l	Gadsave(a5),a6
	move.l	Vi(A5),d0
	beq.s	.novi
	move.l	d0,a0
	jsr	_LVOFreeVisualInfo(a6)
	clr.l	Vi(A5)
.novi
	move.l	Intsave(A5),a6
	suba.l	a0,a0
	move.l	Mypubscreen(A5),d0
	beq.s	.nopub
	move.l	d0,a1
	jsr	_LVOUnlockPubScreen(a6)
	clr.l	Mypubscreen(A5)
.nopub
	pop	all
	rts
GetFont
	tst.b	onsysfont(A5)
	beq.s	.stand

	move.l	grafsave(A5),a6
	lea.l	MyRastPort(a5),a3
	move.l	a3,a1
	jsr	_LVOInitrastport(A6)
	move.l	a3,a1
	lea.l	Attr(a5),a0
	jsr	_LVOAskFont(A6)
	lea.l	Attr(a5),a0
	jsr	_LVOopenfont(A6)
	move.l	d0,fontadr(A5)
	beq.s	.stand
	move.l	d0,a1
	rts
.stand
	move.l	mypubscreen(A5),a1
	lea.l	sc_RastPort(a1),a1
	move.l	rp_Font(a1),a1
	rts
ComputeFont:
	bsr	GetFont

	lea.l	Attr(a5),a0
	move.l	a0,Font(A5)

	move.l  LN_NAME(a1),ta_Name(a0)
	move.w  tf_YSize(a1),ta_YSize(a0)
	move.w  tf_XSize(a1),FontX(A5)
	move.w  tf_YSize(a1),FontY(A5)

	move.l	fontadr(A5),d0
	beq.s	.nofree
	move.l	d0,a1
	move.l	grafsave(A5),a6
	jsr	_LVOclosefont(A6)
.nofree
	move.l	mypubscreen(A5),a0
	move.b	sc_WBorLeft(a0),d0
	ext.w	d0
	move.w	d0,OffX(A5)

	move.l	sc_font(A0),a1
	move.w	ta_YSize(a1),d0

	addq.w	#1,d0
	move.b	sc_WBorTop(a0),d1
	ext.w	d1
	add.w	d1,d0
	move.w	d0,OffY(A5)

	tst.w	d2
	beq.s	CompDone
	tst.w	d3
	beq.s	CompDone
	move.w	d2,d0
	bsr	ComputeX

	add.w   OffX(A5),d0
	move.b	sc_WBorRight(a0),d1
	ext.w	d1
	add.w	d1,d0
	cmp.w	sc_Width(a0),d0

	ifne	test
	bra.s	Usetopaz
	endc

	bhi.s	UseTopaz
	move.w	d0,d2

	move.w	d3,d0
	bsr	ComputeY
	add.w	OffY(a5),d0
	move.b	sc_WBorBottom(a0),d1
	ext.w	d1
	add.w	d1,d0
	cmp.w	sc_Height(a0),d0
	bhi.s	UseTopaz
	move.w	d0,d3
CompDone:
	rts
UseTopaz:
	add.w   OffX(A5),d2
	move.b	sc_WBorRight(a0),d1
	ext.w	d1
	add.w	d1,d2

	add.w	OffY(a5),d3
	move.b	sc_WBorBottom(a0),d1
	ext.w	d1
	add.w	d1,d3

	move.l	Font(A5),a0
	move.l	#TopazName,ta_Name(a0)
	move.w	#8,FontY(A5)
	move.w	#8,FontX(a5)
	move.w	#8,ta_YSize(a0)
	rts
ComputeX:
	move.l	d1,-(sp)
	move.w	FontX(a5),d1
	bra.s	ComputeItX
ComputeY:
	move.l	d1,-(sp)
	move.w	FontY(A5),d1
	mulu	d1,d0
	addq.w	#4,d0
	lsr.w	#3,d0
	move.l	(sp)+,d1
	rts
ComputeItX:
	mulu	d1,d0
	addq.w	#4,d0
	lsr.w	#3,d0
	move.l	(sp)+,d1
	rts
*------------ Hookfunktion, um aktuellen Modus farblich hervorzuheben ------*
*---------------- derzeit noch kein Support für "disabled"-Gadgets ---------*
*benutzte Globals:
* - grafsave+datas = Graphics Base
*
*Erkennung, ob Zeile hervorzuheben oder nicht:
* -  erstes Zeichen im darzustellenden Text ist ein "|"
	;a0:Hook
	;a1:Message
	;a2:Node
my_hook
	push	d1-a6

	move.l	lvdm_MethodID(a1),d1
	cmp.l	#LV_Draw,d1
	bne.w	.hi
	move.l	a1,a4
	move.l	lvdm_RastPort(a4),d7
	beq.w	.hi

	move.l	grafsave+datas,a6			;Graphics Base

	move.l	lvdm_DrawInfo(A4),d0
	beq.w	.hi
	move.l	d0,a1
	move.l	dri_Pens(a1),a1

	sf	d2
	move.l	ln_name(A2),a5		;
	cmp.b	#`|`,(a5)		; Test ob hervorzuheben oder nicht
	bne.s	.textpen

	st	d2
	addq.l	#1,a5
	move	highlighttextpen*2(a1),d0
	bra.s	.high
.textpen
	move	textpen*2(a1),d0
.high
	move	backgroundpen*2(a1),d6

	cmp.l	#LVR_SELECTED,lvdm_State(a4)
	bne.s	.normalBG

	move	FILLPEN*2(a1),d6
	move	textpen*2(a1),d0
	tst.b	d2
	beq.s	.normalBG
	move	highlighttextpen*2(a1),d0
.normalBG
	move	d6,d1
	moveq	#RP_Jam1,d2
	move.l	d7,a1
	jsr	_LVOsetabpendrmd(A6)

	move.w	lvdm_bounds+ra_minx(a4),d0
	move.w	lvdm_bounds+ra_miny(a4),d1
	move.l	d7,a1
	add	rp_TxBaseline(a1),d1
	jsr	_LVOMove(A6)

	move.l	d7,a1
	moveq	#RP_Jam2,d0
	jsr	_LVOsetdrmd(A6)

	move.w	lvdm_bounds+ra_maxx(a4),d5		;Begrenzung des Textes
	sub	lvdm_bounds+ra_minx(a4),d5		;auf Breite des
	blt	.hi					;Listviews, solange

	move.l	a5,a0					;Text
	moveq	#-1,d3					;bis der Text passt
.lop
	addq	#1,d3
	tst.b	(a0)+
	bne.s	.lop
.charloop
	move.l	d7,a1
	move.l	a5,a0					;Text
	move.w	d3,d0
	jsr	_LVOtextlength(A6)
	cmp.w	d5,d0
	blt.s	.ok
	subq.w	#1,d3
	bra.s	.charloop
.ok
	move	d0,d4
	move.w	d3,d0
	move.l	a5,a0					;Text
	move.l	d7,a1
	jsr	_LVOtext(A6)

	move.l	d7,a1
	move	d6,d0
	move	d6,d1
	moveq	#0,d2
	jsr	_LVOsetabpendrmd(A6)

	move	lvdm_bounds+ra_minx(a4),d0
	add	d4,d0
	move	lvdm_bounds+ra_miny(a4),d1
	move	lvdm_bounds+ra_maxx(a4),d2
	move	lvdm_bounds+ra_maxy(a4),d3
	move.l	d7,a1
	jsr	_LVORectfill(a6)	;freien Platz nach dem Text löschen
	
	pop	d1-a6
	moveq	#LVCB_OK,d0
	rts
.hi
	pop	d1-a6
	moveq	#LVCB_Unknown,d0
	rts
CreateGadgets
	move.l	Gadsave(A5),a6
	lea.l	Project0GList(a5),a0
	jsr	_LVOCreateContext(a6)
	move.l	d0,a3
	tst.l	d0
	beq.w	.Project0CError

	moveq	#0,d3
	lea.l	Project0GTags(pc),a4
.Project0GL:
	move.l	4,a6
	lea.l	Project0NGads(pc),a0
	move.l	d3,d0
	mulu	#gng_SIZEOF,d0
	add.l	d0,a0
	lea.l	BufNewGad(a5),a1
	moveq	#gng_SIZEOF,d0
	jsr	_LVOCopyMem(a6)
	lea.l	BufNewGad(a5),a0
	move.l	Vi(a5),gng_VisualInfo(a0)
	move.l	Font(a5),gng_TextAttr(a0)

	move.w	gng_LeftEdge(a0),d0
	bsr	computex
	add.w	OffX(a5),d0
	move.w	d0,gng_LeftEdge(a0)

	move.w	gng_TopEdge(a0),d0
	bsr	computey
	add.w	OffY(a5),d0
	move.w	d0,gng_TopEdge(a0)

	move.w	gng_Width(a0),d0
	bsr	computex
	move.w	d0,gng_Width(a0)

	move.w	gng_Height(a0),d0
	bsr	computey
	move.w	d0,gng_Height(a0)

	move.l	Gadsave(a5),a6
	lea.l	Project0GTypes(pc),a0
	moveq	#0,d0
	move.l	d3,d1
	asl.l	#1,d1
	add.l	d1,a0
	move.w	(a0),d0
	move.l	a3,a0
	lea.l	BufNewGad(a5),a1
	move.l	a4,a2
	jsr	_LVOCreateGadgetA(a6)
	tst.l	d0
	bne.s	.Project0COK
	bra	.Project0CError
.Project0COK:
	move.l	d0,a3
	move.l	d3,d0
	asl.l	#2,d0
	lea.l	Project0Gadgets(a5),a0
	add.l	d0,a0
	move.l	a3,(a0)
.Project0TL:
	tst.l	(a4)
	beq.s	.Project0DN
	addq.w	#8,a4
	bra.s	.Project0TL
.Project0DN:
	addq.w	#4,a4
	addq.w	#1,d3
	cmp.w	#Project0_CNT,d3
	bmi	.Project0GL
.Project0CError
	rts
*************************************************************************
*            Fenster öffnen, Gadgets und Menüs init                     *
*************************************************************************
SetUpWin:
	movem.l d1-d4/a0-a4/a6,-(sp)

	move.l	mypubscreen(a5),a0
	move.l  sc_Font(a0),a1
	move.w  ta_YSize(a1),d3
	addq.w  #1,d3
	move.b  sc_WBorTop(a0),d0
	ext.w   d0
	add.w	d3,d0
	move.w	d0,offy(a5)

	move.b  sc_WBorLeft(a0),d0
	ext.w   d0
	move.w	d0,offx(a5)

	move.w	#Project0Width,d2
	move.w	#Project0Height,d3

	bsr	ComputeFont
	move.l	mypubscreen(A5),a0

	move.l	d2,ahawidth
	move.l	d3,ahaheight

	move.l	d2,d0
	move.l	d0,d4

	moveq	#0,d2
	add.w	d2,d0
	add.w	OffX(a5),d0
	move.b	sc_WBorRight(a0),d1
	ext.w	d1
	add.w	d1,d0
	cmp.w	sc_Width(a0),d0
	bls.s	.Project0WOk
	move.w	sc_Width(a0),d0
	sub.w	d4,d0
	move.w	d0,d2
.Project0WOk:
	move.l	d3,d0
	move.l	d0,d4

	lea	begin(pc),a1
	move.w	eus_winy(a1),d3
	add.w	d3,d0

	add.w	OffY(A5),d0
	move.b	sc_WBorBottom(a0),d1
	ext.w	d1
	add.w	d1,d0
	cmp.w	sc_Height(a0),d0
	bls.s	Project0HOk
	move.w	sc_Height(a0),d0
	sub.w	d4,d0
	move.w	d0,d3
Project0HOk:
	move.l	Gadsave(A5),a6
	lea.l	Project0NewMenu0(pc),a0
	lea.l	MTags0(pc),a1
	jsr	_LVOCreateMenusA(a6)

	move.l	d0,Project0Menus(A5)
	tst.l	d0
	beq	Project0MError
	move.l	d0,a0
	move.l	Vi(A5),a1
	lea.l	mtags0(pc),a2
	jsr	_LVOLayoutMenusA(a6)

	moveq	#0,d0
	moveq	#0,d1
	moveq	#0,d2
	moveq	#0,d3
	moveq	#0,d7
	move	WinPosX(A5),d0
	move	WinPosY(A5),d1
	move	ZoomPosX(A5),d2
	move	ZoomPosY(A5),d3
	move.l	ahawidth(pc),d4
	move.l	ahaheight(pc),d5
	move.l	#ZoomWidth,d6
	move	offy(A5),d7
	tst.b	ZoomState(A5)
	beq.s	.Normal
	exg.l	d0,d2
	exg.l	d1,d3
	exg.l	d4,d6
	exg.l	d5,d7
.normal
	lea.l	Project0WindowTags(pc),a1
	move.l	d0,Project0L+4-Project0WindowTags(A1)
	move.l	d1,Project0T+4-Project0WindowTags(A1)
	move.l	d4,Project0W+4-Project0WindowTags(A1)
	move.l	d5,Project0H+4-Project0WindowTags(A1)
	move.w	d2,ZoomStruct-Project0WindowTags(A1)
	move.w	d3,ZoomStruct+2-Project0WindowTags(A1)
	move	d6,ZoomStruct+4-Project0WindowTags(A1)
	move	d7,ZoomStruct+6-Project0WindowTags(A1)

	move.l	Intsave(A5),a6
	move.l	mypubscreen(a5),Pubadr-Project0WindowTags(a1)
	suba.l	a0,a0
	jsr	_LVOOpenWindowTagList(a6)
	move.l	d0,Winhandle(a5)
	tst.l	d0
	beq	Project0WError
.open13
	move.l	Winhandle(a5),a0
	move.l	Project0Menus(A5),a1
	jsr	_LVOSetMenuStrip(a6)

	bsr	createGadgets

	bsr	AddGads

	moveq	#0,d0
Project0Done:
	movem.l	(sp)+,d1-d4/a0-a4/a6
	rts
Project0CError:
	moveq	#1,d0
	bra.s	Project0Done
Project0GError:
	moveq	#2,d0
	bra.s	Project0Done
Project0MError:
	moveq	#3,d0
	bra.s	Project0Done
Project0WError:
	moveq	#4,d0
	bra.s	Project0Done

AddGads:
	movem.l	d0-a6,-(sp)
	move.l	Project0GList(a5),d0
	beq.s	.nogads
	move.l	d0,a1

	moveq	#0,d1
.count
	move.l	d0,a0

	addq.l	#1,d1

	move.l	(A0),d0
	bne.s	.count

	move.w	d1,RealNumGadgets(A5)

	move.l	intsave(a5),a6
	move.l	winhandle(a5),a0
	moveq	#-1,d0
	moveq	#-1,d1
	suba.l	a2,a2
	jsr	_LVOaddglist(a6)

	move.l	Project0GList(a5),a0
	move.l	winhandle(a5),a1
	suba.l	a2,a2
	moveq	#-1,d0
	jsr	_LVOrefreshglist(a6)

	move.l	GadSave(a5),a6
	move.l	Winhandle(a5),a0
	suba.l	a1,a1
	jsr	_LVOGT_RefreshWindow(a6)

	bsr	UpdateList
.nogads
	movem.l	(sp)+,d0-a6
	rts
*************************************************************************
*            Fenster schließen, Gadgets und Menüs free                  *
*************************************************************************
Closedownwin:
	push	all
	
	move.l	Intsave(A5),a6
	move.l	Project0Menus(A5),d0
	beq.s	Project0NMenu
	move.l	d0,a0
	move.l	Winhandle(a5),a0
	jsr	_LVOClearMenuStrip(a6)
	move.l	GadSave(a5),a6
	move.l	Project0Menus(A5),a0
	jsr	_LVOFreeMenus(a6)
	clr.l	Project0Menus(A5)
Project0NMenu:
	move.l	Intsave(A5),a6
	move.l	Winhandle(a5),d0
	beq.s	.nowin
	move.l	d0,a0
	jsr	_LVOCloseWindow(a6)
	clr.l	Winhandle(a5)
	clr.l	port(a5)
.nowin
	bsr	Freegadgets

	pop	all
	rts
FreeGadgets
	movem.l	d0-a6,-(sp)

	move.l	GadSave(a5),a6
	move.l	Project0GList(A5),a0
	cmpa.l	#0,a0
	beq	.nogad
	jsr	_LVOFreeGadgets(a6)
	clr.l	Project0GList(A5)
.nogad
	movem.l	(sp)+,d0-a6
	rts
*************************************************************
*    Gadgetadresse ausrechnen                               *
* Input D0 - Gadgetnummer (0 < X < MAX)                     *
*************************************************************
_Gadr
	lea	Gadgetadrs(a5),a0
	asl.l	#2,d0
	move.l	(a0,d0),a0
	rts
*************************************************************
*           Nachrichtenbearbeitung                          *
*************************************************************
HandleActions
.ma
	move.l	gadsave(a5),a6

	move.l	port(a5),d0
	beq.s	.nowinny
	move.l	d0,a0
	jsr	_LVOGT_getimsg(a6)
	tst.l	d0
	bne	.msg
.nowinny
	move.l	4,a6
	
	move.l	msgport(a5),a0
	jsr	_LVOgetmsg(a6)
	tst.l	d0
	bne	.AN_msg

	bsr	UpdateDownGadgets
	bne	.ma

	moveq	#0,d0
	move.l	4,a6

	ifne	userprogram
	move.l	msgport(a5),a0
	move.b	mp_sigbit(a0),d1
	bset	d1,d0
	endc

	move.l	Port(a5),d2
	beq.s	.nomain
	move.l	d2,a0
	move.b	mp_sigbit(a0),d1
	bset	d1,d0
.nomain
	move.l	mysignal(a5),d3	;Signal für Analyzer
	bset	d3,d0		;Signalbit für Abarbeitung des Analyzers selbst
				;(Auswertungsroutine namens "ANALYZE1")
	jsr	_LVOwait(a6)
	bra	.ma
;======================= Message an Hauptwindow ============================
.msg
	move.l	d0,a1
	move.l	im_class(a1),d7
	move.w	im_code(a1),d5 		;<- Für Tastatur / Selnummer Listview
	move.l	im_Iaddress(a1),d6 	;<- Für Gadgetabfrage
	move.l	im_seconds(a1),d2	;<- für Doppelclick
	move.l	im_micros(a1),d3	;<- auch f. Doppelclick
	jsr	_LVOGT_replyimsg(a6)

	cmp.l	#IDCMP_Changewindow,d7	;Refresh
	bne.s	.nochangewin

	move.l	winhandle(a5),a0
	move	OffY(A5),d0
	cmp	wd_height(a0),d0
	bne.s	.setposun
	move.w	wd_leftedge(a0),ZoomPosX(a5)
	move.w	wd_topedge(a0),ZoomPosY(a5)
	st	ZoomState(a5)
	bra	.ma
.setposun
	move.w	wd_leftedge(a0),WinPosX(a5)
	move.w	wd_topedge(a0),WinPosY(a5)
	tst.b	ZoomState(a5)
	beq	.ma
	sf	ZoomState(a5)

	bsr	clearwin

	move.l	gadsave(a5),a6
	move.l	winhandle(a5),a0	;*Window
	jsr	_LVOGT_beginrefresh(A6)

	move.l	winhandle(a5),a0	;*Window
	moveq	#1,d0
	jsr	_LVOGT_Endrefresh(A6)	

	bsr	drawbevel
	bra	.ma
.nochangewin
;	cmp.l	#refreshwindow,d7	;Refresh
;	bne.s	.noref
;	pea	.ma(pc)
;.ref
;	bsr	clearwin
;
;	move.l	gadsave(a5),a6
;	move.l	winhandle(a5),a0	;*Window
;	jsr	_LVOGT_beginrefresh(A6)
;
;	move.l	winhandle(a5),a0	;*Window
;	moveq	#1,d0
;	jsr	_LVOGT_Endrefresh(A6)	
;
;	bsr	drawbevel
;	rts
;.noref
	;------------------ Gadgets abfragen ------------------------
	cmp.l	#Gadgetup,d7
	bne.w	.notup

	move.l	d6,a1

	move.w	gg_gadgetid(A1),d4	;ID Für Gadgets

	bsr	TestGadgets
	bra	.ma
.notup
	cmp.l	#Gadgetdown,d7
	bne.w	.notgad

	move.l	d6,a1

	move.w	gg_gadgetid(A1),d4	;ID Für Gadgets

	bsr	TestDOWNGadgets
	bra	.ma

	;------------------------- Menüs abfragen ----------------------------
.menuloop
	move.l	temp(A5),a1
	move.w	mi_nextselect(A1),d5
	bra.s	.menuwei
.notgad:
	cmp.l	#menupick,d7
	bne.w	.nomenu
.menuwei
	move.w	d5,d0
	cmp.w	#menunull,d0
	beq	.ma

	move.l	Project0Menus(A5),a0
	move.l	intsave(a5),a6
	jsr	_LVOitemaddress(a6)
	move.l	d0,a1
	tst.l	d0
	beq	.ma
	move.l	d0,temp(A5)

	move.w	d5,d0
	and.w	#$1f,d0
	bne.s	.2ndmenu
	move.w	d5,d0
	and.w	#$7e0,d0
	bne.s	.noglobal

	move.w	mi_flags(a1),d0
	and.w	#checked,d0
	move.w	d0,d1
	lsr.w	#4,d0
	move.b	d0,Onglobal(A5)

	move.w	Hiercheck(pc),d0
	and.w	#~Checked,d0
	or.w	d1,d0
	move.w	d0,hiercheck

	bsr	SetVoic

	bra	.menuloop
.noglobal
	cmp.w	#64,d0
	bne.s	.noabout		;1. Item (About) ?
	lea	Aboutmessage(pc),a0
	bsr	Merror
	bra	.menuloop
.noabout
	cmp.w	#96,d0			;2. Item (Hide)
	beq.w	.quitit
	cmp.w	#128,d0			;3. Item (Quit)
	beq	.killit
	bra	.menuloop
.2ndmenu				;2. Menü
	move.w	d5,d0
	and.w	#$7e0,d0
	bne.s	.nodefaults

	bsr	Makedefaults			;Default prefs setzen
	bsr	Updatelist

	move.w	SelectedW(a5),d0
	mulu	#P_sizeof,d0
	lea	Prefslist(a5),a0
	move.l	P_Mixrate(A0,d0.w),d0
	bsr	CalcValues

	bsr	SetPlaymode

	bsr	InitEchos
	bsr	Makevoltable

	bra	.menuloop
.nodefaults
	cmp.w	#32,d0
	bne	.nosavepref
	bsr	SaveConfig
.nosavepref
	bra	.menuloop
.nomenu
	cmp.l	#rawkey,d7
	bne	.nokey
.noS
	cmp.b	#$45,d5			;ESC
	beq	.quitit
	bra	.ma
.nokey
	cmp.l	#CloseWindow,d7
	bne	.ma
.quitit
	ifne	userprogram

	bsr	closewin

	move.l	4,a6
	lea	Portname(pc),a1
	jsr	_LVOfindport(a6)
	tst.l	d0
	beq.s	.endme		;kein Eagleplayerport->Ende des Programmes
	move.l	d0,a0			;Portadresse
	move.l	msgport(a5),d3
	move.l	mytask(a5),d4
;	move.l	mysignal(a5),d5
	move.l	#-1,d5
	move.w	#USclass_Hide,d6		;DeActivate,d6
	bsr	sendmess
	bra	.ma

	endc
.endme
	moveq	#-1,d7
	rts
.killit
	moveq	#0,d7
	RTS
;===================== Message an Userprogramm Port =====================
	ifne	userprogram
.AN_msg
	move.l	d0,a1

	move.l	MSGPort(a5),UM_Userport(a1)

	lea	begin(pc),a2

	ifne	debug
	move.w	um_usernr(a1),saveusernr(A5)
	else
	move.w	EUS_Usernr(A2),UM_UserNr(a1)
	endc

	move.l	mytask(a5),UM_TaskAdr(a1)
;	move.l	mysignal(a5),d1
	move.l	#-1,d1
	move.l	d1,UM_Signal(a1)

	move.w	UM_class(a1),d3		;<-
	cmp.w	#USclass_exit,d3
	bne.w	.noex1

	clr.l	um_signal(a1)
	clr.l	um_taskadr(a1)
	clr.l	um_userport(a1)
.noex1
	move.l	UM_Type(a1),d7
	move.l	UM_structadr(a1),d6 	;<-

	clr.w	UM_class(A1)

	cmp.w	#USclass_getconfig,d3
	bne	.nosavepref2
	bsr	SaveConfig			;Save Config
.nosavepref2

	cmp.w	#USclass_getconfig,d3		;when this command comes,set
						;the actual preferences into
						;the Eagleuser-Structure
						;(EUS_-structure at the be-
						;ginning of the program)
	bne	.noprev

	move.w	eus_flags(a2),d0
	and.w	#~EUSB_Show,d0

	move.l	winhandle(A5),d1		;Window
	beq.s	.prnowin			;no Window opened,no change
						;of preferences
	or.w	#EUSB_Show!EUSB_Activate,d0	;set Flag: window is open

	move.l	d1,a0				;Window
	move.w	wd_leftedge(a0),eus_winx(a2)	;Save Windowpostion
	move.w	wd_topedge(a0),eus_winy(a2)

	move.w	wd_width(a0),d2
	moveq	#0,d1
	move.b	wd_borderleft(A0),d1
	sub.w	d1,d2
	move.b	wd_borderright(A0),d1
	sub.w	d1,d2
.prnowin
	move.w	d0,eus_flags(a2)	;Save Flags
.noprev
	cmp.w	#USCLASS_Show,d3
	bne.s	.noshow

	move.l	MYEpBase(pc),a0
	move.l	EPG_SomePrefs(a0),d0
	btst	#EGPRF_Iconify,d0
	bne.s	.noshow

	push	all
	bsr	Openwin
	pop	all
	tst.l	Winhandle(A5)
	beq.s	.noshow
	move	d3,UM_Class(a1)
.noshow

	cmp.w	#USclass_Hide,d3
	bne.s	.noclosewin
	bsr	Closewin
.noclosewin

	move.l	mn_replyport(a1),d0
	cmp.l	MSGport(a5),d0		 ;eine von uns abgeschickte Message ?
	beq.s	.noreply
	jsr	_LVOreplymsg(a6)
.noreply
	
	cmp.l	#USM_Userprg,d7		;Message zurückbekommen ?
	bne.s	.nomy

	move.b	#0,messagesent(a5)	;merken,daß Message-Struktur frei
	bra	.mess			;eventl. Message vom Esagle auswerten

.nomy
	cmp.l	#USM_Eagleplayer,d7	;Hat EaglePlayer was zu melden ?
	bne.w	.noeagle		;nö
.mess

;	lea	begin(pc),a0
;	move.l	eus_epbase(a0),a0
;	move.b	EPG_Wordreserved7(a0),d0
;	beq	.killit

	move.l	d6,an_structadr(a5)
.refre
	cmp.w	#USclass_Dummy,d3	;leere Message,nur neue Analyzer-
	beq.w	.ma			;adresse bekommen
	cmp.w	#USclass_killmodule,d3
	bne.s	.nokill

	move	#-1,Currentnumvoc(a5)
	bsr	MakeLV

.nokill
	cmp.w	#USclass_zipwin,d3
	bne.s	.nozip
.setzip
	move.l	4,a6
	move.l	winhandle(a5),d0
	beq	.ma
	move.l	d0,a0
	move.w	wd_height(a0),d0
	cmp.w	myhoehe1(a5),d0
	beq.w	.ma			;Window schon klein
.zip
	move.w	d0,-(sp)

	move.l	intsave(a5),a6
	jsr	_LVOzipwindow(a6)

	move.w	(sp)+,d4

	move.l	winhandle(a5),a2
.Zipwait:
	moveq	#2,d1
	move.l	_Dos(a5),a6
	jsr	_LVODelay(a6)

	cmp.w	wd_height(a2),d4
	beq.s	.zipwait

	bra	.ma
.nozip
	cmp.w	#USclass_unzipwin,d3
	bne.s	.nounzip

.clearzip
	move.l	4,a6
	move.l	winhandle(a5),d0
	beq	.ma
	move.l	d0,a0
	move.w	wd_height(a0),d0
	cmp.w	myhoehe1(a5),d0
	beq.s	.zip
	bra	.ma
.nounzip
	cmp.w	#USclass_exit,d3
	beq	.endme

;	cmp.w	#USclass_Show,d3
;	bne.w	.nowin
;	bsr	Openwin
;	bra	.ma
;.nowin

	cmp.w	#USclass_DeActivate,d3
	bne.s	.nodeact
;	move.w	eus_flags(a2),d0
;	bset	#EUSF_Disable,d0
;	move	d0,eus_flags(a2)
	bra	.ma
.nodeact

	cmp.w	#USclass_Activate,d3
	bne.s	.noact
;	move.w	eus_flags(a2),d0
;	bclr	#EUSF_Disable,d0
;	move	d0,eus_flags(a2)
	bra	.ma
.noact

	cmp.w	#USClass_SetWaitPointer,d3
	bne.w	.NoWaitPointer
	bsr	WaitPointer
	bra	.ma

.NoWaitPointer:
	cmp.w	#USClass_ClearWaitPointer,d3
	bne.w	.NoClearPointer
	bsr	ClearPointer
	bra	.ma


.NoClearPointer:




	cmp.w	#USclass_NewConfig,d3	;is there a new config
	bne.w	.nonewcon		;no

	lea	begin(pc),a0		;start of program (EUS_-Structure)
	move.w	eus_flags(a0),d0	;get Flags
	btst	#eusf_openwin,d0	;Window open ?
	beq.s	.nowino
	bsr	openwin			;open it
	bra.s	.weio
.nowino
	bsr	closewin		;else close it
.weio
	lea	begin(pc),a0		;start of program (EUS_-Structure)
	move.l	winhandle(a5),d0	;windowaddress
	beq.s	.nothingtomove		;no Window , no movement

	move.l	d0,a1			;Window
	move.l	wd_wscreen(a1),a2	;Parent Screen

	move.w	eus_winx(a0),d0		;new X-position
	move.w	d0,d1			;save
	blt.s	.oldx			;less than 0 -> stop

	add.w	wd_width(a1),d1		;new position + Window-width
	cmp.w	sc_width(a2),d1		;bigger than Screenwidth ?
	bhi.s	.oldx			;then old X-position (Delta = 0)

	sub.w	wd_leftedge(a1),d0	;new - old X-position = Delta X
	bra.s	.gety
.oldx
	moveq	#0,d0			;Delta X = 0
.gety
	move.w	eus_winy(a0),d1		;new Y-position

	move.w	d1,d2			;save
	blt.s	.oldy			;less than 0 -> stop and take old

	add.w	wd_height(a1),d2	;new position + window-height
	cmp.w	sc_height(a2),d2	;bigger than Screenheight ?
	bhi.s	.oldy

	sub.w	wd_topedge(a1),d1	;new - old Y-position = Delta Y
	bra.s	.setdeltas
.oldy	moveq	#0,d1

.setdeltas
	move.l	intsave(a5),a6		;Intuition
	move.l	a1,a0			;Winhandle
	jsr	_LVOmovewindow(A6)
.nothingtomove
	lea	begin(pc),a0
	move.w	eus_flags(a0),d0
	btst	#eusf_zipwin,d0		;Zipwindow ?
	bne	.setzip			;yes
	bra	.clearzip		;no
.nonewcon
	bra	.ma
.noeagle
	bra	.ma
	endc
*********************** Finde Tag über EP Funktion ***************************
FindTag
	movem.l	a1/a5,-(sp)
	move.l	myEPBase(pc),a5
	move.l	EPG_FindTag(a5),a1
	jsr	(a1)
	movem.l	(sp)+,a1/a5
	rts


*-----------------------------------------------------------------------------*
WaitPointer:	movem.l	a0/a1/a4/d0,-(a7)
		tst.l	WinHandle(a5)
		beq.s	.Return
		tst.w	WindowDisabled(a5)
		bne.s	.Return

		*--- Alle Menus disablen ---*
		*Input:a0=Window
		*      a1=Menu
		move.l	Begin+EUS_EPBase(pc),a4
		move.l	WinHandle(a5),a0
		move.l	Project0Menus(A5),a1
		jsr	ENPP_SetWaitPointer(a4)

		move.w	#1,WindowDisabled(a5)

.Return:	movem.l	(sp)+,a0/a1/a4/d0
		rts


*-----------------------------------------------------------------------------*
ClearPointer:	movem.l	a0/a1/a4/d0,-(a7)
		tst.w	WindowDisabled(a5)
		beq.s	.Return

		*--- Alle Menus disablen ---*
		*Input:a0=Window
		*      a1=Menu
		move.l	Begin+EUS_EPBase(pc),a4
		move.l	WinHandle(a5),a0
		move.l	Project0Menus(A5),a1
		jsr	ENPP_ClearWaitPointer(a4)


.Return:	clr.w	WindowDisabled(a5)
		movem.l	(sp)+,a0/a1/a4/d0
		rts


*****************************************************************
allocmsg
	movem.l	d1-a6,-(sp)
	move.l	4,a6
	moveq	#UM_Sizeof,d0
	move.l	#$10001,d1
	jsr	_LVOallocmem(A6)
	movem.l	(sp)+,d1-a6
	tst.l	d0
	rts
*****************************************************************
freemsg
;	moveq	#UM_sizeof,d0

	moveq	#0,d0
	move.w	mn_length(a1),d0
	add.w	#20,d0
	move.l	4,a6
	jsr	_LVOfreemem(A6)
	rts
******************************************************************************
*                       Ausgabe von Error-Messages                           *
*                 Input: a0 -> Zeiger auf Ausgabestring                      *
******************************************************************************
MERROR:
	movem.l	d0/a2-a3,-(sp)
	suba.l	a3,a3			;*Arguments
	lea	my_easygadget(pc),a2
	bsr	Errorout
	movem.l	(sp)+,d0/a2-a3
	rts
Errorout
	movem.l	d1-a6,-(sp)
	move.l	Intsave(a5),a6
	lea	my_easystruct(a5),a1

	move.l	a0,es_textformat(a1)

	move.l	a2,es_gadgetformat(a1)

	lea	my_easytitle(pc),a0
	move.l	a0,es_Title(a1)
	move.l	winhandle(a5),a0	;*Window
	suba.l	a2,a2			;*IDCMP_ptr
	jsr	_LVOeasyrequestargs(a6)
	movem.l	(sp)+,d1-a6	
	rts

;======================= Load 14 Bit Calibration Table ==============================================
LoadCalibration:
	movem.l	d0-a6,-(sp)
	moveq	#-1,d7
	
	move.l	4.w,a6
	lea	dos(pc),a1
	moveq	#33,d0
	jsr	_LVOopenlibrary(A6)
	tst.l	d0
	beq	.error
	move.l	d0,dosbase
	move.l	d0,a6
	lea	.loadname(pc),a1
	move.l	a1,d1
	move.l	#1005,d2			;mode_oldfile
	jsr	_LVOopen(a6)
	move.l	d0,d1				;Handle
	beq.s	.closelib
	move.l	d0,d6

	lea	AdditiveArray(pc),a0
	move.l	a0,d2				;Adr
	move.l	#256,d3				;len
	jsr	_LVOread(A6)
	move.l	d0,d7

	move.l	d6,d1
	jsr	_LVOclose(a6)
.closelib
	move.l	a6,a1
	move.l	4.w,a6
	jsr	_LVOcloselibrary(A6)
	cmp.l	#256,d7
	beq.s	.quit
.error
	lea	AdditiveArray(pc),a0
	move	#255-1,d0
.cop	move.b	#$5f,(a0)+
	dbf	d0,.cop
	move.b	#$7f,(a0)
.quit
	movem.l	(sp)+,d0-a6
	moveq	#0,d0
	rts
.loadname:	dc.b	"ENV:Cybersound/Sounddrivers/14Bit_Calibration",0

;============= Save Player Config Routine ===========================
SaveConfig:
	movem.l	d0-a6,-(sp)
	
	move.l	4.w,a6
	lea	dos(pc),a1
	moveq	#33,d0
	jsr	_LVOopenlibrary(A6)	;Open DOS
	tst.l	d0
	beq	.error
	move.l	d0,dosbase
	move.l	d0,a6

	move.l	myepbase(pc),a0
	move.l	EPG_ConfigDirArrayPtr(a0),d1
	moveq	#-2,d2			;access_read
	jsr	_LVOlock(a6)
	tst.l	d0
	beq	.nolock			;Path not found
	move.l	d0,d1
	jsr	_LVOcurrentdir(A6)
	move.l	d0,d7

	lea	savename(pc),a1
	move.l	a1,d1
	move.l	#1006,d2		;MODE_NEWFILE
	jsr	_LVOopen(A6)
	move.l	d0,d6
	beq.s	.fail

	move.l	d0,d1				;Handle
	lea	ConfigDatas(A5),a1
	move.l	a1,d2				;Adr
	move.l	#ConfigDatasEND-ConfigDatas,d3	;len
	jsr	_LVOwrite(a6)

	move.l	d6,d1
	jsr	_LVOclose(a6)
.fail
	move.l	d7,d1
	jsr	_LVOCurrentdir(A6)
	move.l	d0,d1
	jsr	_LVOUnlock(A6)
.nolock
	move.l	a6,a1
	move.l	4.w,a6
	jsr	_LVOcloselibrary(A6)
.error
	movem.l	(Sp)+,d0-a6
	rts
;============= Load Player Config Routine ===========================
Loadconfig:
	movem.l	d0-a6,-(sp)

	move.l	4.w,a6
	lea	dos(pc),a1
	moveq	#33,d0
	jsr	_LVOopenlibrary(A6)	;Open DOS
	tst.l	d0
	beq	.error
	move.l	d0,dosbase
	move.l	d0,a6

	move.l	myepbase(pc),a0
	move.l	EPG_ConfigDirArrayPtr(a0),d1
	moveq	#-2,d2			;access_read
	jsr	_LVOlock(a6)
	tst.l	d0
	beq	.nolock			;Path not found
	move.l	d0,d1
	jsr	_LVOcurrentdir(A6)
	move.l	d0,d7

	lea	savename(pc),a1
	move.l	a1,d1
	move.l	#MODE_Oldfile,d2		;MODE_NEWFILE
	jsr	_LVOopen(A6)
	move.l	d0,d6
	beq.s	.fail

	move.l	d0,d1				;Handle
	lea	ConfigDatas(A5),a1
	move.l	a1,d2				;Adr
	move.l	#ConfigDatasEND-ConfigDatas,d3	;len
	jsr	_LVOread(a6)

	move.l	d6,d1
	jsr	_LVOclose(a6)
.fail
	move.l	d7,d1
	jsr	_LVOCurrentdir(A6)
	move.l	d0,d1
	jsr	_LVOUnlock(A6)
.nolock
	move.l	a6,a1
	move.l	4.w,a6
	jsr	_LVOcloselibrary(A6)
.error
	movem.l	(sp)+,d0-a6
	rts

dosbase:	dc.l    0       ; Dos-Lib Basisadresse
savename:	dc.b	`14_Bit_Amplifier.cfg`,0

	cnop	0,4
********************************************************************
*               initialize default preferences                     *
********************************************************************
Makedefaults:
	movem.l	d0-a6,-(sp)
	clr.b	Echovalid

	lea	Prefslist(a5),a0
	move.l	#28000,d0			;Rate
	moveq	#10,d1				;VBoost "1.0"
	moveq	#0,d4				;Flags

	moveq	#32-1,d3
.defaults
	move.l	d0,P_Mixrate(a0)		;mixrate.l
	move.w	d1,P_Vboost(a0)			;vboost.w
	move.w	d4,P_Flags(a0)			;flags.w

	lea	P_Echos(A0),a1
	move	#P_Sizeof-P_Echos-1,d2
.clr	clr.b	(a1)+
	dbf	d2,.clr

;	move.b	#1,P_Echos+E_Enabled(A0)
;	move.b	#1,P_Echos+Echo_sizeof+E_Enabled(A0)
;	move.b	#0,P_Echos+Echo_sizeof*2+E_Enabled(A0)

	move.b	#1,P_Echos+E_Delay(a0)
	move.b	#0,P_Echos+E_Volume(A0)
	move.b	#1,P_Echos+E_Special(a0)

	move.b	#31,P_Echos+Echo_sizeof+E_Delay(a0)
	move.b	#2,P_Echos+Echo_sizeof+E_Volume(A0)

	move.b	#31,P_Echos+Echo_sizeof*2+E_Delay(a0)
	move.b	#3,P_Echos+Echo_sizeof*2+E_Volume(A0)

	sub.l	#500,d0
	addq.w	#1,d1
	lea	P_Sizeof(a0),a0
	dbf	d3,.defaults

	movem.l	(sp)+,d0-a6
	rts
*****************************************************************************
*                        Gedrückte Gadgets abfragen                         *
* A1 - aktuelle Gadgetstruktur                                              *
* D4 - Gadget ID                                                            *
*****************************************************************************
TestGadgets
	cmp.w	#GD_Listview,d4		;Listview-Gadget
	bne.s	.noidlv

	move.w	SelectedW(A5),d6	;aktuell angeclickter Modus
	move.w	d5,SelectedW(A5)

	cmp.w	d5,d6			;kein Doppelklick
	beq	.testdoub

	move.l	d2,Seconds(a5)
	move.l	d3,Micros(a5)

	bsr	UpdateList
	bra	.endit
.testdoub
	move.l	Seconds(a5),d0
	move.l	Micros(a5),d1
	move.l	d2,Seconds(a5)
	move.l	d3,Micros(a5)
	move.l	intsave(a5),a6
	jsr	_LVOdoubleclick(a6)
	cmp.l	#1,d0
	bne.w	.disp

	clr.l	Seconds(a5)
	
	mulu	#P_Sizeof,d6
	lea	Prefslist(a5),a0
	move.w	P_Flags(A0,d6.w),d0		;Flags.w (Bit0=disable)
	eor.w	#1,d0
	move.w	d0,P_Flags(a0,d6.w)
.disp
	bsr	UpdateList
	bra	.ma
.noidlv
	cmp.w	#GD_VBOOST,d4		;Volume Boost Slider Gadget
	bne.s	.noidBoost

	tst.b	onglobal(A5)
	bne.s	.sli2global

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_VBoost(a5),a0
	move.w	d5,(A0,d0.w)
	bra.s	.sli2up
.sli2global
	lea	Prefslist+P_VBoost(a5),a0
	moveq	#31-1,d0
.sli2all
	move.w	d5,(A0)
	add.w	#P_Sizeof,a0
	dbf	d0,.sli2all
.sli2up
	bsr	UpdateList		;Später nur Listview update !!!!

;	tst.b	onvboostslider(A5)
;	bne.s	.sli2warschon

	bsr	Makevoltable
;.sli2warschon

	sf	onvboostslider(A5)
	bra	.ma
.noidBoost
	cmp.w	#GD_Samplefreq,d4
	bne.s	.noidsam1

	move.l	gg_specialinfo(a1),a0	;Stringinfo Struktur
	move.l	si_Longint(A0),d1	;Wert des Gadgets
	cmp.l	#4000,d1
	bgt.s	.ok1
	move.l	#4000,d1
.ok1
	cmp.l	#65500,d1		;78000,d1
	ble.s	.ok2
	move.l	#65500,d1		;78000,d1
.ok2
	bra.s	.sli1set
	bra	.ma
.noidsam1
	cmp.w	#GD_MixingSlider,d4
	bne.s	.nosli

	sf	onmixingslider(A5)

	move.w	#10,d1
	mulu	d5,d1
.sli1set
	tst.b	onglobal(A5)
	bne.s	.sli1global

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist(a5),a0
	move.l	d1,P_Mixrate(A0,d0.w)
	bra.s	.sli1up
.sli1global
	lea	Prefslist+P_Mixrate(a5),a0
	moveq	#31-1,d0
.sli1all
	move.l	d1,(A0)
	add.w	#P_Sizeof,a0
	dbf	d0,.sli1all
.sli1up
	bsr	UpdateList		;Später nur Listview update !!!!
	bsr	CalcValues
	bra	.endit
.nosli
	cmp.w	#GD_Active,d4
	bne.s	.noACTI

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	add.l	d0,a0

	moveq	#0,d0
	tst.w	d5
	beq.s	.set_Acti
	moveq	#1,d0
.set_Acti
	sf 	echovalid
	move.b	d0,E_Enabled(A0)

	bsr	MakeLV			;Updatelist
	bsr	Makevoltable
	bsr	InitEchos
	bra	.endit
.noACTI

	cmp.w	#GD_Cross,d4
	bne.s	.noCross

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	add.l	d0,a0

	moveq	#0,d0
	tst.w	d5
	beq.s	.set_Cross
	moveq	#1,d0
.set_Cross
	sf 	echovalid
	move.b	d0,E_Special(A0)

	bsr	MakeLV			;Updatelist
	bsr	Makevoltable
	bsr	InitEchos
	bra	.endit
.noCross
	cmp.w	#GD_Delay,d4			;Delay Slidergadget
	bne.s	.noidDelay

;	tst.b	onglobal(A5)
;	bne.s	.sliDglobal

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	move.b	d5,E_Delay(A0,d0.w)

;	bra.s	.sliDup
;.sliDglobal
;	lea	Prefslist+P_Echos(a5),a0
;	move	Echo_MXactive(A5),d0
;	mulu	#Echo_Sizeof,d0
;	add.l	d0,a0
;	moveq	#31-1,d0
;.sliDall
;	move.w	d5,(A0)
;	add.w	#P_Sizeof,a0
;	dbf	d0,.sliDall
;.sliDup

	bsr	MakeLV			;Updatelist

	sf	OnDelaySlider(A5)
	bra	.ma
.noidDelay

	cmp.w	#GD_Intensity,d4			;Delay Slidergadget
	bne.s	.noidInten

;	tst.b	onglobal(A5)
;	bne.s	.sliIglobal

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	sf	echovalid
	move.b	d5,E_Volume(A0,d0.w)

;	bra.s	.sliIup
;.sliIglobal
;	lea	Prefslist+P_Echos(a5),a0
;	move	Echo_MXactive(A5),d0
;	mulu	#Echo_Sizeof,d0
;	add.l	d0,a0
;	moveq	#31-1,d0
;.sliIall
;	move.w	d5,(A0)
;	add.w	#P_Sizeof,a0
;	dbf	d0,.sliIall
;.sliIup
	bsr	Makevoltable
	bsr	InitEchos

	bsr	MakeLV			;Updatelist

	sf	OnIntensitySlider(A5)
	bsr	SetEcho_IntensityTX
	bra	.ma
.noidInten

.endit
.ma
	rts
*****************************************************************************
*                       SliderGadgets auswerten                             *
*****************************************************************************
TestDOWNGadgets
	cmp.w	#GD_ChooseEcho,d4
	bne.s	.noMX

	move.w	d5,Echo_MXactive(A5)

	bsr	SetEcho_Active
	bsr	SetEcho_Intensity
	bsr	SetEcho_IntensityTX
	bsr	SetEcho_Cross
	bsr	SetEcho_Delay
	bra	.endit
.noMX
	move.l	4.w,a6
	cmp.w	#39,lib_version(A6)
	blt	.endit

	cmp.w	#GD_MixingSlider,d4
	bne.s	.nosli

	st	onmixingslider(A5)
.nosli
	cmp.w	#GD_VBoost,d4
	bne.s	.nosli2

	st	onvboostslider(A5)
.nosli2

	cmp.w	#GD_Delay,d4
	bne.s	.nodelay

	st	ondelayslider(A5)
.nodelay

	cmp.w	#GD_Intensity,d4
	bne.s	.nointens
	st	OnIntensitySlider(A5)
.nointens

.endit
	rts
UpdateDownGadgets
	move.l	4.w,a6
	cmp.w	#39,lib_version(A6)
	blt	.endit

	tst.b	onmixingslider(A5)
	beq.s	.nosli1
	
	moveq	#GD_MixingSlider,d0
	bsr	_GADR			;Gadgetadresse in A0
	move.l	a0,a1
	bsr	.testup

	move.w	#10,d1
	mulu	d5,d1
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Mixrate(a5),a0
	move.l	d1,(A0,d0.w)

	bsr	SetRate
	bsr	CalcValues
	bra.w	.rts
.nosli1
	tst.b	onvboostslider(A5)
	beq.s	.nosli2
	
	moveq	#GD_VBoost,d0
	bsr	_GADR			;Gadgetadresse in A0
	move.l	a0,a1
	bsr	.testup

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_VBoost(a5),a0
	move.w	d5,(A0,d0.w)

	bsr	SetVBoost
	bsr	Makevoltable
	bra.s	.rts
.nosli2

	tst.b	ondelayslider(A5)
	beq.s	.nodelay
	
	moveq	#GD_Delay,d0
	bsr	_GADR			;Gadgetadresse in A0
	move.l	a0,a1
	bsr	.testup

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	move.b	d5,E_Delay(A0,d0.w)

	bra.s	.rts
.nodelay

	tst.b	OnIntensitySlider(A5)
	beq.s	.nointen
	
	moveq	#GD_Intensity,d0
	bsr	_GADR			;Gadgetadresse in A0
	move.l	a0,a1
	bsr	.testup

	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	sf	echovalid
	move.b	d5,E_Volume(A0,d0.w)

	bsr	Makevoltable
	bsr	InitEchos
	bsr	SetEcho_IntensityTX
	bra.s	.rts
.nointen

.endit
	moveq	#0,d0
	rts
.rts
	moveq	#1,d0
	rts
.testup
	movem.l	d1-d4/d6-a6,-(sp)

	move.l	a1,d7
	move.l	_dos(a5),a6
	moveq	#1,d1
	jsr	_LVOdelay(a6)
	move.l	d7,a1

	move.l	a1,a0			;gad
	move.l	gadsave(A5),a6		;lib
	sub.l	a2,a2			;req

	lea	numboo(a5),a1
	lea	mytags(a5),a3		;tags
	move.l	#GTSL_Level,(A3)+
	move.l	a1,(a3)+
	clr.l	(A3)+
	lea	mytags(a5),a3		;tags

	move.l	winhandle(A5),a1	;win

	jsr	_LVOGT_Getgadgetattrsa(A6)

	move.l	numboo(a5),d5

	movem.l	(sp)+,d1-d4/d6-a6
	rts
*****************************************************************************
*                 aktuelle Anzahl von Stimmen selektieren                   *
* Input: d0 = Num Voices                                                    *
*****************************************************************************
SelectEntry:
	movem.l	d0-a6,-(Sp)
	lea	datas,a5

	subq.w	#2,d0
	bpl.s	.hi
	moveq	#0,d0
.hi	move.w	d0,SelectedW(A5)	;aktuell angeclickter Modus
	move	d0,Currentnumvoc(a5)

	bsr	UpdateList

	movem.l	(sp)+,d0-a6
	rts
*****************************************************************************
*          Einsprung, was alles up to Date gebracht werden muß              *
*****************************************************************************
;;
UpdateList:
	tst.l	winhandle(a5)
	beq.s	.end
	movem.l	d0-a6,-(Sp)

	bsr	MakeLV			;Listview in Ordnung bringen
	bsr	SetVoic
	bsr	SetVBoost
	bsr	SetVBoostSlider
	bsr	SetRate
	bsr	SetLevel

	bsr	SetEcho_Active
	bsr	SetEcho_Intensity
	bsr	SetEcho_IntensityTX
	bsr	SetEcho_Cross
	bsr	SetEcho_Delay

	movem.l	(sp)+,d0-a6
.end
	rts
SetEcho_Delay:
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	add.l	d0,a0

	moveq	#0,d1
	move.b	E_Delay(a0),d1

	moveq	#GD_Delay,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTSL_Level,(A3)+
	move.l	d1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
SetEcho_Intensity:
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	add.l	d0,a0

	moveq	#0,d1
	move.b	E_Volume(a0),d1

	moveq	#GD_Intensity,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTSL_Level,(A3)+
	move.l	d1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
SetEcho_IntensityTX:
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	add.l	d0,a0

	moveq	#0,d1
	move.b	E_Volume(a0),d1
	mulu	#Intensity_txt_sz,d1
	lea	Intensity_txt(pc),a1
	add.l	d1,a1

	moveq	#GD_Gadget110,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTTX_Text,(A3)+
	move.l	a1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
Setecho_Cross:
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	add.l	d0,a0

	moveq	#0,d1
	move.b	E_Special(a0),d0
	cmp.b	#1,d0
	bne.s	.dis
	moveq	#1,d1
.dis	moveq	#GD_Cross,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTCB_Checked,(A3)+
	move.l	d1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
Setecho_Active:
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Echos(a5),a0
	add.l	d0,a0
	move	Echo_MXactive(A5),d0
	mulu	#Echo_Sizeof,d0
	add.l	d0,a0

	moveq	#0,d1
	move.b	E_Enabled(a0),d0
	beq.s	.dis
	moveq	#1,d1
.dis	moveq	#GD_Active,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTCB_Checked,(A3)+
	move.l	d1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
SetLevel:
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Mixrate(a5),a0
	move.l	(A0,d0.w),d1		;Mixrate
	divu	#10,d1
	and.l	#$ffff,d1

	moveq	#GD_MixingSlider,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTSL_Level,(A3)+
	move.l	d1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
SetRate
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Mixrate(a5),a0
	move.l	(A0,d0.w),d1

	moveq	#GD_Samplefreq,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTIN_Number,(A3)+
	move.l	d1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
SetVBoost:
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Vboost(a5),a0
	moveq	#0,d1
	move.w	(A0,d0.w),d1

	moveq	#GD_NumVBoost,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTTX_Text,(A3)+
	lea	numboo(a5),a1
	move.l	a1,(a3)+
	clr.l	(A3)+

	divu	#100,d1
	add.b	#" ",d1
	cmp.b	#" ",d1
	beq.s	.set
	add.b	#"0"-" ",d1
.set
	move.b	d1,(a1)+

	clr.w	d1
	swap	d1
	divu	#10,d1
	add.b	#"0",d1
	move.b	d1,(a1)+

	swap	d1
	move.b	#".",(a1)+
	add.b	#"0",d1
	move.b	d1,(a1)+

	clr.b	(a1)
	bra	SetGAD
SetVBoostSlider
	move.w	SelectedW(a5),d0
	mulu	#P_Sizeof,d0
	lea	Prefslist+P_Vboost(a5),a0
	moveq	#0,d1
	move.w	(A0,d0.w),d1		;VolBoost

	moveq	#GD_VBoost,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTSL_Level,(A3)+
	move.l	d1,(a3)+
	clr.l	(A3)+
	bra	SetGAD
SetVoic:
	moveq	#GD_VOICES,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	lea	NumVoc(A5),a1
	move.l	#GTTX_Text,(A3)+
	move.l	a1,(a3)+
	clr.l	(A3)+

	;---------- hier noch test auf Global -------------
	tst.b	onglobal(a5)
	beq.s	.ori

	move.b	#"G",(a1)+
	clr.b	(a1)
	bra.s	setgad
.ori
	move.l	SelectedL(a5),d0
	addq.l	#2,d0

	divu	#10,d0
	add.b	#"0",d0
	move.b	d0,(a1)+

	swap	d0
	add.b	#"0",d0	
	move.b	d0,(a1)+

	clr.b	(a1)
SetGAD
	lea	mytags(a5),a3
	move.l	winhandle(A5),a1
	suba.l	a2,a2
	move.l	gadsave(A5),a6
	jsr	_LVOGT_Setgadgetattrsa(A6)
	rts
MakeLV:
	push	all

	bsr	remlist		;Liste abhängen

	lea	list(a5),a0
	newlist	a0
	lea	Nodes(a5),a4		;1. Node

	move	Currentnumvoc(a5),d5
	moveq	#0,d4

	moveq	#31-1,d7
	moveq	#2,d6
	lea	Prefslist(A5),a3
.nodeloop
	lea	list(A5),a0		;gleich nach Alloc anhängen
	move.l	a4,a1			;(erspart Arbeit)
	addtail
	lea	ML_Nodename(a4),a1
	move.l	a1,ln_name(A4)

	cmp	d4,d5
	bne.s	.nosele
	tst	onplay
	beq.s	.nosele
	move.b	#`|`,(a1)+
.nosele
	addq	#1,d4

;	move.b	#` `,(a1)+

	move.w	P_Flags(a3),d0		;Flags
	and.b	#1,d0
	beq.s	.nodis
	move.b	#"(",(a1)+
.nodis
	move.b	#" ",(a1)+

	move.l	d6,d0
	moveq	#2,d1			;Anzahl der Stellen
	bsr	todez

	move.b	#`c`,(a1)+
	move.b	#`h`,(a1)+
	move.b	#`:`,(a1)+
	move.b	#` `,(a1)+

	move.l	P_Mixrate(A3),d0	;Mixingrate
	moveq	#5,d1			;Anzahl der Stellen
	bsr	todez

	move.b	#` `,(a1)+

	moveq	#0,d0
	move.w	P_VBoost(A3),d0		;Volumeboost
	divu	#10,d0			;durch 100 (wg. Nachkomma)
	and.l	#$fff,d0
	moveq	#2,d1
	bsr	todez
	move.b	#".",(a1)+

	clr.l	d0
	move.w	P_VBoost(A3),d0		;Volumeboost
	divu	#10,d0	
	swap	d0			;Nachkommastelle
	add.b	#"0",d0
	move.b	d0,(a1)+

	lea	P_Echos(A3),a0
	moveq	#`1`,d3
.echoz
	move.b	#` `,(a1)+
	move.b	#" ",(a1)+
	move.b	#`E`,(a1)+
	move.b	d3,(a1)+
	move.b	#`:`,(a1)+
	move.b	#` `,(a1)+
	moveq	#`-`,d0
	tst.b	E_Enabled(A0)
	beq.s	.set
	moveq	#`O`,d0
	tst.b	E_Special(A0)
	beq.s	.set
	moveq	#`X`,d0
.set	move.b	d0,(a1)+

	lea	Echo_Sizeof(A0),a0

	addq	#1,d3
	cmp.b	#numechos+`0`,d3
	ble.s	.echoz

	move.w	P_Flags(a3),d0		;Flags
	and.b	#1,d0
	beq.s	.nodis2
	move.b	#")",(a1)+
.nodis2
	clr.b	(a1)

	lea	P_Sizeof(A3),a3
	addq.w	#1,d6
	lea	ML_Sizeof(a4),a4
	dbf	d7,.nodeloop
	bsr	readdlist
	pop	all
	rts
***************** Liste vom Listview-Gadget entfernen ****************
Remlist
	movem.l	d0-a6,-(sp)
	tst.l	winhandle(a5)
	beq.s	.err

	moveq	#GD_LISTVIEW,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTLV_Labels,(a3)+
	move.l	#-1,(a3)+
	clr.l	(A3)+
	lea	mytags(a5),a3

	move.l	winhandle(A5),a1
	suba.l	a2,a2
	move.l	gadsave(A5),a6
	jsr	_LVOGT_Setgadgetattrsa(A6)
.err
	movem.l	(sp)+,d0-a6
	rts
**************** Liste wieder an Gadget anhängen *********************
readdlist
	movem.l	d0-a6,-(sp)
	tst.l	winhandle(A5)
	beq.s	.err

	moveq	#GD_LISTVIEW,d0
	bsr	_GADR			;Gadgetadresse in A0
	lea	mytags(a5),a3
	move.l	#GTLV_Labels,(a3)+
	lea	list(a5),a2
	move.l	a2,(a3)+
	move.l	#GTLV_Selected,(a3)+
	move.l	selectedL(a5),(a3)+
	move.l	#GTLV_MakeVisible,(A3)+
	move.l	selectedL(a5),(a3)+
	clr.l	(A3)
	lea	mytags(a5),a3

	move.l	winhandle(A5),a1
	suba.l	a2,a2
	move.l	gadsave(A5),a6
	jsr	_LVOGT_Setgadgetattrsa(A6)

	move.l	gadsave(A5),a6
	move.l	winhandle(a5),a0
	suba.l	a1,a1
	jsr	_LVOGT_refreshwindow(A6)
.err
	movem.l	(sp)+,d0-a6
	rts
**************** Hex to decimal ASCII conversion ************************
ToDEZ
	movem.l	d0-a0/a2-a6,-(Sp)
	lea	dectable(pc),a0
	move.w	d1,d2
	lsl.w	#2,d2
	add.w	d2,a0
	subq.w	#1,d1
.loopl
	moveq	#-1,d3
	move.l	-(a0),d2
.loop2l
	addq.b	#1,d3
	sub.l	d2,d0
	bcc.s	.loop2l
	add.l	d2,d0
	add.b	#"0",d3
	move.b	d3,(a1)+
	dbf	d1,.loopl
	movem.l	(sp)+,d0-a0/a2-a6
	rts
;*****************************************************************************
;*                        Amplifier-Init/Mix Routinen                        *
;*****************************************************************************
Checkfeatures:
;          - Initplayer -> Übergabe A0: Tagliste
;                                   A5: EP Globals
;                       -> zurück   D0: 0=OK, <>0=Error
;
	move.l	#EPAMT_Flags,d0
	jsr	ENPP_FindTag(A5)
	beq	.err

	moveq	#1,d2
	move.l	d0,d1
	move.l	d0,d6
	and.l	#EPAMB_WaitForStruct,d6
	and.l	#EPAMB_8Bit,d0
	bne	.ok
	moveq	#2,d2
	btst	#EPAMF_8BitUnsigned,d1
	bne	.ok

	moveq	#3,d2
	btst	#EPAMF_16Bit,d1			;erstmal nur 16 Bit signed
	beq	.err
.ok
	move.l	#EPAMT_Audiostructs,d0
	jsr	ENPP_FindTag(A5)
	beq	.err
	move.l	d0,d7

	move.l	#EPAMT_NumStructs,d0
	jsr	ENPP_FindTag(A5)
	beq	.err
	move.l	d7,a0

	subq.w	#1,d0			;Anzahl der Audio-Strukturen
	blt	.err

	moveq	#0,d1
	moveq	#0,d3
	lea	(a0),a2
.countvoc
	tst.w	AS_LeftRight(a2)
	bpl.s	.addL
	bmi.s	.addR
	bra.s	.noADD
.addL
	cmp.w	#2,AS_Leftright(a2)
	beq	.err
	addq.w	#1,d1
	bra.s	.noADD
.addR
	addq.w	#1,d3
.noadd
	lea	as_sizeof(a2),a2
	dbf	d0,.countvoc

	move.w	d3,d0
	add.w	d1,d0
	beq	.err			;wie, was, gar nichts ?

	cmp	#3,d2
	bne.s	.normal8bit

	cmp	#1,d3
	bne	.err
	cmp	#1,d1
	bne	.err

.normal8bit

	subq.w	#2,d0
	bgt.s	.hi1
	moveq	#0,d0
.hi1
	mulu	#P_Sizeof,d0
	
	lea	Prefslist+datas,a1
	lea	(a1,d0.w),a1
	
	move.w	P_Flags(A1),d0		;Flags.w (Bit0=disable)
	and.b	#1,d0
	bne	.err			;Modus disabled !!

	moveq	#0,d0
	rts
.err
	moveq	#-1,d0
	rts

;---------------- Routinen für den 16 Stimmen 14 Bit Player --------------------
; Init/End
;          - Initplayer -> Übergabe A0: Tagliste
;                                   A5: EP Globals
;                       -> zurück   D0: 0=OK, <>0=Error
;
; Start-Stop: Startint (keine Übergabeargumente)
;
;             Stopint  (keine Übergabeargumente)
;
Init:
	move.l	#EPAMT_Flags,d0
	jsr	ENPP_FindTag(A5)
	beq	.err

	moveq	#1,d2
	move.l	d0,d1
	move.l	d0,d6
	and.l	#EPAMB_WaitForStruct,d6
	and.l	#EPAMB_8Bit,d0
	bne	.ok
	moveq	#2,d2
	btst	#EPAMF_8BitUnsigned,d1
	bne	.ok

	moveq	#3,d2
	btst	#EPAMF_16Bit,d1			;erstmal nur 16 Bit signed
	beq	.err
.ok
	move.w	d2,fformat

	move.l	#EPAMT_Audiostructs,d0
	jsr	ENPP_FindTag(A5)
	beq	.err
	move.l	d0,d7

	move.l	#EPAMT_NumStructs,d0
	jsr	ENPP_FindTag(A5)
	beq	.err
	move.l	d7,a0

	move	d0,numstructs

	subq.w	#1,d0			;Anzahl der Audio-Strukturen
	blt	.err

	moveq	#0,d1
	moveq	#0,d2
	lea	(a0),a2
.countvoc
	tst.w	AS_LeftRight(a2)
	bpl.s	.addL
	bmi.s	.addR
	bra.s	.noADD
.addL
	cmp.w	#2,AS_Leftright(a2)
	beq	.err
	addq.w	#1,d1
	bra.s	.noADD
.addR
	addq.w	#1,d2
.noadd
	lea	as_sizeof(a2),a2
	dbf	d0,.countvoc

	st	onplay

	move.w	d2,d0
	add.w	d1,d0
	beq	.err			;wie, was, gar nichts ?

	move.l	#mix,mixad1
	move.l	#mix2,mixad2

	cmp	#3,fformat
	bne.s	.normal8bit

	cmp	#1,d2
	bne	.err
	cmp	#1,d1
	bne	.err

	move.l	#mix16,mixad1
.normal8bit

	subq.w	#2,d0
	bgt.s	.hi1
	moveq	#0,d0
.hi1
	mulu	#P_Sizeof,d0
	
	lea	Prefslist+datas,a1
	lea	(a1,d0.w),a1
	move.l	a1,usedmode
	
	move.w	P_Flags(A1),d0		;Flags.w (Bit0=disable)
	and.b	#1,d0
	bne	.err			;Modus disabled !!

	move.w	d1,numleft
	move.w	d2,numright

	sf	Private_AS
	move.l	a0,epg_audiostruct(A5)	;Audiostruct setzen
	tst.l	d6			;Flag für "WaitforStruct" gesetzt ?
	beq.s	.normal
	st	Private_AS
	lea	Extra_AS,a0		;ja, also eigene AS Struktur verwenden
.normal
	move.l	a0,myAudioStruct	;AudioStruct vom Replayer sichern
;	move.l	a0,0

	bsr	SetPlaymode

	bsr	InitTables
	bne.s	.err2

	move.w	numleft,d0
	add.w	numright,d0
	bsr	SelectEntry

	bsr	Copy_AS2

	moveq	#0,d0
	rts
.err
	moveq	#-1,d0
.err2
	sf	onplay
	rts

	;-------------------- (noch) keine Funktion -------------------
END:
	bsr	myFreemem
	clr.b	onplay
	clr.l	usedmode

	move	#-1,Currentnumvoc+datas		;kein Modul am Spielen

	move.w	#15,$dff096
	clr.w	$dff0a8
	clr.w	$dff0b8
	clr.w	$dff0c8
	clr.w	$dff0d8

	moveq	#0,d0
	rts

***************************************************************************
*              kopiert neue Audio-Struct auf die eigene AS Struktur rüber *
***************************************************************************
Copy_AS:			;mit Umschaltung von dff09a
		push	all
		lea	$dff09a,a6

		tst.b	onplay
		beq.w	.err

		move.l	MYEpBase(pc),a0
		move.l	epg_audiostruct(A0),d0
		beq.w	.err
		move.l	d0,a0			;Original

;		move.l	myAudioStruct(pc),a1	;meine Extra-Struktur
		lea	Extra_AS,a1

		move	numstructs(pc),d0
		subq	#1,d0
		bmi.w	.err

		move	#1<<7,(a6)		;Audio Int verbieten
.all
		move.l	AS_ChangeFlags(a0),d1
		btst	#ASChF_Adr,d1
		beq.s	.noad
		move.l	AS_CurrentAdr(a0),AS_CurrentAdr(a1)
		clr.l	AS_CurrentPos(a1)
		clr.l	AS_CurrentFPos(a1)
		clr.b	AS_NoLoop(a1)
.noad
		btst	#ASChF_Len,d1
		beq.s	.nolen
		move.l	AS_SampleSize(a0),AS_SampleSize(a1)
.nolen
		btst	#ASChF_RepAdr,d1
		beq.s	.norepadr
		move.l	AS_RepeatAdr(a0),AS_Repeatadr(a1)
.norepadr
		btst	#ASChF_RepLen,d1
		beq.s	.noreplen
		move.l	AS_RepeatSize(a0),AS_RepeatSize(a1)
.norepLen
		move.w	AS_Period(a0),AS_Period(a1)
		move.w	AS_LeftVolume(a0),AS_LeftVolume(a1)
		move.w	AS_RightVolume(a0),AS_RightVolume(a1)
		move.w	AS_DmaBit(a0),AS_DmaBit(a1)
		move.w	AS_LeftRight(a0),AS_LeftRight(a1)
		move.b	AS_LoopFlag(a0),AS_LoopFlag(a1)
		clr.l	AS_ChangeFlags(a0)

		lea	AS_Sizeof(a0),a0
		lea	AS_Sizeof(a1),a1
		dbf	d0,.all

		move	#1<<7!$8000,(a6)	;Kram kopiert, also Audio Int wieder an
.err
		pop	all
		rts


Copy_AS2:
		push	all

		tst.b	onplay
		beq.s	.err

		move.l	myAudioStruct(pc),a1	;meine Extra-Struktur

		move.l	MYEpBase(pc),a0
		move.l	epg_audiostruct(A0),d0
		beq.s	.err
		move.l	d0,a0			;Original

		move	numstructs(pc),d0
		subq	#1,d0
		bmi.s	.err
.all
		moveq	#AS_Sizeof-1,d1
.cp		move.b	(a0)+,(a1)+
		dbf	d1,.cp

		dbf	d0,.all
.err
		pop	all
		rts


*************************************************************************
*              Mem für Tabellen besorgen und Tabellen init              *
*************************************************************************
InitTables:
	movem.l	d1-a6,-(Sp)
	
	move.l	#64*1024*2,d0
	moveq	#MEMF_PUBLIC!MEMF_FAST,d1
	move.l	4.w,a6
	jsr	_LVOallocmem(A6)
	move.l	d0,buff14
	beq.b	myFreemem2
	add.l	#$10000,d0
	move.l	d0,buff14_2

	move.l	#66*256*2,d0

	cmp.w	#3,fformat
	blo	no16it

	move.l	#$10000*2+256,d0	;65000 Werte mal Wortbreite
no16it
	move.l	d0,VTabsize
	moveq	#MEMF_PUBLIC!MEMF_FAST,d1
	move.l	4.w,a6
	jsr	_LVOallocmem(A6)
	move.l	d0,vtab
	beq.b	myFreemem2

	add.l	#255,d0
	and.l	#~$ff,d0
	move.l	d0,Vtabaddr

	bsr	do14tab
	bsr	Makevoltable

	movem.l	(sp)+,d1-a6
	moveq	#0,d0
	rts
***************************************************************************
*                 Speicher von Divtab / VolTab freigeben                  *
***************************************************************************
myFreemem
	movem.l	d1-a6,-(sp)
myFreemem2
	move.l	4.w,a6

	move.l	vtab(pc),d0
	beq.s	.empty1
	move.l	d0,a1

	move.l	VTabsize,d0
	jsr	_LVOfreemem(A6)
	clr.l	vtab
.empty1

	move.l	buff14(pc),d0
	beq.s	.empty2
	move.l	d0,a1
	move.l	#64*1024*2,d0
	jsr	_LVOfreemem(A6)
	clr.l	buff14
	clr.l	buff14_2
.empty2
	movem.l	(sp)+,d1-a6
	moveq	#-1,d0
	rts
****************************************************************************
*                        Divisionstabellen erzeugen                        *
****************************************************************************
do14tab:
	move.l	buff14(pc),d0
	beq.s	.rts
	move.l	d0,a0
	lea	(a0),a1
	add.l	#2*32768,a1			;Mitte der Tabelle

	lea	AdditiveArray(pc),a1

	bsr	_CreateTable
	rts

	moveq	#0,d7
.loo	move	d7,d2
	bpl.b	.plus

	neg	d2
	move	d2,d3
	lsr	#7,d2

	cmp	#128,d2
	bls.s	.ok1
	move	#128,d2
	move	d2,d3
.ok1
	neg.b	d2

	lsr.b	#1,d3
	neg	d3
	move.b	d2,(a0)+
	move.b	d3,(a0)+
	addq.l	#1,d7
	cmp.l	#$10000,d7
	bne.b	.loo
.rts
	rts

.plus	move	d2,d3
	lsr	#7,d2
	lsr.b	#1,d3
	cmp	#127,d2
	bls.s	.ok
	moveq	#127,d2
	moveq	#127,d3
.ok	move.b	d2,(a1)+
	move.b	d3,(a1)+
	addq.l	#1,d7
	cmp.l	#$10000,d7
	bne.b	.loo
	rts

		; Parameters

		; a0 = Table address
		; (MUST have enough space for 65536 UWORDS)
		; a1 = Additive Array
		; 256 UBYTEs
		;
		; the table is organized as follows:
		; 32768 UWORDS positive range, ascending order
		; 32768 UWORDS negative range, ascending order
		; access: (a0,d0.l*2)
		; where d0.w is signed word sample data
		; and the upper word of d0.l is *cleared!*

_CreateTable	movem.l	a2/d2-d6,-(sp)

		lea	128(a1),a2
		add.l	#2*32768,a0		; place at the middle of the table

		move.l	a2,a1			; count the number of steps
		moveq	#128-1,d0		; in the positive range
		moveq	#0,d5
.countpositive	move.b	(a1)+,d1
		ext.w	d1
		ext.l	d1
		add.l	d1,d5
		dbra	d0,.countpositive	; d5=number of steps
		move.l	#32768,d6		; reset stretch counter
		
		move.l	a2,a1			; middle value in calibdata
		move.w	#32768-1,d0		; number of positive values -1
		moveq	#0,d1			; HI value
		moveq	#0,d2			; LO value
		moveq	#0,d3			; counter
.fetchnext2	move.b	(a1)+,d4		; add calibtable to counter
		ext.w	d4
		add.w	d4,d3
.outerloop2	tst.w	d3
		bgt.s	.positive2
.negative2	addq.w	#1,d1			; increment HI value
		sub.w	d4,d2			; reset LO value
		bra.s	.fetchnext2
.positive2	move.b	d1,(a0)+		; store HI and LO value
		move.b	d2,(a0)+
		sub.l	d5,d6			; stretch the table
		bpl.s	.repeat2		; to 32768 entries
		add.l	#32768,d6
		addq.w	#1,d2			; increment LO value
		subq.w	#1,d3			; decrement counter
.repeat2	dbra	d0,.outerloop2

		move.l	a2,a1			; count the number of steps
		moveq	#128-1,d0		; in the negative range
		moveq	#0,d5
.countnegative	move.b	-(a1),d1
		ext.w	d1
		ext.l	d1
		add.l	d1,d5
		dbra	d0,.countnegative	; d5=number of steps
		move.l	#32768,d6		; reset stretch counter
		
		sub.l	#2*32768,a0		; again place at the middle of the table

		move.l	a2,a1			; middle value in calibdata
		move.w	#32768-1,d0		; number of negative values -1
		moveq	#-1,d1			; HI value
		moveq	#-1,d2			; LO value
		moveq	#0,d3			; counter
.fetchnext1	move.b	-(a1),d4		; add calibtable to counter
		ext.w	d4
		add.w	d4,d3
		add.w	d4,d2			; maximize LO value
.outerloop1	tst.w	d3
		bgt.s	.positive1
.negative1	subq.w	#1,d1
		bra.s	.fetchnext1
.positive1	move.b	d2,-(a0)		; store LO and HI value
		move.b	d1,-(a0)
		sub.l	d5,d6			; stretch the table
		bpl.s	.repeat1		; to 32768 entries
		add.l	#32768,d6
		subq.w	#1,d2			; decrement lo value
		subq.w	#1,d3			; decrement counter
.repeat1	dbra	d0,.outerloop1

		movem.l	(sp)+,a2/d2-d6
		rts

****************************************************************************
*                        Volume Tabelle erzeugen                           *
****************************************************************************
Makevoltable:
	push	all
	
	move.b	onplay(pc),d0
	beq.w	.rts

	move.l	usedmode(pc),d0
	beq	.rts
	move.l	d0,a0

	move.w	P_Vboost(a0),d4			;VBoost (auf xx.x bezogen,
						;z.B. 082 für 8.2)
	subq	#2,d4
	mulu	#10,d4				;mal 10 (höhere Genauigkeit)

	lea	P_Echos(a0),a1			;Echos einbeziehen und den Volumewert
	moveq	#NumEchos-1,d2
	moveq	#0,d3
.EchoCalc					;verkleinern
	move.b	E_Enabled(a1),d1
	beq.s	.next_E
	moveq	#0,d0
	move.b	E_Volume(a1),d0			;Nummer
	moveq	#1,d1				;Faktor rauskriegen
	lsl	d0,d1				;(50 / 2^n = Level in %)
	moveq	#50,d0				;
	divu	d1,d0				;
	add.w	d0,d3				;
.next_E	lea	Echo_Sizeof(a1),a1
	dbf	d2,.EchoCalc
					;in d3: Summe der Prozentanzahl aller Echos

	move.l	#32767*100,d0		;32767 = max. Ausschlag für 1 Kanal
	tst	d3
	beq	loud$
	move.l	#32767*70,d0		;32767 = max. Ausschlag für 1 Kanal
loud$
	add	#100,d3			;%-Wert der Echos + Master
	divu.l	d3,d0			;Echos berücksichtigen

	mulu	#100,d4			;Master mal 100 (wg. %)
	divu	d3,d4			;Master umrechnen auf neue Werte

	move.l	vtabaddr(pc),d1
	beq.s	.rts
	move.l	d1,a0

	moveq	#0,d3
	move.w	numleft(pc),d3
	cmp	numright(pc),d3
	bge.s	.take
	move	numright(pc),d3
.take
				; d3: max. # of Channels
	divu.l	d3,d0		; max. Amplitude für einzelnen Kanal bei x Kanälen

	mulu	#100,d3		; Lautstärke etwas absenken wg. PS3M Bug ------------------- !!!

	moveq	#0,d7		; "index"

	cmp.w	#3,fformat
	beq	do16bitsigned

	cmp	#1,fformat
	beq.b	signed2

.lop	move	d7,d6
	tst.b	d7
	bmi.b	.above

	and	#127,d6
	move	#128,d5
	sub	d6,d5
	lsl	#8,d5
	move	d7,d6
	lsr	#8,d6
	mulu	d6,d5
	divu	#63,d5
	mulu	d4,d5			;Boost
	divu	d3,d5
	neg	d5
	move	d5,(a0)+
	addq	#1,d7
	cmp	#256*65,d7
	bne.b	.lop
.rts
	pop	all
	rts

.above	and	#127,d6
	lsl	#8,d6

	move	d7,d5
	lsr	#8,d5
	mulu	d6,d5
	divu	#63,d5
	mulu	d4,d5			;Boost
	divu	d3,d5
	move	d5,(a0)+
	addq	#1,d7
	cmp	#256*65,d7
	bne.b	.lop
	pop	all
	rts

signed2
.lop	move	d7,d6
	tst.b	d7
	bpl.b	.above

	and	#127,d6
	move	#128,d5
	sub	d6,d5
	lsl	#8,d5
	move	d7,d6
	lsr	#8,d6
	mulu	d6,d5
	divu	#63,d5
	mulu	d4,d5			;Boost
	divu.l	d3,d5

	cmp.l	d0,d5
	bls	.lo1
	move	d0,d5
.lo1
	neg	d5
	move	d5,(a0)+
	addq	#1,d7
	cmp	#256*65,d7
	bne.b	.lop
	pop	all
	rts

.above	and	#127,d6
	lsl	#8,d6

	move	d7,d5
	lsr	#8,d5
	mulu	d6,d5
	divu	#63,d5
	mulu	d4,d5			;Boost
	divu.l	d3,d5
	cmp.l	d0,d5
	bls	.lo2
	move	d0,d5
.lo2	move	d5,(a0)+
	addq	#1,d7
	cmp	#256*65,d7
	bne.b	.lop
	pop	all
	rts

do16bitsigned:
	move	#32768-1,d7			;65k Durchläufe
	moveq	#0,d1
.tab1
	move	d1,d2

	mulu	d4,d2			;Boost
	divu.l	d3,d2

	cmp.l	d0,d2
	bls	.lo1
	move	d0,d2
.lo1
	move	d2,(a0)+

	addq	#1,d1
	dbf	d7,.tab1

	move	#32768-1,d7			;65k Durchläufe
	move	#32768,d1
.tab2
	move	d1,d2

	mulu	d4,d2			;Boost
	divu.l	d3,d2

	cmp.l	d0,d2
	bls	.lo2
	move	d0,d2
.lo2
	neg	d2
	move	d2,(a0)+

	subq	#1,d1
	dbf	d7,.tab2

	pop	all
	rts

***************************************************************************
*  Abspielmodus festlegen, sprich Auswahl zwischen Mono-Stereo-Surround   *
* Input: D0 - Stereo Basisbreite                                          *
***************************************************************************
SetPlaymode:
	movem.l	d0-a6,-(sp)

	lea	Buffer0a,a0		;Surround Wiedergabe
	lea	Buffer1a,a1
	lea	Buffer2a,a2
	lea	Buffer3a,a3
	lea	copybuf14,a4
	move.l	a3,SpecialBuffer1	;rechter Kanal nach links
	move.l	a2,SpecialBuffer2	;linker Kanal nach rechts

	lea	Buffer0,a6
	move.l	a0,(a6)+
	move.l	a1,(a6)+
	move.l	a2,(a6)+
	move.l	a3,(a6)+
	move.l	a4,(a6)+

	lea	myupsstruct,a1
	move.w	#64,ups_voice1vol(a1)
	move.w	#64,ups_voice2vol(a1)
	move.w	#1,ups_voice3vol(a1)
	move.w	#1,ups_voice4vol(a1)

	movem.l	(sp)+,d0-a6
	rts

;------------------ Routinen für den FastRamPlayer -----------------------
StartINT:
	push	d1-a6

	lea	OLDINT0(pc),a0
	move.l	#-1,(a0)

;-------------------- hier alloc Audio -------------------------
	jsr	ENPP_AllocAmigaAudio(a5)
	tst.l	d0
	bne	fail$
;---------------------------------------------------------------
	bset	#1,$bfe001
	move.l	MyEPBase(pc),a0
	tst.b	DTG_LED(a0)
	beq.s	.off
	bclr	#1,$bfe001
.off
					;Audio Interrupt disable
	move.w	#$780,$dff09c		;Interrupt Request Hardwarehack

	movem.l	d0-a6,-(sp)		;Audio Interrupt handler durch
					;eigene ersetzen
	move.l	4,a6
	lea	Aud0Interrupt(pc),a1
	moveq	#7,d0
	jsr	-162(a6)			;Setintvektor
	move.l	d0,Oldint0

	movem.l	(sp)+,d0-a6

	move.w	#$8080,$dff09a			;Interrupt Enable Hardwarehack

	bsr	StartDMA

	lea	myupsstruct,a1
	move.w	#UPSB_Adr!UPSB_LEN!UPSB_Per!UPSB_Vol!UPSB_DMACON,ups_flags(a1)
	move.w	#15,UPS_DmaCon(a1)
	clr.w	UPS_Enabled(a1)

	move.w	#64,ups_voice1vol(a1)
	move.w	#64,ups_voice2vol(a1)
	move.w	#1,ups_voice3vol(a1)
	move.w	#1,ups_voice4vol(a1)
	clr.l	tmpvol
	clr.w	tmpvol2

	move.l	newmixingperiod(pc),d0
	move.w	d0,ups_voice1per(a1)
	move.w	d0,ups_voice2per(a1)
	move.w	d0,ups_voice3per(a1)
	move.w	d0,ups_voice4per(a1)

	move.w	#SAMLEN*NumBuffers,ups_voice1len(A1)
	move.w	#SAMLEN*NumBuffers,ups_voice2len(A1)
	move.w	#SAMLEN*NumBuffers,ups_voice3len(A1)
	move.w	#SAMLEN*NumBuffers,ups_voice4len(A1)

	lea	Buffer0a,a0
	move.l	a0,ups_voice1adr(a1)
	lea	Buffer1a-Buffer0a(a0),a0
	move.l	a0,ups_voice2adr(a1)
	lea	Buffer2a-Buffer1a(a0),a0
	move.l	a0,ups_voice3adr(a1)
	lea	Buffer3a-Buffer2a(a0),a0
	move.l	a0,ups_voice4adr(a1)

	moveq	#0,d0
fail$
	pop	d1-a6
	tst.l	d0
	rts
StopINT
	jsr	ENPP_FreeAmigaAudio(a5)

	move.l	Oldint0(pc),d0
	cmp.l	#-1,d0
	beq.s	.empty

	move.w	#$780,$dff09a
	move.w	#$f,$dff096			;DMA Stoppen

	move.l	4,a6
	move.l	Oldint0(pc),a1
	moveq	#7,d0
	jsr	-162(a6)			;Setintvektor

	move.w	#$780,$dff09a

	moveq	#-1,d0
	move.l	d0,OldInt0
	sf 	echovalid

	moveq	#0,d0
.empty
	rts
;============ Puffer löschen und DMA starten =============================
StartDMA:
	move.w	#$f,$dff096		;DMA Stop

	lea	Buffer0a,a0
	move.w	#[ENDBUFFER-Buffer0a]/2-1,d0
.clr
	clr.w	(A0)+
	dbf	d0,.clr

	lea	StartBSSBuffer,a0	;Echo Puffer löschen
	move.w	#[ENDBSSBUFFER-StartBSSBuffer]/2-1,d0
.clr2
	clr.w	(a0)+
	dbf	d0,.clr2

	bsr	CalcValues
	clr.l	tmpvol
	clr.w	tmpvol2
	move.l	newmixingperiod(pc),mixingperiod

					;Anfangsadressen setzen
	move.w	#$ff,$dff09e		;Modulierungen aller Art aus !
		
	lea	$dff0a0,a5
	move.w	#SamLEN,d0
	move.l	#SAMLEN*2,Lastbuffer

	move.l	#0,Tempbuffer_C		;für Echo
	move.w	#0,Num_C		;für Echo

	bsr	InitEchos

	move.l	mixingperiod(pc),d1

	move.l	Buffer0,a0
	move.l	a0,(a5)
	move.w	d0,4(A5)
	move.w	d1,6(a5)
	clr.w	8(A5)

	lea	$10(a5),a5	
	move.l	Buffer1,a0
	move.l	a0,(a5)
	move.w	d0,4(A5)
	move.w	d1,6(a5)
	clr.w	8(A5)

	lea	$10(a5),a5	
	move.l	Buffer2,a0
	move.l	a0,(a5)
	move.w	d0,4(A5)
	move.w	d1,6(a5)
	clr.w	8(A5)

	lea	$10(a5),a5	
	move.l	Buffer3,a0
	move.l	a0,(a5)
	move.w	d0,4(A5)
	move.w	d1,6(a5)
	clr.w	8(A5)

	bsr	CH_DMAWait		;warten bis DMA wirklich gestoppt
	move.w	#$800f,$dff096		;DMA Start
CH_DMAWait
	movem.l	d0/d1,-(SP)
	moveq	#16,d0
.wart2
	move.b	$dff006,d1
.wart
	cmp.b	$dff006,d1
	beq	.wart
	dbf	d0,.wart2
	movem.l	(sp)+,d0/d1
	rts
CalcValues:
;	move.l	#46000,d7			;Samplingrate

	move.b	onplay(pc),d0
	beq.s	skipcalc

	move.l	usedmode,a0
	move.l	P_Mixrate(a0),d7
	move.l	d7,playmixrate
CalcnewmixingPeriod:
	move.l	#14187580/4,clock		;Clock constant

	move.l	audiorate(pc),d2

	move.l	d2,d0
	move.l	d7,d1				;mixingrate(pc),d1
	divu	d1,d0
	move.l	d2,d1
	divu	d0,d1
	swap	d1
	clr	d1
	swap	d1
	move.l	d1,mrate

	move.l	d2,d0
	divu	d1,d0
	swap	d0
	clr	d0
	swap	d0
	move.l	d0,newmixingperiod
skipcalc
	rts
InitEchos:
	push	d0-a6
	sf	echovalid
	move.b	onplay(pc),d0
	beq.w	.skipcalc

	move.l	usedmode(pc),a1
	lea	P_Echos(a1),a1
	moveq	#NumEchos-1,d1
	lea	EchoAD_L(pc),a2
	lea	EchoAD_R(pc),a3
.Echos
	move.b	E_Enabled(a1),d0
	beq.w	.next_E

	lea	CopyEcho14L_2(pc),a4
	lea	CopyEcho14R_2(pc),a6
	move.b	E_Volume(a1),d0
	bne.s	.no50
	cmp.b	#1,E_Special(a1)
	beq.s	.crozz1
	move.l	a4,(a2)+
	move.l	a6,(A3)+
	bra.w	.next_E
.crozz1
	move.l	a6,(a2)+
	move.l	a4,(A3)+
	bra.w	.next_E
.no50
	lea	CopyEcho14L_4(pc),a4
	lea	CopyEcho14R_4(pc),a6
	subq.b	#1,d0
	bne.s	.no25
	cmp.b	#1,E_Special(a1)
	beq.s	.crozz2
	move.l	a4,(a2)+
	move.l	a6,(A3)+
	bra.s	.next_E
.crozz2
	move.l	a6,(a2)+
	move.l	a4,(A3)+
	bra.s	.next_E
.no25
	lea	CopyEcho14L_8(pc),a4
	lea	CopyEcho14R_8(pc),a6
	subq.b	#1,d0
	bne.s	.no12
	cmp.b	#1,E_Special(a1)
	beq.s	.crozz3
	move.l	a4,(a2)+
	move.l	a6,(A3)+
	bra.s	.next_E
.crozz3
	move.l	a6,(a2)+
	move.l	a4,(A3)+
	bra.s	.next_E
.no12

	lea	CopyEcho14L_16(pc),a4
	lea	CopyEcho14R_16(pc),a6
	subq.b	#1,d0
	bne.s	.no6
	cmp.b	#1,E_Special(a1)
	beq.s	.crozz4
	move.l	a4,(a2)+
	move.l	a6,(A3)+
	bra.s	.next_E
.crozz4
	move.l	a6,(a2)+
	move.l	a4,(A3)+
	bra.s	.next_E
.no6

	lea	CopyEcho14L_32(pc),a4
	lea	CopyEcho14R_32(pc),a6
	subq.b	#1,d0
	bne.s	.no3
	cmp.b	#1,E_Special(a1)
	beq.s	.crozz5
	move.l	a4,(a2)+
	move.l	a6,(A3)+
	bra.s	.next_E
.crozz5
	move.l	a6,(a2)+
	move.l	a4,(A3)+
	bra.w	.next_E
.no3
	move.l	a4,(a2)+				;nur zur Sicherheit
	move.l	a6,(A3)+
.next_E
	lea	Echo_Sizeof(a1),a1
	dbf	d1,.Echos

	st	echovalid
.skipcalc
	pop	d0-a6
	rts
;=========================================================================
INT_AUD:
	movem.l d0-a6,-(sp)
;	move.w	#$fff,$dff180
	move.l	MyEPBase(pc),a5
	move.w	#1<<7,$dff09c			;Interrupt Request Rücksetzen

	move.l	Lastbuffer(pc),d0
	if	NumChipBuffers=2
	eor.l	#SAMLEN*2,d0			;128 Worte
	else
	add.l	#SAMLEN*2,d0
	cmp.l	#SAMLEN*2*NumChipBuffers,d0
	blo.s	.lo
	moveq	#0,d0
.lo
	endc
	move.l	d0,LastBuffer

	lea	$dff0a0,a1
	movem.l	Buffer0(pc),d3-d6

	move.w	#$800f,$dff096-$dff0a0(a1)	;DMA richtig setzen

	add.l	d0,d3
	move.l	d3,(a1)

	add.l	d0,d4
	move.l	d4,$10(a1)

	add.l	d0,d5
	move.l	d5,$20(a1)
	
	add.l	d0,d6
	move.l	d6,$30(a1)

;	bsr	SetHardWare

;	move.w	#$000,$dff180

	move.l	4.w,a6
	lea	Int_loopStruct,a1
	cmp.b	#NT_Interrupt,ln_type(a1)
	bne.s	.skip

	jsr	-180(a6)	;_LVOcause

;	move.w	#$005,$dff180
	movem.l	(sp)+,d0-a6
	rts
.skip
;-- Typ der Struktur ist NT_Softint, somit kommt der Prozessor beim Mixen nicht
;-- hinterher -> Mixrate verringern

	move.l	playmixrate(pc),d7
	sub.l	#6000,d7
	cmp.l	#4000,d7
	bge.s	.ok
	move.l	#3800,d7
.ok
	move.l	d7,playmixrate
	bsr	CalcnewmixingPeriod
	move.l	newmixingperiod(pc),mixingperiod

;	move.w	#$f00,$dff180
	movem.l	(sp)+,d0-a6
	rts
;----------------------------------------------------------------------------------------------------
;--------------------------- setzt Lautstärke, Länge, Period neu ------------------------------------
;----------------------------------------------------------------------------------------------------
SetHardWare:
		move	#Samlen,d7
		lea	$dff0a0,a1

		move.w	#$800f,$dff096-$dff0a0(a1)	;DMA richtig setzen

		move	d7,4(a1)
		move	d7,$10+4(a1)
		move	d7,$20+4(a1)
		move	d7,$30+4(a1)
	
		move.l	newmixingperiod(pc),d1
		move.l	d1,mixingperiod
		move.w	d1,6(a1)
		move.w	d1,6+$10(a1)
		move.w	d1,6+$20(a1)
		move.w	d1,6+$30(a1)
	
		move.l	MyEPBase(pc),a5
		move.l	dtg_SndVol(A5),d0	; dtg_SndVol & dtg_SndLBal
		move.w	dtg_SndRBal(A5),d1	; dtg_SndVol & dtg_SndLBal
	
		cmp.w	tmpvol2(pc),d1
		bne.s	newvol$
		cmp.l	tmpvol(pc),d0
		beq.s	weiter$
newvol$
		move.l	d0,tmpvol
		move.w	d1,tmpvol2
	
		move.w	DTG_SndLBal(a5),d0
		mulu	DTG_SndVol(a5),d0
		lsr.w	#6,d0				; durch 64
	
		move.w	DTG_SndRBal(a5),d1
		mulu	DTG_SndVol(a5),d1
		lsr.w	#6,d1				; durch 64
	
		move	d1,d2
		lsr	#4,d2
		beq.s	.zero1
		moveq	#1,d2
.zero1

		move	d0,d3
		lsr	#4,d3
		beq.s	.zero2
		moveq	#1,d3
.zero2
		movem.w	d0-d3,calcvol
		bra.s	weiter2$
weiter$		movem.w	calcvol(pc),d0-d3
weiter2$	move.w	d0,8(A1)
		move.w	d1,8+$10(A1)
		move.w	d2,8+$20(A1)		;!!
		move.w	d3,8+$30(A1)		;!!
		rts
;----------------------------------------------------------------------------------------------------
;------------------------------- Mixroutine Main Loop -----------------------------------------------
;----------------------------------------------------------------------------------------------------
DoMix:
	movem.l	d0-a6,-(Sp)
	bsr	SetHardware

	ifne	CPUtest
	move	#$f0f,$dff180
	endc

;	move.l	MyEPBase(pc),a5
;	move.l	epg_audiostruct(A5),a4			;Audiostruct setzen
	move.l	myaudiostruct(pc),a4

	move	numstructs,d7
	subq.w	#1,d7
	blt.w	.noleft
	
	move.l	mixad1,a1
	lea	TempBuffer,a2
	add.l	Tempbuffer_C(pc),a2

.loo	tst.w	AS_LeftRight(a4)
	ble.s	.n

	movem.l	a1/a2/a4/d7,-(sp)
	jsr	(a1)				; Mix
	movem.l	(sp)+,a1/a2/a4/d7
	move	#1,chans
	lea	AS_Sizeof(a4),a4
	subq	#1,d7
	bra.b	.loo2

.n	lea	AS_Sizeof(a4),a4
	dbf	d7,.loo
	bra.b	.ddq

.loo2	cmp	#1,numleft
	beq.b	.ddq

	move.l	mixad2,a1
.loka	tst.w	AS_LeftRight(a4)
	ble.s	.n2

	movem.l	a1/a2/a4/d7,-(sp)
	jsr	(a1)
	movem.l	(sp)+,a1/a2/a4/d7
	
.n2	lea	AS_Sizeof(a4),a4
	dbf	d7,.loka

.ddq
	move.b	Echovalid(pc),d0
	beq.s	.no_echo

	move.l	usedmode(pc),a1
	lea	P_Echos(a1),a1
	moveq	#NumEchos-1,d1
	lea	Echoad_L(pc),a3
.Echos
	move.b	E_Enabled(a1),d0
	beq.s	.next_E

	moveq	#0,d0
	move.b	E_Delay(a1),d0

	lea	Tempbuffer,a0
	add.l	Tempbuffer_C(pc),a0

	move.l	(a3)+,a2
	jsr	(a2)
.next_E
	lea	Echo_Sizeof(a1),a1
	dbf	d1,.Echos	
.no_echo
	ifne	CPUtest
	move	#$00f,$dff180
	endc

	lea	Tempbuffer,a0
	add.l	Tempbuffer_C(pc),a0

	move.l	Buffer0,a1			;move.l	buff1(a5),a1
	add.l	LastBuffer(pc),a1

	move.l	SpecialBuffer1,a4		;nur für Surround & 14 Bit
	add.l	LastBuffer(pc),a4

	move.l	cbufad,a2
	jsr	(a2)
.noleft
	ifne	CPUtest
	move	#$fff,$dff180
	endc
right
;	move.l	MyEPBase(pc),a5
;	move.l	epg_audiostruct(A5),a4			;Audiostruct setzen
	move.l	myaudiostruct(pc),a4

	move	numstructs,d7
	subq.w	#1,d7
	blt.w	.noright
	
	move.l	mixad1,a1
	lea	TempBuffer2,a2
	add.l	TempBuffer_C(pc),a2

.loo	tst.w	AS_LeftRight(a4)
	bge.s	.n

	movem.l	a1/a2/a4/d7,-(sp)
	jsr	(a1)				; Mix
	movem.l	(sp)+,a1/a2/a4/d7
	move	#1,chans
	lea	AS_Sizeof(a4),a4
	subq	#1,d7
	bra.b	.loo2

.n	lea	AS_Sizeof(a4),a4
	dbf	d7,.loo
	bra.b	.ddq

.loo2	cmp	#1,numright
	beq.b	.ddq

	move.l	mixad2,a1
.loka	tst.w	AS_LeftRight(a4)
	bge.s	.n2

	movem.l	a1/a2/a4/d7,-(sp)
	jsr	(a1)
	movem.l	(sp)+,a1/a2/a4/d7
	
.n2	lea	AS_Sizeof(a4),a4
	dbf	d7,.loka
.ddq
	move.b	Echovalid(pc),d0
	beq.s	.no_echo

	move.l	usedmode(pc),a1
	lea	P_Echos(a1),a1
	moveq	#NumEchos-1,d1
	lea	Echoad_R(pc),a3
.Echos
	move.b	E_Enabled(a1),d0
	beq.s	.next_E

	moveq	#0,d0
	move.b	E_Delay(a1),d0

	lea	Tempbuffer2,a0
	add.l	Tempbuffer_C(pc),a0

	move.l	(a3)+,a2
	jsr	(a2)
.next_E
	lea	Echo_Sizeof(a1),a1
	dbf	d1,.Echos	
.no_echo
	ifne	CPUtest
	move	#$0f0,$dff180
	endc

	lea	Tempbuffer2,a0
	add.l	Tempbuffer_C(pc),a0

	move.l	Buffer1,a1			;move.l	buff2(a5),a1
	add.l	LastBuffer(pc),a1

	move.l	SpecialBuffer2,a4
	add.l	LastBuffer(pc),a4

	ifne	benchmark
	bsr	Copybuf142
	else
	move.l	cbufad,a2
	jsr	(a2)
	endc
.noright
	move	Num_C(pc),d0
	addq.w	#1,d0
	and.w	#Numbuffers-1,d0
	bne.s	.noas
	tst.b	Private_AS
	beq.s	.noas
	bsr	CopyAS				;Audiostruct zurückkopieren (a0/a1/d1 trashed !)
.noas
	move	d0,Num_C
	mulu	#samlen*4,d0
	move.l	d0,Tempbuffer_C

	ifne	CPUtest
	move	#$000,$dff180
	endc
	movem.l	(sp)+,d0-a6
	moveq	#0,d0
	rts

CopyAS:						;Audiostruct zurückkopieren
		lea	Extra_AS,a1		;aktuellen Stuff rückkopieren
		move.l	MYEpBase(pc),a0
		move.l	epg_audiostruct(A0),a0
		move	numstructs(pc),d1
		mulu	#AS_Sizeof/4,d1
		subq.w	#1,d1
copyback$
		move.l	(a1)+,(a0)+
		dbf	d1,copyback$
		rts

;-------------------- 8 Bit Mixing Routine (Part1 - Move Data) ----------------
mix:
	moveq	#0,d7
	move	#samlen*2,d7
	
;	cmp.w	#34*4,AS_Period(a4)
;	blo	.ty

	tst.w	AS_Period(a4)
	beq	.ty

	tst.b	AS_NoLoop(a4)
	bne	.ty			;noloop

	tst.b	AS_DmaBit(a4)
	beq	.ty			;noloop

	tst.l	AS_Currentadr(a4)	;pos (addr)
	bne.s	.dw

	clr.l	AS_CurrentPos(a4)
	move.l	AS_RepeatAdr(A4),AS_CurrentAdr(a4)
	beq	.ty
	move.l	AS_RepeatSize(a4),AS_SampleSize(a4)
	beq	.ty

.dw
;	tst.w	AS_Volume(a4)
;	beq	.vol0

	move.l	clock(pc),d4
	moveq	#0,d0
	move.w	AS_Period(a4),d0

	divu.l	d0,d4
	lsl.l	#8,d4
	lsl.l	#6,d4

	move.l	mrate(pc),d0
	lsr.l	#4,d0
	divu.l	d0,d4
	swap	d4

	move.l	vtabaddr(pc),a3
	moveq	#0,d0
	move	AS_LeftVolume(a4),d0
	add	d0,d0
	lsl.l	#8,d0
	add.l	d0,a3			; Position in volume table

	move.l	AS_Currentadr(a4),a0	;pos (addr)
	move.l	AS_CurrentPos(a4),d6
	add.l	d6,a0			;aktuelle Position + dem schon gespielten

	moveq	#0,d0
	move.w	AS_CurrentFPOS(a4),d0	;fpos
	swap	d0			;nach oben

	moveq	#0,d2
	moveq	#0,d3
	moveq	#0,d5

	move.l	d4,d1			;Counter für Zoom
	swap	d1			;count bis zum nächsten Byte
	lsl.l	#3,d1			;Mal 8 (wg. 8 * Mix)
	swap	d1			;Overflow count, also wieviele neue Bytes zu holen sind
	move.l	d1,a1

	btst	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)
	bne.w	.Ping_Init

	neg.l	d6			;
	add.l	AS_SampleSize(a4),d6	;Gesamtlänge + (- gespielte Länge) = übrige Länge
	bpl.s	.Checkd6
	move.l	AS_SampleSize(a4),d6	;Gesamtlänge + (- gespielte Länge) = übrige Länge
	move.l	AS_Currentadr(a4),a0	;pos (addr)
.Checkd6
	cmp.l	#$7fff,d6
	bls.s	.restart
	move.l	#$7fff,d6
.restart

.leii	subq	#8,d7
	blt.s	.lep

	move.l	a1,d1
	add.l	d0,d1			;+ aktuelle Position, wieviele Bytes schon weg sind
	addx	d5,d1			;+Overflow
	cmp	d6,d1			;größer als übrige Bytes ?
	bhs.s	.lep			;yup

	rept	4
	move.b	(a0,d0),d2
	add.l	d4,d0
	move	(a3,d2*2),d3
	addx	d5,d0
	swap	d3
	move.b	(a0,d0),d2
	add.l	d4,d0
	move	(a3,d2*2),d3
	addx	d5,d0
	move.l	d3,(a2)+
	endr

	bra.s	.leii
.lep	addq	#8,d7
	beq.w	.qw
	subq	#1,d7
.lep2	move.b	(a0,d0),d2
	add.l	d4,d0
	move	(a3,d2*2),(a2)+
	addx	d5,d0

	cmp	d6,d0
	bhs.b	.ddwq
	dbf	d7,.lep2
	bra.w	.qw
.ddwq
	move.b	AS_LoopFlag(a4),d1
	bne.b	.q
	st	AS_NoLoop(a4)
	bra.w	.ty
.q
	addq	#1,d7

	btst	#ASLoopF_PingPong,d1
	bne.s	.PingPongLoop
.NormalLoop
	bset	#ASLoopF_Looping,AS_CurrentFPOS+2(a4)

	move.l	AS_RepeatAdr(a4),a0		;loop start
	move.l	a0,AS_CurrentAdr(a4)

	moveq	#0,d1
	move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
	add.l	AS_CurrentPos(a4),d1
	sub.l	AS_Samplesize(A4),d1
	move.l	d1,AS_CurrentPos(a4)
	add.l	d1,a0

	move.l	AS_RepeatSize(a4),d6		;loop len
	move.l	d6,AS_SampleSize(a4)
	sub.l	d1,d6				;Len - Current Position
	clr	d0				;reset integer part

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT
	dbf	d7,.checkd6	;max. Samplesize is bigger >64k !!
	bra.s	.qw
.PingPongLoop
	btst	#ASLoopF_Looping,AS_CurrentFPOS+2(a4)
	beq.s	.NormalLoop

	bset	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

	move.l	AS_RepeatAdr(a4),a0		;loop start
	move.l	a0,AS_CurrentAdr(a4)

	moveq	#0,d1
	move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
	add.l	AS_CurrentPos(a4),d1
	sub.l	AS_Samplesize(A4),d1		;Übertrag über eigentliche aktuelle Länge

	move.l	AS_Repeatsize(a4),d6
	move.l	d6,AS_Samplesize(a4)
	sub.l	d1,d6
	subq.l	#1,d6
	move.l	d6,AS_CurrentPos(a4)		;aktuelle Position = Repeatsize-1-Übertrag
	add.l	d6,a0				;Aktuelle Position
	clr	d0				;reset integer part

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt_P
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT_P
	dbf	d7,.Ping_Init2
.qw
	moveq	#0,d1
	move	d0,d1
	add.l	AS_CurrentPos(a4),d1
	move.l	d1,AS_CurrentPos(a4)

	swap	d0
	move.w	d0,AS_CurrentFPOS(a4)	;Fraction Pos

	sub.l	AS_SampleSize(a4),d1
	blt.s	.u

	tst.b	AS_LoopFlag(a4)
	bne.b	.q2
	st	AS_NoLoop(a4)			; sample is not looping
	bra.b	.u

.q2	move.l	AS_RepeatSize(a4),d6		;loop len
	move.l	d6,AS_SampleSize(a4)
	move.l	AS_Repeatadr(a4),a0
	move.l	A0,AS_CurrentAdr(a4)

	move.l	d1,AS_CurrentPos(a4)

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt1
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT1
.u	rts

.ty:	moveq	#0,d0
	subq	#1,d7
	bmi.s	.fail
.lll	move	d0,(a2)+
	dbf	d7,.lll
.fail
	rts

.Ping_Init
.Ping_Init2
		neg.w	d4		;rückwärts zählen bei Mixrate < originale Samplerate 
					;in D6 übrige Länge (currentPos = Rest vom aktuellen
					;Wert bis 0)
		move.l	a1,d1
		neg.w	d1
		move.l	d1,a1
.Ping_checkd6
		cmp.l	#$7fff,d6
		bls.s	.Ping_ok
		move.l	#$7fff,d6
.Ping_ok

.Ping_leii
		subq	#8,d7
		blt.s	.Ping_lep

		move.l	a1,d1			;Anzahl zu holender Bytes bei 8 Mixdurchläufen
		add.l	d0,d1			;+ aktuelle Position, wieviele Bytes schon weg sind
		add	d6,d1			;größer als übrige Bytes ?
		ble.s	.Ping_lep		;yup

		rept	4
		move.b	(a0,d0),d2
		add.l	d4,d0
		move	(a3,d2*2),d3
		subx	d5,d0
		swap	d3
		move.b	(a0,d0),d2
		add.l	d4,d0
		move	(a3,d2*2),d3
		subx	d5,d0
		move.l	d3,(a2)+
		endr

		bra.w	.Ping_leii
.Ping_lep	addq	#8,d7
		beq.w	.Ping_qw
		subq	#1,d7
.Ping_lep2
		move.b	(a0,d0),d2
		add.l	d4,d0
		move	(a3,d2*2),(a2)+
		subx	d5,d0

		move	d0,d1
		add	d6,d1
		ble.s	.Ping_ddwq

		dbf	d7,.Ping_lep2
		bra.s	.Ping_qw
.Ping_ddwq
;		move.b	AS_LoopFlag(a4),d1
;		bne.b	.q
;		st	AS_NoLoop(a4)
;		bra.w	.ty
;.q

;weil gerade rückwärts gelooped wurde, gehts nun in jedem Fall vorwärts weiter

		addq	#1,d7

		neg.w	d0		;|gespielte Länge| (für Übertrag)

		bclr	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

		move.l	AS_RepeatAdr(a4),a0		;loop start
		move.l	a0,AS_CurrentAdr(a4)

		moveq	#0,d1
		move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
		sub.l	AS_CurrentPos(a4),d1
		move.l	d1,AS_CurrentPos(a4)
		add.l	d1,a0

		move.l	AS_RepeatSize(a4),d6		;loop len
		move.l	d6,AS_SampleSize(a4)
		sub.l	d1,d6				;Len - Current Position
		clr	d0				;reset integer part

		tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
		beq.s	.Ping_noInt
		movem.l	d0-a6,-(sp)		;nur zur Sicherheit
		move.l	AS_Int(A4),a1
		move.l	4.w,a6
		jsr	_LVOCause(a6)
		movem.l	(sp)+,d0-a6		;man weiss ja nie...
.Ping_noINT
		neg.w	d4		;rückwärts zählen bei Mixrate < originale Samplerate 
					;in D6 übrige Länge (currentPos = Rest vom aktuellen
					;Wert bis 0)

		move.l	a1,d1
		neg.w	d1
		move.l	d1,a1

		dbf	d7,.checkd6	;max. Samplesize is bigger >64k !!

		swap	d0
		move	d0,AS_CurrentFPOS(a4)	;Fraction Pos
		bra.s	.Ping_U
.Ping_qw
		neg.w	d0		;|gespielte Länge| (für Übertrag)

		moveq	#0,d1
		move	d0,d1

		swap	d0
		move.w	d0,AS_CurrentFPOS(a4)	;Fraction Pos

		move.l	AS_CurrentPos(a4),d6
		sub.l	d1,d6
		move.l	d6,AS_CurrentPos(a4)
		bgt.s	.Ping_U

		bclr	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

		move.l	AS_RepeatAdr(a4),a0		;loop start
		move.l	a0,AS_CurrentAdr(a4)

		neg.l	d6
		move.l	d6,AS_CurrentPos(A4)

		move.l	AS_RepeatSize(a4),d6		;loop len
		move.l	d6,AS_SampleSize(a4)

		tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
		beq.s	.Ping_noInt1
		movem.l	d0-a6,-(sp)		;nur zur Sicherheit
		move.l	AS_Int(A4),a1
		move.l	4.w,a6
		jsr	_LVOCause(a6)
		movem.l	(sp)+,d0-a6		;man weiss ja nie...
.Ping_noINT1
.Ping_u		rts


;.vol0	move.l	clock(pc),d4
;	move.w	AS_Period(a4),d0
;	lsl.w	#2,d0
;	divu	d0,d4		;period
;	swap	d4
;	clr	d4
;	lsr.l	#2,d4
;
;	move.l	mrate(pc),d0
;	divu	d0,d4
;	swap	d4
;	clr	d4
;	rol.l	#4,d4
;	swap	d4
;
;	move.l	(a4),a0			;mStart
;	move.l	mFPos(a4),d0
;
;	addq	#1,d7
;
;	movem.l	d0/d1,-(sp)
;	move.l	d7,d1
;	move.l	d4,d0
;	bsr	mulu_32
;	move.l	d0,d4
;	movem.l	(sp)+,d0/d1
;
;	subq	#1,d7
;
;	swap	d0
;	add.l	d4,d0			; Position after "mixing"
;	swap	d0
;	
;	moveq	#0,d1
;	move	d0,d1
;	add.l	d1,a0
;	clr	d0
;	move.l	a0,(a4)
;	move.l	d0,mFPos(a4)
;	sub.l	d1,mLength(a4)
;	bpl	.ty			; OK, Done!
;
;; We're about to mix past the end of the sample
;
;	tst.b	mLoop(a4)
;	bne.b	.q3
;	st	mOnOff(a4)
;	bra	.ty
;
;.q3	move.l	mLLength(a4),d6
;.loop	sub.l	d6,a0
;	add.l	d6,mLength(a4)
;	bmi.b	.loop
;	beq.b	.loop
;
;	move.l	a0,(a4)
;	bra	.ty
;

;-------------------- 8 Bit Mixing Routine (Part2 - Add Data) ----------------
mix2:
	moveq	#0,d7
	move	#samlen*2,d7
	
;	cmp.w	#34*4,AS_Period(a4)
;	blo	.ty

	tst.w	AS_Period(a4)
	beq	.ty

	tst.b	AS_NoLoop(a4)
	bne	.ty			;noloop

	tst.b	AS_DmaBit(a4)
	beq	.ty			;noloop

	tst.l	AS_Currentadr(a4)	;pos (addr)
	bne.s	.dw

	clr.l	AS_CurrentPos(a4)
	move.l	AS_RepeatAdr(A4),AS_CurrentAdr(a4)
	beq	.ty
	move.l	AS_RepeatSize(a4),AS_SampleSize(a4)
	beq	.ty

.dw
;	tst.w	AS_Volume(a4)
;	beq	.vol0

	move.l	clock(pc),d4
	moveq	#0,d0
	move.w	AS_Period(a4),d0

	divu.l	d0,d4
	lsl.l	#8,d4
	lsl.l	#6,d4

	move.l	mrate(pc),d0
	lsr.l	#4,d0
	divu.l	d0,d4
	swap	d4

	move.l	vtabaddr(pc),a3
	moveq	#0,d0
	move	AS_LeftVolume(a4),d0
	add	d0,d0
	lsl.l	#8,d0
	add.l	d0,a3			; Position in volume table

	move.l	AS_Currentadr(a4),a0	;pos (addr)
	move.l	AS_CurrentPos(a4),d6
	add.l	d6,a0			;aktuelle Position + dem schon gespielten

	moveq	#0,d0
	move.w	AS_CurrentFPOS(a4),d0	;fpos
	swap	d0

	moveq	#0,d2
	moveq	#0,d3
	moveq	#0,d5

	move.l	d4,d1			;Counter für Zoom
	swap	d1			;count bis zum nächsten Byte
	lsl.l	#3,d1			;Mal 8 (wg. 8 * Mix)
	swap	d1			;Overflow count, also wieviele neue Bytes zu holen sind
	move.l	d1,a1

	btst	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)
	bne.w	.Ping_Init

	neg.l	d6			;
	add.l	AS_SampleSize(a4),d6	;Gesamtlänge + (- gespielte Länge)
	bpl.s	.Checkd6
	move.l	AS_SampleSize(a4),d6	;Gesamtlänge + (- gespielte Länge) = übrige Länge
	move.l	AS_Currentadr(a4),a0	;pos (addr)
.Checkd6
	cmp.l	#$7fff,d6
	bls.s	.restart
	move.l	#$7fff,d6
.restart

.leii	subq	#8,d7
	blt.s	.lep
;	bra.s	.lep			;nur testhalber enablen !

	move.l	a1,d1
	add.l	d0,d1			;+ aktuelle Position, wieviele Bytes schon weg sind
	addx	d5,d1			;+Overflow
	cmp	d6,d1			;größer als übrige Bytes ?
	bhs.s	.lep			;yup

	rept	8
	move.b	(a0,d0),d2
	move	(a3,d2*2),d3
	add.l	d4,d0
	addx	d5,d0
	add	d3,(a2)+
	endr

	bra.s	.leii
.lep	addq	#8,d7
	beq.w	.qw
	subq	#1,d7
.lep2	move.b	(a0,d0),d2
	move	(a3,d2*2),d3
	add.l	d4,d0
	addx	d5,d0
	add	d3,(a2)+
	cmp	d6,d0
	bhs.b	.ddwq
	dbf	d7,.lep2
	bra.w	.qw
.ddwq
	move.b	AS_LoopFlag(a4),d1
	bne.b	.q
	st	AS_NoLoop(a4)
	bra.w	.ty
.q
	addq	#1,d7

	btst	#ASLoopF_PingPong,d1
	bne.s	.PingPongLoop
.NormalLoop
	bset	#ASLoopF_Looping,AS_CurrentFPOS+2(a4)

	move.l	AS_RepeatAdr(a4),a0		;loop start
	move.l	a0,AS_CurrentAdr(a4)

	moveq	#0,d1
	move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
	add.l	AS_CurrentPos(a4),d1
	sub.l	AS_Samplesize(A4),d1

	move.l	d1,AS_CurrentPos(a4)
	add.l	d1,a0

	move.l	AS_RepeatSize(a4),d6		;loop len
	move.l	d6,AS_SampleSize(a4)
	sub.l	d1,d6
	clr	d0				;reset integer part

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT
	dbf	d7,.checkd6	;max. Samplesize is bigger >64k !!
	bra.s	.qw
.PingPongLoop
	btst	#ASLoopF_Looping,AS_CurrentFPOS+2(a4)
	beq.s	.NormalLoop

	bset	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

	move.l	AS_RepeatAdr(a4),a0		;loop start
	move.l	a0,AS_CurrentAdr(a4)

	moveq	#0,d1
	move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
	add.l	AS_CurrentPos(a4),d1
	sub.l	AS_Samplesize(A4),d1		;Übertrag über eigentliche aktuelle Länge

	move.l	AS_Repeatsize(a4),d6
	move.l	d6,AS_Samplesize(a4)
	sub.l	d1,d6
	subq.l	#1,d6
	move.l	d6,AS_CurrentPos(a4)		;aktuelle Position = Repeatsize-1-Übertrag
	add.l	d6,a0				;Aktuelle Position
	clr	d0				;reset integer part

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt_P
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT_P
	dbf	d7,.Ping_Init
.qw
	moveq	#0,d1
	move	d0,d1
	add.l	AS_CurrentPos(a4),d1
	move.l	d1,AS_CurrentPos(a4)

	swap	d0
	move.w	d0,AS_CurrentFPOS(a4)	;Fraction Pos

	sub.l	AS_SampleSize(a4),d1
	blt.s	.u

	tst.b	AS_LoopFlag(a4)
	bne.b	.q2
	st	AS_NoLoop(a4)			; sample is not looping
	bra.b	.u

.q2	move.l	AS_RepeatSize(a4),d6		;loop len
	move.l	d6,AS_SampleSize(a4)
	move.l	AS_Repeatadr(a4),a0
	move.l	A0,AS_CurrentAdr(a4)

	move.l	d1,AS_CurrentPos(a4)

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt1
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT1
.ty
.u	rts

.Ping_Init
		neg.w	d4		;rückwärts zählen bei Mixrate < originale Samplerate 
					;in D6 übrige Länge (currentPos = Rest vom aktuellen
					;Wert bis 0)
		move.l	a1,d1
		neg.w	d1
		move.l	d1,a1
.Ping_checkd6
		cmp.l	#$7fff,d6
		bls.s	.Ping_ok
		move.l	#$7fff,d6
.Ping_ok

.Ping_leii
		subq	#8,d7
		blt.s	.Ping_lep

		move.l	a1,d1			;Anzahl zu holender Bytes bei 8 Mixdurchläufen
		add.l	d0,d1			;+ aktuelle Position, wieviele Bytes schon weg sind
		add	d6,d1			;größer als übrige Bytes ?
		ble.s	.Ping_lep		;yup

	rept	8
	move.b	(a0,d0),d2
	add.l	d4,d0
	move	(a3,d2*2),d3
	subx	d5,d0
	add	d3,(a2)+
	endr

		bra.w	.Ping_leii
.Ping_lep	addq	#8,d7
		beq.w	.Ping_qw
		subq	#1,d7
.Ping_lep2

		move.b	(a0,d0),d2
		add.l	d4,d0
		move	(a3,d2*2),d3
		subx	d5,d0
		add	d3,(a2)+

		move	d0,d1
		add	d6,d1
		ble.s	.Ping_ddwq

		dbf	d7,.Ping_lep2
		bra.s	.Ping_qw
.Ping_ddwq
;		move.b	AS_LoopFlag(a4),d1
;		bne.b	.q
;		st	AS_NoLoop(a4)
;		bra.w	.ty
;.q

;weil gerade rückwärts gelooped wurde, gehts nun in jedem Fall vorwärts weiter

		addq	#1,d7

		neg.w	d0		;|gespielte Länge| (für Übertrag)

		bclr	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

		move.l	AS_RepeatAdr(a4),a0		;loop start
		move.l	a0,AS_CurrentAdr(a4)

		moveq	#0,d1
		move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
		sub.l	AS_CurrentPos(a4),d1
		move.l	d1,AS_CurrentPos(a4)
		add.l	d1,a0

		move.l	AS_RepeatSize(a4),d6		;loop len
		move.l	d6,AS_SampleSize(a4)
		sub.l	d1,d6				;Len - Current Position
		clr	d0				;reset integer part

		tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
		beq.s	.Ping_noInt
		movem.l	d0-a6,-(sp)		;nur zur Sicherheit
		move.l	AS_Int(A4),a1
		move.l	4.w,a6
		jsr	_LVOCause(a6)
		movem.l	(sp)+,d0-a6		;man weiss ja nie...
.Ping_noINT
		neg.w	d4		;rückwärts zählen bei Mixrate < originale Samplerate 
					;in D6 übrige Länge (currentPos = Rest vom aktuellen
					;Wert bis 0)

		move.l	a1,d1
		neg.w	d1
		move.l	d1,a1

		dbf	d7,.checkd6	;max. Samplesize is bigger >64k !!

		swap	d0
		move	d0,AS_CurrentFPOS(a4)	;Fraction Pos
		bra.s	.Ping_U
.Ping_qw
		neg.w	d0		;|gespielte Länge| (für Übertrag)

		moveq	#0,d1
		move	d0,d1

		swap	d0
		move.w	d0,AS_CurrentFPOS(a4)	;Fraction Pos

		move.l	AS_CurrentPos(a4),d6
		sub.l	d1,d6
		move.l	d6,AS_CurrentPos(a4)
		bgt.s	.Ping_U

		bclr	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

		move.l	AS_RepeatAdr(a4),a0		;loop start
		move.l	a0,AS_CurrentAdr(a4)

		neg.l	d6
		move.l	d6,AS_CurrentPos(A4)

		move.l	AS_RepeatSize(a4),d6		;loop len
		move.l	d6,AS_SampleSize(a4)

		tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
		beq.s	.Ping_noInt1
		movem.l	d0-a6,-(sp)		;nur zur Sicherheit
		move.l	AS_Int(A4),a1
		move.l	4.w,a6
		jsr	_LVOCause(a6)
		movem.l	(sp)+,d0-a6		;man weiss ja nie...
.Ping_noINT1
.Ping_u
		rts

;-------------------- 16 Bit Mixing Routine (Part1 - Move Data) ----------------
;-------------------- currently no volume control supported  -------------------
mix16:
	moveq	#0,d7
	move	#samlen*2,d7
	
	tst.w	AS_Period(a4)
	beq	.ty

	tst.b	AS_NoLoop(a4)
	bne	.ty			;noloop

	tst.b	AS_DmaBit(a4)
	beq	.ty			;noloop

	tst.l	AS_Currentadr(a4)	;pos (addr)
	beq	.ty

.dw	move.l	clock(pc),d4
	moveq	#0,d0
	move.w	AS_Period(a4),d0

	divu.l	d0,d4
	lsl.l	#8,d4
	lsl.l	#6,d4

	move.l	mrate(pc),d0
	lsr.l	#4,d0
	divu.l	d0,d4
	swap	d4

	move.l	vtabaddr(pc),a3

	move.l	AS_Currentadr(a4),a0	;pos (addr)
	move.l	AS_CurrentPos(a4),d6
	add.l	d6,a0			;aktuelle Position + dem schon gespielten
	add.l	d6,a0			;*2 wg. Wortlänge

	moveq	#0,d0
	move.w	AS_CurrentFPOS(a4),d0	;fpos
	swap	d0			;nach oben

	moveq	#0,d2
	moveq	#0,d3
	moveq	#0,d5

	move.l	d4,d1			;Counter für Zoom
	swap	d1			;count bis zum nächsten Wort
	lsl.l	#3,d1			;Mal 8 (wg. 8 * Mix)
	swap	d1			;Overflow count, also wieviele neue Worte zu holen sind
	move.l	d1,a1

	btst	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)
	bne.w	.Ping_Init

	neg.l	d6			;
	move.l	AS_SampleSize(a4),d1
	lsr.l	#1,d1
	add.l	d1,d6			;Gesamtlänge + (- gespielte Länge) = übrige Länge
	bpl.s	.Checkd6
	move.l	d1,d6			;übrige Länge = max
	move.l	AS_Currentadr(a4),a0	;pos (addr)
.Checkd6
	cmp.l	#$7fff,d6
	bls.s	.restart
	move.l	#$7fff,d6
.restart

.leii	subq	#8,d7
	blt.s	.lep

	move.l	a1,d1
	add.l	d0,d1			;+ aktuelle Position, wieviele Bytes schon weg sind
	addx	d5,d1			;+Overflow
	cmp	d6,d1			;größer als übrige Bytes ?
	bhs.s	.lep			;yup

	rept	4
	move.w	(a0,d0*2),d2
	add.l	d4,d0
	move	(a3,d2.l*2),d3
	addx	d5,d0
	swap	d3
	move.w	(a0,d0*2),d2
	add.l	d4,d0
	move	(a3,d2.l*2),d3
	addx	d5,d0
	move.l	d3,(a2)+
	endr

	bra.s	.leii
.lep	addq	#8,d7
	beq.w	.qw
	subq	#1,d7
.lep2	move.w	(a0,d0*2),d2
	add.l	d4,d0
	move	(a3,d2.l*2),(a2)+
	addx	d5,d0

	cmp	d6,d0
	bhs.b	.ddwq
	dbf	d7,.lep2
	bra.w	.qw
.ddwq
	move.b	AS_LoopFlag(a4),d1
	bne.b	.q
	st	AS_NoLoop(a4)
	bra.w	.ty
.q
	addq	#1,d7

	btst	#ASLoopF_PingPong,d1
	bne.s	.PingPongLoop
.NormalLoop
	bset	#ASLoopF_Looping,AS_CurrentFPOS+2(a4)

	move.l	AS_RepeatAdr(a4),a0		;loop start
	move.l	a0,AS_CurrentAdr(a4)

	moveq	#0,d1
	move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
	add.l	AS_CurrentPos(a4),d1
	move.l	AS_Samplesize(A4),d6
	lsr.l	#1,d6
	sub.l	d6,d1
	bpl.s	.ok
	moveq	#0,d1
.ok
	move.l	d1,AS_CurrentPos(a4)

	add.l	d1,a0
	add.l	d1,a0

	move.l	AS_RepeatSize(a4),d6		;loop len
	move.l	d6,AS_SampleSize(a4)
	lsr.l	#1,d6
	sub.l	d1,d6				;Len - Current Position
	clr	d0				;reset integer part

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT
	dbf	d7,.checkd6	;max. Samplesize is bigger >64k !!
	bra.s	.qw
.PingPongLoop
	btst	#ASLoopF_Looping,AS_CurrentFPOS+2(a4)
	beq.s	.NormalLoop

	bset	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

	move.l	AS_RepeatAdr(a4),a0		;loop start
	move.l	a0,AS_CurrentAdr(a4)

	moveq	#0,d1
	move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
	add.l	AS_CurrentPos(a4),d1
	sub.l	AS_Samplesize(A4),d1		;Übertrag über eigentliche aktuelle Länge

	move.l	AS_Repeatsize(a4),d6
	move.l	d6,AS_Samplesize(a4)
	sub.l	d1,d6
	subq.l	#1,d6
	move.l	d6,AS_CurrentPos(a4)		;aktuelle Position = Repeatsize-1-Übertrag
	add.l	d6,a0				;Aktuelle Position
	clr	d0				;reset integer part

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt_P
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT_P
	dbf	d7,.Ping_Init2
.qw
	moveq	#0,d1
	move	d0,d1
	add.l	AS_CurrentPos(a4),d1
	move.l	d1,AS_CurrentPos(a4)

	swap	d0
	move.w	d0,AS_CurrentFPOS(a4)	;Fraction Pos

	move.l	AS_Samplesize(A4),d6
	lsr.l	#1,d6
	sub.l	d6,d1
	blt.s	.u

	tst.b	AS_LoopFlag(a4)
	bne.b	.q2
	st	AS_NoLoop(a4)			; sample is not looping
	bra.b	.u

.q2	move.l	AS_RepeatSize(a4),d6		;loop len
	move.l	d6,AS_SampleSize(a4)
	move.l	AS_Repeatadr(a4),a0
	move.l	A0,AS_CurrentAdr(a4)

	move.l	d1,AS_CurrentPos(a4)

	tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
	beq.s	.noInt1
	movem.l	d0-a6,-(sp)		;nur zur Sicherheit
	move.l	AS_Int(A4),a1
	move.l	4.w,a6
	jsr	_LVOCause(a6)
	movem.l	(sp)+,d0-a6		;man weiss ja nie...
.noINT1
.u	rts

.ty:	moveq	#0,d0
	subq	#1,d7
	bmi.s	.fail
.lll	move	d0,(a2)+
	dbf	d7,.lll
.fail
	rts

.Ping_Init
.Ping_Init2
		neg.w	d4		;rückwärts zählen bei Mixrate < originale Samplerate 
					;in D6 übrige Länge (currentPos = Rest vom aktuellen
					;Wert bis 0)
		move.l	a1,d1
		neg.w	d1
		move.l	d1,a1
.Ping_checkd6
		cmp.l	#$7fff,d6
		bls.s	.Ping_ok
		move.l	#$7fff,d6
.Ping_ok

.Ping_leii
		subq	#8,d7
		blt.s	.Ping_lep

		move.l	a1,d1			;Anzahl zu holender Bytes bei 8 Mixdurchläufen
		add.l	d0,d1			;+ aktuelle Position, wieviele Bytes schon weg sind
		add	d6,d1			;größer als übrige Bytes ?
		ble.s	.Ping_lep		;yup

		rept	4
		move.b	(a0,d0),d2
		add.l	d4,d0
		move	(a3,d2*2),d3
		subx	d5,d0
		swap	d3
		move.b	(a0,d0),d2
		add.l	d4,d0
		move	(a3,d2*2),d3
		subx	d5,d0
		move.l	d3,(a2)+
		endr

		bra.w	.Ping_leii
.Ping_lep	addq	#8,d7
		beq.w	.Ping_qw
		subq	#1,d7
.Ping_lep2
		move.b	(a0,d0),d2
		add.l	d4,d0
		move	(a3,d2*2),(a2)+
		subx	d5,d0

		move	d0,d1
		add	d6,d1
		ble.s	.Ping_ddwq

		dbf	d7,.Ping_lep2
		bra.s	.Ping_qw
.Ping_ddwq
;		move.b	AS_LoopFlag(a4),d1
;		bne.b	.q
;		st	AS_NoLoop(a4)
;		bra.w	.ty
;.q

;weil gerade rückwärts gelooped wurde, gehts nun in jedem Fall vorwärts weiter

		addq	#1,d7

		neg.w	d0		;|gespielte Länge| (für Übertrag)

		bclr	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

		move.l	AS_RepeatAdr(a4),a0		;loop start
		move.l	a0,AS_CurrentAdr(a4)

		moveq	#0,d1
		move.w	d0,d1				;im aktuellen Rundlauf gespielte Länge
		sub.l	AS_CurrentPos(a4),d1
		move.l	d1,AS_CurrentPos(a4)
		add.l	d1,a0

		move.l	AS_RepeatSize(a4),d6		;loop len
		move.l	d6,AS_SampleSize(a4)
		sub.l	d1,d6				;Len - Current Position
		clr	d0				;reset integer part

		tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
		beq.s	.Ping_noInt
		movem.l	d0-a6,-(sp)		;nur zur Sicherheit
		move.l	AS_Int(A4),a1
		move.l	4.w,a6
		jsr	_LVOCause(a6)
		movem.l	(sp)+,d0-a6		;man weiss ja nie...
.Ping_noINT
		neg.w	d4		;rückwärts zählen bei Mixrate < originale Samplerate 
					;in D6 übrige Länge (currentPos = Rest vom aktuellen
					;Wert bis 0)

		move.l	a1,d1
		neg.w	d1
		move.l	d1,a1

		dbf	d7,.checkd6	;max. Samplesize is bigger >64k !!

		swap	d0
		move	d0,AS_CurrentFPOS(a4)	;Fraction Pos
		bra.s	.Ping_U
.Ping_qw
		neg.w	d0		;|gespielte Länge| (für Übertrag)

		moveq	#0,d1
		move	d0,d1

		swap	d0
		move.w	d0,AS_CurrentFPOS(a4)	;Fraction Pos

		move.l	AS_CurrentPos(a4),d6
		sub.l	d1,d6
		move.l	d6,AS_CurrentPos(a4)
		bgt.s	.Ping_U

		bclr	#ASLoopF_BackLooping,AS_CurrentFPOS+2(a4)

		move.l	AS_RepeatAdr(a4),a0		;loop start
		move.l	a0,AS_CurrentAdr(a4)

		neg.l	d6
		move.l	d6,AS_CurrentPos(A4)

		move.l	AS_RepeatSize(a4),d6		;loop len
		move.l	d6,AS_SampleSize(a4)

		tst.l	AS_Int(a4)		;"Interrupt" bei neuem Sample ?
		beq.s	.Ping_noInt1
		movem.l	d0-a6,-(sp)		;nur zur Sicherheit
		move.l	AS_Int(A4),a1
		move.l	4.w,a6
		jsr	_LVOCause(a6)
		movem.l	(sp)+,d0-a6		;man weiss ja nie...
.Ping_noINT1
.Ping_u		rts

;********************************************************************************************
;*                                   Echo-Routinen                                          *
;********************************************************************************************
;Input:
; A0: Zielpuffer für Gesamtdaten
; D0: Delay
;
;Registers:
; A1 darf nicht verändert werden
; A3 darf nicht verändert werden
; D1 darf nicht verändert werden
;--------------50% Echo auf den aktuellen Kanal mit Daten vom Linken Kanal ------------------
CopyEcho14L_2:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#1,d2
	add	d2,(a0)+
	swap	d2
	asr	#1,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts
;--------------50% Echo auf den aktuellen Kanal mit Daten vom Rechten Kanal -----------------
CopyEcho14R_2:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer2,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#1,d2
	add	d2,(a0)+
	swap	d2
	asr	#1,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts
;--------------25% Echo auf den aktuellen Kanal mit Daten vom Linken Kanal ------------------
CopyEcho14L_4:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#2,d2
	add	d2,(a0)+
	swap	d2
	asr	#2,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts
;--------------25% Echo auf den aktuellen Kanal mit Daten vom Rechten Kanal -----------------
CopyEcho14R_4:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer2,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#2,d2
	add	d2,(a0)+
	swap	d2
	asr	#2,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts
;------------12.5% Echo auf den aktuellen Kanal mit Daten vom Linken Kanal ------------------
CopyEcho14L_8:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#3,d2
	add	d2,(a0)+
	swap	d2
	asr	#3,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts
;------------12.5% Echo auf den aktuellen Kanal mit Daten vom Rechten Kanal -----------------
CopyEcho14R_8:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer2,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#3,d2
	add	d2,(a0)+
	swap	d2
	asr	#3,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts

;------------6.25% Echo auf den aktuellen Kanal mit Daten vom Linken Kanal ------------------
CopyEcho14L_16:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#4,d2
	add	d2,(a0)+
	swap	d2
	asr	#4,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts
;------------6,25% Echo auf den aktuellen Kanal mit Daten vom Rechten Kanal -----------------
CopyEcho14R_16:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer2,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#4,d2
	add	d2,(a0)+
	swap	d2
	asr	#4,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts

;------------3.125% Echo auf den aktuellen Kanal mit Daten vom Linken Kanal ------------------
CopyEcho14L_32:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#5,d2
	add	d2,(a0)+
	swap	d2
	asr	#5,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts
;------------3,125% Echo auf den aktuellen Kanal mit Daten vom Rechten Kanal -----------------
CopyEcho14R_32:
	mulu	#SamLEN*4,d0			;Delay*Puffergröße
	move.l	Tempbuffer_C(pc),d2
	sub.l	d0,d2
	bge.s	.take
	add.l	#TempbufferSize,d2
.take
	add.l	#TempBuffer2,d2
	move.l	d2,a2

	move	#Samlen-1,d7
.ldd3	move.l	(a2)+,d2
	asr	#5,d2
	add	d2,(a0)+
	swap	d2
	asr	#5,d2
	add	d2,(a0)+
	dbf	d7,.ldd3
	rts

;---------------------- ins Chipmem kopieren für Stereo 14 Bit  ---------------------
copybuf14
	ifne	benchmark
	move	#$f0f,$dff180
	endc

	move	#Samlen/2-1,d7
	move.l	buff14_2(pc),a2
	moveq	#8,d6
.ldd3
	movem.w	(a0)+,d0/d2/d4/d5			;auto ext.l !!! also SIGNED.l !! ab 68000!

	move.w	(a2,d0.l*2),d1
	move.b	d1,d3
	lsl	d6,d3
	move.w	(a2,d2.l*2),d0
	move.b	d0,d3
	lsr	d6,d0
	move.b	d0,d1
	swap	d3
	swap	d1
	move.w	(a2,d4.l*2),d1
	move.b	d1,d3
	lsl	d6,d3

	move.w	(a2,d5.l*2),d0
	move.b	d0,d3
	lsr	d6,d0
	move.b	d0,d1

	move.l	d3,(a4)+
	move.l	d1,(a1)+
	dbf	d7,.ldd3

	ifne	benchmark
	move	#$0,$dff180
	endc
	rts
	ifne	benchmark
copybuf142
	move	#$0f0,$dff180

;	move	#Samlen/2-1,d7
;	move.l	buff14_2(pc),a2
;.ldd3
;	movem.w	(a0)+,d0/d2/d4/d5			;auto ext.l !!! also SIGNED.l !!
;
;	move.w	(a2,d0.l*2),d1
;	move.b	d1,d3
;	lsl	#8,d3
;	move.b	(a2,d2.l*2),d1
;	move.b	1(a2,d2.l*2),d3
;	swap	d3
;	swap	d1
;	move.w	(a2,d4.l*2),d1
;	move.b	d1,d3
;	lsl	#8,d3
;	move.b	(a2,d5.l*2),d1
;	move.b	1(a2,d5.l*2),d3
;
;	move.l	d1,(a1)+
;	move.l	d3,(a4)+
;	dbf	d7,.ldd3

	move	#Samlen*2-1,d7
	move.l	buff14_2(pc),a2
.ldd3
	move	(a0)+,d2
	ext.l	d2
	move.b	(a2,d2.l*2),(a1)+
	move.b	1(a2,d2.l*2),(a4)+
	dbf	d7,.ldd3

	move	#$0,$dff180
	rts
	endc

;*****************************************************************************
;*                        Daten und Initialisierungen                        *
;*****************************************************************************
dectable:
	dc.l	1,10,100,1000,10000,100000,1000000,10000000,100000000

int:	dc.b	"intuition.library",0
gad:	dc.b	"gadtools.library",0
dos:	dc.b	"dos.library",0
graf	dc.b	"graphics.library",0

NoportMessage:	dc.b	"Cannot find EaglePlayer Port",0
	even
portname:	dc.b	"EAGLEPLAYERPORT",0

my_easygadget:	dc.b	"   OK   ",0
my_easygadget2	dc.b	"Retry|Cancel",0

	even
Project0WindowTags:
Project0L:
	DC.L	WA_Left,0
Project0T:
	DC.L	WA_Top,0
Project0W:
	DC.L	WA_Width,0
Project0H:
	DC.L	WA_Height,0

	DC.L	WA_IDCMP,IDCMP_RawKey!IDCMP_Menupick!LISTVIEWIDCMP!BUTTONIDCMP!IDCMP_CLOSEWINDOW!IDCMP_REFRESHWINDOW!IDCMP_Changewindow
	DC.L	WA_Flags,WFLG_DRAGBAR!WFLG_DEPTHGADGET!WFLG_CLOSEGADGET!WFLG_SMART_REFRESH

	DC.L	WA_Title,Project0WTitle
	DC.L	WA_ScreenTitle,Project0STitle
	dc.l	wa_newlookmenus,1
	dc.l	wa_autoadjust,1

	dc.l	wa_pubscreen
Pubadr
	dc.l	0
	dc.l	WA_Zoom
	dc.l	ZoomStruct
	DC.L	TAG_DONE,0
ZoomStruct
	dc.w	0,0,150,0
Ahawidth
	dc.l	399
Ahaheight
	dc.l	80

IR:
	DC.L	GT_VisualInfo,$00000000,GTBB_recessed,0
	dc.l	TAG_DONE
MTags0:
	DC.L	GTMN_Newlookmenus,1
	dc.l	TAG_DONE

TopazName:
	DC.B	'topaz.font',0

;--------------------------- spezifische Texte und Strukturen --------------------

MyAnalyzername:		dc.b	"E_14Bit_AMP.1",0
MyUsername:		dc.b	"14Bit Amplifier",0
myBuggsname:		dc.b	`Buggs of Defect`,0

myinfo		dc.b	"This Amplifier supports up",10
		dc.b	"to 32 voices using a",10
		dc.b	"special trick to play music",10
		dc.b	"in 14 Bit and offers some",10
		dc.b	"nice echo effects.",10,10
		dc.b	"It allows to change all",10
		dc.b	"parameters in realtime.",10
		dc.b	`68020+ CPU required.`,10,10

		dc.b	"WARNING! Don`t set the",10
		dc.b	"volume boost too high. If  ",10
		dc.b	"you hear loud strange noi- ",10
		dc.b	"ses, decrease the volume   ",10
		dc.b	"boost immediately in order ",10
		dc.b	"to prevent your HiFi equip-",10
		dc.b	"ment from getting damaged  ",10
		dc.b	`when you play music at high`,10
		dc.b	`volume levels. (like me)   `,10,10
		dc.b	"Version "
		ver
		dc.b	" ",10
		dc.b	"Written by Buggs of Defect.",10
		dc.b	"The mixing routine is based",10
		dc.b	'on the "PS3M" code written ',10
		dc.b	"and © by Jarno Paananen,all",10
		dc.b	`optimizations & extensions`,10
		dc.b	`© Henryk "Buggs" Richter,`,10
		dc.b	`14 Bit-table creation and`,10
		dc.b	`calibration routines by`,10
		dc.b	`Christian Buchner`,10,0

my_easytitle:	dc.b	"14 Bit Amplifier Message",0

Aboutmessage:	dc.b	"     Eagleplayer 14 Bit 32 voices Amiga Amplifier "
		ver
		dc.b	10,10
		dc.b	"            © 1995 Buggs of DEFECT",10
		dc.b	"Contact Me At :",10
		dc.b	"                  Henryk Richter",10
		dc.b	"             Stephan-Jantzen-Ring  47",10
		dc.b	"                  18106  Rostock",10
		dc.b	"                     Germany",10,10
		dc.b	"             Phone:  +49-0381-1208867",10
		dc.b	"       EMAIL: tfa652@cks1.rz.uni-rostock.de",10,10,0

Project0WTitle:
	dc.b	'14 Bit Amplifier',0
Project0STitle:
	DC.B	'14 Bit  Echo / Cross Echo  Amplifier, © DEFECT Softworks',0
	even

Project0GTypes:
    DC.W    LISTVIEW_KIND
    DC.W    INTEGER_KIND
    DC.W    SLIDER_KIND
    DC.W    SLIDER_KIND
    DC.W    TEXT_KIND
    DC.W    TEXT_KIND
    DC.W    MX_KIND
    DC.W    SLIDER_KIND
    DC.W    CHECKBOX_KIND
    DC.W    SLIDER_KIND
    DC.W    CHECKBOX_KIND
    DC.W    TEXT_KIND



Project0NGads:
NG_Listview
    DC.W    3,14,360,48
    DC.L    LISTVIEWText,0
    DC.W    GD_LISTVIEW
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    286,97,68,14
    DC.L    SamplefreqText,0
    DC.W    GD_Samplefreq
    DC.L    0,0,0
    DC.W    10,99,271,11
    DC.L    MixingSliderText,0
    DC.W    GD_MixingSlider
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    65,74,244,11
    DC.L    VBoostText,0
    DC.W    GD_VBoost
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    26,72,26,14
    DC.L    VoicesText,0
    DC.W    GD_Voices
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    315,73,36,13
    DC.L    0,0
    DC.W    GD_NumVBoost
    DC.L    0,0,0
    DC.W    10,120,17,9
    DC.L    ChooseEchoText,0
    DC.W    GD_ChooseEcho
    DC.L    PLACETEXT_RIGHT,0,0
    DC.W    61,163,248,11
    DC.L    DelayText,0
    DC.W    GD_Delay
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    116,133,26,11
    DC.L    ActiveText,0
    DC.W    GD_Active
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    169,133,123,10
    DC.L    IntensityText,0
    DC.W    GD_Intensity
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    11,162,26,11
    DC.L    CrossText,0
    DC.W    GD_Cross
    DC.L    PLACETEXT_ABOVE,0,0
    DC.W    298,131,59,13
    DC.L    0,0
    DC.W    GD_Gadget110
    DC.L    0,0,0

myhook					;Hookfunktion für das Listview-Gadget, um
					;Einträge hervorzuheben
	dcb.b	mln_size,0
	dc.l	my_hook
	dc.l	0
	dc.l	0

Project0GTags:
    DC.L    GTLV_ShowSelected,0
	dc.l	GTLV_CallBack,myhook

    DC.L    TAG_DONE
    DC.L    GTIN_Number,32768
    DC.L    GTIN_MaxChars,5
    DC.L    STRINGA_Justification,GACT_STRINGCENTER
    DC.L    TAG_DONE
    DC.L    GTSL_Min,400
    DC.L    GTSL_Max,5800
    DC.L    GTSL_Level,100
    DC.L    PGA_Freedom,LORIENT_HORIZ
    DC.L    GA_Immediate,1
    DC.L    GA_RelVerify,1
    DC.L    TAG_DONE
    DC.L    GTSL_Min,10
    DC.L    GTSL_Max,50
    DC.L    GTSL_Level,50
    DC.L    PGA_Freedom,LORIENT_HORIZ
    DC.L    GA_Immediate,1
    DC.L    GA_RelVerify,1
    DC.L    TAG_DONE
    DC.L    GTTX_Text,VoicesString
    DC.L    GTTX_Border,1
    DC.L    TAG_DONE
    DC.L    GTTX_Text,NumVBoostString
    DC.L    TAG_DONE
    DC.L    GA_RelVerify,1
    DC.L    GTMX_Labels,ChooseEchoLabels
    DC.L    TAG_DONE
    DC.L    GTSL_Max,63
    DC.L    GTSL_MaxLevelLen,5
    DC.L    GTSL_LevelFormat,DelayFormat
    DC.L    GTSL_LevelPlace,PLACETEXT_RIGHT
    DC.L    PGA_Freedom,LORIENT_HORIZ
    DC.L    GA_Immediate,1
    DC.L    GA_RelVerify,1
    DC.L    TAG_DONE
    DC.L    GT_Underscore,'_'
    DC.L    TAG_DONE
    DC.L    GTSL_Max,4
    DC.L    PGA_Freedom,LORIENT_HORIZ
    DC.L    GA_Immediate,1
    DC.L    GA_RelVerify,1
    DC.L    TAG_DONE
    DC.L    TAG_DONE
;	DC.L    GTTX_Text,Gadget110String
    DC.L    TAG_DONE

Intensity_txt:
	dc.b	`50%   `,0
Intensity_txt_sz = *-Intensity_txt
	dc.b	`25%   `,0
	dc.b	`12.5% `,0
	dc.b	`6.25% `,0
	dc.b	`3.125%`,0

VolumeFormat:
    DC.B    '%3.3ld',0

NumVBoostString:
    DC.B    '10.2',0

VoicesString:
    DC.B    '16',0

LISTVIEWText:
    DC.B    'Prefs for each number of Voices',0

SamplefreqText:
    DC.B    '',0

MixingSliderText:
    DC.B    'Sample mixing frequency',0

VBoostText:
    DC.B    'Volume Boost',0

VoicesText:
    DC.B    'Voices',0

ChooseEchoText:
    DC.B    '',0

DelayText:
    DC.B    'Delay',0

ActiveText:
    DC.B    '_Active',0

IntensityText:
    DC.B    'Intensity',0

CrossText:
    DC.B    '<->',0
DelayFormat:
    DC.B    '%ld',0

	even
ChooseEchoLabels:
    DC.L    ChooseEchoLab0
    DC.L    ChooseEchoLab1
    DC.L    ChooseEchoLab2
    DC.L    0

ChooseEchoLab0:    DC.B    'Echo1',0
ChooseEchoLab1:    DC.B    'Echo2',0
ChooseEchoLab2:    DC.B    'Echo3',0
	even

Project0NewMenu0:
    DC.B    NM_TITLE,0
    DC.L    Project0MName0
    DC.L    0
    DC.W    0
    DC.L    0,0

	DC.B	NM_ITEM,0
	DC.L	Project0MName1
	DC.L	Project0MComm1
Hiercheck
	DC.W	CHECKIT!Menutoggle
	DC.L	0,0

	DC.B    NM_ITEM,0
	DC.L    NM_BARLABEL,0
	DC.W    0
	DC.L    0,0

    DC.B    NM_ITEM,0
    DC.L    Project0MName6
    DC.L    Project0MComm6
    DC.W    0
    DC.L    0,0

    DC.B    NM_ITEM,0
    DC.L    Project0MName7
    DC.L    Project0MComm7
    DC.W    0
    DC.L    0,0

    DC.B    NM_ITEM,0
    DC.L    Project0MName8
    DC.L    Project0MComm8
    DC.W    0
    DC.L    0,0

    DC.B    NM_TITLE,0
    DC.L    Project0MName61
    DC.L    0
    DC.W    0
    DC.L    0,0

    DC.B    NM_ITEM,0
    DC.L    Project0MName71
    DC.L    0
    DC.W    0
    DC.L    0,0

    DC.B    NM_ITEM,0
    DC.L    Project0MName81
    DC.L    0
    DC.W    0
    DC.L    0,0

    DC.B    NM_END,0
    DC.L    0,0
    DC.W    0
    DC.L    0,0

Project0MName0:		DC.B    'Project',0
Project0MName1		dc.b	'Global',0
Project0MComm1		dc.b	'G',0
Project0MName6:		DC.B    'About',0
Project0MComm6:		DC.B    'A',0
Project0MName7:		DC.B    'Hide',0
Project0MComm7:		DC.B    'H',0
Project0MName8:		DC.B    'Quit',0
Project0MComm8:		DC.B    'Q',0

Project0MName61:
    DC.B    'Settings',0

Project0MName71:
    DC.B    'Reset to Defaults',0

Project0MName81:
    DC.B    'Save Settings',0


	even
TD:
    DC.L    TAG_DONE

	*------- Activate ------*
EP_Menu:	dc.l	EPM_Show		;Next
		dc.w	0			;Left Edge
		dc.w	0			;Verti Pos.
		dc.w	0			;Width-Size (Negationbreite)
		dc.w	10			;Hight-Size
		dc.w	$5B
		dc.l	0
		dc.l	.ActivateIText
		dc.l	0
		dc.b	0
		ds.b	7
		dc.l	0			*Kick2.04
.ActivateIText:	dc.b	0,3
		ds.w	2
		dc.w	1
		dc.l	0			*Topaz80
		dc.l	0			*Active.MSG (filled by EP)
		dc.l	0
		dc.w	EPNr_MainWindow	*EPNr_Engine
		dc.w	LNr_Active

	*------- Show-Window ------*
EPM_Show	dc.l	0 EPM_BarLabel		;Next
		dc.w	0			;Left Edge
		dc.w	0			;Verti Pos.
		dc.w	0			;Width-Size (Negationbreite)
		dc.w	10			;Hight-Size
		dc.w	$5B
		dc.l	0
		dc.l	.ShowIText
		dc.l	0
		dc.b	0
		ds.b	7
		dc.l	0			*Kick2.04
.ShowIText:	dc.b	0,3
		ds.w	2
		dc.w	1
		dc.l	0			*Topaz80
		dc.l	0			*Active.MSG (filled by EP)
		dc.l	0
		dc.w	EPNr_EngineShowState
		dc.w	LNr_Show2

;----------------- hier nun die Daten für den Mixing Player ----------------

AdditiveArray	dcb.b	255,$55
		dc.b	$7f

LastBuffer	dc.l	0

OLDINT0:	dc.l	0
OLDINT1:	dc.l	0
OLDINT2:	dc.l	0
OLDINT3:	dc.l	0

audiorate	dc.l	3546895		;für PAL
mrate		dc.l	0
mixingperiod	dc.l	0
clock		dc.l	0

Int_loopStruct
	dc.l	0
	dc.l	0
	dc.b	2
	dc.b	32
	dc.l	INT_Name1		;Name
	dc.l	0
	dc.l	Domix			;Interrupt Routine

Aud0Interrupt:
	dc.l	0
	dc.l	0
	dc.b	2
	dc.b	127
	dc.l	INT_Name1		;Name
	dc.l	0
	dc.l	INT_Aud			;Interrupt Routine

INT_Name1	dc.b	"Mixingroutine Audio Interrupt",0

myAudioStruct	dc.l	0
numStructs	dc.w	0
numleft		dc.w	0
numright	dc.w	0
divtabs		ds.l	16
chans		dc.w	0

	;diese hier zusammen lassen
buffer0		dc.l	0
buffer1		dc.l	0
buffer2		dc.l	0
buffer3		dc.l	0
cbufad		dc.l	copybuf14
	;---------------------------
SpecialBuffer1	dc.l	0
SpecialBuffer2	dc.l	0
mixad1		dc.l	mix
mixad2		dc.l	mix2
Vtabaddr	dc.l	0
usedmode	dc.l	0
buff14		dc.l	0
buff14_2	dc.l	0
vtab:		dc.l	0
vtabsize:	dc.l	0
onplay		dc.b	0
		dc.b	0
prefetch	dc.w	0
newmixingperiod	dc.l	0
tmpvol		dc.l	0
tmpvol2		dc.w	0	
calcvol		ds.w	4			;berechnete Lautstärkewerte
fformat		dc.w	0
playmixrate	dc.l	0

Tempbuffer_C	dc.l	0			;aktueller Tembuffer
Num_C		dc.w	0			;aktuelle Anzahl der Puffer

Echoad_L	ds.l	NumEchos		;Einsprungadressen für Echo Linker Kanal
Echoad_R	ds.l	NumEchos		;Einsprungadressen für Echo Rechter Kanal
Echovalid	dc.b	0
Private_AS	dc.b	0			;Kennung, ob WaitForStruct gesetzt ist

;divtab2
;a set 16
;	rept	16
;		ds.b	256*a
;a set a-1
;	endr
;Vtab		ds.b	66*256			; Volume tab size for 14 Bit
;						; for 8 Bit only ½ of this needed

;*********** Leertabellen (später im BSS-Hunk) ***********************
		section	1,BSS_p
		rsreset
datas:
RealNumGadgets	rs.w	1
MyVariable	rs.l	1
Attr		rs.l	2
msgport		rs.l	1
intsave:	rs.l	1
grafsave	rs.l	1
gadsave:	rs.l	1
_dos		rs.l	1
Port:		rs.l	1
Jumpadr		rs.l	1
Menuadr:	rs.l	1
mypubscreen:	rs.l	1	;aktueller Publicscreen
fonth:		rs.l	1	;Fonthöhe
;fontatt:	rs.l	1	;Fontattr Strukturadresse (entweder die des
				;Screens oder die eigene,wenn Screenfont zu
				;groß)
vi:		rs.l	1	;Visualinfo

mytags:		rs.l	10*2
mycontextgad:	rs.b	gg_sizeof	;CreateContext() braucht Zeiger auf
					;leere Gadgetstruktur !?

mygad:		rs.b	gng_sizeof	;Platz für New Gadget Struktur


Project0Gadgets:	rs.l	21
Gadgetadrs=Project0Gadgets

BufNewGad:		rs.w	4
			rs.l	2
			rs.w	1
			rs.l	3

myhoehe2:	rs.w	1
myhoehe1:	equ	myhoehe2
winwidth:	rs.w	1

Project0GList:	rs.l	1
Project0Menus:	rs.l	1
Winhandle	rs.l	1
WindowDisabled	rs.w	1
Font:		rs.l	1
FontX:		rs.w	1
FontY:		rs.w	1
OffX:		rs.w	1
OffY:		rs.w	1
Echo_MXactive	rs.w	1	;aktiver MX-Switch
		rs.w	1

MY_Easystruct:	rs.l	1	;EASY-Request
		rs.l	1
		rs.l	1
		rs.l	1
		rs.l	1
temp1		rs.l	128
temp2		rs.l	128
temp:		rs.l	1

refreshflag	rs.b	1
counter		rs.b	1		;Frei
topazused	rs.b	1
modeid		rs.b	1

an_structadr	rs.l	1
Mytask		rs.l	1
MySignal	rs.l	1
immernull	rs.l	1
myobject	rs.l	1
merkpos		rs.l	1
currpos		rs.l	1
visible		rs.l	1
myplayertaglist	rs.l	1
maxtextwidth	rs.w	1
maxvisible	rs.w	1
SaveString	rs.l	1
myfontatt:	rs.l	1
		rs.w	2

MsgPort1:	rs.b	mp_size	;extra Messageport

micros		rs.l	1
seconds		rs.l	1
merk_seconds	rs.l	1
lasttime	rs.l	1
messagesent	rs.b	1
messagesent2	rs.b	1
savemodnr	rs.l	1
word7		rs.w	1	;Wort für Absturz bei Modifikation
counter2	rs.w	1
onsysfont	rs.b	1
exg		rs.b	1
onglobal	rs.b	1
		rs.b	1
MyRastport	rs.b	rp_sizeof
fontadr		rs.l	1
onmixingslider	rs.b	1
onvboostslider	rs.b	1
OnDelaySlider	rs.b	1
OnIntensitySlider	rs.b	1

NumVoc		rs.l	1	;"12"
numboo		rs.l	1	;"10.1 "
		rs.w	1

SelectedL:	rs.w	1		;die zwei gehören zusammen
SelectedW:	rs.w	1		;-------------------------
Currentnumvoc	rs.w	1

List:		rs.b	lh_size
Nodes:		rs.b	ML_Sizeof*32		;max. 32 voices


;------------------------- Daten, die mit der Konfig abgespeichert werden ----------------

ConfigDatas	rs.b	0

PrefsVersion	rs.l	1		;"EP".w + Versionsnummer, wg. Veränderungen = Check

PrefsList	rs.b	my_prefs_Sizeof

WinPosX		rs.w	1
WinPosY		rs.w	1
ZoomPosX	rs.w	1
ZoomPosY	rs.w	1
ZoomState	rs.b	1		;Zoom or not zoom
		rs.b	1

;-------------------------------------------------------------------------------------------
ConfigDatasEND	rs.b	0


	ifne	debug
saveusernr	rs.w	1
	endc
DatasLen:	rs.w	0
		ds.b	DatasLen

	section	2,bss_c
;-------------- Puffer für die DMA simulierung -----------------
Buffer0a:	ds.w	SamLen*NumChipBuffers
		ds.w	2

Buffer1a:	ds.w	SamLen*NumChipBuffers
		ds.w	2

Buffer2a:	ds.w	SamLen*NumChipBuffers
		ds.w	2

Buffer3a:	ds.w	SamLen*NumChipBuffers
		ds.w	2
EndBuffer
Security2	ds.b	20

	section	3,bss_p

MyUPSStruct	ds.b	UPS_Sizeof

StartBSSBuffer
TempBuffer	ds.b	samlen*4*NumBuffers
TempbufferSize=*-Tempbuffer
		ds.b	2			;zur Sicherheit
TempBuffer2	ds.b	samlen*4*NumBuffers
		ds.b	20			;zur Sicherheit

Extra_AS	ds.b	AS_Sizeof*32
EndBSSBuffer

;tab	ds.l	$20000
	end
