diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /device/lib/pic16/libc/stdlib | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'device/lib/pic16/libc/stdlib')
| -rw-r--r-- | device/lib/pic16/libc/stdlib/atof.c | 94 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/atoi.c | 57 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/atol.c | 52 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/calloc.c | 50 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/crc16.c | 83 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/free.c | 37 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/g_ftoa.S | 236 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/itoa.c | 39 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/ltoa.c | 87 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/malloc.c | 119 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/memfree.c | 49 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/memfreemax.c | 52 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/memmisc.c | 98 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/rand.c | 89 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/realloc.c | 83 | ||||
| -rw-r--r-- | device/lib/pic16/libc/stdlib/x_ftoa.c | 193 |
16 files changed, 1418 insertions, 0 deletions
diff --git a/device/lib/pic16/libc/stdlib/atof.c b/device/lib/pic16/libc/stdlib/atof.c new file mode 100644 index 0000000..956eeed --- /dev/null +++ b/device/lib/pic16/libc/stdlib/atof.c @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------- + atof.c - converts an ASCII string to float + + Copyright (C) 2003, Jesus Calvino-Fraga <jesusc at ieee.org> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <ctype.h> +#include <stdlib.h> + +float atof(char * s) +{ + float value, fraction; + signed char iexp; + char sign; + + //Skip leading blanks + while (isspace(*s)) s++; + + //Get the sign + if (*s == '-') + { + sign=1; + s++; + } + else + { + sign=0; + if (*s == '+') s++; + } + + //Get the integer part + for (value=0.0; isdigit(*s); s++) + { + value=10.0*value+(*s-'0'); + } + + //Get the fraction + if (*s == '.') + { + s++; + for (fraction=0.1; isdigit(*s); s++) + { + value+=(*s-'0')*fraction; + fraction*=0.1; + } + } + + //Finally, the exponent (not very efficient, but enough for now*/ + if (toupper(*s)=='E') + { + s++; + iexp=(signed char)atoi(s); + { + while(iexp!=0) + { + if(iexp<0) + { + value*=0.1; + iexp++; + } + else + { + value*=10.0; + iexp--; + } + } + } + } + + if(sign) value*=-1.0; + return (value); +} diff --git a/device/lib/pic16/libc/stdlib/atoi.c b/device/lib/pic16/libc/stdlib/atoi.c new file mode 100644 index 0000000..798237a --- /dev/null +++ b/device/lib/pic16/libc/stdlib/atoi.c @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------- + atoi.c - convert a string to an integer and return it + + Copyright (C) 1999, Sandeep Dutta <sandeep.dutta at usa.net> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +int atoi(char * s) +{ + int rv=0; + char sign = 0; + + /* skip till we find either a digit or '+' or '-' */ + while (*s) { + if (*s <= '9' && *s >= '0') + break; + if (*s == '-' || *s == '+') + break; + s++; + } + + if(*s == '-')sign=1; + +// sign = (*s == '-'); + if (*s == '-' || *s == '+') s++; + + while (*s && *s >= '0' && *s <= '9') { + rv = (rv * 10) + (*s - '0'); + s++; + } + + if(sign)return (-rv); + else return (rv); + +// return (sign ? -rv : rv); +} diff --git a/device/lib/pic16/libc/stdlib/atol.c b/device/lib/pic16/libc/stdlib/atol.c new file mode 100644 index 0000000..839547c --- /dev/null +++ b/device/lib/pic16/libc/stdlib/atol.c @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + atol.c - convert a string to long integer and return it + + Copyright (C) 1999, Sandeep Dutta <sandeep.dutta at usa.net> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +long atol(char * s) +{ + register long rv=0; + register char sign = 0; + + /* skip till we find either a digit or '+' or '-' */ + while (*s) { + if (*s <= '9' && *s >= '0') + break; + if (*s == '-' || *s == '+') + break; + s++; + } + + sign = (*s == '-'); + if (*s == '-' || *s == '+') s++; + + while (*s && *s >= '0' && *s <= '9') { + rv = (rv * 10) + (*s - '0'); + s++; + } + + return (sign ? -rv : rv); +} diff --git a/device/lib/pic16/libc/stdlib/calloc.c b/device/lib/pic16/libc/stdlib/calloc.c new file mode 100644 index 0000000..0423925 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/calloc.c @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------- + calloc.c - dynamic memory allocation + + Copyright (C) 2004, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <malloc.h> + +extern unsigned char _MALLOC_SPEC *heap; + +unsigned char _MALLOC_SPEC *calloc(unsigned char len) +{ + unsigned char _MALLOC_SPEC *result, *ch; + + if (len >= MAX_BLOCK_SIZE) return ((unsigned char _MALLOC_SPEC *)0); + ch = malloc( len ); + result = ch; + + if (result != 0) { + while (len) { + --len; + *ch = 0; + ch++; + } + } + + return (result); +} diff --git a/device/lib/pic16/libc/stdlib/crc16.c b/device/lib/pic16/libc/stdlib/crc16.c new file mode 100644 index 0000000..22bec9c --- /dev/null +++ b/device/lib/pic16/libc/stdlib/crc16.c @@ -0,0 +1,83 @@ +/*------------------------------------------------------------------------- + crc16.c - CRC16 checksum generation + + Copyright (C) 2005, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +/* + * The CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories + * and Ned W. Rhodes of Software Systems Group. It has been published in + * "Design and Validation of Computer Protocols", Prentice Hall, + * Englewood Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4. + * + * Copyright is held by AT&T. + * + * AT&T gives permission for the free use of the CRC source code. + */ + +#include <stdint.h> + +__code uint16_t crc_table[256] = { + 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U, + 0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU, + 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U, + 0x9339U, 0x8318U, 0xb37bU, 0xa35aU, 0xd3bdU, 0xc39cU, 0xf3ffU, 0xe3deU, + 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64e6U, 0x74c7U, 0x44a4U, 0x5485U, + 0xa56aU, 0xb54bU, 0x8528U, 0x9509U, 0xe5eeU, 0xf5cfU, 0xc5acU, 0xd58dU, + 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76d7U, 0x66f6U, 0x5695U, 0x46b4U, + 0xb75bU, 0xa77aU, 0x9719U, 0x8738U, 0xf7dfU, 0xe7feU, 0xd79dU, 0xc7bcU, + 0x48c4U, 0x58e5U, 0x6886U, 0x78a7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U, + 0xc9ccU, 0xd9edU, 0xe98eU, 0xf9afU, 0x8948U, 0x9969U, 0xa90aU, 0xb92bU, + 0x5af5U, 0x4ad4U, 0x7ab7U, 0x6a96U, 0x1a71U, 0x0a50U, 0x3a33U, 0x2a12U, + 0xdbfdU, 0xcbdcU, 0xfbbfU, 0xeb9eU, 0x9b79U, 0x8b58U, 0xbb3bU, 0xab1aU, + 0x6ca6U, 0x7c87U, 0x4ce4U, 0x5cc5U, 0x2c22U, 0x3c03U, 0x0c60U, 0x1c41U, + 0xedaeU, 0xfd8fU, 0xcdecU, 0xddcdU, 0xad2aU, 0xbd0bU, 0x8d68U, 0x9d49U, + 0x7e97U, 0x6eb6U, 0x5ed5U, 0x4ef4U, 0x3e13U, 0x2e32U, 0x1e51U, 0x0e70U, + 0xff9fU, 0xefbeU, 0xdfddU, 0xcffcU, 0xbf1bU, 0xaf3aU, 0x9f59U, 0x8f78U, + 0x9188U, 0x81a9U, 0xb1caU, 0xa1ebU, 0xd10cU, 0xc12dU, 0xf14eU, 0xe16fU, + 0x1080U, 0x00a1U, 0x30c2U, 0x20e3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U, + 0x83b9U, 0x9398U, 0xa3fbU, 0xb3daU, 0xc33dU, 0xd31cU, 0xe37fU, 0xf35eU, + 0x02b1U, 0x1290U, 0x22f3U, 0x32d2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U, + 0xb5eaU, 0xa5cbU, 0x95a8U, 0x8589U, 0xf56eU, 0xe54fU, 0xd52cU, 0xc50dU, + 0x34e2U, 0x24c3U, 0x14a0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U, + 0xa7dbU, 0xb7faU, 0x8799U, 0x97b8U, 0xe75fU, 0xf77eU, 0xc71dU, 0xd73cU, + 0x26d3U, 0x36f2U, 0x0691U, 0x16b0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U, + 0xd94cU, 0xc96dU, 0xf90eU, 0xe92fU, 0x99c8U, 0x89e9U, 0xb98aU, 0xa9abU, + 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18c0U, 0x08e1U, 0x3882U, 0x28a3U, + 0xcb7dU, 0xdb5cU, 0xeb3fU, 0xfb1eU, 0x8bf9U, 0x9bd8U, 0xabbbU, 0xbb9aU, + 0x4a75U, 0x5a54U, 0x6a37U, 0x7a16U, 0x0af1U, 0x1ad0U, 0x2ab3U, 0x3a92U, + 0xfd2eU, 0xed0fU, 0xdd6cU, 0xcd4dU, 0xbdaaU, 0xad8bU, 0x9de8U, 0x8dc9U, + 0x7c26U, 0x6c07U, 0x5c64U, 0x4c45U, 0x3ca2U, 0x2c83U, 0x1ce0U, 0x0cc1U, + 0xef1fU, 0xff3eU, 0xcf5dU, 0xdf7cU, 0xaf9bU, 0xbfbaU, 0x8fd9U, 0x9ff8U, + 0x6e17U, 0x7e36U, 0x4e55U, 0x5e74U, 0x2e93U, 0x3eb2U, 0x0ed1U, 0x1ef0U +}; + +uint16_t crc16(uint8_t *data, uint32_t size, uint16_t crc) +{ + while (size--) + crc = crc_table[((crc >> 8) ^ *(data++)) & 0xffU] ^ (crc << 8); + + return crc; +} diff --git a/device/lib/pic16/libc/stdlib/free.c b/device/lib/pic16/libc/stdlib/free.c new file mode 100644 index 0000000..69614c2 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/free.c @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + free.c - dynamic memory allocation + + Copyright (C) 2004, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <malloc.h> + +extern char _MALLOC_SPEC *heap; + +void free(unsigned char _MALLOC_SPEC *buf) +{ + /* mark block as deallocated */ + ((_MALLOC_SPEC _malloc_rec *)((unsigned int)buf - 1))->bits.alloc = 0; +} diff --git a/device/lib/pic16/libc/stdlib/g_ftoa.S b/device/lib/pic16/libc/stdlib/g_ftoa.S new file mode 100644 index 0000000..1a11c45 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/g_ftoa.S @@ -0,0 +1,236 @@ +;-------------------------------------------------------------------------- +; g_ftoa.S - floating point to ascii conversion +; +; Copyright (C) 2004, George Gallant <ggallant571 AT verizon.net> +; +; This library is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the +; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +; MA 02110-1301, USA. +; +; As a special exception, if you link this library with other files, +; some of which are compiled with SDCC, to produce an executable, +; this library does not by itself cause the resulting executable to +; be covered by the GNU General Public License. This exception does +; not however invalidate any other reasons why the executable file +; might be covered by the GNU General Public License. +;-------------------------------------------------------------------------- + +;-- +; +; File: ftoa.asm +; Author: George Gallant +; Date: 19OCT04 +; +; This routine provides a floating point to ascii conversion. +; It was written support the SDCC project. +; +; SDCC C Syntax: +; +; extern void g_ftoa(data char *buf, float num, char precision); +; +; The routine is NOT reenterant but expects the entire parameter list +; to be placed on the stack. +; +; Notes: 1. measured 105usec to convert -65535.996 on a 20MHz 18f252 +; 2. Software stack can not cross a RAM page boundary +; +;-- + list r=dec, n=96, st=off, mm=off + + nolist + include <p18fxxx.inc> + list + + udata + + extern digits + +exp: res 1 +man: res 4 +r: res 5 +x: res 3 +bp: res 2 +prec: res 1 +ctr: res 1 + + code + + extern cvt_dec_word + global _g_ftoa + +_g_ftoa: movff FSR2H,POSTDEC1 + movff FSR2L,POSTDEC1 + + movff FSR1H,FSR2H + movff FSR1L,FSR2L + + movff exp, POSTDEC1 + movff man+0, POSTDEC1 + movff man+1, POSTDEC1 + movff man+2, POSTDEC1 + movff man+3, POSTDEC1 + movff r+0, POSTDEC1 + movff r+1, POSTDEC1 + movff r+2, POSTDEC1 + movff r+3, POSTDEC1 + movff r+4, POSTDEC1 + movff x+0, POSTDEC1 + movff x+1, POSTDEC1 + movff bp+0, POSTDEC1 + movff bp+1, POSTDEC1 + movff prec, POSTDEC1 + movff ctr, POSTDEC1 + + movff FSR0H,POSTDEC1 + movff FSR0L,POSTDEC1 + + movlw 3 + addwf FSR2L, f + btfsc STATUS,C + incf FSR2H, f + + movff POSTINC2,FSR0L ;get the low byte of buf pointer + movff POSTINC2,FSR0H + + movff POSTINC2,man+0 ;get the low byte of float + movff POSTINC2,man+1 + movff POSTINC2,man+2 + movff POSTINC2,exp + + movff POSTINC2,prec + + rlcf man+2,w + rlcf exp,f + bnc @1 + movlw '-' + movwf POSTINC0 + +@1: movff man+0,r+0 + movff man+1,r+1 + movff man+2,r+2 + bsf r+2,7 + clrf r+3 + clrf r+4 + +; Shift the mantissa left or right by the expondent + + movf exp,w ;get the expondent + sublw 127 ;subtract the bais + bz @4 ;skip shifting if zero + bn @3 ;shift left if neg + +@2: bcf STATUS,C ;otherwise, shift right + rrcf r+4,f + rrcf r+3,f + rrcf r+2,f + rrcf r+1,f + rrcf r+0,f + decfsz WREG,w + bra @2 + bra @4 + +@3: bcf STATUS,C + rlcf r+0, f + rlcf r+1, f + rlcf r+2, f + rlcf r+3, f + rlcf r+4, f + incfsz WREG,w + bra @3 + +@4: rlcf r+2,w ;extract bit 23 + rlcf r+3,f ;shift rest of whole number + rlcf r+4,f + + movff r+3,PRODL + movff r+4,PRODH + call cvt_dec_word + + movlw '.' + movwf POSTINC0 + +@10: movlw 0x7F + andwf r+2,f + clrf r+3 + + movff r+0,x+0 ;temp copy + movff r+1,x+1 + movff r+2,x+2 + + bcf STATUS,C ;mult by 2 + rlcf r+0,f + rlcf r+1,f + rlcf r+2,f + rlcf r+3,f + + bcf STATUS,C ;mult by 4 + rlcf r+0,f + rlcf r+1,f + rlcf r+2,f + rlcf r+3,f + + movf x+0,w ;mult by 5 + addwf r+0,f + movf x+1,w + addwfc r+1,f + movf x+2,w + addwfc r+2,f + movlw 0 + addwfc r+3,f + + rlcf r+2,w ;div by 0x400000 + rlcf r+3,f ;or just extract bits 24-22 + rlcf WREG,w + rlcf r+3,f + + movf r+3,w ;this is the bcd value + addlw 0x30 ;convert to ascii + movwf POSTINC0 ;and save in memory + + bcf STATUS,C ;mult by 2 + rlcf r+0,f + rlcf r+1,f + rlcf r+2,f + + decfsz prec,f + bra @10 + + clrf POSTINC0 ;pack a nullbyte at the end + + + movff ctr, POSTDEC1 + movff prec, POSTDEC1 + movff bp+1, POSTDEC1 + movff bp+0, POSTDEC1 + movff x+1, POSTDEC1 + movff x+0, POSTDEC1 + movff r+4, POSTDEC1 + movff r+3, POSTDEC1 + movff r+2, POSTDEC1 + movff r+1, POSTDEC1 + movff r+0, POSTDEC1 + movff man+3, POSTDEC1 + movff man+2, POSTDEC1 + movff man+1, POSTDEC1 + movff man+0, POSTDEC1 + movff exp, POSTDEC1 + + movff PREINC1,FSR0L + movff PREINC1,FSR0H + + movff PREINC1,FSR2L + movff PREINC1,FSR2H + return + + end diff --git a/device/lib/pic16/libc/stdlib/itoa.c b/device/lib/pic16/libc/stdlib/itoa.c new file mode 100644 index 0000000..a42bbfe --- /dev/null +++ b/device/lib/pic16/libc/stdlib/itoa.c @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + itoa.c - convert (unsigned) int to strings + + Copyright (C) 2005, Raphael Neider <rneider at web.de> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <stdlib.h> + +void uitoa (unsigned int value, __data char *str, unsigned char radix) +{ + ultoa (value, str, radix); +} + +void itoa (int value, __data char *str, unsigned char radix) +{ + ltoa (value, str, radix); +} diff --git a/device/lib/pic16/libc/stdlib/ltoa.c b/device/lib/pic16/libc/stdlib/ltoa.c new file mode 100644 index 0000000..9bb6084 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/ltoa.c @@ -0,0 +1,87 @@ +/*------------------------------------------------------------------------- + ltoa.c - long integer to string conversion + + Copyright (C) 1999, Bela Torok <bela.torok at kssg.ch> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + value -> Number to be converted + string -> Result + radix -> Base of value (e.g.: 2 for binary, 10 for decimal, 16 for hex) +---------------------------------------------------------------------------*/ + +#define NUMBER_OF_DIGITS 32 + +#if _DEBUG +extern void io_long(unsigned long); +extern void io_str(char *); +#endif + + +void ultoa(unsigned long value, __data char* str, unsigned char radix) +{ + unsigned int index; + unsigned char ch; + unsigned char buffer[NUMBER_OF_DIGITS]; /* space for NUMBER_OF_DIGITS + '\0' */ + + index = NUMBER_OF_DIGITS; + + do { + ch = '0' + (value % radix); + if ( ch > (unsigned char)'9') ch += 'a' - '9' - 1; + +#if _DEBUG + io_str( "ultoa: " ); + io_long( value ); + io_long( (unsigned long) ch ); +#endif + + buffer[ --index ] = ch; + value /= radix; + } while (value != 0); + + do { + *str++ = buffer[index++]; + } while ( index < NUMBER_OF_DIGITS ); + + *str = 0; /* string terminator */ +} + +void ltoa(long value, __data char* str, unsigned char radix) +{ +#if _DEBUG + io_str( "ltoa: " ); + io_long( (unsigned long)value ); +#endif + + if (value < 0 && radix == 10) { + *str++ = '-'; + value = -value; + } + + + + ultoa((unsigned long)value, str, radix); +} diff --git a/device/lib/pic16/libc/stdlib/malloc.c b/device/lib/pic16/libc/stdlib/malloc.c new file mode 100644 index 0000000..56d309d --- /dev/null +++ b/device/lib/pic16/libc/stdlib/malloc.c @@ -0,0 +1,119 @@ +/*------------------------------------------------------------------------- + malloc.c - dynamic memory allocation + + Copyright (C) 2004, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <malloc.h> + +/* this is an external pointer to HEAP. It should be defined in + * the user's program, or it can be a symbol created by linker */ +extern unsigned char _MALLOC_SPEC *heap; + +unsigned char _MALLOC_SPEC *malloc(unsigned char len) +{ + _malloc_rec _MALLOC_SPEC *pHeap; /* pointer to block header */ + _malloc_rec _MALLOC_SPEC *temp; + unsigned char bLen, eLen; /* size of block */ +#if MALLOC_MAX_FIRST + unsigned char pass=1; +#endif + + if(len >= MAX_BLOCK_SIZE) + goto do_end; + + pHeap = (_malloc_rec _MALLOC_SPEC *)&heap; + + while(1) { + bLen = pHeap->bits.count; + + /* if datum is zero, then last block, return NULL */ + if(pHeap->datum == 0) { +#if !MALLOC_MAX_FIRST + goto do_end; +#else + if(!pass) + goto do_end; + + /* in the first pass, we search for blocks that have + * the requested size, in the second pass, try to merge + * adjacent blocks to 'make' the requested block */ + pHeap = (_malloc_rec _MALLOC_SPEC *)&heap; + pass--; + continue; +#endif + } + + /* if current block is allocated then proceed to next */ + if(pHeap->bits.alloc) + goto do_continue; + + + /* current block is not allocated, try to allocate */ + + /* if current block is not enough for allocation, then proceed to next */ + if(bLen <= len) { + +#if MALLOC_MAX_FIRST + /* if we are in the first pass, check next block */ + if(pass) + goto do_continue; + + /* otherwise try merge */ +#endif + + temp = _mergeHeapBlock(pHeap, len); + + if(!temp) + /* otherwise proceed with next block */ + goto do_continue; + + //pHeap = temp; /* temp == pHeap */ + bLen = pHeap->bits.count; + } + + /* current block is enough to hold the new block */ + + /* allocate by filling the fields */ + eLen = (len+1); + pHeap->datum = 0x80 | eLen; + + if(bLen > eLen) { + /* if current block size is greater than the requested one, + * create a new empty block at the end of the newly allocated */ + temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + eLen); + temp->datum = (bLen - eLen); + } + + return ((unsigned char _MALLOC_SPEC *)((unsigned int)pHeap + 1)); + +do_continue: + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + bLen); + } + +do_end: + return ((unsigned char _MALLOC_SPEC *)0); + +} diff --git a/device/lib/pic16/libc/stdlib/memfree.c b/device/lib/pic16/libc/stdlib/memfree.c new file mode 100644 index 0000000..ab7f649 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/memfree.c @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + memfree.c - return size of all unallocated heap + + Copyright (C) 2005, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <malloc.h> + +extern unsigned char _MALLOC_SPEC *heap; + +unsigned int memfree(void) +{ + _malloc_rec _MALLOC_SPEC *pHeap; + unsigned int hsize=0; + unsigned char bLen; + + pHeap = (_malloc_rec _MALLOC_SPEC *)&heap; + + while ((bLen = pHeap->bits.count)) { + if(!pHeap->bits.alloc) + hsize += bLen - 1; + + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + bLen); + } + + return (hsize); +} diff --git a/device/lib/pic16/libc/stdlib/memfreemax.c b/device/lib/pic16/libc/stdlib/memfreemax.c new file mode 100644 index 0000000..1d164a2 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/memfreemax.c @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + memfreemax.c - return size of maximum unallocated heap block + + Copyright (C) 2005, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <malloc.h> + +extern unsigned char _MALLOC_SPEC *heap; + +unsigned int memfreemax(void) +{ + _malloc_rec _MALLOC_SPEC *pHeap; + unsigned char maxSize = 1; + unsigned char bLen; + + pHeap = (_malloc_rec _MALLOC_SPEC *)&heap; + + while ((bLen = pHeap->bits.count)) { + if(!pHeap->bits.alloc && (bLen > maxSize)) + maxSize = bLen; + + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + bLen); + } + + /* do not count the block header */ + --maxSize; + + return (maxSize); +} diff --git a/device/lib/pic16/libc/stdlib/memmisc.c b/device/lib/pic16/libc/stdlib/memmisc.c new file mode 100644 index 0000000..6454f39 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/memmisc.c @@ -0,0 +1,98 @@ +/*------------------------------------------------------------------------- + memmisc.c - heap handling functions + + Copyright (C) 2005, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <malloc.h> + +void _initHeap(unsigned char _MALLOC_SPEC *dheap, unsigned int heapsize) +{ + _malloc_rec _MALLOC_SPEC *pHeap; + unsigned int hsize=0; + int bsize; + + pHeap = (_malloc_rec _MALLOC_SPEC *)dheap; + if (heapsize == 0) return; + /* we need one byte as the end of block list marker */ + heapsize--; + + while (hsize < heapsize) { + /* a guess of the next block size */ + bsize = (heapsize - hsize); /* thus: bsize > 0 */ + if(bsize > MAX_BLOCK_SIZE) bsize = MAX_BLOCK_SIZE; + + /* now we can create the block */ + pHeap->datum = bsize; + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + bsize); + + hsize += bsize; + } + + /* mark end of block list */ + pHeap->datum = 0; +} + +/* search heap starting from sBlock for a block of size bSize, merging + * adjacent blocks if necessery */ +_malloc_rec _MALLOC_SPEC *_mergeHeapBlock(_malloc_rec _MALLOC_SPEC *sBlock, unsigned char bSize) +{ + _malloc_rec _MALLOC_SPEC *temp; + unsigned char bLen; + unsigned char eLen; + unsigned char dat; + + bLen = sBlock->bits.count; + + /* current block is not enough, see if we can merge some adjacent memory + * blocks to make it fit */ + temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)sBlock + bLen); //sBlock->bits.count); + eLen = bLen; + while((temp->datum) && (!temp->bits.alloc) && (eLen <= bSize)) { + eLen += (dat=temp->bits.count); + temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)temp + dat); + } + + if(eLen > bSize) { + unsigned char i; + + /* yes, there are some free blocks that can be merged, so merge them... */ + temp = sBlock; + while(eLen > 0) { + if(eLen > MAX_BLOCK_SIZE)i = MAX_BLOCK_SIZE; + else i = eLen; + temp->datum = i; + temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)temp + i); + eLen -= i; + } + + /* return block starts at the old block start address */ + return (sBlock); + } else { + + /* no, there are no free blocks after sBlock, so return NULL */ + return ((_malloc_rec _MALLOC_SPEC *)0); + } +} diff --git a/device/lib/pic16/libc/stdlib/rand.c b/device/lib/pic16/libc/stdlib/rand.c new file mode 100644 index 0000000..efcd040 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/rand.c @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------- + rand.c - random number generation routines + + Copyright (C) 2005, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +/* + * derived from the book "The C Programming Language," by Kernighan and Ritchie + */ + +#include <stdlib.h> + +static long do_rand(unsigned long *ctx) +{ + return ((*ctx = *ctx * 1103515245UL + 12345UL) % ((unsigned long)RAND_MAX + 1)); +} + +long rand_r(unsigned long *ctx) +{ + unsigned long val = (unsigned long) *ctx; + + *ctx = do_rand(&val); + return (long) *ctx; +} + +static unsigned long next = 1; + +long rand(void) +{ + return do_rand(&next); +} + +void srand(unsigned long seed) +{ + next = seed; +} + +#ifdef TEST + +main() +{ + int i; + unsigned long myseed; + + stdout = STREAM_GPSIM; + + printf("seeding rand with 0x19610910: \n"); + srand(0x19610910); + + printf("generating three pseudo-random numbers:\n"); + for (i = 0; i < 10; i++) + { + printf("next random number = %ld\n", rand()); + } + + printf("generating the same sequence with rand_r:\n"); + myseed = 0x19610910; + for (i = 0; i < 10; i++) + { + printf("next random number = %ld\n", rand_r(&myseed)); + } + + return 0; +} + +#endif /* TEST */ + diff --git a/device/lib/pic16/libc/stdlib/realloc.c b/device/lib/pic16/libc/stdlib/realloc.c new file mode 100644 index 0000000..ee66864 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/realloc.c @@ -0,0 +1,83 @@ +/*------------------------------------------------------------------------- + realloc.c - dynamic memory allocation + + Copyright (C) 2004, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <malloc.h> + +extern unsigned char _MALLOC_SPEC *heap; + +unsigned char _MALLOC_SPEC *realloc(unsigned char _MALLOC_SPEC *mblock, unsigned char len) +{ + _malloc_rec _MALLOC_SPEC *pHeap; /* pointer to block header */ + _malloc_rec _MALLOC_SPEC *temp; + unsigned char bLen; /* size of block */ + + if(len >= MAX_BLOCK_SIZE) + return ((unsigned char _MALLOC_SPEC *)0); + + /* if mblock is NULL, then same as malloc */ + if(!mblock) + return (malloc(len)); + + /* if len is 0 */ + if(len == 0) { + free(mblock); + return ((unsigned char _MALLOC_SPEC *)0); + } + + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)mblock - 1); + bLen = pHeap->bits.count; + + /* block too small for len bytes + 1 byte header <===> bLen < len + 1 <===> blen <= len */ + if (bLen <= len) { + /* so, new segment has size bigger than the old one, we can return a + * valid pointer only when after the block there is an empty block that + * can be merged to produce a new block of the requested size, otherwise + * we return NULL */ + temp = _mergeHeapBlock(pHeap, len); + + if(!temp) { + /* no could not find a valid block, return NULL */ + return ((unsigned char _MALLOC_SPEC *)0); + } + + //pHeap = temp; /* temp == pHeap */ + bLen = pHeap->bits.count; + } + + len++; /* increase to also count the header */ + + if(bLen > len) { + /* new segment is smaller than the old one (or the merged one), that's easy! */ + pHeap->bits.count = len; + temp = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + len); + temp->bits.alloc = 0; + temp->bits.count = bLen - len; + } + + return (mblock); +} 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 0000000..2a9ba9f --- /dev/null +++ b/device/lib/pic16/libc/stdlib/x_ftoa.c @@ -0,0 +1,193 @@ +/*------------------------------------------------------------------------- + x_ftoa.c - wrapper function to use _convert_float + + Copyright (C) 2004, Vangelis Rokas <vrokas at otenet.gr> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, 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 library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include <float.h> + +extern int convert_frac; +extern int convert_int; + +/* char x_ftoa(float, __data char *, unsigned char, unsigned char); */ + + +extern int POSTDEC1; +extern int PLUSW2; +extern int FSR0L; +extern int FSR0H; +extern int PREINC1; +extern int PREINC2; +extern int FSR2L; +extern int FSR2H; + +#define _vv0x00 0x00 +#define _vv0x01 0x01 +#define _vv0x02 0x02 +#define _vv0x03 0x03 +#define _vv0x04 0x04 + +/* do not warn about unreferenced arguments/missing return values */ +#pragma save +#pragma disable_warning 59 +#pragma disable_warning 85 + +char x_cnvint_wrap(unsigned long num, __data char *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 ; +} +#pragma restore + + +union float_long { + unsigned long l; + float f; +}; + +char x_ftoa(float num, __data char *buffer, unsigned char buflen, unsigned char prec) +{ + char len; + signed 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); +} |
