From: cuz Date: Sat, 1 Feb 2003 12:22:09 +0000 (+0000) Subject: Move _heap.h to the compiler include dir. X-Git-Tag: V2.12.0~1775 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=581c12ce40334b5a138260a033e770389bbb27fc;p=cc65 Move _heap.h to the compiler include dir. Create heap.inc and use that from the assembler code. Rename heap related _h... variables to _heap... Add _heapmaxavail and _heapmemavail functions. git-svn-id: svn://svn.cc65.org/cc65/trunk@1912 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/asminc/_heap.inc b/asminc/_heap.inc new file mode 100644 index 000000000..aef77cbf0 --- /dev/null +++ b/asminc/_heap.inc @@ -0,0 +1,25 @@ +; +; _heap.inc +; +; (C) Copyright 2003 Ullrich von Bassewitz (uz@cc65.org) +; + +; Assembler include file that makes the constants and structures in _heap.h +; available for asm code. + +HEAP_ADMIN_SPACE = 2 +HEAP_MIN_BLOCKSIZE = 6 ; Minimum size of an allocated block + +; Struct freeblock offsets and size. NOTE: For performance reasons, the asm +; code often uses increment/decrement operators to access other offsets, so +; just changing offsets here will probably not work. +freeblock_size = 0 +freeblock_next = 2 +freeblock_prev = 4 + +; Variables +.global __heaporg +.global __heapptr +.global __heapend +.global __heapfirst +.global __heaplast diff --git a/include/_heap.h b/include/_heap.h new file mode 100644 index 000000000..f4019da20 --- /dev/null +++ b/include/_heap.h @@ -0,0 +1,43 @@ +/* + * _heap.h + * + * Ullrich von Bassewitz, 03.06.1998 + * + */ + + + +#ifndef __HEAP_H +#define __HEAP_H + + + +/* Space needed for administering used blocks */ +#define HEAP_ADMIN_SPACE sizeof (unsigned) + +/* The data type used to implement the free list. + * Beware: Field order is significant! + */ +struct freeblock { + unsigned size; + struct freeblock* next; + struct freeblock* prev; +}; + + + +/* Variables that describe the heap */ +extern unsigned* _heaporg; /* Bottom of heap */ +extern unsigned* _heapptr; /* Current top */ +extern unsigned* _heapend; /* Upper limit */ +extern struct freeblock* _heapfirst; /* First free block in list */ +extern struct freeblock* _heaplast; /* Last free block in list */ + + + +/* End of _heap.h */ + +#endif + + + diff --git a/include/stdlib.h b/include/stdlib.h index 166eb743a..b57b62a40 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -57,8 +57,17 @@ void* __fastcall__ malloc (size_t size); void* __fastcall__ calloc (size_t count, size_t size); void* __fastcall__ realloc (void* block, size_t size); void __fastcall__ free (void* block); -/* Non standard functions */ -void __fastcall__ _heapadd (void* mem, size_t size); + +/* Non standard memory management functions */ + +void __fastcall__ _heapadd (void* mem, size_t size); +/* Add a block to the heap */ + +size_t __fastcall__ _heapmemavail (void); +/* Return the total free heap space */ + +size_t __fastcall__ _heapmaxavail (void); +/* Return the size of the largest free block on the heap */ /* Random numbers */ #define RAND_MAX 0x7FFF diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index d15852fd4..781019579 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -54,6 +54,8 @@ S_OBJS = _fdesc.o \ _fopen.o \ _heap.o \ _heapadd.o \ + _heapmaxavail.o \ + _heapmemavail.o \ _oserror.o \ _printf.o \ _swap.o \ diff --git a/libsrc/common/_heap.h b/libsrc/common/_heap.h deleted file mode 100644 index 3f8d7800f..000000000 --- a/libsrc/common/_heap.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * _heap.h - * - * Ullrich von Bassewitz, 03.06.1998 - * - */ - - - -#ifndef __HEAP_H -#define __HEAP_H - - - -/* Space needed for administering used blocks */ -#define HEAP_ADMIN_SPACE sizeof (unsigned) - -/* The data type used to implement the free list. - * Beware: Field order is significant! - */ -struct freeblock { - unsigned size; - struct freeblock* next; - struct freeblock* prev; -}; - - - -/* Variables that describe the heap */ -extern unsigned* _horg; /* Bottom of heap */ -extern unsigned* _hptr; /* Current top */ -extern unsigned* _hend; /* Upper limit */ -extern struct freeblock* _hfirst; /* First free block in list */ -extern struct freeblock* _hlast; /* Last free block in list */ - - - -/* End of _heap.h */ - -#endif - - - diff --git a/libsrc/common/_heap.s b/libsrc/common/_heap.s index 5758c7c34..30b89b81e 100644 --- a/libsrc/common/_heap.s +++ b/libsrc/common/_heap.s @@ -4,23 +4,25 @@ ; Heap variables and initialization. ; - .export __horg, __hptr, __hend, __hfirst, __hlast .constructor initheap, 24 .import __BSS_RUN__, __BSS_SIZE__, __STACKSIZE__ .importzp sp + .include "_heap.inc" + + .data -__horg: +__heaporg: .word __BSS_RUN__+__BSS_SIZE__ ; Linker calculates this symbol -__hptr: - .word __BSS_RUN__+__BSS_SIZE__ ; Dito -__hend: +__heapptr: + .word __BSS_RUN__+__BSS_SIZE__ ; Dito +__heapend: .word __BSS_RUN__+__BSS_SIZE__ -__hfirst: - .word 0 -__hlast: - .word 0 +__heapfirst: + .word 0 +__heaplast: + .word 0 ; Initialization. Will be called from startup! @@ -28,12 +30,12 @@ __hlast: .code initheap: - sec - lda sp - sbc #<__STACKSIZE__ - sta __hend - lda sp+1 + sec + lda sp + sbc #<__STACKSIZE__ + sta __heapend + lda sp+1 sbc #>__STACKSIZE__ - sta __hend+1 + sta __heapend+1 rts diff --git a/libsrc/common/_heapadd.s b/libsrc/common/_heapadd.s index d6703e820..f2f9b6826 100644 --- a/libsrc/common/_heapadd.s +++ b/libsrc/common/_heapadd.s @@ -10,22 +10,16 @@ .importzp ptr1, ptr2 .import popax .import heapadd - .export _heapadd + .export __heapadd - .macpack generic - -; Offsets into struct freeblock and other constant stuff - -size = 0 -next = 2 -prev = 4 -admin_space = 2 -min_size = 6 + .include "_heap.inc" + .macpack generic +;----------------------------------------------------------------------------- ; Code -_heapadd: +__heapadd: sta ptr1 ; Store size in ptr1 stx ptr1+1 jsr popax ; Get the block pointer @@ -39,14 +33,14 @@ _heapadd: lda ptr1 ; Load low byte ldx ptr1+1 ; Load/check high byte bne @L1 - cmp #min_size + cmp #HEAP_MIN_BLOCKSIZE bcs @L1 rts ; Block not large enough ; The block is large enough. Set the size field in the block. -@L1: ldy #size +@L1: ldy #freeblock_size sta (ptr2),y iny txa @@ -56,5 +50,3 @@ _heapadd: jmp heapadd - - diff --git a/libsrc/common/_heapmaxavail.s b/libsrc/common/_heapmaxavail.s new file mode 100644 index 000000000..5446c3f28 --- /dev/null +++ b/libsrc/common/_heapmaxavail.s @@ -0,0 +1,77 @@ +; +; Ullrich von Bassewitz, 2003-02-01 +; +; Return the size of the largest free block on the heap. +; +; size_t __fastcall__ _heapmaxavail (void); +; +; + + .importzp ptr1, ptr2 + .export __heapmaxavail + + .include "_heap.inc" + + .macpack generic + +;----------------------------------------------------------------------------- +; Code + +__heapmaxavail: + +; size_t Size = (_heapend - _heapptr) * sizeof (*_heapend); + + lda __heapend + sub __heapptr + sta ptr2 + lda __heapend+1 + sbc __heapptr+1 + sta ptr2+1 + +; struct freeblock* F = _heapfirst; + + lda __heapfirst + sta ptr1 + lda __heapfirst+1 +@L1: sta ptr1+1 + +; while (F) { + + ora ptr1 + beq @L3 ; Jump if end of free list reached + +; if (Size < F->size) { + + ldy #freeblock_size + lda ptr2 + sub (ptr1),y + iny + lda ptr2+1 + sbc (ptr1),y + bcs @L2 + +; Size = F->size; + + ldy #freeblock_size + lda (ptr1),y + sta ptr2 + iny + lda (ptr1),y + sta ptr2+1 + +; F = F->next; + +@L2: iny ; Points to F->next + lda (ptr1),y + tax + iny + lda (ptr1),y + stx ptr1 + jmp @L1 + +; return Size; + +@L3: lda ptr2 + ldx ptr2+1 + rts + diff --git a/libsrc/common/_heapmemavail.s b/libsrc/common/_heapmemavail.s new file mode 100644 index 000000000..b628b1b92 --- /dev/null +++ b/libsrc/common/_heapmemavail.s @@ -0,0 +1,81 @@ +; +; Ullrich von Bassewitz, 2003-02-01 +; +; Return the amount of free memory on the heap. +; +; size_t __fastcall__ _heapmemavail (void); +; +; + + .importzp ptr1, ptr2 + .export __heapmemavail + + .include "_heap.inc" + + .macpack generic + +;----------------------------------------------------------------------------- +; Code + +__heapmemavail: + +; size_t Size = 0; + + lda #0 + sta ptr2 + sta ptr2+1 + +; struct freeblock* F = _heapfirst; + + lda __heapfirst + sta ptr1 + lda __heapfirst+1 +@L1: sta ptr1+1 + +; while (F) { + + ora ptr1 + beq @L2 ; Jump if end of free list reached + +; Size += F->size; + + ldy #freeblock_size + lda (ptr1),y + add ptr2 + sta ptr2 + iny + lda (ptr1),y + adc ptr2+1 + sta ptr2+1 + +; F = F->next; + + iny ; Points to F->next + lda (ptr1),y + tax + iny + lda (ptr1),y + stx ptr1 + jmp @L1 + +; return Size + (_heapend - _heapptr) * sizeof (*_heapend); + +@L2: lda ptr2 + add __heapend + sta ptr2 + lda ptr2+1 + adc __heapend+1 + tax + + lda ptr2 + sub __heapptr + sta ptr2 + txa + sbc __heapptr+1 + tax + lda ptr2 + + rts + + + diff --git a/libsrc/common/free.s b/libsrc/common/free.s index 62a9122c6..0ba91f133 100644 --- a/libsrc/common/free.s +++ b/libsrc/common/free.s @@ -60,20 +60,13 @@ ; .importzp ptr1, ptr2, ptr3, ptr4 - .import __hptr, __hfirst, __hlast, __hend .export _free, heapadd - .macpack generic - -; Offsets into struct freeblock and other constant stuff - -size = 0 -next = 2 -prev = 4 -admin_space = 2 -min_size = 6 + .include "_heap.inc" + .macpack generic +;----------------------------------------------------------------------------- ; Code _free: sta ptr2 @@ -89,11 +82,11 @@ _free: sta ptr2 ; Remember the block size in ptr1. lda ptr2 - sub #admin_space + sub #HEAP_ADMIN_SPACE sta ptr2 bcs @L1 dec ptr2+1 -@L1: ldy #size+1 +@L1: ldy #freeblock_size+1 lda (ptr2),y ; High byte of size sta ptr1+1 ; Save it dey @@ -106,66 +99,66 @@ _free: sta ptr2 tay lda ptr2+1 adc ptr1+1 - cpy __hptr - bne heapadd ; Add to free list - cmp __hptr+1 + cpy __heapptr + bne heapadd ; Add to free list + cmp __heapptr+1 bne heapadd ; The pointer is located at the heap top. Lower the heap top pointer to ; release the block. @L3: lda ptr2 - sta __hptr + sta __heapptr lda ptr2+1 - sta __hptr+1 + sta __heapptr+1 ; Check if the last block in the freelist is now at heap top. If so, remove ; this block from the freelist. - lda __hlast + lda __heaplast sta ptr1 - ora __hlast+1 + ora __heaplast+1 beq @L9 ; Jump if free list empty - lda __hlast+1 + lda __heaplast+1 sta ptr1+1 ; Pointer to last block now in ptr1 - ldy #size + ldy #freeblock_size lda (ptr1),y ; Low byte of block size add ptr1 tax - iny ; High byte of block size + iny ; High byte of block size lda (ptr1),y adc ptr1+1 - cmp __hptr+1 + cmp __heapptr+1 bne @L9 ; Jump if last block not on top of heap - cpx __hptr + cpx __heapptr bne @L9 ; Jump if last block not on top of heap ; Remove the last block lda ptr1 - sta __hptr + sta __heapptr lda ptr1+1 - sta __hptr+1 + sta __heapptr+1 ; Correct the next pointer of the now last block - ldy #prev+1 ; Offset of ->prev field + ldy #freeblock_prev+1 ; Offset of ->prev field lda (ptr1),y - sta ptr2+1 ; Remember f->prev in ptr2 - sta __hlast+1 + sta ptr2+1 ; Remember f->prev in ptr2 + sta __heaplast+1 dey lda (ptr1),y sta ptr2 ; Remember f->prev in ptr2 - sta __hlast - ora __hlast+1 ; -> prev == 0? + sta __heaplast + ora __heaplast+1 ; -> prev == 0? bne @L8 ; Jump if free list not empty ; Free list is now empty (A = 0) - sta __hfirst - sta __hfirst+1 + sta __heapfirst + sta __heapfirst+1 ; Done @@ -176,9 +169,9 @@ _free: sta ptr2 @L8: lda #$00 dey ; Points to high byte of ->next sta (ptr2),y - dey ; Low byte of f->prev->next + dey ; Low byte of f->prev->next sta (ptr2),y - rts ; Done + rts ; Done ; The block is not on top of the heap. Add it to the free list. This was ; formerly a separate function called __hadd that was implemented in C as @@ -235,10 +228,10 @@ _free: sta ptr2 ; /* Merge with the right block */ ; f->size += right->size; ; if (f->next = right->next) { -; f->next->prev = f; +; f->next->prev = f; ; } else { -; /* This is now the last block */ -; _hlast = f; +; /* This is now the last block */ +; _hlast = f; ; } ; } else { ; /* No merge, just set the link */ @@ -256,10 +249,10 @@ _free: sta ptr2 ; /* Merge with the left block */ ; left->size += f->size; ; if (left->next = f->next) { -; left->next->prev = left; +; left->next->prev = left; ; } else { -; /* This is now the last block */ -; _hlast = left; +; /* This is now the last block */ +; _hlast = left; ; } ; } else { ; /* No merge, just set the link */ @@ -279,9 +272,9 @@ _free: sta ptr2 ; Check if the free list is empty, storing _hfirst into ptr3 for later heapadd: - lda __hfirst + lda __heapfirst sta ptr3 - lda __hfirst+1 + lda __heapfirst+1 sta ptr3+1 ora ptr3 bne SearchFreeList @@ -289,49 +282,49 @@ heapadd: ; The free list is empty, so this is the first and only block. A contains ; zero if we come here. - ldy #next-1 -@L2: iny ; f->next = f->prev = 0; + ldy #freeblock_next-1 +@L2: iny ; f->next = f->prev = 0; sta (ptr2),y - cpy #prev+1 ; Done? + cpy #freeblock_prev+1 ; Done? bne @L2 lda ptr2 ldx ptr2+1 - sta __hfirst - stx __hfirst+1 ; _hfirst = f; - sta __hlast - stx __hlast+1 ; _hlast = f; + sta __heapfirst + stx __heapfirst+1 ; _heapfirst = f; + sta __heaplast + stx __heaplast+1 ; _heaplast = f; - rts ; Done + rts ; Done ; We have to search the free list. As we are doing so, check if it is possible ; to combine this block with another, already existing block. Beware: The ; block may be the "missing link" between two blocks. ; ptr3 contains _hfirst (the start value of the search) when execution reaches -; this point, Y contains size+1. We do also know that _hfirst (and therefore +; this point, Y contains size+1. We do also know that _heapfirst (and therefore ; ptr3) is not zero on entry. SearchFreeList: lda #0 sta ptr4 - sta ptr4+1 ; left = 0; - ldy #next+1 + sta ptr4+1 ; left = 0; + ldy #freeblock_next+1 ldx ptr3 -@Loop: lda ptr3+1 ; High byte of right +@Loop: lda ptr3+1 ; High byte of right cmp ptr2+1 bne @L1 cpx ptr2 beq @L2 @L1: bcs CheckRightMerge -@L2: stx ptr4 ; left = right; +@L2: stx ptr4 ; left = right; sta ptr4+1 - dey ; Points to next - lda (ptr3),y ; right = right->next; + dey ; Points to next + lda (ptr3),y ; right = right->next; tax - iny ; Points to next+1 + iny ; Points to next+1 lda (ptr3),y stx ptr3 sta ptr3+1 @@ -342,14 +335,14 @@ SearchFreeList: ; a merge. The new block is the new freelist end. ; A is zero when we come here, Y points to next+1 - sta (ptr2),y ; Clear high byte of f->next + sta (ptr2),y ; Clear high byte of f->next dey - sta (ptr2),y ; Clear low byte of f->next + sta (ptr2),y ; Clear low byte of f->next - lda ptr2 ; _hlast = f; - sta __hlast + lda ptr2 ; _heaplast = f; + sta __heaplast lda ptr2+1 - sta __hlast+1 + sta __heaplast+1 ; Since we have checked the case that the freelist is empty before, if the ; right pointer is NULL, the left *cannot* be NULL here. So skip the @@ -362,7 +355,7 @@ SearchFreeList: CheckRightMerge: lda ptr2 - add ptr1 ; f + size + add ptr1 ; f + size tax lda ptr2+1 adc ptr1+1 @@ -374,11 +367,11 @@ CheckRightMerge: ; Merge with the right block. Do f->size += right->size; - ldy #size + ldy #freeblock_size lda ptr1 add (ptr3),y sta (ptr2),y - iny ; Points to size+1 + iny ; Points to size+1 lda ptr1+1 adc (ptr3),y sta (ptr2),y @@ -386,153 +379,154 @@ CheckRightMerge: ; Set f->next = right->next and remember f->next in ptr1 (we don't need the ; size stored there any longer) - iny ; Points to next - lda (ptr3),y ; Low byte of right->next - sta (ptr2),y ; Store to low byte of f->next + iny ; Points to next + lda (ptr3),y ; Low byte of right->next + sta (ptr2),y ; Store to low byte of f->next sta ptr1 - iny ; Points to next+1 - lda (ptr3),y ; High byte of right->next - sta (ptr2),y ; Store to high byte of f->next + iny ; Points to next+1 + lda (ptr3),y ; High byte of right->next + sta (ptr2),y ; Store to high byte of f->next sta ptr1+1 ora ptr1 - beq @L1 ; Jump if f->next zero + beq @L1 ; Jump if f->next zero ; f->next->prev = f; - iny ; Points to prev - lda ptr2 ; Low byte of f - sta (ptr1),y ; Low byte of f->next->prev - iny ; Points to prev+1 - lda ptr2+1 ; High byte of f - sta (ptr1),y ; High byte of f->next->prev - jmp CheckLeftMerge ; Done + iny ; Points to prev + lda ptr2 ; Low byte of f + sta (ptr1),y ; Low byte of f->next->prev + iny ; Points to prev+1 + lda ptr2+1 ; High byte of f + sta (ptr1),y ; High byte of f->next->prev + jmp CheckLeftMerge ; Done ; f->next is zero, this is now the last block -@L1: lda ptr2 ; _hlast = f; - sta __hlast +@L1: lda ptr2 ; _heaplast = f; + sta __heaplast lda ptr2+1 - sta __hlast+1 + sta __heaplast+1 jmp CheckLeftMerge ; No right merge, just set the link. NoRightMerge: - ldy #next ; f->next = right; + ldy #freeblock_next ; f->next = right; lda ptr3 sta (ptr2),y - iny ; Points to next+1 + iny ; Points to next+1 lda ptr3+1 sta (ptr2),y - iny ; Points to prev - lda ptr2 ; right->prev = f; + iny ; Points to prev + lda ptr2 ; right->prev = f; sta (ptr3),y - iny ; Points to prev+1 + iny ; Points to prev+1 lda ptr2+1 sta (ptr3),y ; Check if the left pointer is zero CheckLeftMerge: - lda ptr4 ; left == NULL? + lda ptr4 ; left == NULL? ora ptr4+1 - bne CheckLeftMerge2 ; Jump if there is a left block + bne CheckLeftMerge2 ; Jump if there is a left block ; We don't have a left block, so f is actually the new freelist start - ldy #prev - sta (ptr2),y ; f->prev = 0; + ldy #freeblock_prev + sta (ptr2),y ; f->prev = 0; iny sta (ptr2),y - lda ptr2 ; _hfirst = f; - sta __hfirst + lda ptr2 ; _heapfirst = f; + sta __heapfirst lda ptr2+1 - sta __hfirst+1 + sta __heapfirst+1 - rts ; Done + rts ; Done ; Check if the left block is adjacent to the following one CheckLeftMerge2: - ldy #size ; Calculate left + left->size - lda (ptr4),y ; Low byte of left->size + ldy #freeblock_size ; Calculate left + left->size + lda (ptr4),y ; Low byte of left->size add ptr4 tax - iny ; Points to size+1 - lda (ptr4),y ; High byte of left->size + iny ; Points to size+1 + lda (ptr4),y ; High byte of left->size adc ptr4+1 cpx ptr2 bne NoLeftMerge cmp ptr2+1 - bne NoLeftMerge ; Jump if blocks not adjacent + bne NoLeftMerge ; Jump if blocks not adjacent ; Merge with the left block. Do left->size += f->size; - dey ; Points to size + dey ; Points to size lda (ptr4),y add (ptr2),y sta (ptr4),y - iny ; Points to size+1 + iny ; Points to size+1 lda (ptr4),y adc (ptr2),y sta (ptr4),y ; Set left->next = f->next and remember left->next in ptr1. - iny ; Points to next - lda (ptr2),y ; Low byte of f->next + iny ; Points to next + lda (ptr2),y ; Low byte of f->next sta (ptr4),y sta ptr1 - iny ; Points to next+1 - lda (ptr2),y ; High byte of f->next + iny ; Points to next+1 + lda (ptr2),y ; High byte of f->next sta (ptr4),y sta ptr1+1 - ora ptr1 ; left->next == NULL? + ora ptr1 ; left->next == NULL? beq @L1 ; Do left->next->prev = left - iny ; Points to prev - lda ptr4 ; Low byte of left + iny ; Points to prev + lda ptr4 ; Low byte of left sta (ptr1),y iny - lda ptr4+1 ; High byte of left + lda ptr4+1 ; High byte of left sta (ptr1),y - rts ; Done + rts ; Done -; This is now the last block, do _hlast = left +; This is now the last block, do _heaplast = left @L1: lda ptr4 - sta __hlast + sta __heaplast lda ptr4+1 - sta __hlast+1 - rts ; Done + sta __heaplast+1 + rts ; Done ; No merge of the left block, just set the link. Y points to size+1 if ; we come here. Do left->next = f. NoLeftMerge: - iny ; Points to next - lda ptr2 ; Low byte of left + iny ; Points to next + lda ptr2 ; Low byte of left sta (ptr4),y iny - lda ptr2+1 ; High byte of left + lda ptr2+1 ; High byte of left sta (ptr4),y ; Do f->prev = left - iny ; Points to prev + iny ; Points to prev lda ptr4 sta (ptr2),y iny lda ptr4+1 sta (ptr2),y - rts ; Done + rts ; Done + diff --git a/libsrc/common/malloc.s b/libsrc/common/malloc.s index 548c96ebe..6b69b4199 100644 --- a/libsrc/common/malloc.s +++ b/libsrc/common/malloc.s @@ -106,50 +106,43 @@ .importzp ptr1, ptr2, ptr3 - .import __hptr, __hfirst, __hlast, __hend .export _malloc - .macpack generic - -; Offsets into struct freeblock and other constant stuff - -size = 0 -next = 2 -prev = 4 -admin_space = 2 -min_size = 6 + .include "_heap.inc" + .macpack generic +;----------------------------------------------------------------------------- ; Code _malloc: - sta ptr1 ; Store size in ptr1 + sta ptr1 ; Store size in ptr1 stx ptr1+1 ; Check for a size of zero, if so, return NULL ora ptr1+1 - beq Done ; a/x already contains zero + beq Done ; a/x already contains zero ; Add the administration space and round up the size if needed lda ptr1 - add #admin_space + add #HEAP_ADMIN_SPACE sta ptr1 bcc @L1 inc ptr1+1 @L1: ldx ptr1+1 bne @L2 - cmp #min_size+1 + cmp #HEAP_MIN_BLOCKSIZE+1 bcs @L2 - lda #min_size - sta ptr1 ; High byte is already zero + lda #HEAP_MIN_BLOCKSIZE + sta ptr1 ; High byte is already zero ; Load a pointer to the freelist into ptr2 -@L2: lda __hfirst +@L2: lda __heapfirst sta ptr2 - lda __hfirst+1 + lda __heapfirst+1 sta ptr2+1 ; Search the freelist for a block that is big enough. We will calculate @@ -157,21 +150,21 @@ _malloc: jmp @L4 -@L3: ldy #size +@L3: ldy #freeblock_size lda (ptr2),y sub ptr1 - tax ; Remember low byte for later - iny ; Y points to size+1 + tax ; Remember low byte for later + iny ; Y points to freeblock_size+1 lda (ptr2),y sbc ptr1+1 - bcs BlockFound ; Beware: Contents of a/x/y are known! + bcs BlockFound ; Beware: Contents of a/x/y are known! ; Next block in list - iny ; Points to next + iny ; Points to freeblock_next lda (ptr2),y tax - iny ; Points to next+1 + iny ; Points to freeblock_next+1 lda (ptr2),y stx ptr2 sta ptr2+1 @@ -180,16 +173,16 @@ _malloc: ; We did not find a block big enough. Try to use new space from the heap top. - lda __hptr - add ptr1 ; _hptr + size + lda __heapptr + add ptr1 ; _heapptr + size tay - lda __hptr+1 + lda __heapptr+1 adc ptr1+1 - bcs OutOfHeapSpace ; On overflow, we're surely out of space + bcs OutOfHeapSpace ; On overflow, we're surely out of space - cmp __hend+1 + cmp __heapend+1 bne @L5 - cpy __hend + cpy __heapend @L5: bcc TakeFromTop beq TakeFromTop @@ -199,18 +192,18 @@ OutOfHeapSpace: lda #0 tax Done: rts - + ; There is enough space left, take it from the heap top TakeFromTop: - ldx __hptr ; p = hptr; + ldx __heapptr ; p = _heapptr; stx ptr2 - ldx __hptr+1 + ldx __heapptr+1 stx ptr2+1 - sty __hptr ; hptr += size; - sta __hptr+1 - jmp FillSizeAndRet ; Done + sty __heapptr ; _heapptr += size; + sta __heapptr+1 + jmp FillSizeAndRet ; Done ; We found a block big enough. If the block can hold just the ; requested size, use the block in full. Beware: When slicing blocks, @@ -220,73 +213,73 @@ TakeFromTop: ; flag is set if the high byte of this remaining size is zero. BlockFound: - bne SliceBlock ; Block is large enough to slice - cpx #min_size+1 ; Check low byte - bcs SliceBlock ; Jump if block is large enough to slice + bne SliceBlock ; Block is large enough to slice + cpx #HEAP_MIN_BLOCKSIZE+1 ; Check low byte + bcs SliceBlock ; Jump if block is large enough to slice ; The block is too small to slice it. Use the block in full. The block ; does already contain the correct size word, all we have to do is to ; remove it from the free list. - ldy #prev+1 ; Load f->prev + ldy #freeblock_prev+1 ; Load f->prev lda (ptr2),y sta ptr3+1 dey lda (ptr2),y sta ptr3 - dey ; Points to next+1 + dey ; Points to freeblock_next+1 ora ptr3+1 - beq @L1 ; Jump if f->prev zero + beq @L1 ; Jump if f->prev zero ; We have a previous block, ptr3 contains its address. ; Do f->prev->next = f->next - lda (ptr2),y ; Load high byte of f->next - sta (ptr3),y ; Store high byte of f->prev->next - dey ; Points to next - lda (ptr2),y ; Load low byte of f->next - sta (ptr3),y ; Store low byte of f->prev->next + lda (ptr2),y ; Load high byte of f->next + sta (ptr3),y ; Store high byte of f->prev->next + dey ; Points to next + lda (ptr2),y ; Load low byte of f->next + sta (ptr3),y ; Store low byte of f->prev->next jmp @L2 ; This is the first block, correct the freelist pointer ; Do _hfirst = f->next -@L1: lda (ptr2),y ; Load high byte of f->next - sta __hfirst+1 - dey ; Points to next - lda (ptr2),y ; Load low byte of f->next - sta __hfirst +@L1: lda (ptr2),y ; Load high byte of f->next + sta __heapfirst+1 + dey ; Points to next + lda (ptr2),y ; Load low byte of f->next + sta __heapfirst ; Check f->next. Y points always to next if we come here -@L2: lda (ptr2),y ; Load low byte of f->next +@L2: lda (ptr2),y ; Load low byte of f->next sta ptr3 - iny ; Points to next+1 - lda (ptr2),y ; Load high byte of f->next + iny ; Points to next+1 + lda (ptr2),y ; Load high byte of f->next sta ptr3+1 - iny ; Points to prev + iny ; Points to prev ora ptr3 - beq @L3 ; Jump if f->next zero + beq @L3 ; Jump if f->next zero ; We have a next block, ptr3 contains its address. ; Do f->next->prev = f->prev - lda (ptr2),y ; Load low byte of f->prev - sta (ptr3),y ; Store low byte of f->next->prev - iny ; Points to prev+1 - lda (ptr2),y ; Load high byte of f->prev - sta (ptr3),y ; Store high byte of f->prev->next - jmp RetUserPtr ; Done + lda (ptr2),y ; Load low byte of f->prev + sta (ptr3),y ; Store low byte of f->next->prev + iny ; Points to prev+1 + lda (ptr2),y ; Load high byte of f->prev + sta (ptr3),y ; Store high byte of f->prev->next + jmp RetUserPtr ; Done ; This is the last block, correct the freelist pointer. ; Do _hlast = f->prev -@L3: lda (ptr2),y ; Load low byte of f->prev - sta __hlast - iny ; Points to prev+1 - lda (ptr2),y ; Load high byte of f->prev - sta __hlast+1 - jmp RetUserPtr ; Done +@L3: lda (ptr2),y ; Load low byte of f->prev + sta __heaplast + iny ; Points to prev+1 + lda (ptr2),y ; Load high byte of f->prev + sta __heaplast+1 + jmp RetUserPtr ; Done ; We must slice the block found. Cut off space from the upper end, so we ; can leave the actual free block chain intact. @@ -295,23 +288,23 @@ SliceBlock: ; Decrement the size of the block. Y points to size+1. - dey ; Points to size - lda (ptr2),y ; Low byte of f->size + dey ; Points to size + lda (ptr2),y ; Low byte of f->size sub ptr1 sta (ptr2),y - tax ; Save low byte of f->size in X - iny ; Points to size+1 - lda (ptr2),y ; High byte of f->size + tax ; Save low byte of f->size in X + iny ; Points to size+1 + lda (ptr2),y ; High byte of f->size sbc ptr1+1 sta (ptr2),y ; Set f to the space above the current block, which is the new block returned ; to the caller. - txa ; Get low byte of f->size + txa ; Get low byte of f->size add ptr2 tax - lda (ptr2),y ; Get high byte of f->size + lda (ptr2),y ; Get high byte of f->size adc ptr2+1 stx ptr2 sta ptr2+1 @@ -319,17 +312,17 @@ SliceBlock: ; Fill the size into the admin space of the block and return the user pointer FillSizeAndRet: - ldy #size ; *p = size; - lda ptr1 ; Low byte of block size + ldy #freeblock_size ; *p = size; + lda ptr1 ; Low byte of block size sta (ptr2),y - iny ; Points to size+1 + iny ; Points to freeblock_size+1 lda ptr1+1 sta (ptr2),y RetUserPtr: - lda ptr2 ; return ++p; + lda ptr2 ; return ++p; ldx ptr2+1 - add #admin_space + add #HEAP_ADMIN_SPACE bcc @L9 inx @L9: rts diff --git a/libsrc/common/realloc.c b/libsrc/common/realloc.c index 6c4f40a6c..baccbf8f2 100644 --- a/libsrc/common/realloc.c +++ b/libsrc/common/realloc.c @@ -35,7 +35,7 @@ #include #include -#include "_heap.h" +#include <_heap.h> @@ -73,13 +73,13 @@ void* __fastcall__ realloc (void* block, size_t size) diff = size - oldsize; /* Is the block at the current heap top? */ - if (((int) b) + oldsize == ((int) _hptr)) { + if (((int) b) + oldsize == ((int) _heapptr)) { /* Check if we've enough memory at the heap top */ int newhptr; - newhptr = ((int) _hptr) + diff; - if (newhptr <= ((int) _hend)) { + newhptr = ((int) _heapptr) + diff; + if (newhptr <= ((int) _heapend)) { /* Ok, there's space enough */ - _hptr = (unsigned*) newhptr; + _heapptr = (unsigned*) newhptr; *b = size; return block; } @@ -109,3 +109,4 @@ void* __fastcall__ realloc (void* block, size_t size) +