*******************************************************
**             XFD external decruncher               **
**          for Eldritch The Cat cruncher            **
**             adapted by Wanted Team                **
*******************************************************

	INCDIR	"dh2:Include/"
	INCLUDE	"libraries/xfdmaster.i"

; 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_CATC		;first slave

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

; xfdSlave structure: this one doesn't support data scanning

S_CATC		dc.l	0		;no more slaves
		dc.w	2		;version
		dc.w	39		;master version
		dc.l	N_CATC		;name
		dc.w	XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_CATC		;recog buffer
		dc.l	DB_CATC		;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment
		dc.w	0,0
		dc.l	12+2

		dc.b	"$VER: CATC v2.0 (21 Mar 2001) by Wanted Team",0
N_CATC		dc.b	"Eldritch The Cat (CATC) data cruncher",0
		even

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

; Recog buffer function: receives buffer + length in a0/d0

RB_CATC
	btst	#0,D0
	bne.b	Exit
	cmp.l	#"CATC",(A0)+
	bne.b	Exit
	tst.b	(A0)
	bne.b	Exit
	move.l	(A0),D1
	subq.l	#4,A0
	add.l	D0,A0
	cmp.l	-(A0),D1
	bne.b	Exit
	move.l	D1,xfdrr_FinalTargetLen(A1)
	move.l	D1,xfdrr_MinTargetLen(A1)
	moveq	#1,D0
	rts	
Exit
	moveq	#0,D0
	rts

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

; Decrunch buffer function: receives bufferinfo in a0
; This style requires xfdmaster.library V39
DB_CATC	
	movem.l	D2-D7/A2-A6,-(A7)
	move.l	A0,A5
	move.l	xfdbi_UserTargetBuf(A5),A1
	move.l	xfdbi_UserTargetBufLen(A5),D1
	move.l	xfdbi_SourceBuffer(A5),A0
	move.l	xfdbi_SourceBufLen(A5),D0
	add.l	D0,A0
	lea	(A1,D1.L),A2
	bsr.b	D_CATC
	move.w	#XFDERR_CORRUPTEDDATA,xfdbi_Error(A5)
	movem.l	(A7)+,D2-D7/A2-A6
	rts

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

; Decruncher from "Crime Does Not Pay" (c) Titus

;	LINK.W	A6,#0
;	MOVEM.L	D0-D7/A0-A5,-(SP)
;	MOVEA.L	8(A6),A0
;	MOVEA.L	$10(A6),A1
;	MOVEA.L	12(A6),A2
;	BSR.S	lbC00AA7A
;	MOVEM.L	(SP)+,D0-D7/A0-A5
;	UNLK	A6
;	RTS

; Input:
; A0 = start + length of file
; A1 = destination
; A2 = destination + depacked length

D_CATC
lbC00AA7A	MOVE.L	-(A0),-(SP)
	MOVE.L	-(A0),D5
	MOVE.L	-(A0),D0
	EOR.L	D0,D5
lbC00AA82	LSR.L	#1,D0
	BNE.S	lbC00AA8A
	BSR.L	lbC00AB26
lbC00AA8A	BCS.S	lbC00AAC8
	MOVEQ	#8,D1
	MOVEQ	#1,D3
	LSR.L	#1,D0
	BNE.S	lbC00AA98
	BSR.L	lbC00AB26
lbC00AA98	BCS.S	lbC00AAF4
	MOVEQ	#3,D1
	CLR.W	D4
lbC00AA9E	BSR.L	lbC00AB32
	MOVE.W	D2,D3
	ADD.W	D4,D3
lbC00AAA6	MOVEQ	#7,D1
lbC00AAA8	LSR.L	#1,D0
	BNE.S	lbC00AAB0
	BSR.L	lbC00AB26
lbC00AAB0	ROXL.L	#1,D2
	DBRA	D1,lbC00AAA8
	MOVE.B	D2,-(A2)
	DBRA	D3,lbC00AAA6
	BRA.L	lbC00AB02

lbC00AAC0	MOVEQ	#8,D1
	MOVEQ	#8,D4
	BRA.L	lbC00AA9E

lbC00AAC8	MOVEQ	#2,D1
	BSR.L	lbC00AB32
	CMP.B	#2,D2
	BLT.S	lbC00AAEA
	CMP.B	#3,D2
	BEQ.S	lbC00AAC0
	MOVEQ	#8,D1
	BSR.L	lbC00AB32
	MOVE.W	D2,D3
	MOVE.W	#12,D1
	BRA.L	lbC00AAF4

lbC00AAEA	MOVE.W	#9,D1
	ADD.W	D2,D1
	ADDQ.W	#2,D2
	MOVE.W	D2,D3
lbC00AAF4	BSR.L	lbC00AB32
lbC00AAF8	SUBQ.W	#1,A2
	MOVE.B	0(A2,D2.W),(A2)
	DBRA	D3,lbC00AAF8
lbC00AB02	CMPA.L	A2,A1
	BLT.L	lbC00AA82
	MOVE.L	(SP)+,D0
	EOR.L	D0,D5
	BNE.S	lbC00AB10

	moveq	#XFDERR_CORRUPTEDDATA,D0

	RTS

lbC00AB10

	moveq	#XFDERR_OK,D0

;	MOVE.L	#$FFFFFFFF,D0
;lbC00AB16	MOVE.W	D0,$DFF180
;	SUBI.L	#1,D0
;	BNE.S	lbC00AB16
	RTS

lbC00AB26	MOVE.L	-(A0),D0
	EOR.L	D0,D5
	MOVE.W	#$10,CCR
	ROXR.L	#1,D0
	RTS

lbC00AB32	SUBQ.W	#1,D1
	CLR.W	D2
lbC00AB36	LSR.L	#1,D0
	BNE.S	lbC00AB44
	MOVE.L	-(A0),D0
	EOR.L	D0,D5
	MOVE.W	#$10,CCR
	ROXR.L	#1,D0
lbC00AB44	ROXL.L	#1,D2
	DBRA	D1,lbC00AB36
	RTS

