* FragCure by r@((e (6/10/97)

* Proggy that tries to minimise memory fragmentation using the trick
* discovered by the developer of "LowFrag" and a little unstable
* imitated by the man behind "FragLess" (which crashed badly on my 060
* at the uni)

* Written on my fascinating A500/512KChip/512KFast/Kick 40.063/1x1MBFDD
* using the ASM-One-clone Trash'M-One at home ,)

* Thanks to Lee Kindness for the SFPatch-archive on Aminet, which I used
* to get some knowledge about patching and to the authors of "LowFrag"
* (for the invention) and "FragLess" (for the motivation) of course.

_LVOOpenLibrary		=	-552
_LVOCloseLibrary	=	-414
_LVOAllocMem		=	-198
_LVOSetFunction		=	-420
_LVOForbid		=	-132
_LVOPermit		=	-138
_LVOCacheClearU		=	-636

MEMF_PUBLIC		=	1
MEMF_REVERSE		= 	$40000

_LVOReadArgs		=	-798
_LVOFreeArgs		=	-858


x
	move.l	4.w,a6
	lea	dosname(pc),a1
	moveq	#0,d0
	jsr	_LVOOpenLibrary(a6)	; open dos library
	lea	dosbase(pc),a0
	move.l	d0,(a0)
	beq	failopendos

	move.l	d0,a6
	lea	template(pc),a0
	move.l	a0,d1
	lea	array(pc),a1
	move.l	a1,d2
	moveq	#0,d3
	jsr	_LVOReadArgs(a6)	; read optional "BYTES"-argument
	lea	rdargs(pc),a0
	move.l	d0,(a0)
	beq.s	failreadargs

	move.l	array(pc),a0
	lea	bytes(pc),a1
	move.l	#32768,(a1)		; default no of bytes for the
					; "lower memory region"
	tst.l	(a0)
	beq.s	pickdefault
	move.l	(a0),(a1)		; copy no of bytes into allocpatch

pickdefault:
	move.l	4.w,a6
	moveq	#allocpatchend-allocpatchbeg,d0
	moveq	#MEMF_PUBLIC,d1
	jsr	_LVOAllocMem(a6)	; allocate some memory for the patch
	lea	patchaddr(pc),a0
	move.l	d0,(a0)
	beq.s	failallocpatch

	lea	allocpatchbeg(pc),a0
	move.l	d0,a1
	moveq	#allocpatchend-allocpatchbeg-1,d0
.copy:
	move.b	(a0)+,(a1)+		; copy patch into its rightful place
	dbf	d0,.copy

	move.l	4.w,a6
	jsr	_LVOForbid(a6)		; dunno if this has to be, copied
					; from SFPatch by Lee Kindness

	move.l	a6,a1
	move.w	#_LVOAllocMem,a0
	move.l	patchaddr(pc),d0
	jsr	_LVOSetFunction(a6)
	move.l	patchaddr(pc),a0	; put old address into our routine
					; (the routine JMPs back to the
					; OS routine after doing the trick)
	move.l	d0,dontpatch-allocpatchbeg+2(a0)

	jsr	_LVOCacheClearU(a6)	; clear cpu cache so the execution
					; cache is valid (taken from SFPatch)

	jsr	_LVOPermit(a6)		; taken from SFPatch again
	
failallocpatch:
	move.l	dosbase(pc),a6
	move.l	rdargs(pc),d1
	jsr	_LVOFreeArgs(a6)

failreadargs:
	move.l	4.w,a6
	move.l	dosbase(pc),a1
	jsr	_LVOCloseLibrary(a6)

failopendos:
	moveq	#0,d0			; quit out (no error code provided)
	rts


allocpatchbeg:
	lea	bytes(pc),a0
	cmp.l	(a0),d0
	blt.s	dontpatch

	or.l	#MEMF_REVERSE,d1

dontpatch:
	jmp	0

bytes:
	dc.l	0
allocpatchend:


dosbase:
	dc.l	0
dosname:
	dc.b	"dos.library",0
	cnop	0,4
template:
	dc.b	"BYTES/N",0
	cnop	0,4
array:
	dc.l	0
rdargs:
	dc.l	0
patchaddr:
	dc.l	0
