Hi,
I've been struggling with finding out how newlib manages to determine the heapsize on CP/M.
I'm trying to replicate this function under the default library, as newlib has no file operations available.
I can statically define memory and initialize the allocator there.
I can roughly determine the top of the stack by grabbing the address of a local variable, and roughly the end of the bss, by grabbing the address of a global variable.
Neither are really good enough for picking up the because I don't know how big the stack section might be, nor the true size of the BSS.
I'm surprised the documentation which goes into detail about how to go about setting up using mallinit/sbrk, but misses out this.
So is there a way of determining the highest address of BSS, and the lowest part of the stack within C?
oldlib/newlib heap initialisation
I hope I understood your question correctly, it seems to me we can split the arguments in three: how to determine the free memory on a CP/M system I order to assign the segments to stack, bss, heap, etc.. the newlib or the libraries in general (file i/o) an the two malloc library variants.
Could you please clarify what you are willing to get ? I suppose you are using the clib=new flag, correct ?
EDIT: could the -DAMALLOC compiler option meet your needs?
Could you please clarify what you are willing to get ? I suppose you are using the clib=new flag, correct ?
EDIT: could the -DAMALLOC compiler option meet your needs?
Hi Stefano!stefano wrote:I hope I understood your question correctly, it seems to me we can split the arguments in three: how to determine the free memory on a CP/M system I order to assign the segments to stack, bss, heap, etc.. the newlib or the libraries in general (file i/o) an the two malloc library variants.
Could you please clarify what you are willing to get ? I suppose you are using the clib=new flag, correct ?
EDIT: could the -DAMALLOC compiler option meet your needs?
I had been using clib=new, as it's new and shiny and has an out of the box working malloc.
Alas I had to revert to classic library, as newlib doesn't have file support.
newlib appears to sbrk around 50K to the heap
-DAMALLOC appears sbrk around 40K to the heap
Both running on the RunCPM emulator which is just fine.
***So yes, it appears that -DAMALLOC is exactly what I needed here***. Thank you.
....Though a bit more googling I see a '-pragma-define:USING_amalloc' I presume this is a more verbose or depricated way of saying the same thing?
A bit more verbose one. AMALLOC is in most of the case little more than a trick setting the heap automatically at an average size.
We borrowed a good portion of the new lib bringing into the classic lib, but we rarely did the opposite. As far as I know the new lib is far more flexible on the way it deals with the file streams.
On the other side, the classic lib had a longer life and few more tricks developed on it (e.g. the user specified file redirection on the command line).
We borrowed a good portion of the new lib bringing into the classic lib, but we rarely did the opposite. As far as I know the new lib is far more flexible on the way it deals with the file streams.
On the other side, the classic lib had a longer life and few more tricks developed on it (e.g. the user specified file redirection on the command line).
As Stefano has indicated, there's been a consolidation of library code, with classic taking much of the standard library (and newlib algorithms etc), there's an intro to classic on this page: https://github.com/z88dk/z88dk/wiki/Classic-Overview
From the viewpoint of CP/M the only real difference will be in stdio and fileio, there's some upcoming work which should also allow classic to work on 8080 based CP/M machines (albeit with some limitations).
To come back to your original question, the end of BSS space can be found via:
Or from C something like this should work:
The stack is impossible to tell - each CP/M machine will have a slightly different TPA and the stack usage of your program is unknown so your guess using the value of sp is as good as any.
The usage of sbrk makes more sense on a machine with a fragmented memory map - eg on the Spectrum the default is to load programs to 32768. The main heap will go after it, but there's unused memory below 32768 which could be added into the heap using sbrk.
From the viewpoint of CP/M the only real difference will be in stdio and fileio, there's some upcoming work which should also allow classic to work on 8080 based CP/M machines (albeit with some limitations).
To come back to your original question, the end of BSS space can be found via:
Code: Select all
#asm
EXTERN __BSS_END_tail
ld hl,__BSS_END_tail
#endasm
Code: Select all
extern void *_BSS_END_tail;
#define BASS_END &_BSS_END_tail
The usage of sbrk makes more sense on a machine with a fragmented memory map - eg on the Spectrum the default is to load programs to 32768. The main heap will go after it, but there's unused memory below 32768 which could be added into the heap using sbrk.