From 26ca26f89a9800d7e0baf3d2747c324188bbd662 Mon Sep 17 00:00:00 2001 From: vrokas Date: Tue, 18 Jan 2005 10:42:16 +0000 Subject: [PATCH] * device/lib/pic16/libc/stdlib/x_ftoa.c: it defines x_ftoa function which converts a float number to its ASCII representation * calloc.c, free.c, malloc.c, realloc.c: added _MALLOC_SPEC to explicit place variables in data ram git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3637 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- device/lib/pic16/libc/stdlib/Makefile | 3 +- device/lib/pic16/libc/stdlib/calloc.c | 10 +- device/lib/pic16/libc/stdlib/free.c | 4 +- device/lib/pic16/libc/stdlib/malloc.c | 16 +-- device/lib/pic16/libc/stdlib/realloc.c | 18 +-- device/lib/pic16/libc/stdlib/x_ftoa.c | 189 +++++++++++++++++++++++++ 6 files changed, 215 insertions(+), 25 deletions(-) create mode 100644 device/lib/pic16/libc/stdlib/x_ftoa.c diff --git a/device/lib/pic16/libc/stdlib/Makefile b/device/lib/pic16/libc/stdlib/Makefile index e905dc94..e0bc36fd 100644 --- a/device/lib/pic16/libc/stdlib/Makefile +++ b/device/lib/pic16/libc/stdlib/Makefile @@ -20,7 +20,8 @@ SRCS = atof \ free \ ltoa \ malloc \ - realloc + realloc \ + x_ftoa CFILES = $(patsubst %,%.c,$(SRCS)) diff --git a/device/lib/pic16/libc/stdlib/calloc.c b/device/lib/pic16/libc/stdlib/calloc.c index e888daae..dae2e2d3 100644 --- a/device/lib/pic16/libc/stdlib/calloc.c +++ b/device/lib/pic16/libc/stdlib/calloc.c @@ -5,18 +5,18 @@ * */ -#include "malloc.h" +#include -extern unsigned char *_dynamicHeap; /* pointer to heap */ +extern unsigned char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ -unsigned char *calloc(unsigned char num) //, unsigned char len) +unsigned char _MALLOC_SPEC *calloc(unsigned char num) //, unsigned char len) { unsigned char len=num; unsigned char total; - unsigned char *result, *ch; + unsigned char _MALLOC_SPEC *result, *ch; total = num * len; - if(total > MAX_BLOCK_SIZE)return ((unsigned char *)0); + if(total > MAX_BLOCK_SIZE)return ((unsigned char _MALLOC_SPEC *)0); result = ch = malloc( (char)(total) ); if(result != 0) { diff --git a/device/lib/pic16/libc/stdlib/free.c b/device/lib/pic16/libc/stdlib/free.c index 4f6ec86f..7f6c7f14 100644 --- a/device/lib/pic16/libc/stdlib/free.c +++ b/device/lib/pic16/libc/stdlib/free.c @@ -7,9 +7,9 @@ #include "malloc.h" -extern char *_dynamicHeap; /* pointer to heap */ +extern char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ -void free(unsigned char *buf) +void free(unsigned char _MALLOC_SPEC *buf) { /* mark block as deallocated */ ((_malloc_rec *)(buf - 1))->bits.alloc = 0; diff --git a/device/lib/pic16/libc/stdlib/malloc.c b/device/lib/pic16/libc/stdlib/malloc.c index 7c0a48a0..8a984762 100644 --- a/device/lib/pic16/libc/stdlib/malloc.c +++ b/device/lib/pic16/libc/stdlib/malloc.c @@ -7,19 +7,19 @@ #include "malloc.h" -extern unsigned char *_dynamicHeap; /* pointer to heap */ +extern unsigned char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ -unsigned char *malloc(unsigned char len) +unsigned char _MALLOC_SPEC *malloc(unsigned char len) { - _malloc_rec *pHeap; /* pointer to block header */ - _malloc_rec *temp; + _malloc_rec _MALLOC_SPEC *pHeap; /* pointer to block header */ + _malloc_rec _MALLOC_SPEC *temp; unsigned char bLen; /* size of block */ unsigned char eLen; if(len > _MAX_HEAP_SIZE) - return ((unsigned char *)0); + return ((unsigned char _MALLOC_SPEC *)0); - pHeap = (_malloc_rec *)&_dynamicHeap; + pHeap = (_malloc_rec _MALLOC_SPEC *)&_dynamicHeap; while(1) { @@ -27,7 +27,7 @@ unsigned char *malloc(unsigned char len) /* if datum is zero, then last block, return NULL */ if(pHeap->datum == 0) - return ((unsigned char *)0); + return ((unsigned char _MALLOC_SPEC *)0); /* if current block is allocated then proceed to next */ if(pHeap->bits.alloc) { @@ -89,6 +89,6 @@ unsigned char *malloc(unsigned char len) temp->bits.alloc = 0; } - return ((unsigned char *)pHeap + 1); + return ((unsigned char _MALLOC_SPEC *)pHeap + 1); } } diff --git a/device/lib/pic16/libc/stdlib/realloc.c b/device/lib/pic16/libc/stdlib/realloc.c index 29705a7a..fb0ae4b1 100644 --- a/device/lib/pic16/libc/stdlib/realloc.c +++ b/device/lib/pic16/libc/stdlib/realloc.c @@ -7,21 +7,21 @@ #include "malloc.h" -extern unsigned char *_dynamicHeap; /* pointer to heap */ +extern unsigned char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ -unsigned char *realloc(unsigned char *mblock, unsigned char len) +unsigned char _MALLOC_SPEC *realloc(unsigned char _MALLOC_SPEC *mblock, unsigned char len) { - _malloc_rec *pHeap; /* pointer to block header */ - _malloc_rec *temp; + _malloc_rec _MALLOC_SPEC *pHeap; /* pointer to block header */ + _malloc_rec _MALLOC_SPEC *temp; unsigned char bLen; /* size of block */ unsigned char eLen; if(len > MAX_BLOCK_SIZE) - return ((unsigned char *)0); + return ((unsigned char _MALLOC_SPEC *)0); len++; /* increase to count header too */ - pHeap = (_malloc_rec *)(mblock-1); + pHeap = (_malloc_rec _MALLOC_SPEC *)(mblock-1); bLen = pHeap->bits.count; /* new size is same as old, return pointer */ @@ -34,7 +34,7 @@ unsigned char *realloc(unsigned char *mblock, unsigned char len) temp->bits.alloc = 0; temp->bits.count = bLen - len; - return (((unsigned char *)pHeap) + 1); + return (((unsigned char _MALLOC_SPEC *)pHeap) + 1); } /* so, new segment has size bigger than the old one @@ -69,11 +69,11 @@ unsigned char *realloc(unsigned char *mblock, unsigned char len) eLen -= i; } - return (((unsigned char *)pHeap) + 1); + return (((unsigned char _MALLOC_SPEC *)pHeap) + 1); } /* no could not find a valid block, return NULL */ - return ((unsigned char *)0); + return ((unsigned char _MALLOC_SPEC *)0); } diff --git a/device/lib/pic16/libc/stdlib/x_ftoa.c b/device/lib/pic16/libc/stdlib/x_ftoa.c new file mode 100644 index 00000000..7ff860aa --- /dev/null +++ b/device/lib/pic16/libc/stdlib/x_ftoa.c @@ -0,0 +1,189 @@ + +/* + * wrapper function to use _convert_float + * + * written by Vangelis Rokas, 2004, + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * $Id$ + */ + +#include + +extern convert_frac; +extern convert_int; + +/* char x_ftoa(float, data char *, unsigned char, unsigned char); */ + + +extern POSTDEC1; +extern PLUSW2; +extern FSR0L; +extern FSR0H; +extern PREINC1; +extern PREINC2; +extern FSR2L; +extern FSR2H; + +#define _vv0x00 0x00 +#define _vv0x01 0x01 +#define _vv0x02 0x02 +#define _vv0x03 0x03 +#define _vv0x04 0x04 + +char x_cnvint_wrap(unsigned long num, data char *buffer) +{ + num; + buffer; + + _asm + movff _vv0x00, _POSTDEC1 + movff _vv0x01, _POSTDEC1 + movff _vv0x02, _POSTDEC1 + movff _vv0x03, _POSTDEC1 + + movlw 2 + movff _PLUSW2, _vv0x00 + movlw 3 + movff _PLUSW2, _vv0x01 + movlw 4 + movff _PLUSW2, _vv0x02 + movlw 5 + movff _PLUSW2, _vv0x03 + + movlw 6 + movff _PLUSW2, _FSR0L + movlw 7 + movff _PLUSW2, _FSR0H + + call _convert_int + + /* return value is already in WREG */ + + movff _PREINC1, _vv0x03 + movff _PREINC1, _vv0x02 + movff _PREINC1, _vv0x01 + movff _PREINC1, _vv0x00 + _endasm ; +} + +char x_cnvfrac_wrap(unsigned long num, data char *buffer, unsigned char prec) +{ + num; + buffer; + prec; + + _asm + movff _vv0x00, _POSTDEC1 + movff _vv0x01, _POSTDEC1 + movff _vv0x02, _POSTDEC1 + movff _vv0x03, _POSTDEC1 + movff _vv0x04, _POSTDEC1 + + movlw 2 + movff _PLUSW2, _vv0x00 + movlw 3 + movff _PLUSW2, _vv0x01 + movlw 4 + movff _PLUSW2, _vv0x02 + movlw 5 + movff _PLUSW2, _vv0x03 + + movlw 6 + movff _PLUSW2, _FSR0L + movlw 7 + movff _PLUSW2, _FSR0H + + movlw 8 + movff _PLUSW2, _vv0x04 + + call _convert_frac + + /* return value is already in WREG */ + + movff _PREINC1, _vv0x04 + movff _PREINC1, _vv0x03 + movff _PREINC1, _vv0x02 + movff _PREINC1, _vv0x01 + movff _PREINC1, _vv0x00 + _endasm ; +} + + + +union float_long { + unsigned long l; + float f; +}; + +char x_ftoa(float num, data char *buffer, unsigned char buflen, unsigned char prec) +{ + char len; + char expn; + unsigned long ll; + unsigned long li; +// volatile + union float_long f_l; + + len = buflen; + while(len--)buffer[len] = 0; + + f_l.f = num; + + if((f_l.l & SIGNBIT) == SIGNBIT) { + f_l.l &= ~SIGNBIT; + *buffer = '-'; + buffer++; + } + + expn = EXCESS - EXP(f_l.l); // - 24; + + ll = MANT(f_l.l); + li = 0; + + while( expn ) { + if(expn < 0) { + li <<= 1; + if(ll & 0x00800000UL)li |= 1; + ll <<= 1; + expn++; + } else { + ll >>= 1; + expn--; + } + } + + if(li) + len = x_cnvint_wrap(li, buffer); + else { + *buffer = '0'; len = 1; + } + + buffer += len; + + if(prec) { + *buffer = '.'; len++; + buffer++; + + len += x_cnvfrac_wrap(ll, buffer, 24-prec); + buffer[ prec ] = '\0'; + } + + return (len); +} -- 2.47.2