2 ; Ullrich von Bassewitz, 19.03.2000
4 ; Free a block on the heap.
6 ; void __fastcall__ free (void* block);
9 ; C implementation was:
11 ; void free (void* block)
12 ; /* Release an allocated memory block. The function will accept NULL pointers
13 ; * (and do nothing in this case).
18 ; struct freeblock* f;
21 ; /* Allow NULL arguments */
26 ; /* Get a pointer to the real memory block, then get the size */
27 ; b = (unsigned*) block;
30 ; /* Check if the block is at the top of the heap */
31 ; if (((int) b) + size == (int) _hptr) {
33 ; /* Decrease _hptr to release the block */
34 ; _hptr = (unsigned*) (((int) _hptr) - size);
36 ; /* Check if the last block in the freelist is now at heap top. If so,
37 ; * remove this block from the freelist.
40 ; if (((int) f) + f->size == (int) _hptr) {
41 ; /* Remove the last block */
42 ; _hptr = (unsigned*) (((int) _hptr) - f->size);
43 ; if (_hlast = f->prev) {
44 ; /* Block before is now last block */
47 ; /* The freelist is empty now */
55 ; /* Not at heap top, enter the block into the free list */
63 .import __hptr, __hfirst, __hlast
64 .import pushax, __hadd
69 ; Offsets into struct freeblock and other constant stuff
81 stx ptr1+1 ; Save block
83 ; Is the argument NULL?
85 ora ptr1+1 ; Is the argument NULL?
88 ; Decrement the given pointer by the admin space amount, so it points to the
89 ; real block allocated. The size of the block is stored in the admin space.
90 ; Remember the block size in ptr2.
98 lda (ptr1),y ; High byte of size
104 ; Check if the block is on top of the heap
115 ; The pointer is located at the heap top. Lower the heap top pointer to
123 ; Check if the last block in the freelist is now at heap top. If so, remove
124 ; this block from the freelist.
129 beq @L9 ; Jump if free list empty
131 sta ptr2+1 ; Pointer to last block now in ptr2
134 lda (ptr2),y ; Low byte of block size
137 iny ; High byte of block size
142 bne @L9 ; Jump if last block not on top of heap
144 bne @L9 ; Jump if last block not on top of heap
146 ; Remove the last block
153 ; Correct the next pointer of the now last block
155 ldy #prev+1 ; Offset of ->prev field
157 sta ptr1+1 ; Remember f->prev in ptr1
161 sta ptr1 ; Remember f->prev in ptr1
163 ora __hlast+1 ; -> prev == 0?
164 bne @L8 ; Jump if free list not empty
166 ; Free list is now empty (A = 0)
175 ; Block before is now last block. ptr1 points to f->prev.
178 dey ; Points to high byte of ->next
180 dey ; Low byte of f->prev->next
184 ; The block is not on top of the heap. Add it to the free list.
192 jsr pushax ; Push size
193 jmp __hadd ; Add to free list and return