+2005-03-31 Vangelis Rokas <vrokas AT users.sourceforge.net>
+
+ * 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 <epetrich AT ivorytower.norman.ok.us>
* src/SDCCBBlock.c (iCodeBreakDown): fixed bug #1170212
#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
--- /dev/null
+
+/*
+ * delay.h - delay functions header file
+ *
+ * adopted for SDCC and pic16 port by Vangelis Rokas, 2005 <vrokas AT 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
+ * 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
*
* 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$
*/
#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__ */
--- /dev/null
+#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
#endif
+
+#define Nop() { _asm nop _endasm; }
+#define ClrWdt() { _asm clrwdt _endasm; }
+#define Sleep() { _asm sleep _endasm; }
+#define Reset() { _asm reset _endasm; }
+
+
#endif /* __PIC18FREGS_H__ */
--- /dev/null
+/*-------------------------------------------------------------------------
+ stdint.h - ISO C99 7.18 Integer types <stdint.h>
+
+ 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 */
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:
+ * <stream> <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);
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 */
DIRS = ctype \
+ delay \
stdlib \
stdio \
string \
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
--- /dev/null
+#
+# 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 <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
+# 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)
+
--- /dev/null
+
+ include <p18fxxx.inc>
+
+ 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
--- /dev/null
+
+ include <p18fxxx.inc>
+
+ 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
--- /dev/null
+
+ include <p18fxxx.inc>
+
+ 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
--- /dev/null
+
+ include <p18fxxx.inc>
+
+ 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
--- /dev/null
+
+ include <p18fxxx.inc>
+
+ 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
--- /dev/null
+
+ include <p18fxxx.inc>
+
+ 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
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)
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <stdarg.h>
+#include <stdio.h>
+
+
+#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);
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <stdarg.h>
+#include <stdio.h>
+
+#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);
+}
#include <stdio.h>
#include <stdlib.h>
-void printf_small(char *fmt, ...)
+void printf_small(char *fmt, ...) reentrant
{
char *ch;
char radix;
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;
while( *ch ) { //for (; *fmt ; fmt++ )
if (*ch == '%') {
- flong = 0; fstr = 0; fchar = 0;
- ffloat = 0;
+ flong = fstr = fchar = ffloat = 0;
radix = 0;
ch++;
/* 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
%s character generic pointer
*/
+#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
+#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);
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <stdarg.h>
+#include <stdio.h>
+
+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);
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <stdio.h>
+
+FILE *stdout = STREAM_USER;
+FILE *stdin = STREAM_USER;
--- /dev/null
+/*-----------------------------------------------------------------
+ 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;
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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;
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <stdio.h>
+
+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 */
+ }
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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;
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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);
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <stdarg.h>
+#include <stdio.h>
+
+unsigned vprintf(char *fmt, va_list ap)
+{
+ unsigned int i;
+
+ i = vfprintf(stdout, fmt, ap);
+
+ return (i);
+}
--- /dev/null
+/*-----------------------------------------------------------------
+ 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 <stdarg.h>
+#include <stdio.h>
+
+
+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);
+}
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)
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) {
s++;
}
- sign = (*s == '-');
+ if(*s == '-')sign=1;
+
+// sign = (*s == '-');
if (*s == '-' || *s == '+') s++;
while (*s && *s >= '0' && *s <= '9') {
s++;
}
- return (sign ? -rv : rv);
+ if(sign)return (-rv);
+ else return (rv);
+
+// return (sign ? -rv : rv);
}
/*
- * 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 <malloc.h>
-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);
}
/*
- * 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 <malloc.h>
-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;
}
--- /dev/null
+;--
+;
+; 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
#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);
+}
*
* 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 <malloc.h>
-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);
- }
}
--- /dev/null
+/*
+ * memfree.c - return size of all unallocated heap
+ *
+ * written by Vangelis Rokas <vrokas AT otenet.gr> 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 <malloc.h>
+
+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);
+}
--- /dev/null
+/*
+ * memfreemax.c - return size of maximum unallocated heap block
+ *
+ * written by Vangelis Rokas <vrokas AT otenet.gr> 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 <malloc.h>
+
+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);
+}
--- /dev/null
+/*
+ * memmisc.c - heap handling functions
+ *
+ * written by Vangelis Rokas, 2005 <vrokas AT 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>
+
+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);
+ }
+}
*
* 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
* 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
/*
- * 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 <malloc.h>
-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));
}
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)
; $Id$
;
radix dec
- list p=18f452
+ list
nolist
;
radix dec
- list p=18f452
+ list
nolist
PROCESSORS = $(MCUS)
-DIRS = adc i2c
+DIRS = adc i2c usart
LOBJS = $(patsubst %,%/*.o,$(DIRS))
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
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))
$(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
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 \
#
-# Makefile - Makefile to build pic16 C Library
+# Makefile - Makefile to build pic16 AD convertion library
#
# This file is part of the GNU PIC Library.
#
# The GNU PIC Library is maintained by,
# Vangelis Rokas <vrokas@otenet.gr>
#
-# $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
#include <adc.h>
-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
}
-#include <pic18fregs.h>
+/*
+ * adcclose - shutdown AD module
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
#include <adc.h>
void adc_close(void)
{
- ADCON0bits.ADON = 0;
- PIE1bits.ADIE = 0;
+ ADCON0bits.ADON = 0;
+ PIE1bits.ADIE = 0;
}
+/*
+ * adcconv - begin a convertion
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
#include <adc.h>
void adc_conv(void)
{
- ADCON0bits.GO = 1;
+ ADCON0bits.GO = 1;
}
+/*
+ * adcopen - initialize AD module
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
#include <adc.h>
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;
}
+/*
+ * adcread - read value of convertion
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
#include <adc.h>
-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;
}
+/*
+ * adcsetch - select convertion channel
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
#include <adc.h>
-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
}
unsigned char i2c_drdy(void)
{
- if(SSPSTATbits.BF)
- return (+1);
- else
- return (0);
+ if(SSPSTATbits.BF)return (+1);
+ else return (0);
}
--- /dev/null
+#
+# 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 <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
+# 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)
+
--- /dev/null
+
+/*
+ * ubaud - set baud value
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+void usart_baud(unsigned char baudconfig) wparam
+{
+ BAUDREG = baudconfig;
+}
--- /dev/null
+
+/*
+ * ubusy - return USART TX state
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+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
+}
--- /dev/null
+
+/*
+ * uclose - shutdown USART module
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+void usart_close(void)
+{
+ RCSTA &= 0x4f;
+ TXSTAbits.TXEN = 0;
+ PIE1 &= 0xcf;
+}
--- /dev/null
+
+/*
+ * udrdy - return 1 is data is received
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+
+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
+}
--- /dev/null
+
+/*
+ * ugetc - get received character
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+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);
+}
--- /dev/null
+
+/*
+ * ugets - read string from USART
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+void usart_gets(RAM_SCLS char *buffer, unsigned char len)
+{
+ unsigned char i;
+ unsigned char dat;
+
+ for(i=0;i<len;i++)
+ {
+ while(!usart_drdy());
+
+ dat = usart_getc();
+ *buffer = dat;
+ buffer++;
+
+ /* read until a \0 is received */
+ if(!dat)return;
+ }
+}
--- /dev/null
+
+/*
+ * uopen - initialize USART module
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+// 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;
+}
--- /dev/null
+
+/*
+ * uputc - write a character to USART
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+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
+}
--- /dev/null
+
+/*
+ * uputs - put a string to USART
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+void usart_puts(char *dat)
+{
+ do {
+ while( usart_busy() );
+ usart_putc( *dat );
+ } while( *dat++ );
+}
--- /dev/null
+
+/*
+ * usartd - status variable definition
+ *
+ * written by Vangelis Rokas, 2004 <vrokas AT otenet.gr>
+ *
+ * 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 <pic18fregs.h>
+
+#include <usart.h>
+
+union USART USART_Status;
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
modschar \
moduchar
+#SRCS =
+
+# modschar \
+# moduchar
+
+#AS_SRCS = divchar \
+# modchar
+
+
include ../Makefile.rules
else \
$(AR) -r $(LIB) $$object ; \
fi; \
- echo adding $$object ; \
+ echo -n "$$object " ; \
done ;
+ @echo
+
\ No newline at end of file
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;
}
#include <sdcc-lib.h>
-#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
{
if (reste >= b)
{
reste -= b;
+
// a <- (result = 1)
a |= 1;
}
}
while (--count);
+
return a;
}
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;
}
#include <sdcc-lib.h>
-#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;
}
count++;
}
+
do
{
if (a >= b)
build-library: $(LIB)
-$(LIB): $(OFILES) clean-intermediate-no-asm
+$(LIB): $(OFILES)
@echo Creating $(LIB) ...
@for object in $(OFILES) ; do \
if [ ! -e $(LIB) ]; then \
else \
$(AR) -r $(LIB) $$object ; \
fi; \
- echo adding $$object ; \
+ echo -n "$$object " ; \
done ;
+ @echo
long l;
};
+#define volatile
+
/* convert float to unsigned long */
unsigned long __fs2ulong (float a1) _FS_REENTRANT
{
return l;
}
-
-
-
-
# 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))
/*
* 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$
*/
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;
}
*
* 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$
*/
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);
void _startup (void) _naked;
/* prototype for the initialized data setup */
-void _do_cinit (void);
+void _do_cinit (void) _naked;
/*
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;
}
} 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;
}
*
* 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$
*/
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);
void _startup (void) _naked;
/* prototype for the initialized data setup */
-void _do_cinit (void);
+void _do_cinit (void) _naked;
/*
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;
}
} 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;
}
======================================================================
======================================================================
+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
static PIC16_device Pics16[] = {
// {
-// {"p18f242", "18f242", "pic18f242", "f242"}, // aliases
+// {"p18f242", "18f242", "pic18f242", "f242", "18F242"}, // aliases
// 0,
// 0x300, // RAMsize
// 0,
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,
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,
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,
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,
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,
{ 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,
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,
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,
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 */ }
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 */ }
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,
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,
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 */ }
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 */ }
(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;
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;i<aop->size;i++)
aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
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);
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 ));
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);
}
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;
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;
}
pic16_emitcode("","%s:",sym->rname);
pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
-
{
absSym *ab;
}
}
-
if(IFFUNC_ISNAKED(ftype)) {
DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
return;
}
} else {
-
/* unsigned compare */
DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
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 );
{
int size, offset, lit;
sym_link *retype = getSpec(operandType(result));
- char fgptrget[32];
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_aopOp(left,ic,FALSE);
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;
}
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 );
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 );
{
int size;
sym_link *retype = getSpec(operandType(right));
- char fgptrput[32];
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
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);
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__)
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 */
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);
/* 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) {
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);
{
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"));
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;
(((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 {
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:"<null>", (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:"<null>", (r)?r->accessBank:-1);
+
+ if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED"));
+ }
+//
}
break;
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;
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__);
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))
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
}
{
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);
+ }
+ }
}
/*-----------------------------------------------------------------*/
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';
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);
}
}
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;
just a bit of a register */
} pCodeOpBit;
#endif
+
typedef struct pCodeOpLit
{
pCodeOp pcop;
#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)
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);
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)
*-----------------------------------------------------------------*/
static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
{
- char b[128], *n2;
+ char b[1024], *n2;
if(!pcops || !pcopd)
return 0;
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);
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) {
}
}
- 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;
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;
}
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;
+ }
+}
+
+
/*-----------------------------------------------------------------*
*
}
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
+
}
/*-----------------------------------------------------------------*
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)) ;
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
reg1 = pic16_getRegFromInstruction(pct1);
if(reg1 && !regUsedinRange(pc1,pc2,reg1)) {
- /*
+
+#if 0
fprintf(stderr, " MOVF/MOVFW. \n");
fprintf(stderr, " ...optimizing\n");
- */
+#endif
/*
Change:
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
}
while(regset) {
reg = regset->item;
regset = regset->next;
-
deleteSet(®->reglives.usedpCodes);
deleteSet(®->reglives.usedpFlows);
void pic16_RegsUnMapLiveRanges(void)
{
-
RegsSetUnMapLiveRanges(pic16_dynAllocRegs);
RegsSetUnMapLiveRanges(pic16_dynStackRegs);
RegsSetUnMapLiveRanges(pic16_dynDirectRegs);
RegsSetUnMapLiveRanges(pic16_dynProcessorRegs);
RegsSetUnMapLiveRanges(pic16_dynDirectBitRegs);
RegsSetUnMapLiveRanges(pic16_dynInternalRegs);
-
}
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);
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 */
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
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__);
/* 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
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))) {
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 );