]> git.sur5r.net Git - cc65/commitdiff
Replaced free.c by an assembler version
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 16 Jul 2000 22:09:58 +0000 (22:09 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 16 Jul 2000 22:09:58 +0000 (22:09 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@158 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/common/Makefile
libsrc/common/free.c [deleted file]
libsrc/common/free.s [new file with mode: 0644]

index bce9f6884fe56513b58f6380ddcfead43e7036a8..4726d5a5f355ecaf4c3e4ed77675516c99d3ef4d 100644 (file)
 
 C_OBJS = fclose.o fgets.o fprintf.o strdup.o calloc.o _fopen.o\
         fputs.o fread.o fwrite.o gets.o realloc.o bsearch.o strxfrm.o\
-        printf.o _hextab.o malloc.o free.o vfprintf.o fdopen.o strtok.o\
+        printf.o _hextab.o malloc.o vfprintf.o fdopen.o strtok.o\
         _afailed.o fopen.o fgetc.o fputc.o puts.o gets.o perror.o getchar.o\
         _printf.o vprintf.o vsprintf.o sprintf.o abort.o qsort.o putchar.o\
         errormsg.o _hadd.o cprintf.o vcprintf.o freopen.o locale.o
 
-S_OBJS = isalpha.o isdigit.o _file.o fmisc.o strlower.o strchr.o tolower.o\
-        toupper.o errno.o strcpy.o strlen.o strcat.o strcmp.o itoa.o\
-        strupper.o isalpha.o isalnum.o isgraph.o islower.o isupper.o\
-                isprint.o ispunct.o isspace.o isxdigit.o isblank.o strrchr.o\
-        _stksize.o _heap.o stricmp.o strncmp.o strncpy.o atoi.o setjmp.o\
-        longjmp.o rand.o atexit.o memset.o memcpy.o memchr.o memcmp.o\
-        ltoa.o strcspn.o strncat.o strpbrk.o strspn.o abs.o labs.o jmpvec.o\
-        _fdesc.o stkcheck.o zerobss.o copydata.o _swap.o strstr.o strcoll.o\
-        _sys.o getcpu.o _oserror.o strerror.o iscntrl.o maperrno.o
+S_OBJS =       _fdesc.o        \
+               _file.o         \
+               _heap.o         \
+               _oserror.o      \
+               _stksize.o      \
+               _swap.o         \
+               _sys.o          \
+               abs.o           \
+               atexit.o        \
+               atoi.o          \
+               copydata.o      \
+               errno.o         \
+               fmisc.o         \
+               free.o          \
+               getcpu.o        \
+               isalnum.o       \
+               isalpha.o       \
+               isblank.o       \
+               iscntrl.o       \
+               isdigit.o       \
+               isgraph.o       \
+               islower.o       \
+                       isprint.o       \
+               ispunct.o       \
+               isspace.o       \
+               isupper.o       \
+               isxdigit.o      \
+               itoa.o          \
+               jmpvec.o        \
+               labs.o          \
+               longjmp.o       \
+               ltoa.o          \
+               maperrno.o      \
+               memchr.o        \
+               memcmp.o        \
+               memcpy.o        \
+               memset.o        \
+               rand.o          \
+               setjmp.o        \
+               stkcheck.o      \
+               strcat.o        \
+               strchr.o        \
+               strcmp.o        \
+               strcoll.o       \
+               strcpy.o        \
+               strcspn.o       \
+               strerror.o      \
+               stricmp.o       \
+               strlen.o        \
+               strlower.o      \
+               strncat.o       \
+               strncmp.o       \
+               strncpy.o       \
+               strpbrk.o       \
+               strrchr.o       \
+               strspn.o        \
+               strstr.o        \
+               strupper.o      \
+               tolower.o       \
+               toupper.o       \
+               zerobss.o
+
 
 all:   $(C_OBJS) $(S_OBJS)
 
diff --git a/libsrc/common/free.c b/libsrc/common/free.c
deleted file mode 100644 (file)
index 686f460..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * free.c
- *
- * Ullrich von Bassewitz, 11.08.1998
- */
-
-
-
-#include <stdlib.h>
-#include "_heap.h"
-
-
-
-void free (void* block)
-/* Release an allocated memory block. The function will accept NULL pointers
- * (and do nothing in this case).
- */
-{
-    unsigned* b;
-    unsigned size;
-    struct freeblock* f;
-
-
-    /* Allow NULL arguments */
-    if (block == 0) {
-        return;
-    }
-
-    /* Get a pointer to the real memory block, then get the size */
-    b = (unsigned*) block;
-    size = *--b;
-
-    /* Check if the block is at the top of the heap */
-    if (((int) b) + size == (int) _hptr) {
-
-        /* Decrease _hptr to release the block */
-        _hptr = (unsigned*) (((int) _hptr) - size);
-
-        /* Check if the last block in the freelist is now at heap top. If so,
-         * remove this block from the freelist.
-         */
-        if (f = _hlast) {
-            if (((int) f) + f->size == (int) _hptr) {
-                /* Remove the last block */
-                _hptr = (unsigned*) (((int) _hptr) - f->size);
-                if (_hlast = f->prev) {
-                   /* Block before is now last block */
-                    f->prev->next = 0;
-                } else {
-                    /* The freelist is empty now */
-                    _hfirst = 0;
-                }
-            }
-        }
-
-    } else {
-
-               /* Not at heap top, enter the block into the free list */
-       _hadd (b, size);
-
-    }
-}
-
-
-
diff --git a/libsrc/common/free.s b/libsrc/common/free.s
new file mode 100644 (file)
index 0000000..faa40c6
--- /dev/null
@@ -0,0 +1,193 @@
+;
+; Ullrich von Bassewitz, 19.03.2000
+;
+; Free a block on the heap.
+;
+; void __fastcall__ free (void* block);
+;
+;
+; C implementation was:
+;
+; void free (void* block)
+; /* Release an allocated memory block. The function will accept NULL pointers
+;  * (and do nothing in this case).
+;  */
+; {
+;     unsigned* b;
+;     unsigned size;
+;     struct freeblock* f;
+;
+;
+;     /* Allow NULL arguments */
+;     if (block == 0) {
+;         return;
+;     }
+;
+;     /* Get a pointer to the real memory block, then get the size */
+;     b = (unsigned*) block;
+;     size = *--b;
+;
+;     /* Check if the block is at the top of the heap */
+;     if (((int) b) + size == (int) _hptr) {
+;
+;         /* Decrease _hptr to release the block */
+;         _hptr = (unsigned*) (((int) _hptr) - size);
+;
+;         /* Check if the last block in the freelist is now at heap top. If so,
+;          * remove this block from the freelist.
+;          */
+;         if (f = _hlast) {
+;             if (((int) f) + f->size == (int) _hptr) {
+;                 /* Remove the last block */
+;                 _hptr = (unsigned*) (((int) _hptr) - f->size);
+;                 if (_hlast = f->prev) {
+;                  /* Block before is now last block */
+;                     f->prev->next = 0;
+;                 } else {
+;                     /* The freelist is empty now */
+;                     _hfirst = 0;
+;                 }
+;             }
+;         }
+;
+;     } else {
+;
+;              /* Not at heap top, enter the block into the free list */
+;              _hadd (b, size);
+;
+;     }
+; }
+;
+
+       .importzp       ptr1, ptr2
+       .import         __hptr, __hfirst, __hlast
+       .import         pushax, __hadd
+       .export         _free
+
+; Offsets into struct freeblock
+
+       size    = 0
+       next    = 2
+       prev    = 4
+
+; Code
+
+_free: sta     ptr1
+       stx     ptr1+1                  ; Save block
+
+; Is the argument NULL?
+
+       ora     ptr1+1                  ; Is the argument NULL?
+               beq     @L9                     ; Jump if yes
+
+; Decrement the given pointer by 2. The size of the block is stored there.
+; Remember the block size in ptr2.
+
+       sec
+       lda     ptr1
+       sbc     #2
+       sta     ptr1
+       bcs     @L1
+       dec     ptr1+1
+@L1:   ldy     #size+1
+       lda     (ptr1),y                ; High byte of size
+       sta     ptr2+1                  ; Save it
+       dey
+       lda     (ptr1),y
+       sta     ptr2
+
+; Check if the block is on top of the heap
+
+       clc
+       adc     ptr1
+       tay
+       lda     ptr1+1
+       adc     ptr2+1
+       cpy     __hptr
+       bne     @AddToFreeList
+       cmp     __hptr+1
+               bne     @AddToFreeList
+
+; The pointer is located at the heap top. Lower the heap top pointer to
+; release the block.
+
+@L3:   lda     ptr1
+       sta     __hptr
+       lda     ptr1+1
+       sta     __hptr+1
+
+; Check if the last block in the freelist is now at heap top. If so, remove
+; this block from the freelist.
+
+       lda     __hlast
+       sta     ptr2
+       ora     __hlast+1
+               beq     @L9                     ; Jump if free list empty
+       lda     __hlast+1
+       sta     ptr2+1                  ; Pointer to last block now in ptr2
+
+       clc
+       ldy     #size
+       lda     (ptr2),y                ; Low byte of block size
+       adc     ptr2
+       tax
+       iny                             ; High byte of block size
+       lda     (ptr2),y
+       adc     ptr2+1
+
+       cmp     __hptr+1
+               bne     @L9                     ; Jump if last block not on top of heap
+       cpx     __hptr
+       bne     @L9                     ; Jump if last block not on top of heap
+
+; Remove the last block
+
+       lda     ptr2
+       sta     __hptr
+       lda     ptr2+1
+       sta     __hptr+1
+
+; Correct the next pointer of the now last block
+
+       ldy     #prev+1                 ; Offset of ->prev field
+               lda     (ptr2),y
+       sta     ptr1+1                  ; Remember f->prev in ptr1
+       sta     __hlast+1
+       dey
+       lda     (ptr2),y
+       sta     ptr1                    ; Remember f->prev in ptr1
+       sta     __hlast
+       ora     __hlast+1               ; -> prev == 0?
+               bne     @L8                     ; Jump if free list not empty
+
+; Free list is now empty (A = 0)
+
+       sta     __hfirst
+       sta     __hfirst+1
+
+; Done
+
+@L9:   rts
+
+; Block before is now last block. ptr1 points to f->prev.
+
+@L8:   lda     #$00
+       dey                             ; Points to high byte of ->next
+       sta     (ptr1),y
+       dey                             ; Low byte of f->prev->next
+       sta     (ptr1),y
+       rts                             ; Done
+
+; The block is not on top of the heap. Add it to the free list.
+
+@AddToFreeList:
+       lda     ptr1
+       ldx     ptr1+1
+       jsr     pushax                  ; Push b
+       lda     ptr2
+       ldx     ptr2+1
+       jsr     pushax                  ; Push size
+       jmp     __hadd                  ; Add to free list and return
+
+
+