Re: [cc65] HEAP from here to there

From: Greg King <>
Date: 2009-06-05 02:51:29
From: "Ullrich von Bassewitz"; on Friday, May 29, 2009; at 05:00 PM -0400
> Regarding the heap segment: The current state of the sources seem to say
> that something like what you were suggesting was planned, and not
> finished.  Unfortunately, I'm so old that I cannot remember. :-)
> Most, but not all, platforms have a HEAP segment that is located at top of
> the RAM (or similar) area, but this segment is nowhere defined.
> I think (but, I'm not sure) that the plan was to mark the start of the
> heap with that segment to make it independent of BSS.  Using the size of
> the heap segment won't work with the current linker, because what we
> usually want is to use the complete remainder of the memory area that
> contains the BSS and STACK for the heap.  Since segments have fixed sizes,
> your suggestion is not satisfactory.  A fixed-size heap segment is either
> too small or too large for > 99% of all programs. :-) Maybe, that is the
> reason why the current solution is still in place:  It works quite well
> for most platforms and programs, and if you need something else, the hooks
> are in place to change the behaviour to your liking.

Uz is not as old as he thinks that he is. :-)
His description is what I had in mind when I put that "HEAP:" line in the
LD65 configure files.  But, Uz pointed out that my idea would have problems
on platforms that must copy the stack-pointer, at run-time, from system
variables (Apple2, Atari, and Pet, for example).  He left "HEAP:" in those
files because he planned to move the heap constructor out of the common part
of the library, and into the platform-specific part of the library.  Then,
we could use the configure-file method on platforms that allow it.


Here is my (improved) idea:

The boundaries of the heap would be formed by two segments (or, only one in
some targets).  They would be placed in different memory areas.  Their size
would be zero; only their starting addresses would be important.  The distance
between those two addresses would be the heap's size.

This would be the relevant part of the standard "c64.cfg" file:

    __STACKSIZE__: value = $800, weak = yes;    # 2 Ki stack
    ZP:  start = $02, size = $1A, define = yes;
    RAM: start = $07FF, size = $C801, define = yes;
    STACK: start = $D000-__STACKSIZE__, size = __STACKSIZE__, define = yes, file = "";
    ZEROPAGE: load = ZP,  type = zp;
    STARTUP:  load = RAM, type = ro,  optional = yes;
    LOWCODE:  load = RAM, type = rw,  optional = yes;
    CODE:     load = RAM, type = ro;
    RODATA:   load = RAM, type = ro;
    DATA:     load = RAM, type = rw;
    INIT:     load = RAM, type = rw,  optional = yes, define = yes;
    ZPSAVE:   load = RAM, type = bss, optional = yes;
    BSS:      load = RAM, type = bss,                 define = yes;
    HEAP:     load = RAM, type = bss, optional = yes;
    HEAPEND: load = STACK, type = bss, optional = yes;

And, the relevant part of "libsrc/c64/_heap.s" would be:

; This file doesn't need a constructor.


        .addr   heap
        .addr   heap
        .addr   heapend


        .res    2,0             ; zerobss puts NULL here
        .res    2,0

        .segment        "HEAP"

        .segment        "HEAPEND"

If __STACKSIZE__ is changed, then the heap automatically is adjusted.  It
uses all of the memory between the program and the stack.  And, if someone
needs to use some of that RAM for something else, then "HEAP" and "HEAPEND"
can be moved easily, without needing to rebuild the library.

Configure-files for targets like the Pet would not have the "STACK:" and
"HEAPEND:" lines in them.  And, those targets' "_heap.s" files would have
the constructor (the one that is there now).  But, the "HEAP" segment-marker
still would give programmers some flexibility!

To unsubscribe from the list send mail to with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Fri Jun 5 02:50:24 2009

This archive was generated by hypermail 2.1.8 : 2009-06-05 02:50:27 CEST