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;
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;
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*+
88 /* the variable initialisation routine */
92 * we'll make the assumption in the following code that these statics
93 * will be allocated into the same bank.
95 static short long prom;
96 static unsigned short curr_byte;
97 static unsigned short curr_entry;
98 static short long data_ptr;
101 /* TBLPTR = &cinit */
112 /* curr_entry = cinit.num_init */
114 movlb __do_cinit_data_ptr_1_1
117 movwf __do_cinit_curr_entry_1_1, 1
120 movwf __do_cinit_curr_entry_1_1+1, 1
124 //while (curr_entry) {
128 tstfsz __do_cinit_curr_entry_1_1, 1
138 /* Count down so we only have to look up the data in _cinit
141 * At this point we know that TBLPTR points to the top of the current
142 * entry in _cinit, so we can just start reading the from, to, and
147 /* read the source address low */
150 movwf __do_cinit_prom_1_1, 1
152 /* source address high */
155 movwf __do_cinit_prom_1_1 + 1, 1
157 /* source address upper */
160 movwf __do_cinit_prom_1_1 + 2, 1
162 /* skip a byte since it's stored as a 32bit int */
165 /* read the destination address directly into FSR0 */
166 /* destination address low */
171 /* destination address high */
176 /* skip two bytes since it's stored as a 32bit int */
180 /* read the destination address directly into FSR0 */
183 movwf __do_cinit_curr_byte_1_1, 1
186 movwf __do_cinit_curr_byte_1_1+1, 1
188 /* skip two bytes since it's stored as a 32bit int */
193 //prom = data_ptr->from;
194 //FSR0 = data_ptr->to;
195 //curr_byte = (unsigned short) data_ptr->size;
196 /* the table pointer now points to the next entry. Save it
197 * off since we'll be using the table pointer to do the copying
200 /* data_ptr = TBLPTR */
202 movff _TBLPTRL, __do_cinit_data_ptr_1_1
203 movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1
204 movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2
208 /* now assign the source address to the table pointer */
211 movff __do_cinit_prom_1_1, _TBLPTRL
212 movff __do_cinit_prom_1_1 + 1, _TBLPTRH
213 movff __do_cinit_prom_1_1 + 2, _TBLPTRU
216 /* do the copy loop */
219 /* determine if we have any more bytes to copy */
220 movlb __do_cinit_curr_byte_1_1
221 movf __do_cinit_curr_byte_1_1, 1, 1
223 bnz copy_one_byte // copy_one_byte
224 movf __do_cinit_curr_byte_1_1 + 1, 1, 1
232 /* decrement byte counter */
233 decf __do_cinit_curr_byte_1_1, 1, 1
234 bnc copy_loop // copy_loop
235 decf __do_cinit_curr_byte_1_1 + 1, 1, 1
241 /* restore the table pointer for the next entry */
242 /* TBLPTR = data_ptr */
244 movff __do_cinit_data_ptr_1_1, _TBLPTRL
245 movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH
246 movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU
256 /* emit done label */