*****************************************************************************
**                                                                         **
** Eagleripper: Magnetic Fields                                            **
**                                                                         **
** 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.
**
***************************************************************************** 


*-----------------------------------------------------------------------------*
*			      Eagleripper V1.0				      *
*			       Magnetic Fields				      *
*-----------------------------------------------------------------------------*
Test	= 0
		incdir	include:
		include	misc/eagleplayer.i
		include	misc/eagleplayerripper.i
		include	exec/exec_lib.i
			
	if	Test
	lea	data+$f6,a0
	*lea	MF_Tags,a0
	move.l	#datasize,d0
	move.l	a0,a5
	move.l	a0,a4
	move.l	d0,d4
	move.l	d0,d6
wait:	move.l	a5,a1
	move.l	a4,a0
	move.l	d4,d0
	move.l	(a1),d1
	bsr	MF_Ripp2
	tst.l	d0
	beq.s	.Ja
	addq.l	#2,a5
	subq.l	#2,d6
	blt.s	.Err
	btst	#6,$bfe001
	bne.s	wait
.err:	moveq	#-1,d0
.ret:	illegal

.ja:	move.l	a0,a1
	lea	playtest,a0
	move.l	#datasize,d0
	bsr	ExtRipp
	move.l	d0,a0
	moveq	#0,d0
	bra.s	.Ret
	endc
		RIPPERHEADER	MF_Tags

	dc.b	"Magnetic Fields EagleRipper V1.0",10
	dc.b	"done by Eagleeye/DFT 28.08.97",0
	even

MF_Tags:	dc.l	RPT_Formatname,.Formatname
		dc.l	RPT_Ripp1,MF_Ripp2
		dc.l	RPT_RequestRipper,1
		dc.l	RPT_Version,1<<16!0
		dc.l	RPT_Creator,.Creator
		dc.l	RPT_Prefix,.Prefix
		dc.l	RPT_Playername,.Playername
		dc.l	RPT_ExtRipp,ExtRipp
		dc.l	RPT_EagleBase,EagleBase
		dc.l	RPT_ExtSave,ExtSave
		dc.l	0

.Creator:	dc.b	"Shaun Southern/Magnetic Fields, adapted by DEFECT",0
.Playername:
.Formatname:	dc.b	"Magnetic Fields",0
.Prefix:	dc.b	"MFP.",0
		even
EagleBase:	dc.l	0


*-----------------------------------------------------------------------------*
* Input: a0=Adr (start of memory)
*	 d0=Size (size of memory)
*	 a1=current adr
*	 d1=(a1.l)
* Output:d0=Error oder NULL
*	 d1=Size
*	 a0=Startadr (data)
*-----------------------------------------------------------------------------*
MF_Ripp2:	cmp.b	#$7f,d1
		beq.s	.TestWeiter
		rts

.TestWeiter:	lea	-$f6(a1),a0

*-----------------------------------------------------------------------------*
* Output: d0=Error oder NULL
*	  d2=Patternanz
*	  d3=Memsize für Protracker
*	  d4=Samplesize
Check:		moveq	#30,d0
		move.l	a0,a1
		moveq	#0,d2
.NextSample:	moveq	#0,d1
		move.w	(a1),d1
		beq.s	.LeeresSample
		add.l	d1,d2
		add.l	d1,d2
		cmp.b	#64,3(a1)
		bhi.w	.Error
		cmp.w	6(a1),d1
		blo.w	.Error
		bra.s	.SampleOk
.LeeresSample:	tst.l	2(a1)
		bne.w	.Error
		cmp.w	#1,6(a1)
		bhi.w	.Error
.SampleOk:	lea	8(a1),a1
		dbf	d0,.NextSample


		*-- Kennung --*
		move.b	$F8(A0),D1
		move.b	$17B(A0),D0
		cmp.b	D1,D0
		bne.w	.Error
		move.b	$17D(A0),D0
		cmp.b	D1,D0
		bne.b	.Error

		moveq	#0,d0
		move.b	(a1)+,d0		;Length
		cmp.b	#$7F,(a1)		;Restart
		bne.w	.Error

	movem.l	d3-d7/a2-a6,-(a7)
		lea	$fa(a0),a1
		moveq	#0,d2
		moveq	#$7f,d0
.NextPattern:	move.b	(a1)+,d1
		blt.s	.Error2
		cmp.b	d1,d2
		bgt.s	.D2Groesser
		move.b	d1,d2
.D2Groesser:	dbf	d0,.NextPattern

		addq.l	#1,d2
		move.l	d2,d1
		mulu	#1024,d1
		add.l	d1,d3			;Memsize
		add.l	#1084,d3

		*--- Länge berechnen ---*
		move.w	$17A(A0),D0
		asl.w	#3,D0			;Länge der Spurenliste
		lea	$17E(A0),A3
		moveq	#0,d3
		move.b	$f8(a0),d3
		lsl.l	#2,d3
		subq.l	#1,d3
		moveq	#0,d4			;Spuren
		blt.s	.Weiter
		moveq	#0,d2
.NextSpur:	move.w	0(A3,D2.W),D1
		adda.w	D0,d1
		cmp.l	d1,d4
		bhi.s	.D4Gr
		move.l	d1,d4
.D4Gr:		addq.l	#2,d2
		dbf	d3,.NextSpur
.Weiter:
		*--- höchstes Pattern durchtesten ---*
		lea	(a3,d4.w),a1
		bsr	CheckPatternLen

		addq.l	#4,a3			;Letzte Langwort adden
		move.l	a3,d1
		sub.l	a0,d1

		movem.l	(a7)+,d3-d7/a2-a6
		moveq	#0,d0
		rts

.Error2:	movem.l	(a7)+,d3-d7/a2-a6
.Error:		moveq	#EPR_UnknownFormat,d0
		rts


*-----------------------------------------------------------------------------*
CheckPatternLen:movem.l	d0/d1/d2/d3/a0/a1,-(a7)

		sub.l	a3,a3
		moveq	#63,d3
		add.w	d2,d2
		moveq	#-$10,d1
.TestPattern:	add.l	#$10,d1

		movem.l	D1/D2,-(SP)
		lsr.w	#4,D1
		move.w	D1,D2
		lsr.w	#4,D2
		andi.w	#3,D2
	*move.b	0(a1,D2.W),D0
	lea	0(a1,D2.W),a2
	move.b	(a2),D0
		cmp.l	a2,a3
		bhi.s	.Ok1
		move.l	a2,a3
.Ok1:		move.w	D1,D2
		lsr.w	#2,D2
		andi.w	#3,D2
		add.b	D0,D2
	*move.b	0(a1,D2.W),D0
	lea	0(a1,D2.W),a2
	move.b	(a2),d0
	cmp.l	a2,a3
	bhi.s	.Ok2
	move.l	a2,a3
.Ok2:		move.w	D1,D2
		andi.w	#3,D2
		add.b	D0,D2
		moveq	#0,D0
	*move.b	0(a1,D2.W),D0
	lea	(a1,D2.W),a2
	move.b	(a2),d0
	cmp.l	a2,a3
	bhi.s	.Ok3
	move.l	a2,a3
.Ok3:
		add.w	D0,D0
	*	move.l	0(a1,D0.W),D0
	lea	(a1,D0.W),a2
	move.l	(a2),d0
	cmp.l	a2,a3
	bhi.s	.Ok4
	lea	(a2),a3
.OK4:
		movem.l	(SP)+,D1/D2

		dbf	d3,.TestPattern
		movem.l	(a7)+,d0/d1/d2/d3/a0/a1
		rts

*-----------------------------------------------------------------------------*
* Hier werden Zusatzfiles gesucht
* Input: a0=Memstart
*	 d0=MemSize
*	 a1=Modadr
*	 d1=Modsize (korrigiert bei -1)
*	 a2=Ripperstruct
* Output:d0=Error oder NULL
*-----------------------------------------------------------------------------*
ExtRipp:	clr.l	MemAdr
		clr.l	MemSize
		bsr	RippItExt
		bne.s	.Return
		move.l	Memadr(pc),a0
		move.l	MemSize(pc),d0
		moveq	#0,d1
		sub.l	a1,a1
	ifeq	Test
		jsr	ENPP_SetListData(a5)	;only for Ripper ExtRipp
	endc
		move.l	d0,d1
		moveq	#0,d0
.Return:	rts

MemAdr:		dc.l	0
MemSize:	dc.l	0

RippItExt:	move.l	EagleBase(pc),a5
	if	Test
	else
		move.l	a0,a4
		move.l	ERPSS_Memstart(a4),a0
		move.l	ERPSS_Memsize(a4),d0
		move.l	ERPSS_Fileptr(a4),a1
		move.l	ERPSS_Filesize(a4),d1
	endc
		move.l	d0,d3
		move.l	a1,a2

.Next		cmp.l	#$30025340,(a0)
		beq.s	.Found
.WeiterImText:	addq.l	#2,a0
		subq.l	#2,d3
		bgt.s	.Next
		moveq	#EPR_UnknownFormat,d0
		bra.s	.Return

.Found:		lea	Searchbytes(pc),a1
		move.l	#SearchBytessize/2-1,d3
		bsr	CheckString
		bne.s	.WeiterImText

		lea	10(a0),a0
		moveq	#0,d0
		move.w	(a0),d0
		beq.s	.findknownformats
		add.l	d0,a0			--> Adr des SamplePtr
		move.l	(a0),d0
		beq.s	.findknownformats
		move.l	d0,a1			--> Ptr to first Sample
		*sub.l	MF_SongDataPtr-MF_SampleStarts(a0),a1
		sub.l	124(a0),a1
		add.l	a2,a1
		move.l	a1,a0
.berechsize:
		*-- Länge der Samples berechnen --*
		moveq	#0,d0
		moveq	#30,d2
.NextSample:	moveq	#0,d1
		move.w	(a2),d1
		beq.s	.SampleOk
		add.l	d1,d0
		add.l	d1,d0
.SampleOk:	lea	8(a2),a2
		dbf	d2,.NextSample
		

		* Input: a0=Adr		\ datasize (e.g. Sampleparameter)
		*	 d0=Size	/
		*	 a1=Memblockadr	\ only if new allocated !!!!!
		*	 d1=Memblocksize/
		move.l	a0,Memadr
		move.l	d0,MemSize
		moveq	#0,d0
.Return:	rts

	*-- Jetzt wird nach Samples gesucht, die bereits bekannt sind --*
.findknownformats:
	ifeq test
		move.l	ERPSS_Memstart(a4),a0
		move.l	ERPSS_Memsize(a4),d0
		subq.l	#4,d0
		blt.s	.error
.fkf_next:	move.l	(a0),d1
		move.l	4(a0),d2
		cmp.l	#$c18222B,d1
		beq.s	.MF_CustCharCen
		cmp.l	#$555b6b63,d1
		beq.s	.MF_CustTitle
.fkf_doch:	addq.l	#2,a0
		subq.l	#2,d0
		bgt.s	.fkf_Next
	endc
.error:		moveq	#EPR_Functionaborted,d0
		rts


	*-- Dies sind Module, bei denen man die Samples nicht über einen
	*-- einen Pointer im Replay rausbekommt
.MF_CustCharcen:cmp.l	#$3538352e,d2
		bne.s	.fkf_doch
		bra.s	.berechsize
.MF_CustTitle:	cmp.l	#$4d4d5c53,d2
		bne.s	.fkf_doch
		bra.s	.berechsize



*-----------------------------------------------------------------------------*
* Input: a0=Adr 1
*	 a1=Adr 2
*	 d3=Size
* Output:d0=Error oder NULL
*-----------------------------------------------------------------------------*
CheckString:	movem.l	a0/a1/d1/d3,-(a7)
		moveq	#-1,d0
.CheckIt:	move.w	(a1)+,d1
		cmp.w	#-1,d1
		beq.s	.DiesNicht
		cmp.w	(a0),d1
		bne.s	.NE
.DiesNicht:	addq.l	#2,a0
		dbf	d3,.CheckIt
		moveq	#0,d0
.Ne:		movem.l	(a7)+,a0/a1/d1/d3
		rts




	*--- Playroutinensuche ---*
SearchBytes:	move.w	D2,D0
		subq.w	#1,D0
		asl.w	#2,D0
		moveq	#0,D3
		*lea	MF_Samplestarts(PC),A1	<-- dieses lea suchen
		dc.w	$43fa,-1
		move.w	D2,D4
		subq.l	#1,D2
		asl.l	#2,D2
		mulu.w	#8,D4
		move.l	0(A1,D2.L),4(A6)
		move.w	0(A3,D4.L),8(A6)
		move.w	0(A3,D4.L),$28(A6)
		move.b	2(A3,D4.L),$12(A6)
		move.b	3(A3,D4.L),$13(A6)
		move.w	4(A3,D4.L),D3

SearchBytessize	= *-SearchBytes


*-----------------------------------------------------------------------------*
* Hier werden Zusatzfiles gesucht
* Input: a1=Dir
*	 a2=first Filename
*	 a3=ERPSS_Struct
* Output:d0=Error oder NULL
*-----------------------------------------------------------------------------*
ExtSave:	move.l	EagleBase(pc),a5

		move.l	a1,EPG_Arg3(a5)
		move.l	a1,a0
		jsr	ENPP_CalcStringSize(a5)
		lea	(a0,d0.w),a1
		lea	.Smpl.MSG(pc),a0
		moveq	#32,d1
		jsr	ENPP_StringCopy(a5)
		lea	4(a2),a0
		jsr	ENPP_StringCopy(a5)


		*moveq	#0,d0
		*jsr	ENPP_GetLoadListData(a5)

		clr.l	MemAdr
		clr.l	MemSize

		move.l	a3,a0
		bsr	RippItExt
		bne.s	.Return
		move.l	MemAdr(pc),EPG_Arg1(a5)
		move.l	MemSize(pc),EPG_Arg2(a5)

		move.l	#-1,EPG_Arg4(a5)
		moveq	#%111,d0
		move.l	d0,EPG_Arg5(a5)
		moveq	#5,d0
		move.l	d0,EPG_ArgN(a5)
		move.l	EPG_SaveMem(a5),a0
	ifeq	Test
		jsr	(a0)
	endc
.Return:	rts


.Smpl.MSG	dc.b	"Smp.",0
		even


*-----------------------------------------------------------------------------*dGetPTNote:			rts
*-----------------------------------------------------------------------------*dGetPTNote:			rts



	if	test
	section daten,code_c
data:	
*	incdir	"Modules:__ Tests/__ Rippertests/"
*playtest
*	incbin	"MFP.ripptest_301"
*




	incdir	"Modules:Trackerclones/Magnetic_Fields/"
	ds.b	200
module:
		incbin	"MFP.03"
		*incbin	"MFP.501"
		*incbin	"MFP.507"
		*incbin	"MFP.78"
		*incbin	"MFP.KidChaos Title"
		*incbin	"MFP.SoWhat"
datensize	= *-data
playtest

	*--- Playroutinensuche ---*
	move.w	D2,D0
	subq.w	#1,D0
	asl.w	#2,D0
	moveq	#0,D3
	lea	MF_Samplestarts(PC),A1			<-- dieses lea suchen
	move.w	D2,D4
	subq.l	#1,D2
	asl.l	#2,D2
	mulu.w	#8,D4
	move.l	0(A1,D2.L),4(A6)
	move.w	0(A3,D4.L),8(A6)
	move.w	0(A3,D4.L),$28(A6)
	move.b	2(A3,D4.L),$12(A6)
	move.b	3(A3,D4.L),$13(A6)
	move.w	4(A3,D4.L),D3

MF_Samplestarts:
	dc.l	sample,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	dc.l	0,0,0,0,0,0
MF_SongDataPtr:	dc.l	module
		ds.b	200
sample:		*ds.b	1000000
	incbin	"Smp.03"
		*incbin	"Smp.501"
		*incbin	"Smp.507"
		*incbin	"Smp.78"
		*incbin	"SMP.KidChaos Title"
		*incbin	"SMP.SoWhat"

samplesize	= *-sample


datasize	= *-data


	endc


