SuperH-based fx calculators
fx legacy: Heap

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
 

 

(19.03.2011 12:24:20)