Joined: Thu May 28, 2009 9:46 pm Posts: 8507 Location: Midwestern USA
|
BigEd wrote: Oops, I think I've overcooked things a bit. Probably the users of this allocated memory can't do anything useful with an allocation which spans banks. And you can't span banks very usefully if they are not consecutive. So the allocator is perhaps separately managing two pools, or it has to satisfy large allocations sometimes by skipping to the start of the next bank. It could be done with page translation hardware. The problem, of course, is that it is said hardware would be external to the '816. Since it is the '816 that is responsible for setting the effective address, the cart is in front of the horse and the conventional methods of mapping virtual addresses to physical ones aren't going to work.
I don't see any obvious reason why an malloc function that spans banks can't be made to work. As you note, a large allocation would have to either start at the zeroth address of the next bank or be prepared to use multiple contiguous banks. The latter would require the use of 24 bit pointers for everything. Whomever was responsible for the development of the WDC C compiler worked out a solution. This excerpt from the C compiler's manual sheds some light on the subject:
Heap Functions
The ANSI standard library includes functions for allocating, freeing and reallocating memory from a memory heap. The WDC C Development System supports a heap built on top of the sbrk() function. This function allocates memory from a heap area that is specified by the programmer. The beginning of the heap is specified by declaring and initializing the two variables, heap_start and heap_end. The sbrk() function begins by allocating memory starting at heap_start and will continue to allocate until heap_end is reached. For the small and medium models, the heap must be in bank zero, while for the compact and large models, the heap may be anywhere in memory and of any size. [emphasis added]
For example:
void *heap_start = ( void * )0xa000, *heap_end = (void * )0xd000; void *heap_start = (void * )0x28000, *heap_end = (void * )0x48000; The first example allocates 0x3000 bytes of space in the zero bank. The second example allocates 128K of space in banks 2, 3 and 4. The ANSI functions that use the heap are malloc, calloc, realloc, and free. The sbrk function is not an ANSI function. The small and medium model libraries also contain the functions farsbrk, farmalloc, farfree, farrealloc, and farcalloc. These functions use full 32 bit pointers which must be declared as far in these models.
To have the heap start at the end of the “Unitialized Data” area, use the following statements:
extern char _END_UDATA: void *heap_start = ( void * )&_END_UDATA, *heap_end = ( void * )( &_END_UDATA + nnn ); The remark about sbrk not being an ANSI function is important—it's operating system dependent. The local operating system would have to provide some mechanism to implement sbrk, which could be modeled on UNIX's or Linux's implementation. In UNIX/Linux, the brk call sets a new absolute ending address for the heap space, whereas sbrk relocates the end of the heap space by adding its argument to the current address (a negative argument to sbrk shrinks the heap space size). Although it isn't clear from what I read, their sbrk function appears to model the UNIX/Linux equivalent.
_________________ x86? We ain't got no x86. We don't NEED no stinking x86!
|
|