2 * crt0i.c - SDCC pic16 port runtime start code with
5 * Converted for SDCC and pic16 port
6 * by Vangelis Rokas (vrokas@otenet.gr)
8 * based on Microchip MPLAB-C18 startup files
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2, or (at your option) any
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * In other words, you are welcome to use, share and improve this program.
25 * You are forbidden to forbid anyone else to use, share and improve
26 * what you give them. Help stamp out software-hoarding!
28 * $Id: crt0i.c 5183 2008-05-26 18:55:44Z tecodev $
42 /* global variable for forcing gplink to add _cinit section */
46 /* external reference to the user's main routine */
47 extern void main (void);
49 void _entry (void) __naked __interrupt 0;
50 void _startup (void) __naked;
51 void _do_cinit (void) __naked;
53 /* Access bank selector. */
58 * entry function, placed at interrupt vector 0 (RESET)
60 void _entry (void) __naked __interrupt 0
67 void _startup (void) __naked
70 ; Initialize the stack pointer
74 ; 1st silicon does not do this on POR
77 ; Initialize the flash memory access configuration.
78 ; This is harmless for non-flash devices, so we do it on all parts.
79 bsf 0xa6, 7, a ; EECON1.EEPGD = 1, TBLPTR accesses program memory
80 bcf 0xa6, 6, a ; EECON1.CFGS = 0, TBLPTR accesses program memory
83 /* Initialize global and/or static variables. */
86 /* Call the main routine. */
91 ; Returning from main will lock up.
97 /* the cinit table will be filled by the linker */
98 extern __code struct {
99 unsigned short num_init;
108 #define TBLRDPOSTINC tblrd*+
110 #define prom 0x00 /* 0x00 0x01 0x02*/
111 #define curr_byte 0x03 /* 0x03 0x04 */
112 #define curr_entry 0x05 /* 0x05 0x06 */
113 #define data_ptr 0x07 /* 0x07 0x08 0x09 */
115 /* the variable initialisation routine */
116 void _do_cinit (void) __naked
119 * access registers 0x00 - 0x09 are not saved in this function
130 ; curr_entry = cinit.num_init
137 movwf curr_entry + 1, a
140 movf curr_entry, w, a
143 movf curr_entry + 1, w, a
147 ; Count down so we only have to look up the data in _cinit once.
149 ; At this point we know that TBLPTR points to the top of the current
150 ; entry in _cinit, so we can just start reading the from, to, and
153 ; read the source address low
158 ; source address high
163 ; source address upper
168 ; skip a byte since it is stored as a 32bit int
171 ; read the destination address directly into FSR0
172 ; destination address low
177 ; destination address high
182 ; skip two bytes since it is stored as a 32bit int
186 ; read the size of data to transfer to destination address
193 movwf curr_byte + 1, a
195 ; skip two bytes since it is stored as a 32bit int
199 ; prom = data_ptr->from;
200 ; FSR0 = data_ptr->to;
201 ; curr_byte = (unsigned short) data_ptr->size;
203 ; the table pointer now points to the next entry. Save it
204 ; off since we will be using the table pointer to do the copying
208 movff _TBLPTRL, data_ptr
209 movff _TBLPTRH, data_ptr + 1
210 movff _TBLPTRU, data_ptr + 2
212 ; now assign the source address to the table pointer
215 movff prom + 1, _TBLPTRH
216 movff prom + 2, _TBLPTRU
222 movf curr_byte + 1, w, a
230 ; decrement byte counter
233 decf curr_byte + 1, f, a
237 ; restore the table pointer for the next entry
239 movff data_ptr, _TBLPTRL
240 movff data_ptr + 1, _TBLPTRH
241 movff data_ptr + 2, _TBLPTRU
243 ; decrement entry counter
244 decf curr_entry, f, a
246 decf curr_entry + 1, f, a