*****************************************************************************
*   $Id: FCG.a,v 1.2 2005/06/23 14:39:16 stoecker Exp $
*   FCG decrunching slave
*
*   XFD library system for cruncher handling
*   Copyright (C) 1994-1998 by Georg Hörmann
*   Copyright (C) 1998 by Dirk Stöcker <soft@dstoecker.de>
*
*   This library is free software; you can redistribute it and/or
*   modify it under the terms of the GNU Lesser General Public
*   License as published by the Free Software Foundation; either
*   version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*****************************************************************************

S_FCG10		
		IFND	XFD_LASTSLAVE
		dc.l	S_FCG_END-Xfd68KHeader
		ELSE
		dc.l	0
		ENDIF
		dc.w	2
		dc.w	39
		dc.l	N_FCG10-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_FCG10-Xfd68KHeader
		dc.l	DB_FCG10-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_FCG10
		dc.w	0
		dc.l	$20c+4+24

N_FCG10		dc.b	'FCG 1.0',0
		even

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

RB_FCG10	cmp.l	#$4ef800c4,$58(a0)
		bne.s	.Exit
		cmp.l	#$7610740f,$84(a0)
		bne.s	.Exit
		cmp.l	#$5242b642,$92(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DB_FCG10	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		lea	-16(a7),a7
		move.l	a7,a4
		move.l	xfdbi_SourceBuffer(a5),a2

		move.l	$7c(a2),d0	;byte size
		move.l	d0,(a4)
		moveq	#1,d1
		move.l	xfdm_ExecBase(a6),a6
		jsr	-198(a6)
		move.w	#XFDERR_NOMEMORY,xfdbi_Error(a5)
		move.l	d0,4(a4)
		beq	.Exit

		move.l	d0,a0
		lea	$20c(a2),a1	;source
		lea	$10c(a2),a3
		move.l	a0,a2		;target
		add.l	(a4),a2
		bsr	D_FCG

		move.l	4(a4),a0	;byte counter 1
		move.l	a0,a1
		lea	$66(a1),a1
		add.l	$1e(a0),a1
		move.w	$1a(a0),d2
		lea	$66(a0),a0
		moveq	#0,d0		;count

.Byte1Count1	addq.l	#1,d0
.Byte1Count3	cmp.l	a0,a1
		beq.s	.Byte1Count2
		cmp.b	(a0)+,d2
		bne.s	.Byte1Count1
		moveq	#0,d1
		move.b	(a0)+,d1
		beq.s	.Byte1Count1
		add.l	d1,d0
		addq.w	#3,a0
		bra.s	.Byte1Count3

.Byte1Count2	move.l	d0,8(a4)
		moveq	#1,d1
		jsr	-198(a6)
		move.l	d0,12(a4)
		beq	.Exit2
		
		move.l	d0,a0
		move.l	4(a4),a2	;byte decr 1
		move.l	a2,a3
		lea	$66(a3),a3
		add.l	$1e(a2),a3
		move.w	$1a(a2),d7
		move.l	$36(a2),d6	;start addr for correction
		lea	$66(a2),a2
		move.l	a0,d5
		bsr	D_FCGByte1

		move.l	(a4),d0		;1. buffer loeschen
		move.l	4(a4),a1
		jsr	-210(a6)
		move.l	8(a4),(a4)
		move.l	12(a4),4(a4)

		move.l	4(a4),a0	;byte counter 2
		move.l	a0,a1
		move.l	$34(a0),xfdbi_DecrAddress(a5)
		move.l	$6a(a0),xfdbi_JmpAddress(a5)
		lea	$6e(a1),a1
		add.l	$26(a0),a1
		move.w	$1a(a0),d2
		lea	$6e(a0),a0
		moveq	#0,d0		;count

.Byte2Count	cmp.l	a1,a0
		beq.s	.Byte2Count3
		cmp.b	(a0)+,d2
		beq.s	.Byte2Count2
.Byte2Count1	addq.l	#1,d0
		bra.s	.Byte2Count
.Byte2Count2	moveq	#0,d1
		move.b	(a0)+,d1
		beq.s	.Byte2Count1
		addq.w	#1,a0
		add.l	d1,d0
		bra.s	.Byte2Count

.Byte2Count3	move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)
		move.l	xfdbi_TargetBufMemType(a5),d1
		jsr	-198(a6)
		move.l	d0,xfdbi_TargetBuffer(a5)
		beq.s	.Exit2

		move.l	d0,a0
		move.l	4(a4),a1	;byte decr 2
		move.l	a1,a2
		lea	$6e(a2),a2
		add.l	$26(a1),a2
		move.w	$1a(a1),d7
		lea	$6e(a1),a1
		bsr	D_FCGByte2

		moveq	#1,d0

.Exit2		move.l	d0,-(a7)
		move.l	(a4),d0
		move.l	4(a4),a1
		jsr	-210(a6)
		move.l	(a7)+,d0

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

;=================================================

D_FCG		moveq	#16,d3
		moveq	#15,d2
.Decr1		cmp.l	a0,a2
		beq.s	.Exit

		addq.w	#1,d2
		cmp.w	d2,d3
		bne.s	.Decr2
		move.w	(a1)+,d0
		moveq	#0,d2
.Decr2		lsl.w	#1,d0
		bcs.s	.Decr8

		addq.w	#1,d2
		cmp.w	d2,d3
		bne.s	.Decr3
		move.w	(a1)+,d0
		moveq	#0,d2
.Decr3		lsl.w	#1,d0
		bcs.s	.Decr7

		moveq	#2,d4
		moveq	#0,d5

.Decr4		moveq	#0,d1
.Decr5		addq.w	#1,d2
		cmp.w	d2,d3
		bne.s	.Decr6
		move.w	(a1)+,d0
		moveq	#0,d2
.Decr6		lsl.w	#1,d0
		roxl.w	#1,d1
		dbra	d4,.Decr5
		add.w	d5,d1
		move.b	(a3,d1.w),d1
		move.b	d1,(a0)+
		bra.s	.Decr1

.Decr7		moveq	#4,d4
		moveq	#8,d5
		bra.s	.Decr4

.Decr8		addq.w	#1,d2
		cmp.w	d2,d3
		bne.s	.Decr9
		move.w	(a1)+,d0
		moveq	#0,d2
.Decr9		lsl.w	#1,d0
		bcc.s	.Decr11

		addq.w	#1,d2
		cmp.w	d2,d3
		bne.s	.Decr10
		move.w	(a1)+,d0
		moveq	#0,d2
.Decr10		lsl.w	#1,d0
		bcc.s	.Decr12

		moveq	#6,d4
		move.w	#$88,d5
		bra.s	.Decr4

.Decr11		moveq	#4,d4
		moveq	#$28,d5
		bra.s	.Decr4

.Decr12		moveq	#5,d4
		moveq	#$48,d5
		bra.s	.Decr4

.Exit		rts

D_FCGByte1	cmp.l	a2,a3
		beq.s	.Exit
		move.b	(a2)+,d0
		cmp.b	d0,d7
		bne.s	.Decr1
		move.b	(a2)+,d1
		bne.s	.Decr3
.Decr1		move.b	d0,(a0)+
		bra.s	D_FCGByte1
.Decr3		moveq	#0,d0
		move.b	(a2)+,d0
		swap	d0
		move.b	(a2)+,d0
		lsl.w	#8,d0
		move.b	(a2)+,d0
		sub.l	d6,d0
		add.l	d5,d0
		move.l	d0,a1
.Decr2		move.b	(a1)+,(a0)+
		subq.b	#1,d1
		bne.s	.Decr2
		bra.s	D_FCGByte1
.Exit		rts

D_FCGByte2	cmp.l	a2,a1
		beq.s	.Exit
		move.b	(a1)+,d0
		cmp.b	d7,d0
		beq.s	.Decr1
		move.b	d0,(a0)+
		bra.s	D_FCGByte2
.Decr1		move.b	(a1)+,d1
		beq.s	.Decr3
		move.b	(a1)+,d0
.Decr2		move.b	d0,(a0)+
		subq.b	#1,d1
		bne.s	.Decr2
		bra.s	D_FCGByte2
.Decr3		move.b	d7,(a0)+
		bra.s	D_FCGByte2
.Exit		rts

S_FCG_END

