CP/M Plus memory management

Post Reply
sgjava
Member
Posts: 25
Joined: Thu Feb 22, 2024 9:25 pm

CP/M Plus memory management

Post by sgjava »

I'm trying to understand how the heap is allocated using:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
	char *test = (char*) malloc(5 * sizeof(char));
	unsigned short addr = (unsigned short) test;
	strcpy(test, "test");
	printf("%04x, %04x\n", test, addr);
	free(test);
	return 0;
}
The output looks like:

A>MEMTEST
B65F, B65F

According to https://github.com/z88dk/z88dk/wiki/Cla ... ive-sizing the heap should start with the last byte of the program? The program is like 4 or 5K and should be loaded at 0x100?

Build line looks like:

zcc +cpm -vn -DAMALLOC -I"$HOME/z88dk/include" -I./include -o ./build/demo/memtest.com ./src/demo/memtest.c

Target is C128 CPM Plus. On HTC compiler the heap does start after the last program byte using same code.
User avatar
dom
Well known member
Posts: 2304
Joined: Sun Jul 15, 2007 10:01 pm

Re: CP/M Plus memory management

Post by dom »

It looks like the heap allocates from the top down which explains the number you're getting.

In terms of heap sizing and location, I went through all targets and cleaned up their CRTs and in the progress added in a few pragmas to make things a bit more flexible.
Screenshot 2024-03-11 at 21.45.52.png
If you just specify -DAMALLOC then 75% of the memory between the end of the program and sp will be taken as heap space. -DAMALLOC2 uses 50% and -DAMALLOC3 uses 25%

So far so good, however IMO reserving say 25% of 40+K to the stack is over-generous.

Rather than do more maths, you could use -pragma-define:CRT_MAX_HEAP_ADDRESS=nnnn to set the highest heap address to that specified

Or if you just want a fixed size heap, -pragma-define:CLIB_MALLOC_HEAP_SIZE=nnn will do that for you.

I've just spotted the newlib has an option to specify how much memory to leave to the stack, so I'll add support in for that one as well.
You do not have the required permissions to view the files attached to this post.
sgjava
Member
Posts: 25
Joined: Thu Feb 22, 2024 9:25 pm

Re: CP/M Plus memory management

Post by sgjava »

Wow, OK, this explains it. I thought maybe it was backwards compared to HTC 309. Based on a previous post it was recommended to use:

#pragma output REGISTER_SP = -6

For CP/M plus, so when called from submit it didn't hang. This is all good info. Oh, and I agree with the large stack space. Unless your call stack has a lot of local vars does 25% make sense?
User avatar
dom
Well known member
Posts: 2304
Joined: Sun Jul 15, 2007 10:01 pm

Re: CP/M Plus memory management

Post by dom »

Oh, and I agree with the large stack space. Unless your call stack has a lot of local vars does 25% make sense?
Since 25% is a bit of a floating number it's hard to say! I think when it was added we weren't really thinking about CP/M with a 60k TPA - there's always been a programmatic way to setup the heap so -DAMALLOC was just a convenience.

However, I've now added CRT_STACK_SIZE to define the amount of memory available to the stack, so if you grab the next nightly you can use it. Details of usage on the pragma page: https://github.com/z88dk/z88dk/wiki/Classic--Pragmas and a longer discussion on the memory allocation page: https://github.com/z88dk/z88dk/wiki/Classic-allocation

There's also no need to specify the REGISTER_SP option - that's been taken care of now.
sgjava
Member
Posts: 25
Joined: Thu Feb 22, 2024 9:25 pm

Re: CP/M Plus memory management

Post by sgjava »

OK, thanks, I have a 59K CP/M TPA and at least with HTC I never had a problem with memory management. But I was only able to create programs ~20K .com size. I'm working my way through integrating asm code now. Eventually I'll come up with the correct recipe.

I ended up having to use a local buffer for https://github.com/sgjava/c3lz/blob/mai ... /convpcm.c because of heap corruption. It seems to revolve around file I/O, but I haven't tracked it down.
User avatar
dom
Well known member
Posts: 2304
Joined: Sun Jul 15, 2007 10:01 pm

Re: CP/M Plus memory management

Post by dom »

I just took a look at your project. This looks a bit suspicious in getDir:

Code: Select all

        struct fcb *fcb;
        retVal = bdos(CPM_FNXT, &fcb);
Passing the address of the pointer - it should be bdos(CPM_FNXT, fcb)
Post Reply