	**************************************************************
	** EaglePlayer/DelitrackerV1.3+ Noisepackerplayroutine 3.x  **
	** angepaßt 1993 von Buggs of DEFECT                        **
	**************************************************************
test = 0
		incdir	include:
		include	misc/Eagleplayer.i

	ifne	test
	lea	mod,a0
	bsr	np_check

	lea	mod,a0
	move.l	a0,np_data
	bsr	np_init

wa	move.b	$dff006,d0
	cmp.b	#$50,d0
	bne	wa
	bsr	np_music
	btst	#6,$bfe001
	bne	wa
	move.w	#15,$dff096
	illegal
	endc

	PLAYERHEADER Tags
	dc.b	'$VER: NoisePacker3 Eagleplayer V1.50 (jan/26/93)',0,0

Tags		dc.l	DTP_PlayerVersion,5
		dc.l	DTP_PlayerName,playername
		dc.l	DTP_Creator,creator
		dc.l	DTP_Check2,NP_check
		dc.l	DTP_Interrupt,interrupt
		dc.l	DTP_InitPlayer,initplayer
		dc.l	DTP_EndPlayer,endplayer
		dc.l	DTP_InitSound,np_init
		dc.l	DTP_EndSound,np_endsnd
		dc.l	DTP_NextPatt,NP_NextPattern
		dc.l	DTP_PrevPatt,NP_PrevPattern
		dc.l	DTP_Volume,SetVol
		dc.l	DTP_Balance,SetVol
		dc.l	EP_Flags,EPB_Save!EPB_Restart!EPB_Songend!EPB_Volume!EPB_Balance!EPB_Voices!EPB_Analyzer!EPB_Moduleinfo!EPB_Nextpatt!EPB_Prevpatt
		dc.l	EP_Voices,SetVoices
		dc.l	EP_Get_ModuleInfo,NP_GetInfos
		dc.l	EP_GetPositionNr,NP_GetPosNr
		dc.l	EP_StructInit,StrukInit
		dc.l	0

Playername:	dc.b	"NoisePacker 3.x",0
creator		dc.b	"Twins of Phenomena,",10
		dc.b	"adapted by DEFECT",0
NP_Prefix	dc.b	"NP3.",0
		even

*-----------------------------------------------------------------------------*
NP_SongendAdr:	dc.l	0
NP_Structadr:	ds.b	ups_sizeof
NP_Data:	dc.l	0
NP_RightVol	dc.w	0
NP_LeftVol	dc.w	0
NP_SndVol	dc.w	0

NP_Voice1	dc.w	1
NP_Voice2	dc.w	1
NP_Voice3	dc.w	1
NP_Voice4	dc.w	1
NP_OldVoice1	dc.w	0
NP_OldVoice2	dc.w	0
NP_OldVoice3	dc.w	0
NP_OldVoice4	dc.w	0
num_samples:	dc.w	0

;================ Struktur übergeben =====================================
Strukinit:	lea	NP_StructAdr(pc),a0
		rts


*-----------------------------------------------------------------------------*
NP_NextPattern:	lea	np_block+$15(pc),a6
		lea	np_voidat1+128(pc),a2
		moveq	#0,d0
		move.b	d0,(a6)
		move.l	d0,-32(a2)
		move.l	d0,-64(a2)
		move.l	d0,-96(a2)
		move.l	d0,-128(a2)

		lea	np_block+2(pc),a6
		move.l	(a6)+,a0
		addq.w	#2,(a6)
		move.w	(a6),d0
		cmp.w	-4(a0),d0
		bne.b	.np_next
		move.w	-2(a0),d0

		move.l	NP_SongEndAdr(pc),a0
		jsr	(a0)
	
		cmp.w	#254,d0
		blo.s	.ok
		moveq	#0,d0
.ok		move.w	d0,(a6)
.np_next:	bra	np_PATTE

*------------------------------------------------------------------------*
NP_PrevPattern:	lea	np_block+$15(pc),a6
		lea	np_voidat1+128(pc),a2
		moveq	#0,d0
		move.b	d0,(a6)
		move.l	d0,-32(a2)
		move.l	d0,-64(a2)
		move.l	d0,-96(a2)
		move.l	d0,-128(a2)

		lea	np_block+6(pc),a6
		subq.w	#2,(a6)
		tst.w	(a6)
		bge.s	NP_Patte
		clr.w	(a6)

*------------------------------------------------------------------------*
NP_Patte:	lea	$dff0a8,a0
		move.w	#0,(a0)
		move.w	#0,$10(a0)
		move.w	#0,$20(a0)
		move.w	#0,$30(a0)
		rts

*------------------------------------------------------------------------*
NP_GetPosNr:	moveq	#0,d0
		move.w	np_block+6(pc),d0
		lsr.w	#1,d0
		rts

*--------------- Daten in die Userprogramm-Struktur übergeben -----------*
NP_GetVoice:	movem.l	d0-d1/a1,-(sp)
		lea	NP_Structadr(pc),a1	;1.Kanal
		cmp.l	#$dff0a0,a4
		beq.s	.yes
		lea	NP_Structadr+ups_modulo(pc),a1	;2.Kanal
		cmp.l	#$dff0b0,a4
		beq.s	.yes
		lea	NP_Structadr+ups_modulo*2(pc),a1	;3.Kanal
		cmp.l	#$dff0c0,a4
		beq.s	.yes
		lea	NP_Structadr+ups_modulo*3(pc),a1	;4.Kanal
.yes:		move.w	-6(a2),UPS_Voice1Per(a1)	;Sampleperiode
		move.l	(a3),UPS_Voice1Adr(a1)		;Sampleadresse
		moveq	#0,d1
		cmp.w	#1,10(a3)	;Repeat on ?
		bhi.s	.ok
		moveq	#1,d1		;nein,Repeat "off" setzen
.ok		move.w	d1,UPS_Voice1Repeat(a1)
		move.w	4(a3),UPS_Voice1len(a1)	;Länge/2
		movem.l	(sp)+,d0-d1/a1
		rts

*------------------- Tag-Item Struktur für Module-Info -----------------*
NP_InfoBuffer:	dc.l	MI_Length
NP_Infolen:	dc.l	0
		dc.l	MI_SongSize
NP_InfoSong	dc.l	0
		dc.l	MI_SamplesSize
NP_InfoSamples	dc.l	0
		dc.l	MI_Samples
NP_NumSamples	dc.l	0
		dc.l	MI_CalcSize
NP_Numall	dc.l	0
		dc.l	MI_Pattern
NP_Numpatts	dc.l	0
		dc.l	MI_Unpackedsystem,MIUS_Noisetracker
		dc.l	MI_Unpacked
NP_Unp		dc.l	0
		dc.l	MI_Prefix,NP_Prefix
		dc.l	0

*------------------------------------------------------------------------*
NP_GetInfos:	lea	NP_InfoBuffer(pc),a0
		move.l	np_numpatts(pc),d0
		lsr.w	#3,d0
		move.l	d0,np_numpatts-NP_InfoBuffer(a0)
		mulu	#1024,d0
		add.l	#$43c,d0
		add.l	NP_InfoSamples(pc),d0
		move.l	d0,np_unp-NP_InfoBuffer(a0)
NP_Return:	rts

*-----------------------------------------------------------------------*
*		d0 Bit 0-3 = Set Voices Bit=1 Voice on			*
SetVoices:	lea	NP_Voice1(pc),a0
		lea	NP_StructAdr(pc),a1
		moveq	#1,d1
		move.w	d1,(a0)+			Voice1=0 setzen
		btst	#0,d0
		bne.s	.NoVoice1
		clr.w	-2(a0)
		clr.w	$dff0a8
		clr.w	UPS_Voice1Vol(a1)
.NoVoice1:	move.w	d1,(a0)+			Voice2=0 setzen
		btst	#1,d0
		bne.s	.NoVoice2
		clr.w	-2(a0)
		clr.w	$dff0b8
		clr.w	UPS_Voice2Vol(a1)
.NoVoice2:	move.w	d1,(a0)+			Voice3=0 setzen
		btst	#2,d0
		bne.s	.NoVoice3
		clr.w	-2(a0)
		clr.w	$dff0c8
		clr.w	UPS_Voice3Vol(a1)
.NoVoice3:	move.w	d1,(a0)+			Voice4=0 setzen
		btst	#3,d0
		bne.s	.NoVoice4
		clr.w	-2(a0)
		clr.w	$dff0d8
		clr.w	UPS_Voice4Vol(a1)
.NoVoice4:	move.w	d0,UPS_DMACON(a1)
		moveq	#0,d0
		rts

*-----------------------------------------------------------------------*
SetVol:		move.w	DTG_SndLBal(a5),d0
		mulu	DTG_SndVol(a5),d0
		lsr.w	#6,d0				; durch 64
		move.w	d0,NP_LeftVol			; Left Volume

		move.w	DTG_SndRBal(a5),d0
		mulu	DTG_SndVol(a5),d0
		lsr.w	#6,d0				; durch 64
		move.w	d0,NP_RightVol			; Right Volume


		lea	NP_OldVoice1(pc),a0
		lea	$dff0a0,a4
		moveq	#3,d1
.SetNew		move.w	(a0)+,d0
		bsr.s	NP_SetVoices
		addq.l	#8,a4
		addq.l	#8,a4
		dbf	d1,.SetNew
		rts
*-----------------------------------------------------------------------*
NP_SetVoices:	and.w	#$7f,d0
		cmp.l	#$dff0a0,a4			;Left Volume
		bne.s	.NoVoice1
		move.w	d0,NP_OldVoice1
		tst.w	NP_Voice1
		bne.s	.Voice1On
		moveq	#0,d0
.Voice1On:	move.w	d0,NP_StructAdr+UPS_Voice1Vol
		mulu.w	NP_LeftVol(pc),d0
		bra.b	.SetIt
.NoVoice1:	cmp.l	#$dff0b0,a4			;Right Volume
		bne.s	.NoVoice2
		move.w	d0,NP_OldVoice2
		tst.w	NP_Voice2
		bne.s	.Voice2On
		moveq	#0,d0
.Voice2On:	move.w	d0,NP_StructAdr+UPS_Voice2Vol
		mulu.w	NP_RightVol(pc),d0
		bra.b	.SetIt
.NoVoice2:	cmp.l	#$dff0c0,a4			;Right Volume
		bne.s	.NoVoice3
		move.w	d0,NP_OldVoice3
		tst.w	NP_Voice3
		bne.w	.Voice3On
		moveq	#0,d0
.Voice3On:	move.w	d0,NP_StructAdr+UPS_Voice3Vol
		mulu.w	NP_RightVol(pc),d0
		bra.b	.SetIt
.NoVoice3:	cmp.l	#$dff0d0,a4
		bne.s	.Return
		move.w	d0,NP_OldVoice4
		tst.w	NP_Voice4
		bne.w	.Voice4On
		moveq	#0,d0
.Voice4On:	move.w	d0,NP_StructAdr+UPS_Voice4Vol
		mulu.w	NP_LeftVol(pc),d0
.SetIt:		lsr.w	#6,d0
		move.w	d0,8(a4)
.Return:	rts


*--------------------------- Modultyp überprüfen -----------------------------*
NP_Check:	ifeq	test
		move.l	dtg_ChkData(a5),a0
		endc

	move.l	a0,a1
	move.l	a0,a2

	move.w	(a0),d0		;Anzahl der Samples
	move.w	d0,d1		;merken
	and.w	#$f,d0		;jedes NP Modul beginnt mit
				;(Anzahl der Samples*16) OR 12
	cmp.w	#$c,d0		;ist die 12 vorhanden ?
	bne	.NP_Fail	;nö
	lsr.w	#4,d1		;$c rausrotieren
	cmp.w	#$1f,d1		;Anzahl der Samples > 32 (0..31)
	bhi	.NP_Fail	;ja,Fehler

	moveq	#0,d2
	move.w	4(a0),d2	;Offset Patterns
	btst	#0,d2		;Ungerade ?
	bne	.np_fail	;->Fehler
	move.l	d2,NP_Numpatts	;Anzahl Patterns
	add.w	(a0),a1		;auf Pointer addieren
	move.w	-4(a1),d0	;Höchste Patternnummer ist 2 mal eingetragen
	btst	#0,d0		;Ungerade ?
	bne	.np_fail	;->Fehler
	cmp.w	2(a0),d0	;Vergleich
	bne	.NP_fail	;Unstimmigkeit,Ende der Vorstellung

	move.l	a0,a1		;Pointer auf Modul saven
	add.w	(a1),a0		;Liste der Patterns für jeweilige Songposition
	moveq	#0,d1		;D1 löschen
	move.w	-4(a0),d1	;Länge des Songs
	asr.w	#1,d1		;durch 2 dividieren
	move.l	d1,NP_Infolen	;Songlänge in Patterns (für Eagleplayer)
	subq.w	#1,d1
				;in A0 Zeiger auf Tabelle für die
				;Zeiger auf die Patternnummer für die
				;jeweilige Songposition

	moveq	#0,d0
	move.w	d1,d4		;brauchen wir noch
.check2
	move.w	(a0)+,d3	;Patternnummer
	cmp.w	d0,d3		;mit derzeit höchster vergleichen
	bls.s	.check1		;kleiner -> weiter
	move.w	d3,d0		;höchste Patternnr. merken
.check1	dbf	d1,.check2	;alle Patterns
	addq.l	#8,d0		;+8
	cmp.w	d0,d2		;Gegenvergleich
	bne	.np_fail	;passt nicht -> Fehler
	and.w	#7,d0		;ausmaskieren (Patternnummer muß durch 8 
				;teilbar sein)
	bne	.np_fail	;nein->Fehler

			;A0 muß hier auf dem Anfang der Offsettabelle der
			;Patterns stehen

	moveq	#0,d0		;D0 killen
	move.w	(a1),d0		;Pointer auf Patternliste
	add.w	2(a1),a1	;Länge dieser Patternliste
	add.l	d0,a1		;zusammenaddieren = Pointer auf Patternoffsets

	cmp.l	a0,a1		;stimmt das ?
	bne	.np_fail	;wieso auch ?

;an dieser Stelle kann als gesichert gelten,daß es sich um ein
;Noisepackermodul handelt,es bleibt nur die Unterscheidung zum
;Noisepacker 2

;Trick: beim Noisepacker3 sind die Sampleinfos folgendermaßen
;angeordnet :
;
;Lautstärke.w,Adresse.l,Länge.w,Repeatadresse.l,Repeatlänge.w,Repeatbeginn.w
;
;bei Noisepacker 2.02 so:
;
;Adresse.l,Länge.w,Lautstärke.w,Repeatadresse.l,Repeatlänge.w,Repeatbeginn.w

	moveq	#0,d0
	move.w	(a2),d0		;Anzahl der Sampeles
	lsr.w	#4,d0		;$c rausrotieren
	move.w	d0,d2		;für später aufheben
	move.l	d0,NP_NumSamples;nur für Eagleplayer wichtig,hat mit Checkrou-
				;tine nichts zu tun
	subq.w	#1,d0		;minus 1 für DBF-Schleife

	lea	8(a2),a0	;Zeiger auf SampleVolume (NP3)

	moveq	#0,d1		;Länge NP3
	moveq	#0,d7		;...
.np_Getstuff
	moveq	#0,d6		;...

	move.w	6(a0),d6	;Länge NP3
	add.l	d6,d1

	cmp.b	#$40,1(a0)	;Lautstärke NP3 überprüfen
	bhi	.np_fail	;größer 64 -> Fehler
		;^- Anmerkung:sollte es sich um ein NP2-Modul handeln,kommt
		;   es hierzu sowieso erst,wenn das Modul beim Rippen außerhalb
		;   der 4-Megabyte Chipmem Grenze lag (also allein
		;   AA-Chipset-Rechner - und dann noch nicht mal 1200 und 4000)
	cmp.b	#$F,(a0)	;Finetune,falls irgendeiner auf die Idee kommt
				;und Protrackermodule hiermit packen will
	bhi	.np_fail	;Finetune bei allen mir bekannten Protrackern
				;geht nur bis $F (-8...7)

	tst.l	2(a0)		;Sampleadresse schon mal initialisiert (Modul
				;gerippt oder NP2 - Modul) ?
	beq.s	.np3_testwei	;wenn also eine Null.l steht,heißt das:
				;Noisepacker 3,weil bei NP2 in unteren Wort
				;die Länge steht,die immer größer 0 ist

	tst.l	8(a0)		;Test,ob Repeatbeginn eingetragen ist,wenn
				;nicht,dann ist es kein NP3-Modul,weil bei Init
				;der Adresse auch Repeatbeginn gesetzt wird
	beq	.np_fail	;Fehler

	move.w	14(a0),d6	;RepeatBeginn in Worten
	add.l	d6,d6		;mal 2 -> Repeatbeginn in Bytes
	move.l	2(a0),d7	;Samplestart
	add.l	d6,d7		;Samplestart+Repeatstart
	cmp.l	8(a0),d7	;Samplestart+Repeatstart = Repeatbeginn im
				;Modul
	bne	.np_fail	;Fehler
.np3_testwei
	addq.l	#8,a0		;nächstes Sample ist 16 Bytes weiter
	addq.l	#8,a0		

	dbf	d0,.np_getstuff	;alle Samples durchgehen

	add.l	d1,d1		;in D1 steht nun die Länge des gesamten
				;Sampleblockes !

	suba.l	a1,a1		;Moduladresse
	add.w	(a2)+,a1	;die ersten 4 Wörter repräsentieren
	add.w	(a2)+,a1	;die gesamte Länge des
	add.w	(a2)+,a1	;Einführungsblockes und der Patterns

	add.w	(a2)+,a1
	move.l	a1,NP_infosong	;nur für Eagleplayer von Nutzen

	add.l	d1,a1		;Gesamtlänge berechnen

	move.l	a1,NP_numall		;nur für Eagleplayer von Nutzen
	move.l	d1,NP_infosamples	;nur für Eagleplayer von Nutzen

;folgende Routine kann bei Bedarf eingefügt werden,sie testet
;die Länge des berechneten Modules und vergleicht mit den Realwerten
;	move.l	a1,a2		;saven
;	sub.l	#2000,a2	;~2k nach unten Spielraum,falls falsch gerippt
;	add.l	#2000,a1	;~2k nach oben Spielraum,falls falsch gerippt
;	move.l	dtg_ChkSize(a5),d1	;Länge des getesteten Moduls
;	cmp.l	a2,d1		;Vergleich: Realwert und min. Wert
;	blt.s	.np_fail	;Fehler
;	cmp.l	a1,d1		;Vergleich: Realwert und max. Wert
;	bgt.s	.np_fail	;Fehler

.NP_ok		moveq	#0,d0
		rts

.NP_fail	moveq	#-1,d0			;fail!
		rts					;gone!

*--------------------------------------------------------------------------*
Interrupt	movem.l	d0-d7/a0-a6,-(sp)
		lea	NP_StructAdr(pc),a0
		move.w	#UPSB_Adr!UPSB_LEN!UPSB_Per!UPSB_Vol!UPSB_DMACON,UPS_Flags(a0)
		clr.w	UPS_Voice1per(a0)
		clr.w	UPS_Voice2per(a0)
		clr.w	UPS_Voice3per(a0)
		clr.w	UPS_Voice4per(a0)
		move.w	#1,UPS_Enabled(A0)

		bsr.w	NP_Music
		lea	NP_StructAdr(pc),a0
		clr.w	UPS_Enabled(A0)
		movem.l	(sp)+,d0-d7/a0-a6
		rts

*--------------------------------------------------------------------------*
Initplayer:	moveq	#0,d0
		move.l	dtg_GetListData(a5),a0
		jsr	(a0)
		lea	NP_Data(pc),a1
		move.l	a0,(a1)
		move.l	DTG_SongEnd(a5),NP_SongEndAdr-NP_Data(a1)
		move.l	dtg_AudioAlloc(a5),a0
		jmp	(a0)

Endplayer:	move.l	dtg_AudioFree(a5),a0
		jmp	(a0)

;======== Noisepacker III Playroutine (C) Phenomena =========================
np_init		lea	np_datastart(pc),a6
		moveq	#NP_Datalen>>1-1,d0
.clr:		clr.w	(a6)+
		dbf	d0,.clr

		moveq	#1,d0
		moveq	#0,d1

		move.l	np_data(pc),a4
		lea	$dff000,a5

		lea	np_datastart(pc),a6
		move.l	#0,(a6)+
		move.w	d0,(a6)+

		move.l	a4,a3
		add.w	(a4)+,a3
		move.l	a3,(a6)+
		move.w	d1,(a6)+

np_ini1:		adda.w	(a4)+,a3
		move.l	a3,(a6)+
		dbf	d0,np_ini1

		move.w	(a4)+,d0
		adda.l	d0,a3
		move.l	#$82000006,(a6)+
		move.w	#$0100,(a6)+
		move.l	#np_portup,(a6)+
		move.l	#np_portdown,(a6)+
		move.l	#np_port,(a6)+
		move.l	#np_vib,(a6)+
		move.l	#np_port2,(a6)+
		move.l	#np_vib2,(a6)+
		move.l	#np_volslide,(a6)+
		move.l	#np_arp,(a6)+
		move.l	#np_songjmp,(a6)+
		move.l	#np_setvol,(a6)+
		move.l	#np_pattbreak,(a6)+
		move.l	#np_filter,(a6)+
		move.l	#np_setspeed,(a6)+
		moveq	#0,d0

		movea.l	a4,a6

		adda.w	-8(a4),a6
		suba.w	#12,a6
np_ini2:	move.l	a3,2(a4)
		movea.l	a3,a2
		move.w	14(a4),d0
		add.w	d0,d0
		adda.l	d0,a2
		move.l	a2,8(a4)
		move.w	6(a4),d0
		add.w	d0,d0
		adda.l	d0,a3
		adda.w	#16,a4
		cmpa.l	a4,a6
		bne.b	np_ini2

		clr.w	$a8(a5)
		clr.w	$b8(a5)
		clr.w	$c8(a5)
		clr.w	$d8(a5)
		move.w	#$f,$96(a5)
		rts



;=========================================================================
np_endsnd	lea	np_block+$15(pc),a6
		lea	np_voidat1+128(pc),a2
		moveq	#0,d0
		move.b	d0,(a6)
		move.l	d0,-32(a2)
		move.l	d0,-64(a2)
		move.l	d0,-96(a2)
		move.l	d0,-128(a2)

		moveq	#31,d0
		lea	np_voidat1(pc),a0
.npclr		clr.l	(a0)+
		dbf	d0,.npclr
		moveq	#0,d0
		lea	$dff000,a0
		move.l	d0,$a6(a0)
		move.l	d0,$b6(a0)
		move.l	d0,$c6(a0)
		move.l	d0,$d6(a0)
		move.w	#$f,$96(a0)
		rts

*----------------------------------------------------------------------------*
np_music	moveq	#0,d6
		lea	$dff0d0,a4
		lea	np_block(pc),a6
		subq.w	#1,(a6)+
		bhi	np_nonew
		movea.l	(a6)+,a1
		adda.w	(a6)+,a1
		movea.l	(a6)+,a0
		adda.w	(a1),a0
		move.l	(a6)+,d2
		movea.l	np_data(pc),a1
		subq.w	#8,a1
		lea	np_voidat1(pc),a2
		moveq	#8,d0
		moveq	#0,d1
		moveq	#0,d4
		moveq	#0,d5

np_loop1:	move.w	(a0)+,d1
		tst.w	(a2)+
		bpl.b	np_lop3
		addq.w	#1,-(a2)
		adda.w	#32,a2
		addq.w	#8,a4
		bra	np_lop7

np_lop3		movea.l	d2,a3
		adda.l	d1,a3
		adda.w	(a2),a3
		move.b	(a3)+,d1
		bpl.b	np_lop4
		ext.w	d1
		addq.w	#1,d1
		addq.w	#1,(a2)
		move.w	d1,-(a2)
		move.w	d6,8(a2)
		adda.w	#32,a2
		addq.w	#8,a4
		bra	np_lop7

np_lop4		move.b	(a3)+,d3
		move.b	(a3)+,d4
		addq.w	#3,(a2)+
		movea.l	a1,a3
		move.b	d1,d7
		lsl.w	#8,d7
		or.b	d3,d7
		andi.w	#$1f0,d7
		bne.b	np_loop3
		adda.w	(a2)+,a3
		addq.w	#2,a2
		addq.w	#2,a3
		bra.b	np_loop4

np_loop3:	move.w	d7,(a2)+
		adda.w	d7,a3
		move.w	(a3)+,(a2)+
np_loop4:	andi.w	#$f,d3
		move.w	d3,(a2)+
		move.w	d4,(a2)+
		andi.w	#$fe,d1
		beq.b	np_loop5
		move.w	np_periods-2(pc,d1.w),d7
		subq.w	#3,d3
		beq	np_setport
		subq.w	#2,d3
		beq	np_setport
		or.w	d0,d5
		move.w	d7,(a2)+	;-6
		move.w	d1,(a2)+	;-4
		move.w	d6,(a2)+	;-2

		bsr	np_getvoice
					;(a2)->Periode
		move.l	(a3)+,(a4)+	;Adresse		  (a3)
		move.w	(a3)+,(a4)+	;Länge/2		 4(a3)
		move.l	(a3)+,(a2)+	;Repeatadresse		 6(a3)
		move.w	(a3)+,(a2)+	;Repeatlänge		10(a3)

		subq.w	#6,d3
		bmi.b	np_loop6
		add.w	d3,d3
		add.w	d3,d3
		movea.l	38(a6,d3.w),a3
		jmp	(a3)

np_loop5	adda.w	#12,a2
		addq.w	#6,a4
		subi.w	#11,d3
		bmi.b	np_loop6
		add.w	d3,d3
		add.w	d3,d3
		movea.l	38(a6,d3.w),a3
		jmp	(a3)

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

NP_setvolume:	move.l	a4,-(sp)
		subq.l	#8,a4
		bsr	NP_SetVoices
		move.l	(sp)+,a4
		rts

np_loop6	move.w	-12(a2),(a4)+
np_loop7	;move.w	-18(a2),(a4)	;Volume
		move.l	d0,-(sp)
		move.w	-18(a2),d0
		bsr	NP_setvolume
		move.l	(sp)+,d0
		addq.w	#8,a2
		bra.s	np_com

np_lop7		;move.w	-26(a2),(a4)	;Volume

		move.l	d0,-(sp)
		move.w	-26(a2),d0
		bsr	NP_setvolume
		move.l	(sp)+,d0

np_com:		suba.w	#$18,a4
		lsr.w	#1,d0
		bne	np_loop1
		move.w	d5,6(a4)
		or.w	d5,(a6)+
		move.w	(a6)+,-20(a6)
		bsr	waitdma
		move.w	np_block+16(pc),$dff096
		bsr	waitdma
		bset	#0,(a6)+
		beq.b	np_break
		addq.b	#1,(a6)
		cmpi.b	#64,(a6)
		bne.b	np_next

np_break:	move.b	d6,(a6)
		move.l	d6,-32(a2)
		move.l	d6,-64(a2)
		move.l	d6,-96(a2)
		move.l	d6,-128(a2)

		lea	np_block+2(pc),a6
		movea.l	(a6)+,a0
		addq.w	#2,(a6)
		move.w	(a6),d0
		cmp.w	-4(a0),d0
		bne.b	np_next
		move.w	-2(a0),(a6)

	ifeq	test
		move.l	NP_SongEndAdr(pc),a0
		jsr	(a0)
	endc

np_next		move.l	np_voidat1+18(pc),$dff0d0
		move.w	np_voidat1+22(pc),$dff0d4
		move.l	np_voidat1+50(pc),$dff0c0
		move.w	np_voidat1+54(pc),$dff0c4
		move.l	np_voidat1+82(pc),$dff0b0
		move.w	np_voidat1+86(pc),$dff0b4
		move.l	np_voidat1+114(pc),$dff0a0
		move.w	np_voidat1+118(pc),$dff0a4
		rts

np_checkend	bpl	np_notdone
np_notdone	rts

np_setvol	move.w	d4,-18(a2)
		bra.w	np_loop6

np_pattbreak	move.b	d6,4(a6)
		bra.w	np_loop6

np_songjmp	move.b	#63,5(a6)
		move.b	d4,-9(a6)
		bra.w	np_loop6

np_setspeed	move.w	d4,2(a6)
		bra	np_loop6

np_filter	;andi.b	#$fd,$bfe001
	;	or.b	d4,$bfe001
		bra	np_loop6

np_setport	adda.w	#12,a2
		addq.w	#8,a4
		cmp.w	-12(a2),d7
		slt	(a2)
		beq.b	np_clear
		move.w	d7,2(a2)
		bra	np_loop7

np_clear	move.w	d6,2(a2)
		bra	np_loop7

np_nonew	lea	np_voidat1(pc),a0
		moveq	#3,d0
np_lop1		move.w	8(a0),d1
		beq.w	np_lop2
		subq.w	#8,d1
		bhi.w	np_lop2
		addq.w	#7,d1
		add.w	d1,d1
		add.w	d1,d1
		movea.l	20(a6,d1.w),a3
		jmp	(a3)

np_lop2:	adda.w	#32,a0
		suba.w	#$10,a4
		dbf	d0,np_lop1
		rts

np_portup:	move.w	10(a0),d2
		sub.w	d2,12(a0)
		cmpi.w	#$71,12(a0)
		bpl.b	np_portup2
		move.w	#$71,12(a0)

np_portup2:	move.w	12(a0),6(a4)
		bra.b	np_lop2

np_portdown:	move.w	10(a0),d2
		add.w	d2,12(a0)
		cmpi.w	#$358,12(a0)
		bmi.b	np_portdown2
		move.w	#$358,12(a0)

np_portdown2:	move.w	12(a0),6(a4)
		bra.b	np_lop2

np_arp:		move.w	-2(a6),d2
		sub.w	16(a6),d2
		neg.w	d2
		move.b	np_arplist(pc,d2.w),d2
		beq.b	np_arp0
		subq.w	#2,d2
		beq.b	np_arp2

np_arp1		move.w	10(a0),d2
		lsr.w	#3,d2
		andi.w	#$e,d2
		bra.b	np_arp3

np_arp2		move.w	10(a0),d2
		andi.w	#$f,d2
		add.w	d2,d2
np_arp3		add.w	14(a0),d2
		cmpi.w	#$48,d2
		bls.b	np_arp4
		moveq	#$48,d2
np_arp4		lea	np_periods-2(pc),a3
		move.w	(a3,d2.w),6(a4)
		bra	np_lop2

np_arp0		move.w	12(a0),6(a4)
		bra	np_lop2

np_arplist	dc.b 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1
np_sin		dc.b $00,$18,$31,$4a,$61,$78,$8d,$a1,$b4,$c5,$d4,$e0,$eb,$f4,$fa,$fd
		dc.b $ff,$fd,$fa,$f4,$eb,$e0,$d4,$c5,$b4,$a1,$8d,$78,$61,$4a,$31,$18

np_vib		move.w	10(a0),d3
		beq.b	np_vib2
		move.w	d3,30(a0)
np_vib2		move.w	16(a0),d3
		lsr.w	#2,d3
		andi.w	#$1f,d3
		moveq	#0,d2
		move.b	np_sin(pc,d3.w),d2
		move.w	30(a0),d3
		andi.w	#$f,d3
		mulu.w	d3,d2
		lsr.w	#7,d2
		move.w	12(a0),d3
		tst.b	17(a0)
		bmi.b	np_vibsub
		add.w	d2,d3
		bra.b	np_vib3

np_vibsub:	sub.w	d2,d3
np_vib3		move.w	d3,6(a4)
		move.w	30(a0),d3
		lsr.w	#2,d3
		andi.w	#$3c,d3
		add.b	d3,17(a0)
		cmpi.b	#20,d1
		bne	np_lop2

np_volslide:	move.w	10(a0),d2
		add.b	d2,7(a0)
		bmi.b	np_vol3
		cmpi.w	#$40,6(a0)
		bmi.b	np_vol2
		move.w	#$40,6(a0)
np_vol2	;	move.w	6(a0),8(A4)
		move.l	d0,-(sp)
		move.w	6(a0),d0
		bsr	NP_setvoices
		move.l	(sp)+,d0
		bra	np_lop2

np_vol3		move.w	d6,6(a0)
		bra.s	NP_vol2

np_port		move.w	10(a0),d2
		beq.b	np_port2
		move.w	d2,28(a0)

np_port2:	move.w	26(a0),d2
		beq.b	np_rts
		move.w	28(a0),d3
		tst.w	24(a0)
		bne.b	np_sub
		add.w	d3,12(a0)
		cmp.w	12(a0),d2
		bgt.b	np_portok
		move.w	d2,12(a0)
		move.w	d6,26(a0)

np_portok:	move.w	12(a0),6(a4)
np_rts		cmpi.b	#16,d1
		beq.b	np_volslide
		bra	np_lop2

np_sub		sub.w	d3,12(a0)
		cmp.w	12(a0),d2
		blt.b	np_portok
		move.w	d2,12(a0)
		move.w	d6,26(a0)
		move.w	12(a0),6(a4)
		cmpi.b	#16,d1
		beq	np_volslide
		bra	np_lop2

waitdma		movem.l	d0-d1,-(sp)
		moveq	#7,d0
.wait1		move.b	$dff006,d1
.wait2		cmp.b	$dff006,d1
		beq	.wait2
		dbra	d0,.wait1
		movem.l	(sp)+,d0-d1
		rts

np_datastart	dc.l	0
np_block	ds.l	19
np_voidat1	ds.l	32
		dc.l	0
NP_Datalen=*-np_datastart
	ifne	test
Mod
	incdir	vr0:
;	incbin	Np3.agnostica
	incbin	Np3.quartz
	endc
