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