* device/include/malloc.h: Added z80 and gbz80 support.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 5 Nov 2001 04:25:30 +0000 (04:25 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 5 Nov 2001 04:25:30 +0000 (04:25 +0000)
* device/lib/gbz80/heap.s: Added.
* device/lib/z80/heap.s: Added.
* device/lib/malloc.c: Added z80 and gbz80 support.
* support/regression/tests/malloc.c (testMalloc): Added.
* src/SDCCmain.c (parseCmdLine): Added support for -Wp.

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1504 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
device/include/asm/gbz80/features.h
device/include/asm/z80/features.h
device/include/malloc.h
device/lib/gbz80/Makefile
device/lib/gbz80/crt0.s
device/lib/malloc.c
device/lib/z80/Makefile
device/lib/z80/crt0.s
support/regression/tests/malloc.c [new file with mode: 0644]

index 9d11a0c0616cb1e88c9f03aa27a741155b33ac5d..3921f27e2da62922376d30125866978addd84567 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2001-11-04  Michael Hope  <michaelh@juju.net.nz>
 
+       * device/include/malloc.h: Added z80 and gbz80 support.
+
+       * device/lib/gbz80/heap.s: Added.
+
+       * device/lib/z80/heap.s: Added.
+
+       * device/lib/malloc.c: Added z80 and gbz80 support.
+
+       * support/regression/tests/malloc.c (testMalloc): Added.
+
        * src/SDCCmain.c (parseCmdLine): Added support for -Wp.
 
        * support/regression/tests/bug-478094.c: Added.
index 7e90a8dec9c0e977bbe974128273c06966e6e979..fd9dc1ef8fcfdc6f75a3bbf5685c9bbf3eaffc28 100644 (file)
@@ -16,4 +16,6 @@
 /* Register allocator is as good as hand coded asm.  Cool. */
 #define _SDCC_PORT_PROVIDES_STRCPY     0
 
+#define _SDCC_MALLOC_TYPE_MLH          1
+
 #endif
index 7e90a8dec9c0e977bbe974128273c06966e6e979..fd9dc1ef8fcfdc6f75a3bbf5685c9bbf3eaffc28 100644 (file)
@@ -16,4 +16,6 @@
 /* Register allocator is as good as hand coded asm.  Cool. */
 #define _SDCC_PORT_PROVIDES_STRCPY     0
 
+#define _SDCC_MALLOC_TYPE_MLH          1
+
 #endif
index 060ed85728b964d64a8c015fc09087b3717bef05..05055bbf009b640c28df6c9de214173b769e4643 100644 (file)
    what you give them.   Help stamp out software-hoarding!  
 -------------------------------------------------------------------------*/
 /* malloc.h */
-#define MEMHEADER   struct MAH// Memory Allocation Header
-
 #ifndef __SDCC51_MALLOC_H
 #define __SDCC51_MALLOC_H
+#include <sdcc-lib.h>
+
+#if _SDCC_MALLOC_TYPE_MLH
+void *malloc (unsigned int);
+void free(void *p);
+
+#else
+
+#define MEMHEADER   struct MAH// Memory Allocation Header
 
 MEMHEADER
 {
@@ -48,6 +55,7 @@ extern void init_dynamic_memory(MEMHEADER xdata *  , unsigned int );
 extern void xdata * malloc (unsigned int );
 extern void free (void xdata *  p);
 
+#endif
 #endif
 
 #endif
index 91098a1ba7625a9763dfa897ca640f8f0a5b9e0a..40480d66bc552d89aaa5b42cdaee85aedd7ba61d 100644 (file)
@@ -5,7 +5,7 @@ TOPDIR = ../../..
 SCC = $(TOPDIR)/bin/sdcc -mgbz80
 SAS = $(TOPDIR)/bin/as-gbz80
 
-OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o
+OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o
 
 LIB = gbz80.lib
 CC = $(SCC)
index 653a2471961dbd51f6ae323c7c669482669a9d24..00faa3ba2914063cacc9c897e521b7aa89216210 100644 (file)
@@ -44,6 +44,7 @@ init:
         
        .area   _DATA
         .area   _BSS
+        .area   _HEAP
 
         .area   _CODE
 __clock::
index c5aabbb5a22c0d2631e710f703df045a4b07feb3..22f813c59a9b4b92effc54013f24e9d14356a992 100644 (file)
@@ -1,4 +1,121 @@
+#include <sdcc-lib.h>
 
+#if _SDCC_MALLOC_TYPE_MLH
+#include <malloc.h>
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+  MEMHEADER *  next;
+  MEMHEADER *  prev;
+  unsigned int       len;
+  unsigned char      mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+#define NULL        0
+
+/* These veriables are defined through the crt0 functions. */
+/* Base of this variable is the first byte of the heap. */
+extern MEMHEADER _sdcc_heap_start;
+/* Address of this variable is the last byte of the heap. */
+extern char _sdcc_heap_end;
+
+void 
+_sdcc_heap_init(void)
+{
+  MEMHEADER *pbase = &_sdcc_heap_start;
+  unsigned int size = &_sdcc_heap_end - (char *)pbase;
+
+  pbase->next = (MEMHEADER *)((char *)pbase + size - HEADER_SIZE);
+  pbase->next->next = NULL; //And mark it as last
+  pbase->prev       = NULL; //and mark first as first
+  pbase->len        = 0;    //Empty and ready.
+}
+
+void *
+malloc (unsigned int size)
+{
+  MEMHEADER * current_header;
+  MEMHEADER * new_header;
+
+  if (size>(0xFFFF-HEADER_SIZE))
+    {
+      return NULL; //To prevent overflow in next line
+    }
+
+  size += HEADER_SIZE; //We need a memory for header too
+  current_header = &_sdcc_heap_start;
+
+  while (1)
+    {
+      //    current
+      //    |   len       next
+      //    v   v         v
+      //....*****.........******....
+      //         ^^^^^^^^^
+      //           spare
+
+      if ((((unsigned int)current_header->next) -
+           ((unsigned int)current_header) -
+           current_header->len) >= size) 
+        {
+          break; //if spare is more than need
+        }
+      current_header = current_header->next;    //else try next             
+      if (!current_header->next)  
+        {
+          return NULL;  //if end_of_list reached    
+        }
+    }
+
+  if (!current_header->len)
+    { //This code works only for first_header in the list and only
+      current_header->len = size; //for first allocation
+      return &current_header->mem;
+    } 
+  else
+    {
+      //else create new header at the begin of spare
+      new_header = (MEMHEADER * )((char *)current_header + current_header->len);
+      new_header->next = current_header->next; //and plug it into the chain
+      new_header->prev = current_header;
+      current_header->next  = new_header;
+      if (new_header->next)
+        {
+          new_header->next->prev = new_header;
+        }
+      new_header->len  = size; //mark as used
+      return &new_header->mem;
+    }
+}
+
+void 
+free (void *p)
+{
+  MEMHEADER *prev_header, *pthis;
+
+  if ( p ) //For allocated pointers only!
+    {
+      pthis = (MEMHEADER * )((char *)  p - HEADER_SIZE); //to start of header
+      if ( pthis->prev ) // For the regular header
+        {
+          prev_header = pthis->prev;
+          prev_header->next = pthis->next;
+          if (pthis->next)  
+            {
+              pthis->next->prev = prev_header;
+            }
+        }
+      else 
+        {
+          pthis->len = 0; //For the first header
+        }
+    }
+}
+
+#else
 
             //--------------------------------------------------------------------
             //Written by Dmitry S. Obukhov, 1997
             }
             //END OF MODULE
 
+#endif
index fac4986d055ca4ff42bfb169e239005773ac3c5a..cda0855eebb843b88f8ca9708653a0e90bc7fc64 100644 (file)
@@ -5,7 +5,7 @@ TOPDIR = ../../..
 SCC = $(TOPDIR)/bin/sdcc -mz80
 SAS = $(TOPDIR)/bin/as-z80
 
-OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o
+OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o
 
 LIB = z80.lib
 CC = $(SCC)
index 9f21f26b1d52a31b77264a967e2d9aba07ad13ce..61006f372f24f53e156003d07184a4e407c1a38b 100644 (file)
@@ -39,6 +39,7 @@ init:
         
        .area   _DATA
         .area   _BSS
+        .area   _HEAP
 
         .area   _CODE
 __clock::
diff --git a/support/regression/tests/malloc.c b/support/regression/tests/malloc.c
new file mode 100644 (file)
index 0000000..361ef99
--- /dev/null
@@ -0,0 +1,37 @@
+/* Simple malloc tests.
+ */
+#include <testfwk.h>
+#include <malloc.h>
+
+/* PENDING */
+#if defined(__gbz80) || defined(__z80) || defined(__GNUC__)
+#define XDATA
+#else
+#define XDATA xdata
+#endif
+
+XDATA char heap[100];
+
+void
+testMalloc(void)
+{
+  void XDATA *p1, *p2, *p3;
+  
+#if !defined(__gbz80) && !defined(__z80) && !defined(__GNUC__)
+  init_dynamic_memory((MEMHEADER xdata *)heap, sizeof(heap));
+#endif
+
+  p1 = malloc(5);
+  ASSERT(p1 != NULL);
+  LOG(("p1: %u\n", p1));
+
+  p2 = malloc(20);
+  ASSERT(p2 != NULL);
+  LOG(("p2: %u\n", p2));
+
+  free(p2);
+
+  p3 = malloc(10);
+  ASSERT(p3 != NULL);
+  LOG(("p3, after freeing p2: %u\n", p3));
+}