*****************************************************************************
*   $Id: Ultimate.a,v 1.2 2005/06/23 14:39:16 stoecker Exp $
*   Ultimate Packer 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_Ult11
		IFND	XFD_LASTSLAVE
		dc.l	S_Ult_END-Xfd68KHeader
		ELSE
		dc.l	0
		ENDIF
		dc.w	2
		dc.w	39
		dc.l	N_Ult11-Xfd68KHeader
		dc.w	XFDPFF_RELOC!XFDPFF_RELMODE
		dc.w	0
		dc.l	RB_Ult11-Xfd68KHeader
		dc.l	DB_Ult11-Xfd68KHeader
		dc.l	RS_Ult11-Xfd68KHeader
		dc.l	DS_Ult11-Xfd68KHeader
		dc.w	XFDID_UltimatePacker11
		dc.w	0
		dc.l	$2d8+4

N_Ult11		dc.b	'Ultimate Packer 1.1',0
		even

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

RB_Ult11	cmp.w	#$abcd,$26(a0)
		bne.s	.Exit
		cmp.w	#$03f6,$2d6(a0)
		bne.s	.Exit

		cmp.l	#$47ed0214,$94(a0)
		bne.s	.Exit
		cmp.l	#$45ed0214,$9c(a0)
		bne.s	.Exit
		cmp.l	#$3f045884,$2b2(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

Ult_BufferInfo	SET	xfdBufferInfo_SIZE
Ult_MemType	SET	xfdBufferInfo_SIZE+4
Ult_Code	SET	xfdBufferInfo_SIZE+8
Ult_Relocs	SET	xfdBufferInfo_SIZE+$c
Ult_Temp0	SET	xfdBufferInfo_SIZE+$10
Ult_Temp1	SET	xfdBufferInfo_SIZE+$11
Ult_Temp2	SET	xfdBufferInfo_SIZE+$12
Ult_Temp3	SET	xfdBufferInfo_SIZE+$13
Ult_Table	SET	xfdBufferInfo_SIZE+$14
Ult_SIZE	SET	xfdBufferInfo_SIZE+$c14

DB_Ult11	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a0,a2
		move.l	#Ult_SIZE,d0
		move.l	#$10001,d1
		move.l	xfdm_ExecBase(a6),a6
		jsr	_LVOAllocMem(a6)
		move.w	#XFDERR_NOMEMORY,xfdbi_Error(a2)
		tst.l	d0
		beq	.Error
		move.l	d0,a5
		move.l	a2,Ult_BufferInfo(a5)
		move.l	a5,a1
		moveq	#xfdBufferInfo_SIZE-1,d1
.CopyBI1	move.b	(a2)+,(a1)+
		dbf	d1,.CopyBI1

		move.l	xfdbi_SourceBuffer(a5),a3
		move.l  $3c(a3),d0
		ror.l	#3,d0
		and.l	#$c0000000,d0
		move.l	d0,Ult_MemType(a5)
		add.w	#$2d8,a3

		lea	Ult_Table(a5),a2
		moveq	#0,d5
		moveq	#0,d2

		bsr	.Decr_254
		bsr	.Decr_1F6
		move.l	d4,d6

		bsr	.Decr_1F6
		moveq	#24+8+16+4,d0	;header+hunk+reloc+end
		move.l	d4,Ult_Relocs(a5)
		bne.s	.Relocs
		moveq	#24+8+4,d0	;header+hunk+end
.Relocs		add.l	d6,d0		;code
		lsl.l	#2,d4
		add.l	d4,d0		;relocs

		move.l	d0,xfdbi_TargetBufLen(a5)
		move.l	d0,xfdbi_TargetBufSaveLen(a5)
		move.l	xfdbi_TargetBufMemType(a5),d1
		jsr	_LVOAllocMem(a6)
		move.l	d0,xfdbi_TargetBuffer(a5)
		beq.s	.Exit

		move.l	d0,a4
		move.l	#$3f3,(a4)+
		clr.l	(a4)+
		move.l	#1,(a4)+
		clr.l	(a4)+
		clr.l	(a4)+
		move.l	d6,d0
		lsr.l	#2,d0
		move.l	d0,d1
		or.l	Ult_MemType(a5),d1
		move.l	d1,(a4)+
		move.l	#$3e9,(a4)+
		move.l	d0,(a4)+

		move.l	a4,Ult_Code(a5)
		add.l	a4,d6

		bsr	.Decr_1E4
		move.b	d3,Ult_Temp0(a5)
		bsr	.Decr_1E4
		move.b	d3,Ult_Temp1(a5)
		bsr	.Decr_1E4
		move.b	d3,Ult_Temp2(a5)
		bsr	.Decr_1E4
		move.b	d3,Ult_Temp3(a5)
.Decr1		bsr.s	.Decr_13C
		cmp.l	d6,a4
		bcs.s	.Decr1

		move.l	#$3ec,(a4)+
		move.l	Ult_Relocs(a5),d7
		beq.s	.NoRelocs
		move.l	d7,(a4)+
		clr.l	(a4)+
.Decr2		bsr	.Decr_1F6
		move.l	d4,(a4)+
		subq.l	#1,d7
		bne.s	.Decr2
		clr.l	(a4)+
		move.l	#$3f2,(a4)+
		bra.s	.Ok
.NoRelocs	addq.l	#$f2-$ec,-(a4)

.Ok		moveq	#1,d0

.Exit		move.l	Ult_BufferInfo(a5),a1
		move.l	a5,a0
		moveq	#xfdBufferInfo_SIZE-1,d1
.CopyBI2	move.b	(a0)+,(a1)+
		dbf	d1,.CopyBI2
		move.l	d0,d2
		move.l	a5,a1
		move.l	#Ult_SIZE,d0
		jsr	_LVOFreeMem(a6)
		move.l	d2,d0
.Error		movem.l	(a7)+,d2-d7/a2-a6
		rts

.Decr_13C	bsr.s	.Decr_1E4
		cmp.b	Ult_Temp1(a5),d3
		beq.s	.Decr_162
		cmp.b	Ult_Temp0(a5),d3
		beq.s	.Decr_170
		cmp.b	Ult_Temp2(a5),d3
		beq.s	.Decr_182
		cmp.b	Ult_Temp3(a5),d3
		beq.s	.Decr_1A4
		move.b	d3,(a4)+
		rts

.Decr_162	bsr.s	.Decr_1E4
		moveq	#0,d0
.Decr_168	move.b	d0,(a4)+
		dbra	d3,.Decr_168
		rts

.Decr_170	bsr.s	.Decr_1E4
		move.w	d3,d7
		bsr.s	.Decr_1E4
.Decr_17A	move.b	d3,(a4)+
		dbra	d7,.Decr_17A
		rts

.Decr_182	bsr.s	.Decr_1E4
		ext.l	d3
		addq.l	#1,d3
		asl.l	#8,d3
		movem.l	d3/a4,-(a7)
		add.l	d3,a4
		bsr.s	.Decr_13C
		movem.l	(a7)+,d3/a0
		move.b	-(a4),d0
		subq.l	#1,d3
.Decr_19C	move.b	d0,(a0)+
		dbra	d3,.Decr_19C
		rts

.Decr_1A4	bsr.s	.Decr_1E4
		move.w	d3,d7
		bsr.s	.Decr_1F6
		move.l	Ult_Code(a5),a0
		lea	(a0,d4.l),a0
.Decr_1B6	move.b	(a0)+,(a4)+
		dbra	d7,.Decr_1B6
		rts

.Decr_1E4	moveq	#0,d3
.Decr_1E6	move.l	(a2,d3.w),d3
		bmi.s	.Decr_1F4
		bsr.s	.Decr_226
		bne.s	.Decr_1E6
		swap	d3
		bra.s	.Decr_1E6
.Decr_1F4	rts

.Decr_1F6	moveq	#0,d4
		bsr.s	.Decr_1E4
		move.b	d3,d4
		lsl.l	#8,d4
		bsr.s	.Decr_1E4
		move.b	d3,d4
		lsl.l	#8,d4
		bsr.s	.Decr_1E4
		move.b	d3,d4
		rts

.Decr_20A	subq.w	#8,d2
		bcc.s	.Decr_220
		lsl.w	#8,d5
		move.b	(a3)+,d5
		addq.w	#8,d2
.Decr_220	move.l	d5,d0
		lsr.l	d2,d0
		rts

.Decr_226	subq.w	#1,d2
		bcc.s	.Decr_250
		add.w	#32,d2
		move.b	(a3)+,d5
		lsl.w	#8,d5
		move.b	(a3)+,d5
		swap	d5
		move.b	(a3)+,d5
		lsl.w	#8,d5
		move.b	(a3)+,d5
.Decr_250	btst	d2,d5
		rts

.Decr_254	move.l	a2,a4
		moveq	#0,d4
		move.w	d4,-(a7)
		addq.l	#4,d4
		bsr.s	.Decr_276
		addq.w	#2,a7
		rts

.Decr_264	bsr.s	.Decr_20A
		move.w	4(a7),d1
		move.w	#$FFFF,(a4,d1.w)
		move.b	d0,3(a4,d1.w)
		rts

.Decr_276	bsr.s	.Decr_226
		bne.s	.Decr_264
		move.w	4(a7),d0
		move.w	d4,(a4,d0.w)
		move.w	d4,-(a7)
		addq.l	#4,d4
		bsr.s	.Decr_276
		addq.w	#2,a7
		move.w	4(a7),d0
		move.w	d4,2(a4,d0.w)
		move.w	d4,-(a7)
		addq.l	#4,d4
		bsr.s	.Decr_276
		addq.w	#2,a7
		rts

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

RS_Ult11	add.l	a0,a0
		add.l	a0,a0
		cmp.l	#($aa*4)+8,-4(a0)
		bne.s	.Exit

		cmp.w	#$abcd,$26-$1c(a0)
		bne.s	.Exit
		cmp.l	#$47ed0214,$94-$1c(a0)
		bne.s	.Exit
		cmp.l	#$45ed0214,$9c-$1c(a0)
		bne.s	.Exit
		cmp.l	#$3f045884,$2b2-$1c(a0)
		bne.s	.Exit
		moveq	#1,d0
		rts

.Exit		moveq	#0,d0
		rts

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

Ult_SegmentInfo	SET	xfdBufferInfo_SIZE
Ult_DosBase	SET	xfdBufferInfo_SIZE+4
Ult_Handle	SET	xfdBufferInfo_SIZE+8
Ult_MemType	SET	xfdBufferInfo_SIZE+$c
Ult_Relocs	SET	xfdBufferInfo_SIZE+$10
Ult_Temp0	SET	xfdBufferInfo_SIZE+$14
Ult_Temp1	SET	xfdBufferInfo_SIZE+$15
Ult_Temp2	SET	xfdBufferInfo_SIZE+$16
Ult_Temp3	SET	xfdBufferInfo_SIZE+$17
Ult_Code	SET	xfdBufferInfo_SIZE+$18
Ult_DecrBuf	SET	xfdBufferInfo_SIZE+$1c	;200
Ult_Table	SET	xfdBufferInfo_SIZE+$21c	;c00
Ult_SIZE	SET	xfdBufferInfo_SIZE+$e1c

DS_Ult11	movem.l	d2-d7/a2-a6,-(a7)
		move.l	a6,a3
		move.l	a0,a2
		move.l	#Ult_SIZE,d0
		move.l	#$10001,d1
		move.l	xfdm_ExecBase(a3),a6
		jsr	_LVOAllocMem(a6)
		move.w	#XFDERR_NOMEMORY,xfdsi_Error(a2)
		tst.l	d0
		beq	.Error
		move.l	d0,a5
		move.l	a2,Ult_SegmentInfo(a5)
		move.l	a5,a1
		moveq	#xfdSegmentInfo_SIZE-1,d1
.CopySI1	move.b	(a2)+,(a1)+
		dbf	d1,.CopySI1
		move.l	xfdm_DosBase(a3),Ult_DosBase(a5)

		move.l	xfdsi_SegList(a5),a0
		add.l	a0,a0
		add.l	a0,a0
		move.l	$20(a0),Ult_MemType(a5)

		move.l	$c(a0),d1
		move.l	d1,Ult_Handle(a5)
		move.l	#$2d8,d2
		moveq	#-1,d3
		move.l	Ult_DosBase(a5),a6
		jsr	_LVOSeek(a6)

		lea	Ult_DecrBuf+$200(a5),a3
		lea	Ult_DecrBuf+$1fc(a5),a1
		lea	Ult_Table(a5),a2
		moveq	#0,d5
		moveq	#0,d2

		bsr	.Decr_254
		bsr	.Decr_1F6
		move.l	d4,d6
		bsr	.Decr_1F6
		move.l	d4,Ult_Relocs(a5)

		move.w	xfdsi_RelMode(a5),d0
		cmp.w	#XFDREL_DEFAULT,d0
		beq.s	.AllocDefault
		move.l	#$10003,d1
		cmp.w	#XFDREL_FORCECHIP,d0
		beq.s	.AllocChipFast
		move.l	#$10005,d1
		cmp.w	#XFDREL_FORCEFAST,d0
		beq.s	.AllocChipFast
		move.w	#XFDERR_BADRELMODE,xfdsi_Error(a5)
		bra.s	.Exit
.AllocDefault	move.l	Ult_MemType(a5),d1
.AllocChipFast	move.l	d6,d0
		addq.l	#8,d0
		move.l	4.w,a6
		jsr	_LVOAllocMem(a6)
		tst.l	d0
		beq.s	.Exit

		move.l	d0,a4
		move.l	d6,(a4)
		addq.l	#8,(a4)+
		clr.l	(a4)+
		add.l	a4,d6
		move.l	a4,Ult_Code(a5)
		lea	Ult_DecrBuf+$1fc(a5),a1

		bsr	.Decr_1E4
		move.b	d3,Ult_Temp0(a5)
		bsr	.Decr_1E4
		move.b	d3,Ult_Temp1(a5)
		bsr	.Decr_1E4
		move.b	d3,Ult_Temp2(a5)
		bsr	.Decr_1E4
		move.b	d3,Ult_Temp3(a5)
.Decr1		bsr.s	.Decr_13C
		cmp.l	d6,a4
		bcs.s	.Decr1

		move.l	Ult_Code(a5),a4
		move.l	a4,d6
		move.l	Ult_Relocs(a5),d7
		beq.s	.NoRelocs
.Decr2		bsr	.Decr_1F6
		add.l	d6,(a4,d4.l)
		subq.l	#1,d7
		bne.s	.Decr2

.NoRelocs	move.l	xfdsi_SegList(a5),d1
		move.l	Ult_DosBase(a5),a6
		jsr	_LVOUnLoadSeg(a6)

		move.l	Ult_Code(a5),d1
		subq.l	#4,d1
		lsr.l	#2,d1
		move.l	d1,xfdsi_SegList(a5)
		moveq	#1,d0

.Exit		move.l	Ult_SegmentInfo(a5),a1
		move.l	a5,a0
		moveq	#xfdSegmentInfo_SIZE-1,d1
.CopySI2	move.b	(a0)+,(a1)+
		dbf	d1,.CopySI2
		move.l	d0,d2
		move.l	a5,a1
		move.l	#Ult_SIZE,d0
		move.l	4.w,a6
		jsr	_LVOFreeMem(a6)
		move.l	d2,d0
.Error		movem.l	(a7)+,d2-d7/a2-a6
		rts

.Decr_13C	bsr.s	.Decr_1E4
		cmp.b	Ult_Temp1(a5),d3
		beq.s	.Decr_162
		cmp.b	Ult_Temp0(a5),d3
		beq.s	.Decr_170
		cmp.b	Ult_Temp2(a5),d3
		beq.s	.Decr_182
		cmp.b	Ult_Temp3(a5),d3
		beq.s	.Decr_1A4
		move.b	d3,(a4)+
		rts

.Decr_162	bsr.s	.Decr_1E4
		moveq	#0,d0
.Decr_168	move.b	d0,(a4)+
		dbra	d3,.Decr_168
		rts

.Decr_170	bsr.s	.Decr_1E4
		move.w	d3,d7
		bsr.s	.Decr_1E4
.Decr_17A	move.b	d3,(a4)+
		dbra	d7,.Decr_17A
		rts

.Decr_182	bsr.s	.Decr_1E4
		ext.l	d3
		addq.l	#1,d3
		asl.l	#8,d3
		movem.l	d3/a4,-(a7)
		add.l	d3,a4
		bsr.s	.Decr_13C
		movem.l	(a7)+,d3/a0
		move.b	-(a4),d0
		subq.l	#1,d3
.Decr_19C	move.b	d0,(a0)+
		dbra	d3,.Decr_19C
		rts

.Decr_1A4	bsr.s	.Decr_1E4
		move.w	d3,d7
		bsr.s	.Decr_1F6
		move.l	Ult_Code(a5),a0
		lea	(a0,d4.l),a0
.Decr_1B6	move.b	(a0)+,(a4)+
		dbra	d7,.Decr_1B6
		rts

.Decr_1E4	moveq	#0,d3
.Decr_1E6	move.l	(a2,d3.w),d3
		bmi.s	.Decr_1F4
		bsr.s	.Decr_226
		bne.s	.Decr_1E6
		swap	d3
		bra.s	.Decr_1E6

.Decr_1F4	rts

.Decr_1F6	moveq	#0,d4
		bsr.s	.Decr_1E4
		move.b	d3,d4
		lsl.l	#8,d4
		bsr.s	.Decr_1E4
		move.b	d3,d4
		lsl.l	#8,d4
		bsr.s	.Decr_1E4
		move.b	d3,d4
		rts

.Decr_20A	subq.w	#8,d2
		bcc.s	.Decr_220
		lea	Ult_DecrBuf+$200(a5),a0
		cmp.l	a0,a3
		bne.s	.Decr_21A
		bsr.s	.Decr_1BE
.Decr_21A	lsl.w	#8,d5
		move.b	(a3)+,d5
		addq.w	#8,d2
.Decr_220	move.l	d5,d0
		lsr.l	d2,d0
		rts

.Decr_226	subq.w	#1,d2
		bcc.s	.Decr_250
		cmp.l	a1,a3
		bls.s	.Decr_23E
		addq.w	#8,d2
		lea	Ult_DecrBuf+$200(a5),a0
		cmp.l	a0,a3
		bne.s	.Decr_24E
		subq.w	#8,d2
		bsr.s	.Decr_1BE
.Decr_23E	add.w	#32,d2
		move.b	(a3)+,d5
		lsl.w	#8,d5
		move.b	(a3)+,d5
		swap	d5
		move.b	(a3)+,d5
		lsl.w	#8,d5
.Decr_24E	move.b	(a3)+,d5
.Decr_250	btst	d2,d5
		rts

.Decr_254	move.l	a2,a4
		moveq	#0,d4
		move.w	d4,-(a7)
		addq.l	#4,d4
		bsr.s	.Decr_276
		addq.w	#2,a7
		rts

.Decr_264	bsr.s	.Decr_20A
		move.w	4(a7),d1
		move.w	#$FFFF,(a4,d1.w)
		move.b	d0,3(a4,d1.w)
		rts

.Decr_276	bsr.s	.Decr_226
		bne.s	.Decr_264
		move.w	4(a7),d0
		move.w	d4,(a4,d0.w)
		move.w	d4,-(a7)
		addq.l	#4,d4
		bsr.s	.Decr_276
		addq.w	#2,a7
		move.w	4(a7),d0
		move.w	d4,2(a4,d0.w)
		move.w	d4,-(a7)
		addq.l	#4,d4
		bsr.s	.Decr_276
		addq.w	#2,a7
		rts

.Decr_1BE	movem.l	d0-d3/a0/a1/a6,-(a7)
		lea	Ult_DecrBuf(a5),a3
		move.l	Ult_Handle(a5),d1
		move.l	a3,d2
		move.l	#$200,d3
		move.l	Ult_DosBase(a5),a6
		jsr	_LVORead(a6)
		movem.l	(a7)+,d0-d3/a0/a1/a6
		rts

S_Ult_END
