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

		INCLUDE	"AINCLUDE:IncDirs.i"
		INCLUDE	"libraries/xfdmaster.i"
		INCLUDE "lvo/exec_lib.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_HUFF		;first slave

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

		dc.b	"$VER: HUFF 2.0 (19.04.2000)",0
N_HUFF		dc.b	"(HUFF) Data Cruncher",0
		EVEN

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

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

S_HUFF		dc.l	0		;no more slaves
		dc.w	2		;version
		dc.w	39		;master version
		dc.l	N_HUFF		;name
		dc.w	XFDPFF_DATA
		dc.w	0
		dc.l	RB_HUFF		;recog buffer
		dc.l	DB_HUFF		;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment
		dc.w	0,0
		dc.l	$408	* header, table, 1 long data

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

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

RB_HUFF		MOVEQ	#0,D0
		CMP.L	#"HUFF",(A0)
		BNE.B	.Exit
		MOVEQ	#1,D0
.Exit		RTS

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

;Decrunch buffer function: receives bufferinfo in a0

DB_HUFF		movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		move.l	xfdbi_SourceBufLen(a5),d3
		move.l	xfdbi_SourceBuffer(a5),a2
		SUBA.L	A1,A1
		MOVEA.L	A2,A0
		MOVEQ	#1,D2
		BSR.B	D_HUFF

		MOVE.L	A1,D0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)
		move.l	xfdbi_TargetBufMemType(a5),d1
		MOVEA.L	xfdm_ExecBase(A6),A6
		jsr	_LVOAllocMem(A6)
		move.w	#XFDERR_NOMEMORY,xfdbi_Error(a5)
		move.l	D0,xfdbi_TargetBuffer(a5)
		beq.b	.Exit

		move.l	d0,a1
		move.l	a2,a0
		MOVEQ	#0,D2
		bsr.s	D_HUFF

		moveq	#1,d0
.Exit		movem.l	(a7)+,d2-d7/a2-a6
		rts

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

		* A0 = input buffer
		* A1 = output buffer
		* D2 = test mode
		* D3 = input size
D_HUFF		MOVEM.L	D2-D7/A2-A6,-(A7)
		LEA	4(A0),A6	* table data $404 byte
		LEA	$404(A0),A0	* data start
		SUB.L	#$404,D3	* size checks done in xfd structure!
		MOVEQ	#0,D7
		LEA	$200(A6),A5
		MOVE.W	$1FE(A6),D4
.mainloop	MOVE.W	D4,D5
.lab1		DBRA	D7,.lab2
		SUBQ.L	#4,D3
		BMI.S	.end
		MOVEQ	#31,D7
		MOVE.L	(A0)+,D6
.lab2		LSR.L	#1,D6
		BCC.S	.lab3
		MOVE.W	(A5,D5.W),D5
		BPL.S	.lab1
		BRA.S	.lab4
.lab3		MOVE.W	(A6,D5.W),D5
		BPL.S	.lab1
.lab4		TST.L	D2
		BNE.B	.testmode
		MOVE.B	D5,(A1)+
		BRA.S	.mainloop
.testmode	ADDQ.L	#1,A1
		BRA.B	.mainloop
.end		MOVEM.L	(A7)+,D2-D7/A2-A6
		RTS

		END
