/*
** $VER: AllocFrags.c 1.2 (18.10.97) by Bernardo Innocenti
**
** Brutally remove annoying holes in your memory list.
** Use this program right after SetPatch on 68040/060 systems.
*/

#include <exec/execbase.h>
#include <exec/memory.h>

#include <proto/exec.h>
#include <proto/dos.h>


LONG _main (void)
{
	struct DosLibrary *DOSBase;
	struct ExecBase	*SysBase;
	struct MemHeader *memheader;
	struct MemChunk *memchunk, *prevchunk;
	LONG allocsize;
	LONG chunks_cnt = 0, rem_cnt = 0;

	SysBase = *((struct ExecBase **) 4);

	Forbid();

	memheader = (struct MemHeader *)(SysBase->MemList.lh_Head);

	while (memheader->mh_Node.ln_Succ)
	{
		allocsize = 0;

		/* Fake prevchunk */
		prevchunk = (struct MemChunk *)(&memheader->mh_First);
		memchunk = memheader->mh_First;

		while (memchunk)
		{
			chunks_cnt++;

			if (memchunk->mc_Bytes <= 256)
			{
				/* Remove memory chunk */
				prevchunk->mc_Next = memchunk->mc_Next;
				allocsize += memchunk->mc_Bytes;
				rem_cnt++;
			}
			else
				/* Move prevchunk on current chunk */
				prevchunk = memchunk;

			/* Go to next chunk */
			memchunk = memchunk->mc_Next;
		}

		/* Fix free size otherwise we get a corrupted memory list
		 * guru as soon as someone calls AvailMem()
		 */
		memheader->mh_Free -= allocsize;

		memheader = (struct MemHeader *)memheader->mh_Node.ln_Succ;
	}

	Permit();


	/* Write stats */
	DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 0);
	Printf ("Total chunks: %ld, Removed: %ld\n", chunks_cnt, rem_cnt);
	CloseLibrary ((struct Library *)DOSBase);

	return 0;
}

static const char version[] = "$VER: AllocFrags 1.2 (18.10.97) by Bernardo Innocenti";
