Notes on the usage of MemManager_.mpas



1. Unlike Delphi, the memory manager has to be initialised in this library. I can not yet automate this (yet).
So, at init time 2 constant values have to be provided. Example:
const HEAP_START:word           = 2000; // the address of the lowest ram place to be used by the MemManager as Heap
      HEAP_SIZE:word            = 1000; // the size of that heap in bytes

The heap (the pool of available memory for dynamic variables) will reside in the area HEAP_START to (HEAP_START + HEAP_SIZE - 1).
The first constant(HEAP_START) gives the lower boundary of the heap, the second constant(HEAP_SIZE) gives its size in bytes.

Important:
Additionally, unlike Delphi again, the procedure FreeMem always requires the size parameter.

2. The memory manager maintains a list of free blocks in the heap with a fixed number of entries (const NR_FREE_BLOCKS).
If this "FreeList" is full and another "FreeMem" occurs then this is a fatal error: no recovery possible, the memory manager stops working (GetMem returns "zero" pointers). Only a memory manager init will get it going again.
The "FreeList" resides in a "normal" variable (so, ouside the heap) and takes a fixed NR_FREE_BLOCKS * 4 bytes.

Of course the freelist is defragmented (= entries if memory blocks which are adjacent are merged) when needed (= there are no free memory blocks large enough to satisfy a "GetMem" or the freelist is full after a "FreeMem").

3. It is imperative that "FreeMem" is used with pointervalues received from "GetMem", and that the same values for the "size" of the dynamic variables are used in both "FreeMem" and "GetMem".
There is no check on this, it would make the memory manager too heavy (this is also the reason why "FreeMem" always requires the "size" parameter).

Have fun!

The most important routines/declarations are:
// 2 constants to be declared in the definition part of your main unit:
const HEAP_START:word           = 2000; // the address of the lowest ram place to be used by the MemManager as Heap
      HEAP_SIZE:word            = 1000; // the size of that heap in bytes

procedure MM_Init;
// Initializes the memory manager

procedure GetMem(var P: Word; WantedSize: word);
// Fetches memory from the memory heap.
// Returns a pointer (> 0) to the fetched memory (of "WantedSize" bytes) in P if success,
//   otherwise 0 (no free blocks of memory are large enough...). This is not a fatal error,
//   there is only not enough memory at the moment. The memory manager stays operational.
// P is a variable of any pointer type.
// "WantedSize" is an expression specifying the size in bytes of the dynamic variable to allocate.
// Access the newly allocated memory by dereferencing the pointer; that is, use P^.

procedure FreeMem(var P: word; ActualSize: word);
// FreeMem destroys the variable referenced by P and returns its memory to the heap.
// P is a variable of any pointer type previously assigned by the GetMem procedure.
// "ActualSize" specifies the size in bytes of the dynamic variable to dispose of,
//   and should be the same as the one used to "GetMem".
// After calling FreeMem, the value of P is nil (0) (not assigned pointer).

-------------------------------------------