Programming AmigaOS in C

Allocating Memory

a) Memory types

In the classic Amiga, there are these following memory types (see exec/memory.h):

MEMF_CHIP = Chip memory is used to stoe graphics, audio, sprite, bitmap information used by the custom chips on the Amiga.Upto 2MB is available.
MEMF_FAST = Faster memory used mainly by the processor.
MEMF_PUBLIC = Memory that is not mapped, swapped or otherwise non-addressable.
MEMF_ANY = Can use any type of available memory
MEMF_LOCAL = Memory that does not disappear after a reset such as autoconfig boards.
MEMF_24BITDMA = Memory within the address range of 24 bit DMA devices (Zorro II)
MEMF_KICK = Memory used by KickMem and KickTags.

MEMF_SHARED = New memory type in AmigaOS 4 (same as MEMF_ANY). Recommended type to use.
MEMF_PRIVATE = Memory is private to the task and it is swapped (Amiga OS 4).
MEMF_EXECUTABLE = Memory is used for PowerPC executable code (Amiga OS 4).

These additional memory attributes can be used with the above types:

MEMF_CLEAR= Clears the memory to zero.
MEMF_LARGEST = Returns the largest chunk size.
MEMF_REVERSE = Allocate memory from the top down
MEMF_TOTAL = Return total size of memory.
MEMF_NOEXPUNGE = Do not expunge memory on failure.

All memory functions are provided with the Exec.library or kernel. Use IExec-> for Amiga OS 4 functions.
To use the memory function you will need to include the following headers:

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

b) Allocating memory

i) AllocMem(byte size, attributes)

This will allocate a set number of bytes of type with the give memory type and attributes.
Also, test that the memory is allocated before trying to use it, otherwise it can cause application or system failures.
e.g.

UBYTE *buffer;
buffer = AllocMem( 256, MEMF_ANY | MEMF_CLEAR);

This will allocate 256 bytes of memory of any type and clear it to zeros.

Similar memory functions include Allocate(), AllocAbs() and AllocEntry().
In Amigos 4, the this function have been deprecated and replaced. See AllocVecTags.

ii) Freemem( pointer, byte size)

This will deallocate memory back to the system. You should not free memory that is already be freed, so you should test before freeing the memory.
e.g.

 if (buffer) FreeMem( buffer, 256);

iii) AllocVec (byte size, attributes) or AllocVecTagList() or AllocVecTags().

This will allocate a set number of bytes with the given memory type. This function is preferred over AllocMem as it can track memory used and is used on AmigaOS 4 systems.
e.g.

UBYTE *buffer;
buffer = AllocVec (256, MEMF_SHARED); /* Amiga OS 3 only */
or
buffer = AllocVecTagList ( 1000, AVT_Type, MEMF_SHARED, TAG_END); or buffer = IExec->AllocVecTagList ( 1000, AVT_Type, MEMF_SHARED, TAG_END); /* AmigaOS 4 */

iv) FreeVec( pointer )

The FreeVec function will free up the memory allocated by AllocVec, back to the system.
e.g.

if (buffer) FreeVec (pointer);
or
if (buffer) IExec->FreeVec (pointer); /* AmigaOS 4 */

v) CreatePool (memFlags, puddlesize, threshSize), AllocPooled (poolHeader, memSize) or AllocSysObject

These commands create and allocate 'pools' of memory which shrink or expand as necessary. Fixed sized 'puddles' are allocated by the pool manager when more memory is required.
Small allocations can fit in a single puddle. Allocations larger than the thresh size are allocated in their own puddles. This type of allocation is useful when lots of memory allocations are used,
and could prevent memory fragmentation. Use AllocSysObject() in AmigaOS 4 instead of CreatePool().
e.g.

poolhd = CreatePool(MEMF_ANY,  1024, 1024);

if (poolhd) memptr = AllocPooled (poolhd, 512);

For AmigaOS 4, use the AllocSysObject() or AllocSysObjectTags() functions with ASOT_MEMPOOL type to allocate pools of memory, for example, create a pool of memory of 4096 bytes with a threshold of 2048 bytes:

 APTR mem_pool = IExec->AllocSysObjectTags(ASOT_MEMPOOL, 
   ASOPOOL_Puddle, 4096, 
   ASOPOOL_Threshold, 2048,
   TAG_END);

To allocate memory from a pool, e.g. 512 bytes, use the AllocPooled() function and returns a pointer to the allocated memory.

some_mem = IExec->AllocPooled(mem_pool, 512);

vi) FreePooled (poolHeader, memory, memSize), DeletePool (poolHeader) or FreeSysObject(type, pool)

These will deallocate individual pool 'puddles' or delete the entire pool of memory. You will need to specify the memory size of each 'puddle' of memory as they are not tracked.
e.g.

if (memptr) FreePooled (poolhd, memptr, 512);

if (poolhd) DeletePool (poolhd); 

or

if (memptr) IExec->FreePooled (poolhd, memptr, 512); /* Amiga OS 4 */
IExec->FreeSysObject(ASOT_MEMPOOL, mempool); /* Amiga OS 4 */

Reading command line arguments