*****************************************************************************
*   $Id: StoneCracker.a,v 1.2 2005/06/23 14:39:16 stoecker Exp $
*   StoneCracker 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_Stone270	dc.l	S_Stone270Pro-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone270-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone270-Xfd68KHeader
		dc.l	DB_Stone270-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker270
		dc.w	0
		dc.l	$186+22+4

N_Stone270	dc.b	'StoneCracker 2.70',0
		even

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

RB_Stone270	cmp.l	#$1e3a0157,$30(a0)
		bne.s	.Exit
		cmp.l	#$1a3a0160,$34(a0)
		bne.s	.Exit
		cmp.l	#$1c3a015d,$38(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$a0(a4),d0
		sub.l	$9a(a4),d0
		move.l	d0,xfdbi_TargetBufLen(a5)
		move.l	$18e(a4),xfdbi_TargetBufSaveLen(a5)

		move.l	$f8(a4),xfdbi_JmpAddress(a5)
		move.l	$9a(a4),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	$198(a4),a0
		add.l	$192(a4),a0

		move.l	d0,a1
		add.l	xfdbi_TargetBufLen(a5),a1
		move.l	a1,a2
		sub.l	$18a(a4),a2

		moveq	#0,d7
		moveq	#0,d6
		moveq	#0,d5
		move.b	$189(a4),d7
		move.b	$196(a4),d5
		move.b	$197(a4),d6

		move.l	xfdbi_TargetBuffer(a5),a3
		add.l	$18e(a4),a3

		move.b	$186(a4),d0
		move.b	$187(a4),d1
		move.b	$188(a4),d2

		bsr	D_Stone270

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

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

S_Stone270Pro	dc.l	S_Stone292-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone270Pro-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone270Pro-Xfd68KHeader
		dc.l	DB_Stone270Pro-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker270Pro
		dc.w	0
		dc.l	$216+22+4

N_Stone270Pro	dc.b	'StoneCracker 2.70 Pro',0
		even

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

RB_Stone270Pro	cmp.l	#$1e3a0181,$96(a0)
		bne.s	.Exit
		cmp.l	#$1a3a018a,$9a(a0)
		bne.s	.Exit
		cmp.l	#$1c3a0187,$9e(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$11c(a4),d0
		sub.l	$116(a4),d0
		move.l	d0,xfdbi_TargetBufLen(a5)
		move.l	$21e(a4),xfdbi_TargetBufSaveLen(a5)

		move.l	$182(a4),xfdbi_JmpAddress(a5)
		move.l	$116(a4),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	$228(a4),a0
		add.l	$222(a4),a0

		move.l	d0,a1
		add.l	xfdbi_TargetBufLen(a5),a1
		move.l	a1,a2
		sub.l	$21a(a4),a2

		moveq	#0,d7
		moveq	#0,d6
		moveq	#0,d5
		move.b	$219(a4),d7
		move.b	$226(a4),d5
		move.b	$227(a4),d6

		move.l	xfdbi_TargetBuffer(a5),a3
		add.l	$21e(a4),a3

		move.b	$216(a4),d0
		move.b	$217(a4),d1
		move.b	$218(a4),d2

		bsr.b	D_Stone270

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

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

D_Stone270	movem.w	d0-d2,-(a7)
		move.l	-(a0),d0
.Decr1		moveq	#0,d1
		add.l	d0,d0
		bne.s	.Decr2
		bsr.s   .Decr16
.Decr2		bcc	.Decr17
		add.l	d0,d0
		bne.s	.Decr3
		bsr.s   .Decr16
.Decr3		bcs.s	.Decr4
		moveq	#7,d3
		moveq	#1,d4
		bra.s	.Decr6

.Decr4		addx.w	d1,d1
		add.l	d0,d0
		bne.s	.Decr5
		bsr.s   .Decr16
.Decr5		addx.w	d1,d1
		moveq	#8,d3
		moveq	#2,d4
		cmp.w	#2,d1
		beq.s	.Decr6
		moveq	#9,d3
		addq.w	#1,d4
.Decr6		bsr	.Decr23
.Decr7		move.b	-1(a1,d2.w),-(a1)
		cmp.l	a2,a1
		dbeq	d4,.Decr7
.Decr8		cmp.w	#-1,d4
		beq.s	.Decr1

		movem.w	(a7)+,d0-d2
		move.l	xfdbi_TargetBuffer(a5),a0
.Decr9		moveq	#0,d7
		move.b	(a1)+,d4
		cmp.b	d0,d4
		beq.s	.Decr11
		cmp.b	d1,d4
		beq.s	.Decr12
.Decr10		move.b	d4,(a0)+
		cmp.l	a3,a0
		bne.s	.Decr9
		rts	

.Decr11		move.b	(a1)+,d5
		beq.b	.Decr10
		move.b	(a1)+,d4
		bra.s	.Decr13

.Decr12		move.b	(a1)+,d5
		beq.s	.Decr10
		move.b	d2,d4
.Decr13		move.b	d5,d7
		addq.w	#1,d7
.Decr14		move.b	d4,(a0)+
		cmp.l	a3,a0
		dbeq	d7,.Decr14
		cmp.w	#-1,d7
		beq.s	.Decr9
		rts

.Decr16		move.l	-(a0),d0
		move.b	#$10,ccr
		addx.l	d0,d0
		rts

.Decr17		add.l	d0,d0
		bne.s	.Decr18
		bsr.s   .Decr16
.Decr18		bcc.s	.Decr21
		addx.w	d1,d1
		add.l	d0,d0
		bne.s	.Decr19
		bsr.s   .Decr16
.Decr19		addx.w	d1,d1
		cmp.w	#2,d1
		beq.s	.Decr20
		move.w	d5,d3
		bsr.s   .Decr23
		move.w	d2,d4
		addq.w	#4,d4
		move.w	d7,d3
		bra.s	.Decr6

.Decr20		move.w	d6,d3
		bsr.s   .Decr23
		addq.w	#7,d2
		move.w	d2,d4
		bra.s	.Decr22

.Decr21		moveq	#2,d3
		bsr.s   .Decr23
		move.w	d2,d4
		subq.w	#1,d4
		and.w	#7,d4
.Decr22		moveq	#7,d3
		bsr.s   .Decr23
		move.b	d2,-(a1)
		cmp.l	a2,a1
		dbeq	d4,.Decr22
		bra	.Decr8

.Decr23		moveq	#0,d2
.Decr24		add.l	d0,d0
		bne.s	.Decr25
		bsr.s   .Decr16
.Decr25		addx.w	d2,d2
		dbra	d3,.Decr24
		rts

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

S_Stone292	dc.l	S_Stone292Data-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone292-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone292-Xfd68KHeader
		dc.l	DB_Stone292-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker292
		dc.w	0
		dc.l	$180+16+4

N_Stone292	dc.b	'StoneCracker 2.92',0
		even

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

RB_Stone292	cmp.l	#$183a00ab,$d6(a0)
		bne.s	.Exit
		cmp.l	#$d1fa00b8,$ca(a0)
		bne.s	.Exit
		cmp.l	#$123b006a,$114(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$184(a4),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$164(a4),xfdbi_JmpAddress(a5)
		move.l	$a4(a4),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	$18c(a4),a2
		add.l	$188(a4),a2

		move.l	d0,a0
		move.l	a0,a1
		add.l	xfdbi_TargetBufSaveLen(a5),a0

		moveq	#0,d4
		move.b	$183(a4),d4

		move.l	$180(a4),-(a7)
		move.l	a7,a3
		bsr	D_Stone299
		addq.w	#4,a7

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

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

S_Stone292Data	dc.l	S_Stone299-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone292Data-Xfd68KHeader
		dc.w	XFDPFF_DATA|XFDPFF_RECOGLEN|XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_Stone292Data-Xfd68KHeader
		dc.l	DB_Stone292Data-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker292Data
		dc.w	0
		dc.l	$E

N_Stone292Data	dc.b	'StoneCracker 2.92 Data',0
		even

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

RB_Stone292Data	CMPI.W	#$0809,(A0)
		BNE.B	.Exit
		CMPI.W	#$0A08,2(A0)
		BEQ.B	.Ok
		CMPI.W	#$0A0A,2(A0)
		BEQ.B	.Ok
		CMPI.W	#$0A0B,2(A0)
		BEQ.B	.Ok
		CMPI.W	#$0A0C,2(A0)
		BEQ.B	.Ok
		CMPI.W	#$0A0D,2(A0)
		BEQ.B	.Ok
		CMPI.W	#$0A0E,2(A0)
		BNE.B	.Exit
.Ok		MOVE.L	8(A0),D1
		CMP.L	4(A0),D1
		BGT.B	.Exit
		MOVE.L	4(A0),D1
		MOVE.L	D1,xfdrr_MinTargetLen(A1)
		MOVE.L	D1,xfdrr_FinalTargetLen(A1)
		MOVEQ	#12,D1
		ADD.L	8(A0),D1
		MOVE.L	D1,xfdrr_MinSourceLen(A1)
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DB_Stone292Data	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		move.l	xfdbi_SourceBuffer(a5),a4
		lea	$C(A4),A2
		add.l	8(A4),A2
		MOVE.L	xfdbi_UserTargetBuf(A5),A0
		move.l	a0,a1
		add.l	xfdbi_TargetBufSaveLen(a5),a0
		moveq	#0,d4
		move.b	$3(a4),d4
		move.l	(a4),-(a7)
		move.l	a7,a3
		bsr	D_Stone299
		addq.l	#4,a7
		moveq	#1,d0
		movem.l	(a7)+,d2-d7/a2-a6
		rts

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

S_Stone299	dc.l	S_Stone299b-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone299-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone299-Xfd68KHeader
		dc.l	DB_Stone299-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker299
		dc.w	0
		dc.l	$178+16+4

N_Stone299	dc.b	'StoneCracker 2.99',0
		even

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

RB_Stone299	cmp.l	#$183a00a7,$d2(a0)
		bne.s	.Exit
		cmp.l	#$d1fa00b4,$c6(a0)
		bne.s	.Exit
		cmp.l	#$123b0068,$10e(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$17c(a4),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$15c(a4),xfdbi_JmpAddress(a5)
		move.l	$a0(a4),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	$184(a4),a2
		add.l	$180(a4),a2

		move.l	d0,a0
		move.l	a0,a1
		add.l	xfdbi_TargetBufSaveLen(a5),a0

		moveq	#0,d4
		move.b	$17b(a4),d4

		move.l	$178(a4),-(a7)
		move.l	a7,a3
		bsr	D_Stone299
		addq.w	#4,a7

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

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

S_Stone299b	dc.l	S_Stone299d-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone299b-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone299b-Xfd68KHeader
		dc.l	DB_Stone299b-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker299b
		dc.w	0
		dc.l	$174+16+4

N_Stone299b	dc.b	'StoneCracker 2.99b',0
		even

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

RB_Stone299b	cmp.l	#$183a00a7,$ce(a0)
		bne.s	.Exit
		cmp.l	#$4bfa0158,$26(a0)
		bne.s	.Exit
		cmp.l	#$123b0068,$10a(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$178(a4),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$158(a4),xfdbi_JmpAddress(a5)
		move.l	$a0(a4),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	$180(a4),a2
		add.l	$17c(a4),a2

		move.l	d0,a0
		move.l	a0,a1
		add.l	xfdbi_TargetBufSaveLen(a5),a0

		moveq	#0,d4
		move.b	$177(a4),d4

		move.l	$174(a4),-(a7)
		move.l	a7,a3
		bsr	D_Stone299
		addq.w	#4,a7

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

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

S_Stone299d	dc.l	S_Stone300-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone299d-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone299d-Xfd68KHeader
		dc.l	DB_Stone299d-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker299d
		dc.w	0
		dc.l	$168+24+4

N_Stone299d	dc.b	'StoneCracker 2.99d',0
		even

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

RB_Stone299d	cmp.l	#$183a00a7,$c2(a0)
		bne.s	.Exit
		cmp.l	#$4bfa0154,$26(a0)
		bne.s	.Exit
		cmp.l	#$123b0068,$fe(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$16c(a4),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$14c(a4),xfdbi_JmpAddress(a5)
		move.l	$92(a4),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	$17c(a4),a2
		add.l	$170(a4),a2

		move.l	d0,a0
		move.l	a0,a1
		add.l	xfdbi_TargetBufSaveLen(a5),a0

		moveq	#0,d4
		move.b	$16b(a4),d4

		move.l	$168(a4),-(a7)
		move.l	a7,a3
		bsr.s	D_Stone299
		addq.w	#4,a7

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

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

D_Stone299	moveq	#$7f,d3
		moveq	#3,d5
		moveq	#7,d6
		move.l	-(a2),d7
.Decr1		moveq	#0,d2
		lsr.l	#1,d7
		bne.s	.Decr2
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr2		bcc.s	.Decr7
.Decr3		move.w	d5,d1
		bsr.s	.Decr15
		add.l	d0,d2
		cmp.w	d6,d0
		beq.s	.Decr3
.Decr4		move.w	d6,d1
.Decr5		lsr.l	#1,d7
		bne.s	.Decr6
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr6		roxr.b	#1,d0
		dbra	d1,.Decr5
		move.b	d0,-(a0)
		cmp.l	a1,a0
		beq.s	.Exit
		subq.l	#1,d2
		bne.s	.Decr4
		bra.s	.Decr1

.Decr7		moveq	#1,d1
		bsr.s	.Decr16
		moveq	#0,d1
		move.l	d0,d2
		move.b	(a3,d0.w),d1
		cmp.w	d5,d0
		bne.s	.Decr12
		lsr.l	#1,d7
		bne.s	.Decr8
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr8		bcs.s	.Decr10
.Decr9		move.w	d6,d1
		bsr.s	.Decr15
		add.l	d0,d2
		cmp.w	d3,d0
		beq.s	.Decr9
		add.l	d6,d2
		add.l	d6,d2
		bra.s	.Decr11

.Decr10		move.w	d5,d1
		bsr.s	.Decr15
		add.l	d0,d2
		cmp.w	d6,d0
		beq.s	.Decr10
.Decr11		move.w	d4,d1
.Decr12		addq.l	#1,d2
		bsr.s	.Decr16
.Decr13		move.b	(a0,d0.w),-(a0)
		cmp.l	a1,a0
		beq.s	.Exit
		subq.l	#1,d2
		bpl.s	.Decr13
		bra.s	.Decr1
.Exit		rts

.Decr15		subq.w	#1,d1
.Decr16		moveq	#0,d0
.Decr17		lsr.l	#1,d7
		bne.s	.Decr18
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr18		addx.l	d0,d0
		dbra	d1,.Decr17
		rts

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

S_Stone300	dc.l	S_Stone300Data-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone300-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone300-Xfd68KHeader
		dc.l	DB_Stone300-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker300
		dc.w	0
		dc.l	$178+16+4

N_Stone300	dc.b	'StoneCracker 3.00',0
		even

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

RB_Stone300	cmp.l	#$183a00ab,$c2(a0)
		bne.s	.Exit
		cmp.l	#$43fa008c,$c6(a0)
		bne.s	.Exit
		cmp.l	#$123b0066,$104(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$170(a4),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$150(a4),xfdbi_JmpAddress(a5)
		move.l	$92(a4),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	$184(a4),a2
		add.l	$174(a4),a2

		move.l	d0,a0
		move.l	a0,a1
		add.l	xfdbi_TargetBufSaveLen(a5),a0

		moveq	#0,d4
		move.b	$16f(a4),d4

		move.l	$16c(a4),-(a7)
		move.l	a7,a3
		bsr	D_Stone300
		addq.w	#4,a7

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

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

S_Stone300Data	dc.l	S_Stone310-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone300Data-Xfd68KHeader
		dc.w	XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_Stone300Data-Xfd68KHeader
		dc.l	DB_Stone300Data-Xfd68KHeader
		dc.l	SD_Stone300Data-Xfd68KHeader
		dc.l	VD_Stone300Data-Xfd68KHeader
		dc.w	XFDID_StoneCracker300Data
		dc.w	0
		dc.l	4+16

N_Stone300Data	dc.b	'StoneCracker 3.00 Data',0
		even

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

RB_Stone300Data	BSR.B	SD_Stone300Data
		TST.L	D0
		beq.b	.Exit
		move.l	4(a0),d0
		and.l	#$f0f0f0f0,d0
		bne.s	.Exit
		MOVE.L	8(A0),D0
		MOVE.L	D0,xfdrr_MinTargetLen(A1)
		MOVE.L	D0,xfdrr_FinalTargetLen(A1)
		MOVEQ	#$10,D0
		ADD.L	12(A0),D0
		MOVE.L	D0,xfdrr_MinSourceLen(A1)
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

SD_Stone300Data	MOVEQ	#0,D0
		MOVE.L	(A0),D1
		CMP.L	#'S300',D1
		BEQ.B	.ok
		AND.L	#$FFFFFF00,D1
		CMP.L	#$31414D00,D1
		BNE.B	.Exit
.ok		MOVEQ	#1,D0
.Exit		RTS

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

VD_Stone300Data	move.l	4(a0),d1
		and.l	#$f0f0f0f0,d1
		bne.s	.Exit
		moveq	#$10,d1
		add.l	12(a0),d1	;crlen
		cmp.l	d0,d1		;crlen > buflen ??
		bgt.s	.Exit
		move.l	8(a0),d0
		sub.l	12(a0),d0	;cr > uncr ??
		bmi.s	.Exit
		move.l	d1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		lea	$10(a4),a2
		add.l	$c(a4),a2

		MOVE.L	xfdbi_UserTargetBuf(A5),A0
		move.l	a0,a1
		add.l	xfdbi_TargetBufSaveLen(a5),a0

		moveq	#0,d4
		move.b	7(a4),d4

		move.l	4(a4),-(a7)
		move.l	a7,a3
		bsr.b	D_Stone300
		addq.w	#4,a7

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

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

D_Stone300	moveq	#$7F,d3
		moveq	#3,d5
		moveq	#7,d6
		move.l	-(a2),d7
.Decr1		lsr.l	#1,d7
		bne.s	.Decr2
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr2		bcc.s	.Decr7
		moveq	#1,d2
.Decr3		moveq	#2,d1
		bsr.s	.Decr16
		add.l	d0,d2
		cmp.w	d6,d0
		beq.s	.Decr3
.Decr4		moveq	#7,d1
.Decr5		lsr.l	#1,d7
		bne.s	.Decr6
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr6		roxr.b	#1,d0
		dbra	d1,.Decr5
		move.b	d0,-(a0)
		cmp.l	a1,a0
		beq.s	.Exit
		subq.l	#1,d2
		bne.s	.Decr4
		bra.s	.Decr1

.Decr7		moveq	#1,d1
		bsr.s	.Decr16
		moveq	#0,d1
		move.l	d0,d2
		move.b	(a3,d0.w),d1
		cmp.w	d5,d0
		bne.s	.Decr12
		lsr.l	#1,d7
		bne.s	.Decr8
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr8		bcs.s	.Decr10
.Decr9		moveq	#6,d1
		bsr.s	.Decr16
		add.l	d0,d2
		cmp.w	d3,d0
		beq.s	.Decr9
		move.w	d4,d1
		bra.s	.Decr12

.Decr10		moveq	#2,d1
		bsr.s	.Decr16
		add.l	d0,d2
		cmp.w	d6,d0
		beq.s	.Decr10
		moveq	#7,d1
.Decr12		addq.l	#1,d2
		bsr.s	.Decr16
.Decr13		move.b	(a0,d0.w),-(a0)
		cmp.l	a1,a0
		beq.s	.Exit
		subq.l	#1,d2
		bpl.s	.Decr13
		bra.s	.Decr1
.Exit		rts

.Decr16		moveq	#0,d0
.Decr17		lsr.l	#1,d7
		bne.s	.Decr18
		move.l	-(a2),d7
		roxr.l	#1,d7
.Decr18		addx.l	d0,d0
		dbra	d1,.Decr17
		rts

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

S_Stone310	dc.l	S_Stone310Data-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone310-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone310-Xfd68KHeader
		dc.l	DB_Stone310-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker310
		dc.w	0
		dc.l	$228+12+4

N_Stone310	dc.b	'StoneCracker 3.10',0
		even

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

RB_Stone310	cmp.l	#$010203ff,$148(a0)
		bne.s	.Exit
		cmp.l	#$600000c6,$144(a0)
		bne.s	.Exit
		cmp.l	#$163b20e0,$166(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$228(a2),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$21c(a2),xfdbi_JmpAddress(a5)
		move.l	$76(a2),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

		move.l	d0,a0
		lea	$228(a2),a2
		bsr	D_Stone310

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

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

S_Stone310Data	dc.l	S_Stone311-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone310Data-Xfd68KHeader
		dc.w	XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_Stone310Data-Xfd68KHeader
		dc.l	DB_Stone310Data-Xfd68KHeader
		dc.l	SD_Stone310Data-Xfd68KHeader
		dc.l	VD_Stone310Data-Xfd68KHeader
		dc.w	XFDID_StoneCracker310Data
		dc.w	0
		dc.l	4+12

N_Stone310Data	dc.b	'StoneCracker 3.10 Data',0
		even

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

RB_Stone310Data	moveq	#0,d0
		cmp.l	#'S310',(a0)
		bne.s	.Exit
		MOVE.L	4(A0),D0
		MOVE.L	D0,xfdrr_MinTargetLen(A1)
		MOVE.L	D0,xfdrr_FinalTargetLen(A1)
		MOVEQ	#$C,D0
		ADD.L	8(A0),D0
		MOVE.L	D0,xfdrr_MinSourceLen(A1)
		moveq	#1,d0
.Exit		rts

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

SD_Stone310Data	moveq	#0,d0
		cmp.l	#'S310',(a0)
		bne.s	.Exit
		moveq	#1,d0
.Exit		rts

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

VD_Stone310Data	moveq	#$c,d1
		add.l	8(a0),d1	;crlen
		cmp.l	d0,d1		;crlen > buflen ??
		bgt.s	.Exit
		move.l	4(a0),d0
		sub.l	8(a0),d0	;cr > uncr ??
		bmi.s	.Exit
		move.l	d1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DB_Stone310Data	movem.l	d2-d7/a2-a6,-(a7)
		MOVE.L	xfdbi_SourceBuffer(A0),A2
		MOVE.L	xfdbi_UserTargetBuf(A0),A0
		move.l	(a2)+,d0
		bsr	D_Stone310
		moveq	#1,d0
		movem.l	(a7)+,d2-d7/a2-a6
		rts

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

S_Stone311	dc.l	S_Stone400-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone311-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone311-Xfd68KHeader
		dc.l	DB_Stone311-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker311
		dc.w	0
		dc.l	$218+12+4

N_Stone311	dc.b	'StoneCracker 3.11',0
		even

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

RB_Stone311	cmp.l	#$010203ff,$136(a0)
		bne.s	.Exit
		cmp.l	#$600000c6,$132(a0)
		bne.s	.Exit
		cmp.l	#$163b20e0,$154(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	$218(a2),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$20a(a2),xfdbi_JmpAddress(a5)
		move.l	$76(a2),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

		move.l	d0,a0
		lea	$218(a2),a2
		bsr.b	D_Stone310

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

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

D_Stone310	moveq	#2,d5
		moveq	#$1f,d6
		moveq	#7,d7
		move.l	(a2)+,a3
		move.l	(a2)+,d0
		add.l	a0,a3
		move.l	(a2)+,d0
		lsr.w	#1,d6
		bra.s	.Decr2

.Decr1		add.l	d0,d0
		bne.s	.Decr3
		move.l	(a2)+,d0
.Decr2		addx.l	d0,d0
.Decr3		bcs.s	.Decr17

		moveq	#0,d3

.Decr4		moveq	#3-1,d4
		moveq	#0,d2
.Decr5		add.l	d0,d0
		bne.s	.Decr6
		move.l	(a2)+,d0
		addx.l	d0,d0
.Decr6		addx.w	d2,d2
		dbra	d4,.Decr5

		add.l	d2,d3
		cmp.w	d7,d2
		beq.s	.Decr4

.Decr8		moveq	#8-1,d4
.Decr9		add.l	d0,d0
		bne.s	.Decr10
		move.l	(a2)+,d0
		addx.l	d0,d0
.Decr10		addx.b	d2,d2
		dbra	d4,.Decr9

		move.b	d2,(a0)+
		cmp.l	a3,a0
		beq.s	.Exit
		subq.l	#1,d3
		bne.s	.Decr8
		bra.s	.Decr1

.Decr40		dc.b	10-1,11-1,12-1,8-1

.Decr17		moveq	#0,d2

		add.l	d0,d0
		bne.s	.Decr18
		move.l	(a2)+,d0
		addx.l	d0,d0
.Decr18		addx.w	d2,d2

		add.l	d0,d0
		bne.s	.Decr19
		move.l	(a2)+,d0
		addx.l	d0,d0
.Decr19		addx.w	d2,d2

		moveq	#0,d1
		moveq	#0,d3
		move.b	.Decr40(pc,d2.w),d3

.Decr20		add.l	d0,d0
		bne.s	.Decr21
		move.l	(a2)+,d0
		addx.l	d0,d0
.Decr21		addx.w	d1,d1
		dbra	d3,.Decr20

		cmp.w	d5,d2
		bcs.s	.Decr36

		moveq	#0,d2
.Decr31		moveq	#0,d3
		moveq	#4-1,d4
.Decr32		add.l	d0,d0
		bne.s	.Decr33
		move.l	(a2)+,d0
		addx.l	d0,d0
.Decr33		addx.w	d3,d3
		dbra	d4,.Decr32

		add.l	d3,d2
		cmp.w	d6,d3
		beq.s	.Decr31

.Decr36		addq.l	#3,d2
		move.l	a0,a1
		sub.w	d1,a1
.Decr37		move.b	(a1)+,(a0)+
		cmp.l	a3,a0
		beq.s	.Exit
		subq.l	#1,d2
		bne.s	.Decr37
		bra	.Decr1
.Exit		rts

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

S_Stone400	dc.l	S_Stone400Data-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone400-Xfd68KHeader
		dc.w	XFDPFF_RELOC!XFDPFF_RELMODE
		dc.w	0
		dc.l	RB_Stone400-Xfd68KHeader
		dc.l	DB_Stone400-Xfd68KHeader
		dc.l	RS_Stone400-Xfd68KHeader
		dc.l	DS_Stone400-Xfd68KHeader
		dc.w	XFDID_StoneCracker400
		dc.w	0
		dc.l	$1f8+12+4

N_Stone400	dc.b	'StoneCracker 4.00',0
		even

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

RB_Stone400	BSR	xfdCodeBeginRecog
		TST.L	D0
		BEQ.B	.Exit

		cmp.l	#$4bfafff6,$38-$2c-8(a0)
		bne.s	.Exit
		cmp.l	#$49fa004c,$3c-$2c-8(a0)
		bne.s	.Exit
		cmp.l	#$53006af6,$92-$2c-8(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	xfdbi_SourceBuffer(a5),a0
		moveq	#1,d0
		add.l	16(a0),d0
		sub.l	12(a0),d0
		lsl.l	#2,d0
		lea	20(a0,d0.l),a0
				
		move.l	4(a0),d0
		lsl.l	#2,d0
		lea	8+4(a0,d0.l),a0	;first bss hunk

.NextBSS	cmp.l	#$3eb,(a0)+
		bne.s	.NoBSS
		addq.w	#8,a0
		bra.s	.NextBSS
		
.NoBSS		move.l	(a0)+,d0
		lsl.l	#2,d0
		lea	4(a0,d0.l),a0	;start of data hunk

		move.w	#XFDERR_BADHUNK,xfdbi_Error(a5)
		moveq	#0,d0
		cmp.l	#$3ea,(a0)+
		bne.s	.Exit
		addq.w	#4,a0
		move.l	a0,a2

		move.l	4(a0),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(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

		move.l	d0,a0
		move.l	(a2)+,d0
		bsr.s	D_Stone40x

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

D_Stone40x	cmp.l	#'S400',d0
		beq	D_Stone400
		cmp.l	#'S401',d0
		beq	D_Stone401
		rts

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

RS_Stone400	add.l	a0,a0
		add.l	a0,a0
		cmp.l	#($1a*4)+8,-4(a0)
		bne.s	.Exit

		cmp.l	#$4bfafff6,$8(a0)
		bne.s	.Exit
		cmp.l	#$49fa004c,$c(a0)
		bne.s	.Exit
		cmp.l	#$53006af6,$62(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	xfdsi_SegList(a5),a2
		clr.l	xfdsi_SegList(a5)
		add.l	a2,a2
		add.l	a2,a2

		moveq	#1,d2
		add.b	$11(a2),d2

		move.l	xfdm_ExecBase(a6),a6
.FreeNext	move.l	a2,a1
		move.l	(a2),a2
		add.l	a2,a2
		add.l	a2,a2
		move.l	-(a1),d0
		jsr	-210(a6)
		dbf	d2,.FreeNext

		lea	4(a2),a0	;dest
		move.l	8(a2),d1	;destlen
		movem.l	d1/a0/a2,-(a7)

		moveq	#12,d0
		add.l	12(a2),d0
		lea	4(a2,d0.l),a1
		add.l	-(a2),a2
.Copy		move.l	-(a1),-(a2)
		subq.l	#4,d0
		bne.s	.Copy

		move.l	(a2)+,d0
		bsr.w	D_Stone40x

		movem.l	(a7)+,d0/a0/a2
		lea	xfdsi_SegList(a5),a1
		move.w	xfdsi_RelMode(a5),d1
		move.l	10*4(a7),a6
		jsr	_LVOxfdRelocate(a6)
		moveq	#0,d1
		move.w	d0,xfdsi_Error(a5)
		bne.s	.FreeData
		moveq	#1,d1

.FreeData	move.l	d1,-(a7)
		move.l	a2,a1
		move.l	-(a1),d0
		move.l	xfdm_ExecBase(a6),a6
		jsr	-210(a6)
		move.l	(a7)+,d0

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

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

S_Stone400Data	dc.l	S_Stone401-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone400Data-Xfd68KHeader
		dc.w	XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_Stone400Data-Xfd68KHeader
		dc.l	DB_Stone400Data-Xfd68KHeader
		dc.l	SD_Stone400Data-Xfd68KHeader
		dc.l	VD_Stone310Data-Xfd68KHeader		;gleich
		dc.w	XFDID_StoneCracker400Data
		dc.w	0
		dc.l	4+12

N_Stone400Data	dc.b	'StoneCracker 4.00 Data',0
		even

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

RB_Stone400Data	moveq	#0,d0
		cmp.l	#'S400',(a0)
		bne.s	.Exit
		MOVE.L	4(A0),D0
		MOVE.L	D0,xfdrr_MinTargetLen(A1)
		MOVE.L	D0,xfdrr_FinalTargetLen(A1)
		MOVEQ	#$C,D0
		ADD.L	8(A0),D0
		MOVE.L	D0,xfdrr_MinSourceLen(A1)
		moveq	#1,d0
.Exit		rts

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

SD_Stone400Data	moveq	#0,d0
		cmp.l	#'S400',(a0)
		bne.s	.Exit
		moveq	#1,d0
.Exit		rts

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

DB_Stone400Data	movem.l	d2-d7/a2-a6,-(a7)
		MOVE.L	xfdbi_SourceBuffer(A0),A2
		MOVE.L	xfdbi_UserTargetBuf(A0),A0
		move.l	(a2)+,d0
		bsr	D_Stone40x
		moveq	#1,d0
		movem.l	(a7)+,d2-d7/a2-a6
		rts

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

S_Stone401	dc.l	S_Stone401Data-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone401-Xfd68KHeader
		dc.w	XFDPFF_RELOC!XFDPFF_RELMODE
		dc.w	0
		dc.l	RB_Stone401-Xfd68KHeader
		dc.l	DB_Stone400-Xfd68KHeader	;gleich
		dc.l	RS_Stone401-Xfd68KHeader
		dc.l	DS_Stone400-Xfd68KHeader	;gleich
		dc.w	XFDID_StoneCracker401
		dc.w	0
		dc.l	$1f8+12+4

N_Stone401	dc.b	'StoneCracker 4.01',0
		even

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

RB_Stone401	BSR	xfdCodeBeginRecog
		TST.L	D0
		BEQ.B	.Exit

		cmp.l	#$4bfafff6,$38-$2c-8(a0)
		bne.s	.Exit
		cmp.l	#$49fa004c,$3c-$2c-8(a0)
		bne.s	.Exit
		cmp.l	#$51c8fff8,$92-$2c-8(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

RS_Stone401	add.l	a0,a0
		add.l	a0,a0
		cmp.l	#($1a*4)+8,-4(a0)
		bne.s	.Exit

		cmp.l	#$4bfafff6,$8(a0)
		bne.s	.Exit
		cmp.l	#$49fa004c,$c(a0)
		bne.s	.Exit
		cmp.l	#$51c8fff8,$62(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

S_Stone401Data	dc.l	S_Stone401Addr-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone401Data-Xfd68KHeader
		dc.w	XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_Stone401Data-Xfd68KHeader
		dc.l	DB_Stone400Data-Xfd68KHeader	;gleich
		dc.l	SD_Stone401Data-Xfd68KHeader
		dc.l	VD_Stone310Data-Xfd68KHeader	;gleich
		dc.w	XFDID_StoneCracker401Data
		dc.w	0
		dc.l	4+12

N_Stone401Data	dc.b	'StoneCracker 4.01 Data',0
		even

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

RB_Stone401Data	BSR.B	SD_Stone401Data
		TST.L	D0
		beq.b	.Exit
		move.l	4(a0),xfdrr_MinTargetLen(a1)
		move.l	4(a0),xfdrr_FinalTargetLen(a1)
		MOVEQ	#$C,D1
		ADD.L	8(A0),D1
		MOVE.L	D1,xfdrr_MinSourceLen(A1)
.Exit		rts

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

SD_Stone401Data	MOVEQ	#0,D0
		MOVE.L	(A0),D1
		CMP.L	#'S401',D1
		BEQ.B	.ok
		AND.L	#$FFFFFF00,D1
		CMP.L	#$32414D00,D1
		BNE.B	.Exit
.ok		MOVEQ	#1,D0
.Exit		RTS

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

S_Stone401Addr	dc.l	S_Stone401BetaAddr-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone401Addr-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone401Addr-Xfd68KHeader
		dc.l	DB_Stone401Addr-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker401Addr
		dc.w	0
		dc.l	$14c+12+4

N_Stone401Addr	dc.b	'StoneCracker 4.01 Addr',0
		even

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

RB_Stone401Addr	cmp.l	#$21c90010,$4a(a0)
		bne.s	.Exit
		cmp.l	#$2e4049fa,$50(a0)
		bne.s	.Exit
		cmp.l	#$45fa00f0,$56(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

		move.l	xfdbi_SourceBuffer(a5),a2
		move.l	$14c(a2),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(a5)

		move.l	$32(a2),xfdbi_DecrAddress(a5)
		move.l	$144(a2),xfdbi_JmpAddress(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

		move.l	d0,a0
		lea	$14c(a2),a2
		bsr	D_Stone401

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

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

S_Stone401BetaAddr	dc.l	S_Stone403-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone401BetaAddr-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone401BetaAddr-Xfd68KHeader
		dc.l	DB_Stone401BetaAddr-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker401BetaAddr
		dc.w	0
		dc.l	$134+12+4

N_Stone401BetaAddr	dc.b	'StoneCracker 4.01ß Addr',0
		even

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

RB_Stone401BetaAddr
		cmp.l	#$21c90010,$4a(a0)
		bne.s	.Exit
		cmp.l	#$2e4049f9,$50(a0)
		bne.s	.Exit
		cmp.l	#$45fa00d0,$62(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

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

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

		move.l	$32(a2),xfdbi_DecrAddress(a5)
		move.l	$12c(a2),xfdbi_JmpAddress(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

		move.l	d0,a0
		lea	$134(a2),a2
		bsr	D_Stone401

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

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

D_Stone400	moveq	#2,d5
		moveq	#$f,d6
		moveq	#-1,d7
		move.l	(a2)+,a3
		move.l	(a2)+,d0
		add.l	a0,a3
		move.w	(a2)+,d0
		lsr.w	#1,d6
		addx.w	d0,d0
		bra.s	.Decr2

.Decr1		add.w	d0,d0
.Decr2		bne.s	.Decr3
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr3		bcs.s	.Decr11
		moveq	#-1,d3
.Decr4		moveq	#0,d2
		moveq	#2,d4
.Decr5		add.w	d0,d0
		bne.s	.Decr6
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr6		addx.w	d2,d2
		dbra	d4,.Decr5
		add.w	d2,d3
		cmp.w	d6,d2
		beq.s	.Decr4
.Decr7		moveq	#7,d4
.Decr8		add.w	d0,d0
		bne.s	.Decr9
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr9		addx.b	d2,d2
		dbra	d4,.Decr8
		move.b	d2,(a0)+
		cmp.l	a3,a0
		dbeq	d3,.Decr7
		cmp.w	d7,d3
		beq.s	.Decr1
		rts

.Decr40		dc.b	1,2,3,-1

.Decr11		moveq	#0,d2
		moveq	#1,d4
.Decr12		add.w	d0,d0
		bne.s	.Decr13
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr13		addx.w	d2,d2
		dbra	d4,.Decr12
		moveq	#0,d3
		moveq	#0,d1
		move.b	.Decr40(pc,d2.w),d3
		bmi.s	.Decr16
.Decr14		add.w	d0,d0
		bne.s	.Decr15
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr15		addx.w	d1,d1
		dbra	d3,.Decr14
.Decr16		moveq	#7,d4
.Decr17		add.w	d0,d0
		bne.s	.Decr18
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr18		addx.w	d1,d1
		dbra	d4,.Decr17
		cmp.w	d5,d2
		bcs.s	.Decr22
		moveq	#0,d2
.Decr19		moveq	#0,d3
		moveq	#2,d4
.Decr20		add.w	d0,d0
		bne.s	.Decr21
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr21		addx.w	d3,d3
		dbra	d4,.Decr20
		add.l	d3,d2
		cmp.w	d6,d3
		beq.s	.Decr19
.Decr22		addq.l	#2,d2
		move.l	a0,a1
		sub.w	d1,a1
.Decr23		move.b	(a1)+,(a0)+
		cmp.l	a3,a0
		beq.s	.Exit
		subq.l	#1,d2
		bpl.s	.Decr23
		bra	.Decr1
.Exit		rts

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

D_Stone401	moveq	#-1,d7
		move.l	(a2)+,a3
		move.l	(a2)+,d0
		add.l	a0,a3
		move.w	#$8000,d0
.Decr1		moveq	#0,d2
		add.w	d0,d0
		bne.s	.Decr2
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr2		bcs.s	.Decr9
		moveq	#0,d3
.Decr3		moveq	#2,d4
.Decr4		add.w	d0,d0
		bne.s	.Decr5
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr5		addx.w	d2,d2
		dbra	d4,.Decr4
		add.w	d2,d3
		subq.w	#7,d2
		beq.s	.Decr3
.Decr6		moveq	#7,d4
.Decr7		add.w	d0,d0
		bne.s	.Decr8
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr8		addx.b	d2,d2
		dbra	d4,.Decr7
		move.b	d2,(a0)+
		cmp.l	a3,a0
		dbeq	d3,.Decr6
		cmp.w	d7,d3
		beq.s	.Decr1
		rts

.Decr40		dc.b	1,2,3,-1

.Decr9		moveq	#1,d4
.Decr10		add.w	d0,d0
		bne.s	.Decr11
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr11		addx.w	d2,d2
		dbra	d4,.Decr10
		moveq	#8,d3
		moveq	#0,d1
		add.b	.Decr40(pc,d2.w),d3
.Decr12		add.w	d0,d0
		bne.s	.Decr13
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr13		addx.w	d1,d1
		dbra	d3,.Decr12
		subq.l	#2,d2
		bcs.s	.Decr17
		moveq	#-2,d2
		moveq	#0,d3
.Decr14		moveq	#2,d4
.Decr15		add.w	d0,d0
		bne.s	.Decr16
		move.w	(a2)+,d0
		addx.w	d0,d0
.Decr16		addx.w	d3,d3
		dbra	d4,.Decr15
		add.l	d3,d2
		subq.w	#7,d3
		beq.s	.Decr14
.Decr17		addq.l	#4,d2
		move.l	a0,a1
		sub.w	d1,a1
.Decr18		move.b	(a1)+,(a0)+
		cmp.l	a3,a0
		beq.s	.Exit
		subq.l	#1,d2
		bpl.s	.Decr18
		bra	.Decr1
.Exit		rts

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

S_Stone403	dc.l	S_Stone403Data-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone403-Xfd68KHeader
		dc.w	XFDPFF_RELOC!XFDPFF_RELMODE
		dc.w	0
		dc.l	RB_Stone403-Xfd68KHeader
		dc.l	DB_Stone403-Xfd68KHeader
		dc.l	RS_Stone403-Xfd68KHeader
		dc.l	DS_Stone403-Xfd68KHeader
		dc.w	XFDID_StoneCracker403
		dc.w	0
		dc.l	$1e8+16+12

N_Stone403	dc.b	'StoneCracker 4.03',0
		even

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

RB_Stone403	cmp.l	#$487a0048,$24(a0)
		bne.s	.Exit
		cmp.l	#$4ea90004,$36(a0)
		bne.s	.Exit
		cmp.l	#$4bfa0152,$82(a0)
		bne.s	.Exit
		;cmp.l	#'S403',$1e8(a0)
		;bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DB_Stone403	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		move.l	xfdbi_SourceBuffer(a5),a3
		add.w	#$1f0,a3

		move.l	(a3),d0
		move.l	d0,d4

		moveq	#1,d1
		move.l	xfdm_ExecBase(a6),a6
		jsr	-198(a6)
		move.w	#XFDERR_NOMEMORY,xfdbi_Error(a5)
		tst.l	d0
		beq	DB_S404_Exit
		move.l	d0,a4

		move.l	a4,a0
		move.l	a3,a1
		bsr.w	D_Stone403

		bra	DB_Stone403Common

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

RS_Stone403	add.l	a0,a0
		add.l	a0,a0

		cmp.l	#($13*4)+8,-4(a0)
		bne.s	.Exit
		cmp.l	#$487a0048,$4(a0)
		bne.b	.Exit
		cmp.l	#$4ea90004,$16(a0)
		bne.b	.Exit
		move.l	(a0),d0
		beq.b	.Exit
		lsl.l	#2,d0
		move.l	d0,a0
		cmp.l	#$4bfa0152,$a(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DS_Stone403	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		move.l	xfdsi_SegList(a5),a4
		clr.l	xfdsi_SegList(a5)

		move.l	a4,a0
		add.l	a0,a0
		add.l	a0,a0
		move.l	(a0),a0
		add.l	a0,a0
		add.l	a0,a0
		add.w	#$1e8-$78,a0

		lea	4(a0),a1
		add.l	(a1)+,a0
		move.l	a0,-(a7)
		bsr.w	D_Stone403
		move.l	(a7)+,a2

		bra	DS_Stone403Common

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

S_Stone403Data	dc.l	S_Stone404-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone403Data-Xfd68KHeader
		dc.w	XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_Stone403Data-Xfd68KHeader
		dc.l	DB_Stone403Data-Xfd68KHeader
		dc.l	SD_Stone403Data-Xfd68KHeader
		dc.l	VD_Stone403Data-Xfd68KHeader		;gleich
		dc.w	XFDID_StoneCracker403Data
		dc.w	0
		dc.l	16+4

N_Stone403Data	dc.b	'StoneCracker 4.03 Data',0
		even

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

RB_Stone403Data	BSR.B	SD_Stone403Data
		TST.L	D0
		BEQ.B	.Exit
		move.l	8(a0),xfdrr_MinTargetLen(a1)
		move.l	8(a0),xfdrr_FinalTargetLen(a1)
		MOVEQ	#18,D0
		ADD.L	12(A0),D0
		MOVE.L	D0,xfdrr_MinSourceLen(A1)
		moveq	#1,d0
.Exit		rts

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

SD_Stone403Data	moveq	#0,d0
		cmp.l	#'Z&G!',(a0)
		beq.b	.ok
		cmp.l	#'ZULU',(a0)
		beq.b	.ok
		cmp.l	#'S403',(a0)
		bne.s	.Exit
.ok		moveq	#1,d0
.Exit		rts

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

VD_Stone403Data	moveq	#20,d1
		add.l	12(a0),d1	;crlen
		cmp.l	d0,d1		;crlen > buflen ??
		bgt.s	.Exit
		move.l	8(a0),d0
		sub.l	12(a0),d0	;cr > uncr ??
		bmi.s	.Exit
		move.l	d1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DB_Stone403Data	movem.l	d2-d7/a2-a6,-(a7)
		MOVE.L	xfdbi_SourceBuffer(A0),A3
		MOVE.L	xfdbi_UserTargetBuf(A0),A0
		lea	8(a3),a1
		bsr.b	D_Stone403
		moveq	#1,d0
		movem.l	(a7)+,d2-d7/a2-a6
		rts

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


* a1: data
* a0: dest

D_Stone403	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,d4
		add.l	(a1)+,a0
		add.l	(a1)+,a1
		moveq	#0,d7
		move.w	(a1),d6
		moveq	#$10,d5
		move.w	-(a1),d7
.lbC000968	dbra	d6,.lbC000970
		move.w	-(a1),d7
		moveq	#$F,d6
.lbC000970	lsr.w	#1,d7
		bcs.s	.lbC0009B4
		move.w	d6,d0
		subq.w	#8,d6
		bpl.s	.lbC000984
		move.w	d7,d3
		move.w	-(a1),d7
		add.w	d5,d6
		lsl.l	d0,d7
		or.w	d3,d7
.lbC000984	move.b	d7,-(a0)
		lsr.l	#8,d7
		cmp.l	a0,d4
		bcs.s	.lbC000968
		movem.l	(a7)+,d2-d7/a2-a6
		rts

.lbW000994	dc.w	5
		dc.w	$1F
		dc.w	1
		dc.w	0

		dc.w	8
		dc.w	$FF
		dc.w	$21
		dc.w	0

		dc.w	$A
		dc.w	$3FF
		dc.w	$121
		dc.w	0

		dc.w	$C
		dc.w	$FFF
		dc.w	$521
		dc.w	0

.lbC0009B4	move.w	d6,d0
		moveq	#3,d2
		subq.w	#2,d6
		bpl.s	.lbC0009C4
		lsr.w	d0,d7
		move.w	-(a1),d7
		roxl.l	d0,d7
		add.w	d5,d6
.lbC0009C4	and.w	d7,d2
		lsl.w	#3,d2
		move.w	d6,d0
		movem.w	.lbW000994(pc,d2.w),d1/d2/a2
		lsr.l	#2,d7
		sub.w	d1,d6
		bpl.s	.lbC0009E0
		move.w	d7,d3
		move.w	-(a1),d7
		add.w	d5,d6
		lsl.l	d0,d7
		or.w	d3,d7
.lbC0009E0	and.w	d7,d2
		add.l	a0,a2
		lsr.l	d1,d7
		add.w	d2,a2
		dbra	d6,.lbC0009F0
		move.w	-(a1),d7
		moveq	#$F,d6
.lbC0009F0	lsr.w	#1,d7
		bcs.s	.lbC000A34
		dbra	d6,.lbC0009FC
		move.w	-(a1),d7
		moveq	#$F,d6
.lbC0009FC	lsr.w	#1,d7
		bcs.s	.lbC000A32
		dbra	d6,.lbC000A08
		move.w	-(a1),d7
		moveq	#$F,d6
.lbC000A08	lsr.w	#1,d7
		bcs.s	.lbC000A30
		moveq	#0,d1
.lbC000A0E	move.w	d6,d0
		moveq	#7,d2
		subq.w	#3,d6
		bpl.s	.lbC000A20
		move.w	d7,d3
		move.w	-(a1),d7
		add.w	d5,d6
		lsl.l	d0,d7
		or.w	d3,d7
.lbC000A20	and.w	d7,d2
		lsr.l	#3,d7
		add.w	d2,d1
		subq.w	#7,d2
		beq.s	.lbC000A0E
.lbC000A2A	move.b	-(a2),-(a0)
		dbra	d1,.lbC000A2A
.lbC000A30	move.b	-(a2),-(a0)
.lbC000A32	move.b	-(a2),-(a0)
.lbC000A34	move.b	-(a2),-(a0)
		move.b	-(a2),-(a0)
		cmp.l	a0,d4
		bcs	.lbC000968
		movem.l	(a7)+,d2-d7/a2-a6
		rts

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

S_Stone404	dc.l	S_Stone404Lib-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone404-Xfd68KHeader
		dc.w	XFDPFF_RELOC!XFDPFF_RELMODE
		dc.w	0
		dc.l	RB_Stone404-Xfd68KHeader
		dc.l	DB_Stone404-Xfd68KHeader
		dc.l	RS_Stone404-Xfd68KHeader
		dc.l	DS_Stone404-Xfd68KHeader
		dc.w	XFDID_StoneCracker404
		dc.w	0
		dc.l	$200+16+12

N_Stone404	dc.b	'StoneCracker 4.04',0
		even

S_Stone404Lib	dc.l	S_Stone404Data-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone404Lib-Xfd68KHeader
		dc.w	XFDPFF_RELOC!XFDPFF_RELMODE
		dc.w	0
		dc.l	RB_Stone404Lib-Xfd68KHeader
		dc.l	DB_Stone404-Xfd68KHeader
		dc.l	RS_Stone404Lib-Xfd68KHeader
		dc.l	DS_Stone404-Xfd68KHeader
		dc.w	XFDID_StoneCracker404Lib
		dc.w	0
		dc.l	$108+16+12

N_Stone404Lib	dc.b	'StoneCracker 4.04 Library',0
		even


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

RB_Stone404	MOVEQ	#0,D0
		cmp.l	#$4e714e71,$24(a0)	; virus hiding
		bne.b	.next
		addq.l	#4,A0
.next		cmp.l	#$487a0048,$24(a0)
		bne.s	.Exit
		cmp.l	#$4eab0004,$36(a0)
		bne.s	.Exit
		cmp.l	#$45fa0186,$78(a0)
		bne.s	.Exit
		;cmp.l	#'S404',$200(a0)
		;bne.s	.Exit
		moveq	#1,d0
.Exit		rts

RB_Stone404Lib	MOVEQ	#0,D0
		cmp.l	#$487a0018,$24(a0)
		bne.s	.LibNew
		cmp.l	#$4eab0012,$36(a0)
		bne.s	.LibNew
		cmp.l	#'stc.',$48(a0)
		bne.s	.LibNew
		cmp.l	#'S404',$70(a0)
		bne.s	.LibNew
		moveq	#2,d0
		rts

.LibNew		;cmp.l	#$108+16+12,d0	;header,data,end
		;ble.s	.Exit
		cmp.l	#$487a0018,$24(a0)
		bne.s	.Exit
		cmp.l	#$4eab003a,$36(a0)
		bne.s	.Exit
		cmp.l	#' stc',$52(a0)
		bne.s	.Exit
		cmp.l	#'S404',$108(a0)
		bne.s	.Exit
		moveq	#3,d0
.Exit		rts

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

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

		move.l	xfdbi_SourceBuffer(a5),a0
		move.l	xfdbi_SourceBufLen(a5),d0
		BSR.W	RB_Stone404
		TST.L	D0
		BNE.B	.NoLib
		BSR.B	RB_Stone404Lib

.NoLib		move.l	a0,a3
		move.w	#$208,d1
		subq.w	#1,d0
		beq.s	.OffsetOk
		moveq	#$78,d1
		subq.w	#1,d0
		beq.s	.OffsetOk
		move.w	#$110,d1
.OffsetOk	add.w	d1,a3

		move.l	(a3),d0
		move.l	d0,d4

		moveq	#1,d1
		move.l	xfdm_ExecBase(a6),a6
		jsr	-198(a6)
		move.w	#XFDERR_NOMEMORY,xfdbi_Error(a5)
		tst.l	d0
		beq	DB_S404_Exit
		move.l	d0,a4

		move.l	a4,a0
		move.l	a3,a1
		bsr	D_Stone404

DB_Stone403Common
		moveq	#20,d7	;3f3,0,x,0,x-1
		move.l	a4,a0
		move.l	(a0)+,d0

		move.l	d0,d1
		and.l	#$fffffc00,d1	; check if more than 1023 hunks
		beq.s	.HunksOk	; => very likely to be corrupt
		move.w	#XFDERR_CORRUPTEDDATA,xfdbi_Error(a5)
		moveq	#0,d0
		bra	.ExitFree

.HunksOk	addq.l	#1,d0
		lsl.l	#2,d0
		add.l	d0,a0	;first hunk
		lsl.l	#2,d0
		add.l	d0,d7	;hunklen,type,len,end

.CountNext	move.w	(a0)+,d0
		btst	#14,d0
		beq.s	.CountNoCode
		swap	d0	;code,data
		move.w	(a0)+,d0
		lsl.l	#2,d0
		add.l	d0,a0
		add.l	d0,d7
		bra.s	.CountTest

.CountNoCode	tst.w	d0	;bss
		bne.s	.CountTest

		addq.l	#8,d7	;3ec,0

.CountNextRel	move.w	a0,d0		;reloc
		lsr.w	#1,d0
		bcc.s	.CountEven
		addq.w	#1,a0
.CountEven
		moveq	#0,d1
		move.w	(a0)+,d1	;amount
		beq.s	.CountTest
		addq.w	#2,a0		;hunknum
		addq.l	#8,d7		;amount,hunknum
		move.l	d1,d0
		lsl.l	#2,d0
		add.l	d0,d7		;relocs

		move.b	(a0),d0
		addq.w	#4,a0
		moveq	#3,d2
		cmp.b	#2,d0
		beq.s	.CountRelOff
		moveq	#2,d2
		cmp.b	#6,d0
		ble.s	.CountRelOff
		moveq	#1,d2
.CountRelOff	subq.w	#1,d1
		mulu	d1,d2
		add.l	d2,a0
		bra.s	.CountNextRel

.CountTest	cmp.w	#-1,(a0)
		bne.s	.CountNext

		move.l	d7,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	.ExitFree

		move.l	a4,a0
		move.l	d0,a1

		move.l	#$3f3,(a1)+
		clr.l	(a1)+
		move.l	(a0),d0
		addq.l	#1,d0
		move.l	d0,(a1)+
		clr.l	(a1)+
		move.l	(a0)+,(a1)+
		move.l	a1,a2
.CopyLens	move.l	(a0)+,(a1)+
		subq.l	#1,d0
		bne.s	.CopyLens

.CopyNext	move.w	(a0)+,d0
		bclr	#14,d0
		beq.s	.CopyNoCode
		swap	d0	;code,data
		move.w	(a0)+,d0
		move.l	#$3e9,d1
		bclr	#31,d0
		beq.s	.CopyNoData
		addq.w	#1,d1
.CopyNoData	move.l	d1,(a1)+
		move.l	d0,(a1)+
		beq.s	.CopyCodeEmpty
.CopyCode	move.l	(a0)+,(a1)+
		subq.l	#1,d0
		bne.s	.CopyCode
.CopyCodeEmpty	addq.w	#4,a2
		bra.s	.CopyTest

.CopyNoCode	tst.w	d0	;bss
		beq.s	.CopyReloc
		move.l	#$3eb,(a1)+
		move.l	(a2)+,d0
		and.l	#$3fffffff,d0
		move.l	d0,(a1)+
		bra.s	.CopyTest

.CopyReloc	subq.w	#4,a1	;wegen end
		move.l	#$3ec,(a1)+

.CopyNextRel	move.w	a0,d0		;reloc
		lsr.w	#1,d0
		bcc.s	.CopyEven
		addq.w	#1,a0
.CopyEven
		moveq	#0,d1
		move.w	(a0)+,d1
		move.l	d1,(a1)+	;amount
		beq.s	.CopyTest
		moveq	#0,d0
		move.w	(a0)+,d0
		move.l	d0,(a1)+	;hunknum

		moveq	#0,d2
		move.b	(a0),d2
		move.l	(a0)+,d3
		and.l	#$00ffffff,d3
		bra.s	.CopyFirstRel

.CopyAddRel	moveq	#0,d0
		jmp	.CopyAddRel2-2(pc,d2.w)
.CopyAddRel2	move.b	(a0)+,d0
		lsl.w	#8,d0
		move.b	(a0)+,d0
		lsl.l	#8,d0
		move.b	(a0)+,d0
		add.l	d0,d3
.CopyFirstRel	move.l	d3,(a1)+
		subq.w	#1,d1
		bne.s	.CopyAddRel
		bra.s	.CopyNextRel

.CopyTest	move.l	#$3f2,(a1)+
		cmp.w	#-1,(a0)
		bne	.CopyNext

		moveq	#1,d0

.ExitFree	move.l	d0,-(a7)
		move.l	d4,d0
		move.l	a4,a1
		jsr	-210(a6)
		move.l	(a7)+,d0

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

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

RS_Stone404	add.l	a0,a0
		add.l	a0,a0

		cmp.l	#($13*4)+8,-4(a0)
		BNE.B	.Exit
		cmp.l	#$487a0048,$4(a0)
		BNE.B	.Exit
		cmp.l	#$4eab0004,$16(a0)
		BNE.B	.Exit
		move.l	(a0),d0
		BEQ.B	.Exit
		lsl.l	#2,d0
		move.l	d0,a0
		cmp.l	#$45fa0186,$4(a0)
		BNE.B	.Exit
		add.w	#$200-$74,a0
		;cmp.l	#'S404',(a0)
		;bne.b	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

RS_Stone404Lib	add.l	a0,a0
		add.l	a0,a0

RS_Stone404Lib2 cmp.l	#($7*4)+8,-4(a0)
		bne.s	.Exit
		cmp.l	#$487a0018,$4(a0)
		bne.s	.Exit
		cmp.l	#$4eab0012,$16(a0)
		bne.s	.LibNew
		move.l	(a0),d0
		beq.s	.Exit
		lsl.l	#2,d0
		move.l	d0,a0
		cmp.l	#'stc.',$4(a0)
		bne.s	.Exit
		add.w	#$70-$44,a0
		cmp.l	#'S404',(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.LibNew		cmp.l	#$4eab003a,$16(a0)
		bne.s	.Exit
		move.l	(a0),d0
		beq.s	.Exit
		lsl.l	#2,d0
		move.l	d0,a0
		cmp.l	#' stc',$e(a0)
		bne.s	.Exit
		add.w	#$108-$44,a0
		cmp.l	#'S404',(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DS_Stone404	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		move.l	xfdsi_SegList(a5),a4

		move.l	a4,a0
		BSR.W	RS_Stone404
		TST.L	D0
		BNE.B	.NoLib
		BSR.W	RS_Stone404Lib2
.NoLib		move.w	#XFDERR_CORRUPTEDDATA,xfdsi_Error(a5)
		tst.l	d0
		beq	DS_S404_Exit

		clr.l	xfdsi_SegList(a5)

		lea	4(a0),a1
		add.l	(a1)+,a0
		move.l	a0,-(a7)
		bsr	D_Stone404
		move.l	(a7)+,a2

DS_Stone403Common
		add.l	a4,a4	;first hunk
		add.l	a4,a4
		moveq	#-1,d0
		bsr	.GetHunk
		lea	-4(a1),a3

		move.l	(a2)+,d7
		move.l	d7,d1
		and.l	#$fffffc00,d1	; check if more than 1023 hunks
		beq.s	.HunksOk	; => very likely to be corrupt
		move.w	#XFDERR_CORRUPTEDDATA,xfdsi_Error(a5)
		moveq	#0,d0
		bra	.FreeSeg

.HunksOk	move.l	xfdm_ExecBase(a6),a6
		move.w	#XFDERR_NOMEMORY,xfdsi_Error(a5)
		move.w	xfdsi_RelMode(a5),d6

.AllocNext	cmp.w	#XFDREL_DEFAULT,d6
		beq.s	.AllocDefault
		move.l	#$10003,d1
		cmp.w	#XFDREL_FORCECHIP,d6
		beq.s	.AllocChipFast
		move.l	#$10005,d1
		cmp.w	#XFDREL_FORCEFAST,d6
		beq.s	.AllocChipFast
		move.w	#XFDERR_BADRELMODE,xfdsi_Error(a5)
		moveq	#0,d0
		bra	.FreeSeg
.AllocDefault	moveq	#1,d1
		swap	d1
		move.w	(a2),d1
		rol.w	#3,d1
		and.w	#$0006,d1
		or.w	#$0001,d1
.AllocChipFast	move.l	(a2)+,d0
		addq.l	#2,d0
		lsl.l	#2,d0
		move.l	d0,d3
		jsr	-198(a6)
		move.l	d0,d1
		lsr.l	#2,d0
		move.l	d0,(a3)
		beq	.FreeSeg
		addq.l	#1,(a3)
		move.l	d1,a3
		move.l	d3,(a3)+
		dbf	d7,.AllocNext

		moveq	#-1,d6
		lsr.l	#8,d6
.Continue	move.w	(a2)+,d1
		bne.s	.NoReloc
.NextReloc	move.w	a2,d0
		lsr.w	#1,d0
		bcc.s	.Even
		addq.w	#1,a2
.Even		move.w	(a2)+,d1
		beq.s	.CheckEnd
		move.w	(a2)+,d0
		bsr.s	.GetHunk
		move.l	a1,d0
		MOVEQ	#0,D2			* Harry Sintonen
		move.b	(a2),d2
		move.l	(a2)+,d3
		and.l	d6,d3
		bra.s	.StartReloc
.NextOffset	moveq	#0,d4
		jmp	.Jump-2(pc,d2.w)
.Jump		move.b	(a2)+,d4
		lsl.w	#8,d4
		move.b	(a2)+,d4
		lsl.l	#8,d4
		move.b	(a2)+,d4
		add.l	d4,d3
.StartReloc	add.l	d0,(a0,d3.l)
		subq.w	#1,d1
		bne.s	.NextOffset
		bra.s	.NextReloc

.GetHunk	move.l	a4,a1
		addq.w	#1,d0
.GetHunk1	move.l	(a1),a1
		add.l	a1,a1
		add.l	a1,a1
		dbra	d0,.GetHunk1
		addq.w	#4,a1
		rts

.NoReloc	addq.w	#1,d7
		swap	d1
		btst	#30,d1
		beq.s	.CheckEnd
		move.w	(a2)+,d1
		lsl.l	#2,d1
		beq.s	.CheckEnd
		move.w	d7,d0
		bsr.s	.GetHunk
		move.l	a1,a0
		bra.s	.StartCopy
.Copy		move.l	(a2)+,(a1)+
.StartCopy	subq.l	#4,d1
		bpl.s	.Copy

.CheckEnd	cmp.w	(a2),d6
		bne.s	.Continue

		moveq	#-1,d0
		bsr.s	.GetHunk
		move.l	-(a1),xfdsi_SegList(a5)
		clr.l	(a1)
		moveq	#1,d0

.FreeSeg	move.l	d0,-(a7)
		move.l	a4,d1
		lsr.l	#2,d1
		move.l	(10+1)*4(a7),a0
		move.l	xfdm_DosBase(a0),a6
		jsr	-156(a6)
		move.l	(a7)+,d0

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

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

S_Stone404Data	dc.l	S_Stone404Addr-Xfd68KHeader
		dc.w	2
		dc.w	39
		dc.l	N_Stone404Data-Xfd68KHeader
		dc.w	XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET
		dc.w	0
		dc.l	RB_Stone404Data-Xfd68KHeader
		dc.l	DB_Stone404Data-Xfd68KHeader
		dc.l	SD_Stone404Data-Xfd68KHeader
		dc.l	VD_Stone404Data-Xfd68KHeader
		dc.w	XFDID_StoneCracker404Data
		dc.w	0
		dc.l	16+4

N_Stone404Data	dc.b	'StoneCracker 4.04 Data',0
		even

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

RB_Stone404Data	BSR.B	SD_Stone404Data
		TST.L	D0
		BEQ.B	.Exit
		TST.B	8(A0)
		BNE.B	.Exit
		TST.B	12(A0)
		BNE.B	.Exit
		move.l	8(a0),xfdrr_MinTargetLen(a1)
		move.l	8(a0),xfdrr_FinalTargetLen(a1)
		MOVEQ	#18,D0
		ADD.L	12(A0),D0
		MOVE.L	D0,xfdrr_MinSourceLen(A1)
		moveq	#1,d0
		rts
.Exit		MOVEQ	#0,D0
		RTS

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

SD_Stone404Data	moveq	#0,d0
		cmp.l	#'S404',(a0)
		beq.s	.Ok
		CMP.L	#'SLAM',(A0)
		BEQ.B	.Ok
		CMP.L	#'AYS!',(A0)
		BEQ.B	.Ok
		CMP.L	#'PTN!',(A0)
		BEQ.B	.Ok
		CMP.L	#'Pack',(A0)
		BNE.B	.Exit
.Ok		moveq	#1,d0
.Exit		rts

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

VD_Stone404Data	moveq	#18,d1
		add.l	12(a0),d1	;crlen
		cmp.l	d0,d1		;crlen > buflen ??
		bgt.s	.Exit
		move.l	8(a0),d0
		sub.l	12(a0),d0	;cr > uncr ??
		bmi.s	.Exit
		move.l	d1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

DB_Stone404Data	movem.l	d2-d7/a2-a6,-(a7)
		MOVE.L	xfdbi_SourceBuffer(A0),A3
		MOVE.L	xfdbi_UserTargetBuf(A0),A0
		lea	8(a3),a1
		bsr	D_Stone404
		moveq	#1,d0
		movem.l	(a7)+,d2-d7/a2-a6
		rts

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

S_Stone404Addr	
		IFND	XFD_LASTSLAVE
		dc.l	S_Stone_END-Xfd68KHeader
		ELSE
		dc.l	0
		ENDIF
		dc.w	2
		dc.w	39
		dc.l	N_Stone404Addr-Xfd68KHeader
		dc.w	XFDPFF_ADDR
		dc.w	0
		dc.l	RB_Stone404Addr-Xfd68KHeader
		dc.l	DB_Stone404Addr-Xfd68KHeader
		dc.l	0
		dc.l	0
		dc.w	XFDID_StoneCracker404Addr
		dc.w	0
		dc.l	$1a4+16+12

N_Stone404Addr	dc.b	'StoneCracker 4.04 Addr',0
		even

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

RB_Stone404Addr	cmp.l	#$4e7bc801,$56(a0)
		BNE.B	.Plain
		cmp.l	#$43fa0012,$74(a0)
		BNE.B	.Exit
		cmp.l	#$4c9100c4,$b6(a0)
		BNE.B	.Exit
		cmp.l	#'S404',$1A4(a0)
		BNE.B	.Exit
		MOVEQ	#1,D0
		rts

.Plain		CMP.L	#$4E7145F9,(A0)
		BNE.B	.Normal
		CMP.L	#$43FA00E2,8(A0)
		BNE.B	.Exit
		CMP.L	#$4C9100C4,$16(A0)
		BNE.B	.Exit
		CMP.L	#'S404',$E4(A0)
		MOVEQ	#2,D0
		RTS

.Normal		cmp.l	#$4e7145f9,$20(a0)
		bne.s	.Exit
		cmp.l	#$43fa00f2,$28(a0)
		bne.s	.Exit
		cmp.l	#$4c9100c4,$36(a0)
		bne.s	.Exit
		cmp.l	#'S404',$114(a0)
		bne.s	.Exit
		MOVEQ	#3,D0
		RTS

.Exit		moveq	#0,d0
		rts

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

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

		move.l	xfdbi_SourceBuffer(a5),a3
		move.l	a3,a0
		move.l	xfdbi_SourceBufLen(a5),d0
		BSR.W	RB_Stone404Addr
		SUBQ.W	#1,D0
		BEQ.B	.KillSys
		SUBQ.W	#1,D0
		BEQ.B	.Plain
		move.l	$24(a3),xfdbi_DecrAddress(a5)
		move.l	$110(a3),xfdbi_JmpAddress(a5)
		lea	$11c(a3),a3
		BRA.B	.Common

.Plain		MOVE.L	$4(A3),xfdbi_DecrAddress(A5)
		MOVE.L	$E0(A3),xfdbi_JmpAddress(A5)
		LEA	$EC(A3),A3
		BRA.B	.Common

.KillSys	move.l	$8a(a3),xfdbi_DecrAddress(a5)
		move.l	$186(a3),xfdbi_JmpAddress(a5)
		lea	$1ac(a3),a3

.Common		move.l	(a3),d0
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	d0,xfdbi_TargetBufLen(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

		move.l	d0,a0
		move.l	a3,a1
		bsr.b	D_Stone404

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

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

* a1: data
* a0: dest

D_Stone404	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a5
		add.l	(a1)+,a0
		add.l	(a1),a1
		moveq	#0,d4
		moveq	#$10,d5
		movem.w	(a1),d2/d6/d7
		not.w	d4
		lea	.lbC000AF4(pc),a3
		lea	.lbC000AE8(pc),a4
		moveq	#1,d0
		moveq	#-1,d3
		bra.s	.lbC000A8C

		cnop	0,4

.lbC000A68	subq.w	#8,d7
		bpl.s	.lbC000A88
		move.w	d7,d1
		addq.w	#8,d7
		lsl.l	d7,d6
		move.w	-(a1),d6
		neg.w	d1
		lsl.l	d1,d6
		addq.w	#8,d7
		swap	d6
		move.b	d6,-(a0)
		swap	d6
		cmp.l	a0,a5
		dbcc	d7,.lbC000A98
		bra.s	.lbC000A92

.lbC000A88	rol.w	#8,d6
		move.b	d6,-(a0)
.lbC000A8C	cmp.l	a0,a5
		dbcc	d7,.lbC000A98
.lbC000A92	bcc.s	.end
.lbC000A94	move.w	-(a1),d6
		moveq	#$F,d7
.lbC000A98	add.w	d6,d6
		bcc.s	.lbC000A68
		dbra	d7,.lbC000AA4
		move.w	-(a1),d6
		moveq	#$F,d7
.lbC000AA4	add.w	d6,d6
		bcs.s	.lbC000B08
		dbra	d7,.lbC000AB0
		move.w	-(a1),d6
		moveq	#$F,d7
.lbC000AB0	moveq	#2,d1
		moveq	#2,d3
		add.w	d6,d6
		bcs.s	.lbC000AE4
		dbra	d7,.lbC000AC0
		move.w	-(a1),d6
		moveq	#$F,d7
.lbC000AC0	add.w	d6,d6
		bcc.s	.lbC000AE0
		moveq	#4,d1
		moveq	#6,d3
		lea	.lbC000ACE(pc),a6
		bra.s	.lbC000B40

.lbC000ACE	add.w	d1,d3
		cmp.w	#$F,d1
		bcs.s	.lbC000B14
		moveq	#5,d1
		moveq	#$E,d3
		lea	.lbC000B7A(pc),a6
		bra.s	.lbC000B40

.lbC000AE0	moveq	#$15,d3
.lbC000AE2	moveq	#8,d1
.lbC000AE4	move.l	a4,a6
		bra.s	.lbC000B40

.lbC000AE8	add.w	d1,d3
		not.b	d1
		dbeq	d7,.lbC000B1C
		bne.s	.lbC000B18
		beq.s	.lbC000AE2
.lbC000AF4	add.w	d1,a2
		move.b	(a2),-(a0)
		cmp.l	a0,a5		*SDI
		bcc.b	.end		*SDI
.lbC000AF8	move.b	-(a2),-(a0)
		cmp.l	a0,a5		*SDI
		dbcc	d3,.lbC000AF8	*SDI (was DBRA)
.lbC000AFE	cmp.l	a0,a5
		dbcc	d7,.lbC000A98
		bcs.s	.lbC000A94
.end		movem.l	(a7)+,d2-d7/a2-a6
		rts

.lbC000B08	dbra	d7,.lbC000B10
		move.w	-(a1),d6
		moveq	#$F,d7
.lbC000B10	add.w	d6,d6
		addx.w	d0,d3
.lbC000B14	dbra	d7,.lbC000B1C
.lbC000B18	move.w	-(a1),d6
		moveq	#$F,d7
.lbC000B1C	add.w	d6,d6
		bcs.s	.lbC000B38
		dbra	d7,.lbC000B28
		move.w	-(a1),d6
		moveq	#$F,d7
.lbC000B28	moveq	#9,d1
		lea	$20(a0),a2
		add.w	d6,d6
		bcc.s	.lbC000B3E
		moveq	#5,d1
		move.l	a0,a2
		bra.s	.lbC000B3E

.lbC000B38	lea	$220(a0),a2
		move.w	d2,d1
.lbC000B3E	move.l	a3,a6
.lbC000B40	and.l	d4,d6
		sub.w	d1,d7
		bpl.s	.lbC000B52
		add.w	d7,d1
		lsl.l	d1,d6
		move.w	d7,d1
		move.w	-(a1),d6
		neg.w	d1
		add.w	d5,d7
.lbC000B52	lsl.l	d1,d6
		move.l	d6,d1
		swap	d1
		jmp	(a6)

.lbC000B5A	moveq	#-1,d3
		bra	.lbC000A88

.lbC000B60	rol.w	#8,d6
		move.b	d6,-(a0)
		cmp.l	a0,a5		*SDI
		bcc.b	.end		*SDI
.lbC000B64	lsl.l	d7,d6
		move.w	-(a1),d6
		lsl.l	d1,d6
		swap	d6
		move.b	d6,-(a0)
		cmp.l	a0,a5		*SDI
		bcc.b	.end		*SDI
		swap	d6
		subq.w	#2,d3
		bgt.s	.lbC000B60
		beq.s	.lbC000B5A
		addq.w	#8,d7
		bra.w	.lbC000AFE

.lbC000B7A	add.w	d1,d3
		move.b	.lbB000B88(pc,d7.w),d1
		bpl.s	.lbC000B64
		subq.w	#8,d7
		dbra	d3,.lbC000B60

.lbB000B88	dc.b	$08,$07,$06,$05,$04,$03,$02,$01
		dc.b	$88,$87,$86,$85,$84,$83,$82,$81

S_Stone_END

