;XpkMASH library source (I)

;at the end of this file is included xpkMASH16.library.S from RAM:
;select directory as you wish 
;
;Compiled with 1.3 includes
;
;sys inc
	incdir	"df0:Include/"
;	incdir	"Include:"
	include	"exec/types.i"
	include	"exec/initializers.i"
	include	"exec/libraries.i"
	include	"exec/lists.i"
	include	"exec/nodes.i"
	include	"exec/resident.i"
	include	"exec/exec_lib.i"
	include	"exec/memory.i"
;xpk inc
	include	"libraries/xpk.i"
	include	"libraries/xpksub.i"

Pri		equ	-127
Version		equ	1
Revision	equ	16
ResVersion	equ	1

; global constants

PACKMEM		equ	0

UNPACKMEM	equ	0

PACKBUFFER	equ	$10000
HASHBUFFER	equ	$20000

; MASH librarystructure
		STRUCTURE	XpkMash,LIB_SIZE
		ULONG	xid_SysLib
		ULONG	xid_SegList
		STRUCT	xid_Reserved,32
		LABEL	XpkMash_SIZEOF

; usefull makros

CALLSYS MACRO
		jsr	_LVO\1(a6)
	ENDM

DummyEntry:	moveq	#-1,d0	;Tell all fools trying to execute us
		rts		;that our execution failed. ;-)

Resident:	dc.w	RTC_MATCHWORD
		dc.l	Resident
		dc.l	ResEnd
		dc.b	RTF_AUTOINIT
		dc.b	ResVersion
		dc.b	NT_LIBRARY
		dc.b	Pri
		dc.l	LibName
		dc.l	IdString
		dc.l	Init

LibName:	dc.b	'xpkMASH.library',0
IdString:	dc.b	'$VER: xpkMASH.library V1.16',13,10,0
		EVEN


Init:		dc.l	XpkMash_SIZEOF
		dc.l	FuncTable
		dc.l	DataTable
		dc.l	InitRoutine

; --- sys
FuncTable:	dc.l	Open
		dc.l	Close
		dc.l	Expunge
		dc.l	Null
; --- xpksub
		dc.l	PackerInfo
		dc.l	PackChunk
		dc.l	PackFree
		dc.l	PackReset
		dc.l	UnpackChunk
		dc.l	UnpackFree
; --- omega
		dc.l	-1


DataTable:	INITBYTE	LH_TYPE,NT_LIBRARY
		INITLONG	LN_NAME,LibName
		INITBYTE	LIB_FLAGS,LIBF_SUMUSED+LIBF_CHANGED
		INITWORD	LIB_VERSION,Version
		INITWORD	LIB_REVISION,Revision
		INITLONG	LIB_IDSTRING,IdString
		dc.l	0


InitRoutine:	move.l	a5,-(a7)
		move.l	d0,a5
		move.l	a6,xid_SysLib(a5)
		move.l	a0,xid_SegList(a5)
		move.l	(a7)+,a5
		rts

;--- sys entries

Open:		addq.w	#1,LIB_OPENCNT(a6)
		bclr.b	#LIBB_DELEXP,LIB_FLAGS(a6)
		move.l	a6,d0
rts00:		rts


Close:		moveq	#0,d0
		subq.w	#1,LIB_OPENCNT(a6)
		bne.s	rts00
		btst.b	#LIBB_DELEXP,LIB_FLAGS(a6)
		beq.s	rts00

	;;; Fall through to Expunge and remove the lib from memory.

Expunge:	movem.l	d1-d2/a5-a6,-(a7)
		move.l	a6,a5
		move.l	xid_SysLib(a5),a6
		tst.w	LIB_OPENCNT(a5)
		beq.s	exp1
		bset.b	#LIBB_DELEXP,LIB_FLAGS(a5)
		moveq	#0,d0
		bra.s	expEnd

exp1:		move.l	xid_SegList(a5),d2
		move.l	a5,a1
		CALLSYS	Remove
		moveq	#0,d0
		move.l	a5,a1
		move.w	LIB_NEGSIZE(a5),d0
		sub.l	d0,a1
		add.w	LIB_POSSIZE(a5),d0
		CALLSYS	FreeMem
		move.l	d2,d0
expEnd:		movem.l	(a7)+,d1-d2/a5-a6
		rts

Null:		moveq	#0,d0
		rts

; --- End of sys stuff ---


PACKCHUNKREGS	reg	d1-d7/a0-a6
PackChunk:
	movem.l PACKCHUNKREGS,-(a7)
	move.l	a6,a5			; lib base
	move.l	a0,a4			; xparams
	move.l	xid_SysLib(a5),a6

AllocPackMem:
	move.l	#PACKBUFFER,d0
	move.l	d0,d3
	moveq	#MEMF_PUBLIC,d1
	CALLSYS AllocMem
	tst.l	d0
	beq.b	NoMemoryMain
	move.l	d0,a2

packMemOK:
	movem.l	d3/a2,-(a7)
	move.l	#HASHBUFFER,d3		;$20000 bytes needed
	moveq	#8,d5			;16 bits hash
.next_try
	move.l	d3,d0
	moveq	#MEMF_PUBLIC,d1
	CALLSYS	AllocMem
	tst.l	d0
	bne.b	.memok
	lsr.l	#1,d3			;divide memory needed for hash func
	lsr.w	#1,d5
	cmp.w	#1,d5
	bcc.b	.next_try			;mim. 9 bits
	bra.b	NoMemoryHash
.memok	move.l	d0,a3
	movem.l	d3/a3,-(a7)		;d5:=number of bits for hash func
	move.l	xsp_InBuf(a4),a0        ;a0:=InBuf
	move.l	xsp_OutBuf(a4),a1       ;a1:=OutBuf
	move.l	xsp_InLen(a4),d7	;d7:=InLen
	lea	-50(a1,d7.l),a5
	move.l	a5,xsp_Sub+2*4(a4)	;xsp_Sub+8:=end of chunk
	move.l	xsp_Mode(a4),d1
	divs	#10,d1
	moveq	#1,d2
	asl.w	d1,d2
	move.l	d2,xsp_Sub+3*4(a4)	;xsp_Sub+12:=deep counter
					;a2:=Hash buffer
	bsr.w	Pack_It			;Call the compressor.
	move.l	d0,xsp_OutLen(a4)	;Fill in Final output length XpkSubParams

	movem.l	(a7)+,d0/a1		;Free allocated buffers
	CALLSYS	FreeMem

	movem.l	(a7)+,d0/a1
	CALLSYS	FreeMem

	tst.l	xsp_OutLen(a4)
	bne.s	Nooverrun
	moveq.l #XPKERR_EXPANSION,d0
	bra.s	endPackChunk
NoMemoryHash:					;Something goes wrong
	movem.l	(a7)+,d0/a1			;free allocated buffers
	CALLSYS	FreeMem
NoMemoryMain:
	moveq	#XPKERR_NOMEM,d0
	bra.s	endPackChunk	
Nooverrun:
	moveq	#XPKERR_OK,d0
endPackChunk:
	movem.l (sp)+,PACKCHUNKREGS
	rts

PackFree:
UnpackFree:
PackReset:	moveq	#XPKERR_OK,d0
		rts

UnpackChunk:	move.l	a1,-(sp)
		move.l	xsp_OutBuf(a0),a1
		move.l	a1,d4
		add.l	xsp_OutLen(a0),d4
		move.l	xsp_InBuf(a0),a0
		bsr.w	UnPack_It
		move.l	(sp)+,a1
		moveq	#XPKERR_OK,d0
		rts

PackerInfo:	move.l	a0,d0
		lea	MashInfo(pc),a0
		exg.l	a0,d0
		rts



; --- Static Data --------
MashInfo:
 dc.w	1		;xi_XpkInfoVersion:Version number of this structure
 dc.w	Version 	;xi_LibVersion	 : The version of this sublibrary
 dc.w	2		;xi_MasterVersion: The required master lib version
 dc.w	0		;xi_ModesVersion : Longword align
 dc.l	MashName	;xi_Name	 : Brief name of the packer
 dc.l	LongName	;xi_LongName	 : Full name of the packer
 dc.l	Description	;xi_Description  : One line description of packer
 dc.b	'MASH'          ;xi_ID           : ID the packer goes by (XPK format)
			;xi_Flags	 : Defined below
 dc.l	XPKIF_PK_CHUNK+XPKIF_UP_CHUNK+XPKIF_MODES
 dc.l	$f0000		;xi_MaxPkInChunk : Max input chunk size for packing
 dc.l	80		;xi_MinPkInChunk : Min input chunk size for packing
 dc.l	$10000		;xi_DefPkInChunk : Default packing chunk size
 dc.l	PackMsg 	;xi_PackMsg	 : Packing message, present tense
 dc.l	UnpackMsg	;xi_UnpackMsg	 : Unpacking message, present tense
 dc.l	PackedMsg	;xi_PackedMsg	 : Packing message, past tense
 dc.l	UnpackedMsg	;xi_UnpackedMsg  : Unpacking message, past tense
 dc.w	100		;xi_DefMode	 : Default mode number
 dc.w	0		;xi_Pad 	 : for future use
 dc.l	Modes		;xi_Modes	 : Array of compression modes
 dc.l	0,0,0,0,0,0	;xi_Reserved,6*4 : Future expansion - set to zero
		;LABEL	;xi_SIZEOF	 : Size of the *first* part only

MashName:	dc.b	'Mashiner',0
LongName:	dc.b	'MASH V1.16, another LZ77-family',0
Description:	dc.b	'WindowSize: 32KB, 2 mixed streams  '
		dc.b	'Dynamic Buffer Allocation,  Nice CF',0
PackMsg:	dc.b	'Mashing',0
PackedMsg:	dc.b	'Mashed',0
UnpackMsg:	dc.b	'UnMashing',0
UnpackedMsg:	dc.b	'UnMashed',0

	EVEN

Modes:
 dc.l	0		;xm_Next	  : Chain to next descriptor for ModeDesc list
 dc.l	100		;xm_Upto	  : Maximum efficiency handled by this mode.
			;xm_Flags	  : Defined below
 dc.l	0		;XPKMF_A3000SPEED
 dc.l	PACKMEM 	;xm_PackMemory	  : Extra memory required during packing
 dc.l	UNPACKMEM	;xm_UnpackMemory  : Extra memory during unpacking
 dc.l	18		;xm_PackSpeed	  : Approx packing speed in K per second
 dc.l	300		;xm_UnpackSpeed   : Approx unpacking speed in K per second
 dc.w	480		;xm_Ratio	  : CF in 0.1% for AmigaVision executable
 dc.w	0		;xm_ChunkSize	  : Desired chunk size in K (!!) for this mode
 dc.b	' -->    '      ;xm_Description,10:8 character mode description
 dc.l	0

		;LABEL	;xm_SIZEOF

	incdir	'ram:'
	include	'xpkMASH16.library.S'
ResEnd:
	
