Initial revision
diff --git a/contiki-cpc/contiki-cpc/arch/malloc.c b/contiki-cpc/contiki-cpc/arch/malloc.c
new file mode 100644
index 0000000..d4e91b5
--- /dev/null
+++ b/contiki-cpc/contiki-cpc/arch/malloc.c
@@ -0,0 +1,268 @@
+#include <sdcc-lib.h>
+#include <malloc.h>
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+  MEMHEADER *  next;
+  MEMHEADER *  prev;
+  unsigned int       len;
+  unsigned char      mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+
+/* 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;
+
+extern char *get_ram_start();
+extern char *get_ram_end();
+extern void calc_free_ram();
+extern char progend;
+
+static MEMHEADER *firstheader;
+/* setup two headers. One at start of free ram, second at end of free ram.
+ We find free ram range by asking Amstrad's firmware. */
+
+void
+_sdcc_heap_init(void)
+{
+  MEMHEADER *lastheader;
+  unsigned int size;
+  char * ramstart;
+
+  /* ask firmware for free ram */
+  calc_free_ram();
+
+  /* start of ram is either start of range given by firmware,
+  or end of program; whichever is largest */
+  ramstart = get_ram_start();
+  if (ramstart<&progend)
+	ramstart = &progend;
+
+  /* this is our first mem header */
+  firstheader = (MEMHEADER *)ramstart;
+  
+  /* this is the size of ram available */
+  size = get_ram_end() - ramstart;
+
+  /* calc address of last header */
+  lastheader = (MEMHEADER *)((char *)firstheader + size - HEADER_SIZE); 
+  
+  /* setup last header */
+  lastheader->next = NULL;
+  lastheader->prev = firstheader;
+  lastheader->len = 0;
+
+  /* setup first header */
+  firstheader->next = lastheader;
+  firstheader->prev       = NULL; //and mark first as first
+  firstheader->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 = firstheader;
+
+  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
+            //dso@usa.net
+            //--------------------------------------------------------------------
+            //Modified for SDCC by Sandeep Dutta, 1999
+            //sandeep.dutta@usa.net
+            //--------------------------------------------------------------------
+            //malloc and free functions implementation for embedded system
+            //Non-ANSI keywords are C51 specific.
+            // xdata - variable in external memory (just RAM)
+            //--------------------------------------------------------------------
+
+            #define MEMHEADER   struct MAH// Memory Allocation Header
+
+            MEMHEADER
+            {
+              MEMHEADER xdata *  next;
+              MEMHEADER xdata *  prev;
+              unsigned int       len;
+	      unsigned char      mem;
+            };
+
+            #define HEADER_SIZE (sizeof(MEMHEADER)-1)
+
+            //Static here means: can be accessed from this module only
+            static MEMHEADER xdata * FIRST_MEMORY_HEADER_PTR;
+            void init_dynamic_memory(MEMHEADER xdata * array, unsigned int size) 
+            {
+
+            //This function MUST be called after the RESET.
+            //Parameters: array - pointer to memory allocated by the linker
+            //            size  - size of this memory pool
+            //Example:
+            //     #define DYNAMIC_MEMORY_SIZE 0x2000
+            //     .....
+            //     unsigned char xdata dynamic_memory_pool[DYNAMIC_MEMORY_SIZE];
+            //     unsigned char xdata * current_buffer;
+            //     .....
+            //     void main(void)
+            //     {
+            //         ...
+            //         init_dynamic_memory(dynamic_memory_pool,DYNAMIC_MEMORY_SIZE);
+            //         Now it is possible to use malloc.
+            //         ...
+            //         current_buffer = malloc(0x100);
+            //
+            //
+
+              if ( !array ) /*Reserved memory starts on 0x0000 but it's NULL...*/
+              {             //So, we lost one byte!
+                 array = (MEMHEADER xdata * )((char xdata * ) array + 1) ;
+                 size --;
+              }
+              FIRST_MEMORY_HEADER_PTR = array;
+              //Reserve a mem for last header
+              array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - HEADER_SIZE);
+              array->next->next = (void xdata * ) NULL; //And mark it as last
+              array->prev       = (void xdata * ) NULL; //and mark first as first
+              array->len        = 0;    //Empty and ready.
+            }
+
+            void  xdata * malloc (unsigned int size)
+            {
+              register MEMHEADER xdata * current_header;
+              register MEMHEADER xdata * new_header;
+
+              if (size>(0xFFFF-HEADER_SIZE)) return (void xdata *) NULL; //To prevent overflow in next line
+              size += HEADER_SIZE; //We need a memory for header too
+              current_header = FIRST_MEMORY_HEADER_PTR;
+              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 (void xdata *) 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 ((xdata *)&(current_header->mem));
+              } //else create new header at the begin of spare
+              new_header = (MEMHEADER xdata * )((char xdata *)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 ((xdata *)&(new_header->mem));
+            }
+
+            void free (void xdata * p)
+            {
+              register MEMHEADER xdata * prev_header;
+              if ( p ) //For allocated pointers only!
+              {
+                  p = (MEMHEADER xdata * )((char xdata *)  p - HEADER_SIZE); //to start of header
+                  if ( ((MEMHEADER xdata * ) p)->prev ) // For the regular header
+                  {
+                    prev_header = ((MEMHEADER xdata * ) p)->prev;
+                    prev_header->next = ((MEMHEADER xdata * ) p)->next;
+                    if (((MEMHEADER xdata * ) p)->next)
+		       ((MEMHEADER xdata * ) p)->next->prev = prev_header;
+                  }
+                  else ((MEMHEADER xdata * ) p)->len = 0; //For the first header
+              }
+            }
+            //END OF MODULE
+#endif