*****************************************************************************
*   $Id: TetraPack.a,v 1.2 2005/06/23 14:39:16 stoecker Exp $
*   Tetra Pack 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_Tetra102	dc.l	S_Tetra11-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Tetra102-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Tetra102-Xfd68KHeader
		dc.l	DB_Tetra102-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_TetraPack102
		dc.w	0
		dc.l	$108+4+4

N_Tetra102	dc.b	'TetraPack 1.02',0
		even

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

RB_Tetra102	cmp.l	#$b1b900df,$72(a0)
		bne.s	.Exit
		cmp.l	#$49f80080,$9c(a0)
		bne.s	.Exit
		cmp.l	#$4ef80080,$a6(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$e2(a3),d0
		sub.l	$dc(a3),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$104(a3),xfdbi_JmpAddress(a5)
		move.l	$dc(a3),xfdbi_DecrAddress(a5)

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

		lea	$108(a3),a0
		add.l	$26(a3),a0	;decr data end

		move.l	d0,a1
		add.l	$2c(a3),a1
		sub.l	$dc(a3),a1

		moveq	#0,d0
		move.b	$3f(a3),d0
		move.w	d0,a4
		moveq	#0,d5
		move.b	$81(a3),d5		
		moveq	#0,d0
		move.b	$d5(a3),d0
		move.w	d0,a6		
		move.b	$d9(a3),d7		

		moveq	#0,d6
		cmp.w	#$4e71,$84(a3)
		bne.s	.NoNOP
		moveq	#1,d6

.NoNOP		bsr	D_Tetra

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

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

S_Tetra11	dc.l	S_Tetra21-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Tetra11-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Tetra11-Xfd68KHeader
		dc.l	DB_Tetra11-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_TetraPack11
		dc.w	0
		dc.l	$100+4+4

N_Tetra11	dc.b	'TetraPack 1.1',0
		even

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

RB_Tetra11	cmp.l	#$b1b900df,$72(a0)
		bne.s	.Exit
		cmp.l	#$41fa00de,$20(a0)
		bne.s	.Exit
		cmp.l	#$6da0602e,$94(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$d0(a3),d0
		sub.l	$ca(a3),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$f2(a3),xfdbi_JmpAddress(a5)
		move.l	$ca(a3),xfdbi_DecrAddress(a5)

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

		lea	$100(a3),a0
		add.l	$26(a3),a0	;decr data end

		move.l	d0,a1
		add.l	$2c(a3),a1
		sub.l	$ca(a3),a1

		moveq	#0,d0
		move.b	$3f(a3),d0
		move.w	d0,a4
		moveq	#0,d5
		move.b	$81(a3),d5		
		moveq	#0,d0
		move.b	$c3(a3),d0
		move.w	d0,a6		
		move.b	$c7(a3),d7

		moveq	#0,d6
		cmp.w	#$4e71,$84(a3)
		bne.s	.NoNOP
		moveq	#1,d6

.NoNOP		bsr	D_Tetra

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

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

S_Tetra21	dc.l	S_Tetra21Pro-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Tetra21-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Tetra21-Xfd68KHeader
		dc.l	DB_Tetra21-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_TetraPack21
		dc.w	0
		dc.l	$108+4+4

N_Tetra21	dc.b	'TetraPack 2.1',0
		even

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

RB_Tetra21	cmp.l	#$41fa00e4,$22(a0)
		bne.s	.Exit
		cmp.l	#$b0076610,$e6(a0)
		bne.s	.Exit
		cmp.l	#$153220ff,$90(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$e0(a3),d0
		sub.l	$da(a3),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$104(a3),xfdbi_JmpAddress(a5)
		move.l	$da(a3),xfdbi_DecrAddress(a5)

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

		lea	$108(a3),a0
		add.l	$2e(a3),a0	;decr data end

		move.l	d0,a1
		add.l	$34(a3),a1
		sub.l	$da(a3),a1

		moveq	#0,d0
		move.b	$47(a3),d0
		move.w	d0,a4
		moveq	#0,d5
		move.b	$87(a3),d5		
		moveq	#0,d0
		move.b	$c9(a3),d0
		move.w	d0,a6		
		move.b	$d7(a3),d7		

		moveq	#0,d6
		cmp.w	#$4e71,$8a(a3)
		bne.s	.NoNOP
		moveq	#1,d6

.NoNOP		bsr	D_Tetra

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

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

S_Tetra21Pro	dc.l	S_Tetra22-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Tetra21Pro-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Tetra21Pro-Xfd68KHeader
		dc.l	DB_Tetra21Pro-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_TetraPack21Pro
		dc.w	0
		dc.l	$16c+4+4

N_Tetra21Pro	dc.b	'TetraPack 2.1 Pro',0
		even

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

RB_Tetra21Pro	cmp.l	#$41fa00f2,$78(a0)
		bne.s	.Exit
		cmp.l	#$b0076610,$9a(a0)
		bne.s	.Exit
		cmp.l	#$153220ff,$12e(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$94(a3),d0
		sub.l	$8e(a3),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$70(a3),xfdbi_JmpAddress(a5)
		move.l	$8e(a3),xfdbi_DecrAddress(a5)

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

		lea	$16c(a3),a0
		add.l	$cc(a3),a0	;decr data end

		move.l	d0,a1
		add.l	$d2(a3),a1
		sub.l	$8e(a3),a1

		moveq	#0,d0
		move.b	$e5(a3),d0
		move.w	d0,a4
		moveq	#0,d5
		move.b	$125(a3),d5		
		moveq	#0,d0
		move.b	$169(a3),d0
		move.w	d0,a6		
		move.b	$8b(a3),d7		

		moveq	#0,d6
		cmp.w	#$4e71,$128(a3)
		bne.s	.NoNOP
		moveq	#1,d6

.NoNOP		bsr	D_Tetra

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

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

S_Tetra22	dc.l	S_Tetra22Pro-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Tetra22-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Tetra22-Xfd68KHeader
		dc.l	DB_Tetra22-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_TetraPack22
		dc.w	0
		dc.l	$120+4+4

N_Tetra22	dc.b	'TetraPack 2.2',0
		even

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

RB_Tetra22	cmp.l	#$43fa00fc,$22(a0)
		bne.s	.Exit
		cmp.l	#$b0076610,$fe(a0)
		bne.s	.Exit
		cmp.l	#$153220ff,$a8(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$f8(a3),d0
		sub.l	$f2(a3),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$11c(a3),xfdbi_JmpAddress(a5)
		move.l	$f2(a3),xfdbi_DecrAddress(a5)

		LEA	$120(A3),A2
		ADD.L	$34(A3),A2	;decr data end
		MOVE.W	#XFDERR_CORRUPTEDDATA,xfdbi_Error(A5)
		CMP.L	-4(A2),D0
		BLO.B	.Err

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

		MOVE.L	A2,A0		;decr data end

		move.l	d0,a1
		add.l	$4c(a3),a1
		sub.l	$f2(a3),a1

		moveq	#0,d0
		move.b	$5f(a3),d0
		move.w	d0,a4
		moveq	#0,d5
		move.b	$9f(a3),d5		
		moveq	#0,d0
		move.b	$e1(a3),d0
		move.w	d0,a6		
		move.b	$ef(a3),d7		

		moveq	#0,d6
		cmp.w	#$4e71,$a2(a3)
		bne.s	.NoNOP
		moveq	#1,d6

.NoNOP		bsr	D_Tetra

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

.Err		MOVEQ	#0,D0
		BRA.B	.Exit

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

S_Tetra22Pro	
		IFND	XFD_LASTSLAVE
		dc.l	S_Tetra_END-Xfd68KHeader
		ELSE
		dc.l	0
		ENDIF
		dc.w	2
		dc.w	39
		dc.l	N_Tetra22Pro-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Tetra22Pro-Xfd68KHeader
		dc.l	DB_Tetra22Pro-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_TetraPack22Pro
		dc.w	0
		dc.l	$184+4+4

N_Tetra22Pro	dc.b	'TetraPack 2.2 Pro',0
		even

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

RB_Tetra22Pro	cmp.l	#$43fa010a,$78(a0)
		bne.s	.Exit
		cmp.l	#$b0076610,$c4(a0)
		bne.s	.Exit
		cmp.l	#$153220ff,$146(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$be(a3),d0
		sub.l	$b8(a3),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$70(a3),xfdbi_JmpAddress(a5)
		move.l	$b8(a3),xfdbi_DecrAddress(a5)

		LEA	$184(A3),A2
		ADD.L	$84(A3),A2	;decr data end
		MOVE.W	#XFDERR_CORRUPTEDDATA,xfdbi_Error(A5)
		CMP.L	-4(A2),D0
		BLO.B	.Err

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

		MOVE.L	A2,A0		;decr data end

		move.l	d0,a1
		add.l	$9c(a3),a1
		sub.l	$b8(a3),a1

		moveq	#0,d0
		move.b	$fd(a3),d0
		move.w	d0,a4
		moveq	#0,d5
		move.b	$13d(a3),d5		
		moveq	#0,d0
		move.b	$181(a3),d0
		move.w	d0,a6		
		move.b	$b5(a3),d7		

		moveq	#0,d6
		cmp.w	#$4e71,$140(a3)
		bne.s	.NoNOP
		moveq	#1,d6

.NoNOP		bsr.s	D_Tetra

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

.Err		MOVEQ	#0,D0
		BRA.B	.Exit

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

* a0: source end
* a1: target begin
* d5-d7/a4/a6: parameters

D_Tetra		move.l	-(a0),a2
		add.l	a1,a2
		move.l	-(a0),d0
.Decr1		bsr.s	.Decr9
		bcs.s	.Decr17
		move.w	a4,d1		;<--
		moveq	#1,d3
		bsr.s	.Decr9
		bcs.s	.Decr11
		moveq	#3,d1
		moveq	#0,d4
.Decr4		bsr.s	.Decr14
		move.w	d2,d3
		add.w	d4,d3
.Decr5		moveq	#7,d1
.Decr6		bsr.s	.Decr9
		roxl.l	#1,d2
		dbra	d1,.Decr6
		move.b	d2,-(a2)
		cmp.l	a1,a2
		dbeq	d3,.Decr5
		bra.s	.Decr13

.Decr8		moveq	#7,d1
		moveq	#8,d4
		bra.s	.Decr4

.Decr9		lsr.l	#1,d0
		bne.s	.Decr7
		move.l	-(a0),d0
		move.b	#$10,ccr
		roxr.l	#1,d0
.Decr7		rts

.Decr17		moveq	#2,d1
		bsr.s	.Decr14
		cmp.b	#2,d2
		blt.s	.Decr10
		cmp.b	#3,d2
		beq.s	.Decr8
		moveq	#8,d1
		bsr.s	.Decr14
		move.w	d2,d3
		addq.w	#4,d3
		move.w	a6,d1		;<--
		bra.s	.Decr11

.Decr10		move.w	d5,d1		;<--
		move.w	d2,d3
		tst.w	d6		;<--
		bne.s	.Decr40		;<--
		add.w	d2,d1		;<-- nop
.Decr40		addq.w	#2,d3
.Decr11		bsr.s	.Decr14
.Decr12		move.b	-1(a2,d2.w),-(a2)
		cmp.l	a1,a2
		dbeq	d3,.Decr12
.Decr13		cmp.w	#-1,d3
		beq.s	.Decr1
		bra.s	.Decr18

.Decr14		subq.w	#1,d1
		moveq	#0,d2
.Decr15		bsr.s	.Decr9
		roxl.l	#1,d2
		dbra	d1,.Decr15
		rts

.Decr18		move.l	xfdbi_TargetBuffer(a5),a0
		move.l	a0,a2
		add.l	xfdbi_TargetBufLen(a5),a2
.Decr19		move.b	(a1)+,d0
		cmp.b	d7,d0		;<--
		bne.s	.Decr21
		moveq	#0,d1
		move.b	(a1)+,d1
		beq.s	.Decr21
		move.b	(a1)+,d0
		addq.w	#1,d1
.Decr20		move.b	d0,(a0)+
		cmp.l	a2,a0
		dbeq	d1,.Decr20
		cmp.w	#-1,d1
		bne.s	.Exit
.Decr21		move.b	d0,(a0)+
		cmp.l	a2,a0
		bne.s	.Decr19
.Exit		rts

S_Tetra_END

