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 /* external reference to the user's main routine */
26 extern void main (void);
28 /* prototype for the startup function */
29 void _entry (void) _naked interrupt 0;
32 /* prototype for the initialized data setup */
33 void _do_cinit (void);
37 * entry function, placed at interrupt vector 0 (RESET)
40 void _entry (void) _naked interrupt 0
42 _asm goto __startup _endasm;
49 // Initialize the stack pointer
52 clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
54 // initialize the flash memory access configuration. this is harmless
55 // for non-flash devices, so we do it on all parts.
63 /* load FSR0 with top of RAM memory */
69 /* place a 1 at address 0x00, as a marker
70 * we haven't reached yet to it */
74 /* load WREG with zero */
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 /* the variable initialisation routine */
110 void _do_cinit (void)
113 * we'll make the assumption in the following code that these statics
114 * will be allocated into the same bank.
116 static short long prom;
117 static unsigned short curr_byte;
118 static unsigned short curr_entry;
119 static short long data_ptr;
122 /* TBLPTR = &cinit */
133 /* curr_entry = cinit.num_init */
135 movlb __do_cinit_data_ptr_1_1
138 movwf __do_cinit_curr_entry_1_1, 1
141 movwf __do_cinit_curr_entry_1_1+1, 1
145 //while (curr_entry) {
149 tstfsz __do_cinit_curr_entry_1_1, 1
159 /* Count down so we only have to look up the data in _cinit
162 * At this point we know that TBLPTR points to the top of the current
163 * entry in _cinit, so we can just start reading the from, to, and
168 /* read the source address low */
171 movwf __do_cinit_prom_1_1, 1
173 /* source address high */
176 movwf __do_cinit_prom_1_1 + 1, 1
178 /* source address upper */
181 movwf __do_cinit_prom_1_1 + 2, 1
183 /* skip a byte since it's stored as a 32bit int */
186 /* read the destination address directly into FSR0 */
187 /* destination address low */
192 /* destination address high */
197 /* skip two bytes since it's stored as a 32bit int */
201 /* read the destination address directly into FSR0 */
204 movwf __do_cinit_curr_byte_1_1, 1
207 movwf __do_cinit_curr_byte_1_1+1, 1
209 /* skip two bytes since it's stored as a 32bit int */
214 //prom = data_ptr->from;
215 //FSR0 = data_ptr->to;
216 //curr_byte = (unsigned short) data_ptr->size;
217 /* the table pointer now points to the next entry. Save it
218 * off since we'll be using the table pointer to do the copying
221 /* data_ptr = TBLPTR */
223 movff _TBLPTRL, __do_cinit_data_ptr_1_1
224 movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1
225 movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2
229 /* now assign the source address to the table pointer */
232 movff __do_cinit_prom_1_1, _TBLPTRL
233 movff __do_cinit_prom_1_1 + 1, _TBLPTRH
234 movff __do_cinit_prom_1_1 + 2, _TBLPTRU
237 /* do the copy loop */
240 /* determine if we have any more bytes to copy */
241 movlb __do_cinit_curr_byte_1_1
242 movf __do_cinit_curr_byte_1_1, 1, 1
244 bnz copy_one_byte // copy_one_byte
245 movf __do_cinit_curr_byte_1_1 + 1, 1, 1
253 /* decrement byte counter */
254 decf __do_cinit_curr_byte_1_1, 1, 1
255 bnc copy_loop // copy_loop
256 decf __do_cinit_curr_byte_1_1 + 1, 1, 1
262 /* restore the table pointer for the next entry */
263 /* TBLPTR = data_ptr */
265 movff __do_cinit_data_ptr_1_1, _TBLPTRL
266 movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH
267 movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU
277 /* emit done label */