
	**********************************************************
	**   XFD external decruncher for the BHC3 cruncher	**
	**********************************************************

		opt o+,ow2-,c-

		SECTION	BHC3,CODE

		Incdir	Inx:
		Include	Libraries/xfdmaster.I
		Include	Macros.I
		Include	LVO.Gs
		Include	Exec/Memory.I

; xfdForeman structure MUST be first thing in all external decrunchers

F_BHC3		moveq	#-1,d0			;security
		rts

		dc.l	XFDF_ID_EQU		;id
		dc.w	1			;version
		dc.w	0
		dc.l	0,0			;private
		dc.l	S_BHC3			;first slave

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

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

S_BHC3		dc.l	0			;no more slaves
		dc.w	1			;version
		dc.w	36			;master version
		dc.l	N_BHC3			;name
		dc.w	XFDPFF_RELOC		;flags
		dc.w	0
		dc.l	RB_BHC3			;recog buffer
		dc.l	DB_BHC3			;decrunch buffer
		dc.l	0			;recog segment
		dc.l	0			;decrunch segment
		dc.w	0,0
		dc.l	$17A			; Minsize

N_BHC3		dc.b	'BHC3 Decruncher',0
		even

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

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

RB_BHC3		Moveq.l	#1,d0			; True

		Cmp.l	#$000003F3,(a0)
		bne.b	.No

		Cmp.l	#$41FA0178,$20(a0)	; Lea PackedData(PC),a0
		Bne.b	.No

		Cmp.l	#"BHC3",$6C(a0)
		Bne.b	.No

		Cmp.l	#"BHC3",$19A(a0)
		Beq.b	.Yes

.No		Moveq.l	#0,d0
.Yes		rts

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

;Decrunch buffer function: receives bufferinfo in a0

DB_BHC3		;Illegal
		PushM	d2-d7/a2-a6
		move.l	a0,a5

		Move.l	xfdbi_SourceBuffer(a5),a0
		Move.l	$19e(a0),d0
		Move.l	d0,xfdbi_TargetBufSaveLen(a5)
		Push	d0
		Add.l	#512,d0
		move.l	d0,xfdbi_TargetBufLen(a5)

		Move.l	#Memf_Clear,d1
		Or.l	$30(a0),d1			; Get memtype
		move.l	4.w,a6
		Call	AllocMem
		Tst.l	d0
		beq.b	.NoMem

		Move.l	d0,a1
		Lea	512(a1),a1
		move.l	a1,xfdbi_TargetBuffer(a5)

		Move.l	xfdbi_SourceBuffer(a5),a0	; packed data
		Lea	$19E(a0),a0			; Point to just after HDR
		Pushm	a0/a1

		Move.l	#Memf_Clear,d1
		Moveq.l	#4*4,d0
		move.l	4.w,a6
		Call	AllocMem
		Tst.l	d0
		beq.b	.NoMem2
		Move.l	d0,a2
		Popm	a0/a1

		Push	a2
		Bsr.b	.Depack

		Pop	a1
		Move.l	4.w,a6
		Moveq.l	#4*4,d0
		Call	FreeMem

;Move everything back 512 bytes
		move.l	xfdbi_TargetBuffer(a5),a0
		move.l	a0,a1
		Lea	-512(a1),a1
		Move.l	a1,xfdbi_TargetBuffer(a5)
		Pop	d0
		Call	CopyMem

		Moveq.l	#1,d0				; True = Decrunched ok
.Out		PopM	d2-d7/a2-a6
		Rts

.NoMem		moveq	#XFDERR_NOMEMORY,d1
		Move.w	d1,xfdbi_Error(a5)
		Bra.b	.Out

.NoMem2		moveq	#XFDERR_NOMEMORY,d1
		Move.w	d1,xfdbi_Error(a5)
		Move.l	xfdbi_TargetBuffer(a5),a1
		Move.l	xfdbi_TargetBufLen(a5),d0
		Call	FreeMem
		Bra.b	.Out
		

**************************************************
.Depack		move.l	(A0)+,D1		;depacked size
		move.l	(A0)+,D0
		move.l	A1,D7
		add.l	D1,A1
		move.b	(A0)+,D2
		and.w	#7,D2
		subq.w	#1,D2
		moveq	#0,D3
		move.b	(A0)+,D3
		move.l	A0,(A2)
		add.w	D3,A0
		move.w	(A0)+,D3
		move.l	A0,4(A2)
		add.w	D3,A0
		move.w	(A0)+,D3
		move.l	A0,8(A2)
		add.w	D3,A0
		move.w	(A0)+,D3
		move.l	A0,12(A2)
		add.w	D3,A0
		add.l	D0,A0
		bsr	lbC000170
		bra.s	lbC000098

lbC000090	add.l	D6,D6
		bne.s	lbC000098

		bsr	lbC000170
lbC000098	bcc.s	lbC0000E4

		move.l	4(A2),A3
		bsr.b	lbC00012A
		cmp.b	#6,D2
		beq.s	lbC0000D4

		move.l	(A2),A3
		subq.w	#1,D3
lbC0000AC	add.l	D6,D6
		bne.s	lbC0000B4

		bsr	lbC000170
lbC0000B4	bcc.s	lbC0000C6

		moveq	#0,D4
		move.w	D2,D0
		bmi.s	lbC0000C0

		bsr.b	lbC000108
lbC0000C0	move.b	(A3,D4.W),-(A1)
		bra.s	lbC0000CE

lbC0000C6	moveq	#7,D0
		bsr.b	lbC000108
		move.b	D4,-(A1)
lbC0000CE	dbra	D3,lbC0000AC

		bra.s	lbC000100

lbC0000D4	subq.w	#1,D3
lbC0000D6	moveq	#7,D0
		bsr.b	lbC000108
		move.b	D4,-(A1)
		dbra	D3,lbC0000D6

		bra.s	lbC000100

lbC0000E4	move.l	8(A2),A3
		bsr.b	lbC00012A
		move.w	D3,D4
		move.l	12(A2),A3
		bsr.b	lbC00012A
		subq.w	#1,D3
lbC0000F8	move.b	-1(A1,D4.W),-(A1)
		dbra	D3,lbC0000F8

lbC000100	cmp.l	D7,A1
		bhi.b	lbC000090
		rts


lbC000108	moveq	#0,D4
lbC00010A	add.l	D6,D6
		bne.s	lbC000112

		bsr.b	lbC000170
lbC000112	addx.w	D4,D4
		dbra	D0,lbC00010A

		rts


lbC00012A	moveq	#0,D1
		move.l	D1,D3

lbC00012E	moveq	#0,D0
		move.b	(A3),D0
		rol.w	D1,D3
		add.w	D0,D1
		subq.w	#1,D0
		bmi.s	lbC000148

lbC00013A	add.l	D6,D6
		bne.s	lbC000142

		bsr.b	lbC000170
lbC000142	roxl.w	#1,D3
		dbra	D0,lbC00013A

lbC000148	ror.w	D1,D3
		cmp.w	2(A3),D3
		beq.s	lbC000154

		addq.w	#4,A3
		bra.s	lbC00012E

lbC000154	moveq	#0,D0
		move.b	1(A3),D0
		moveq	#1,D3
		subq.w	#1,D0
		bmi.s	Out

lbC000160	add.l	D6,D6
		bne.s	lbC000168

		bsr.b	lbC000170
lbC000168	addx.w	D3,D3
		dbra	D0,lbC000160
Out		rts

lbC000170	move.l	-(A0),D6
		move.w	#$10,CCR
		addx.l	D6,D6
		rts
