The heap starts at 0x88024000 and ends at 0x8802FFFF
(48k). It is allocated in chunks of 0x400 bytes.
The system maintains a linked list of free heap-pieces. The pointer
linkliststart to the first item of this list is stored at 0x88004434
(OS 1.02..1.05, 1,05AU), 0x88004780 (OS1.10, 1.11), 0x880051A8 (OS 2.00,
2.00AU), 0x8800527C (OS 2.00 slim), 0x88005224 (OS 2.00 GII).
The linked list starts with a THeapFreePieceLinkedListItem, defining the
start of the linked (chained) list of free heap pieces (fragmentation).
Initially linkliststart is 0x88024000.
typedef
struct{
unsigned
int FreePieceLength;
void*next;
} THeapFreePieceLinkedListItem
FreePieceLength is the size of the free space immediately following the
actual THeapFreePieceLinkedListItem. T. i., if linkliststart
contains a value of 0x00000240, the next free heap piece starts at
linkliststart + 8 and is 0x23C long. If a chunk is used up, then
next-field is used as data area, too. This is not true for the first chunk,
starting at linkliststart.
THeapFreePieceLinkedListItem.next contains the pointer to the next
THeapFreePieceLinkedListItem struct. If next is zero, the free piece linked
list is at its end.
The following code walks along the heap’s free piece list:
THeapFreePieceLinkedListItem*FreePiece =
(THeapFreePieceLinkedListItem*)//linkliststart//;
while(
(*FreePiece).next
){
FreePiece = (THeapFreePieceLinkedListItem*)((*FreePiece).next);
}
To get the current heap load:
int HeapMaxContiguousPiece(
int*freespace ){
// freespace returns the sum of heap space available
int result = 0x88030000
- Heap_SetTopChunk(0);
// see SysCall 0x0499 below
*freespace = result;
THeapFreePieceLinkedListItem*FreePiece
= (THeapFreePieceLinkedListItem*)//linkliststart//;
while(
(*FreePiece).next
){
if ( result <
(*FreePiece).length
) result = (*FreePiece).length;
*freespace += (*FreePiece).length;
FreePiece = (THeapFreePieceLinkedListItem*)((*FreePiece).next);
}
if
( result < (*FreePiece).length
) result = (*FreePiece).length;
*freespace += (*FreePiece).length;
return
result;
}
heap related syscalls:
0x0499: int
Heap_SetTopChunk(int size);
Syscall 0x499 sets the next free heap chunk address
and returns the previous value. With size == 0 it returns the
address of the actual first free heap chunk. Usually size is
0x400-aligned. The syscall mustn’t be called with an argument other than
zero.
returns -1 if the request exceeds the upper heap limit