summaryrefslogtreecommitdiff
path: root/device/lib/pic16/libc/stdlib
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /device/lib/pic16/libc/stdlib
downloadsdcc-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.c94
-rw-r--r--device/lib/pic16/libc/stdlib/atoi.c57
-rw-r--r--device/lib/pic16/libc/stdlib/atol.c52
-rw-r--r--device/lib/pic16/libc/stdlib/calloc.c50
-rw-r--r--device/lib/pic16/libc/stdlib/crc16.c83
-rw-r--r--device/lib/pic16/libc/stdlib/free.c37
-rw-r--r--device/lib/pic16/libc/stdlib/g_ftoa.S236
-rw-r--r--device/lib/pic16/libc/stdlib/itoa.c39
-rw-r--r--device/lib/pic16/libc/stdlib/ltoa.c87
-rw-r--r--device/lib/pic16/libc/stdlib/malloc.c119
-rw-r--r--device/lib/pic16/libc/stdlib/memfree.c49
-rw-r--r--device/lib/pic16/libc/stdlib/memfreemax.c52
-rw-r--r--device/lib/pic16/libc/stdlib/memmisc.c98
-rw-r--r--device/lib/pic16/libc/stdlib/rand.c89
-rw-r--r--device/lib/pic16/libc/stdlib/realloc.c83
-rw-r--r--device/lib/pic16/libc/stdlib/x_ftoa.c193
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);
+}