2 * crt0iz.c - SDCC pic16 port runtime start code with
3 * initialisation and RAM memory zero
5 * Converted for SDCC and pic16 port
6 * by Vangelis Rokas (vrokas@otenet.gr)
8 * based on Microchip MPLAB-C18 startup files
25 /* global variable for forcing gplink to add _cinit section */
28 /* external reference to the user's main routine */
29 extern void main (void);
31 /* prototype for the startup function */
32 void _entry (void) _naked interrupt 0;
35 /* prototype for the initialized data setup */
36 void _do_cinit (void);
40 * entry function, placed at interrupt vector 0 (RESET)
43 void _entry (void) _naked interrupt 0
45 _asm goto __startup _endasm;
52 // Initialize the stack pointer
55 clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
57 // initialize the flash memory access configuration. this is harmless
58 // for non-flash devices, so we do it on all parts.
66 /* load FSR0 with top of RAM memory */
72 /* place a 1 at address 0x00, as a marker
73 * we haven't reached yet to it */
77 /* load WREG with zero */
89 /* Call the user's main routine */
93 /* return from main will lock up */
98 /* the cinit table will be filled by the linker */
101 unsigned short num_init;
110 #define tblrdpostinc tblrd*+
112 /* the variable initialisation routine */
113 void _do_cinit (void)
116 * we'll make the assumption in the following code that these statics
117 * will be allocated into the same bank.
119 static short long prom;
120 static unsigned short curr_byte;
121 static unsigned short curr_entry;
122 static short long data_ptr;
125 /* TBLPTR = &cinit */
136 /* curr_entry = cinit.num_init */
138 movlb __do_cinit_data_ptr_1_1
141 movwf __do_cinit_curr_entry_1_1, 1
144 movwf __do_cinit_curr_entry_1_1+1, 1
148 //while (curr_entry) {
152 tstfsz __do_cinit_curr_entry_1_1, 1
162 /* Count down so we only have to look up the data in _cinit
165 * At this point we know that TBLPTR points to the top of the current
166 * entry in _cinit, so we can just start reading the from, to, and
171 /* read the source address low */
174 movwf __do_cinit_prom_1_1, 1
176 /* source address high */
179 movwf __do_cinit_prom_1_1 + 1, 1
181 /* source address upper */
184 movwf __do_cinit_prom_1_1 + 2, 1
186 /* skip a byte since it's stored as a 32bit int */
189 /* read the destination address directly into FSR0 */
190 /* destination address low */
195 /* destination address high */
200 /* skip two bytes since it's stored as a 32bit int */
204 /* read the destination address directly into FSR0 */
207 movwf __do_cinit_curr_byte_1_1, 1
210 movwf __do_cinit_curr_byte_1_1+1, 1
212 /* skip two bytes since it's stored as a 32bit int */
217 //prom = data_ptr->from;
218 //FSR0 = data_ptr->to;
219 //curr_byte = (unsigned short) data_ptr->size;
220 /* the table pointer now points to the next entry. Save it
221 * off since we'll be using the table pointer to do the copying
224 /* data_ptr = TBLPTR */
226 movff _TBLPTRL, __do_cinit_data_ptr_1_1
227 movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1
228 movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2
232 /* now assign the source address to the table pointer */
235 movff __do_cinit_prom_1_1, _TBLPTRL
236 movff __do_cinit_prom_1_1 + 1, _TBLPTRH
237 movff __do_cinit_prom_1_1 + 2, _TBLPTRU
240 /* do the copy loop */
243 /* determine if we have any more bytes to copy */
244 movlb __do_cinit_curr_byte_1_1
245 movf __do_cinit_curr_byte_1_1, 1, 1
247 bnz copy_one_byte // copy_one_byte
248 movf __do_cinit_curr_byte_1_1 + 1, 1, 1
256 /* decrement byte counter */
257 decf __do_cinit_curr_byte_1_1, 1, 1
258 bnc copy_loop // copy_loop
259 decf __do_cinit_curr_byte_1_1 + 1, 1, 1
265 /* restore the table pointer for the next entry */
266 /* TBLPTR = data_ptr */
268 movff __do_cinit_data_ptr_1_1, _TBLPTRL
269 movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH
270 movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU
280 /* emit done label */