From: Greg King (gngking_at_erols.com)
Date: 2003-05-20 22:11:22
From: Ullrich von Bassewitz
Date: Friday, April 25, 2003, 06:10 AM
>
> But, Shawn and Groepaz are right with one thing: This won't work with
> the current library code, because the heap is initialized to start
> at the end of the BSS segment, and extends to the bottom of the stack,
> which, in turn, is placed at the end of the RAM memory section.
> And, there is no way to use a HEAP segment as a general solution,
> because the linker can only handle fixed-size segments, while the heap
> size should vary, depending on the size of the program.
I recognize a challenge when I see one. I believe that I have discovered
a way to do it:
Only the linker-script defines the heap and the stack. ld65 determines
most of their addresses when a program is built. BSS, the heap,
and the stack don't need to be next to each other. The heap can be
stationary (pre-set location and size) or mobile (as in the C64).
They can be changed without changing the library.
Two segments, in different memory-areas,
are used as fences around the heap.
The crt0.s files set the stack-pointer to
"(__STK_START__ + __STK_SIZE__)".
stkchk.s uses "__STK_SIZE__" instead of "__STACKSIZE__".
This file defines the heap's pointers:
=====================================================================
; _heap.s
;
; Names that describe the heap:
; static size_t _heaporg; /* Bottom of heap */
; struct freeblock* _heapfirst; /* First free-block in list */
; struct freeblock* _heaplast; /* Last free-block in list */
; size_t* _heapptr; /* Current top */
; size_t _heapend; /* Upper limit */
.constructor initheap
.include "_heap.inc"
; Initiation -- is run during start-up.
;
initheap:
lda #<__heaporg
ldx #>__heaporg
sta __heapptr
stx __heapptr+1
rts
.bss
__heapfirst:
.res 2 ; zerobss puts NULL here
__heaplast:
.res 2
__heapptr:
.res 2
.segment "HEAP"
__heaporg:
.segment "HEAPEND"
__heapend:
=====================================================================
malloc.s, _heapmaxavail.s, _heapmemavail.s, _heap.h, heaptest.c,
and strdup-test.c use "__heaporg" and "__heapend" as immediate-addresses,
instead of, as variables.
Here are the relevant parts of the C64 target's configuration-script:
MEMORY {
ZP: ...
RAM: start = $07FF, size = $c801;
STK: start = $c800, size = $0800, define = yes, file = "";
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
STARTUP: load = RAM, type = wp;
...
...
...
BSS: load = RAM, type = bss, define = yes;
HEAP: load = RAM, type = bss;
HEAPEND: load = STK, type = bss;
}
...
...
...
#SYMBOLS {
# __STACKSIZE__ = $800; # (delete this section)
#}
And, here are the relevant parts of the NES target's configuration-script:
MEMORY {
ZP: ...
# ...
HEADER: ... , type = ro, ...
# ...
# - data (load)
# Hardware Vectors at end of 2nd 16k ROM
ROM0: start = $8000, size = $8000, type = ro, fill = yes;
# ...
ROM2: ... , type = ro, ...
# ...
# $0500-$0800 3 pages for cc65's parameter stack
STK: start = $0500, size = $0300, define = yes, file = "";
# ...
# - data (run)
# - bss
# - heap
RAM0: start = $6000, size = $2000;
RAM1: start = $8000, size = 1;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
HEADER: load = HEADER, type = wp;
STARTUP: load = ROM0, type = wp;
CODE: load = ROM0, type = ro;
RODATA: load = ROM0, type = ro;
DATA: load = ROM0, type = rw, define = yes, run = RAM0;
VECTORS: load = ROM0, type = ro, start = $fff4;
CHARS: load = ROM2, type = ro;
BSS: load = RAM0, type = bss, define = yes;
HEAP: load = RAM0, type = bss;
HEAPEND: load = RAM1, type = bss;
}
...
...
...
#SYMBOLS {
# __STACKSIZE__ = $0300; # (delete this section)
#}
The NES's heap and stack have a different relationship.
But, the library code is the same as it is for the C64's configuration
(and, for other configurations).
P.S.,
(I removed "define=yes" from ROM0, STARTUP, CODE, and RODATA.
They aren't needed, because the __DATA_SIZE__ number of bytes
should be copied from __DATA_LOAD__ to __DATA_RUN__.)
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo_at_musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
This archive was generated by hypermail 2.1.3 : 2003-05-20 22:17:16 CEST