From 992c2218a2339d024c181e57f8622dd5df9a884b Mon Sep 17 00:00:00 2001 From: michaelh Date: Mon, 5 Nov 2001 04:25:30 +0000 Subject: [PATCH] * 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. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1504 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 10 +++ device/include/asm/gbz80/features.h | 2 + device/include/asm/z80/features.h | 2 + device/include/malloc.h | 12 ++- device/lib/gbz80/Makefile | 2 +- device/lib/gbz80/crt0.s | 1 + device/lib/malloc.c | 118 ++++++++++++++++++++++++++++ device/lib/z80/Makefile | 2 +- device/lib/z80/crt0.s | 1 + support/regression/tests/malloc.c | 37 +++++++++ 10 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 support/regression/tests/malloc.c diff --git a/ChangeLog b/ChangeLog index 9d11a0c0..3921f27e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2001-11-04 Michael Hope + * 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. diff --git a/device/include/asm/gbz80/features.h b/device/include/asm/gbz80/features.h index 7e90a8de..fd9dc1ef 100644 --- a/device/include/asm/gbz80/features.h +++ b/device/include/asm/gbz80/features.h @@ -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 diff --git a/device/include/asm/z80/features.h b/device/include/asm/z80/features.h index 7e90a8de..fd9dc1ef 100644 --- a/device/include/asm/z80/features.h +++ b/device/include/asm/z80/features.h @@ -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 diff --git a/device/include/malloc.h b/device/include/malloc.h index 060ed857..05055bbf 100644 --- a/device/include/malloc.h +++ b/device/include/malloc.h @@ -22,10 +22,17 @@ 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 + +#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 diff --git a/device/lib/gbz80/Makefile b/device/lib/gbz80/Makefile index 91098a1b..40480d66 100644 --- a/device/lib/gbz80/Makefile +++ b/device/lib/gbz80/Makefile @@ -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) diff --git a/device/lib/gbz80/crt0.s b/device/lib/gbz80/crt0.s index 653a2471..00faa3ba 100644 --- a/device/lib/gbz80/crt0.s +++ b/device/lib/gbz80/crt0.s @@ -44,6 +44,7 @@ init: .area _DATA .area _BSS + .area _HEAP .area _CODE __clock:: diff --git a/device/lib/malloc.c b/device/lib/malloc.c index c5aabbb5..22f813c5 100644 --- a/device/lib/malloc.c +++ b/device/lib/malloc.c @@ -1,4 +1,121 @@ +#include +#if _SDCC_MALLOC_TYPE_MLH +#include + +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 ¤t_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 @@ -118,3 +235,4 @@ } //END OF MODULE +#endif diff --git a/device/lib/z80/Makefile b/device/lib/z80/Makefile index fac4986d..cda0855e 100644 --- a/device/lib/z80/Makefile +++ b/device/lib/z80/Makefile @@ -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) diff --git a/device/lib/z80/crt0.s b/device/lib/z80/crt0.s index 9f21f26b..61006f37 100644 --- a/device/lib/z80/crt0.s +++ b/device/lib/z80/crt0.s @@ -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 index 00000000..361ef99a --- /dev/null +++ b/support/regression/tests/malloc.c @@ -0,0 +1,37 @@ +/* Simple malloc tests. + */ +#include +#include + +/* 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)); +} -- 2.30.2