******************************************************************************
* IMP! (IMP!) Multi-selection capable data-compressor
* ----------------------------------------------------------------------------
* Just a simple reqtools front end tacked onto the Imploder algorithm for
* data compression. Decent compression, very good on decompression speed.
*
* THE IMP! ALGORITHM IS FULLY *FREEWARE* AND IS SUPPLIED WITH THE FREEWARE
* BEERMON MONITOR PACKAGE. YOU CAN USE IT IN ANY PRODUCTIONS YOU LIKE 
******************************************************************************
HeaderID	=	"IMP!"		;also recognised as "ATN!"

		rsreset
_DOSBase:	rs.l	1
_RTBase:	rs.l	1
ProgHandle:	rs.l	1
ProgBuff:	rs.l	1
ProgSize:	rs.l	1
TotalGain	rs.l	1
filereq		rs.l	1
volreq		rs.l	1
flist		rs.l	1
Savename	rs.l	1
PackedSize	rs.l	1
Array		rs.l	6
valbuf:		rs.b	20
hexbuff		rs.b	10
Buffer		rs.b	128
filename	rs.b	34
finalname:	rs.b	256
volpath:	rs.b	128
vars_SIZEOF	rs.b	0
		rsreset

		section	multiselect,code

		include	'includes:misc/os3_gst.i'

		link	a4,#-vars_SIZEOF
		move.l	#vars_SIZEOF-1,d7
clear_bss:	clr.b	-(a4)
		dbra	d7,clear_bss
		
*-------------- Open dos library..

		move.l	4.w,a6
		lea	DOSName(pc),a1
		CALL	OldOpenLibrary
		move.l	d0,_DOSBase(a4)
		beq.w	NoLib

		lea	About.txt(pc),a0
		bsr.w	putstr

*-------------- Open reqtools library..

		lea	ReqName(pc),a1
		CALL	OldOpenLibrary
		move.l	d0,_RTBase(a4)
		beq.w	closedos
		move.l	d0,a6

*-------------- Allocate a Reqtools File Requester

		move.l	#RT_FILEREQ,d0
		suba.l	a0,a0
		CALL	rtAllocRequestA
		move.l	d0,filereq(a4)
		beq.w	ok17

*-------------- multiselect some filenames...

		move.l	filereq(a4),a1
		lea	filename(a4),a2
		lea	Text66(pc),a3
		lea	Tags9(pc),a0
		CALL	rtFileRequestA
		move.l	d0,flist(a4)
		beq.w	ok16

*-------------- allocate a volume requester..

		move.l	#RT_FILEREQ,d0
		sub.l	a0,a0
		CALL	rtAllocRequestA
		move.l	d0,volreq(a4)
		beq.w	freelist			;free multilist..

*-------------- select destination path..

		lea	volpath(a4),a1
		clr.b	(a1)

		suba.l	a2,a2
		lea	Text89(pc),a3
		lea	Tags11(pc),a0
		move.l	volreq(a4),a1
		CALL	rtFileRequestA
		tst.l	d0
		beq.s	vol_error

*-------------- selection ok...

		move.l	volreq(a4),a0
		move.l	rtfi_Dir(a0),a0
		lea	volpath(a4),a1
get_volname:	move.b	(a0)+,(a1)+
		bne.s	get_volname
		bra.s	vol_free

*-------------- selection cancelled or failed..

vol_error	lea	NoPath.txt(pc),a0
		bsr.w	putstr

vol_free	move.l	volreq(a4),a1
		CALL	rtFreeRequest

*-------------- process all filenames in the list...

		clr.l	TotalGain(a4)
		
		move.l	flist(a4),a6
nextfile:
		lea	finalname(a4),a5
		move.l	a5,a1

		move.l	filereq(a4),a0
		move.l	rtfi_Dir(a0),d0
		beq.s	no_slash
		move.l	d0,a0
		move.l	rtfl_Name(a6),d1
		beq.s	nextname
		
bytecopy:	move.b	(a0)+,(a1)+
		bne.s	bytecopy
		cmp.b	#":",-2(a1)
		bne.s	add_slash
		tst.b	-(a1)
		bra.s	no_slash
add_slash:	tst.b	-(a1)
		move.b	#"/",(a1)+
no_slash:	move.l	d1,a0
bytecopy2:	move.b	(a0)+,(a1)+
		bne.s	bytecopy2
		clr.b	(a1)+
		move.l	a5,d0

*-------------- d0.l = final filename..

		bsr.s	process			;process files in linked list.
		tst.l	d0			;abort processing of files??
		bne.s	aborted

nextname	move.l	rtfl_Next(a6),a6
		cmp.l	#0,a6
		bne.s	nextfile

		move.l	TotalGain(a4),d0
		lea	TotGain.Txt(pc),a0
		bsr.w	putstr			;d0.l = Gained bytes
		bsr.w	H2A

		lea	Done.txt(pc),a0
		bsr.w	putstr

*-------------- free list of filenames..

freelist
aborted		move.l	flist(a4),a0
		move.l	_RTBase(a4),a6
		CALL	rtFreeFileList

*-------------- free file requesters..

ok16		move.l	filereq(a4),a1
		CALL	rtFreeRequest

*-------------- close reqtools library..

closelibs
ok17		move.l	_RTBase(a4),a1
		move.l	4.w,a6
		CALL	CloseLibrary

*-------------- close dos library..

closedos:	move.l	_DOSBase(a4),a1
		move.l	4.w,a6
		CALL	CloseLibrary

NoLib:		lea	vars_SIZEOF(a4),a4		* Restore stack memory!
		unlk	a4
		moveq	#0,d0
		rts




process		movem.l	d1-d7/a0-a6,-(sp)

*-------------- Attempt to load this file..

LoadFile:	move.l	d0,-(sp)
		lea	Load.txt(pc),a0
		bsr.w	putstr
		move.l	(sp),a0
		bsr.w	putstr
		lea	LF.txt(pc),a0
		bsr.w	putstr
		move.l	(sp),a0
		bsr.w	LoadDOSFile
		move.l	(sp)+,a0
		tst.l	d0
		beq.s	Load_Okay

		cmp.l	#-2,d0
		bne.s	notf

*-------------- out of memory

		move.l	a0,-(sp)
		lea	ErrorMem.txt(pc),a0
		bsr.w	putstr
		move.l	(sp)+,a0
		bra.w	nosave

*-------------- file not found
notf
		move.l	a0,-(sp)
		lea	ErrorLoad.txt(pc),a0
		bsr.w	putstr
		move.l	(sp)+,a0
		bra.w	nosave

Load_Okay:
		move.l	a0,-(sp)
		lea	Packing.txt(pc),a0
		bsr.w	putstr
		move.l	(sp)+,a0

		bsr.w	sort_destname

		move.l	d0,-(sp)
		move.l	ProgBuff(a4),a0
		move.l	ProgSize(a4),d0
		move.l	#11,d1
		bsr.w	_compress_slow
		move.l	(sp)+,a0		;a0=filename..

		move.l	a0,Savename(a4)
		move.l	d0,PackedSize(a4)
		bne.s	packedokay	
					
		lea	ErrorGain.txt(pc),a0
		bsr.w	putstr
		bra.w	nosave

packedokay
*-------------- show packed statistics..

		move.l	ProgSize(a4),d0
		lea	OrigLength.Txt(pc),a0
		bsr.w	putstr
		bsr.w	H2A

		move.l	PackedSize(a4),d0
		lea	PakLength.Txt(pc),a0
		bsr.w	putstr
		bsr.w	H2A

		move.l	ProgSize(a4),d0		;original size
		sub.l	PackedSize(a4),d0	;d0.l = gain in bytes.
		add.l	d0,TotalGain(a4)

		lea	Gained.Txt(pc),a0
		bsr.w	putstr			;d0.l = Gained bytes
		bsr.w	H2A

		move.l	PackedSize(a4),d0	;d0.l = Packed size
		move.l	ProgSize(a4),d1		;d1.l = Original size
		move.l	d1,d2
		sub.l	d0,d2
		move.l	d1,d3
getgain1:	tst.l	d2
		bmi.s	getgain2
		tst.l	d3
		bmi.s	getgain2
		add.l	d2,d2
		add.l	d3,d3
		bra.s	getgain1

getgain2:	lsr.l	#1,d2
		lsr.l	#1,d3
		clr.w	d2
		clr.w	d3
		swap	d2
		swap	d3
		mulu	#100,d2
		divu	d3,d2

*-------------- d2.w = % gain
;		d0.l = old size
;		d1.l = new size

		lea	Percentage.Txt(pc),a0
		bsr.w	putstr			;d0.l = Gained bytes

		moveq	#0,d0
		move.w	d2,d0
		move.l	d2,-(sp)
		lea	valbuf(a4),a0
		bsr.w	hex2asc
		bsr.w	putstr

		lea	valbuf(a4),a0
		move.w	#$2E00,(a0)
		bsr.w	putstr

		lea	valbuf(a4),a0
		move.l	(sp)+,d0
		clr.w	d0
		swap	d0
		bsr.w	hex2asc
		sf.b	2(a0)
		bsr.w	putstr

		lea	valbuf(a4),a0
		move.w	#$2500,(a0)
		bsr.w	putstr

		lea	LF.txt(pc),a0
		bsr.w	putstr

*-------------- Attempt to save this file..

SaveFile:
		lea	Save.txt(pc),a0
		bsr.w	putstr
		move.l	Savename(a4),a0
		bsr.w	putstr
		lea	LF.txt(pc),a0
		bsr.b	putstr

*-------------- write file out..

		move.l	Savename(a4),a0
		move.l	ProgBuff(a4),a1
		move.l	PackedSize(a4),d1
		bsr.w	SaveDOSFile
		tst.l	d0
		beq.s	Save_Okay

		lea	ErrorSave.txt(pc),a0
		bsr.b	putstr
Save_Okay

nosave		bsr.w	FreeDOSFile

*-------------- abort processing of files if CTRL+C was pressed...

		bsr.b	_CheckBreak

		movem.l	(sp)+,d1-d7/a0-a6
		rts


_CheckBreak:	moveq	#0,d0
		moveq	#0,d1
		bset.l	#SIGBREAKB_CTRL_C,d1	;check for CTRL_C
		move.l	_DOSBase(a4),a6
		CALL	CheckSignal		;did user signal a break??

		btst.l	#SIGBREAKB_CTRL_C,d0
		beq.s	NoBreak
WasBroken:	moveq	#1,d0			;yes.. user tried to break..
		rts

NoBreak:	moveq	#0,d0			;no break
		rts




sort_destname:	lea	volpath(a4),a3
		lea	finalname(a4),a5
		move.l	a5,a1
		move.l	a3,a0
		move.l	rtfl_Name(a6),d1
		beq.w	nextname
_bytecopy:	move.b	(a0)+,(a1)+
		bne.s	_bytecopy
		cmp.b	#":",-2(a1)
		bne.s	_add_slash
		tst.b	-(a1)
		bra.s	_no_slash
_add_slash:	tst.b	-(a1)
		move.b	#"/",(a1)+
_no_slash:	move.l	d1,a0
_bytecopy2:	move.b	(a0)+,(a1)+
		bne.s	_bytecopy2
		clr.b	(a1)+
		move.l	a5,d0
		rts

*-------------- returns d0.l = filename..

* Putstr
*
* Sends a ascii text string to current console output
* 
* $Inputs:	a0.l = String ptr (null terminated)

putstr:		movem.l	d0-d7/a1-a6,-(sp)
		move.l	a0,d2
		moveq	#-1,d3			;d4=0
getlen3		addq.l	#1,d3			;increase string length by 1
		tst.b	(a0)+			;increase position
		bne.s	getlen3			;nope not found, so keep on
		move.l	_DOSBase(a4),a6
		CALL	Output			;get output base
		move.l	d0,d1
		CALL	Write			;print error msg to cli
		movem.l	(sp)+,d0-d7/a1-a6
		rts
				
* _LoadDOSFile :- Loads an AmigaDOS file from any device into memory
*
* In		a0 (.L)	= Filename
*
* Out		d0 (.L) = Result Code (0=File Ok,-1=Load Failed!)	
*		d1 (.L) = Length
	
LoadDOSFile:	movem.l	d2-d7/a0/a2-a6,-(sp)
		clr.l	ProgHandle(a4)
		clr.l	ProgBuff(a4)
		clr.l	ProgSize(a4)

*-------------- Open file
		move.l	a0,d1			;get filename
		move.l	#MODE_OLDFILE,d2
		move.l	_DOSBase(a4),a6
		CALL	Open			;open file
		move.l	d0,ProgHandle(a4)
		beq.s	NotFound

*-------------- Get Length of file

		move.l	d0,d5			;ProgHandle
		move.l	d5,d1			;file handle
		moveq	#0,d2
		moveq	#1,d3
		CALL	Seek			;seek start of file
		move.l	d5,d1			;file handle
		moveq	#0,d2
		moveq	#-1,d3
		CALL	Seek			;seek end of file
		move.l	d0,ProgSize(a4)

*-------------- Allocate Memory for file

		move.l	4.w,a6			;get execbase
		move.l	#MEMF_PUBLIC,d1		;we want public mem
		CALL	AllocVec		;allocate it...
		move.l	d0,ProgBuff(a4)		;save base
		beq.b	TooBig			;fail?

*-------------- Load in whole file
				
		move.l	ProgHandle(a4),d1
		move.l	ProgBuff(a4),d2
		move.l	ProgSize(a4),d3
		move.l	_DOSBase(a4),a6
		CALL	Read			;read file

*-------------- Close file

CloseFile:	move.l	ProgHandle(a4),d1
		CALL	Close			;close file

		move.l	ProgSize(a4),d1		;d1=ProgSize
		move.l	ProgBuff(a4),a1		

		movem.l	(sp)+,d2-d7/a0/a2-a6
		moveq	#0,d0			;resultcode (okay)
		rts

NotFound:	movem.l	(sp)+,d2-d7/a0/a2-a6
		moveq	#-1,d0			;file not found error-code
		rts

TooBig:		move.l	ProgHandle(a4),d1
		move.l	_DOSBase(a4),a6
		CALL	Close			;close file
		movem.l	(sp)+,d2-d7/a0/a2-a6
		moveq	#-2,d0			;file too big error-code
NotAlloc	rts




*-------------- Free Memory for DOSFile

FreeDOSFile:	move.l	(AbsExecBase).w,a6	;get execbase

		move.l	ProgBuff(a4),d0		;ptr to our RS.Variables base
		beq.s	NotAlloc1
		move.l	d0,a1
		CALL	FreeVec			;free the memory
		clr.l	ProgBuff(a4)
		clr.l	ProgSize(a4)

NotAlloc1:	rts

* SaveMem2File
*
* $Inputs:	a0.l	= Filename
*		a1.l	= Mem Address
*		d1.l	= Save Length
*
* $Outputs:	d0.l	= 0 - success
*		d0.l	= 1 - failure

SaveDOSFile:	movem.l	d2-d7/a0-a6,-(sp)
		move.l	a1,d5			;progbuffer
		move.l	d1,d6			;proglength
		beq.s	_NoGain

		move.l	a0,d1			;filename
		move.l	#MODE_NEWFILE,d2
		move.l	_DOSBase(a4),a6
		CALL	Open
		move.l	d0,d7
		beq.b	_SaveError

		move.l	d7,d1			;fh...
		move.l	d5,d2			;adr
		move.l	d6,d3			;length
		CALL	Write			;write file

		move.l	d7,d1
		CALL	Close			;close file
_NoGain:	movem.l	(sp)+,d2-d7/a0-a6
		moveq	#0,d0
		rts
_SaveError:	movem.l	(sp)+,d2-d7/a0-a6
		moveq	#1,d0
		rts



H2A:		lea	valbuf(a4),a0
Hex2ASCIIDec:	bsr.b	hex2asc
		bsr.w	putstr
		lea	LFs.Txt(pc),a0
		bra.w	putstr

hex2asc		lea	hextable(pc),a1
		move.b	#"0",d6			; constant
		moveq	#9-1,d4
		move.b	#" ",d5			; replace leading 0's
ccloop		move.l	(a1)+,d1
		cmp.l	d1,d0
		bcs.s	get3
 		move.w	#32-1,d3
		moveq	#0,d2
get1		add.l	d0,d0
		roxl.l	#1,d2
		cmp.l	d1,d2
		bcs.s	get2
		sub.l	d1,d2
		addq.l	#1,d0
get2		dbra	d3,get1
		add.b	d6,d0
		move.b	d0,(a0)+
		move.l	d2,d0
		move.b	d6,d5
		bra.s	get4

get3		move.b	d5,(a0)+
get4		dbra	d4,ccloop
 		add.b	d6,d0
		move.b	d0,(a0)+
		lea	valbuf(a4),a0
.getstart	cmp.b	#" ",(a0)+
		beq.s	.getstart
		tst.b	-(a0)
		rts

hextable	dc.l	1000000000
		dc.l	100000000
		dc.l	10000000
		dc.l	1000000
		dc.l	100000
		dc.l	10000
		dc.l	1000
		dc.l	100
		dc.l	10
		dc.l	1
		dc.l	0

* ATN Header (Imploder)
*
* In:	a0.l=*buffer
*	d0.l=data length
*	d1.l=crunch mode
*
* Out:	d0.l=<>0:crunched length

CacheFlush:	movem.l	d0-d7/a0-a6,-(sp)
		move.l	4.w,a6
		cmp.w	#37,$14(a6)
		bcs.s	no_flush
		CALL	CacheClearU
no_flush:	movem.l	(sp)+,d0-d7/a0-a6
		rts

		cnop	0,4
_compress_slow:	movem.l	d2-d7/a2-a6,-(sp)

		moveq	#88-1,d2
atn01:		clr.w	-(sp)
		dbf	d2,atn01
		move.l	sp,a6

		cmp.l	#$40,d0
		blo.w	atn23

		scs	(a6)
		move.l	a0,10(a6)
		move.l	a0,$22(a6)
		move.l	a0,$26(a6)
		move.l	d0,$12(a6)
		add.l	d0,a0
		move.l	a0,14(a6)
		lea	atntab0(pc),a0
		lsl.w	#2,d1
		move.l	0(a0,d1.w),d1
		addq.l	#1,d1
		cmp.l	d0,d1
		bls.s	atn03

		move.l	d0,d1
		subq.l	#1,d1
atn03:		move.l	d1,$1A(a6)
		subq.l	#1,d1
		moveq	#0,d0
atn04:		cmp.l	(a0)+,d1
		bls.s	atn05
		addq.b	#1,d0
		bra.s	atn04

atn05:		move.b	d0,1(a6)
		lea	$A4(a6),a1
		moveq	#12,d1
		mulu	d1,d0
		lea	atntab1(pc),a0
		add.l	d0,a0
		subq.w	#1,d1
atn06:		move.b	(a0)+,(a1)+
		dbf	d1,atn06

		lea	$74(a6),a1
		lea	$A4(a6),a0
		moveq	#12-1,d1
atn07:		move.b	(a0)+,d0
		moveq	#0,d2
		bset	d0,d2
		move.l	d2,(a1)+
		dbf	d1,atn07

		lea	$74(a6),a0
		lea	$84(a6),a1
		moveq	#8-1,d1
atn08:		move.l	(a0)+,d0
		add.l	d0,(a1)+
		dbf	d1,atn08

		tst.b	(a6)
		beq.s	atn11

		lea	$74(a6),a1
		moveq	#8-1,d0
atn09:		move.l	(a1)+,d1
		move.w	d1,(a2)+
		dbf	d0,atn09

		lea	$A4(a6),a1
		moveq	#12-1,d0
atn10:		move.b	(a1)+,(a2)+
		dbf	d0,atn10

atn11:		move.b	#7,$2D(a6)
atn12:
		bsr.w	atn28
		beq.s	atn15

		bsr.w	atn55
		bne.s	atn13

		lea $1e(a6),a5
		addq.l #1,(a5)+		;$1e
		move.l (a5),a0		;$22
		addq.l #1,(a5)+		;$22
		move.l (a5),a1		;$26
		move.b (a0),(a1)
		addq.l #1,(a5)		;$26
		addq.l #1,$30(a6)	;$30	

		cmp.l #$4012,$30(a6)
		blo.s	atn12
		bra.s	atn15

atn13:		move.b	$5C(a6),d0
		move.l	$60(a6),d1
		bsr.w	atn37
		move.b	$5E(a6),d0
		move.w	$66(a6),d1
		bsr.w	atn37
		move.b	$5D(a6),d0
		move.w	$64(a6),d1
		cmp.b	#13,d0
		bne.s	atn14
		move.l	$26(a6),a0
		move.b	d1,(a0)+
		move.l	a0,$26(a6)
		moveq	#5,d0
		moveq	#$1F,d1

atn14:		bsr.w	atn37
		moveq	#0,d0
		move.l d0,$30(a6)	;clr.l	$30(a6)
		move.b	$2E(a6),d0
		add.l	d0,$22(a6)
		bra.b	atn12

		cnop	0,4
atn15:		lea $1e(a6),a5
		addq.l #1,(a5)+		;$1e
		move.l (a5),a0		;$22
		addq.l #1,(a5)		;$22
		move.l (a5)+,d0		;$22
		move.l (a5),a1		;$26
		move.b (a0),(a1)
		addq.l #1,(a5)		;$26
		addq.l #1,$30(a6)	;$30

		cmp.l	14(a6),d0
		bne.s	atn15

		tst.b	(a6)
		bne.w	atn19
		move.l	$26(a6),d0
		sub.l	10(a6),d0
		moveq	#12,d1
		cmp.l	d1,d0		;cmp.l #12,d0
		blo.w	atn23

		move.l	$12(a6),d1
		sub.l	d0,d1
		moveq	#$36,d7
		cmp.l	d7,d1		;cmp.l	#$36,d1
		bls.w	atn23
		move.l	10(a6),a1
		move.l	$26(a6),a0
		move.w	#$ff00,d7	;move.l	#$FF00,d7
		btst	#0,d0
		beq.s	atn16
		moveq	#0,d7
		addq.l	#1,d0
		clr.b	(a0)+
atn16:		move.l	(a1),8(a0)
		move.l	#HeaderID,(a1)
		move.l	4(a1),4(a0)
		move.l	$12(a6),4(a1)
		move.l	8(a1),(a0)
		move.l	d0,8(a1)
		moveq	#$2e,d1
		add.l	d1,d0		;add.l	#$2E,d0
		move.l	d0,$16(a6)
		move.l	$30(a6),12(a0)
		move.b	$2C(a6),d1
		and.w	#$FE,d1
		move.b	$2D(a6),d0
		bset	d0,d1
		or.w	d7,d1
		move.w	d1,$10(a0)

		lea	$74(a6),a1
		lea	$12(a0),a0
		moveq	#8-1,d0
atn17:		move.l	(a1)+,d1
		move.w	d1,(a0)+
		dbf	d0,atn17

		lea	$A4(a6),a1
		moveq	#12-1,d0
atn18:		move.b	(a1)+,(a0)+
		dbf	d0,atn18
		bra.s	atn23

		cnop	0,4
atn19:		move.l	$26(a6),d0
		sub.l	10(a6),d0
		move.l	$12(a6),d1
		sub.l	d0,d1
		moveq #6,d2
		cmp.l d2,d1		;cmp.l	#6,d1
		bls.s	atn23

		move.b	$2C(a6),d1
		and.b	#$FE,d1
		move.b	$2D(a6),d2
		bset	d2,d1
		move.l	$26(a6),a0
		btst	#0,d0
		beq.s	atn20
		move.b	d1,(a0)+
		move.l	$30(a6),(a0)
		bra.s	atn21

		cnop	0,4
atn20:		move.l	$30(a6),(a0)+
		move.b	d1,(a0)
atn21:		addq.l	#5,d0
		move.l	d0,$16(a6)
		bra.s	atn23

atn22:		moveq	#-1,d0
		bra.s	atn24

		cnop	0,4
atn23:		move.l	$16(a6),d0
atn24:		moveq	#88-1,d2
atn25:		clr.w	(sp)+
		dbf	d2,atn25

		movem.l	(sp)+,d2-d7/a2-a6
		bsr.w	CacheFlush
		tst.l	d0
		rts

atntab0:	dc.l	128
		dc.l	256
		dc.l	512
		dc.l	1024
		dc.l	1792
		dc.l	3328
		dc.l	5376
		dc.l	9472
		dc.l	20736
		dc.l	37376
		dc.l	67840
		dc.l	67840

atntab1:	dc.l	$5050505,$5050505,$6060606,$5060707,$6060606,$7070606
		dc.l	$5060707,$7070707,$8080808,$5060708,$7070808,$8080909
		dc.l	$6070708,$7080909,$8090A0A,$6070708,$709090A,$80A0B0B
		dc.l	$6070808,$709090A,$80A0B0C,$6070808,$709090A,$90A0C0D
		dc.l	$6070708,$709090C,$90A0C0E,$6070809,$7090A0C,$90B0D0F
		dc.l	$6070808,$70A0B0B,$90C0D10,$6080809,$70B0C0C,$90D0E11

atntab2:	dc.l	$2060E,$1020304

atntab3:	dc.l	$1010101,$2030304,$405070E

atntab4:	dc.l	$20002
		dc.l	$20002
		dc.l	$6000A
		dc.l	$A0012
		dc.l	$16002A
		dc.l	$8A4012

		cnop	0,4
atn28:		move.l	$22(a6),a5
		move.l	14(a6),d4
		move.l	a5,d0
		addq.l	#1,d0
		add.l	$1A(a6),d0
		cmp.l	d4,d0
		bls.s	atn29
		move.l	d4,d0
		move.l	d0,d1
		sub.l	a5,d1
		cmp.l	#3,d1
		bcc.s	atn29
		moveq	#0,d0
		rts

		cnop	0,4
atn29:		move.l	d0,d5
		move.l	a5,a2
		addq.l	#1,a2
		move.l	a2,a4
		moveq	#1,d7
		move.b	(a5),d3

		lea	$34(a6),a3
atn30:		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.b	(a2)+,d3
		beq.s	atn32
		cmp.l	a2,d5
		bhi.s	atn30

atn31:		moveq	#-1,d0
		rts

		cnop	0,4
atn32:		cmp.l	a2,d5
		bls.s	atn31
		move.l	a4,a0
		move.l	a2,a1
		cmpm.b	(a0)+,(a1)+
		bne.s	atn30
		cmpm.b	(a0)+,(a1)+
		bne.s	atn35
		cmpm.b	(a0)+,(a1)+
		bne.s	atn34

		move.w	#252-1,d0
atn33:		cmpm.b	(a0)+,(a1)+
		dbne	d0,atn33

atn34:		cmp.l	d4,a1
		bls.s	atn35
		move.l	d4,a1

atn35:		move.l	a1,d6
		sub.l	a2,d6
		cmp.w	d6,d7
		bcc.s	atn30
		move.w	d6,d7
		cmp.w	#8,d6
		bhi.s	atn36
		tst.b	-2(a3,d6.w)
		bne.w	atn30
		move.b	d6,-2(a3,d6.w)
		move.l	a2,d0
		sub.l	a5,d0
		subq.l	#2,d0
		move.w	d6,d1
		lsl.w	#2,d1
		move.l	d0,0(a3,d1.w)
		bra.w	atn30

		cnop	0,4
atn36:		move.b	d6,7(a3)
		move.l	a2,d0
		sub.l	a5,d0
		subq.l	#2,d0
		move.l	d0,$24(a3)
		cmp.b	#$FF,d6
		bne.w	atn30
		bra.s	atn31

		cnop	0,4
atn37:		move.b	$2C(a6),d2
		move.b	$2D(a6),d3
		move.l	$26(a6),a0
atn38:		lsr.l	#1,d1
		roxr.b	#1,d2
		subq.b	#1,d3
		bpl.s	atn39
		moveq	#7,d3
		move.b	d2,(a0)+
		moveq	#0,d2
atn39:		subq.b	#1,d0
		bne.s	atn38
		move.l	a0,$26(a6)
		move.b	d3,$2D(a6)
		move.b	d2,$2C(a6)
		rts

		cnop	0,4
atn40:		and.l	#$FF,d0
		cmp.b	#13,d0
		bhi.s	atn42
		cmp.b	#5,d0
		bhi.s	atn41
		lea	atntab2(pc),a0
		move.b	-2(a0,d0.w),$71(a6)
		move.b	2(a0,d0.w),$69(a6)
		bra.s	atn44

		cnop	0,4
atn41:		subq.b	#6,d0
		or.b	#$F0,d0
		move.b	d0,$71(a6)
		move.b	#8,$69(a6)
		bra.s	atn43

		cnop	0,4
atn42:		move.b	#$1F,$70(a6)
		move.b	d0,$71(a6)
		move.b	#13,$69(a6)
atn43:		moveq	#5,d0
atn44:		subq.b	#2,d0
		move.l	$30(a6),d2
		lea	atntab3(pc),a1
		lea	atntab4(pc),a0
		add.l	d0,a0
		add.l	d0,a0
		cmp.w	(a0),d2
		bcc.s	atn45
		move.b	0(a1,d0.w),d6
		move.b	d6,d3
		addq.b	#1,d3
		sf $73(a6)		;move.b	#0,$73(a6)
		moveq	#0,d4
		bra.s	atn48

		cnop	0,4
atn45:		cmp.w	8(a0),d2
		bcc.s	atn46
		move.b	4(a1,d0.w),d6
		move.b	d6,d3
		addq.b	#2,d3
		move.b	#2,$73(a6)
		move.w	(a0),d4
		bra.s	atn48

		cnop	0,4
atn46:		cmp.w	$10(a0),d2
		blo.s	atn47
		moveq	#0,d0
		rts

		cnop	0,4
atn47:		move.b	8(a1,d0.w),d6
		move.b	d6,d3
		addq.b	#2,d3
		move.b	#3,$73(a6)
		move.w	8(a0),d4
atn48:		move.b	d3,$6A(a6)
		sub.w	d4,d2
		moveq	#$10,d5
		sub.b	d6,d5
		lsl.w	d5,d2
atn49:		add.w	d2,d2
		roxl	$72(a6)
		subq.b	#1,d6
		bne.s	atn49
		lea	$A4(a6),a1
		lea	$74(a6),a0
		add.w	d0,a0
		add.w	d0,a0
		add.w	d0,a0
		add.w	d0,a0

		cmp.l	(a0),d1
		bcc.s	atn50
		move.b	0(a1,d0.w),d6
		move.b	d6,d3
		addq.b	#1,d3
		moveq	#0,d7
		move.l	d7,d4
		bra.s	atn53
atn50:		cmp.l	$10(a0),d1
		bcc.s	atn51
		move.b	4(a1,d0.w),d6
		move.b	d6,d3
		addq.b	#2,d3
		moveq	#2,d7
		move.l	(a0),d4
		bra.s	atn53
atn51:		cmp.l	$20(a0),d1
		blo.s	atn52
		moveq	#0,d0
		rts

		cnop	0,4
atn52:		move.b	8(a1,d0.w),d6
		move.b	d6,d3
		addq.b	#2,d3
		moveq	#3,d7
		move.l	$10(a0),d4
atn53:		move.b	d3,$68(a6)
		sub.l	d4,d1
		moveq	#$20,d5
		sub.b	d6,d5
		lsl.l	d5,d1
atn54:		add.l	d1,d1
		addx.l	d7,d7
		subq.b	#1,d6
		bne.s	atn54
		move.l	d7,$6C(a6)

		moveq	#-1,d0
		rts

		cnop	0,4
atn55:		clr.w	$2A(a6)
		clr.b	$2E(a6)
		lea	$34(a6),a4
		lea	$3C(a6),a5
atn56:		move.l	(a5)+,d1
		move.b	(a4)+,d0
		beq.s	atn58

		bsr.w	atn40
		beq.s	atn58

		moveq	#0,d0
		moveq	#0,d1
		move.b	-1(a4),d0
		lsl.w	#3,d0
		add.b	$69(a6),d1
		add.b	$68(a6),d1
		add.b	$6A(a6),d1
		sub.w	d1,d0
		bmi.s	atn58

		cmp.w	$2A(a6),d0
		blo.s	atn58
		move.w	d0,$2A(a6)
		move.b	-1(a4),$2E(a6)

		lea	$5C(a6),a0
		lea	$68(a6),a1
		moveq	#13-1,d1
atn57:		move.b	(a1)+,(a0)+
		dbf	d1,atn57

atn58:		move.l	a4,d0
		sub.l	a6,d0
		cmp.w	#$3C,d0
		bne.s	atn56
		clr.l	-(a4)
		clr.l	-(a4)
		tst.w	$2E(a6)
		rts

H2H:		movem.l	d1-d2/a0-a1,-(sp)
		addq.l	#8,a0
		lea     hextab(pc),a1
		moveq   #8-1,d1
NextByte:	move.l	d0,d2
		and.l	#15,d2
		move.b	0(a1,d2.w),-(a0)
		lsr.l	#4,d0
		dbra	d1,NextByte
		movem.l	(sp)+,d1-d2/a0-a1
		rts

About.txt	dc.b	$1b,'c',$a
		dc.b	$1b,'[1mIMP!',$1b,'[22m ',$1b,'[33mData-Packer ',$1b,'[32m1.01',$1b,'[3m',$1b,'[31mQuick FrontEnd',$1b,'[23m',$1b,'[3m(Imploder Algorithm)',$1b,'[23m',$1b,'[3m',$1b,'[23m',$a
		dc.b	'Copyright © 1996. All Rights Are Reserved.',$a
		dc.b	'Assembly Date: Jan-96.',$a,$a
		dc.b	'NB: While packing use CTRL+C to abort the entire session!',$a,0
LFs.Txt:
LF.txt		dc.b	10,0
Load.txt	dc.b	10,'Loading file.. ',0
Save.txt	dc.b	10,'Saving file.. ',0
Packing.txt:	dc.b	10,'Packing file...',10
		dc.b	'Please wait..',10,0
NoPath.txt:	dc.b	10,'No Destination Path Specified!',10,0
ErrorMem.txt:	dc.b	'Error: Out Of Memory...',0
ErrorLoad.txt	dc.b	'Error: Skipping file, failed to load..',10,0
ErrorSave.txt	dc.b	'Error: Skipping file, failed to save..',10,0
ErrorGain.txt:	dc.b	'Error: Skipping file, No gain!!',10,0
OrigLength.Txt:	dc.b	10,'Original Data Length : ',0
PakLength.Txt:	dc.b	'Packed Data Length   : ',0
Gained.Txt:	dc.b	'Gained Bytes         : ',0
Percentage.Txt:	dc.b	'Percentage Gain      : ',0
TotGain.Txt:	dc.b	10,'Total Gain           : ',0
Done.txt:	dc.b	10,'Session Done...',10,0
Text89		dc.b	"Select Destination Path..",0
Text66		dc.b	"Select File(s)...",0
		even
Tags9		dc.l	RTFI_Flags,FREQF_MULTISELECT
		dc.l	TAG_END
Tags11		dc.l	RTFI_Flags,FREQF_NOFILES
		dc.l	TAG_END
DOSName		dc.b	'dos.library',0
ReqName		dc.b	'reqtools.library',0
		cnop	0,2
hextab		dc.b	'0123456789ABCDEF'

