*******************************************************
**     XFD external decruncher for FIRE Cruncher     **
**        written by Dexter & Bartman / Abyss        **
**             modified by Georg Hörmann             **
*******************************************************

		OUTPUT	"LIBS:xfd/FIRE"

		SECTION	FIREDecrunch,CODE

		INCDIR	"dh0:Include_Asm"	;change this as you need it
		INCLUDE	"dh0:xfd/xfdmaster.i"

; xfdForeman structure MUST be first thing in all external decrunchers

F_FIRE		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_FIRE		;first slave

		dc.b	"$VER: External FIRE decruncher for xfdmaster.library "
		dc.b	"by Dexter&Bartman/Abyss, modified by G.H.",13,10,0
		cnop	0,4

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

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

S_FIRE		dc.l	0		;no more slaves
		dc.w	1		;version
		dc.w	33		;master version
		dc.l	N_FIRE		;name
		dc.w	XFDPFF_DATA	;flags
		dc.w	0
		dc.l	RB_FIRE		;recog buffer
		dc.l	DB_FIRE		;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment

N_FIRE		dc.b	"FIRE (RNC Clone) Cruncher",0
		even

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

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

RB_FIRE		cmp.l	#12+2,d0
		ble.s	.Exit
		cmp.l	#"FIRE",(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

;Decrunch buffer function: receives bufferinfo in a0

DB_FIRE		movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		move.l	xfdbi_SourceBuffer(a5),a2

		move.l	8(a2),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	xfdbi_TargetBufMemType(a5),d1
		move.l	4.w,a6
		jsr	-198(a6)
		move.w	#XFDERR_NOMEMORY,xfdbi_Error(a5)
		move.l	d0,xfdbi_TargetBuffer(a5)
		beq.s	.Exit

		move.l	d0,a1
		move.l	a2,a0
		bsr.s	D_FIRE

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

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

D_FIRE		movem.l	d2-d7/a3-a6,-(a7)
		move.l	a0,a5
		move.l	a1,a6
		move.l	a6,a4
		add.l	8(a0),a6
		add.l	4(a0),a5

		move.b	-(a5),d7
		lea	.Tab(pc),a3
		moveq	#1,d6
		swap	d6
		moveq	#0,d5
		moveq	#-1,d4

.Next		bsr.s	.GetBit
		bcc.s	.CheckOtherBits
		moveq	#1-1,d1
		bsr.s	.GetBit
		bcc.s	.DoUncr
		move.l	a3,a0
		moveq	#4-1,d3
.GetNumUncr	move.l	-(a0),d0
		bsr.s	.GetBits
		swap	d0
		cmp.w	d0,d1
		dbne	d3,.GetNumUncr
		add.l	16(a0),d1
.DoUncr		move.b	-(a5),-(a6)
		cmp.l	a4,a6
		dbeq	d1,.DoUncr
		cmp.w	d4,d1
		beq.s	.CheckOtherBits
		bra	.Exit

.GetBit		add.b	d7,d7
		bne.s	.GetBit1
		move.b	-(a5),d7
		addx.b	d7,d7
.GetBit1	rts

.GetBits	moveq	#0,d1
.GetBits1	add.b	d7,d7
		bne.s	.GetBits2
		move.b	-(a5),d7
		addx.b	d7,d7
.GetBits2	addx.w	d1,d1
		dbf	d0,.GetBits1
		rts

.CheckOtherBits	moveq	#2-1,d0
		bsr.s	.GetBits
		subq.w	#1,d1
		bmi.s	.lbc001c0a
		beq.s	.lbc001c30
		subq.w	#1,d1
		beq.s	.lbc001c38
		bsr.s	.GetBit
		bcc.s	.lbc001c26
		bsr.s	.GetBit
		bcc.s	.lbc001c44
		bra.s	.lbc001c4e

.lbc001bea	moveq	#2-1,d0
		bsr.s	.GetBits
		subq.w	#1,d1
		bpl.s	.lbc001bfa
		moveq	#0,d0
		rts

.lbc001bf6	moveq	#2-1,d0
		bsr.s	.GetBits
.lbc001bfa	add.w	d1,d1
		add.w	d1,d1
		movem.w	16(a3,d1.w),d0/d5
		bsr.s	.GetBits
		add.l	d5,d1
		rts

.lbc001c0a	moveq	#2-1,d0
		bsr.s	.GetBits
		subq.w	#1,d1
		bmi.s	.lbc001c62
		add.w	d1,d1
		add.w	d1,d1
		movem.w	32(a3,d1.w),d0/d2
		bsr.s	.GetBits
		add.w	d1,d2
		bsr.s	.lbc001bf6
		move.w	d2,d0
		bra.s	.lbc001c74

.lbc001c26	moveq	#3-1,d0
		bsr.s	.GetBits
		moveq	#0,d0
		bset	d1,d0
		bra.s	.lbc001c5e

.lbc001c30	moveq	#8-1,d0
		bsr.s	.GetBits
		moveq	#1-1,d0
		bra.s	.lbc001c76

.lbc001c38	bsr.s	.lbc001bea
		tst.w	d0
		beq.s	.lbc001c5e
		moveq	#2-1,d0
		bra.s	.lbc001c76

.lbc001c44	bsr.s	.lbc001bea
		tst.w	d0
		beq.s	.lbc001c5c
		moveq	#3-1,d0
		bra.s	.lbc001c76

.lbc001c4e	bsr.s	.lbc001bea
		tst.w	d0
		beq.s	.lbc001c58
		moveq	#4-1,d0
		bra.s	.lbc001c76

.lbc001c58	moveq	#-1,d0
		bra.s	.lbc001c5e

.lbc001c5c	move.b	(a6),d0
.lbc001c5e	move.b	d0,-(a6)
		cmp.l	a4,a6
		beq.s	.Exit
		bra	.Next

.lbc001c62	bsr.s	.lbc001bf6
		beq	.Next
		move.b	(a6),d0
.CopySame	move.b	d0,-(a6)
		cmp.l	a4,a6
		dbeq	d1,.CopySame
		cmp.w	d4,d1
		bne.s	.Exit
		sub.l	d6,d1
		bmi	.Next
		bra.s	.CopySame

.lbc001c74	subq.w	#2,d0
.lbc001c76	lea	2(a6,d1.l),a0
		add.w	d0,a0
		move.b	-(a0),-(a6)
		cmp.l	a4,a6
		beq.s	.Exit
.CopyStr	move.b	-(a0),-(a6)
		cmp.l	a4,a6
		dbeq	d0,.CopyStr
		cmp.w	d4,d0
		beq	.Next

.Exit		movem.l	(a7)+,d2-d7/a3-a6
		rts

		dc.w	$03ff,10-1
		dc.w	$0007,3-1
		dc.w	$0003,2-1
		dc.w	$0003,2-1

.Tab		dc.l	14
		dc.l	7
		dc.l	4
		dc.l	1

		dc.w	4-1,$0000
		dc.w	8-1,$0010
		dc.w	12-1,$0110
		dc.w	16-1,$1110

		dc.w	4-1,$0005
		dc.w	6-1,$0015
		dc.w	8-1,$0055

		END
