3 //--------------------------------------------------------------------
4 //Written by Dmitry S. Obukhov, 1997
6 //--------------------------------------------------------------------
7 //Modified for SDCC by Sandeep Dutta, 1999
8 //sandeep.dutta@usa.net
9 //--------------------------------------------------------------------
10 //malloc and free functions implementation for embedded system
11 //Non-ANSI keywords are C51 specific.
12 // xdata - variable in external memory (just RAM)
13 //--------------------------------------------------------------------
15 #define MEMHEADER struct MAH// Memory Allocation Header
19 MEMHEADER xdata * next;
20 MEMHEADER xdata * prev;
25 #define HEADER_SIZE (sizeof(MEMHEADER)-1)
26 #define NULL (void xdata * ) 0
29 //Static here means: can be accessed from this module only
30 static MEMHEADER xdata * FIRST_MEMORY_HEADER_PTR;
31 void init_dynamic_memory(MEMHEADER xdata * array, unsigned int size)
34 //This function MUST be called after the RESET.
35 //Parameters: array - pointer to memory allocated by the linker
36 // size - size of this memory pool
38 // #define DYNAMIC_MEMORY_SIZE 0x2000
40 // unsigned char xdata dynamic_memory_pool[DYNAMIC_MEMORY_SIZE];
41 // unsigned char xdata * current_buffer;
46 // init_dynamic_memory(dynamic_memory_pool,DYNAMIC_MEMORY_SIZE);
47 // Now it is possible to use malloc.
49 // current_buffer = malloc(0x100);
53 if ( !array ) /*Reserved memory starts on 0x0000 but it's NULL...*/
54 { //So, we lost one byte!
55 array = (MEMHEADER xdata * )((char xdata * ) array + 1) ;
58 FIRST_MEMORY_HEADER_PTR = array;
59 //Reserve a mem for last header
60 array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - HEADER_SIZE);
61 array->next->next = NULL; //And mark it as last
62 array->prev = NULL; //and mark first as first
63 array->len = 0; //Empty and ready.
66 void xdata * malloc (unsigned int size)
68 register MEMHEADER xdata * current_header;
69 register MEMHEADER xdata * new_header;
71 if (size>(0xFFFF-HEADER_SIZE)) return NULL; //To prevent overflow in next line
72 size += HEADER_SIZE; //We need a memory for header too
73 current_header = FIRST_MEMORY_HEADER_PTR;
80 //....*****.........******....
84 if ((((unsigned int)current_header->next) -
85 ((unsigned int)current_header) -
86 current_header->len) >= size) break; //if spare is more than need
87 current_header = current_header->next; //else try next
88 if (!current_header->next) return NULL; //if end_of_list reached
90 if (!current_header->len)
91 { //This code works only for first_header in the list and only
92 current_header->len = size; //for first allocation
93 return (current_header->mem);
94 } //else create new header at the begin of spare
95 new_header = (MEMHEADER xdata * )((char xdata *)current_header + current_header->len);
96 new_header->next = current_header->next; //and plug it into the chain
97 new_header->prev = current_header;
98 current_header->next = new_header;
99 if (new_header->next) new_header->next->prev = new_header;
100 new_header->len = size; //mark as used
101 return (new_header->mem);
104 void free (MEMHEADER xdata * p)
106 register MEMHEADER xdata * prev_header;
107 if ( p ) //For allocated pointers only!
109 p = (MEMHEADER xdata * )((char xdata *) p - HEADER_SIZE); //to start of header
110 if ( p->prev ) // For the regular header
112 prev_header = p->prev;
113 prev_header->next = p->next;
114 if (p->next) p->next->prev = prev_header;
116 else p->len = 0; //For the first header