1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 15:29:46 +00:00
cc65/libsrc/common/_heapmaxavail.s
Oliver Schmidt d001a6f1a0 Have _heapmaxavail() work as advertised.
The cc65 doc explicitly states that the return value of _heapmaxavail() can be used as parameter of malloc(). To actually allow for that the size of HEAP_ADMIN_SPACE has to be substracted from the raw size of the largest free heap block.
2014-02-20 21:04:11 +01:00

86 lines
1.6 KiB
ArmAsm

;
; Ullrich von Bassewitz, 2003-02-01
;
; Return the size of the largest free block on the heap.
;
; size_t _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
; if (Size < HEAP_ADMIN_SPACE) return 0;
@L3: lda ptr2
sub #HEAP_ADMIN_SPACE
ldx ptr2+1
bcs @L5
bne @L4
txa
rts
; return Size - HEAP_ADMIN_SPACE;
@L4: dex
@L5: rts