*******************************************************
**     XFD external decruncher for pack Cruncher     **
**        written by Mr. Larmer / Wanted Team        **
**	   shortened and fixed by SDI in 1999  	     **
*******************************************************

		INCLUDE	AINCLUDE:IncDirs.i
		INCLUDE	"libraries/xfdmaster.i"

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

; xfdForeman structure MUST be first thing in all external decrunchers

ForeMan		moveq	#-1,d0		;security
		rts
		dc.l	XFDF_ID		;id
		dc.w	1		;version
		dc.w	0
		dc.l	0,0		;private
		dc.l	S_pack		;first slave

		dc.b	"$VER: pack 2.0 (04.12.1999)",0
N_pack		dc.b	"(pack) Data Cruncher",0
		EVEN

**************************************************

; xfdSlave structure: this one doesn't support segment decrunching

S_pack		dc.l	0		;no more slaves
		dc.w	2		;version
		dc.w	39		;master version
		dc.l	N_pack		;name
		dc.w	XFDPFF_DATA|XFDPFF_USERTARGET|XFDPFF_RECOGLEN
		dc.w	0
		dc.l	RB_pack		;recog buffer
		dc.l	DB_pack		;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment
		dc.w	0,0
		dc.l	8+2

RB_pack		MOVEQ	#0,D0
		CMP.L	#"pack",(A0)
		BNE.B	.Exit
		MOVE.L	4(A0),D0
		MOVE.L	D0,xfdrr_FinalTargetLen(A1)
		MOVE.L	D0,xfdrr_MinTargetLen(A1)
		MOVE.L	D0,xfdrr_MinSourceLen(A1)
		MOVEQ	#1,D0
.Exit		RTS

;-------------------------------------------------

DB_pack		MOVEM.L	D2-D7/A2-A6,-(A7)
		MOVE.L	xfdbi_UserTargetBuf(A0),A6
		MOVE.L	xfdbi_SourceBuffer(A0),A5

		LEA	-$C80(A7),A7
		MOVE.L	A7,A3
		BSR.B	D_pack
		; return result is set correctly
		LEA	$C80(A7),A7
		TST.L	D0
		BNE.B	.Exit
		MOVE.W	#XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
.Exit		MOVEM.L	(A7)+,D2-D7/A2-A6
		RTS

**************************************************

D_pack		movem.l	D0-D7/A0-A6,-(SP)
		move.l  (A5)+,D0	* skip ID
		move.l	(A5)+,-(SP)
		move.l	(A5)+,D6
		moveq	#$1F,D7
		moveq	#$20,D0
		lea	(A3),A0
		bsr.w	lbC00013E
		moveq	#0,D0
		lea	$80(A3),A0
		bsr.w	lbC00013E
		moveq	#0,D0
		lea	$480(A3),A0
		bsr.w	lbC00013E
		moveq	#0,D0
		lea	$880(A3),A0
		bsr.w	lbC00013E
		move.l	(SP)+,D0
		moveq	#$1F,D5
		sub.w	D7,D5
		asl.l	D5,D6
		lea	lbW0001D8(PC),A1
		lea	lbL000214(PC),A2
lbC00006E:
		lea	$80(A3),A0
		bsr.w	lbC00010A
		moveq	#0,D4
		move.b	D2,D4
		cmpi.b	#$FF,D4
		bcs.s	lbC00009C
lbC000080:
		moveq	#0,D2
		moveq	#7,D3
lbC000084:
		add.l	D6,D6
		addx.l	D2,D2
		dbra	D7,lbC000090
		move.l	(A5)+,D6
		moveq	#$1F,D7
lbC000090:
		dbra	D3,lbC000084
		add.w	D2,D4
		cmpi.w	#$FF,D2
		beq.s	lbC000080
lbC00009C:
		move.w	D4,D1
		beq.s	lbC0000AC
		lea	$880(A3),A0
lbC0000A4:
		bsr.s	lbC00010A
		move.b	D2,(A6)+
		subq.w	#1,D1
		bne.s	lbC0000A4
lbC0000AC:
		sub.l	D4,D0
		bmi.w	lbC0001BC
		beq.s	lbC000104
		lea	(A3),A0
		bsr.s	lbC00010A
		moveq	#0,D1
		moveq	#0,D3
		move.b	D2,D3
		add.w	D3,D3
		move.w	0(A2,D3.W),D2
		beq.s	lbC0000DA
		subq.w	#1,D2
lbC0000CA:
		add.l	D6,D6
		addx.l	D1,D1
		dbra	D7,lbC0000D6
		move.l	(A5)+,D6
		moveq	#$1F,D7
lbC0000D6:
		dbra	D2,lbC0000CA
lbC0000DA:
		or.w	0(A1,D3.W),D1
		lea	$480(A3),A0
		bsr.b	lbC00010A
		moveq	#0,D3
		move.b	D2,D3
		move.w	D3,D2
		lea	(A6),A4
		suba.w	D2,A4
		suba.w	D1,A4
		subq.w	#1,D2
lbC0000F4:
		move.b	(A4)+,(A6)+
		dbra	D2,lbC0000F4
		sub.l	D3,D0
		bmi.w	lbC0001BC
		bne.w	lbC00006E
lbC000104:
		movem.l	(SP)+,D0-D7/A0-A6
		moveq	#1,D0
		rts

lbC00010A:
		moveq	#0,D2
lbC00010C:
		moveq	#0,D3
		add.l	D6,D6
		addx.w	D3,D3
		add.w	D3,D3
		add.w	D3,D2
		move.w	0(A0,D2.W),D2
		bmi.s	lbC000134
lbC00011C:
		dbra	D7,lbC00010C
		move.l	(A5)+,D6
		moveq	#$1F,D7
		moveq	#0,D3
		add.l	D6,D6
		addx.w	D3,D3
		add.w	D3,D3
		add.w	D3,D2
		move.w	0(A0,D2.W),D2
		bpl.s	lbC00011C
lbC000134:
		dbra	D7,lbC00013C
		move.l	(A5)+,D6
		moveq	#$1F,D7
lbC00013C:
		rts
lbC00013E:
		lea	(A0),A1
		clr.l	(A1)+
		moveq	#0,D1
lbC000144:
		bsr.s	lbC000192
		beq.s	lbC00018A
		moveq	#5,D5
		bsr.s	lbC0001A2
		move.w	D4,D3
		move.w	D4,D5
		bsr.s	lbC0001A2
		lea	(A0),A2
		moveq	#0,D2
		subq.w	#1,D3
		beq.s	lbC000176
lbC00015A:
		btst	D3,D4
		beq.s	lbC000160
		addq.w	#2,D2
lbC000160:
		move.w	0(A0,D2.W),D5
		bne.s	lbC000170
		move.l	A1,D5
		sub.l	A0,D5
		move.w	D5,0(A0,D2.W)
		clr.l	(A1)+
lbC000170:
		move.w	D5,D2
		subq.w	#1,D3
		bne.s	lbC00015A
lbC000176:
		btst	D3,D4
		beq.s	lbC00017C
		addq.w	#2,D2
lbC00017C:
		tst.w	0(A0,D2.W)
		bne.s	lbC0001C0
		move.b	D1,1(A0,D2.W)
		st	0(A0,D2.W)
lbC00018A:
		addq.b	#1,D1
		cmp.b	D0,D1
		bne.s	lbC000144
		rts
lbC000192:
		move.w	D7,D4
		move.l	D6,D5
		dbra	D7,lbC00019E
		moveq	#$1F,D7
		move.l	(A5)+,D6
lbC00019E:
		btst	D4,D5
		rts
lbC0001A2:
		moveq	#0,D4
		subq.w	#1,D5
		bmi.s	lbC0001BA
lbC0001A8:
		btst	D7,D6
		beq.s	lbC0001AE
		bset	D5,D4
lbC0001AE:
		dbra	D7,lbC0001B6
		moveq	#$1F,D7
		move.l	(A5)+,D6
lbC0001B6:
		dbra	D5,lbC0001A8
lbC0001BA:
		rts
lbC0001BC:
		movem.l	(SP)+,D0-D7/A0-A6
		moveq	#0,D0
		rts
lbC0001C0:
		pea	lbC0001BC(pc)
		rts

lbW0001D8:
		dc.w	0
		dc.w	1
		dc.w	2
		dc.w	3
		dc.w	4
		dc.w	6
		dc.w	8
		dc.w	12
		dc.w	$10
		dc.w	$18
		dc.w	$20
		dc.w	$30
		dc.w	$40
		dc.w	$60
		dc.w	$80
		dc.w	$C0
		dc.w	$100
		dc.w	$180
		dc.w	$200
		dc.w	$300
		dc.w	$400
		dc.w	$600
		dc.w	$800
		dc.w	$C00
		dc.w	$1000
		dc.w	$1800
		dc.w	$2000
		dc.w	$3000
		dc.w	$4000
		dc.w	$6000
lbL000214:
		dc.l	0
		dc.l	0
		dc.l	$10001
		dc.l	$20002
		dc.l	$30003
		dc.l	$40004
		dc.l	$50005
		dc.l	$60006
		dc.l	$70007
		dc.l	$80008
		dc.l	$90009
		dc.l	$A000A
		dc.l	$B000B
		dc.l	$C000C
		dc.l	$D000D

		END
