From 91070d31fe63aaa9412098be0aa469660b10822d Mon Sep 17 00:00:00 2001 From: vrokas Date: Thu, 31 Mar 2005 16:25:17 +0000 Subject: [PATCH] * src/pic16/device.c (Pics16[]): added devices 18F2550, 18F4331, 18F4455, * (pic16_assignConfigWordValue): disable testing of configuration register value with config mask, * src/pic16/gen.c (pic16_testStackOverflow): prefix stack test function with port->fun_prefix, * (genFunction): when generating a naked interrupt function never create an absolute segment placed in interrupt vector address, place the actual interrupt function at IVA instead, when an interrupt function is generated with unspecified interrupt then do not create the absolute section, * (genGenPointerGet, genGenPointerSet, genPackBits): replace all code for generating a call to generic pointer get/put function with a call to function pic16_callGenericPointer(), * src/pic16/genutils.c (pic16_callGenericPointerRW): NEW, generates the call to the generic pointer get/put functions with prefixing the function name with port->fun_prefix, * src/pic16/glue.c (pic16glue): ifdef-out test of OF_LR_SUPPORT, * src/pic16/main.c (_process_pragma): prefix function with port->fun_prefix, * (_pic16_finaliseOptions): define macro __18Fxxxx macro when calling assembler, old 18Fxxxx macro is deprecated, * src/pic16/pcode.c (unlinkpCodeFromBranch): added PC_INLINE and PC_ASMDIR in while condition, * (findInstruction): add PC_ASMDIR in while condition, * (buildCallTree): prefix main with port->fun_prefix, * (pic16_pCode2str): fixed bug that didn't emit the memory access identifier for variable with banked access in instructions BTFSS, BTFSC, BCF, BSF, BTG * (AnalyzeFlow): moved call to OptimizepCode to pic16_AnalyzeBanking, * src/pic16/pcodepeep.c (pCodeOpCompare): increase size of b to 1024, * src/pic16/pcoderegs.c (pic16_pCodeRegoptimizeRegUsage): don't perform optimization when enviroment variable NO_REG_OPT is set, * (insideLRBlock): NEW, return 1 if register is inside an INF_LOCALREGS block, * (RemoveRegFromLRBlock): remove a register that is completely eliminated by register optimization, but it is still left in local register store/restore in/from stack block, * (Remove2pcodes): after removing register, check to see if it should be removed from local register store/restore in/from stack block, * src/pic16/ralloc.c (pic16_decodeOp): added decode for DUMMY_READ_VOLATILE, * device/include/pic16/adc.h: minor prototype modifications and update, * device/include/pic16/malloc.h: added GPL notice various modifications, * device/include/pic16/stdint.h: NEW, standard header for ints * device/include/pic16/delay.h: NEW, header for delay functions, delay10tcy, delay100tcy, delay1ktcy, delay10ktcy, delay100ktcy, delay1mtcy, * device/include/pic16/signal.h: NEW, header providing helper macros for implementing signal handlers, * device/include/pic16/stdio.h: added prototypes for functions, printf, vprintf, sprintf, vsprintf, fprintf, vfprintf. Added prototypes for stdin and stdout, added macro PUTCHAR to automatically implement putchar function prototype, * device/include/pic16/usart.h: modified and updated USART library, * device/lib/pic16/libio/adc/, * device/lib/pic16/libio/i2c: some modifications to improve library performance, * device/lib/pic16/libc/stdio/: modifications for the new printf* family of functions, * device/lib/pic16/libc/stdlib/: various modifications in the malloc family of functions and other sources, * device/lib/pic16/libio/usart/: NEW, c sources for the usart module of the PIC18Fxx[28] devices, * device/lib/pic16/libc/delay/: NEW, c sources for the delay functions, * device/lib/pic16/libc/utils/: minor modifications in the .S sources, * device/lib/pic16/startup/{crt0i.c, crt0iz.c}: redesign of the _do_cinit function, because the previous failed when local variables where not placed in the same memory bank, * device/lib/pic16/libsdcc/char/: various modifications to improve library performance, * doc/sdccman.lyx: some reorganization of the PIC16 part, added many information on the new functions of the c library and more... git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3711 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 80 +++++ device/include/pic16/adc.h | 12 +- device/include/pic16/delay.h | 50 +++ device/include/pic16/malloc.h | 104 +++++- device/include/pic16/p18fxxx.inc | 86 +++++ device/include/pic16/pic18fregs.h | 7 + device/include/pic16/stdint.h | 157 +++++++++ device/include/pic16/stdio.h | 74 +++- device/include/pic16/stdlib.h | 8 +- device/lib/pic16/libc/Makefile | 1 + device/lib/pic16/libc/Makefile.rules | 17 +- device/lib/pic16/libc/delay/Makefile | 52 +++ device/lib/pic16/libc/delay/delay100ktcy.S | 46 +++ device/lib/pic16/libc/delay/delay100tcy.S | 39 +++ device/lib/pic16/libc/delay/delay10ktcy.S | 46 +++ device/lib/pic16/libc/delay/delay10tcy.S | 31 ++ device/lib/pic16/libc/delay/delay1ktcy.S | 39 +++ device/lib/pic16/libc/delay/delay1mtcy.S | 53 +++ device/lib/pic16/libc/stdio/Makefile | 15 +- device/lib/pic16/libc/stdio/fprintf.c | 53 +++ device/lib/pic16/libc/stdio/printf.c | 54 +++ device/lib/pic16/libc/stdio/printf_small.c | 9 +- device/lib/pic16/libc/stdio/printf_tiny.c | 88 +++-- device/lib/pic16/libc/stdio/sprintf.c | 46 +++ device/lib/pic16/libc/stdio/streams.c | 33 ++ device/lib/pic16/libc/stdio/strmgpsim.c | 41 +++ device/lib/pic16/libc/stdio/strmmssp.c | 40 +++ device/lib/pic16/libc/stdio/strmputchar.c | 61 ++++ device/lib/pic16/libc/stdio/strmusart.c | 46 +++ device/lib/pic16/libc/stdio/vfprintf.c | 168 +++++++++ device/lib/pic16/libc/stdio/vprintf.c | 39 +++ device/lib/pic16/libc/stdio/vsprintf.c | 43 +++ device/lib/pic16/libc/stdlib/Makefile | 19 +- device/lib/pic16/libc/stdlib/atoi.c | 13 +- device/lib/pic16/libc/stdlib/calloc.c | 52 ++- device/lib/pic16/libc/stdlib/free.c | 29 +- device/lib/pic16/libc/stdlib/g_ftoa.S | 208 ++++++++++++ device/lib/pic16/libc/stdlib/ltoa.c | 55 ++- device/lib/pic16/libc/stdlib/malloc.c | 172 ++++++---- device/lib/pic16/libc/stdlib/memfree.c | 46 +++ device/lib/pic16/libc/stdlib/memfreemax.c | 47 +++ device/lib/pic16/libc/stdlib/memmisc.c | 95 ++++++ device/lib/pic16/libc/stdlib/putchar.c | 3 +- device/lib/pic16/libc/stdlib/realloc.c | 144 ++++---- device/lib/pic16/libc/utils/Makefile | 20 +- device/lib/pic16/libc/utils/cnvfrac.S | 2 +- device/lib/pic16/libc/utils/cnvint.S | 2 +- device/lib/pic16/libio/Makefile | 4 +- device/lib/pic16/libio/Makefile.rules | 19 +- device/lib/pic16/libio/adc/Makefile | 18 +- device/lib/pic16/libio/adc/adcbusy.c | 13 +- device/lib/pic16/libio/adc/adcclose.c | 33 +- device/lib/pic16/libio/adc/adcconv.c | 30 +- device/lib/pic16/libio/adc/adcopen.c | 74 ++-- device/lib/pic16/libio/adc/adcread.c | 44 ++- device/lib/pic16/libio/adc/adcsetch.c | 53 ++- device/lib/pic16/libio/i2c/i2cdrdy.c | 6 +- device/lib/pic16/libio/usart/Makefile | 58 ++++ device/lib/pic16/libio/usart/ubaud.c | 36 ++ device/lib/pic16/libio/usart/ubusy.c | 47 +++ device/lib/pic16/libio/usart/uclose.c | 39 +++ device/lib/pic16/libio/usart/udrdy.c | 47 +++ device/lib/pic16/libio/usart/ugetc.c | 53 +++ device/lib/pic16/libio/usart/ugets.c | 50 +++ device/lib/pic16/libio/usart/uopen.c | 73 ++++ device/lib/pic16/libio/usart/uputc.c | 61 ++++ device/lib/pic16/libio/usart/uputs.c | 40 +++ device/lib/pic16/libio/usart/usartd.c | 33 ++ device/lib/pic16/libsdcc/Makefile.rules | 11 +- device/lib/pic16/libsdcc/char/Makefile | 13 +- device/lib/pic16/libsdcc/char/divschar.c | 16 +- device/lib/pic16/libsdcc/char/divuchar.c | 7 +- device/lib/pic16/libsdcc/char/modschar.c | 18 +- device/lib/pic16/libsdcc/char/moduchar.c | 6 +- device/lib/pic16/libsdcc/float/Makefile | 5 +- device/lib/pic16/libsdcc/float/fs2ulong.c | 6 +- device/lib/pic16/startup/Makefile | 2 +- device/lib/pic16/startup/crt0.c | 47 ++- device/lib/pic16/startup/crt0i.c | 338 +++++++++--------- device/lib/pic16/startup/crt0iz.c | 376 +++++++++++---------- src/pic16/NOTES | 11 + src/pic16/device.c | 129 +++++-- src/pic16/gen.c | 114 ++----- src/pic16/gen.h | 12 +- src/pic16/genutils.c | 30 ++ src/pic16/genutils.h | 5 + src/pic16/glue.c | 2 + src/pic16/main.c | 5 +- src/pic16/pcode.c | 260 +++++++------- src/pic16/pcode.h | 9 +- src/pic16/pcodepeep.c | 16 +- src/pic16/pcoderegs.c | 161 ++++++--- src/pic16/ralloc.c | 158 +++++++-- src/pic16/ralloc.h | 1 + 94 files changed, 4100 insertions(+), 1034 deletions(-) create mode 100644 device/include/pic16/delay.h create mode 100644 device/include/pic16/p18fxxx.inc create mode 100644 device/include/pic16/stdint.h create mode 100644 device/lib/pic16/libc/delay/Makefile create mode 100644 device/lib/pic16/libc/delay/delay100ktcy.S create mode 100644 device/lib/pic16/libc/delay/delay100tcy.S create mode 100644 device/lib/pic16/libc/delay/delay10ktcy.S create mode 100644 device/lib/pic16/libc/delay/delay10tcy.S create mode 100644 device/lib/pic16/libc/delay/delay1ktcy.S create mode 100644 device/lib/pic16/libc/delay/delay1mtcy.S create mode 100644 device/lib/pic16/libc/stdio/fprintf.c create mode 100644 device/lib/pic16/libc/stdio/printf.c create mode 100644 device/lib/pic16/libc/stdio/sprintf.c create mode 100644 device/lib/pic16/libc/stdio/streams.c create mode 100644 device/lib/pic16/libc/stdio/strmgpsim.c create mode 100644 device/lib/pic16/libc/stdio/strmmssp.c create mode 100644 device/lib/pic16/libc/stdio/strmputchar.c create mode 100644 device/lib/pic16/libc/stdio/strmusart.c create mode 100644 device/lib/pic16/libc/stdio/vfprintf.c create mode 100644 device/lib/pic16/libc/stdio/vprintf.c create mode 100644 device/lib/pic16/libc/stdio/vsprintf.c create mode 100644 device/lib/pic16/libc/stdlib/g_ftoa.S create mode 100644 device/lib/pic16/libc/stdlib/memfree.c create mode 100644 device/lib/pic16/libc/stdlib/memfreemax.c create mode 100644 device/lib/pic16/libc/stdlib/memmisc.c create mode 100644 device/lib/pic16/libio/usart/Makefile create mode 100644 device/lib/pic16/libio/usart/ubaud.c create mode 100644 device/lib/pic16/libio/usart/ubusy.c create mode 100644 device/lib/pic16/libio/usart/uclose.c create mode 100644 device/lib/pic16/libio/usart/udrdy.c create mode 100644 device/lib/pic16/libio/usart/ugetc.c create mode 100644 device/lib/pic16/libio/usart/ugets.c create mode 100644 device/lib/pic16/libio/usart/uopen.c create mode 100644 device/lib/pic16/libio/usart/uputc.c create mode 100644 device/lib/pic16/libio/usart/uputs.c create mode 100644 device/lib/pic16/libio/usart/usartd.c diff --git a/ChangeLog b/ChangeLog index d65987b3..fc5caa69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,83 @@ +2005-03-31 Vangelis Rokas + + * src/pic16/device.c (Pics16[]): added devices 18F2550, 18F4331, + 18F4455, + * (pic16_assignConfigWordValue): disable testing of configuration + register value with config mask, + * src/pic16/gen.c (pic16_testStackOverflow): prefix stack test + function with port->fun_prefix, + * (genFunction): when generating a naked interrupt function never + create an absolute segment placed in interrupt vector address, place + the actual interrupt function at IVA instead, when an interrupt + function is generated with unspecified interrupt then do not create + the absolute section, + * (genGenPointerGet, genGenPointerSet, genPackBits): replace all + code for generating a call to generic pointer get/put function with + a call to function pic16_callGenericPointer(), + * src/pic16/genutils.c (pic16_callGenericPointerRW): NEW, generates + the call to the generic pointer get/put functions with prefixing the + function name with port->fun_prefix, + * src/pic16/glue.c (pic16glue): ifdef-out test of OF_LR_SUPPORT, + * src/pic16/main.c (_process_pragma): prefix function with + port->fun_prefix, + * (_pic16_finaliseOptions): define macro __18Fxxxx macro when + calling assembler, old 18Fxxxx macro is deprecated, + * src/pic16/pcode.c (unlinkpCodeFromBranch): added PC_INLINE and + PC_ASMDIR in while condition, + * (findInstruction): add PC_ASMDIR in while condition, + * (buildCallTree): prefix main with port->fun_prefix, + * (pic16_pCode2str): fixed bug that didn't emit the memory access + identifier for variable with banked access in instructions BTFSS, + BTFSC, BCF, BSF, BTG + * (AnalyzeFlow): moved call to OptimizepCode to pic16_AnalyzeBanking, + * src/pic16/pcodepeep.c (pCodeOpCompare): increase size of b to 1024, + * src/pic16/pcoderegs.c (pic16_pCodeRegoptimizeRegUsage): don't + perform optimization when enviroment variable NO_REG_OPT is set, + * (insideLRBlock): NEW, return 1 if register is inside an + INF_LOCALREGS block, + * (RemoveRegFromLRBlock): remove a register that is completely + eliminated by register optimization, but it is still left in local + register store/restore in/from stack block, + * (Remove2pcodes): after removing register, check to see if it + should be removed from local register store/restore in/from stack + block, + * src/pic16/ralloc.c (pic16_decodeOp): added decode for + DUMMY_READ_VOLATILE, + + * device/include/pic16/adc.h: minor prototype modifications and + update, + * device/include/pic16/malloc.h: added GPL notice various + modifications, + * device/include/pic16/stdint.h: NEW, standard header for ints + * device/include/pic16/delay.h: NEW, header for delay functions, + delay10tcy, delay100tcy, delay1ktcy, delay10ktcy, delay100ktcy, + delay1mtcy, + * device/include/pic16/signal.h: NEW, header providing helper macros + for implementing signal handlers, + * device/include/pic16/stdio.h: added prototypes for functions, + printf, vprintf, sprintf, vsprintf, fprintf, vfprintf. Added + prototypes for stdin and stdout, added macro PUTCHAR to + automatically implement putchar function prototype, + * device/include/pic16/usart.h: modified and updated USART library, + * device/lib/pic16/libio/adc/, + * device/lib/pic16/libio/i2c: some modifications to improve library + performance, + * device/lib/pic16/libc/stdio/: modifications for the new printf* + family of functions, + * device/lib/pic16/libc/stdlib/: various modifications in the malloc + family of functions and other sources, + * device/lib/pic16/libio/usart/: NEW, c sources for the usart module + of the PIC18Fxx[28] devices, + * device/lib/pic16/libc/delay/: NEW, c sources for the delay functions, + * device/lib/pic16/libc/utils/: minor modifications in the .S sources, + * device/lib/pic16/startup/{crt0i.c, crt0iz.c}: redesign of the + _do_cinit function, because the previous failed when local variables + where not placed in the same memory bank, + * device/lib/pic16/libsdcc/char/: various modifications to improve + library performance, + * doc/sdccman.lyx: some reorganization of the PIC16 part, added many + information on the new functions of the c library and more... + 2005-03-28 Erik Petrich * src/SDCCBBlock.c (iCodeBreakDown): fixed bug #1170212 diff --git a/device/include/pic16/adc.h b/device/include/pic16/adc.h index b6815732..ce1e9f8d 100644 --- a/device/include/pic16/adc.h +++ b/device/include/pic16/adc.h @@ -79,16 +79,22 @@ #define ADC_CFG_1A_2R 0x0f +/* initialize AD module */ void adc_open(unsigned char channel, unsigned char fosc, unsigned char pcfg, unsigned char config); +/* shutdown AD module */ void adc_close(void); +/* begin a conversion */ void adc_conv(void); -char adc_busy(void); +/* return 1 if AD is performing a conversion, 0 if done */ +char adc_busy(void) _naked; -int adc_read(void); +/* get value of convertion */ +int adc_read(void) _naked; -void adc_setchannel(unsigned char channel); +/* setup conversion channel */ +void adc_setchannel(unsigned char channel) _naked; #endif diff --git a/device/include/pic16/delay.h b/device/include/pic16/delay.h new file mode 100644 index 00000000..1f935364 --- /dev/null +++ b/device/include/pic16/delay.h @@ -0,0 +1,50 @@ + +/* + * delay.h - delay functions header file + * + * adopted for SDCC and pic16 port by Vangelis Rokas, 2005 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* +** $Id$ +*/ + + +#ifndef __DELAY_H__ +#define __DELAY_H__ + +#pragma library c + +/* + * the delayNNtcy family of functions performs a + * delay of NN cycles. Possible values for NN are: + * 10 10*n cycles delay + * 100 100*n cycles delay + * 1k 1000*n cycles delay + * 10k 10000*n cycles delay + * 100k 100000*n cycles delay + * 1m 1000000*n cycles delay + */ + +void delay10tcy(unsigned char) wparam; +void delay100tcy(unsigned char) wparam; +void delay1ktcy(unsigned char) wparam; +void delay10ktcy(unsigned char) wparam; +void delay100ktcy(unsigned char) wparam; +void delay1mtcy(unsigned char) wparam; + +#endif diff --git a/device/include/pic16/malloc.h b/device/include/pic16/malloc.h index 4f9d24e7..173a6974 100644 --- a/device/include/pic16/malloc.h +++ b/device/include/pic16/malloc.h @@ -3,6 +3,25 @@ * * written by Vangelis Rokas, 2004 (vrokas@otenet.gr) * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ */ @@ -17,43 +36,94 @@ #ifndef __MALLOC_H__ #define __MALLOC_H__ -#pragma library c +/* set EMULATION to 1 to enable native Linux malloc emulation layer. This is + * for debugging purposes only */ + +#ifndef EMULATION #define EMULATION 0 +#endif #if EMULATION -#define malloc pic16_malloc -#define free pic16_free -#define realloc pic16_realloc -#define calloc pic16_calloc +//#define malloc pic16_malloc +//#define free pic16_free +//#define realloc pic16_realloc +//#define calloc pic16_calloc + +//#define lmalloc pic16_lmalloc +//#define lfree pic16_lfree +//#define lrealloc pic16_lrealloc +//#define lcalloc pic16_lcalloc #define _MALLOC_SPEC -#endif + +#else + +#pragma library c #define _MALLOC_SPEC data -#define MAX_BLOCK_SIZE 0x7f /* 126 bytes */ +#endif + +/* when MALLOC_MAX_FIRST is 1, the memory allocator tries to find a block + * that fits the requested size without merging (initially), if this block + * is not found, then tries to merge adjacent blocks. If MALLOC_MAX_FIRST is + * set 0, then the allocator tries to merge adjacent blocks in the first + * place. Both behaviours may give better results when used in certain + * circumstancs. I.e. if realloc is to be used, leaving some space after the + * block, will allow realloc to allocate it, otherwise it may result in much + * more memory fragmentation. An algorithm can be implemented to allow small + * fragments to be allocated but this is much too complicated for the PIC18F's + * architecture */ +#define MALLOC_MAX_FIRST 0 + +#define MAX_BLOCK_SIZE 0x7f /* 127 bytes */ #define MAX_HEAP_SIZE 0x200 /* 512 bytes */ #define _MAX_HEAP_SIZE (MAX_HEAP_SIZE-1) #define ALLOC_FLAG 0x80 #define HEADER_SIZE 1 - +/* memory block header, max size 127 bytes, 126 usable */ typedef union { - unsigned char datum; - struct { - unsigned count: 7; - unsigned alloc: 1; - } bits; + unsigned char datum; + struct { + unsigned count: 7; + unsigned alloc: 1; + } bits; } _malloc_rec; -unsigned char _MALLOC_SPEC *malloc(unsigned char); -void free(unsigned char _MALLOC_SPEC *); -unsigned char _MALLOC_SPEC *calloc(unsigned char num); //, unsigned char len); +/* initialize heap, should be called before any call to malloc/realloc/calloc */ +void _initHeap(unsigned char _MALLOC_SPEC *dHeap, unsigned int heapsize); + + +/* start searching for a block of size at least bSize, merge adjacent blocks + * if necessery */ +_malloc_rec _MALLOC_SPEC *_mergeHeapBlock(_malloc_rec _MALLOC_SPEC *sBlock, unsigned char bSize); + + +/* allocate a memory block */ +unsigned char _MALLOC_SPEC *malloc(unsigned char len); + + +/* same as malloc, but clear memory */ +unsigned char _MALLOC_SPEC *calloc(unsigned char len); + + +/* expand or reduce a memory block, if mblock is NULL, then same as malloc */ unsigned char _MALLOC_SPEC *realloc(unsigned char _MALLOC_SPEC *mblock, unsigned char len); -#endif /* __MALLOC_H__ */ +/* free a memory block */ +void free(unsigned char _MALLOC_SPEC *); + + +/* returns the size of all the unallocated memory */ +unsigned int memfree(void); +/* return the size of the maximum unallocated memory block */ +unsigned int memfreemax(void); + + +#endif /* __MALLOC_H__ */ diff --git a/device/include/pic16/p18fxxx.inc b/device/include/pic16/p18fxxx.inc new file mode 100644 index 00000000..71615a3e --- /dev/null +++ b/device/include/pic16/p18fxxx.inc @@ -0,0 +1,86 @@ +#ifndef __P18FXXX__ +#define __P18FXXX__ 1 + + + list r=dec, n=96, st=off, mm=off + + nolist + +; This header file defines configurations, registers, and other useful bits of +; information common to all PIC18Fxxx microcontrollers. + +FSR0 equ 0 +FSR1 equ 1 +FSR2 equ 2 + +FAST equ 1 + +W equ 0 +A equ 0 +ACCESS equ 0 +BANKED equ 1 + +; Register Files + +TOSU equ 0x0FFF +TOSH equ 0x0FFE +TOSL equ 0x0FFD + +STKPTR equ 0x0FFC + +PCLATU equ 0x0FFB +PCLATH equ 0x0FFA +PCL equ 0x0FF9 + +TBLPTRU equ 0x0FF8 +TBLPTRH equ 0x0FF7 +TBLPTRL equ 0x0FF6 +TABLAT equ 0x0FF5 + +PRODH equ 0x0FF4 +PRODL equ 0x0FF3 + +INDF0 equ 0x0FEF +POSTINC0 equ 0x0FEE +POSTDEC0 equ 0x0FED +PREINC0 equ 0x0FEC +PLUSW0 equ 0x0FEB +FSR0H equ 0x0FEA +FSR0L equ 0x0FE9 + +WREG equ 0x0FE8 + +INDF1 equ 0x0FE7 +POSTINC1 equ 0x0FE6 +POSTDEC1 equ 0x0FE5 +PREINC1 equ 0x0FE4 +PLUSW1 equ 0x0FE3 +FSR1H equ 0x0FE2 +FSR1L equ 0x0FE1 + +BSR equ 0x0FE0 + +INDF2 equ 0x0FDF +POSTINC2 equ 0x0FDE +POSTDEC2 equ 0x0FDD +PREINC2 equ 0x0FDC +PLUSW2 equ 0x0FDB +FSR2H equ 0x0FDA +FSR2L equ 0x0FD9 + +STATUS equ 0x0FD8 + +PORTC equ 0x0F82 +PORTB equ 0x0F81 +PORTA equ 0x0F80 + +; Status Register Bit Definitions + +C equ 0 +DC equ 1 +Z equ 2 +OV equ 3 +N equ 4 + + list +#endif diff --git a/device/include/pic16/pic18fregs.h b/device/include/pic16/pic18fregs.h index 717ecb5f..89fd6f61 100644 --- a/device/include/pic16/pic18fregs.h +++ b/device/include/pic16/pic18fregs.h @@ -75,4 +75,11 @@ #endif + +#define Nop() { _asm nop _endasm; } +#define ClrWdt() { _asm clrwdt _endasm; } +#define Sleep() { _asm sleep _endasm; } +#define Reset() { _asm reset _endasm; } + + #endif /* __PIC18FREGS_H__ */ diff --git a/device/include/pic16/stdint.h b/device/include/pic16/stdint.h new file mode 100644 index 00000000..12b26d5b --- /dev/null +++ b/device/include/pic16/stdint.h @@ -0,0 +1,157 @@ +/*------------------------------------------------------------------------- + stdint.h - ISO C99 7.18 Integer types + + Written By - Maarten Brock, sourceforge.brock@dse.nl (2005) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------*/ + +#ifndef _STDINT_H +#define _STDINT_H 1 + +/* Exact integral types. */ + +/* Signed. */ + +typedef signed char int8_t; +typedef short int int16_t; +typedef long int int32_t; + +/* Unsigned. */ +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned long int uint32_t; + + +/* Small types. */ + +/* Signed. */ +typedef signed char int_least8_t; +typedef short int int_least16_t; +typedef long int int_least32_t; + +/* Unsigned. */ +typedef unsigned char uint_least8_t; +typedef unsigned short int uint_least16_t; +typedef unsigned long int uint_least32_t; + + +/* Fast types. */ + +/* Signed. */ +typedef signed char int_fast8_t; +typedef int int_fast16_t; +typedef long int int_fast32_t; + +/* Unsigned. */ +typedef unsigned char uint_fast8_t; +typedef unsigned int uint_fast16_t; +typedef unsigned long int uint_fast32_t; + + +/* Types for `void *' pointers. */ +typedef long int intptr_t; +typedef unsigned long int uintptr_t; + + +/* Largest integral types. */ +typedef long int intmax_t; +typedef unsigned long int uintmax_t; + + +/* Limits of integral types. */ + +/* Minimum of signed integral types. */ +# define INT8_MIN (-128) +# define INT16_MIN (-32767-1) +# define INT32_MIN (-2147483647L-1) +/* Maximum of signed integral types. */ +# define INT8_MAX (127) +# define INT16_MAX (32767) +# define INT32_MAX (2147483647L) + +/* Maximum of unsigned integral types. */ +# define UINT8_MAX (255) +# define UINT16_MAX (65535) +# define UINT32_MAX (4294967295UL) + +/* Minimum of signed integral types having a minimum size. */ +# define INT_LEAST8_MIN (-128) +# define INT_LEAST16_MIN (-32767-1) +# define INT_LEAST32_MIN (-2147483647L-1) +/* Maximum of signed integral types having a minimum size. */ +# define INT_LEAST8_MAX (127) +# define INT_LEAST16_MAX (32767) +# define INT_LEAST32_MAX (2147483647L) + +/* Maximum of unsigned integral types having a minimum size. */ +# define UINT_LEAST8_MAX (255) +# define UINT_LEAST16_MAX (65535) +# define UINT_LEAST32_MAX (4294967295UL) + +/* Minimum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MIN (-128) +# define INT_FAST16_MIN (-32767-1) +# define INT_FAST32_MIN (-2147483647L-1) + +/* Maximum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MAX (127) +# define INT_FAST16_MAX (32767) +# define INT_FAST32_MAX (2147483647L) + +/* Maximum of fast unsigned integral types having a minimum size. */ +# define UINT_FAST8_MAX (255) +# define UINT_FAST16_MAX (65535) +# define UINT_FAST32_MAX (4294967295UL) + +/* Values to test for integral types holding `void *' pointer. */ +# define INTPTR_MIN (-2147483647L-1) +# define INTPTR_MAX (2147483647L) +# define UINTPTR_MAX (4294967295UL) + +/* Minimum for largest signed integral type. */ +# define INTMAX_MIN (-__INT32_C(-2147483647L)-1) +/* Maximum for largest signed integral type. */ +# define INTMAX_MAX (__INT32_C(2147483647L)) + +/* Maximum for largest unsigned integral type. */ +# define UINTMAX_MAX (__UINT32_C(4294967295UL)) + + +/* Limits of other integer types. */ + +/* Limits of `ptrdiff_t' type. */ +# define PTRDIFF_MIN (-2147483647L-1) +# define PTRDIFF_MAX (2147483647L) + +/* Limit of `size_t' type. */ +# define SIZE_MAX (65535) + +/* Signed. */ +# define INT8_C(c) c +# define INT16_C(c) c +# define INT32_C(c) c ## L + +/* Unsigned. */ +# define UINT8_C(c) c ## U +# define UINT16_C(c) c ## U +# define UINT32_C(c) c ## UL + +/* Maximal type. */ +# define INTMAX_C(c) c ## L +# define UINTMAX_C(c) c ## UL + + +#endif /* stdint.h */ diff --git a/device/include/pic16/stdio.h b/device/include/pic16/stdio.h index 22cecd56..35f0be68 100644 --- a/device/include/pic16/stdio.h +++ b/device/include/pic16/stdio.h @@ -47,28 +47,82 @@ typedef unsigned int size_t; #endif -//typedef void (*pfn_outputchar)(char c, void* p) _REENTRANT; -//extern int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list ap); +/* stream descriptor definition */ +typedef char *FILE; + + +/* USART and MSSP module stream descriptors */ + +/* since FILE is declared as a generic pointer, + * the upper byte is used to dereference the pointer + * information. For the stream descriptors we + * use the 5th bit and the lower nubble bits. + * Descriptors are denoted by an 1 in bit 5, + * further dereference is made for: + * <3:0> bits + * USART 0 (0x0) + * MSSP 1 (0x1) + * USER 15 (0xf) + * + * There is a special value for GPSIM specific (see below) + * which is: + * GPSIM 14 (0xe) + * + * + * if further stream descriptors need to be added then more + * bits of the upper byte can be used + */ + + +#define USART_DEREF 0x0 +#define MSSP_DEREF 0x1 +#define USER_DEREF 0xf + +#define STREAM_USART ((FILE *)(0x00200000UL)) +#define STREAM_MSSP ((FILE *)(0x00210000UL)) +#define STREAM_USER ((FILE *)(0x002f0000UL)) + + +/* this is a custom dereference which points to a custom + * port of GPSIM simulator. This port redirects characters + * to /tmp/gpsim.debug.1 file (used for debugging purposes) + * NOTICE: This feature is not part of the official gpsim + * distribution. Contact vrokas AT users.sourceforge.net + * for more info */ +#define GPSIM_DEREF 0xe +#define STREAM_GPSIM ((FILE *)(0x002e0000UL)) + +extern FILE * stdin; +extern FILE * stdout; -/*-----------------------------------------------------------------------*/ +//typedef void (*pfn_outputchar)(char c, void* p) _REENTRANT; +//extern int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list ap); /* printf_small() supports float print */ extern void printf_small(char *, ...); /* printf_tiny() does not support float print */ -extern void printf_tiny(char *, ...); +extern void printf_tiny(char *, ...) reentrant; -extern int printf (char *,...); -extern int vprintf (char *, va_list); +extern unsigned int printf (char *,...); +extern unsigned int sprintf (char *, char *, ...); +extern unsigned int fprintf(FILE *, char *, ...); -extern int sprintf (char *, const char *, ...); -extern int vsprintf (char *, const char *, va_list); +extern unsigned int vsprintf (char *, char *, va_list); +extern unsigned int vprintf (char *, va_list); +extern unsigned int vfprintf(FILE *, char *, va_list); extern int puts(char *); -#pragma wparam putchar -extern void putchar(char); +extern void __stream_putchar(FILE *, unsigned char); + +#define PUTCHAR(arg) void putchar(unsigned char arg) wparam +extern PUTCHAR(c); + +extern void __stream_usart_putchar(unsigned char c) _naked wparam; +extern void __stream_mssp_putchar(unsigned char c) _naked wparam; +extern void __stream_gpsim_putchar(unsigned char c) _naked wparam; extern char *gets(char *); extern char getchar(void); diff --git a/device/include/pic16/stdlib.h b/device/include/pic16/stdlib.h index 77ec060b..fa9d166e 100644 --- a/device/include/pic16/stdlib.h +++ b/device/include/pic16/stdlib.h @@ -44,11 +44,13 @@ extern int atoi (char *); extern long atol (char *); extern void uitoa(unsigned int, data char *, unsigned char); -extern void itoa(unsigned int, data char*, unsigned char); +extern void itoa(int, data char*, unsigned char); -extern void ultoa(unsigned long, data char *, unsigned char); -extern void ltoa(unsigned long, data char*, unsigned char); +extern void ultoa(unsigned long, data unsigned char *, unsigned char); +extern void ltoa(long, data unsigned char*, unsigned char); extern char x_ftoa(float, data char *, unsigned char, unsigned char); +extern void g_ftoa(data char *, float, char); + #endif /* __PIC16_STDLIB_H */ diff --git a/device/lib/pic16/libc/Makefile b/device/lib/pic16/libc/Makefile index 71b11918..4f12f23a 100644 --- a/device/lib/pic16/libc/Makefile +++ b/device/lib/pic16/libc/Makefile @@ -13,6 +13,7 @@ DIRS = ctype \ + delay \ stdlib \ stdio \ string \ diff --git a/device/lib/pic16/libc/Makefile.rules b/device/lib/pic16/libc/Makefile.rules index 83975781..fe84ec80 100644 --- a/device/lib/pic16/libc/Makefile.rules +++ b/device/lib/pic16/libc/Makefile.rules @@ -19,19 +19,28 @@ PRJDIR = ../../../../.. LIBC_INC_DIR = $(PRJDIR)/device/include/pic16 #OPT_FLAGS += --pstack-model=large +#OPT_FLAGS += --stack-auto -COMPILE_FLAGS += $(MODELFLAGS) -COMPILE_FLAGS += $(OPT_FLAGS) +COMPILE_FLAGS += $(MODELFLAGS) $(OPT_FLAGS) CFLAGS = -I$(LIBC_INC_DIR) CFILES = $(patsubst %,%.c,$(SRCS)) -OFILES = $(patsubst %.c,%.o,$(CFILES)) +COFILES = $(patsubst %.c,%.o,$(CFILES)) -%.o: %.c +ASFLAGS = -I$(LIBC_INC_DIR) -p18f452 -D__18F452 + +SFILES = $(patsubst %,%.S,$(S_SRCS)) +SOFILES = $(patsubst %.S,%.o,$(SFILES)) + +OFILES = $(COFILES) $(SOFILES) + +.c.o: $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $< +.S.o: + $(AS) $(ASFLAGS) -c $< all: build-library clean-intermediate-no-asm diff --git a/device/lib/pic16/libc/delay/Makefile b/device/lib/pic16/libc/delay/Makefile new file mode 100644 index 00000000..a8ac5e5e --- /dev/null +++ b/device/lib/pic16/libc/delay/Makefile @@ -0,0 +1,52 @@ +# +# Makefile - Makefile to build pic16 C Library +# +# This file is part of the GNU PIC Library. +# +# January, 2004 +# The GNU PIC Library is maintained by, +# Vangelis Rokas +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# $Id$ +# +# + +include ../Makefile.rules + +CSRCS = + +S_SRCS = delay10tcy \ + delay100tcy \ + delay1ktcy \ + delay10ktcy \ + delay100ktcy \ + delay1mtcy + + +SRCS = $(CSRCS) + + +DEBUG= +#COMPILE_FLAGS += --pomit-config-words --pomit-ivt --denable-peeps --optimize-goto --obanksel=2 +COMPILE_FLAGS += $(DEBUG) + + +#all: build-library + +build-library: $(OFILES) + diff --git a/device/lib/pic16/libc/delay/delay100ktcy.S b/device/lib/pic16/libc/delay/delay100ktcy.S new file mode 100644 index 00000000..9ea41237 --- /dev/null +++ b/device/lib/pic16/libc/delay/delay100ktcy.S @@ -0,0 +1,46 @@ + + include + + extern _delay10tcy + extern _delay1ktcy + + global _delay100ktcy + + code + +_delay100ktcy: + ; polynomial for 100ktcy delay is f(x) = 100000 * (x-1) + 100000 + decf WREG, f + + movwf POSTDEC1 + movlw 99 + call _delay1ktcy + + movlw 99 + call _delay10tcy + + movf PREINC1, w + + bz @delay100k_end + bra $+2 + +@delay100k_loop: + movwf POSTDEC1 + + movlw 99 + call _delay1ktcy + + movlw 99 + call _delay10tcy + + bra $+2 + bra $+2 + nop + movf PREINC1, w + decfsz WREG, f + bra @delay100k_loop + +@delay100k_end: + return + + end diff --git a/device/lib/pic16/libc/delay/delay100tcy.S b/device/lib/pic16/libc/delay/delay100tcy.S new file mode 100644 index 00000000..1783b932 --- /dev/null +++ b/device/lib/pic16/libc/delay/delay100tcy.S @@ -0,0 +1,39 @@ + + include + + extern _delay10tcy + + global _delay100tcy + + code + +_delay100tcy: + ; polynomial for 100tcy delay is f(x) = 100 * (x-1) + 100 + decf WREG, f + movwf POSTDEC1 + movlw 9 + call _delay10tcy + + movf PREINC1, w + + bz @delay100_end + bra $+2 + +@delay100_loop: + movwf POSTDEC1 + + movlw 9 + call _delay10tcy + + bra $+2 + + movf PREINC1, w + nop + bra $+2 + decfsz WREG, f + bra @delay100_loop + +@delay100_end: + return + + end diff --git a/device/lib/pic16/libc/delay/delay10ktcy.S b/device/lib/pic16/libc/delay/delay10ktcy.S new file mode 100644 index 00000000..a5a68cbc --- /dev/null +++ b/device/lib/pic16/libc/delay/delay10ktcy.S @@ -0,0 +1,46 @@ + + include + + extern _delay10tcy + extern _delay1ktcy + + global _delay10ktcy + + code + +_delay10ktcy: + ; polynomial for 10ktcy delay is f(x) = 10000 * (x-1) + 10000 + decf WREG, f + + movwf POSTDEC1 + movlw 9 + call _delay1ktcy + + movlw 99 + call _delay10tcy + + movf PREINC1, w + + bz @delay10k_end + bra $+2 + +@delay10k_loop: + movwf POSTDEC1 + + movlw 9 + call _delay1ktcy + + movlw 99 + call _delay10tcy + + bra $+2 + bra $+2 + nop + movf PREINC1, w + decfsz WREG, f + bra @delay10k_loop + +@delay10k_end: + return + + end diff --git a/device/lib/pic16/libc/delay/delay10tcy.S b/device/lib/pic16/libc/delay/delay10tcy.S new file mode 100644 index 00000000..8d292f00 --- /dev/null +++ b/device/lib/pic16/libc/delay/delay10tcy.S @@ -0,0 +1,31 @@ + + include + + global _delay10tcy + + code + +_delay10tcy: + ; polynomial for 10tcy delay is f(x) = 10 * (x-1) + 10 + decf WREG, f + nop + + movf WREG, w + bz @delay10_end + + bra $+2 + +@delay10_loop: + bra $+2 + bra $+2 + bra $+2 + + nop + decfsz WREG, f + bra @delay10_loop + +@delay10_end: + + return + + end diff --git a/device/lib/pic16/libc/delay/delay1ktcy.S b/device/lib/pic16/libc/delay/delay1ktcy.S new file mode 100644 index 00000000..cd0fb054 --- /dev/null +++ b/device/lib/pic16/libc/delay/delay1ktcy.S @@ -0,0 +1,39 @@ + + include + + extern _delay10tcy + + global _delay1ktcy + + code + +_delay1ktcy: + ; polynomial for 1ktcy delay is f(x) = 1000 * (x-1) + 1000 + decf WREG, f + + movwf POSTDEC1 + movlw 99 + call _delay10tcy + + movf PREINC1, w + + bz @delay1k_end + bra $+2 + +@delay1k_loop: + movwf POSTDEC1 + movlw 99 + call _delay10tcy + + bra $+2 + bra $+2 + nop + + movf PREINC1, w + decfsz WREG, f + bra @delay1k_loop + +@delay1k_end: + return + + end diff --git a/device/lib/pic16/libc/delay/delay1mtcy.S b/device/lib/pic16/libc/delay/delay1mtcy.S new file mode 100644 index 00000000..b112e54c --- /dev/null +++ b/device/lib/pic16/libc/delay/delay1mtcy.S @@ -0,0 +1,53 @@ + + include + + extern _delay10tcy + extern _delay100tcy + extern _delay10ktcy + + global _delay1mtcy + + code + +_delay1mtcy: + ; polynomial for 1mtcy delay is f(x) = 100000 * (x-1) + 100000 + decf WREG, f + + movwf POSTDEC1 + movlw 99 + call _delay10ktcy + + movlw 99 + call _delay100tcy + + movlw 9 + call _delay10tcy + + movf PREINC1, w + + bz @delay1m_end + bra $+2 + +@delay1m_loop: + movwf POSTDEC1 + + movlw 99 + call _delay10ktcy + + movlw 99 + call _delay100tcy + + movlw 9 + call _delay10tcy + + bra $+2 + bra $+2 + nop + movf PREINC1, w + decfsz WREG, f + bra @delay1m_loop + +@delay1m_end: + return + + end diff --git a/device/lib/pic16/libc/stdio/Makefile b/device/lib/pic16/libc/stdio/Makefile index 40080668..6f96ab72 100644 --- a/device/lib/pic16/libc/stdio/Makefile +++ b/device/lib/pic16/libc/stdio/Makefile @@ -14,14 +14,25 @@ include ../Makefile.rules SRCS = printf_tiny \ - printf_small + printf_small \ + printf \ + sprintf \ + fprintf \ + vprintf \ + vsprintf \ + vfprintf \ + strmusart \ + strmmssp \ + strmgpsim \ + strmputchar \ + streams CFILES = $(patsubst %,%.c,$(SRCS)) OFILES = $(patsubst %.c,%.o,$(CFILES)) -DEBUG= --stack-auto +DEBUG= #COMPILE_FLAGS += --pomit-config-words --pomit-ivt --no-peep COMPILE_FLAGS += $(DEBUG) diff --git a/device/lib/pic16/libc/stdio/fprintf.c b/device/lib/pic16/libc/stdio/fprintf.c new file mode 100644 index 00000000..df2bc8e9 --- /dev/null +++ b/device/lib/pic16/libc/stdio/fprintf.c @@ -0,0 +1,53 @@ +/*----------------------------------------------------------------- + fprintf.c - + + Written for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +#include +#include + + +#if _DEBUG +extern void io_long(unsigned long); +extern void io_str(char *); +#endif + +unsigned int fprintf(FILE *stream, char *fmt, ...) +{ + unsigned int i; + va_list ap; + +#if _DEBUG + io_str( "fprintf: " ); + io_long((unsigned long)stream); + io_long((unsigned long)fmt); +#endif + + va_start(ap, fmt); + i = vfprintf(stream, fmt, ap); + + return (i); +} diff --git a/device/lib/pic16/libc/stdio/printf.c b/device/lib/pic16/libc/stdio/printf.c new file mode 100644 index 00000000..6bbf2e1d --- /dev/null +++ b/device/lib/pic16/libc/stdio/printf.c @@ -0,0 +1,54 @@ +/*----------------------------------------------------------------- + printf.c - + + Written for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +#include +#include + +#if _DEBUG +extern void io_long(unsigned long); +extern void io_str(char *); +#endif + + +unsigned int printf(char *fmt, ...) +{ + unsigned int i; + va_list ap; +// char *cfmt; + +#if _DEBUG + io_str( "printf: " ); + io_long( (unsigned long)stdout ); +#endif +// cfmt = fmt; + + va_start(ap, fmt); + i = vfprintf(stdout, fmt, ap); + + return (i); +} diff --git a/device/lib/pic16/libc/stdio/printf_small.c b/device/lib/pic16/libc/stdio/printf_small.c index 2fc589af..e478dd50 100644 --- a/device/lib/pic16/libc/stdio/printf_small.c +++ b/device/lib/pic16/libc/stdio/printf_small.c @@ -56,7 +56,7 @@ #include #include -void printf_small(char *fmt, ...) +void printf_small(char *fmt, ...) reentrant { char *ch; char radix; @@ -67,10 +67,8 @@ void printf_small(char *fmt, ...) float flt; char *str; data char *str1; -//#define str1 str long val; -// static - char buffer[35]; + static char buffer[16]; va_list ap ; ch = fmt; @@ -78,8 +76,7 @@ void printf_small(char *fmt, ...) while( *ch ) { //for (; *fmt ; fmt++ ) if (*ch == '%') { - flong = 0; fstr = 0; fchar = 0; - ffloat = 0; + flong = fstr = fchar = ffloat = 0; radix = 0; ch++; diff --git a/device/lib/pic16/libc/stdio/printf_tiny.c b/device/lib/pic16/libc/stdio/printf_tiny.c index d700b3f0..2107a593 100644 --- a/device/lib/pic16/libc/stdio/printf_tiny.c +++ b/device/lib/pic16/libc/stdio/printf_tiny.c @@ -38,12 +38,15 @@ /* following formats are supported :- format output type argument-type + %u* unsigned * + + %b binary %d decimal int %ld decimal long %hd decimal char %x hexadecimal int - %lx hexadecimal long - %hx hexadecimal char + %lxX hexadecimal long + %hxX hexadecimal char %o octal int %lo octal long %ho octal char @@ -51,65 +54,102 @@ %s character generic pointer */ +#include #include #include #include +#if 0 +#define DPUT(c) putchar( c ) +#else +#define DPUT(c) +#endif + +#define ISLONG (flong) +#define ISSTR (fstr) +#define ISCHAR (fchar) +#define HAVESIGN (nosign) + + +#if 1 +extern void io_long(long); +extern void io_int(long); +extern void io_char(char); +#endif + void printf_tiny(char *fmt, ...) { - char *ch; char radix; - char flong; - char fstr; - char fchar; - char *str; + char flong, fstr; + char fchar, nosign; + char upcase; + + char *str, *ch; data char *str1; long val; -// static - char buffer[35]; +// static char buffer[16]; + char buffer[16]; va_list ap ; - ch = fmt; va_start(ap,fmt); - + ch = fmt; + while( *ch ) { //for (; *fmt ; fmt++ ) if (*ch == '%') { - flong = fstr = fchar = 0; + ISLONG = 0; + ISSTR = 0; + ISCHAR = 0; + HAVESIGN = 0; radix = 0; + upcase = 0; ch++; + if(*ch == 'u') { + HAVESIGN = 1; + ch++; + } + if(*ch == 'l') { - flong = 1; + ISLONG = 1; ch++; } else if(*ch == 'h') { - fchar = 1; + ISCHAR = 1; ch++; } - if(*ch == 's')fstr = 1; + if(*ch == 's')ISSTR = 1; else if(*ch == 'd')radix = 10; - else if(*ch == 'x')radix = 16; + else if(*ch == 'x'){ radix = 16; upcase = 0; } + else if(*ch == 'X'){ radix = 16; upcase = 1; } else if(*ch == 'c')radix = 0; else if(*ch == 'o')radix = 8; + else if(*ch == 'b')radix = 2; - if(fstr) { + if(ISSTR) { str = va_arg(ap, char *); - while (*str) putchar(*str++); + while(*str) { putchar(*str);str++;} } else { - if(flong)val = va_arg(ap, long); + if(ISLONG)val = va_arg(ap, long); else - if(fchar)val = va_arg(ap, char); + if(ISCHAR)val = va_arg(ap, char); else { val = va_arg(ap, int); } - + if(radix) { - ltoa (val, buffer, radix); + if(HAVESIGN) + ultoa(val, buffer, radix); + else + ltoa (val, buffer, radix); str1 = buffer; - while ( *str1 ) { - putchar ( *str1++ ); + while( (*str1) ) { + radix = *str1; + if(upcase) + radix = toupper( radix ); + putchar ( radix ); + str1++; } } else putchar((char)val); diff --git a/device/lib/pic16/libc/stdio/sprintf.c b/device/lib/pic16/libc/stdio/sprintf.c new file mode 100644 index 00000000..548c531a --- /dev/null +++ b/device/lib/pic16/libc/stdio/sprintf.c @@ -0,0 +1,46 @@ +/*----------------------------------------------------------------- + sprintf.c - + + Written for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +#include +#include + +unsigned int sprintf(char *ebuf, char *fmt, ...) +{ + unsigned int i; + va_list ap; + char *cfmt; + + + cfmt = fmt; + + ap = va_start(ap, fmt); + i = vfprintf((FILE *) &ebuf, cfmt, ap); + *ebuf='\0'; + + return (i+1); +} diff --git a/device/lib/pic16/libc/stdio/streams.c b/device/lib/pic16/libc/stdio/streams.c new file mode 100644 index 00000000..65fa6c04 --- /dev/null +++ b/device/lib/pic16/libc/stdio/streams.c @@ -0,0 +1,33 @@ +/*----------------------------------------------------------------- + streams.c - source file for stream declarations + + Written by Vangelis Rokas, 2004 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + + +#include + +FILE *stdout = STREAM_USER; +FILE *stdin = STREAM_USER; diff --git a/device/lib/pic16/libc/stdio/strmgpsim.c b/device/lib/pic16/libc/stdio/strmgpsim.c new file mode 100644 index 00000000..45190e92 --- /dev/null +++ b/device/lib/pic16/libc/stdio/strmgpsim.c @@ -0,0 +1,41 @@ +/*----------------------------------------------------------------- + strmusart.c - usart stream putchar + + Modified for pic16 port, by Vangelis Rokas, 2004 (vrokas@otenet.gr) + + Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +extern WREG; + +/* note that USART should already been initialized */ +void __stream_gpsim_putchar(unsigned char c) _naked wparam +{ + c; + _asm + MOVFF _WREG, 0xf7f + RETURN + _endasm; +} diff --git a/device/lib/pic16/libc/stdio/strmmssp.c b/device/lib/pic16/libc/stdio/strmmssp.c new file mode 100644 index 00000000..2846057f --- /dev/null +++ b/device/lib/pic16/libc/stdio/strmmssp.c @@ -0,0 +1,40 @@ +/*----------------------------------------------------------------- + strmmssp.c - MSSP stream putchar + + Written for pic16 port, by Vangelis Rokas, 2004 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +extern WREG; +extern SSPBUF; + +/* note that USART should already been initialized */ +void __stream_mssp_putchar(unsigned char c) _naked wparam +{ + c; + _asm + MOVWF _SSPBUF + RETURN + _endasm; +} diff --git a/device/lib/pic16/libc/stdio/strmputchar.c b/device/lib/pic16/libc/stdio/strmputchar.c new file mode 100644 index 00000000..339fa33a --- /dev/null +++ b/device/lib/pic16/libc/stdio/strmputchar.c @@ -0,0 +1,61 @@ +/*----------------------------------------------------------------- + strmputchar.c - stream putchar dispatch function + + Written for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +#include + +void __stream_putchar(FILE *stream, unsigned char c) +{ + unsigned char deref; + + deref = (unsigned char)(((unsigned long)stream) >> 16); + +#if _DEBUG + io_str( "__stream_putchar: " ); + io_long((unsigned long)stream); +#endif + + if(deref == 0x80) { + /* this is a data/near memory pointer */ + *(*(char **)stream) = c; + *(char **)stream+=1; + } else + if(deref & 0x20) { + deref ^= 0x20; + if(deref == USART_DEREF) + __stream_usart_putchar(c); + else + if(deref == MSSP_DEREF) + __stream_mssp_putchar(c); + else + if(deref == USER_DEREF) + putchar(c); + else + if(deref == GPSIM_DEREF) /* see stdio.h for info on this */ + __stream_gpsim_putchar(c); /* feature */ + } +} diff --git a/device/lib/pic16/libc/stdio/strmusart.c b/device/lib/pic16/libc/stdio/strmusart.c new file mode 100644 index 00000000..634774fc --- /dev/null +++ b/device/lib/pic16/libc/stdio/strmusart.c @@ -0,0 +1,46 @@ +/*----------------------------------------------------------------- + strmusart.c - usart stream putchar + + Written for pic16 port, by Vangelis Rokas, 2004 (vrokas@otenet.gr) + + Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +extern WREG; +extern TXREG; +extern TXSTA; + +/* note that USART should already been initialized */ +void __stream_usart_putchar(unsigned char c) _naked wparam +{ + c; + _asm +@1: + BTFSS _TXSTA, 1 + BRA @1 + MOVWF _TXREG + RETURN + _endasm; +} diff --git a/device/lib/pic16/libc/stdio/vfprintf.c b/device/lib/pic16/libc/stdio/vfprintf.c new file mode 100644 index 00000000..6e7bc625 --- /dev/null +++ b/device/lib/pic16/libc/stdio/vfprintf.c @@ -0,0 +1,168 @@ +/*----------------------------------------------------------------- + vfprintf.c - source file for reduced version of printf + + Modified for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr) + + Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +/* following formats are supported :- + format output type argument-type + %u* unsigned * + %b binary + %d decimal int + %ld decimal long + %hd decimal char + %x hexadecimal int + %lxX hexadecimal long + %hxX hexadecimal char + %o octal int + %lo octal long + %ho octal char + %c character char + %s character generic pointer +*/ + +#include +#include +#include +#include + +#if _DEBUG +extern void io_long(unsigned long); +extern void io_str(char *); +extern void io_int(unsigned int); +#endif + +unsigned int vfprintf(FILE *stream, char *fmt, va_list ap) +{ + unsigned char radix; + unsigned char flong, fstr; + unsigned char fchar, nosign; + unsigned char upcase; + unsigned int count=0; + unsigned char *str, *ch; + data char *str1; + long val; +// static char buffer[16]; + char buffer[16]; + + +#if _DEBUG + io_str( "vfprintf: " ); + io_long( (unsigned long)stream ); + io_long( (unsigned long)fmt ); +#endif + +// va_start(ap,fmt); + ch = fmt; + + while( *ch ) { //for (; *fmt ; fmt++ ) + if (*ch == '%') { + flong = 0; + fstr = 0; + fchar = 0; + nosign = 0; + radix = 0; + upcase = 0; + ch++; + + if(*ch == 'u') { + nosign = 1; + ch++; + } + + if(*ch == 'l') { + flong = 1; + ch++; + } else + if(*ch == 'h') { + fchar = 1; + ch++; + } + + if(*ch == 's')fstr = 1; + else if(*ch == 'd')radix = 10; + else if(*ch == 'x'){ radix = 16; upcase = 0; } + else if(*ch == 'X'){ radix = 16; upcase = 1; } + else if(*ch == 'c')radix = 0; + else if(*ch == 'o')radix = 8; + else if(*ch == 'b')radix = 2; + + if(fstr) { + str = va_arg(ap, char *); + while(*str) { __stream_putchar(stream, *str); str++; count++; } + } else { + val = 0; + if(flong) { + val = va_arg(ap, long); +#if _DEBUG + io_long(val); +#endif + } + else + if(fchar) { + val = va_arg(ap, char); +#if _DEBUG + io_long(val); +#endif + } + else { + val = va_arg(ap, int); +#if _DEBUG + io_long(val); +#endif + } + + if(radix) { + if(nosign) + ultoa(val, buffer, radix); + else + ltoa (val, buffer, radix); + + str1 = buffer; + while( (*str1) ) { + radix = *str1; + if(upcase) + radix = toupper( radix ); + __stream_putchar(stream, (unsigned char)radix); + count++; + str1++; + } + } else { + __stream_putchar(stream, (unsigned char)val); + count++; + } + } + } else { + __stream_putchar(stream, *ch); + count++; + } + + ch++; + } + + return (count); +} diff --git a/device/lib/pic16/libc/stdio/vprintf.c b/device/lib/pic16/libc/stdio/vprintf.c new file mode 100644 index 00000000..992132df --- /dev/null +++ b/device/lib/pic16/libc/stdio/vprintf.c @@ -0,0 +1,39 @@ +/*----------------------------------------------------------------- + vprintf.c - + + Written for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +#include +#include + +unsigned vprintf(char *fmt, va_list ap) +{ + unsigned int i; + + i = vfprintf(stdout, fmt, ap); + + return (i); +} diff --git a/device/lib/pic16/libc/stdio/vsprintf.c b/device/lib/pic16/libc/stdio/vsprintf.c new file mode 100644 index 00000000..3dbdc9be --- /dev/null +++ b/device/lib/pic16/libc/stdio/vsprintf.c @@ -0,0 +1,43 @@ +/*----------------------------------------------------------------- + vsprintf.c - + + Written for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by the + Free Software Foundation; either version 2, 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 Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +/* +** $Id$ +*/ + +#include +#include + + +unsigned int vsprintf(char *ebuf, char *fmt, va_list ap) +{ + unsigned int i; + char *cfmt; + + cfmt = fmt; + i = vfprintf((FILE *) &ebuf, cfmt, ap); + *ebuf = '\0'; + + return (i+1); +} diff --git a/device/lib/pic16/libc/stdlib/Makefile b/device/lib/pic16/libc/stdlib/Makefile index 00cf59f4..aa201bb2 100644 --- a/device/lib/pic16/libc/stdlib/Makefile +++ b/device/lib/pic16/libc/stdlib/Makefile @@ -20,24 +20,29 @@ SRCS = atof \ free \ ltoa \ malloc \ + memfree \ + memfreemax \ + memmisc \ realloc \ x_ftoa \ putchar +S_SRCS = g_ftoa -CFILES = $(patsubst %,%.c,$(SRCS)) -OFILES = $(patsubst %.c,%.o,$(CFILES)) +#CFILES = $(patsubst %,%.c,$(SRCS)) +#OFILES = $(patsubst %.c,%.o,$(CFILES)) +#OPT_FLAGS += --stack-auto -DEBUG= --stack-auto +DEBUG= #COMPILE_FLAGS += --pomit-config-words --pomit-ivt --denable-peeps --optimize-goto --obanksel=2 COMPILE_FLAGS += $(DEBUG) -CFILES = $(patsubst %,%.c,$(SRCS)) -OFILES = $(patsubst %.c,%.o,$(CFILES)) +#CFILES = $(patsubst %,%.c,$(SRCS)) +#OFILES = $(patsubst %.c,%.o,$(CFILES)) -%.o: %.c - $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $< +#.c.o +# $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $< build-library: $(OFILES) diff --git a/device/lib/pic16/libc/stdlib/atoi.c b/device/lib/pic16/libc/stdlib/atoi.c index 334cf11f..4167cda1 100644 --- a/device/lib/pic16/libc/stdlib/atoi.c +++ b/device/lib/pic16/libc/stdlib/atoi.c @@ -24,8 +24,8 @@ int atoi(char * s) { - register int rv=0; - register char sign = 0; + int rv=0; + char sign = 0; /* skip till we find either a digit or '+' or '-' */ while (*s) { @@ -36,7 +36,9 @@ int atoi(char * s) s++; } - sign = (*s == '-'); + if(*s == '-')sign=1; + +// sign = (*s == '-'); if (*s == '-' || *s == '+') s++; while (*s && *s >= '0' && *s <= '9') { @@ -44,6 +46,9 @@ int atoi(char * s) s++; } - return (sign ? -rv : rv); + if(sign)return (-rv); + else return (rv); + +// return (sign ? -rv : rv); } diff --git a/device/lib/pic16/libc/stdlib/calloc.c b/device/lib/pic16/libc/stdlib/calloc.c index dae2e2d3..d3be5799 100644 --- a/device/lib/pic16/libc/stdlib/calloc.c +++ b/device/lib/pic16/libc/stdlib/calloc.c @@ -1,31 +1,51 @@ /* - * malloc.c - dynamic memory allocation + * calloc.c - dynamic memory allocation * * written by Vangelis Rokas, 2004 (vrokas@otenet.gr) * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ */ #include -extern unsigned char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ +extern unsigned char _MALLOC_SPEC *heap; -unsigned char _MALLOC_SPEC *calloc(unsigned char num) //, unsigned char len) +unsigned char _MALLOC_SPEC *calloc(unsigned char len) { - unsigned char len=num; - unsigned char total; unsigned char _MALLOC_SPEC *result, *ch; - total = num * len; - if(total > MAX_BLOCK_SIZE)return ((unsigned char _MALLOC_SPEC *)0); - result = ch = malloc( (char)(total) ); - - if(result != 0) { - while(total) { - total--; - *ch = 0; - 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 = 1; + ch++; + *ch = 0; + ch++; + } + } return (result); } diff --git a/device/lib/pic16/libc/stdlib/free.c b/device/lib/pic16/libc/stdlib/free.c index 7f6c7f14..a11c9ecb 100644 --- a/device/lib/pic16/libc/stdlib/free.c +++ b/device/lib/pic16/libc/stdlib/free.c @@ -1,17 +1,36 @@ /* - * malloc.c - dynamic memory allocation + * free.c - dynamic memory allocation * * written by Vangelis Rokas, 2004 (vrokas@otenet.gr) * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ */ -#include "malloc.h" +#include -extern char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ +extern char _MALLOC_SPEC *heap; void free(unsigned char _MALLOC_SPEC *buf) { - /* mark block as deallocated */ - ((_malloc_rec *)(buf - 1))->bits.alloc = 0; + /* mark block as deallocated */ + ((_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 00000000..fd7b0154 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/g_ftoa.S @@ -0,0 +1,208 @@ +;-- +; +; 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 "/usr/local/share/gputils/header/p18f452.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/ltoa.c b/device/lib/pic16/libc/stdlib/ltoa.c index 875972bf..ca0ffdac 100644 --- a/device/lib/pic16/libc/stdlib/ltoa.c +++ b/device/lib/pic16/libc/stdlib/ltoa.c @@ -15,33 +15,54 @@ #define NUMBER_OF_DIGITS 32 -void ultoa(unsigned long value, data char *string, unsigned char radix) +#if _DEBUG +extern void io_long(unsigned long); +extern void io_str(char *); +#endif + + +void ultoa(unsigned long value, data unsigned char* str, unsigned char radix) { -unsigned char index; -char buffer[NUMBER_OF_DIGITS]; /* space for NUMBER_OF_DIGITS + '\0' */ + unsigned int index; + unsigned char ch; + unsigned char buffer[NUMBER_OF_DIGITS]; /* space for NUMBER_OF_DIGITS + '\0' */ - index = NUMBER_OF_DIGITS; + index = NUMBER_OF_DIGITS; + + do { + ch = '0' + (value % radix); + if ( ch > '9') ch += 'a' - '9' - 1; - do { - buffer[--index] = '0' + (value % radix); - if ( buffer[index] > '9') buffer[index] += 'A' - '9' - 1; - value /= radix; - } while (value != 0); +#if _DEBUG + io_str( "ultoa: " ); + io_long( value ); + io_long( (unsigned long) ch ); +#endif - do { - *string++ = buffer[index++]; - } while ( index < NUMBER_OF_DIGITS ); + buffer[ --index ] = ch; + value /= radix; + } while (value != 0); - *string = 0; /* string terminator */ + do { + *str++ = buffer[index++]; + } while ( index < NUMBER_OF_DIGITS ); + + *str = 0; /* string terminator */ } -void ltoa(long value, data char *string, unsigned char radix) +void ltoa(long value, data unsigned char* str, unsigned char radix) { +#if _DEBUG + io_str( "ltoa: " ); + io_long( (unsigned long)value ); +#endif + if (value < 0 && radix == 10) { - *string++ = '-'; + *str++ = '-'; value = -value; } - ultoa(value, string, radix); -} + + ultoa((unsigned long)value, str, radix); +} diff --git a/device/lib/pic16/libc/stdlib/malloc.c b/device/lib/pic16/libc/stdlib/malloc.c index 8a984762..cd355ced 100644 --- a/device/lib/pic16/libc/stdlib/malloc.c +++ b/device/lib/pic16/libc/stdlib/malloc.c @@ -3,92 +3,116 @@ * * written by Vangelis Rokas, 2004 (vrokas@otenet.gr) * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ */ -#include "malloc.h" +#include -extern unsigned char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ +/* 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; /* size of block */ - unsigned char eLen; + 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; - if(len > _MAX_HEAP_SIZE) - return ((unsigned char _MALLOC_SPEC *)0); + + /* current block is not allocated, try to allocate */ + + /* if current block is not enough for allocation, then proceed to next */ + if(bLen <= len) { - pHeap = (_malloc_rec _MALLOC_SPEC *)&_dynamicHeap; +#if MALLOC_MAX_FIRST + /* if we are in the first pass, check next block */ + if(pass) + goto do_continue; + /* otherwise try merge */ +#endif - while(1) { - bLen = pHeap->bits.count; - - /* if datum is zero, then last block, return NULL */ - if(pHeap->datum == 0) - return ((unsigned char _MALLOC_SPEC *)0); + temp = _mergeHeapBlock(pHeap, len); + + if(!temp) + /* otherwise proceed with next block */ + goto do_continue; - /* if current block is allocated then proceed to next */ - if(pHeap->bits.alloc) { - pHeap += pHeap->bits.count; - continue; - } + pHeap = temp; + 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); + //pHeap->bits.count); + } + +do_end: + return ((unsigned char _MALLOC_SPEC *)0); - - /* current block is not allocated, try to allocate */ - - /* if current block is not enough for allocation, then proceed to next */ - if(bLen <= len) { - - /* current block is not enough see if we can merge some adjacent - * memory blocks to make it fit */ - temp = pHeap + pHeap->bits.count; - eLen = bLen; - while((temp->datum) && (!temp->bits.alloc) && (eLen < len)) { - eLen += temp->bits.count; - temp += temp->bits.count; - } - - if(eLen >= len) { - int i; - /* yes, there are some free blocks that can be merged, merge them... */ - - temp = pHeap; - while(eLen > 0) { - if(eLen > MAX_BLOCK_SIZE)i = MAX_BLOCK_SIZE; - else i = eLen; - - temp->bits.count = i; - temp->bits.alloc = 0; - - temp += i; - eLen -= i; - } - - bLen = pHeap->bits.count; - } else { - /* otherwise proceed with next block */ - pHeap += pHeap->bits.count; - continue; - } - } - - - /* current block is enough to hold the new block */ - - /* allocate by filling the fields */ - pHeap->bits.count = len+1; - pHeap->bits.alloc = 1; - - if(bLen > len+1) { - /* if current block size is greater than the requested one, - * create a new empty block at the end of the newly allocated */ - temp = pHeap + len+1; - temp->bits.count = bLen - len - 1; - temp->bits.alloc = 0; - } - - return ((unsigned char _MALLOC_SPEC *)pHeap + 1); - } } diff --git a/device/lib/pic16/libc/stdlib/memfree.c b/device/lib/pic16/libc/stdlib/memfree.c new file mode 100644 index 00000000..fe710705 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/memfree.c @@ -0,0 +1,46 @@ +/* + * memfree.c - return size of all unallocated heap + * + * written by Vangelis Rokas 2005 + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ + */ + +#include + +extern unsigned char _MALLOC_SPEC *heap; + +unsigned int memfree(void) +{ + _malloc_rec _MALLOC_SPEC *pHeap; + unsigned int hsize=0; + + pHeap = (_malloc_rec _MALLOC_SPEC *)&heap; + + while(pHeap->datum) { + if(!pHeap->bits.alloc) + hsize += pHeap->bits.count; + + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + pHeap->bits.count); + } + + 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 00000000..bd25918b --- /dev/null +++ b/device/lib/pic16/libc/stdlib/memfreemax.c @@ -0,0 +1,47 @@ +/* + * memfreemax.c - return size of maximum unallocated heap block + * + * written by Vangelis Rokas 2005 + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ + */ + +#include + +extern unsigned char _MALLOC_SPEC *heap; + +unsigned int memfreemax(void) +{ + _malloc_rec _MALLOC_SPEC *pHeap; + unsigned int maxSize=0; + + pHeap = (_malloc_rec _MALLOC_SPEC *)&heap; + + while(pHeap->datum) { + if(!pHeap->bits.alloc + && pHeap->bits.count > maxSize) + maxSize = pHeap->bits.count; + + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + pHeap->bits.count); + } + + 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 00000000..fe341ad1 --- /dev/null +++ b/device/lib/pic16/libc/stdlib/memmisc.c @@ -0,0 +1,95 @@ +/* + * memmisc.c - heap handling functions + * + * written by Vangelis Rokas, 2005 + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ + */ + +#include + +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; + + while(hsize < heapsize-1) { + + /* a guess of the next block size */ + bsize = (heapsize - hsize); + if(bsize > MAX_BLOCK_SIZE)bsize = MAX_BLOCK_SIZE; + else bsize--; + + if(bsize < 0)return; + + /* now we can create the block */ + pHeap->datum = bsize; + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)pHeap + bsize); + + hsize += bsize; + if(!bsize)break; + } +} + +/* search heap starting from sBlock for a block of size bSize, merging + * adjacent blocks if ne 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/putchar.c b/device/lib/pic16/libc/stdlib/putchar.c index f526c289..a932b341 100644 --- a/device/lib/pic16/libc/stdlib/putchar.c +++ b/device/lib/pic16/libc/stdlib/putchar.c @@ -3,7 +3,6 @@ * * written by Vangelis Rokas, 2005 (vrokas@otenet.gr) * - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 @@ -30,7 +29,7 @@ * NOTE that putchar() is declared in stdio.h to * have the argument in WCHAR (via the wparam pragma) */ -void putchar(char c) +PUTCHAR(c) { c; _asm diff --git a/device/lib/pic16/libc/stdlib/realloc.c b/device/lib/pic16/libc/stdlib/realloc.c index fb0ae4b1..be3b3ebb 100644 --- a/device/lib/pic16/libc/stdlib/realloc.c +++ b/device/lib/pic16/libc/stdlib/realloc.c @@ -1,79 +1,95 @@ /* - * malloc.c - dynamic memory allocation + * realloc.c - dynamic memory allocation * * written by Vangelis Rokas, 2004 (vrokas@otenet.gr) * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * $Id$ */ -#include "malloc.h" +#include -extern unsigned char _MALLOC_SPEC *_dynamicHeap; /* pointer to heap */ +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 */ - unsigned char eLen; - - if(len > MAX_BLOCK_SIZE) - return ((unsigned char _MALLOC_SPEC *)0); - - len++; /* increase to count header too */ - - pHeap = (_malloc_rec _MALLOC_SPEC *)(mblock-1); - bLen = pHeap->bits.count; - - /* new size is same as old, return pointer */ - if(bLen == len)return (mblock); - - if(bLen > len) { - /* new segment is smaller than the old one, that's easy! */ - pHeap->bits.count = len; - temp = pHeap + len; - temp->bits.alloc = 0; - temp->bits.count = bLen - len; - - return (((unsigned char _MALLOC_SPEC *)pHeap) + 1); - } - - /* so, new segment has size bigger than the old one - * we can only 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 = pHeap + pHeap->bits.count; - eLen = bLen; - while((temp->datum) && (!temp->bits.alloc) && (eLen < len)) { - eLen += temp->bits.count; - temp += temp->bits.count; - } - - if(eLen >= len) { - int i; - /* so we found one, adjust memory blocks */ - temp = pHeap; - - temp->bits.count = len; - eLen -= len; - temp += len; - - while(eLen>0) { - if(eLen > MAX_BLOCK_SIZE)i = MAX_BLOCK_SIZE; - else i = eLen; - - temp->bits.count = i; - temp->bits.alloc = 0; - temp += i; - eLen -= i; - } - - return (((unsigned char _MALLOC_SPEC *)pHeap) + 1); - } - - - /* no could not find a valid block, return NULL */ - return ((unsigned char _MALLOC_SPEC *)0); + 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 (malloc(0)); + } + + len++; /* increase to count header too */ + + pHeap = (_malloc_rec _MALLOC_SPEC *)((unsigned int)mblock - 1); + bLen = pHeap->bits.count; + + /* new size is same as old, return pointer */ + if(bLen == len)return (mblock); + + if(bLen > len) { + /* new segment is smaller than the old 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 ((unsigned char _MALLOC_SPEC *)((unsigned int)pHeap + 1)); + } + + /* 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; + bLen = pHeap->bits.count; + + /* allocate by filling the fields */ + pHeap->bits.count = len; + pHeap->bits.alloc = 1; + + if(bLen > len) { + /* 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 + len); + temp->bits.count = bLen - len; + temp->bits.alloc = 0; + } + + return ((unsigned char _MALLOC_SPEC *)((unsigned int)pHeap + 1)); } diff --git a/device/lib/pic16/libc/utils/Makefile b/device/lib/pic16/libc/utils/Makefile index 258f7c92..6d399da4 100644 --- a/device/lib/pic16/libc/utils/Makefile +++ b/device/lib/pic16/libc/utils/Makefile @@ -30,31 +30,19 @@ include ../Makefile.rules CSRCS = -SSRCS = cnvfrac \ - cnvint +S_SRCS = cnvfrac \ + cnvint \ + cvtdec SRCS = $(CSRCS) -# $(SSRCS) -CFILES = $(patsubst %,%.c,$(CSRCS)) -SFILES = $(patsubst %,%.S,$(SSRCS)) - -COFILES = $(patsubst %.c,%.o,$(CFILES)) -SOFILES = $(patsubst %.S,%.o,$(SFILES)) - -OFILES = $(COFILES) -OFILES += $(SOFILES) DEBUG= #COMPILE_FLAGS += --pomit-config-words --pomit-ivt --denable-peeps --optimize-goto --obanksel=2 COMPILE_FLAGS += $(DEBUG) -%.o: %.c - $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $< - -%.o: %.S - $(AS) -c $< +#all: build-library build-library: $(OFILES) diff --git a/device/lib/pic16/libc/utils/cnvfrac.S b/device/lib/pic16/libc/utils/cnvfrac.S index 1788e156..64b4d075 100644 --- a/device/lib/pic16/libc/utils/cnvfrac.S +++ b/device/lib/pic16/libc/utils/cnvfrac.S @@ -21,7 +21,7 @@ ; $Id$ ; radix dec - list p=18f452 + list nolist diff --git a/device/lib/pic16/libc/utils/cnvint.S b/device/lib/pic16/libc/utils/cnvint.S index a7eebf8a..47ca9089 100644 --- a/device/lib/pic16/libc/utils/cnvint.S +++ b/device/lib/pic16/libc/utils/cnvint.S @@ -24,7 +24,7 @@ ; radix dec - list p=18f452 + list nolist diff --git a/device/lib/pic16/libio/Makefile b/device/lib/pic16/libio/Makefile index abbf31d4..8dc2251c 100644 --- a/device/lib/pic16/libio/Makefile +++ b/device/lib/pic16/libio/Makefile @@ -16,7 +16,7 @@ MCUS = $(shell cat ../pics.build) PROCESSORS = $(MCUS) -DIRS = adc i2c +DIRS = adc i2c usart LOBJS = $(patsubst %,%/*.o,$(DIRS)) @@ -37,7 +37,7 @@ build-libraries: build-processor-library: for dir in $(DIRS) ; do \ $(MAKE) -C $$dir clean ; \ - $(MAKE) -C $$dir build-mcu-library MCU=18f$(MMCU); \ + $(MAKE) -C $$dir build-io-lib MCU=18f$(MMCU); \ done; gplib -c $(LIB) $(LOBJS) mv -v $(LIB) ../bin diff --git a/device/lib/pic16/libio/Makefile.rules b/device/lib/pic16/libio/Makefile.rules index a7a64aee..4380fa95 100644 --- a/device/lib/pic16/libio/Makefile.rules +++ b/device/lib/pic16/libio/Makefile.rules @@ -18,12 +18,16 @@ PRJDIR = ../../../../.. LIBC_INC_DIR = $(PRJDIR)/device/include/pic16 + COMPILE_FLAGS += $(MODELFLAGS) COMPILE_FLAGS += -p$(MCU) -#COMPILE_FLAGS += --pomit-config-words --pomit-ivt -COMPILE_FLAGS += --no-peep -COMPILE_FLAGS += --i-code-in-asm -CFLAGS = -I$(LIBC_INC_DIR) +COMPILE_FLAGS += $(OPT_FLAGS) +#COMPILE_FLAGS += --i-code-in-asm + +OPT_FLAGS2 += + +CFLAGS = -I$(LIBC_INC_DIR) $(OPT_FLAGS2) + CFILES = $(patsubst %,%.c,$(SRCS)) OFILES = $(patsubst %.c,%.o,$(CFILES)) @@ -32,11 +36,11 @@ OFILES = $(patsubst %.c,%.o,$(CFILES)) $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $< all: - @echo "Please make target build-mcu-library setting" + @echo "Please make target \`build-io-lib' setting" @echo "MCU= to the target device (i.e. MCU=18f452)" -build-mcu-library: build-library clean-intermediate-no-asm +build-io-lib: build-library clean-intermediate-no-asm clean-intermediate: $(RM) -f *.lst *.asm *.dump* *.p *.d *.adb @@ -48,6 +52,9 @@ clean-intermediate-no-asm: clean: clean-intermediate $(RM) -f $(LIB) *.o +ttest: + $(MAKE) -C ./ build-io-lib MCU=18f452 + dep .depend: rm -f .depend for temp in $(CFILES); do \ diff --git a/device/lib/pic16/libio/adc/Makefile b/device/lib/pic16/libio/adc/Makefile index f83358bf..93470da2 100644 --- a/device/lib/pic16/libio/adc/Makefile +++ b/device/lib/pic16/libio/adc/Makefile @@ -1,5 +1,5 @@ # -# Makefile - Makefile to build pic16 C Library +# Makefile - Makefile to build pic16 AD convertion library # # This file is part of the GNU PIC Library. # @@ -7,9 +7,23 @@ # The GNU PIC Library is maintained by, # Vangelis Rokas # -# $Id$ +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # +# $Id$ +# include ../Makefile.rules diff --git a/device/lib/pic16/libio/adc/adcbusy.c b/device/lib/pic16/libio/adc/adcbusy.c index 5328c314..ae8dd58a 100644 --- a/device/lib/pic16/libio/adc/adcbusy.c +++ b/device/lib/pic16/libio/adc/adcbusy.c @@ -4,7 +4,16 @@ #include -char adc_busy(void) +char adc_busy(void) _naked { - return (ADCON0bits.GO == 1); +#if 1 + return (ADCON0bits.GO); +#else + _asm + movlw 0x00 + btfsc _ADCON0bits, 2 + addlw 0x01 + return + _endasm; +#endif } diff --git a/device/lib/pic16/libio/adc/adcclose.c b/device/lib/pic16/libio/adc/adcclose.c index e6e5b237..3b103b37 100644 --- a/device/lib/pic16/libio/adc/adcclose.c +++ b/device/lib/pic16/libio/adc/adcclose.c @@ -1,11 +1,38 @@ -#include +/* + * adcclose - shutdown AD module + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* +** $Id$ +*/ +#include #include void adc_close(void) { - ADCON0bits.ADON = 0; - PIE1bits.ADIE = 0; + ADCON0bits.ADON = 0; + PIE1bits.ADIE = 0; } diff --git a/device/lib/pic16/libio/adc/adcconv.c b/device/lib/pic16/libio/adc/adcconv.c index 279ba769..b2196d4e 100644 --- a/device/lib/pic16/libio/adc/adcconv.c +++ b/device/lib/pic16/libio/adc/adcconv.c @@ -1,4 +1,32 @@ +/* + * adcconv - begin a convertion + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* +** $Id$ +*/ + #include #include @@ -6,5 +34,5 @@ void adc_conv(void) { - ADCON0bits.GO = 1; + ADCON0bits.GO = 1; } diff --git a/device/lib/pic16/libio/adc/adcopen.c b/device/lib/pic16/libio/adc/adcopen.c index 43e8381e..1842eb10 100644 --- a/device/lib/pic16/libio/adc/adcopen.c +++ b/device/lib/pic16/libio/adc/adcopen.c @@ -1,4 +1,32 @@ +/* + * adcopen - initialize AD module + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* +** $Id$ +*/ + #include #include @@ -13,27 +41,27 @@ void adc_open(unsigned char channel, unsigned char fosc, unsigned char pcfg, unsigned char config) { - ADCON0 = 0; - ADCON1 = 0; - - /* setup channel */ - ADCON0 |= (channel & 0x07) << 3; - - /* setup fosc */ - ADCON0 |= (fosc & 0x03) << 6; - ADCON1 |= (fosc & 0x04) << 4; - - /* setup reference and pins */ - ADCON1 |= pcfg & 0x0f; - - ADCON0 |= (config & ADC_FRM_RJUST); - - if(config & ADC_INT_ON) { - PIR1bits.ADIF = 0; - PIE1bits.ADIE = 1; - INTCONbits.PEIE = 1; - } - - /* enable the A/D module */ - ADCON0bits.ADON = 1; + ADCON0 = 0; + ADCON1 = 0; + + /* setup channel */ + ADCON0 |= (channel & 0x07) << 3; + + /* setup fosc */ + ADCON0 |= (fosc & 0x03) << 6; + ADCON1 |= (fosc & 0x04) << 4; + + /* setup reference and pins */ + ADCON1 |= pcfg & 0x0f; + + ADCON0 |= (config & ADC_FRM_RJUST); + + if(config & ADC_INT_ON) { + PIR1bits.ADIF = 0; + PIE1bits.ADIE = 1; + INTCONbits.PEIE = 1; + } + + /* enable the A/D module */ + ADCON0bits.ADON = 1; } diff --git a/device/lib/pic16/libio/adc/adcread.c b/device/lib/pic16/libio/adc/adcread.c index 445854f1..b3072bb7 100644 --- a/device/lib/pic16/libio/adc/adcread.c +++ b/device/lib/pic16/libio/adc/adcread.c @@ -1,18 +1,42 @@ +/* + * adcread - read value of convertion + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* +** $Id$ +*/ + #include #include -int adc_read(void) +int adc_read(void) _naked { - union { - int ri; - char rb[2]; - } result; - - result.rb[0] = ADRESL; - result.rb[1] = ADRESH; - - return (result.ri); + _asm + movff _ADRESH, _PRODL + movf _ADRESL, w + return + _endasm; } diff --git a/device/lib/pic16/libio/adc/adcsetch.c b/device/lib/pic16/libio/adc/adcsetch.c index f55e77b1..5802e67c 100644 --- a/device/lib/pic16/libio/adc/adcsetch.c +++ b/device/lib/pic16/libio/adc/adcsetch.c @@ -1,11 +1,58 @@ +/* + * adcsetch - select convertion channel + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* +** $Id$ +*/ + #include #include -void adc_setchannel(unsigned char channel) +void adc_setchannel(unsigned char channel) _naked { - ADCON0 &= ~(0x7 << 3); - ADCON0 |= channel << 3; +#if 0 + ADCON0 &= ~(0x7 << 3); + ADCON0 |= channel << 3; +#else + channel; + _asm + movlw 0xc7 + andwf _ADCON0, f + + movlw 0x01 + movf _PLUSW1, w + + rlcf _WREG, w + rlcf _WREG, w + rlcf _WREG, w + + iorwf _ADCON0, f + + return + _endasm; +#endif } diff --git a/device/lib/pic16/libio/i2c/i2cdrdy.c b/device/lib/pic16/libio/i2c/i2cdrdy.c index bd61b3c3..1cbd0f6c 100644 --- a/device/lib/pic16/libio/i2c/i2cdrdy.c +++ b/device/lib/pic16/libio/i2c/i2cdrdy.c @@ -6,8 +6,6 @@ unsigned char i2c_drdy(void) { - if(SSPSTATbits.BF) - return (+1); - else - return (0); + if(SSPSTATbits.BF)return (+1); + else return (0); } diff --git a/device/lib/pic16/libio/usart/Makefile b/device/lib/pic16/libio/usart/Makefile new file mode 100644 index 00000000..03c49fb0 --- /dev/null +++ b/device/lib/pic16/libio/usart/Makefile @@ -0,0 +1,58 @@ +# +# Makefile - Makefile to build pic16 USART communications library +# +# This file is part of the GNU PIC Library. +# +# January, 2005 +# The GNU PIC Library is maintained by, +# Vangelis Rokas +# +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# $Id$ +# + +include ../Makefile.rules + +SRCS = uclose \ + ugetc \ + uopen \ + usartd \ + ubusy \ + udrdy \ + ugets \ + uputc \ + uputs + +#ubaud + +CFILES = $(patsubst %,%.c,$(SRCS)) +OFILES = $(patsubst %.c,%.o,$(CFILES)) + + +DEBUG= +#COMPILE_FLAGS += --pomit-config-words --pomit-ivt --no-peep +COMPILE_FLAGS += $(DEBUG) + +CFILES = $(patsubst %,%.c,$(SRCS)) +OFILES = $(patsubst %.c,%.o,$(CFILES)) + +%.o: %.c + $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $< + +build-library: $(OFILES) + diff --git a/device/lib/pic16/libio/usart/ubaud.c b/device/lib/pic16/libio/usart/ubaud.c new file mode 100644 index 00000000..bdc8500d --- /dev/null +++ b/device/lib/pic16/libio/usart/ubaud.c @@ -0,0 +1,36 @@ + +/* + * ubaud - set baud value + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + +#include + +#include + +void usart_baud(unsigned char baudconfig) wparam +{ + BAUDREG = baudconfig; +} diff --git a/device/lib/pic16/libio/usart/ubusy.c b/device/lib/pic16/libio/usart/ubusy.c new file mode 100644 index 00000000..8533ca18 --- /dev/null +++ b/device/lib/pic16/libio/usart/ubusy.c @@ -0,0 +1,47 @@ + +/* + * ubusy - return USART TX state + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + + +#include + +#include + +unsigned char usart_busy(void) _naked +{ +#if 0 + if(!TXSTAbits.TRMT)return 1; + else return 0; +#else + _asm + movlw 0x00 + btfss _TXSTAbits, 1 + addlw 0x01 + return + _endasm; +#endif +} diff --git a/device/lib/pic16/libio/usart/uclose.c b/device/lib/pic16/libio/usart/uclose.c new file mode 100644 index 00000000..404793f5 --- /dev/null +++ b/device/lib/pic16/libio/usart/uclose.c @@ -0,0 +1,39 @@ + +/* + * uclose - shutdown USART module + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + + +#include + +#include + +void usart_close(void) +{ + RCSTA &= 0x4f; + TXSTAbits.TXEN = 0; + PIE1 &= 0xcf; +} diff --git a/device/lib/pic16/libio/usart/udrdy.c b/device/lib/pic16/libio/usart/udrdy.c new file mode 100644 index 00000000..a4c16f4a --- /dev/null +++ b/device/lib/pic16/libio/usart/udrdy.c @@ -0,0 +1,47 @@ + +/* + * udrdy - return 1 is data is received + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + +#include + +#include + + +unsigned char usart_drdy(void) _naked +{ +#if 0 + if(PIR1bits.RCIF)return 1; + else return 0; +#else + _asm + movlw 0x00 + btfsc _PIR1bits, 5 + addlw 0x01 + return + _endasm; +#endif +} diff --git a/device/lib/pic16/libio/usart/ugetc.c b/device/lib/pic16/libio/usart/ugetc.c new file mode 100644 index 00000000..242b875f --- /dev/null +++ b/device/lib/pic16/libio/usart/ugetc.c @@ -0,0 +1,53 @@ + +/* + * ugetc - get received character + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + + +#include + +#include + +extern union USART USART_Status; + +unsigned char usart_getc(void) +{ + USART_Status.val &= 0xf0; + + if(RCSTAbits.RX9) { + USART_Status.RX_NINE = 0; + if(RCSTAbits.RX9D) + USART_Status.RX_NINE = 1; + } + + if(RCSTAbits.FERR) + USART_Status.FRAME_ERROR = 1; + + if(RCSTAbits.OERR) + USART_Status.OVERRUN_ERROR = 1; + + return (RCREG); +} diff --git a/device/lib/pic16/libio/usart/ugets.c b/device/lib/pic16/libio/usart/ugets.c new file mode 100644 index 00000000..5b833bc2 --- /dev/null +++ b/device/lib/pic16/libio/usart/ugets.c @@ -0,0 +1,50 @@ + +/* + * ugets - read string from USART + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + + +#include + +#include + +void usart_gets(RAM_SCLS char *buffer, unsigned char len) +{ + unsigned char i; + unsigned char dat; + + for(i=0;i + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + + +#include + +#include + +// USART Status Structure +extern union USART USART_Status; + +void usart_open(unsigned char config, unsigned int spbrg) wparam +{ + TXSTA = 0; // Reset USART registers to POR state + RCSTA = 0; + + if(config&0x01)TXSTAbits.SYNC = 1; + + if(config&0x02) { + TXSTAbits.TX9 = 1; + RCSTAbits.RX9 = 1; + } + + if(config&0x04)TXSTAbits.CSRC = 1; + + if(config&0x08)RCSTAbits.CREN = 1; + else RCSTAbits.SREN = 1; + + if(config&0x10)TXSTAbits.BRGH = 1; + else TXSTAbits.BRGH = 0; + + /* TX interrupts */ + PIR1bits.TXIF = 0; + + if(config&0x40)PIE1bits.RCIE = 1; + else PIE1bits.RCIE = 0; + + /* RX interrupts */ + PIR1bits.RCIF = 0; + + if(config&0x80)PIE1bits.TXIE = 1; + else PIE1bits.TXIE = 0; + + SPBRG = (char)spbrg; + + TXSTAbits.TXEN = 1; + RCSTAbits.SPEN = 1; +} diff --git a/device/lib/pic16/libio/usart/uputc.c b/device/lib/pic16/libio/usart/uputc.c new file mode 100644 index 00000000..b62dba42 --- /dev/null +++ b/device/lib/pic16/libio/usart/uputc.c @@ -0,0 +1,61 @@ + +/* + * uputc - write a character to USART + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + + +#include + +#include + +extern union USART USART_Status; + +void usart_putc(unsigned char dat) wparam _naked +{ +#if 0 + if(TXSTAbits.TX9) { + TXSTAbits.TX9D = 0; + if(USART_Status.TX_NINE)TXSTAbits.TX9D = 1; + } + + TXREG = dat; // Write the data byte to the USART +#else + dat; + _asm + btfss _TXSTAbits, 6 + bra _01_ + + bcf _TXSTAbits, 0 + banksel _USART_Status + btfsc _USART_Status, 1, b + bsf _TXSTAbits, 0 + +_01_: + movwf _TXREG + return + _endasm; +#endif +} diff --git a/device/lib/pic16/libio/usart/uputs.c b/device/lib/pic16/libio/usart/uputs.c new file mode 100644 index 00000000..86e6d66a --- /dev/null +++ b/device/lib/pic16/libio/usart/uputs.c @@ -0,0 +1,40 @@ + +/* + * uputs - put a string to USART + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + + +#include + +#include + +void usart_puts(char *dat) +{ + do { + while( usart_busy() ); + usart_putc( *dat ); + } while( *dat++ ); +} diff --git a/device/lib/pic16/libio/usart/usartd.c b/device/lib/pic16/libio/usart/usartd.c new file mode 100644 index 00000000..378adc92 --- /dev/null +++ b/device/lib/pic16/libio/usart/usartd.c @@ -0,0 +1,33 @@ + +/* + * usartd - status variable definition + * + * written by Vangelis Rokas, 2004 + * + * Devices implemented: + * PIC18F[24][45][28] + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + +#include + +#include + +union USART USART_Status; diff --git a/device/lib/pic16/libsdcc/Makefile.rules b/device/lib/pic16/libsdcc/Makefile.rules index fcd5ed62..9a7d0eee 100644 --- a/device/lib/pic16/libsdcc/Makefile.rules +++ b/device/lib/pic16/libsdcc/Makefile.rules @@ -19,22 +19,27 @@ PRJDIR = ../../../../.. LIBC_INC_DIR = $(PRJDIR)/device/include/pic16 +DEBUG = + +OPT_FLAGS += --optimize-cmp #OPT_FLAGS += --stack-auto -COMPILE_FLAGS += $(MODELFLAGS) $(OPT_FLAGS) +COMPILE_FLAGS += $(MODELFLAGS) $(OPT_FLAGS) $(DEBUG) CFLAGS = --nostdinc -I$(LIBC_INC_DIR) CFILES = $(patsubst %,%.c,$(SRCS)) -OFILES = $(patsubst %.c,%.o,$(CFILES)) +COFILES = $(patsubst %.c,%.o,$(CFILES)) SFILES = $(patsubst %,%.S,$(AS_SRCS)) SOFILES = $(patsubst %.S,%.o,$(SFILES)) +OFILES = $(COFILES) $(SOFILES) + %.o: %.c $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $< .S.o: - $(AS) -c $< + $(AS) -I $(LIBC_INC_DIR) -c $< all: build-library clean-intermediate-no-asm diff --git a/device/lib/pic16/libsdcc/char/Makefile b/device/lib/pic16/libsdcc/char/Makefile index d00b3d72..51845937 100644 --- a/device/lib/pic16/libsdcc/char/Makefile +++ b/device/lib/pic16/libsdcc/char/Makefile @@ -19,6 +19,15 @@ SRCS = divschar \ modschar \ moduchar +#SRCS = + +# modschar \ +# moduchar + +#AS_SRCS = divchar \ +# modchar + + include ../Makefile.rules @@ -34,5 +43,7 @@ $(LIB): $(OFILES) else \ $(AR) -r $(LIB) $$object ; \ fi; \ - echo adding $$object ; \ + echo -n "$$object " ; \ done ; + @echo + \ No newline at end of file diff --git a/device/lib/pic16/libsdcc/char/divschar.c b/device/lib/pic16/libsdcc/char/divschar.c index d306f941..173ea905 100644 --- a/device/lib/pic16/libsdcc/char/divschar.c +++ b/device/lib/pic16/libsdcc/char/divschar.c @@ -38,16 +38,12 @@ char _divschar (char a, char b) _IL_REENTRANT register char r; char ta, tb; - if(a<0)ta = -a; else ta = a; - if(b<0)tb = -b; else tb = b; + if(a<0)ta = -a; else ta = a; + if(b<0)tb = -b; else tb = b; - r = _divuchar(ta, tb); - -#if 1 - if ( (a < 0) ^ (b < 0)) - return -r; - else - return r; -#endif + r = _divuchar(ta, tb); + + if ((a < 0) ^ (b < 0)) return -r; + else return r; } diff --git a/device/lib/pic16/libsdcc/char/divuchar.c b/device/lib/pic16/libsdcc/char/divuchar.c index 0aee20d0..7c4ea26d 100644 --- a/device/lib/pic16/libsdcc/char/divuchar.c +++ b/device/lib/pic16/libsdcc/char/divuchar.c @@ -30,13 +30,14 @@ #include -#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) +//#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) +#define MSB_SET(x) (x & 0x80) unsigned char _divuchar (unsigned char a, unsigned char b) _IL_REENTRANT { unsigned char reste = 0; unsigned char count = 8; - char c; + char c; do { @@ -50,10 +51,12 @@ unsigned char _divuchar (unsigned char a, unsigned char b) _IL_REENTRANT if (reste >= b) { reste -= b; + // a <- (result = 1) a |= 1; } } while (--count); + return a; } diff --git a/device/lib/pic16/libsdcc/char/modschar.c b/device/lib/pic16/libsdcc/char/modschar.c index d8c966f7..753bd71f 100644 --- a/device/lib/pic16/libsdcc/char/modschar.c +++ b/device/lib/pic16/libsdcc/char/modschar.c @@ -38,16 +38,12 @@ char _modschar (char a, char b) _IL_REENTRANT register char r; char ta, tb; - if(a<0)ta = -a; else ta = a; - if(b<0)tb = -b; else tb = b; - -// r = _moduchar((a < 0 ? -a : a), -// (b < 0 ? -b : b)); - r = _moduchar(ta, tb); - - if (a < 0) - return -r; - else - return r; + if(a<0)ta = -a; else ta = a; + if(b<0)tb = -b; else tb = b; + + r = _moduchar(ta, tb); + + if (a < 0) return -r; + else return r; } diff --git a/device/lib/pic16/libsdcc/char/moduchar.c b/device/lib/pic16/libsdcc/char/moduchar.c index c627ccc9..d3628906 100644 --- a/device/lib/pic16/libsdcc/char/moduchar.c +++ b/device/lib/pic16/libsdcc/char/moduchar.c @@ -27,13 +27,14 @@ #include -#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) +//#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) +#define MSB_SET(x) (x & 0x80) + unsigned char _moduchar (unsigned char a, unsigned char b) _IL_REENTRANT { unsigned char count = 0; - while (!MSB_SET(b)) { b <<= 1; @@ -44,6 +45,7 @@ unsigned char _moduchar (unsigned char a, unsigned char b) _IL_REENTRANT } count++; } + do { if (a >= b) diff --git a/device/lib/pic16/libsdcc/float/Makefile b/device/lib/pic16/libsdcc/float/Makefile index be6b04a5..bbb233d9 100644 --- a/device/lib/pic16/libsdcc/float/Makefile +++ b/device/lib/pic16/libsdcc/float/Makefile @@ -44,7 +44,7 @@ all: build-library build-library: $(LIB) -$(LIB): $(OFILES) clean-intermediate-no-asm +$(LIB): $(OFILES) @echo Creating $(LIB) ... @for object in $(OFILES) ; do \ if [ ! -e $(LIB) ]; then \ @@ -52,5 +52,6 @@ $(LIB): $(OFILES) clean-intermediate-no-asm else \ $(AR) -r $(LIB) $$object ; \ fi; \ - echo adding $$object ; \ + echo -n "$$object " ; \ done ; + @echo diff --git a/device/lib/pic16/libsdcc/float/fs2ulong.c b/device/lib/pic16/libsdcc/float/fs2ulong.c index ccb200dd..0f305558 100644 --- a/device/lib/pic16/libsdcc/float/fs2ulong.c +++ b/device/lib/pic16/libsdcc/float/fs2ulong.c @@ -28,6 +28,8 @@ union float_long long l; }; +#define volatile + /* convert float to unsigned long */ unsigned long __fs2ulong (float a1) _FS_REENTRANT { @@ -47,7 +49,3 @@ unsigned long __fs2ulong (float a1) _FS_REENTRANT return l; } - - - - diff --git a/device/lib/pic16/startup/Makefile b/device/lib/pic16/startup/Makefile index 4fdbd8b0..b0807e77 100644 --- a/device/lib/pic16/startup/Makefile +++ b/device/lib/pic16/startup/Makefile @@ -23,7 +23,7 @@ SRCS = crt0 \ # add nostdinc and nostdlib for this device libraries COMPILE_FLAGS += $(MODELFLAGS) $(OPT_FLAGS) -COMPILE_FLAGS += --nostdinc --nostdlib +COMPILE_FLAGS += --nostdinc --nostdlib --fommit-frame-pointer CFILES = $(patsubst %,%.c,$(SRCS)) OFILES = $(patsubst %.c,%.o,$(CFILES)) diff --git a/device/lib/pic16/startup/crt0.c b/device/lib/pic16/startup/crt0.c index bd34113b..d906a4bf 100644 --- a/device/lib/pic16/startup/crt0.c +++ b/device/lib/pic16/startup/crt0.c @@ -1,11 +1,30 @@ /* * crt0.c - SDCC pic16 port runtime start code * + * * Converted for SDCC and pic16 port * by Vangelis Rokas (vrokas@otenet.gr) * * based on Microchip MPLAB-C18 startup files * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * * $Id$ */ @@ -34,24 +53,24 @@ void _entry (void) _naked interrupt 0 void _startup (void) _naked { - _asm - // Initialize the stack pointer - lfsr 1, _stack_end - lfsr 2, _stack_end - clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR + _asm + // Initialize the stack pointer + lfsr 1, _stack_end + lfsr 2, _stack_end + clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR - // initialize the flash memory access configuration. this is harmless - // for non-flash devices, so we do it on all parts. - bsf 0xa6, 7, 0 - bcf 0xa6, 6, 0 + // initialize the flash memory access configuration. this is harmless + // for non-flash devices, so we do it on all parts. + bsf 0xa6, 7, 0 + bcf 0xa6, 6, 0 - _endasm ; + _endasm ; - /* Call the user's main routine */ - main (); + /* Call the user's main routine */ + main(); loop: - /* return from main will lock up */ - goto loop; + /* return from main will lock up */ + goto loop; } diff --git a/device/lib/pic16/startup/crt0i.c b/device/lib/pic16/startup/crt0i.c index 9459d62c..d8cfe434 100644 --- a/device/lib/pic16/startup/crt0i.c +++ b/device/lib/pic16/startup/crt0i.c @@ -7,6 +7,24 @@ * * based on Microchip MPLAB-C18 startup files * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * * $Id$ */ @@ -21,8 +39,11 @@ extern FSR0H; extern TABLAT; extern POSTINC0; + +#if 1 /* global variable for forcing gplink to add _cinit section */ char __uflags = 0; +#endif /* external reference to the user's main routine */ extern void main (void); @@ -32,7 +53,7 @@ void _entry (void) _naked interrupt 0; void _startup (void) _naked; /* prototype for the initialized data setup */ -void _do_cinit (void); +void _do_cinit (void) _naked; /* @@ -47,27 +68,27 @@ void _entry (void) _naked interrupt 0 void _startup (void) _naked { - _asm - // Initialize the stack pointer - lfsr 1, _stack_end - lfsr 2, _stack_end - clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR + _asm + // Initialize the stack pointer + lfsr 1, _stack_end + lfsr 2, _stack_end + clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR - // initialize the flash memory access configuration. this is harmless - // for non-flash devices, so we do it on all parts. - bsf 0xa6, 7, 0 - bcf 0xa6, 6, 0 + // initialize the flash memory access configuration. this is harmless + // for non-flash devices, so we do it on all parts. + bsf 0xa6, 7, 0 + bcf 0xa6, 6, 0 - _endasm ; + _endasm ; - _do_cinit(); + _do_cinit(); - /* Call the user's main routine */ - main (); + /* Call the user's main routine */ + main(); loop: - /* return from main will lock up */ - goto loop; + /* return from main will lock up */ + goto loop; } @@ -83,183 +104,172 @@ extern code struct } cinit; -#define tblrdpostinc tblrd*+ - +#define TBLRDPOSTINC tblrd*+ -#pragma udata access _do_cinit_prom, _do_cinit_curr_byte -#pragma udata access _do_cinit_ curr_entry, _do_cinit_data_ptr +#define prom 0x00 /* 0x00 0x01 0x02*/ +#define curr_byte 0x03 /* 0x03 0x04 */ +#define curr_entry 0x05 /* 0x05 0x06 */ +#define data_ptr 0x07 /* 0x07 0x08 0x09 */ -static short long _do_cinit_prom; -static unsigned short _do_cinit_curr_byte; -static unsigned short _do_cinit_curr_entry; -static short long _do_cinit_data_ptr; +/* + * static short long _do_cinit_prom; + * static unsigned short _do_cinit_curr_byte; + * static unsigned short _do_cinit_curr_entry; + * static short long _do_cinit_data_ptr; + */ /* the variable initialisation routine */ -void _do_cinit (void) +void _do_cinit (void) _naked { /* - * we'll make the assumption in the following code that these statics - * will be allocated into the same bank. + * access registers 0x00 - 0x09 are not saved in this function */ + _asm + ; TBLPTR = &cinit + movlw low(_cinit) + movwf _TBLPTRL + movlw high(_cinit) + movwf _TBLPTRH + movlw upper(_cinit) + movwf _TBLPTRU + + ; curr_entry = cinit.num_init + ; movlb data_ptr + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_entry + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_entry+1 - /* TBLPTR = &cinit */ - _asm - movlw low(_cinit) - movwf _TBLPTRL, 0 - movlw high(_cinit) - movwf _TBLPTRH, 0 - movlw upper(_cinit) - movwf _TBLPTRU, 0 - _endasm; - - - /* curr_entry = cinit.num_init */ - _asm - movlb __do_cinit_data_ptr - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry, 1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry+1, 1 - _endasm; - - - //while (curr_entry) { - _asm + ; while (curr_entry) { test: - bnz done1 - tstfsz __do_cinit_curr_entry, 1 - bra cont1 + bnz done1 + tstfsz curr_entry, 1 + bra cont1 done1: - goto done + goto done cont1: - _endasm; + ; Count down so we only have to look up the data in _cinit once. - /* Count down so we only have to look up the data in _cinit - * once. - * - * At this point we know that TBLPTR points to the top of the current - * entry in _cinit, so we can just start reading the from, to, and - * size values. - */ - _asm - - /* read the source address low */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom, 1 + ; At this point we know that TBLPTR points to the top of the current + ; entry in _cinit, so we can just start reading the from, to, and + ; size values. + + ; read the source address low + TBLRDPOSTINC + movf _TABLAT, w + movwf prom - /* source address high */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom + 1, 1 - - /* source address upper */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom + 2, 1 - - /* skip a byte since it's stored as a 32bit int */ - tblrdpostinc - - /* read the destination address directly into FSR0 */ - /* destination address low */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _FSR0L, 0 - - /* destination address high */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _FSR0H, 0 - - /* skip two bytes since it's stored as a 32bit int */ - tblrdpostinc - tblrdpostinc - - /* read the destination address directly into FSR0 */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte, 1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte+1, 1 - - /* skip two bytes since it's stored as a 32bit int */ - tblrdpostinc - tblrdpostinc - _endasm; - - //prom = data_ptr->from; - //FSR0 = data_ptr->to; - //curr_byte = (unsigned short) data_ptr->size; - /* the table pointer now points to the next entry. Save it - * off since we'll be using the table pointer to do the copying - * for the entry */ - - /* data_ptr = TBLPTR */ - _asm - movff _TBLPTRL, __do_cinit_data_ptr - movff _TBLPTRH, __do_cinit_data_ptr + 1 - movff _TBLPTRU, __do_cinit_data_ptr + 2 - _endasm; + ; source address high + TBLRDPOSTINC + movf _TABLAT, w + movwf prom + 1 + + ; source address upper + TBLRDPOSTINC + movf _TABLAT, w + movwf prom + 2 + + ; skip a byte since it is stored as a 32bit int + TBLRDPOSTINC + + ; read the destination address directly into FSR0 + ; destination address low + TBLRDPOSTINC + movf _TABLAT, w + movwf _FSR0L + + ; destination address high + TBLRDPOSTINC + movf _TABLAT, w + movwf _FSR0H + + ; skip two bytes since it is stored as a 32bit int + TBLRDPOSTINC + TBLRDPOSTINC + + ; read the destination address directly into FSR0 + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_byte + + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_byte+1 + + + ; skip two bytes since it is stored as a 32bit int + TBLRDPOSTINC + TBLRDPOSTINC + + ; prom = data_ptr->from; + ; FSR0 = data_ptr->to; + ; curr_byte = (unsigned short) data_ptr->size; + + ; the table pointer now points to the next entry. Save it + ; off since we will be using the table pointer to do the copying + ; for the entry + ; data_ptr = TBLPTR + + movff _TBLPTRL, data_ptr + movff _TBLPTRH, data_ptr + 1 + movff _TBLPTRU, data_ptr + 2 - /* now assign the source address to the table pointer */ - /* TBLPTR = prom */ - _asm - movff __do_cinit_prom, _TBLPTRL - movff __do_cinit_prom + 1, _TBLPTRH - movff __do_cinit_prom + 2, _TBLPTRU - _endasm; - - /* do the copy loop */ - _asm - - /* determine if we have any more bytes to copy */ - movlb __do_cinit_curr_byte - movf __do_cinit_curr_byte, 1, 1 + ; now assign the source address to the table pointer + ; TBLPTR = prom + + movff prom, _TBLPTRL + movff prom + 1, _TBLPTRH + movff prom + 2, _TBLPTRU + + ; do the copy loop + + ; determine if we have any more bytes to copy + ; movlb curr_byte + movf curr_byte, w + copy_loop: - bnz copy_one_byte // copy_one_byte - movf __do_cinit_curr_byte + 1, 1, 1 - bz done_copying + bnz copy_one_byte ; copy_one_byte + movf curr_byte + 1, w + bz done_copying copy_one_byte: - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _POSTINC0, 0 + TBLRDPOSTINC + movf _TABLAT, w + movwf _POSTINC0 - /* decrement byte counter */ - decf __do_cinit_curr_byte, 1, 1 - bnc copy_loop // copy_loop - decf __do_cinit_curr_byte + 1, 1, 1 + ; decrement byte counter + decf curr_byte, f + bnc copy_loop ; copy_loop + decf curr_byte + 1, f - bra copy_loop + bra copy_loop done_copying: - _endasm; - - /* restore the table pointer for the next entry */ - /* TBLPTR = data_ptr */ - _asm - movff __do_cinit_data_ptr, _TBLPTRL - movff __do_cinit_data_ptr + 1, _TBLPTRH - movff __do_cinit_data_ptr + 2, _TBLPTRU - _endasm; - /* next entry... */ - _do_cinit_curr_entry--; + ; restore the table pointer for the next entry + ; TBLPTR = data_ptr + movff data_ptr, _TBLPTRL + movff data_ptr + 1, _TBLPTRH + movff data_ptr + 2, _TBLPTRU + + dcfsnz curr_entry, f + decf curr_entry + 1, f + + ; next entry... + ; _do_cinit_curr_entry--; - _asm - goto test; + goto test; - /* emit done label */ + ; emit done label done: - _endasm; + return + _endasm; } diff --git a/device/lib/pic16/startup/crt0iz.c b/device/lib/pic16/startup/crt0iz.c index 55d339b4..8e621536 100644 --- a/device/lib/pic16/startup/crt0iz.c +++ b/device/lib/pic16/startup/crt0iz.c @@ -7,6 +7,24 @@ * * based on Microchip MPLAB-C18 startup files * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * * $Id$ */ @@ -22,8 +40,10 @@ extern TABLAT; extern POSTINC0; extern POSTDEC0; +#if 1 /* global variable for forcing gplink to add _cinit section */ char __uflags = 0; +#endif /* external reference to the user's main routine */ extern void main (void); @@ -33,7 +53,7 @@ void _entry (void) _naked interrupt 0; void _startup (void) _naked; /* prototype for the initialized data setup */ -void _do_cinit (void); +void _do_cinit (void) _naked; /* @@ -48,50 +68,50 @@ void _entry (void) _naked interrupt 0 void _startup (void) _naked { - _asm - // Initialize the stack pointer - lfsr 1, _stack_end - lfsr 2, _stack_end - clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR + _asm + // Initialize the stack pointer + lfsr 1, _stack_end + lfsr 2, _stack_end + clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR - // initialize the flash memory access configuration. this is harmless - // for non-flash devices, so we do it on all parts. - bsf 0xa6, 7, 0 - bcf 0xa6, 6, 0 - - _endasm ; + // initialize the flash memory access configuration. this is harmless + // for non-flash devices, so we do it on all parts. + bsf 0xa6, 7, 0 + bcf 0xa6, 6, 0 + _endasm ; - /* cleanup the RAM */ - _asm - /* load FSR0 with top of RAM memory */ - movlw 0xff - movwf _FSR0L, 0 - movlw 0x0e - movwf _FSR0H, 0 + /* cleanup the RAM */ + _asm + /* load FSR0 with top of RAM memory */ + ; movlw 0xff + ; movwf _FSR0L, 0 + setf _FSR0L + movlw 0x0e + movwf _FSR0H, 0 - /* place a 1 at address 0x00, as a marker - * we haven't reached yet to it */ - movlw 1 - movwf 0x00, 0 + /* place a 1 at address 0x00, as a marker + * we haven't reached yet to it */ + ; movlw 1 + ; movwf 0x00, 0 + setf 0x00 - /* load WREG with zero */ - movlw 0x00 + /* load WREG with zero */ + movlw 0x00 clear_loop: - movwf _POSTDEC0, 0 - movf 0x00, 1, 0 - bnz clear_loop - _endasm ; + movwf _POSTDEC0 + movf 0x00, w + bnz clear_loop + _endasm ; + _do_cinit(); - _do_cinit(); - - /* Call the user's main routine */ - main (); + /* Call the user's main routine */ + main(); loop: - /* return from main will lock up */ - goto loop; + /* return from main will lock up */ + goto loop; } @@ -107,178 +127,174 @@ extern code struct } cinit; -#define tblrdpostinc tblrd*+ +#define TBLRDPOSTINC tblrd*+ + +#define prom 0x00 /* 0x00 0x01 0x02*/ +#define curr_byte 0x03 /* 0x03 0x04 */ +#define curr_entry 0x05 /* 0x05 0x06 */ +#define data_ptr 0x07 /* 0x07 0x08 0x09 */ + +/* + * static short long _do_cinit_prom; + * static unsigned short _do_cinit_curr_byte; + * static unsigned short _do_cinit_curr_entry; + * static short long _do_cinit_data_ptr; + */ /* the variable initialisation routine */ -void _do_cinit (void) +void _do_cinit (void) _naked { /* - * we'll make the assumption in the following code that these statics - * will be allocated into the same bank. + * access registers 0x00 - 0x09 are not saved in this function */ - static short long prom; - static unsigned short curr_byte; - static unsigned short curr_entry; - static short long data_ptr; - - - /* TBLPTR = &cinit */ - _asm - movlw low(_cinit) - movwf _TBLPTRL, 0 - movlw high(_cinit) - movwf _TBLPTRH, 0 - movlw upper(_cinit) - movwf _TBLPTRU, 0 - _endasm; + _asm + ; TBLPTR = &cinit + movlw low(_cinit) + movwf _TBLPTRL + movlw high(_cinit) + movwf _TBLPTRH + movlw upper(_cinit) + movwf _TBLPTRU - /* curr_entry = cinit.num_init */ - _asm - movlb __do_cinit_data_ptr_1_1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry_1_1, 1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry_1_1+1, 1 - _endasm; - - - //while (curr_entry) { - _asm + ; curr_entry = cinit.num_init + ; movlb data_ptr + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_entry + + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_entry+1 + + ; while (curr_entry) { test: - bnz done1 - tstfsz __do_cinit_curr_entry_1_1, 1 - bra cont1 + bnz done1 + tstfsz curr_entry, 1 + bra cont1 done1: - goto done + goto done cont1: - _endasm; + ; Count down so we only have to look up the data in _cinit once. - /* Count down so we only have to look up the data in _cinit - * once. - * - * At this point we know that TBLPTR points to the top of the current - * entry in _cinit, so we can just start reading the from, to, and - * size values. - */ - _asm - - /* read the source address low */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1, 1 + ; At this point we know that TBLPTR points to the top of the current + ; entry in _cinit, so we can just start reading the from, to, and + ; size values. + + ; read the source address low + TBLRDPOSTINC + movf _TABLAT, w + movwf prom - /* source address high */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1 + 1, 1 - - /* source address upper */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1 + 2, 1 - - /* skip a byte since it's stored as a 32bit int */ - tblrdpostinc - - /* read the destination address directly into FSR0 */ - /* destination address low */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _FSR0L, 0 - - /* destination address high */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _FSR0H, 0 - - /* skip two bytes since it's stored as a 32bit int */ - tblrdpostinc - tblrdpostinc - - /* read the destination address directly into FSR0 */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte_1_1, 1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte_1_1+1, 1 - - /* skip two bytes since it's stored as a 32bit int */ - tblrdpostinc - tblrdpostinc - _endasm; - - //prom = data_ptr->from; - //FSR0 = data_ptr->to; - //curr_byte = (unsigned short) data_ptr->size; - /* the table pointer now points to the next entry. Save it - * off since we'll be using the table pointer to do the copying - * for the entry */ - - /* data_ptr = TBLPTR */ - _asm - movff _TBLPTRL, __do_cinit_data_ptr_1_1 - movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1 - movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2 - _endasm; + ; source address high + TBLRDPOSTINC + movf _TABLAT, w + movwf prom + 1 + + ; source address upper + TBLRDPOSTINC + movf _TABLAT, w + movwf prom + 2 + + ; skip a byte since it is stored as a 32bit int + TBLRDPOSTINC + + ; read the destination address directly into FSR0 + ; destination address low + TBLRDPOSTINC + movf _TABLAT, w + movwf _FSR0L + + ; destination address high + TBLRDPOSTINC + movf _TABLAT, w + movwf _FSR0H + + ; skip two bytes since it is stored as a 32bit int + TBLRDPOSTINC + TBLRDPOSTINC + + ; read the destination address directly into FSR0 + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_byte + + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_byte+1 + + + ; skip two bytes since it is stored as a 32bit int + TBLRDPOSTINC + TBLRDPOSTINC + + ; prom = data_ptr->from; + ; FSR0 = data_ptr->to; + ; curr_byte = (unsigned short) data_ptr->size; + + ; the table pointer now points to the next entry. Save it + ; off since we will be using the table pointer to do the copying + ; for the entry + ; data_ptr = TBLPTR + + movff _TBLPTRL, data_ptr + movff _TBLPTRH, data_ptr + 1 + movff _TBLPTRU, data_ptr + 2 - /* now assign the source address to the table pointer */ - /* TBLPTR = prom */ - _asm - movff __do_cinit_prom_1_1, _TBLPTRL - movff __do_cinit_prom_1_1 + 1, _TBLPTRH - movff __do_cinit_prom_1_1 + 2, _TBLPTRU - _endasm; - - /* do the copy loop */ - _asm - - /* determine if we have any more bytes to copy */ - movlb __do_cinit_curr_byte_1_1 - movf __do_cinit_curr_byte_1_1, 1, 1 + ; now assign the source address to the table pointer + ; TBLPTR = prom + + movff prom, _TBLPTRL + movff prom + 1, _TBLPTRH + movff prom + 2, _TBLPTRU + + ; do the copy loop + + ; determine if we have any more bytes to copy + ; movlb curr_byte + movf curr_byte, w + copy_loop: - bnz copy_one_byte // copy_one_byte - movf __do_cinit_curr_byte_1_1 + 1, 1, 1 - bz done_copying + bnz copy_one_byte ; copy_one_byte + movf curr_byte + 1, w + bz done_copying copy_one_byte: - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _POSTINC0, 0 + TBLRDPOSTINC + movf _TABLAT, w + movwf _POSTINC0 - /* decrement byte counter */ - decf __do_cinit_curr_byte_1_1, 1, 1 - bnc copy_loop // copy_loop - decf __do_cinit_curr_byte_1_1 + 1, 1, 1 + ; decrement byte counter + decf curr_byte, f + bnc copy_loop ; copy_loop + decf curr_byte + 1, f - bra copy_loop + bra copy_loop done_copying: - _endasm; - - /* restore the table pointer for the next entry */ - /* TBLPTR = data_ptr */ - _asm - movff __do_cinit_data_ptr_1_1, _TBLPTRL - movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH - movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU - _endasm; - /* next entry... */ - curr_entry--; + ; restore the table pointer for the next entry + ; TBLPTR = data_ptr + movff data_ptr, _TBLPTRL + movff data_ptr + 1, _TBLPTRH + movff data_ptr + 2, _TBLPTRU + + + dcfsnz curr_entry, f + decf curr_entry + 1, f + + ; next entry... + ; _do_cinit_curr_entry--; - _asm - goto test; + goto test; - /* emit done label */ + ; emit done label done: - _endasm; + return + _endasm; } diff --git a/src/pic16/NOTES b/src/pic16/NOTES index 35cf9318..847485e9 100644 --- a/src/pic16/NOTES +++ b/src/pic16/NOTES @@ -19,6 +19,17 @@ Scott Dattalo ====================================================================== ====================================================================== +2005-Mar-23 Vangelis Rokas +1. I have added some optimizations that are controlled via enviroment +variables to allow checking. Later these will be either enabled globally +or controlled by command line options. The variables are: + a. OPTIMIZE_BITFIELD_POINTER_GET : optimizes bit field pointer reads + + b. NO_REG_OPT : there is no register optimization performed by pCode + optimizer + + + 2004-Oct-29 Vangelis Rokas 1. Function parameters are passed now all via stack. This might lower performance, but some issues are solved this way. Later diff --git a/src/pic16/device.c b/src/pic16/device.c index fdf37ec6..fad6adf7 100644 --- a/src/pic16/device.c +++ b/src/pic16/device.c @@ -43,7 +43,7 @@ static PIC16_device Pics16[] = { // { -// {"p18f242", "18f242", "pic18f242", "f242"}, // aliases +// {"p18f242", "18f242", "pic18f242", "f242", "18F242"}, // aliases // 0, // 0x300, // RAMsize // 0, @@ -73,8 +73,8 @@ static PIC16_device Pics16[] = { 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ , + { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -95,8 +95,8 @@ static PIC16_device Pics16[] = { 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , { -1, 0, 0xff } /* 4 */ , { -1, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ , + { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -161,8 +161,8 @@ static PIC16_device Pics16[] = { 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ , + { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -183,8 +183,8 @@ static PIC16_device Pics16[] = { 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , { -1, 0, 0xff } /* 4 */ , { -1, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ , + { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -271,8 +271,8 @@ static PIC16_device Pics16[] = { 0x30000d, { { 0xcf, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x1f, 0, 0xff } /* 3 */ , { -1, 0, 0xff } /* 4 */ , { 0x83, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ , + { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -280,6 +280,72 @@ static PIC16_device Pics16[] = { { 0, 0 }, { 0, 0 }, { 0, 0 } } } }, + { + {"p18f2550", "18f2550", "pic18f2550", "f2550"}, + 0, + 0x800, /* 2048 */ + 0x60, + 0, + { 0xf62, 0xfff }, /* PIC18F2550 range of SFR's */ + { + /* PIC18F2550 configuration words */ + 0x300000, + 0x30000d, + { { 0x3f, 0, 0xff } /* 0 */ , { 0xcf, 0, 0xff } /* 1 */ , { 0x3f, 0, 0xff } /* 2 */ , + { 0x1f, 0, 0xff } /* 3 */ , { -1, 0, 0xff } /* 4 */ , { 0x87, 0, 0xff } /* 5 */ , + { 0xe5, 0, 0xff } /* 6 */ , { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , + { 0xc0, 0, 0xff } /* 9 */ , { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , + { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } + }, + { 0x200000, 0x200007, + { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 } } + } + }, + { + {"p18f4331", "18f4331", "pic18f4331", "f4331"}, + 0, + 0x300, /* 768 */ + 0x60, + 0, + { 0xf60, 0xfff }, /* PIC18F4331 range of SFR's */ + { + /* PIC18F4331 configuration words */ + 0x300001, + 0x30000d, + { { 0xcf, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x3f, 0, 0xff } /* 3 */ , + { 0x3c, 0, 0xff } /* 4 */ , { 0x9d, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , + { 0x40, 0, 0xff } /* d */ } + }, + { 0x200000, 0x200007, + { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 } } + } + }, + { + {"p18f4455", "18f4455", "pic18f4455", "f4455"}, + 0, + 0x800, /* 2048 */ + 0x60, + 0, + { 0xf62, 0xfff }, /* PIC18F4455 range of SFR's */ + { + /* PIC18F4455 configuration words */ + 0x300000, + 0x30000d, + { { 0x3f, 0, 0xff } /* 0 */ , { 0xcf, 0, 0xff } /* 1 */ , { 0x3f, 0, 0xff } /* 2 */ , + { 0x1f, 0, 0xff } /* 3 */ , { -1, 0, 0xff } /* 4 */ , { 0x87, 0, 0xff } /* 5 */ , + { 0xe5, 0, 0xff } /* 6 */ , { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , + { 0xc0, 0, 0xff } /* 9 */ , { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , + { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } + }, + { 0x200000, 0x200007, + { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 } } + } + }, { {"p18f6520", "18f6520", "pic18f6520", "f6520"}, 0, @@ -292,9 +358,9 @@ static PIC16_device Pics16[] = { 0x300001, 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , - { 0x80, 0, 0xff } /* 4 */ , { 0x88, 0, 0xff } /* 5 */ , { -1, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x03, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -314,9 +380,9 @@ static PIC16_device Pics16[] = { 0x300001, 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , - { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x03, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -330,13 +396,13 @@ static PIC16_device Pics16[] = { 0xf00, /* 3840 */ 0x60, 0, - { 0xf00, 0xfff }, /* PIC18F6680 range of SFR's */ + { 0xd60, 0xfff }, /* PIC18F6680 range of SFR's */ { /* PIC18F6680 configuration words */ 0x300001, 0x30000d, { { 0x2f, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x1f, 0, 0xff } /* 3 */ , - { -1, 0, 0xff } /* 4 */ , { 0x83, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x81, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } @@ -358,7 +424,7 @@ static PIC16_device Pics16[] = { 0x300001, 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , - { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x03, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } @@ -380,9 +446,9 @@ static PIC16_device Pics16[] = { 0x300001, 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , - { 0x83, 0, 0xff } /* 4 */ , { 0x88, 0, 0xff } /* 5 */ , { -1, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x03, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -402,9 +468,9 @@ static PIC16_device Pics16[] = { 0x300001, 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , - { 0x83, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , - { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x03, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , + { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } }, { 0x200000, 0x200007, @@ -417,14 +483,14 @@ static PIC16_device Pics16[] = { 0, 0xf00, /* 3840 */ 0x60, - 0, - { 0xf00, 0xfff }, /* PIC18F8680 range of SFR's */ + 1, + { 0xd60, 0xfff }, /* PIC18F8680 range of SFR's */ { /* PIC18F8680 configuration words */ 0x300001, 0x30000d, { { 0x2f, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x1f, 0, 0xff } /* 3 */ , - { 0x83, 0, 0xff } /* 4 */ , { 0x83, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x81, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } @@ -446,7 +512,7 @@ static PIC16_device Pics16[] = { 0x300001, 0x30000d, { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ , - { 0x83, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { 0x83, 0, 0xff } /* 4 */ , { 0x03, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ , { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ , { 0x40, 0, 0xff } /* d */ } @@ -1105,11 +1171,14 @@ void pic16_assignConfigWordValue(int address, unsigned int value) (pic16->cwInfo.crInfo[i].mask) & (~value)); #endif +#if 0 if((((pic16->cwInfo.crInfo[i].mask) & (~value))&0xff) != ((~value)&0xff)) { fprintf(stderr, "%s:%d a wrong value has been given for configuration register 0x%x\n", __FILE__, __LINE__, address); return; } +#endif + pic16->cwInfo.crInfo[i].value = value; pic16->cwInfo.crInfo[i].emit = 1; return; diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 3164667a..26ad8236 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -679,7 +679,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) DEBUGpic16_emitcode("; +++ ", "%s:%d\top = %s", __FILE__, __LINE__, pic16_decodeOp(ic->op)); if((ic->op == '=' /*|| ic->op == CAST*/) && IC_RESULT(ic) && AOP( IC_RESULT(ic) ) && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG)) { - pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) )); +// pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) )); for(i=0;isize;i++) aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx); @@ -1272,7 +1272,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK!\n", __FUNCTION__, __LINE__); DEBUGpic16_emitcode (";","%s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__); assert (getSize(sym->type) <= 1); - aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);//pic16_popRegFromString("_WREG", getSize(sym->type), 0, op); + aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg); } aop->size = getSize(sym->type); @@ -2404,7 +2404,7 @@ static void mov2fp(pCodeOp *dst, asmop *src, int offset) void pic16_testStackOverflow(void) { -#define GSTACK_TEST_NAME "__gstack_test" +#define GSTACK_TEST_NAME "_gstack_test" pic16_emitpcode(POC_CALL, pic16_popGetWithString( GSTACK_TEST_NAME )); @@ -2412,7 +2412,8 @@ void pic16_testStackOverflow(void) symbol *sym; sym = newSymbol( GSTACK_TEST_NAME , 0 ); - strcpy(sym->rname, GSTACK_TEST_NAME); + sprintf(sym->rname, "%s%s", port->fun_prefix, GSTACK_TEST_NAME); +// strcpy(sym->rname, GSTACK_TEST_NAME); checkAddSym(&externs, sym); } @@ -3657,21 +3658,25 @@ static void genFunction (iCode *ic) sprintf(asymname, "ivec_%s", sym->name); else sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name); - asym = newSymbol(asymname, 0); - - /* FIXME: when an interrupt is declared as naked, do not emit the special - * wrapper segment at vector address. The user should take care for this - * instead. -- VR */ - - apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); - pic16_addpBlock( apb ); - - pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------")); - pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name)); - pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname ))); + + /* when an interrupt is declared as naked, do not emit the special + * wrapper segment at vector address. The user should take care for + * this instead. -- VR */ + + if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) =! INTNO_UNSPEC)) { + asym = newSymbol(asymname, 0); + apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); + pic16_addpBlock( apb ); + + pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------")); + pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name)); + pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname ))); - /* mark the end of this tiny function */ - pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL)); + /* mark the end of this tiny function */ + pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL)); + } else { + sprintf(asymname, "%s", sym->rname); + } { absSym *abSym; @@ -3685,7 +3690,7 @@ static void genFunction (iCode *ic) case 2: abSym->address = 0x000018; break; default: - fprintf(stderr, "no interrupt number is given\n"); +// fprintf(stderr, "no interrupt number is given\n"); abSym->address = -1; break; } @@ -3705,7 +3710,6 @@ static void genFunction (iCode *ic) pic16_emitcode("","%s:",sym->rname); pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname)); - { absSym *ab; @@ -3717,7 +3721,6 @@ static void genFunction (iCode *ic) } } - if(IFFUNC_ISNAKED(ftype)) { DEBUGpic16_emitcode("; ***", "_naked function, no prologue"); return; @@ -6161,7 +6164,6 @@ static void genCmp (operand *left, operand *right, } } else { - /* unsigned compare */ DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); @@ -6172,10 +6174,8 @@ static void genCmp (operand *left, operand *right, compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); } - if(ifx)ifx->generated = 1; - if(AOP_SIZE(result)) { pic16_emitpLabel(falselbl->key); pic16_outBitC( result ); @@ -11169,7 +11169,6 @@ static void genGenPointerGet (operand *left, { int size, offset, lit; sym_link *retype = getSpec(operandType(result)); - char fgptrget[32]; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(left,ic,FALSE); @@ -11205,31 +11204,10 @@ static void genGenPointerGet (operand *left, pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl))); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2)); - switch( size ) { - case 1: strcpy(fgptrget, "__gptrget1"); break; - case 2: strcpy(fgptrget, "__gptrget2"); break; - case 3: strcpy(fgptrget, "__gptrget3"); break; - case 4: strcpy(fgptrget, "__gptrget4"); break; - default: - werror(W_POSSBUG2, __FILE__, __LINE__); - abort(); - } - - pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget )); + pic16_callGenericPointerRW(0, size); assignResultValue(result, 1); - { - symbol *sym; - - sym = newSymbol( fgptrget, 0 ); - sym->used++; - strcpy(sym->rname, fgptrget); - checkAddSym(&externs, sym); - -// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget); - } - goto release; } @@ -11511,13 +11489,8 @@ static void genPackBits (sym_link *etype , operand *result, pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl))); pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2)); - pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrget1")); - { - symbol *sym; - sym = newSymbol( "__gptrget1", 0 ); - strcpy(sym->rname, "__gptrget1"); - checkAddSym(&externs, sym); - } + + pic16_callGenericPointerRW(0, 1); } else { // data pointer (just 2 byte given) pic16_loadFSR0( result, 0 ); @@ -11560,13 +11533,8 @@ static void genPackBits (sym_link *etype , operand *result, pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl))); pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2)); - pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrput1")); - { - symbol *sym; - sym = newSymbol( "__gptrput1", 0 ); - strcpy(sym->rname, "__gptrput1"); - checkAddSym(&externs, sym); - } + + pic16_callGenericPointerRW(1, 1); } else { // data pointer (just 2 byte given) if (!fsr0_setup) pic16_loadFSR0( result, 0 ); @@ -12130,7 +12098,6 @@ static void genGenPointerSet (operand *right, { int size; sym_link *retype = getSpec(operandType(right)); - char fgptrput[32]; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -12173,28 +12140,7 @@ static void genGenPointerSet (operand *right, pic16_popCopyReg(&pic16_pc_prodl))); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2)); - - /* put code here */ - switch (size) { - case 1: strcpy(fgptrput, "__gptrput1"); break; - case 2: strcpy(fgptrput, "__gptrput2"); break; - case 3: strcpy(fgptrput, "__gptrput3"); break; - case 4: strcpy(fgptrput, "__gptrput4"); break; - default: - werror(W_POSSBUG2, __FILE__, __LINE__); - abort(); - } - - pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput )); - - { - symbol *sym; - - sym = newSymbol( fgptrput, 0 ); - sym->used++; - strcpy(sym->rname, fgptrput); - checkAddSym(&externs, sym); - } + pic16_callGenericPointerRW(1, size); release: pic16_freeAsmop(right,NULL,ic,TRUE); diff --git a/src/pic16/gen.h b/src/pic16/gen.h index bafe4f8c..497b2999 100644 --- a/src/pic16/gen.h +++ b/src/pic16/gen.h @@ -208,17 +208,25 @@ void dumpiCode(iCode *lic); int inWparamList(char *s); +#include "device.h" + #define DUMP_FUNCTION_ENTRY 1 #define DUMP_FUNCTION_EXIT 0 #if DUMP_FUNCTION_ENTRY -#define FENTRY pic16_emitpcomment("**{\t%d %s", __LINE__, __FUNCTION__) +#define FENTRY if(pic16_options.debgen&2)pic16_emitpcomment("**{\t%d %s", __LINE__, __FUNCTION__) #define FENTRY2 if(pic16_options.debgen&2)pic16_emitpcomment("**{\t%d %s", __LINE__, __FUNCTION__) +#else +#define FENTRY +#define FENTRY2 #endif #if DUMP_FUNCTION_EXIT -#define FEXIT pic16_emitpcomment("; **}", "%d %s", __LINE__, __FUNCTION__) +#define FEXIT if(pic16_options.debgen&2)pic16_emitpcomment("; **}", "%d %s", __LINE__, __FUNCTION__) #define FEXIT2 if(pic16_options.debgen&2)pic16_emitpcomment("**{\t%d %s", __LINE__, __FUNCTION__) +#else +#define FEXIT +#define FEXIT2 #endif #define ERROR werror(W_POSSBUG2, __FILE__, __LINE__) diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c index ccbc503f..4e077b4d 100644 --- a/src/pic16/genutils.c +++ b/src/pic16/genutils.c @@ -465,6 +465,36 @@ void gpsimDebug_StackDump(char *fname, int line, char *info) gpsimio2_lit('\n'); } +const char *gptr_fns[4][2] = { + { "_gptrget1", "_gptrput1" }, + { "_gptrget2", "_gptrput2" }, + { "_gptrget3", "_gptrput3" }, + { "_gptrget4", "_gptrput4" } }; + +extern set *externs; + +/* generate a call to the generic pointer read/write functions */ +void pic16_callGenericPointerRW(int rw, int size) +{ + char buf[32]; + symbol *sym; + + if(size>4) { + werror(W_POSSBUG2, __FILE__, __LINE__); + abort(); + } + + strcpy(buf, port->fun_prefix); + strcat(buf, gptr_fns[size-1][rw]); + + pic16_emitpcode (POC_CALL, pic16_popGetWithString (buf)); + + sym = newSymbol( buf, 0 ); + sym->used++; + strcpy(sym->rname, buf); + checkAddSym(&externs, sym); +} + /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */ diff --git a/src/pic16/genutils.h b/src/pic16/genutils.h index 187bda36..0695c576 100644 --- a/src/pic16/genutils.h +++ b/src/pic16/genutils.h @@ -53,6 +53,11 @@ void pic16_DumpAop(char *prefix, asmop *aop); void pic16_DumpSymbol(char *prefix, symbol *sym); void pic16_DumpOp(char *prefix, operand *op); +pCodeOp *pic16_popGetWithString(char *str); +void pic16_callGenericPointerRW(int rw, int size); + + + void gpsimio2_pcop(pCodeOp *pcop); void gpsimio2_lit(unsigned char lit); diff --git a/src/pic16/glue.c b/src/pic16/glue.c index af1307ab..6898b5c2 100644 --- a/src/pic16/glue.c +++ b/src/pic16/glue.c @@ -1704,9 +1704,11 @@ pic16glue () /* Put all variables into a cblock */ pic16_AnalyzeBanking(); +#if 0 if(pic16_options.opt_flags & OF_LR_SUPPORT) { pic16_OptimizeLocalRegs(); } +#endif /* remove redundant BANKSELs -- added by RN 2005-01-17 */ if(pic16_options.opt_banksel > 1) { diff --git a/src/pic16/main.c b/src/pic16/main.c index 53af64d4..8298c732 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -258,7 +258,7 @@ _process_pragma(const char *sz) while(symname) { ssym = Safe_calloc(1, sizeof(sectSym)); ssym->name = Safe_calloc(1, strlen(symname)+2); - sprintf(ssym->name, "_%s", symname); + sprintf(ssym->name, "%s%s", port->fun_prefix, symname); ssym->reg = NULL; addSet(§Syms, ssym); @@ -694,12 +694,11 @@ _pic16_finaliseOptions (void) { char buf[128]; - sprintf(buf, "-D%s -D%s", pic16->name[2], pic16->name[1]); + sprintf(buf, "-D%s -D__%s", pic16->name[2], pic16->name[1]); *(strrchr(buf, 'f')) = 'F'; addSet(&asmOptionsSet, Safe_strdup( buf )); } - if(STACK_MODEL_LARGE) { addSet(&preArgvSet, Safe_strdup("-DSTACK_MODEL_LARGE")); addSet(&asmOptionsSet, Safe_strdup("-DSTACK_MODEL_LARGE")); diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index d6a4205b..9962f37f 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -4247,6 +4247,32 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx) return pcop; } +pCodeOp *pic16_newpCodeOpRegNotVect(bitVect *bv) +{ + pCodeOp *pcop; + regs *r; + + pcop = Safe_calloc(1, sizeof(pCodeOpReg)); + pcop->name = NULL; + + r = pic16_findFreeReg(REG_GPR); + + while(r) { + if(!bitVectBitValue(bv, r->rIdx)) { + PCOR(pcop)->r = r; + PCOR(pcop)->rIdx = r->rIdx; + pcop->type = r->pc_type; + return (pcop); + } + + r = pic16_findFreeRegNext(REG_GPR, r); + } + + return NULL; +} + + + pCodeOp *pic16_newpCodeOpRegFromStr(char *name) { pCodeOp *pcop; @@ -4950,8 +4976,8 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) (((pCodeOpRegBit *)(PCI(pc)->pcop))->bit )); } else if(PCI(pc)->pcop->type == PO_GPR_BIT) { - SAFE_snprintf(&s,&size,"%s,%d", pic16_get_op_from_instruction(PCI(pc)),PCORB(PCI(pc)->pcop)->bit); - }else + SAFE_snprintf(&s,&size,"%s, %d", pic16_get_op_from_instruction(PCI(pc)),PCORB(PCI(pc)->pcop)->bit); + } else SAFE_snprintf(&s,&size,"%s,0 ; ?bug", pic16_get_op_from_instruction(PCI(pc))); //PCI(pc)->pcop->t.bit ); } else { @@ -4962,21 +4988,23 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) else SAFE_snprintf(&s,&size,"(1 << (%s & 7))",pic16_get_op_from_instruction(PCI(pc))); - }else { - SAFE_snprintf(&s,&size,"%s", pic16_get_op_from_instruction(PCI(pc))); - - if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) { - if(PCI(pc)->num_ops == 3) - SAFE_snprintf(&s,&size,", %c", ( (PCI(pc)->isModReg) ? 'F':'W')); - - r = pic16_getRegFromInstruction(pc); -// fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n", -// __FUNCTION__, __LINE__, r, (r)?r->name:"", (r)?r->accessBank:-1); - - if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED")); - } } + else + { + SAFE_snprintf(&s,&size,"%s", pic16_get_op_from_instruction(PCI(pc))); + } } + if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) { + if(PCI(pc)->num_ops == 3 && !PCI(pc)->isBitInst) + SAFE_snprintf(&s,&size,", %c", ( (PCI(pc)->isModReg) ? 'F':'W')); + + r = pic16_getRegFromInstruction(pc); +// fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n", +// __FUNCTION__, __LINE__, r, (r)?r->name:"", (r)?r->accessBank:-1); + + if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED")); + } +// } break; @@ -4988,7 +5016,7 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) case PC_INFO: SAFE_snprintf(&s,&size,"; info ==>"); - switch(((pCodeInfo *)pc)->type) { + switch( PCINF(pc)->type ) { case INF_OPTIMIZATION: SAFE_snprintf(&s,&size, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]); break; @@ -5244,7 +5272,7 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc) bprev = NULL; - if(pcl->type == PC_OPCODE) + if(pcl->type == PC_OPCODE || pcl->type == PC_INLINE || pcl->type == PC_ASMDIR) b = PCI(pcl)->label; else { fprintf(stderr, "LINE %d. can't unlink from non opcode\n",__LINE__); @@ -6537,7 +6565,7 @@ static pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs) for(pc = pcs; pc; pc = pc->next) { - if(((pc->type == PC_OPCODE) || (pc->type == PC_INLINE)) && + if(((pc->type == PC_OPCODE) || (pc->type == PC_INLINE) || (pc->type == PC_ASMDIR)) && (PCI(pc)->pcop) && (PCI(pc)->pcop->type == PO_LABEL) && (PCOLAB(PCI(pc)->pcop)->key == pcl->key)) @@ -7504,120 +7532,116 @@ static void AnalyzeFlow(int level) static int times_called=0; pBlock *pb; - if(!the_pFile) { - - /* remove unused allocated registers before exiting */ - pic16_RemoveUnusedRegisters(); - - return; - } - + if(!the_pFile) { + /* remove unused allocated registers before exiting */ + pic16_RemoveUnusedRegisters(); + return; + } - /* if this is not the first time this function has been called, - then clean up old flow information */ - if(times_called++) { - for(pb = the_pFile->pbHead; pb; pb = pb->next) - unBuildFlow(pb); - pic16_RegsUnMapLiveRanges(); - } + /* if this is not the first time this function has been called, + * then clean up old flow information */ + if(times_called++) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) + unBuildFlow(pb); + pic16_RegsUnMapLiveRanges(); + } + GpcFlowSeq = 1; - GpcFlowSeq = 1; - - /* Phase 2 - Flow Analysis - Register Banking - * - * In this phase, the individual flow blocks are examined - * and register banking is fixed. - */ + /* Phase 2 - Flow Analysis - Register Banking + * + * In this phase, the individual flow blocks are examined + * and register banking is fixed. + */ #if 0 - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_FixRegisterBanking(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pic16_FixRegisterBanking(pb); #endif - /* Phase 2 - Flow Analysis - * - * In this phase, the pCode is partition into pCodeFlow - * blocks. The flow blocks mark the points where a continuous - * stream of instructions changes flow (e.g. because of - * a call or goto or whatever). - */ + /* Phase 2 - Flow Analysis + * + * In this phase, the pCode is partition into pCodeFlow + * blocks. The flow blocks mark the points where a continuous + * stream of instructions changes flow (e.g. because of + * a call or goto or whatever). + */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_BuildFlow(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pic16_BuildFlow(pb); - /* Phase 2 - Flow Analysis - linking flow blocks - * - * In this phase, the individual flow blocks are examined - * to determine their order of excution. - */ + /* Phase 2 - Flow Analysis - linking flow blocks + * + * In this phase, the individual flow blocks are examined + * to determine their order of excution. + */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) - LinkFlow(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + LinkFlow(pb); - /* Phase 3 - Flow Analysis - Flow Tree - * - * In this phase, the individual flow blocks are examined - * to determine their order of execution. - */ + /* Phase 3 - Flow Analysis - Flow Tree + * + * In this phase, the individual flow blocks are examined + * to determine their order of execution. + */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_BuildFlowTree(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pic16_BuildFlowTree(pb); - /* Phase x - Flow Analysis - Used Banks - * - * In this phase, the individual flow blocks are examined - * to determine the Register Banks they use - */ + /* Phase x - Flow Analysis - Used Banks + * + * In this phase, the individual flow blocks are examined + * to determine the Register Banks they use + */ #if 0 - for(pb = the_pFile->pbHead; pb; pb = pb->next) - FixBankFlow(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + FixBankFlow(pb); #endif - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_pCodeRegMapLiveRanges(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pic16_pCodeRegMapLiveRanges(pb); - pic16_RemoveUnusedRegisters(); + pic16_RemoveUnusedRegisters(); // for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_pCodeRegOptimizeRegUsage(level); - - - if(!options.nopeep) - OptimizepCode('*'); + pic16_pCodeRegOptimizeRegUsage(level); #if 0 - for(pb = the_pFile->pbHead; pb; pb = pb->next) - DumpFlow(pb); + if(!options.nopeep) + OptimizepCode('*'); #endif - /* debug stuff */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - pCode *pcflow; - for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; - pcflow = pcflow->next) { +#if 0 + for(pb = the_pFile->pbHead; pb; pb = pb->next) + DumpFlow(pb); +#endif - FillFlow(PCFL(pcflow)); - } - } + /* debug stuff */ + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + pCode *pcflow; + + for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); + (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; + pcflow = pcflow->next) { + FillFlow(PCFL(pcflow)); + } + } #if 0 - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - pCode *pcflow; - - for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; - pcflow = pcflow->next) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + pCode *pcflow; - FlowStats(PCFL(pcflow)); - } - } + for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); + (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; + pcflow = pcflow->next) { + FlowStats(PCFL(pcflow)); + } + } #endif } @@ -7638,25 +7662,27 @@ void pic16_AnalyzeBanking(void) { pBlock *pb; + /* Phase x - Flow Analysis - Used Banks + * + * In this phase, the individual flow blocks are examined + * to determine the Register Banks they use + */ - /* Phase x - Flow Analysis - Used Banks - * - * In this phase, the individual flow blocks are examined - * to determine the Register Banks they use - */ + AnalyzeFlow(0); + AnalyzeFlow(1); - AnalyzeFlow(0); - AnalyzeFlow(1); + if(!options.nopeep) + OptimizepCode('*'); - if(!the_pFile)return; - if(!pic16_options.no_banksel) { - for(pb = the_pFile->pbHead; pb; pb = pb->next) { -// fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb); - pic16_FixRegisterBanking(pb); - } - } + if(!the_pFile)return; + if(!pic16_options.no_banksel) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) { +// fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb); + pic16_FixRegisterBanking(pb); + } + } } /*-----------------------------------------------------------------*/ @@ -7720,8 +7746,10 @@ static void buildCallTree(void ) if(isPCF(pc)) { if (PCF(pc)->fname) { + char buf[16]; - if(STRCASECMP(PCF(pc)->fname, "_main") == 0) { + sprintf(buf, "%smain", port->fun_prefix); + if(STRCASECMP(PCF(pc)->fname, buf) == 0) { //fprintf(stderr," found main \n"); pb->cmemmap = NULL; /* FIXME do we need to free ? */ pb->dbName = 'M'; @@ -8100,7 +8128,7 @@ static void pBlockStats(FILE *of, pBlock *pb) fprintf(of,";%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' ')); while (r) { - fprintf(of,"; %s\n",r->name); + fprintf(of, "; %s\n",r->name); r = setNextItem(pb->tregisters); } } diff --git a/src/pic16/pcode.h b/src/pic16/pcode.h index 1787df9c..bb2c7613 100644 --- a/src/pic16/pcode.h +++ b/src/pic16/pcode.h @@ -302,7 +302,7 @@ typedef enum PC_CSOURCE, /* C-Source Line */ PC_ASMDIR, /* Assembler directive */ PC_BAD, /* Mark the pCode object as being bad */ - PC_INFO /* pCode informatio node, used primarily in optimizing */ + PC_INFO /* pCode information node, used primarily in optimizing */ } PC_TYPE; @@ -406,6 +406,7 @@ typedef struct pCodeOpBit just a bit of a register */ } pCodeOpBit; #endif + typedef struct pCodeOpLit { pCodeOp pcop; @@ -963,6 +964,7 @@ typedef struct peepCommand { #define isPCW(x) ((PCODE(x)->type == PC_WILD)) #define isPCCS(x) ((PCODE(x)->type == PC_CSOURCE)) #define isPCAD(x) ((PCODE(x)->type == PC_ASMDIR)) +#define isPCINFO(x) ((PCODE(x)->type == PC_INFO)) #define isCALL(x) ((isPCI(x)) && (PCI(x)->op == POC_CALL)) #define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS) @@ -1012,11 +1014,13 @@ pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace, PIC_OPTYPE subt pCodeOp *pic16_newpCodeOpRegFromStr(char *name); pCodeOp *pic16_newpCodeOpReg(int rIdx); pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p); +pCodeOp *pic16_newpCodeOpRegNotVect(bitVect *bv); pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop); pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop); pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key); pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type); +pCodeOp *pic16_newpCodeOpReg(int rIdx); pCode * pic16_findNextInstruction(pCode *pci); pCode * pic16_findNextpCode(pCode *pc, PC_TYPE pct); @@ -1031,6 +1035,9 @@ extern void pic16_pcode_test(void); extern int pic16_debug_verbose; extern int pic16_pcode_verbose; +extern char *LR_TYPE_STR[]; + + #ifndef debugf //#define debugf(frm, rest...) _debugf(__FILE__, __LINE__, frm, rest) #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) diff --git a/src/pic16/pcodepeep.c b/src/pic16/pcodepeep.c index ecd6e11d..07fbf87e 100644 --- a/src/pic16/pcodepeep.c +++ b/src/pic16/pcodepeep.c @@ -1739,7 +1739,7 @@ int pic16_pCodeSearchCondition(pCode *pc, unsigned int cond) *-----------------------------------------------------------------*/ static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) { - char b[128], *n2; + char b[1024], *n2; if(!pcops || !pcopd) return 0; @@ -1765,8 +1765,8 @@ static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) return 0; } - b[0]=0; - pic16_get_op(pcops,b,128); + memset(b, 0, sizeof(b) ); //b[0]=0; + pic16_get_op(pcops,b, sizeof(b) ); n2 = pic16_get_op(pcopd,NULL,0); @@ -2438,16 +2438,16 @@ int pic16_pCodePeepMatchRule(pCode *pc) pcin->prev = pc->prev; -#if 0 +#if 1 { /* DEBUG */ /* Converted the deleted pCodes into comments */ - char buf[256]; + char buf[1024]; pCodeCSource *pc_cline2=NULL; - buf[0] = ';'; - buf[1] = '#'; +// buf[0] = ';'; + buf[0] = '#'; while(pc && pc!=pcin) { @@ -2461,7 +2461,7 @@ int pic16_pCodePeepMatchRule(pCode *pc) } } - pic16_pCode2str(&buf[2], 254, pc); + pic16_pCode2str(&buf[1], sizeof( buf )-1, pc); pic16_pCodeInsertAfter(pcprev, pic16_newpCodeCharP(buf)); pcprev = pcprev->next; pc = pc->next; diff --git a/src/pic16/pcoderegs.c b/src/pic16/pcoderegs.c index ffa28c93..ee9a2b52 100644 --- a/src/pic16/pcoderegs.c +++ b/src/pic16/pcoderegs.c @@ -289,8 +289,10 @@ static void Remove1pcode(pCode *pc, regs *reg) if(pcn) { if(PCI(pcn)->cline) { - //fprintf(stderr, "source line has been optimized completely out\n"); - //pc->print(stderr,pc); +#if 0 + fprintf(stderr, "source line has been optimized completely out\n"); + pc->print(stderr,pc); +#endif } else { PCI(pcn)->cline = PCI(pc)->cline; } @@ -400,6 +402,67 @@ void pic16_RemoveUnusedRegisters(void) fprintf(stderr, " *** Saved %d registers ***\n", total_registers_saved); } +static int insideLRBlock(pCode *pc) +{ + pCode *pc1; + int t1=-1, t2=-1; + + pc1 = pc->prev; + while(pc1) { + if(isPCINFO(pc1) && (PCINF(pc1)->type == INF_LOCALREGS)) { + t1 = PCOLR (PCINF (pc1)->oper1)->type; + break; + } + pc1 = pc1->prev; + } + + pc1 = pc->next; + while(pc1) { + if(isPCINFO(pc1) && (PCINF(pc1)->type == INF_LOCALREGS)) { + t2 = PCOLR (PCINF (pc1)->oper1)->type; + break; + } + } + + if((t1 == LR_ENTRY_BEGIN && t2 == LR_ENTRY_END) + || (t1 == LR_EXIT_BEGIN && t2 == LR_EXIT_END)) + return 1; + + return 0; +} + + +static void RemoveRegFromLRBlock(regs *reg) +{ + if(elementsInSet(reg->reglives.usedpCodes) == 2) { + pCode *pc1; + + /* only continue if there are just 2 uses of the register, + * in in the local *entry* block and one in the local *exit* block */ + + /* search for entry block */ + pc1 = indexSet(reg->reglives.usedpCodes, 1); + + if(insideLRBlock( pc1 )) { + fprintf(stderr, "usedpCodes[0] inside LR block\n"); + deleteSetItem(&pc1->pb->tregisters, PCOR(PCI(pc1)->pcop)->r); + Remove1pcode(pc1, reg); + } + + pc1 = indexSet(reg->reglives.usedpCodes, 0); + if(insideLRBlock( pc1 )) { + fprintf(stderr, "usedpCodes[1] inside LR block\n"); + deleteSetItem(&pc1->pb->tregisters, PCOR(PCI(pc1)->pcop)->r); + Remove1pcode(pc1, reg); + } + + /* remove r0x00 */ + reg->isFree = 1; + reg->wasUsed = 0; + } +} + + /*-----------------------------------------------------------------* * @@ -430,6 +493,15 @@ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg, int } pCodeRegMapLiveRangesInFlow(PCFL(pcflow)); + +#if 1 +// fprintf(stderr, "register %s is used in %d pCodes, assigned in %d pCodes\n", reg->name, +// elementsInSet(reg->reglives.usedpCodes), +// elementsInSet(reg->reglives.assignedpFlows)); + + RemoveRegFromLRBlock(reg); +#endif + } /*-----------------------------------------------------------------* @@ -446,6 +518,13 @@ static int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg) return 1; } + if(PCI(pc1)->is2MemOp) { + testreg = pic16_getRegFromInstruction2(pc1); + if(testreg && (testreg->rIdx == reg->rIdx)) { + return 1; + } + } + pc1 = pic16_findNextInstruction(pc1->next); } while (pc1 && (pc1 != pc2) && (i++ < 100)) ; @@ -595,19 +674,19 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re if(usesW(pct3)) ; // Remove2pcodes(pcfl_used, pc1, NULL, reg, can_free); - else + else { Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); - - total_registers_saved++; // debugging stats. - return 1; - } else { - //fprintf(stderr,"didn't optimize because Z bit is used\n"); - } + total_registers_saved++; // debugging stats. + return 1; + } + } else { +// fprintf(stderr,"didn't optimize because Z bit is used\n"); + } } #if 0 fprintf(stderr, " couldn't optimize\n"); if(reg2) - fprintf(stderr, " %s is used in range\n",reg2->name); + fprintf(stderr, " %s is used in range\n", reg2->name); else fprintf(stderr, " reg2 is NULL\n"); #endif @@ -622,10 +701,11 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re reg1 = pic16_getRegFromInstruction(pct1); if(reg1 && !regUsedinRange(pc1,pc2,reg1)) { - /* + +#if 0 fprintf(stderr, " MOVF/MOVFW. \n"); fprintf(stderr, " ...optimizing\n"); - */ +#endif /* Change: @@ -851,42 +931,44 @@ void pic16_pCodeRegOptimizeRegUsage(int level) int saved = 0; int t = total_registers_saved; - if(!register_optimization) - return; + if(getenv("NO_REG_OPT")) + return; -#define OPT_PASSES 4 - passes = OPT_PASSES; + if(!register_optimization) + return; - do { - saved = total_registers_saved; +#define OPT_PASSES 8 + passes = OPT_PASSES; - /* Identify registers used in one flow sequence */ - OptimizeRegUsage(pic16_dynAllocRegs,level, (OPT_PASSES-passes)); - OptimizeRegUsage(pic16_dynStackRegs,level, (OPT_PASSES-passes)); - OptimizeRegUsage(pic16_dynDirectRegs,0, (OPT_PASSES-passes)); + do { + saved = total_registers_saved; - if((total_registers_saved != saved) - && (pic16_pcode_verbose)) - fprintf(stderr, " *** pass %d, Saved %d registers, total saved %d ***\n", - (1+OPT_PASSES-passes),total_registers_saved-saved,total_registers_saved); - - passes--; + /* Identify registers used in one flow sequence */ + OptimizeRegUsage(pic16_dynAllocRegs,level, (OPT_PASSES-passes)); + OptimizeRegUsage(pic16_dynStackRegs,level, (OPT_PASSES-passes)); + OptimizeRegUsage(pic16_dynDirectRegs,0, (OPT_PASSES-passes)); - } while( passes && ((total_registers_saved != saved) || (passes==OPT_PASSES-1)) ); + if((total_registers_saved != saved) + && (pic16_pcode_verbose)) + fprintf(stderr, " *** pass %d, Saved %d registers, total saved %d ***\n", + (1+OPT_PASSES-passes),total_registers_saved-saved,total_registers_saved); + + passes--; - if(total_registers_saved == t) + } while( passes && ((total_registers_saved != saved) || (passes==OPT_PASSES-1)) ); - if(pic16_debug_verbose) - fprintf(stderr, "No registers saved on this pass\n"); + if(total_registers_saved == t) + if(pic16_debug_verbose) + fprintf(stderr, "No registers saved on this pass\n"); #if 0 - fprintf(stderr,"dynamically allocated regs:\n"); - dbg_regusage(pic16_dynAllocRegs); - fprintf(stderr,"stack regs:\n"); - dbg_regusage(pic16_dynStackRegs); - fprintf(stderr,"direct regs:\n"); - dbg_regusage(pic16_dynDirectRegs); + fprintf(stderr,"dynamically allocated regs:\n"); + dbg_regusage(pic16_dynAllocRegs); + fprintf(stderr,"stack regs:\n"); + dbg_regusage(pic16_dynStackRegs); + fprintf(stderr,"direct regs:\n"); + dbg_regusage(pic16_dynDirectRegs); #endif } @@ -902,7 +984,6 @@ static void RegsSetUnMapLiveRanges(set *regset) while(regset) { reg = regset->item; regset = regset->next; - deleteSet(®->reglives.usedpCodes); deleteSet(®->reglives.usedpFlows); @@ -914,12 +995,10 @@ static void RegsSetUnMapLiveRanges(set *regset) void pic16_RegsUnMapLiveRanges(void) { - RegsSetUnMapLiveRanges(pic16_dynAllocRegs); RegsSetUnMapLiveRanges(pic16_dynStackRegs); RegsSetUnMapLiveRanges(pic16_dynDirectRegs); RegsSetUnMapLiveRanges(pic16_dynProcessorRegs); RegsSetUnMapLiveRanges(pic16_dynDirectBitRegs); RegsSetUnMapLiveRanges(pic16_dynInternalRegs); - } diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 829ba99d..c324c470 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -314,6 +314,7 @@ pic16_decodeOp (unsigned int op) case LABEL: return "LABEL"; case RECEIVE: return "RECEIVE"; case SEND: return "SEND"; + case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE"; } sprintf (buffer, "unkown op %d %c", op, op & 0xff); @@ -446,6 +447,26 @@ regFindFree (set *dRegs) return NULL; } + +static regs * +regFindFreeNext(set *dRegs, regs *creg) +{ + regs *dReg; + + if(creg) { + /* position at current register */ + for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs)); + } + + for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) { + if(dReg->isFree) { + return dReg; + } + } + + return NULL; +} + /*-----------------------------------------------------------------*/ /* pic16_initStack - allocate registers for a pseudo stack */ /*-----------------------------------------------------------------*/ @@ -1089,6 +1110,33 @@ pic16_findFreeReg(short type) return NULL; } } + +regs * +pic16_findFreeRegNext(short type, regs *creg) +{ + // int i; + regs* dReg; + + switch (type) { + case REG_GPR: + if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL) + return dReg; + return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL))); + + case REG_STK: + + if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL) + return dReg; + + return NULL; + + case REG_PTR: + case REG_CND: + case REG_SFR: + default: + return NULL; + } +} /*-----------------------------------------------------------------*/ /* freeReg - frees a register */ /*-----------------------------------------------------------------*/ @@ -2932,13 +2980,32 @@ farSpacePackable (iCode * ic) return NULL; } +#if 0 +static int packRegsForPointerGet(iCode *ic, eBBlock *ebp) +{ + iCode *dic, *sic; + + debugLog ("%d\t%s\n", __LINE__, __FUNCTION__); + debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) ); + debugAopGet (" result:", IC_RESULT (ic)); + debugAopGet (" left:", IC_LEFT (ic)); + debugAopGet (" right:", IC_RIGHT (ic)); + + dic = ic->prev; + if((dic->op == '=') + && ( +} +#endif + + +void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst); + /*-----------------------------------------------------------------*/ /* packRegsForAssign - register reduction for assignment */ /*-----------------------------------------------------------------*/ static int packRegsForAssign (iCode * ic, eBBlock * ebp) { - iCode *dic, *sic; debugLog ("%d\t%s\n", __LINE__, __FUNCTION__); @@ -3111,34 +3178,34 @@ pack: /* found the definition */ /* replace the result with the result of */ /* this assignment and remove this assignment */ - bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); - IC_RESULT (dic) = IC_RESULT (ic); - if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) - { - OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq; - } - /* delete from liverange table also - delete from all the points inbetween and the new - one */ - for (sic = dic; sic != ic; sic = sic->next) - { - bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key); - if (IS_ITEMP (IC_RESULT (dic))) - bitVectSetBit (sic->rlive, IC_RESULT (dic)->key); - } - - remiCodeFromeBBlock (ebp, ic); - bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); + IC_RESULT (dic) = IC_RESULT (ic); - debugLog(" %d\n", __LINE__ ); - hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); - return 1; + if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) + { + OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq; + } + /* delete from liverange table also + delete from all the points inbetween and the new + one */ + for (sic = dic; sic != ic; sic = sic->next) + { + bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key); + if (IS_ITEMP (IC_RESULT (dic))) + bitVectSetBit (sic->rlive, IC_RESULT (dic)->key); + } + remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + debugLog(" %d\n", __LINE__ ); + hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); + OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); } + #if 1 #define NO_packRegsForAccUse @@ -3977,13 +4044,58 @@ pic16_packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; } + +#if 0 + /* if this is an arithmetic operation + * && result or left is not rematerializable (so it is a plain arithmetic op) + * && and left is not used after this iCode */ + + if(getenv("OPTIMIZE_NEAR_POINTER_GET")) + + if (IS_ARITHMETIC_OP(ic) + && !IS_OP_LITERAL (IC_LEFT (ic)) + && !OP_SYMBOL (IC_RESULT(ic))->rematiCode + && !OP_SYMBOL (IC_LEFT(ic))->rematiCode + && (OP_LIVETO (IC_LEFT(ic) ) <= ic->seq) + ) { + iCode *dic = ic->prev; + + /* search backwards to find assignment from a remat pointer */ + while(dic && dic->seq >= OP_LIVEFROM( IC_LEFT(ic) )) { + + /* is it a pointer_get? */ + if(POINTER_GET(dic) + && IS_DATA_PTR(OP_SYM_TYPE (IC_LEFT (dic)))) { + fprintf(stderr, "%s:%d `%s' is a data pointer (ic seq: %d)\n", __FILE__, __LINE__, + OP_SYMBOL(IC_LEFT(dic))->rname, dic->seq); + + /* so we can replace ic->left with dic->left, & remove assignment */ + ReplaceOpWithCheaperOp( &IC_LEFT(ic), IC_LEFT(dic) ); + + bitVectUnSetBit(OP_USES( IC_LEFT(ic) ), ic->key); + bitVectUnSetBit(OP_DEFS( IC_RESULT(dic) ), dic->key ); + +// dic->op = DUMMY_READ_VOLATILE; +#if 1 + remiCodeFromeBBlock(ebp, dic); + hTabDeleteItem(&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); +#endif + break; + } + dic = dic->prev; + } + } +#endif + /* mark the pointer usages */ if (POINTER_SET (ic)) { OP_SYMBOL (IC_RESULT (ic))->uptr = 1; debugLog (" marking as a pointer (set) =>"); debugAopGet (" result:", IC_RESULT (ic)); + } + if (POINTER_GET (ic)) { if(IS_SYMOP(IC_LEFT(ic))) { diff --git a/src/pic16/ralloc.h b/src/pic16/ralloc.h index 1c9d126b..756e31be 100644 --- a/src/pic16/ralloc.h +++ b/src/pic16/ralloc.h @@ -118,6 +118,7 @@ regs *pic16_regWithName(char *name); void pic16_freeAllRegs (); void pic16_deallocateAllRegs (); regs *pic16_findFreeReg(short type); +regs *pic16_findFreeRegNext(short type, regs *creg); regs *pic16_allocWithIdx (int idx); regs *pic16_allocDirReg (operand *op ); -- 2.30.2