* Programmheader
*
*	Name:		PCompress2
*	Author:		SDI
*	Distribution:	PD
*	Description:	XFD external decruncher for recognising PCompress2
*	Compileropts:	-
*	Linkeropts:	-
*
* 1.0   06.08.98 : first version
* 1.1   07.08.98 : added FALH and optimized FALH and CheckSum for FALH
* 1.2   08.08.98 : a lot of optimizations
* 1.3   02.10.98 : optimizations

		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,Slave_PCompHILH

		DC.B	"$VER: PCompress2 1.3 (02.10.1998) by SDI",0
N_PCompressHILH	DC.B	'PCompress HILH Data',0
N_PCompressFALH	DC.B	'PCompress FALH Data',0
		EVEN

Slave_PCompHILH	DC.L	Slave_PCompFALH	;next slave
		DC.W	2		;version
		DC.W	38		;master version
		DC.L	N_PCompressHILH	;name
		DC.W	XFDPFF_DATA|XFDPFF_USERTARGET|XFDPFF_RECOGLEN
		DC.W	0
		DC.L	RB_PCompHILH	;recog buffer
		DC.L	DB_PComp	;decrunch buffer
		DC.L	0		;recog segment
		DC.L	0		;decrunch segment
		DC.W	0,0
		DC.L	14		;MinBufSize

Slave_PCompFALH	DC.L	0		;next slave
		DC.W	2		;version
		DC.W	38		;master version
		DC.L	N_PCompressFALH	;name
		DC.W	XFDPFF_DATA|XFDPFF_USERTARGET|XFDPFF_RECOGLEN
		DC.W	0
		DC.L	RB_PCompFALH	;recog buffer
		DC.L	DB_PComp	;decrunch buffer
		DC.L	0		;recog segment
		DC.L	0		;decrunch segment
		DC.W	0,0
		DC.L	14		;MinBufSize

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

RB_PCompHILH	MOVEQ	#0,D0			; False

* optional	DC.L	'PRE',byte-num
* file format:	DC.B	'HILH'
*		DC.L	original length
*		DC.L	compressed length
*		DC.W	checksum

		CMP.W	#"PR",(A0)
		BNE.B	.normal
		CMP.B	#'E',2(A0)
		BNE.B	.No
		ADDQ.L	#4,A0
.normal		CMP.L	#"HILH",(A0)
		BNE.B	.No
		MOVE.L	4(A0),D1
		CMP.L	8(A0),D1	* source greater than destination
		BLE.B	.No
		MOVE.L	D1,xfdrr_FinalTargetLen(A1)
		MOVE.L	D1,xfdrr_MinTargetLen(A1)
		MOVEQ	#1,D0			; True
.No		RTS

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

RB_PCompFALH	MOVEQ	#0,D0			; False

* optional	DC.L	'PRE',byte-num
* file format:	DC.B	'FALH'
*		DC.L	original length
*		DC.L	size of compress data part 1
*		DC.W	checksum

		CMP.W	#"PR",(A0)
		BNE.B	.normal
		CMP.B	#'E',2(A0)
		BNE.B	.No
		ADDQ.L	#4,A0
.normal		CMP.L	#"FALH",(A0)
		BNE.B	.No
		MOVE.L	4(A0),D1
		CMP.L	8(A0),D1	* source greater than destination
		BLE.B	.No
		MOVE.L	D1,xfdrr_FinalTargetLen(A1)
		MOVE.L	D1,xfdrr_MinTargetLen(A1)
		MOVEQ	#1,D0			; True
.No		RTS

*************************************************************************
*	      decrunch buffer function for uncrunched files		*
*           receives xfdbiBufferInfo in A0 and bufferpos in A1		*
*************************************************************************

DB_PComp	MOVEM.L	D4/A2/A4-A6,-(A7)
		MOVE.L	xfdbi_SourceBuffer(A0),A4
		MOVE.L	A0,A5
		MOVE.L	4.W,A6

		CMP.W	#"PR",(A4)		* skip PRE0 or PRE1 header
		BNE.B	.calldecr
		ADDQ.L	#4,A4

.calldecr	MOVE.W	#XFDERR_NOMEMORY,xfdbi_Error(A5)
		MOVE.L	4(A4),D0
		MOVE.L	xfdbi_UserTargetBuf(A5),A2
		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,A2

.Decrunch	MOVEM.L	D2-D7/A2-A6,-(A7)
		CMP.W	#'HI',(A4)
		BNE.B	.falh
		BSR.B	DecompHILH
		BRA.B	.next
.falh		BSR.W	DecompFALH
.next		MOVEM.L	(A7)+,D2-D7/A2-A6
		CLR.W	xfdbi_Error(A5)
		MOVEA.L	xfdbi_TargetBufSaveLen(A5),D4
		BSR.W	GetCheckSum
		CMP.W	12(A4),D0
		BEQ.B	.ok
		MOVE.W	#XFDERR_CORRUPTEDDATA,xfdbi_Error(A5)
		BTST.B	#XFDFB_USERTARGET,1+xfdbi_Flags(A5)
		BNE.B	.skip
		MOVE.L	A2,A1
		MOVE.L	D4,D0
		JSR	_LVOFreeMem(A6)
.skip		MOVEQ	#0,D0
		BRA.B	.End
.ok		MOVEQ	#1,D0
.End		MOVEM.L	(A7)+,D4/A2/A4-A6
		RTS

*************************************************************************
*		 decrunch routine for HILH data				*
*									*
* This is made of reassembled code from PCompress2 and P-Reader.	*
* I removed a lot of obsolete stuff and made the routine mem to mem	*
* decrunching. Thus it should be a lot shorter and faster. I hope I     *
* catched all the stuff and did not miss any obsolete code.		*
*									*
* I think I also removed a bug. I tried PCompress2 with WordWorth7.01   *
* executable (972972 bytes) and it fails after circa 300000 bytes. My   *
* decruncher has no problems with this :-)				*
*									*
*	gets following parameters:					*
*		A4	source buffer					*
*		A2	destination buffer				*
*************************************************************************

DecompHILH	LINK	A5,#-$0018
		CLR.L	-4(A5)
		CLR.L	-$000C(A5)
		MOVE.L	4(A4),-8(A5)		* source size
		LEA	14(A4),A4		* source buffer
		MOVE.L	(A4)+,-$0014(A5)

		MOVE.L	#$844,D0
		MOVE.L	#MEMF_CLEAR,D1
		MOVE.L	4.W,A6
		JSR	_LVOAllocMem(A6)
		MOVEA.L	D0,A3
		TST.L	D0
		BEQ.B	.end
		BSR.B	DecrunchHILH
		MOVE.L	#$844,D0
		MOVEA.L	A3,A1
		MOVE.L	4.W,A6
		JSR	_LVOFreeMem(A6)
.end		UNLK	A5
		RTS

DecrunchHILH	SUBA.L	A6,A6			* current file size
		MOVEQ	#0,D2
DeHILH1 	CMPI.W	#$0020,D2
		BLT.B	DeHILH2
		CMPI.W	#$007E,D2
		BGT.B	DeHILH2
		MOVEQ	#3,D0
		BRA.B	DeHILH3
DeHILH2		MOVEQ	#1,D0
DeHILH3		MOVE.W	D2,D1
		ADDI.W	#$01F8,D1
		EXT.L	D1
		ASL.L	#1,D1
		MOVE.W	D0,(A3,D1.L)
		ADDQ.W	#1,D2
		CMPI.W	#$0105,D2
		BLT.B	DeHILH1
		MOVE.W	#1,$0702(A3)
		MOVE.W	#1,$05F8(A3)
		BSR.W	HILHsub5
		MOVE.L	#$80000000,$0840(A3)
		BRA.W	HILH19
HILH01		MOVE.L	-$000C(A5),D0
		CMP.L	A6,D0
		BHI.B	HILH02
		BSR.W	HILHsub3
		MOVE.L	D0,-$000C(A5)
		BRA.B	HILH01
HILH02		CLR.L	-$0010(A5)
		CLR.L	-$0018(A5)
		BSR.W	HILHsub6
		MOVE.W	D0,-2(A5)
		CMPI.W	#$0100,-2(A5)
		BGE.B	HILH03
		MOVE.L	A6,D0
		ADDQ.L	#1,A6
		MOVE.B	-1(A5),(A2,D0.L)
		BRA.W	HILH20
HILH03		CMPI.W	#$0104,D0
		BGE.B	HILH06
		SUBI.W	#$0100,D0
		MOVE.W	D0,-$000E(A5)
		ADDQ.W	#2,D0
		BSR.W	HILHsub1
		MOVE.W	-$000E(A5),D1
		BSR.W	HILHsub2
		MOVE.W	D0,-$0010(A5)
		ADDQ.W	#2,-$0010(A5)
HILH04		MOVE.L	A6,D0
		LEA	(A2,D0.L),A1
		LEA	-1(A2,D0.L),A0
HILH05		MOVE.W	-$0010(A5),D0
		BEQ.W	HILH20
		SUBQ.W	#1,-$0010(A5)
		MOVE.B	(A0)+,(A1)+
		ADDQ.L	#1,A6
		BRA.B	HILH05
HILH06		CMPI.W	#$0105,-2(A5)
		BGE.B	HILH07
		MOVE.W	#$0010,D0
		BSR.W	HILHsub1
		MOVE.W	D0,-$0010(A5)
		BRA.B	HILH04
HILH07		CMPI.W	#$0135,-2(A5)
		BGE.B	HILH09
		SUBI.W	#$0103,D0
		MOVE.W	D0,-$0016(A5)
		MOVEQ	#0,D3
HILH08		CMPI.L	#2,D3
		BEQ.W	HILH20
		MOVE.L	A6,D0
		MOVE.L	D0,D1
		MOVE.L	-$0018(A5),D2
		SUB.L	D2,D0
		MOVE.B	(A2,D0.L),(A2,D1.L)
		ADDQ.L	#1,A6
		ADDQ.L	#1,D3
		BRA.B	HILH08
HILH09		CMPI.W	#$0151,-2(A5)
		BGE.B	HILH12
		SUBI.W	#$0135,D0
		MOVE.W	D0,-$000E(A5)
		LSR.W	#2,D0
		BSR.W	HILHsub1
		ASL.W	#2,D0
		MOVE.W	D0,D7
		MOVE.W	-$000E(A5),D0
		ANDI.W	#3,D0
		OR.W	D0,D7
		MOVE.W	D7,D0
		MOVE.W	-$000E(A5),D1
		LSR.W	#2,D1
		BSR.W	HILHsub2
		MOVE.W	D0,-$0016(A5)
		ADDQ.W	#3,-$0016(A5)
		MOVE.W	#3,-$0010(A5)
HILH10		MOVE.L	A6,D3
		LEA	(A2,D3.L),A1
		MOVE.L	-$0018(A5),D2
		SUB.L	D2,D3
		LEA	(A2,D3.L),A0
HILH11		MOVE.W	-$0010(A5),D0
		BEQ.W	HILH20
		SUBQ.W	#1,-$0010(A5)
		MOVE.B	(A0)+,(A1)+
		ADDQ.L	#1,A6
		ADDQ.L	#1,D3
		BEQ.B	HILH10
		BRA.B	HILH11
HILH12		CMPI.W	#$0189,-2(A5)
		BGE.B	HILH13
		SUBI.W	#$0151,D0
		MOVE.W	D0,-$0016(A5)
		MOVEQ	#0,D0
		MOVE.W	-$0016(A5),D0
		DIVU	#$000E,D0
		MOVE.W	D0,-$000E(A5)
		SWAP	D0
		MOVE.W	D0,-$0016(A5)
		MOVE.W	-$000E(A5),D0
		ADDQ.W	#2,D0
		BSR.W	HILHsub1
		MOVE.W	-$000E(A5),D1
		BSR.W	HILHsub2
		MOVE.W	D0,-$0010(A5)
		MOVE.W	-$0016(A5),D0
		ADDQ.W	#2,D0
		BSR.W	HILHsub1
		MOVE.W	-$0016(A5),D1
		BSR.W	HILHsub2
		MOVE.W	D0,-$0016(A5)
		ADDQ.W	#8,-$0010(A5)
		MOVE.W	-$0010(A5),D0
		ADD.W	D0,-$0016(A5)
		BRA.W	HILH10
HILH13		CMPI.W	#$018A,-2(A5)
		BGE.B	HILH14
		MOVE.W	#$0010,D0
		BSR.W	HILHsub1
		MOVE.W	D0,-$0010(A5)
		MOVE.W	#$0010,D0
		BSR.W	HILHsub1
		MOVE.W	D0,-$0016(A5)
		BRA.W	HILH10
HILH14		CMPI.W	#$01A4,-2(A5)
		BGE.B	HILH15
		MOVEQ	#4,D2
		MOVE.W	#$018A,D3
		BRA.B	HILH18
HILH15		CMPI.W	#$01C0,-2(A5)
		BGE.B	HILH16
		MOVEQ	#5,D2
		MOVE.W	#$01A4,D3
		BRA.B	HILH18
HILH16		CMPI.W	#$01DC,-2(A5)
		BGE.B	HILH17
		MOVEQ	#6,D2
		MOVE.W	#$01C0,D3
		BRA.B	HILH18
HILH17		MOVEQ	#7,D2
		MOVE.W	#$01DC,D3
HILH18		SUB.W	D3,D0
		MOVE.W	D0,-$000E(A5)
		LSR.W	#1,D0
		ADDQ.W	#1,D0
		BSR.B	HILHsub1
		ASL.W	#1,D0
		MOVE.W	D0,D7
		MOVE.W	-$000E(A5),D0
		ANDI.W	#1,D0
		OR.W	D0,D7
		MOVE.W	D7,D0
		MOVE.W	-$000E(A5),D1
		LSR.W	#1,D1
		BSR.W	HILHsub2
		ADD.W	D2,D0
		MOVE.W	D0,-$0016(A5)
		MOVE.W	D2,-$0010(A5)
		BRA.W	HILH10
HILH19		CMP.L	-8(A5),A6
		BLT.W	HILH01
HILH20		ADDQ.W	#1,-4(A5)
		CMPI.W	#$07D0,-4(A5)
		BLT.B	HILH21
		CLR.W	-4(A5)
HILH21		CMP.L	-8(A5),A6
		BLT.W	HILH01
		RTS	

HILHsub1	MOVEQ	#0,D4
		MOVE.W	D0,D3
HILHsub1_1	MOVE.W	D3,D0
		SUBQ.W	#1,D3
		TST.W	D0
		BEQ.B	HILHsub1_2
		BSR.B	HILHsub1_3
		MOVE.W	D4,D1
		ASL.W	#1,D1
		OR.W	D1,D0
		MOVE.W	D0,D4
		BRA.B	HILHsub1_1
HILHsub1_2	MOVE.W	D4,D0
		RTS
HILHsub1_3	MOVEQ	#0,D1
		MOVE.L	$0840(A3),D0
		LSR.L	#1,D0
		MOVE.L	D0,$0840(A3)
		MOVE.L	-$0014(A5),D0
		CMP.L	$0840(A3),D0
		BCS.B	HILHsub1_4
		MOVEQ	#1,D1
		MOVE.L	$0840(A3),D0
		SUB.L	D0,-$0014(A5)
HILHsub1_4	CMPI.L	#$01000000,$0840(A3)
		BCC.B	HILHsub1_5
		MOVE.L	-$0014(A5),D0
		ASL.L	#8,D0
		MOVE.L	D0,-$0014(A5)
		MOVEQ	#0,D0
		MOVE.B	(A4)+,D0
		OR.L	D0,-$0014(A5)
		MOVE.L	$0840(A3),D0
		ASL.L	#8,D0
		MOVE.L	D0,$0840(A3)
		BRA.B	HILHsub1_4
HILHsub1_5	MOVE.W	D1,D0
		RTS	

HILHsub2	LEA	HILHData(PC),A0
		ASL.W	#1,D1
		MOVE.W	(A0,D1.W),D1
		ADD.W	D1,D0
		RTS	

HILHsub3	MOVEM.L	D1-D6,-(A7)
		MOVEQ	#0,D6
		MOVE.L	D0,D6
		CMPI.L	#$00000030,D6
		BGE.B	HILHsub3_1
		ADDI.L	#$00000105,D0
		BSR.W	HILHsub3_12
HILHsub3_1	MOVEQ	#4,D2
		MOVEQ	#0,D4
		BRA.B	HILHsub3_3
HILHsub3_2	MOVE.L	D2,D0
		ASL.L	#1,D0
		MOVE.L	D0,D2
		ADDQ.W	#1,D4
HILHsub3_3	MOVE.L	D6,D0
		ADDQ.L	#4,D0
		CMP.L	D0,D2
		BLT.B	HILHsub3_2
		CMP.L	D2,D0
		BNE.B	HILHsub3_8
		CMPI.W	#$000E,D4
		BGE.B	HILHsub3_8
		CMPI.W	#$000D,D4
		BGE.B	HILHsub3_4
		MOVE.W	D4,D0
		ASL.W	#1,D0
		MOVE.L	D0,D3
		ADDI.W	#$018A,D0
		BSR.W	HILHsub3_12
		ADDQ.W	#1,D0
		BSR.W	HILHsub3_12
HILHsub3_4	MOVE.W	D4,D0
		ASL.W	#1,D0
		ADDI.W	#$01A4,D0
		BSR.B	HILHsub3_12
		ADDQ.W	#1,D0
		BSR.B	HILHsub3_12
		ADDI.W	#$001B,D0
		BSR.B	HILHsub3_12
		ADDQ.W	#1,D0
		BSR.B	HILHsub3_12
		ADDI.W	#$001B,D0
		BSR.B	HILHsub3_12
		ADDQ.W	#1,D0
		BSR.B	HILHsub3_12
		CMPI.W	#7,D4
		BGE.B	HILHsub3_6
		MOVEQ	#0,D5
HILHsub3_5	MOVE.W	D4,D0
		ASL.W	#2,D0
		ADD.W	D5,D0
		ADDI.W	#$0135,D0
		BSR.B	HILHsub3_12
		ADDQ.W	#1,D5
		CMPI.W	#4,D5
		BLT.B	HILHsub3_5
HILHsub3_6	MOVEQ	#0,D5
HILHsub3_7	MOVE.W	D5,D0
		MULS	#$000E,D0
		ADD.W	D4,D0
		ADDI.W	#$0151,D0
		BSR.B	HILHsub3_12
		ADDQ.W	#1,D5
		CMPI.W	#4,D5
		BLT.B	HILHsub3_7
HILHsub3_8	MOVE.L	D6,D0
		ADDQ.L	#1,D0
		CMP.L	#$00000030,D0
		BGE.B	HILHsub3_10
HILHsub3_9	MOVEM.L	(A7)+,D1-D6
		RTS	
HILHsub3_10	MOVE.L	D6,D0
		ADDQ.L	#1,D0
		CMP.L	#$00000030,D0
		BNE.B	HILHsub3_11
		MOVEQ	#$003C,D0
		BRA.B	HILHsub3_9
HILHsub3_11	MOVE.L	D6,D0
		ADDQ.L	#4,D0
		ASL.L	#1,D0
		SUBQ.L	#4,D0
		BRA.B	HILHsub3_9
HILHsub3_12	MOVE.L	D0,-(A7)
		ADDI.W	#$01F8,D0
HILHsub3_13	TST.W	D0
		BEQ.B	HILHsub3_14
		MOVE.W	D0,D1
		ASL.W	#1,D1
		ADDQ.W	#1,(A3,D1.L)
		ASR.W	#1,D0
		BRA.B	HILHsub3_13
HILHsub3_14	CMPI.W	#$2000,2(A3)
		BCS.B	HILHsub3_15
		BSR.B	HILHsub4
HILHsub3_15	MOVE.L	(A7)+,D0
		RTS	

HILHsub4	MOVE.L	D4,-(A7)
		MOVE.W	#$01F8,D4
HILHsub4_1	MOVE.W	D4,D0
		ASL.W	#1,D0
		TST.W	(A3,D0.W)
		BEQ.B	HILHsub4_2
		MOVE.W	(A3,D0.W),D2
		LSR.W	#1,D2
		ADDQ.W	#1,D2
		MOVE.W	D2,(A3,D0.L)
HILHsub4_2	ADDQ.W	#1,D4
		CMP.W	#$03F0,D4
		BLT.B	HILHsub4_1
		BSR.B	HILHsub5
		MOVE.L	(A7)+,D4
		RTS	

HILHsub5	MOVE.W	#$01F7,D5
		MOVEQ	#0,D3
HILHsub5_1	MOVE.W	D5,D0
		ASL.W	#1,D0
		MOVE.W	D0,D1
		ASL.W	#1,D1
		MOVE.W	D0,D2
		ADDQ.W	#1,D2
		ASL.W	#1,D2
		MOVE.W	(A3,D1.W),D3
		ADD.W	(A3,D2.W),D3
		MOVE.W	D3,(A3,D0.L)
		SUBQ.W	#1,D5
		CMPI.W	#1,D5
		BGE.B	HILHsub5_1
		RTS	

HILHsub6	BSR.B	HILHsub6_6
		MOVE.W	D0,D6
		MOVEM.L	D4-D6,-(A7)
		MOVE.W	2(A3),D0
		MOVEQ	#$000A,D1
		LSR.W	D1,D0
		MOVE.W	D0,D5
		ADDQ.W	#3,D5
		ADDI.W	#$01F8,D6
HILHsub6_1	TST.W	D6
		BEQ.B	HILHsub6_2
		MOVE.W	D6,D0
		EXT.L	D0
		ASL.L	#1,D0
		ADD.W	D5,(A3,D0.L)
		ASR.W	#1,D6
		BRA.B	HILHsub6_1
HILHsub6_2	CMPI.W	#$2000,2(A3)
		BCS.B	HILHsub6_3
		BSR.W	HILHsub4
HILHsub6_3	MOVEM.L	(A7)+,D4-D6
HILHsub6_4	CMPI.L	#$01000000,$0840(A3)
		BCC.B	HILHsub6_5
		MOVE.L	-$0014(A5),D0
		ASL.L	#8,D0
		MOVE.L	D0,-$0014(A5)
		MOVEQ	#0,D0
		MOVE.B	(A4)+,D0
		OR.L	D0,-$0014(A5)
		MOVE.L	$0840(A3),D0
		ASL.L	#8,D0
		MOVE.L	D0,$0840(A3)
		BRA.B	HILHsub6_4
HILHsub6_5	MOVE.W	D6,D0
		RTS	
HILHsub6_6	MOVEM.L	D2-D7,-(A7)
		MOVEQ	#0,D4
		MOVEQ	#0,D5
		MOVE.W	2(A3),D3
		MOVEQ	#0,D2
HILHsub6_7	CMPI.W	#$01F8,D2
		BGE.B	HILHsub6_8
		MOVE.L	$0840(A3),D7
		MOVEQ	#0,D0
		MOVE.W	D2,D0
		ASL.W	#2,D0
		MOVEQ	#0,D1
		MOVE.W	D4,D1
		ADD.W	(A3,D0.W),D1
		BSR.B	HILHsub6_9
		MOVE.L	D0,D6
		ASL.W	#1,D2
		MOVE.L	-$0014(A5),D1
		CMP.L	D0,D1
		BCS.B	HILHsub6_7
		MOVE.L	D6,D5
		MOVE.W	D2,D0
		ASL.W	#1,D0
		ADD.W	(A3,D0.W),D4
		ADDQ.W	#1,D2
		BRA.B	HILHsub6_7
HILHsub6_8	MOVE.L	D5,D0
		SUB.L	D0,-$0014(A5)
		MOVE.W	D2,D0
		ASL.W	#1,D0
		MOVEQ	#0,D1
		MOVE.W	(A3,D0.W),D1
		BSR.B	HILHsub6_9
		MOVE.L	D0,$0840(A3)
		MOVE.W	D2,D0
		SUBI.W	#$01F8,D0
		MOVEM.L	(A7)+,D2-D7
		RTS	
HILHsub6_9	MOVEM.L	D2-D3,-(A7)
		MOVE.L	D1,D2
		SWAP	D2
		DIVU	D3,D2
		MOVE.L	D2,D1
		SWAP	D1
		CLR.W	D2
		DIVU	D3,D2
		MOVE.W	D2,D1
		MOVE.L	D7,D3
		MOVEQ	#0,D0
		MOVE.L	D1,D2
		SWAP	D2
		MULU	D3,D2
		SWAP	D2
		MOVE.W	D2,D0
		SWAP	D3
		MOVE.L	D3,D2
		MULU	D1,D2
		CLR.W	D2
		SWAP	D2
		ADD.L	D2,D0
		SWAP	D1
		MULU	D3,D1
		ADD.L	D1,D0
		MOVEM.L	(A7)+,D2-D3
		RTS	

HILHData	DC.W	0,4,$C,$1C,$3C,$7C,$FC,$1FC,$3FC,$7FC,$FFC,$1FFC
		DC.W	$3FFC,$7FFC,-4

*************************************************************************
*		 decrunch routine for FALH data				*
*									*
* This is made of reassembled code from PCompress2 and P-Reader.	*
* I removed a lot of obsolete stuff and made the routine mem to mem	*
* decrunching. Thus it should be a lot shorter and faster. I replaced   *
* stack usage completely with register usage and I hope I catched all	*
* the stuff and did not miss any obsolete code.				*
*									*
*	gets following parameters:					*
*		A4	source buffer					*
*		A2	destination buffer				*
*************************************************************************

DecompFALH	CLR.L	D5			* current destination size
		MOVEQ	#$10,D7
		MOVE.L	4(A4),A3		* source size
		MOVE.L	8(A4),D0		* packed size
		LEA	14(A4),A4		* source buffer
		LEA	(A4,D0.L),A6		* pack buffer end - part 1
		MOVE.L	(A4)+,D6

FALH01		CLR.L	D4
		SUBA.L	A5,A5
		MOVEQ	#1,D0
		BSR.W	FALHsub
		TST.L	D0
		BNE.B	FALH05
		MOVEQ	#1,D1
		MOVEQ	#2,D2
FALH02		ADDQ.W	#1,D1
		ASL.W	#1,D2
		MOVE.L	D1,D0
		BSR.W	FALHsub
		ADD.L	D0,D4
		TST.L	D0
		BNE.B	FALH03
		ADD.L	D2,D4
		SUBQ.L	#1,D4
		BRA.B	FALH02
FALH03		CMP.L	A3,D5			* end reached ?
		BCC.W	FALHend
		MOVE.B	(A6)+,(A2,D5.L)
		ADDQ.L	#1,D5
FALH04		SUBQ.L	#1,D4
		BNE.B	FALH03
FALH05		MOVEQ	#2,D0
		BSR.W	FALHsub
		ADDQ.W	#1,D0
		MOVE.L	D0,D3
		CMPI.L	#2,D0
		BNE.B	FALH06
		MOVE.W	#2,A5		* 32 bit MOVE also with .W !!!
		MOVEQ	#8,D0
		BSR.W	FALHsub
		MOVE.L	D0,D1
		BRA.B	FALH11
FALH06		MOVE.L	D3,A5
		CMPI.L	#1,D3
		BNE.B	FALH09
		ADDQ.L	#3,A5
		MOVEQ	#2,D1
		MOVEQ	#4,D2
FALH07		ADDQ.W	#1,D1
		ASL.W	#1,D2
		MOVE.L	D1,D0
		BSR.B	FALHsub
		MOVE.L	D0,D3
		BNE.B	FALH08
		ADD.L	D2,D0
		SUBQ.L	#1,D0
FALH08		ADD.L	D0,A5
		TST.L	D3
		BEQ.B	FALH07
FALH09		MOVEQ	#3,D0
		BSR.B	FALHsub
		TST.L	D0
		BNE.B	FALH10
		MOVEQ	#5,D0
		BSR.B	FALHsub
		MOVE.L	D0,D1
		MOVEQ	#1,D0
		BSR.B	FALHsub
		TST.L	D0
		BEQ.B	FALH11
		ADDI.L	#$00000020,D1
		BRA.B	FALH11
FALH10		MOVE.L	D0,D1
		ADD.L	D1,D1
		LEA	FALHData(PC),A0
		MOVE.W	(A0,D1.L),D2
		ADDQ.W	#5,D0
		BSR.B	FALHsub
		ADD.L	D2,D0
		MOVE.L	D0,D1
		BEQ.B	FALHend
FALH11		MOVE.L	D5,D3
		LEA	(A2,D3.L),A1
		SUB.L	D1,D3
		LEA	(A2,D3.L),A0
FALH12		CMP.L	A3,D5			* end reached ?
		BCC.B	FALHend
		MOVE.L	A5,D0
		BEQ.B	FALHend
		SUBQ.L	#1,A5
		MOVE.B	(A0)+,(A1)+
		ADDQ.L	#1,D5
		BRA.B	FALH12
FALHend		CMP.L	A3,D5			* end reached ?
		BLT.W	FALH01
		RTS

		* uses variables D6 and D7, returns D0
FALHsub		MOVEM.L	D1-D4,-(A7)
		MOVE.L	D6,D1
		SUBQ.W	#1,D0
		MOVEQ	#0,D2
FALHsub1	ADD.L	D1,D1
		ADDX	D2,D2
		SUBQ.L	#1,D7
		BNE.B	FALHsub2
		MOVE.W	(A4)+,D4
		MOVEQ	#$10,D7
		OR.W	D4,D1
FALHsub2	DBRA	D0,FALHsub1
		MOVE.L	D2,D0
		MOVE.L	D1,D6
		MOVEM.L	(A7)+,D1-D4
		RTS	

FALHData	DC.W	$20,$40,$80,$100,$200,$400,$800,$1000

*************************************************************************
*		 checksum CRC-16 calculation routine 			*
*									*
* This is made of reassembled code from PCompress2 and P-Reader.	*
* I optimized the code a lot and is real assembler now.	:-)		*
*									*
*	gets following parameters:					*
*		A2	buffer						*
*	        D4	buffersize					*
*	returns D0:	checksum (WORD)					*
*************************************************************************

GetCheckSum	MOVEM.L	D2/D4/A2,-(A7)
		LEA	-$200(A7),A7		* get work space

		MOVEQ	#0,D1
		ST	D1			* set $FF
.Loop1		MOVE.W	D1,D0
		MOVEQ	#7,D2
.Loop2		LSR.W	#1,D0
		BCC.B	.Loop2End		* is shifted bit 1 ?
		EORI.W	#$A001,D0
.Loop2End	DBRA	D2,.Loop2
		MOVE.W	D1,D2
		ASL.L	#1,D2
		MOVE.W	D0,(A7,D2.W)
		DBRA	D1,.Loop1

		MOVEQ	#0,D0
.SumLoop	MOVE.B	(A2)+,D1
		EOR.B	D1,D0
		MOVEQ	#0,D1
		MOVE.B	D0,D1
		ASL.W	#1,D1
		LSR.W	#8,D0
		MOVE.W	(A7,D1.W),D1
		EOR.W	D1,D0
		SUBQ.L	#1,D4
		BNE.B	.SumLoop
		LEA	$200(A7),A7		* free work space
		MOVEM.L	(A7)+,D2/D4/A2
		RTS	
		END
