*******************************************************
**       XFD external decruncher for PMC files       **
**        written and © 1994 by Georg Hörmann        **
*******************************************************

		OUTPUT	"LIBS:xfd/PMC"

		SECTION	PMC,CODE

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

_LVOLHAllocBufferInfo	= -30
_LVOLHFreeBufferInfo	= -36
_LVOLHDecrunchBuffer	= -48

; xfdForeman structure MUST be first thing in all external decrunchers

F_PMC		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_PMCnormal	;first slave

		dc.b	"$VER: XFD PMC decruncher by Georg Hörmann",13,10,0
LHlib		dc.b	"lh.library",0
		cnop	0,4

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

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

S_PMCnormal	dc.l	S_PMCsample	;next slave
		dc.w	1		;version
		dc.w	33		;master version
		dc.l	N_PMCnormal	;name
		dc.w	XFDPFF_DATA	;flags
		dc.w	0
		dc.l	RB_PMCnormal	;recog buffer
		dc.l	DB_PMCnormal	;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment

N_PMCnormal	dc.b	'PMC Normal',0
		even

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

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

RB_PMCnormal	cmp.l	#12+4,d0	;min. file length for header and data
		ble.s	.Exit
		cmp.l	#'SFHD',(a0)	;some more verification
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

;Decrunch buffer function: receives bufferinfo in a0

DB_PMCnormal	moveq	#0,d0

** combined normal/sample routine

DB_PMC		movem.l	d2-d7/a2-a6,-(a7)
		move.w	d0,d7		;sample flag
		move.l	a0,a5

** open lib

		moveq	#0,d0
		lea	LHlib(pc),a1
		move.l	4.w,a6
		jsr	-552(a6)
		move.w	#XFDERR_MISSINGRESOURCE,xfdbi_Error(a5)
		tst.l	d0
		beq	.Exit
		move.l	d0,a4

** allocate buffer

		move.l	xfdbi_SourceBuffer(a5),a2
		move.l	4(a2),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

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

** decrunch

		moveq	#1,d0
		move.l	a4,a6
		jsr	_LVOLHAllocBufferInfo(a6)
		move.l	d0,d6
		beq.s	.FreeBuffer

		move.l	d6,a0
		lea	12(a2),a1
		move.l	a1,(a0)
		move.l	8(a2),4(a0)
		move.l	xfdbi_TargetBuffer(a5),8(a0)
		move.l	4(a2),12(a0)
		jsr	_LVOLHDecrunchBuffer(a6)
		move.w	#XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)

		move.l	d0,-(a7)
		move.l	d6,a0
		jsr	_LVOLHFreeBufferInfo(a6)
		move.l	(a7)+,d0
		cmp.l	xfdbi_TargetBufSaveLen(a5),d0
		bne.s	.FreeBuffer

** do sample mode

		tst.w	d7
		beq.s	.NoSample
		move.l	xfdbi_TargetBuffer(a5),a0
		move.l	xfdbi_TargetBufSaveLen(a5),d0
		subq.l	#1,d0
		move.b	(a0)+,d1
.DoSample	add.b	(a0),d1
		move.b	d1,(a0)+
		subq.l	#1,d0
		bne.s	.DoSample

.NoSample	moveq	#1,d0
		bra.s	.ExitLib

** error -> free buffer

.FreeBuffer	move.l	xfdbi_TargetBuffer(a5),a1
		move.l	xfdbi_TargetBufLen(a5),d0
		move.l	4.w,a6
		jsr	-210(a6)
		moveq	#0,d0

** close lib

.ExitLib	move.l	d0,-(a7)
		move.l	a4,a1
		move.l	4.w,a6
		jsr	-414(a6)
		move.l	(a7)+,d0

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

		cnop	0,4

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

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

S_PMCsample	dc.l	0		;no more slaves
		dc.w	1		;version
		dc.w	33		;master version
		dc.l	N_PMCsample	;name
		dc.w	XFDPFF_DATA	;flags
		dc.w	0
		dc.l	RB_PMCsample	;recog buffer
		dc.l	DB_PMCsample	;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment

N_PMCsample	dc.b	'PMC Sample',0
		even

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

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

RB_PMCsample	cmp.l	#12+4,d0	;min. file length for header and data
		ble.s	.Exit
		cmp.l	#'SFCD',(a0)	;some more verification
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

;Decrunch buffer function: receives bufferinfo in a0

DB_PMCsample	moveq	#1,d0
		bra	DB_PMC

		END
