****************************************************************************
* Mirage Data/Executable File Packer v1.0
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Mediocre data compression algorithms, not so good on compression ability
* but good on speed.
*
* Offers ability to pack data or abosolute addressed code as an executable.
* Caution must be used if ANY type of nasty abosolute address code is packed
* as it probably won`t work on most amiga`s! Use data compression instead!!
*
* This is a very simple console window effort, this however is great for
* beginners to learn from!
****************************************************************************
_custom		=	$DFF000
color		=	$180

HUNK_BSS	=	$3EB
HUNK_CODE	=	$3E9
HUNK_END	=	$3F2
HUNK_HEADER	=	$3F3
HUNK_RELOC32	=	$3EC

MEMF_CLEAR	=	$10000
MODE_NEWFILE	=	$3EE
MODE_OLDFILE	=	$3ED

AbsExecBase	=	$4
_LVOAllocMem	=	-$C6
_LVOClose	=	-$24
_LVOCloseLibrary=	-$19E
_LVOExecute	=	-$DE
_LVOFreeMem	=	-$D2
_LVOInput	=	-$36
_LVOOldOpenLibrary=	-$198
_LVOOpen	=	-$1E
_LVOOutput	=	-$3C
_LVORead	=	-$2A
_LVOWrite	=	-$30

BeginProg:	movea.l	AbsExecBase,a6		* execbase
		lea	DOSName,a1
		jsr	_LVOOldOpenLibrary(a6)
		move.l	d0,_DOSBase		* open dos library
		beq.s	BadDos
		bra.s	Begin

BadDos:		clr.l	_custom+color		* error ! Dos failed to open!
		moveq	#-1,d0			* panic and exit..
		rts

_filehandle	dc.l	0
_StdOut		dc.l	0
_StdIn		dc.l	0
_DOSBase	dc.l	0
DOSName		dc.b	'dos.library',0
		even

*-------------- get stdio..

Begin:		movea.l	_DOSBase,a6
		jsr	_LVOOutput(a6)		* get dos output
		move.l	d0,_StdOut

		jsr	_LVOInput(a6)		* get dos input
		move.l	d0,_StdIn

*-------------- show info about proggy..

		movea.l	_DOSBase,a6
		move.l	_StdOut,d1
		move.l	#About.txt,d2		* str to show
		move.l	#AboutEnd.txt-About.txt,d3	* str length..
		jsr	_LVOWrite(a6)		* show msg about program

*-------------- Get workspace memory..

get_wordspace:	movea.l	_DOSBase,a6
		move.l	_StdOut,d1
		move.l	#Workspace.txt,d2
		move.l	#WorkspaceEnd.txt-Workspace.txt,d3
		jsr	_LVOWrite(a6)		* show workspace prompt

		bsr	clear_strbuff		* erase input buffer

		move.l	_StdIn,d1
		move.l	#_strbuff,d2
		moveq	#4,d3
		jsr	_LVORead(a6)		* read 4 char workspace string

		cmpi.l	#1,d0			* if < 1 then repeat process
		bls.s	get_wordspace

*-------------- convert str to hex long

		subq.l	#1,d0
		movea.l	#_strbuff,a0
		adda.l	d0,a0
		move.b	-(a0),d1
		subq.l	#1,d0
		bsr	AsciiToHex		* convert this char..

		cmpi.b	#10,d1			* bad workspace?
		bcc.s	get_wordspace

		moveq	#0,d2
		move.b	d1,d2
		tst.b	d0
		beq.s	gotit

		move.b	-(a0),d1
		subq.l	#1,d0
		bsr	AsciiToHex
		cmpi.b	#10,d1			* bad workspace?
		bcc.s	get_wordspace

		andi.w	#15,d1
		mulu.w	#10,d1
		add.w	d1,d2
		tst.b	d0
		beq.s	gotit

		move.b	-(a0),d1
		bsr	AsciiToHex
		cmpi.b	#10,d1			* bad workspace?
		bcc	get_wordspace

		andi.w	#15,d1
		mulu.w	#100,d1
		add.w	d1,d2
		tst.w	d2
		beq	get_wordspace

gotit:		moveq	#0,d0
		subq.w	#1,d2			* got a valid workspace..

calc_kbytes:	addi.l	#1024,d0		* convert to bytes..
		dbra	d2,calc_kbytes		* lame method :)

		move.l	d0,_workspace_len	* FINALLY: Workspace (bytes)

*-------------- allocate workspace memory..

		movea.l	AbsExecBase,a6
		move.l	#MEMF_CLEAR,d1
		move.l	_workspace_len,d0
		jsr	_LVOAllocMem(a6)	* allocate workspace memory
		move.l	d0,_workspace_ptr
		beq	get_wordspace		* did it fail?

		addi.l	#128,d0
		move.l	d0,_workaddition

*-------------- try to get filename of file to load..

		movea.l	_DOSBase,a6
GetFilename:	move.l	_StdOut,d1
		move.l	#Loadname.txt,d2
		move.l	#LoadnameEnd.txt-Loadname.txt,d3
		jsr	_LVOWrite(a6)

		move.l	_StdIn,d1
		move.l	#_strbuff,d2
		moveq	#30,d3
		jsr	_LVORead(a6)		* get users input filename
		cmpi.l	#1,d0
		bls.s	GetFilename

		subq.l	#1,d0
		lea	_strbuff,a0
		adda.l	d0,a0
		clr.b	(a0)

		lea	_strbuff,a0
		cmpi.b	#'-',(a0)		* did user try to execute?
		bne.s	LoadFile

*-------------- if user entered a '-' they want to execute a dos command..

		addq.l	#1,a0
		move.l	a0,d1
		moveq	#0,d2
		move.l	_StdOut,d3
		jsr	_LVOExecute(a6)		* execute dos cmd ..

		bra.s	GetFilename		* now return to get filename


LoadFile:	cmpi.l	#'exit',(a0)		* did user want to quit prog?
		beq.l	exitprog

		move.l	#_strbuff,d1
		move.l	#MODE_OLDFILE,d2
		jsr	_LVOOpen(a6)		* try to open file requested
		move.l	d0,_filehandle
		beq.s	GetFilename		* if failed ask again!

*-------------- now try to read in the file..

		move.l	_filehandle,d1
		move.l	_workaddition,d2	* truncate to workspace size!
		move.l	_workspace_len,d3	* NOT clever at all :(
		subi.l	#128,d3
		jsr	_LVORead(a6)		* read in the file...
		move.l	d0,_OrigLen

*-------------- close the file..

		move.l	_filehandle,d1
		jsr	_LVOClose(a6)		* close load file..

*-------------- check loading went ok..

		move.l	_workspace_len,d0
		subi.l	#128,d0
		cmp.l	_OrigLen,d0		* did whole file load in?
		bls	GetFilename		* if not.. get a new filename..

*-------------- Show original program length string

		move.l	_StdOut,d1
		move.l	#OrigLen.txt,d2
		move.l	#OrigLenEnd.txt-OrigLen.txt,d3
		jsr	_LVOWrite(a6)		* show original length prompt

*-------------- now the actual hex length string..

		move.l	_OrigLen,d0
		bsr	PrintBigHex		* now display actual length

*-------------- Now get the offset (packing ratio)..

GetOffset:	movea.l	_DOSBase,a6
		move.l	_StdOut,d1
		move.l	#Offset.txt,d2
		move.l	#OffsetEnd.txt-Offset.txt,d3
		jsr	_LVOWrite(a6)		* show offset prompt..

		bsr	clear_strbuff		* clear string buffer

*-------------- get offset string from user..

		move.l	_StdIn,d1
		move.l	#_strbuff,d2
		moveq	#5,d3
		jsr	_LVORead(a6)		* get user offset

*-------------- validate offset..

		cmpi.l	#1,d0			* check offset bounds..
		bls.s	GetOffset

		moveq	#4,d0			* convert string into long..
		bsr	StringToHex

		cmpi.w	#4096,d0		* no offset > 4096 allowed..
		bhi.s	GetOffset

		bclr	#0,d0			* make sure its EVEN..

		move.l	d0,_PackOffset		* save packing ratio!

*-------------- now compress that DATA!!!

		bsr	MiragePack

*-------------- save packed length size!

		movea.l	_workspace_ptr,a0
		move.l	_PackedLen,(a0)

*-------------- show packed length stats..

		movea.l	_DOSBase,a6
		lea	mp_longs1(pc),a5
		moveq	#6-1,d1
conv3:		move.w	(a5)+,d0
		bsr	PrintSmallHex
		dbra	d1,conv3

		move.l	_StdOut,d1
		move.l	#PackedLen.txt,d2
		move.l	#PackedLenEnd.txt-PackedLen.txt,d3
		jsr	_LVOWrite(a6)

		move.l	_PackedLen,d0
		addi.l	#12,d0
		bsr	PrintBigHex

*-------------- get file saving type..

GetSaveType:	move.l	_StdOut,d1
		move.l	#SaveType.txt,d2
		move.l	#SaveTypeEnd.txt-SaveType.txt,d3
		jsr	_LVOWrite(a6)

		move.l	_StdIn,d1
		move.l	#_strbuff,d2
		moveq	#30,d3
		jsr	_LVORead(a6)		* get save method
		cmpi.l	#1,d0
		bls.s	GetSaveType

		lea	_strbuff,a0
		cmpi.b	#'d',(a0)		* write a boring datafile?
		beq	Write_Data

		cmpi.b	#'e',(a0)		* write an executable?
		bne.s	GetSaveType

*-------------- if an executable we need 'start address and jump address'

get_loadadr:	move.l	_StdOut,d1
		move.l	#LoadAddr.txt,d2
		move.l	#LoadAddrEnd.txt-LoadAddr.txt,d3
		jsr	_LVOWrite(a6)		* show start addr prompt

		move.l	_StdIn,d1
		move.l	#_strbuff,d2
		moveq	#30,d3
		jsr	_LVORead(a6)		* get start address 

		cmpi.l	#1,d0			* was this address in range?
		bls.s	get_loadadr

		moveq	#5,d0
		bsr	StringToHex		* convert ascii to longword
		move.l	d0,_LoadAddr		* save start address

get_jumpin:	move.l	_StdOut,d1
		move.l	#JumpAdr.txt,d2
		move.l	#JumpAdrEnd.txt-JumpAdr.txt,d3
		jsr	_LVOWrite(a6)		* show jump addr prompt

		move.l	_StdIn,d1
		move.l	#_strbuff,d2
		moveq	#30,d3
		jsr	_LVORead(a6)		* get jump address

		cmpi.l	#1,d0			* was this address in range?
		bls.s	get_jumpin

		moveq	#5,d0
		bsr	StringToHex		* convert ascii to longword
		move.l	d0,_JumpAddr		* save start address

*-------------- now create the executable in memory..

		movea.l	_workspace_ptr,a0	* base of workspace..
		adda.l	_PackedLen,a0
		adda.l	#12,a0
		movea.l	a0,a1
		adda.l	#ExeHeader-PackCode,a1	* add length of decrunch header
		movea.l	a1,a2
		move.l	_PackedLen,d0
		addi.l	#12,d0
		move.l	d0,d1
		swap	d1
		bra.s	startcopy

bytecpy:	move.b	-(a0),-(a1)		* copy packed data in..
startcopy:	dbra	d0,bytecpy
		dbra	d1,bytecpy

		lea	ExeHeader,a0
		movea.l	_workspace_ptr,a1
		move.w	#(ExeHeader-PackCode)-1,d0
add_header:	move.b	(a0)+,(a1)+		* now copy header in to..
		dbra	d0,add_header

*-------------- calculate BCPL sizes for hunk headers..

		move.l	a2,d0
		sub.l	_workspace_ptr,d0
		subi.l	#36,d0
		move.l	d0,d1
		divu.w	#4,d1
		swap	d1
		tst.b	d1
		beq.s	patch_header

		addi.l	#2,d0
		move.l	d0,d1
		divu.w	#4,d1
		swap	d1
patch_header:	swap	d1			* d1 = hunk size (BCPL)

*-------------- insert correct sizes into executable decrunch header

		movea.l	_workspace_ptr,a0
		move.l	d1,exelen2-ExeHeader(a0)
		move.l	d1,exelen1-ExeHeader(a0)

*-------------- calculate final length of crunched file..

		addi.l	#36,d0
		movea.l	d0,a2
		adda.l	a0,a2
		addi.l	#24,d0
		subi.l	#12,d0
		move.l	d0,_PackedLen

		lea	BSS_Size,a0
		movea.l	a2,a1
		moveq	#24-1,d0
copy_bss_sec:	move.b	(a0)+,(a1)+
		dbra	d0,copy_bss_sec

*-------------- put decrunch and jump address into executable header..

		movea.l	_workspace_ptr,a0
		move.l	_LoadAddr,unpack_adr-ExeHeader(a0)	* put load address into executable header
		move.l	_JumpAddr,jmp_adr-ExeHeader(a0)		* put jump address into executable header

*-------------- get save filename..

Write_Data:	move.l	_StdOut,d1
		move.l	#SaveName.txt,d2
		move.l	#SaveNameEnd.txt-SaveName.txt,d3
		jsr	_LVOWrite(a6)		* show savename prompt

		move.l	_StdIn,d1
		move.l	#_strbuff,d2
		moveq	#30,d3
		jsr	_LVORead(a6)		* now get filename

		cmpi.l	#1,d0			* bad filename?
		bls.s	Write_Data

		subq.l	#1,d0
		lea	_strbuff,a0
		adda.l	d0,a0
		clr.b	(a0)

		lea	_strbuff,a0
		cmpi.b	#'-',(a0)		* execute a dos command?
		bne.s	write_file

		addq.l	#1,a0
		move.l	a0,d1
		moveq	#0,d2
		move.l	_StdOut,d3
		jsr	_LVOExecute(a6)		* do the execution..

		bra.s	Write_Data		* get save filename again..


write_file:	cmpi.l	#'exit',(a0)		* quit program,abort no save..
		beq.s	exitprog

*-------------- open save filename..

		move.l	#_strbuff,d1
		move.l	#MODE_NEWFILE,d2
		jsr	_LVOOpen(a6)		* open save file
		move.l	d0,_filehandle

*-------------- write data..

		move.l	d0,d1
		move.l	_workspace_ptr,d2
		move.l	_PackedLen,d3		* packed data length
		addi.l	#12,d3			* + header length..
		jsr	_LVOWrite(a6)		* write save file

		cmpi.l	#$FFFFFFFF,d0		* did save go ok?
		beq.l	Write_Data		* if not try again eh?

*-------------- close file..

		move.l	_filehandle,d1
		jsr	_LVOClose(a6)		* close save file.

*-------------- free workspace memory..

exitprog:	movea.l	AbsExecBase,a6		* execbase in a6
		move.l	_workspace_len,d0
		movea.l	_workspace_ptr,a1
		jsr	_LVOFreeMem(a6)		* free workspace

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

		movea.l	_DOSBase,a1
		jsr	_LVOCloseLibrary(a6)	* close dos libary

		clr.l	d0			* no return code for CLI..
		rts				* exit program..

****************************************************************************
* hex conversion routines..

*-------------- convert a hex string into a longword..

StringToHex:	movem.l	d1-d7/a0-a6,-(sp)	* save trashed registers

		move.l	d0,d3
		clr.l	d0			* erase registers
		clr.l	d1			* nb: should use 'moveq #0,dn'
		clr.l	d2			* instead of 'clr.l dn'.
						* its 2 cycles quicker.. 
		lea	_strbuff,a0		* ptr to string buffer
StrToHex:	move.b	(a0)+,d1		* read byte of string
		bsr.s	AsciiToHex		* byte to hex
		andi.w	#15,d1			* null out crap in d1
		lsl.l	#4,d2			* shift into place in longword
		or.w	d1,d2			* add into final longword
		cmpi.b	#10,(a0)		* reached Linefeed?
		beq.s	strdone			* if so stop conversion..
		dbra	d3,StrToHex
strdone:	move.l	d2,d0			* d0.l = converted longword

		movem.l	(sp)+,d1-d7/a0-a6	* restore trashed registers..
		rts

*-------------- return a value in range of 0-15 depending on ascii input char

AsciiToHex:	movem.l	d0/a0,-(sp)

		moveq	#0,d0
		lea	HexTable,a0
strhex1:	cmp.b	0(a0,d0.l),d1
		beq.s	strhex2
		addq.l	#1,d0
		cmpi.l	#16,d0
		bcs.s	strhex1	
strhex2:	move.l	d0,d1

		movem.l	(sp)+,d0/a0
		rts

*-------------- Print to screen a 6 character hex long as an ascii string

PrintSmallHex:	movem.l	d0-d7/a0-a6,-(sp)

		lea	_strbuff,a0
		adda.l	#6,a0
		lea	HexTable,a1
		move.b	#' ',-(a0)
		moveq	#4,d2
conv2:		move.l	d0,d1
		andi.l	#15,d1
		move.b	0(a1,d1.l),-(a0)
		lsr.l	#4,d0
		dbra	d2,conv2

		move.b	#'$',(a0)

		move.l	_StdOut,d1
		move.l	#_strbuff,d2
		moveq	#6,d3
		jsr	_LVOWrite(a6)

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

*-------------- Print to screen a 10 character hex long as an ascii string

PrintBigHex:	movem.l	d0-d7/a0-a6,-(sp)

		lea	_strbuff,a0
		adda.l	#10,a0
		lea	HexTable,a1
		move.b	#10,-(a0)
		moveq	#9-1,d2
conv4:		move.l	d0,d1
		andi.l	#15,d1
		move.b	0(a1,d1.l),-(a0)
		lsr.l	#4,d0
		dbra	d2,conv4

		move.b	#'$',(a0)		* put hex id into string..

		move.l	_StdOut,d1
		move.l	#_strbuff,d2
		moveq	#10,d3			* length of ascii hex string
		jsr	_LVOWrite(a6)		* write string to console

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

****************************************************************************
* Actual 'Mirage' packing routine

MiragePack:	movea.l	_workaddition,a0
		movea.l	_workaddition,a1
		adda.l	_OrigLen,a1		* source data

		movea.l	_workspace_ptr,a2	* destination (for packed data)
		move.l	#0,(a2)+
		move.l	_OrigLen,(a2)+		* put original length header
		move.l	#0,(a2)+

		moveq	#1,d2
		clr.w	d1
		clr.l	d7
mp1:		bsr.s	mp3
		tst.b	d0
		beq.s	mp2

		addq.w	#1,d1
		cmpi.w	#$108,d1
		bne.s	mp2

		bsr	mp19
mp2:		cmpa.l	a0,a1			* finished packing yet?
		bgt.s	mp1			* if not keep on..

		bsr	mp19
		bsr	mp_24
		move.l	a2,d0
		sub.l	_workspace_ptr,d0
		subi.l	#12,d0
		move.l	d0,_PackedLen
		movea.l	_workspace_ptr,a3
		move.l	d7,8(a3)
		move.l	d0,(a3)
		rts

mp3:		movea.l	a0,a3
		adda.l	_PackOffset,a3
		cmpa.l	a1,a3
		ble.s	mp4

		movea.l	a1,a3
mp4:		moveq	#1,d5
		movea.l	a0,a5
		addq.w	#1,a5
mp5:		move.b	(a0),d3
		move.b	1(a0),d4
mp6:		cmp.b	(a5)+,d3
		bne.s	mp7
		cmp.b	(a5),d4
		beq.s	mp8

mp7:		cmpa.l	a5,a3
		bgt.s	mp6
		bra.s	mp15

mp8:		subq.w	#1,a5
		movea.l	a0,a4
mp9:		move.b	(a4)+,d3
		cmp.b	(a5)+,d3
		bne.s	mp10

		cmpa.l	a5,a3
		bgt.s	mp9

mp10:		move.l	a4,d3
		sub.l	a0,d3
		subq.l	#1,d3
		cmp.l	d3,d5
		bge.s	mp14

		move.l	a5,d4
		sub.l	a0,d4
		sub.l	d3,d4
		subq.w	#1,d4
		cmpi.l	#4,d3
		ble.s	mp12

		moveq	#6,d6
		cmpi.l	#$101,d3
		blt.s	mp11

		move.w	#$100,d3
mp11:		bra.s	mp13

mp12:		move.w	d3,d6
		subq.w	#2,d6
		lsl.w	#1,d6
mp13:		lea	OffsetTable,a6
		cmp.w	0(a6,d6.w),d4
		bge.s	mp14

		move.l	d3,d5
		move.l	d4,mplong1
		move.b	d6,mp_word1
mp14:		cmpa.l	a5,a3
		bgt.s	mp5

mp15:		cmpi.l	#1,d5
		beq.s	mp17

		bsr	mp19
		move.b	mp_word1,d6
		move.l	mplong1,d3
		move.w	d3,_custom+color	* simple colour flash..
		move.w	8(a6,d6.w),d0
		bsr	mp_22
		move.w	$10(a6,d6.w),d0
		beq.s	mp16

		move.l	d5,d3
		subq.w	#1,d3
		bsr	mp_22
mp16:		move.w	$18(a6,d6.w),d0
		move.w	$20(a6,d6.w),d3
		bsr	mp_22
		addi.w	#1,$28(a6,d6.w)
		adda.l	d5,a0
		clr.b	d0
		rts

mp17:		move.b	(a0)+,d3
		moveq	#8,d0
		bsr.s	mp_22
		moveq	#1,d0
		rts

_PackOffset:	dc.l	0
mplong1:	dc.l	0
mp_word1:	dc.w	0
OffsetTable:	dc.w	$100,$200,$400,$1000,8,9,10,12,0,0,0,8,2,3,3,3,1,4,5,6
mp_longs1:	dc.l	0,0
mp_word2:	dc.w	0
mp_word3:	dc.w	0

mp19:		tst.w	d1
		beq.s	mp_done

		move.w	d1,d3
		clr.w	d1
		cmpi.w	#9,d3
		bge.s	mp_21

		addq.w	#1,mp_word2
		subq.w	#1,d3
		moveq	#5,d0
		bra.s	mp_22

mp_done:	rts

mp_21:		addq.w	#1,mp_word3
		subi.w	#9,d3
		ori.w	#$700,d3

		moveq	#12-1,d0
		nop
mp_22:		subq.w	#1,d0
mp_23:		lsr.l	#1,d3
		roxl.l	#1,d2
		bcs.s	mp_25

		dbra	d0,mp_23
		rts

mp_24:		clr.w	d0
mp_25:		move.l	d2,(a2)+	* store 4 bytes..
		eor.l	d2,d7
		moveq	#1,d2
		dbra	d0,mp_23
		rts

********************************************************************************
* Executable File header
********************************************************************************

_PackedLen:	dc.l	0		* start of file
ExeHeader:	dc.l	HUNK_HEADER,0	* hunk header
		dc.l	2,0,1		* 2 hunks in executable
exelen1:	dc.l	59		* correct size of executable / 4 
		dc.l	1,HUNK_CODE
exelen2:	dc.l	59		* correct size of executable / 4 

PackCode:	lea	UnpackSize(pc),a0	* packed data ptr
		lea	($12345678).l,a1	* decrunch address
unpack_adr	=	*-4
		move.l	(a0)+,d0
		move.l	(a0)+,d1
		move.l	(a0)+,d5
		movea.l	a1,a2
		adda.l	d0,a0
		adda.l	d1,a2
		move.l	-(a0),d0
		eor.l	d0,d5
unpack1:	lsr.l	#1,d0
		bne.s	unpack2

		bsr	unpack14
unpack2:	bcs.s	unpack9

		moveq	#8,d1
		moveq	#1,d3
		lsr.l	#1,d0
		bne.s	unpack3

		bsr	unpack14
unpack3:	bcs.s	unpack11

		moveq	#3,d1
		clr.w	d4
unpack4:	bsr	unpack15
		move.w	d2,d3
		add.w	d4,d3
unpack5:	moveq	#7,d1
unpack6:	lsr.l	#1,d0
		bne.s	unpack7

		bsr	unpack14
unpack7:	roxl.l	#1,d2
		dbra	d1,unpack6
		move.b	d2,-(a2)
		dbra	d3,unpack5
		bra	unpack13

unpack8:	moveq	#8,d1
		moveq	#8,d4
		bra	unpack4

unpack9:	moveq	#2,d1
		bsr	unpack15
		cmpi.b	#2,d2
		blt.s	unpack10

		cmpi.b	#3,d2
		beq.s	unpack8

		moveq	#8,d1
		bsr	unpack15
		move.w	d2,d3
		move.w	#12,d1
		bra	unpack11

unpack10:	move.w	#9,d1
		add.w	d2,d1
		addq.w	#2,d2
		move.w	d2,d3
unpack11:	bsr	unpack15
unpack12:	subq.w	#1,a2
		move.b	0(a2,d2.w),(a2)
		dbra	d3,unpack12
unpack13:	move.w	_custom+$106,_custom+color
		cmpa.l	a2,a1			* unpacked all data yet?
		blt	unpack1

		jmp	($12345678).l		* jump into depacked data..
jmp_adr		=	*-4

		move.w	#$FFFF,d0
unpack_error:	move.w	d0,_custom+color
		dbra	d0,unpack_error
		moveq	#-1,d0
		rts

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

unpack15:	subq.w	#1,d1
		clr.w	d2
unpack16:	lsr.l	#1,d0
		bne.s	unpack17

		move.l	-(a0),d0
		eor.l	d0,d5
		move.w	#$10,ccr
		roxr.l	#1,d0
unpack17:	roxl.l	#1,d2
		dbra	d1,unpack16
		rts
PackCodeEnd

UnpackSize:	dc.l	$E290E392
BSS_Size:	dc.l	HUNK_RELOC32,0,HUNK_END
		dc.l	HUNK_BSS,1,HUNK_END,-1,-1,-1

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

*-------------- Erase 30 byte string buffer

clear_strbuff:	movem.l	d0/a0,-(sp)		* save trashed registers

		lea	_strbuff,a0		* ptr to buffer to clear
		moveq	#15-1,d0		* loop 15 times
clrloop:	clr.w	(a0)+			* clear 2 bytes per loop
		dbra	d0,clrloop		* 15x2 = 30 bytes

		movem.l	(sp)+,d0/a0		* restore trashed registers
		rts

_OrigLen:	dc.l	0			* original file length (bytes)
_strbuff:	ds.b	30			* for strings..
_workspace_len:	dc.l	0			* workspace length (bytes)
_workspace_ptr:	dc.l	0			* workspace address (ptr)
_workaddition:	dc.l	0			* 2nd workspace address (ptr)
_LoadAddr:	dc.l	0			* load address (for executable)
_JumpAddr:	dc.l	0			* jump address (for executable)

HexTable:	dc.b	'0123456789abcdef'	* hex conversion table..


About.txt:	dc.b	10,$1B,'[4m',$1B,'[2m* MIRAGE-PACKER  V1.0 * ',$A,$A
		dc.b	$1B,'[0mİ 1993 By: X-ACT !',$1B,'[37m                         ',$A0,$A0,10
		dc.b	$1B,'[3mHighspeed',$1B,'[0m version by: Gizmo/XCT in 1994!     ',$A,$A
		dc.b	$1B,'[0m'
AboutEnd.txt:

Workspace.txt:	dc.b	10,10,'Allocate work space (KBbyte) : '
WorkspaceEnd.txt:

Loadname.txt:	dc.b	10,'Filename to load (exit to leave, -(command) to execute CLI command.)',$A,$A
		dc.b	'Filename/Command : '
LoadnameEnd.txt:

OrigLen.txt:	dc.b	10,'original length : '
OrigLenEnd.txt:

PackedLen.txt:	dc.b	10,10,'packed length   : '
PackedLenEnd.txt:

SaveName.txt:	dc.b	10,'save Filename (exit to leave, -(command) to execute CLI command.)',$A,$A
		dc.b	'Filename/Command : '
SaveNameEnd.txt:

Offset.txt:	dc.b	10,'offset (max $1000) :$'
OffsetEnd.txt:

SaveType.txt:	dc.b	10,'create executeable file or data file ? (e/d):'
SaveTypeEnd.txt:

LoadAddr.txt:	dc.b	10,'loacate file at :$'
LoadAddrEnd.txt:

JumpAdr.txt:	dc.b	10,'jump in :$1000) ',0
JumpAdrEnd.txt:
		dc.b	0,0
		
		end

