	include	lvo/exec_lib.i
	include	lvo/dos_lib.i
	include	dos/dos.i
	include	exec/memory.i

stackf	MACRO	; stack_symbol, stackelement_symbol
	IFND	\1
\1	set	0
	ENDC
\1	set	\1-4
\2	equ	\1
	ENDM

BLOCK	equr	A2

	stackf	stk, length	;\
	stackf	stk, packlen	; | these four filled by ReadArgs
	stackf	stk, to		; |
	stackf	stk, from	;/
	stackf	stk, rdargs
	stackf	stk, execbase
	stackf	stk, dosbase
args=from

	link	a5,#stk

	move.l	4.w,a6
	move.l	a6,execbase(a5)

	lea	dosname(pc),a1
	moveq	#37,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,dosbase(a5)
	beq	.nodos
	move.l	d0,a6

	lea	templat(pc),a0
	move.l	a0,d1
	lea	args(a5),a0
	move.l	a0,d2
	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+
	moveq	#0,d3
	jsr	_LVOReadArgs(a6)
	move.l	d0,rdargs(a5)
	beq	.nomem

	; allocate memory
	move.l	execbase(a5),a6
	move.l	length(a5),a0
	move.l	(a0),d0
	add.l	d0,d0	; just for fun
	move.l	#MEMF_ANY|MEMF_CLEAR,d1
	jsr	_LVOAllocVec(a6)
	tst.l	d0
	beq	.nomem
	move.l	d0,BLOCK

	move.l	dosbase(a5),a6
	move.l	from(a5),d1
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)
	move.l	d0,d4
	beq.s	.fail
	move.l	d4,d1
	move.l	BLOCK,d2
	move.l	packlen(a5),a0
	move.l	(a0),d3
	jsr	_LVORead(a6)
	move.l	d0,d2
	move.l	d4,d1
	jsr	_LVOClose(a6)
	tst.l	d2
	bmi.s	.fail

	; unpack here
	move.l	BLOCK,-(sp)
	move.l	BLOCK,-(sp)
	move.l	packlen(a5),a0
	move.l	(a0),d0
	add.l	d0,(sp)
	bsr	DECRUNCHER
	addq.l	#8,sp

	; open 'to' file
	move.l	to(a5),d1
	move.l	#MODE_NEWFILE,d2
	jsr	_LVOOpen(a6)
	move.l	d0,d4
	beq.s	.fail
	move.l	d0,d1
	move.l	BLOCK,d2
	move.l	length(a5),a0
	move.l	(a0),d3
	jsr	_LVOWrite(a6)
	move.l	d0,d2
	move.l	d4,d1
	jsr	_LVOClose(a6)

.fail	move.l	BLOCK,a1
	move.l	execbase(a5),a6
	jsr	_LVOFreeVec(a6)
.nomem	move.l	dosbase(a5),a6
	move.l	rdargs(a5),d1
	beq.s	.noargs
	jsr	_LVOFreeArgs(a6)	; free args if allocated
.noargs	move.l	dosbase(a5),a1
	move.l	execbase(a5),a6
	jsr	_LVOCloseLibrary(a6)	; close dos.library
.nodos	unlk	a5
	moveq	#0,d0
	rts

; bytekiller strikes again

DECRUNCHER
	link.w	a5,#0
	move.w	#0,ccr
	movem.l	d0-d7/a0-a6,-(sp)
	movea.l	(8,a5),a0
	movea.l	(12,a5),a1
	movea.l	-(a0),a2
	adda.l	a1,a2
	move.l	-(a0),d5
	move.l	-(a0),d0
	eor.l	d0,d5
1$	lsr.l	#1,d0
	bne.b	2$
	bsr.w	16$
2$	blo.b	9$
	moveq	#8,d1
	moveq	#1,d3
	lsr.l	#1,d0
	bne.b	3$
	bsr.b	16$
3$	blo.b	11$
	moveq	#3,d1
	clr.w	d4
4$	bsr.b	17$
	move.w	d2,d3
	add.w	d4,d3
5$	moveq	#7,d1
6$	lsr.l	#1,d0
	bne.b	7$
	bsr.b	16$
7$	roxl.l	#1,d2
	dbra	d1,6$
	move.b	d2,-(a2)
	dbra	d3,5$
	bra.b	13$

8$	moveq	#8,d1
	moveq	#8,d4
	bra.b	4$

9$	moveq	#2,d1
	bsr.b	17$
	cmp.b	#2,d2
	blt.b	10$
	cmp.b	#3,d2
	beq.b	8$
	moveq	#8,d1
	bsr.b	17$
	move.w	d2,d3
	move.w	#12,d1
	bra.b	11$

10$	move.w	#9,d1
	add.w	d2,d1
	addq.w	#2,d2
	move.w	d2,d3
11$	bsr.b	17$
12$	subq.w	#1,a2
	move.b	(a2,d2.w),(a2)
	dbra	d3,12$
13$	cmpa.l	a2,a1
	blt.b	1$
;	tst.l	d5
;	bne.b	14$
;	bra.b	20$
;
;14$	move.w	#$FFFF,d0
;15$	move.w	d0,($DFF180).l
;	subi.l	#1,d0
;	bne.b	15$
	bra.b	20$

16$	move.l	-(a0),d0
	eor.l	d0,d5
	move.w	#$10,ccr
	roxr.l	#1,d0
	rts

17$	subq.w	#1,d1
	clr.w	d2
18$	lsr.l	#1,d0
	bne.b	19$
	move.l	-(a0),d0
	eor.l	d0,d5
	move.w	#$10,ccr
	roxr.l	#1,d0
19$	roxl.l	#1,d2
	dbra	d1,18$
	rts

20$	movem.l	(sp)+,d0-d7/a0-a6
	unlk	a5
	rts

templat	dc.b	'FROM/A,TO/A,PACKED/N/A,LENGTH/N/A',0
dosname	dc.b	'dos.library',0
