* Programmheader
*
*	Name:		DataPACK
*	Author:		SDI
*	Distribution:	PD
*	Description:	XFD external decruncher for unknown PACK data
*	Compileropts:	-
*	Linkeropts:	-
*
* 1.0   07.02.98 : first version
* 1.1   08.02.98 : recognized Testament PACK as PP20 Clone, added PP2O and
*	"Seek and Destroy" PP-Clones
* 1.2   09.02.98 : little fixes
* 1.3   28.02.98 : better Pepsi-Recognition
* 1.4   03.03.98 : removed PP2O
* 1.5   11.11.98 : removed PP20-Clone

		INCLUDE	"AINCLUDE:IncDirs.i"
		INCLUDE	"lvo.i"

		INCLUDE	"libraries/xfdmaster.i"
		INCLUDE	"exec/memory.i"

		* head function for tests
*		INCLUDE	"xfdExeHead.a"

ForeMan		MOVEQ	#-1,D0		;security
		RTS

		DC.L	XFDF_ID
		DC.W	1,0
		DC.L	0,0,Slave1

		DC.B	"$VER: DataPACK 1.5 (11.11.1998) by SDI",0
N_PACKPepsi	DC.B	'PACK Data (Pepsi Game)',0
		EVEN

*** This is a ByteKiller clone!

Slave1		DC.L	0		;next slave
		DC.W	2		;version
		DC.W	38		;master version
		DC.L	N_PACKPepsi	;name
		DC.W	XFDPFF_DATA|XFDPFF_USERTARGET|XFDPFF_RECOGLEN
		DC.W	0
		DC.L	RB_PACKPepsi	;recog buffer
		DC.L	DB_PACKPepsi	;decrunch buffer
		DC.L	0		;recog segment
		DC.L	0		;decrunch segment
		DC.W	0,0
		DC.L	$10		;MinBufSize

*************************************************************************
*	Recog buffer function: receives buffer + length in A0/D0	*
*	and receives pointer to struct RecogResult in A1		*
*************************************************************************

PEP_SOURCELEN	EQU	4
PEP_DESTLEN	EQU	8
PEP_PACKMATCH	EQU	$025569EE

RB_PACKPepsi	MOVEQ	#0,D0			; False

		CMPI.L	#"PACK",(A0)
		BNE.B	.No

		MOVE.L	PEP_SOURCELEN(A0),D1
		SUBI.L	#PEP_PACKMATCH,D1 ; must be greater than PACKMATCH
		BLE.B	.No
		CMP.L	#$C800000,D1	  ; should be shorther than 200MB
		BGT.B	.No
		MOVE.L	PEP_DESTLEN(A0),D1
		CMP.L	PEP_SOURCELEN(A0),D1 ; source <= destination
		BLE.B	.No
		SUBI.L	#PEP_PACKMATCH,D1 ; must be greater than PACKMATCH
		BLE.B	.No
		CMP.L	#$C800000,D1	  ; should be shorther than 200MB
		BGT.B	.No

		MOVE.L	D1,xfdrr_FinalTargetLen(A1)
		MOVE.L	D1,xfdrr_MinTargetLen(A1)
		MOVEQ	#1,D0			; True
.No		RTS

*************************************************************************
*	Decrunch buffer functions: receives xfdbiBufferInfo in A0	*
*************************************************************************

DB_PACKPepsi	MOVEM.L	D2-D5/A2/A4-A6,-(A7)
		MOVE.L	4.W,A6
		MOVE.L	A0,A5
		MOVE.L	xfdbi_SourceBuffer(A5),A4

		MOVE.W	#XFDERR_NOMEMORY,xfdbi_Error(A5)
		MOVE.L	PEP_DESTLEN(A4),D0
		SUBI.L	#PEP_PACKMATCH,D0
		MOVE.L	xfdbi_UserTargetBuf(A5),A1
		MOVE.L	D0,xfdbi_TargetBufSaveLen(A5)

		BTST.B	#XFDFB_USERTARGET,1+xfdbi_Flags(A5)
		BNE.B	.Decrunch

		MOVE.L	D0,xfdbi_TargetBufLen(A5)
		MOVE.L	xfdbi_TargetBufMemType(A5),D1
		JSR	_LVOAllocMem(A6)
		MOVE.L	D0,xfdbi_TargetBuffer(A5)
		BEQ.B	.End

		MOVE.L	D0,A1
.Decrunch	MOVE.L	A4,A0
		LEA.L	$10(A0),A0	* pack space start
		MOVE.L	xfdbi_TargetBufSaveLen(A5),D1
		MOVE.L	PEP_SOURCELEN(A4),D0
		SUBI.L	#PEP_PACKMATCH,D0
		MOVE.W	#XFDERR_CORRUPTEDDATA,xfdbi_Error(A5)

		BSR.B	DecompPepsi

		BTST.B	#XFDFB_USERTARGET,1+xfdbi_Flags(A5)
		BNE.B	.End
		TST.L	D0
		BNE.B	.ok
		MOVE.L	xfdbi_TargetBuffer(A5),A1
		MOVE.L	xfdbi_TargetBufLen(A5),D0
		JSR	_LVOFreeMem(A6)
		MOVEQ	#0,D0
		BRA.B	.End
.ok		CLR.W	xfdbi_Error(A5)
		MOVEQ	#1,D0
.End		MOVEM.L	(A7)+,D2-D5/A2/A4-A6
		RTS

*************************************************************************
*	      decrunch routine for Pepsi PACK data			*
*									*
*	gets following parameters:					*
*		D0	crunched size					*
*		D1	uncrunched size					*
*		A0	source buffer					*
*		A1	destination buffer				*
*	returns D0: 0 = error						*
*************************************************************************

DecompPepsi	MOVEA.L	A1,A2
		MOVE.L	-4(A0),D5	* checksum
		ADDA.L	D0,A0	* get end of source buffer
		ADDA.L	D1,A2	* get end of destination buffer
		MOVE.L	-(A0),D0
		EOR.L	D0,D5
.Decr1		LSR.L	#1,D0
		BNE.B	.Decr2
		BSR.B	.DecrSub1
.Decr2		BCS.B	.Decr9
		MOVEQ	#8,D1
		MOVEQ	#1,D3
		LSR.L	#1,D0
		BNE.B	.Decr3
		BSR.B	.DecrSub1
.Decr3		BCS.B	.Decr11
		MOVEQ	#3,D1
		CLR.W	D4
.Decr4		BSR.B	.DecrSub2
		MOVE.W	D2,D3
		ADD.W	D4,D3
.Decr5		MOVEQ	#7,D1
.Decr6		LSR.L	#1,D0
		BNE.B	.Decr7
		BSR.B	.DecrSub1
.Decr7		ROXL.L	#1,D2
		DBRA	D1,.Decr6
		MOVE.B	D2,-(A2)
		DBRA	D3,.Decr5
		BRA.B	.Decr13

.Decr8		MOVEQ	#8,D1
		MOVEQ	#8,D4
		BRA.B	.Decr4

.Decr9		MOVEQ	#2,D1
		BSR.B	.DecrSub2
		CMPI.B	#2,D2
		BLT.B	.Decr10
		CMPI.B	#3,D2
		BEQ.B	.Decr8
		MOVEQ	#8,D1
		BSR.B	.DecrSub2
		MOVE.W	D2,D3
		MOVE.W	#$C,D1
		BRA.B	.Decr11

.Decr10		MOVE.W	#9,D1
		ADD.W	D2,D1
		ADDQ.W	#2,D2
		MOVE.W	D2,D3
.Decr11		BSR.B	.DecrSub2
.Decr12		SUBQ.W	#1,A2
		MOVE.B	(A2,D2.W),(A2)
		DBRA	D3,.Decr12
.Decr13		CMPA.L	A2,A1
		BLT.B	.Decr1
		MOVEQ	#0,D0	* error
		TST.L	D5		* checksum ok ?
		BNE.B	.End
		MOVEQ	#1,D0	* no error
.End		RTS	

.DecrSub1	MOVE.L	-(A0),D0
		EOR.L	D0,D5		* checksum
		MOVE	#$10,CCR
		ROXR.L	#1,D0
		RTS	

.DecrSub2	SUBQ.W	#1,D1
		CLR.W	D2
.DecrSub2_1	LSR.L	#1,D0
		BNE.B	.DecrSub2_2
		MOVE.L	-(A0),D0
		EOR.L	D0,D5		* checksum
		MOVE	#$10,CCR
		ROXR.L	#1,D0
.DecrSub2_2	ROXL.L	#1,D2
		DBRA	D1,.DecrSub2_1
		RTS	
		END
