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
24 /* global variable for forcing gplink to add _cinit section */
27 /* external reference to the user's main routine */
28 extern void main (void);
30 /* prototype for the startup function */
31 void _entry (void) _naked interrupt 0;
32 void _startup (void) _naked;
34 /* prototype for the initialized data setup */
35 void _do_cinit (void);
39 * entry function, placed at interrupt vector 0 (RESET)
42 void _entry (void) _naked interrupt 0
44 _asm goto __startup _endasm;
48 void _startup (void) _naked
51 // Initialize the stack pointer
54 clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
56 // initialize the flash memory access configuration. this is harmless
57 // for non-flash devices, so we do it on all parts.
65 /* Call the user's main routine */
69 /* return from main will lock up */
74 /* the cinit table will be filled by the linker */
77 unsigned short num_init;
86 #define tblrdpostinc tblrd*+
89 /* the variable initialisation routine */
93 * we'll make the assumption in the following code that these statics
94 * will be allocated into the same bank.
96 static short long prom;
97 static unsigned short curr_byte;
98 static unsigned short curr_entry;
99 static short long data_ptr;
102 /* TBLPTR = &cinit */
113 /* curr_entry = cinit.num_init */
115 movlb __do_cinit_data_ptr_1_1
118 movwf __do_cinit_curr_entry_1_1, 1
121 movwf __do_cinit_curr_entry_1_1+1, 1
125 //while (curr_entry) {
129 tstfsz __do_cinit_curr_entry_1_1, 1
139 /* Count down so we only have to look up the data in _cinit
142 * At this point we know that TBLPTR points to the top of the current
143 * entry in _cinit, so we can just start reading the from, to, and
148 /* read the source address low */
151 movwf __do_cinit_prom_1_1, 1
153 /* source address high */
156 movwf __do_cinit_prom_1_1 + 1, 1
158 /* source address upper */
161 movwf __do_cinit_prom_1_1 + 2, 1
163 /* skip a byte since it's stored as a 32bit int */
166 /* read the destination address directly into FSR0 */
167 /* destination address low */
172 /* destination address high */
177 /* skip two bytes since it's stored as a 32bit int */
181 /* read the destination address directly into FSR0 */
184 movwf __do_cinit_curr_byte_1_1, 1
187 movwf __do_cinit_curr_byte_1_1+1, 1
189 /* skip two bytes since it's stored as a 32bit int */
194 //prom = data_ptr->from;
195 //FSR0 = data_ptr->to;
196 //curr_byte = (unsigned short) data_ptr->size;
197 /* the table pointer now points to the next entry. Save it
198 * off since we'll be using the table pointer to do the copying
201 /* data_ptr = TBLPTR */
203 movff _TBLPTRL, __do_cinit_data_ptr_1_1
204 movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1
205 movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2
209 /* now assign the source address to the table pointer */
212 movff __do_cinit_prom_1_1, _TBLPTRL
213 movff __do_cinit_prom_1_1 + 1, _TBLPTRH
214 movff __do_cinit_prom_1_1 + 2, _TBLPTRU
217 /* do the copy loop */
220 /* determine if we have any more bytes to copy */
221 movlb __do_cinit_curr_byte_1_1
222 movf __do_cinit_curr_byte_1_1, 1, 1
224 bnz copy_one_byte // copy_one_byte
225 movf __do_cinit_curr_byte_1_1 + 1, 1, 1
233 /* decrement byte counter */
234 decf __do_cinit_curr_byte_1_1, 1, 1
235 bnc copy_loop // copy_loop
236 decf __do_cinit_curr_byte_1_1 + 1, 1, 1
242 /* restore the table pointer for the next entry */
243 /* TBLPTR = data_ptr */
245 movff __do_cinit_data_ptr_1_1, _TBLPTRL
246 movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH
247 movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU
257 /* emit done label */