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!
44 /* global variable for forcing gplink to add _cinit section */
48 /* external reference to the user's main routine */
49 extern void main (void);
51 /* prototype for the startup function */
52 void _entry (void) __naked __interrupt 0;
53 void _startup (void) __naked;
55 /* prototype for the initialized data setup */
56 void _do_cinit (void) __naked;
60 * entry function, placed at interrupt vector 0 (RESET)
63 void _entry (void) __naked __interrupt 0
65 __asm goto __startup __endasm;
69 void _startup (void) __naked
72 // Initialize the stack pointer
75 clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
77 // initialize the flash memory access configuration. this is harmless
78 // for non-flash devices, so we do it on all parts.
86 /* Call the user's main routine */
90 /* return from main will lock up */
95 /* the cinit table will be filled by the linker */
98 unsigned short num_init;
107 #define TBLRDPOSTINC tblrd*+
109 #define prom 0x00 /* 0x00 0x01 0x02*/
110 #define curr_byte 0x03 /* 0x03 0x04 */
111 #define curr_entry 0x05 /* 0x05 0x06 */
112 #define data_ptr 0x07 /* 0x07 0x08 0x09 */
115 * static short long _do_cinit_prom;
116 * static unsigned short _do_cinit_curr_byte;
117 * static unsigned short _do_cinit_curr_entry;
118 * static short long _do_cinit_data_ptr;
121 /* the variable initialisation routine */
122 void _do_cinit (void) __naked
125 * access registers 0x00 - 0x09 are not saved in this function
136 ; curr_entry = cinit.num_init
146 ; while (curr_entry) {
157 ; Count down so we only have to look up the data in _cinit once.
159 ; At this point we know that TBLPTR points to the top of the current
160 ; entry in _cinit, so we can just start reading the from, to, and
163 ; read the source address low
168 ; source address high
173 ; source address upper
178 ; skip a byte since it is stored as a 32bit int
181 ; read the destination address directly into FSR0
182 ; destination address low
187 ; destination address high
192 ; skip two bytes since it is stored as a 32bit int
196 ; read the size of data to transfer destination address
205 ; skip two bytes since it is stored as a 32bit int
209 ; prom = data_ptr->from;
210 ; FSR0 = data_ptr->to;
211 ; curr_byte = (unsigned short) data_ptr->size;
213 ; the table pointer now points to the next entry. Save it
214 ; off since we will be using the table pointer to do the copying
219 movff _TBLPTRL, data_ptr
220 movff _TBLPTRH, data_ptr + 1
221 movff _TBLPTRU, data_ptr + 2
223 ; now assign the source address to the table pointer
227 movff prom + 1, _TBLPTRH
228 movff prom + 2, _TBLPTRU
232 ; determine if we have any more bytes to copy
237 bnz copy_one_byte ; copy_one_byte
238 movf curr_byte + 1, w
248 ; decrement byte counter
250 bc copy_loop ; copy_loop
251 decf curr_byte + 1, f
257 ; restore the table pointer for the next entry
259 movff data_ptr, _TBLPTRL
260 movff data_ptr + 1, _TBLPTRH
261 movff data_ptr + 2, _TBLPTRU
265 decf curr_entry + 1, f
270 ; _do_cinit_curr_entry--;