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
24 /* external reference to the user's main routine */
25 extern void main (void);
27 /* prototype for the startup function */
28 void _entry (void) _naked interrupt 0;
31 /* prototype for the initialized data setup */
32 void _do_cinit (void);
36 * entry function, placed at interrupt vector 0 (RESET)
39 void _entry (void) _naked interrupt 0
41 _asm goto __startup _endasm;
48 // Initialize the stack pointer
51 clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
53 // initialize the flash memory access configuration. this is harmless
54 // for non-flash devices, so we do it on all parts.
62 /* load FSR0 with top of RAM memory */
68 /* place a 1 at address 0x00, as a marker
69 * we haven't reached yet to it */
73 /* load WREG with zero */
85 /* Call the user's main routine */
89 /* return from main will lock up */
94 /* the cinit table will be filled by the linker */
97 unsigned short num_init;
106 #define tblrdpostinc tblrd*+
108 /* the variable initialisation routine */
109 void _do_cinit (void)
112 * we'll make the assumption in the following code that these statics
113 * will be allocated into the same bank.
115 static short long prom;
116 static unsigned short curr_byte;
117 static unsigned short curr_entry;
118 static short long data_ptr;
121 /* TBLPTR = &cinit */
132 /* curr_entry = cinit.num_init */
134 movlb __do_cinit_data_ptr_1_1
137 movwf __do_cinit_curr_entry_1_1, 1
140 movwf __do_cinit_curr_entry_1_1+1, 1
144 //while (curr_entry) {
148 tstfsz __do_cinit_curr_entry_1_1, 1
158 /* Count down so we only have to look up the data in _cinit
161 * At this point we know that TBLPTR points to the top of the current
162 * entry in _cinit, so we can just start reading the from, to, and
167 /* read the source address low */
170 movwf __do_cinit_prom_1_1, 1
172 /* source address high */
175 movwf __do_cinit_prom_1_1 + 1, 1
177 /* source address upper */
180 movwf __do_cinit_prom_1_1 + 2, 1
182 /* skip a byte since it's stored as a 32bit int */
185 /* read the destination address directly into FSR0 */
186 /* destination address low */
191 /* destination address high */
196 /* skip two bytes since it's stored as a 32bit int */
200 /* read the destination address directly into FSR0 */
203 movwf __do_cinit_curr_byte_1_1, 1
206 movwf __do_cinit_curr_byte_1_1+1, 1
208 /* skip two bytes since it's stored as a 32bit int */
213 //prom = data_ptr->from;
214 //FSR0 = data_ptr->to;
215 //curr_byte = (unsigned short) data_ptr->size;
216 /* the table pointer now points to the next entry. Save it
217 * off since we'll be using the table pointer to do the copying
220 /* data_ptr = TBLPTR */
222 movff _TBLPTRL, __do_cinit_data_ptr_1_1
223 movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1
224 movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2
228 /* now assign the source address to the table pointer */
231 movff __do_cinit_prom_1_1, _TBLPTRL
232 movff __do_cinit_prom_1_1 + 1, _TBLPTRH
233 movff __do_cinit_prom_1_1 + 2, _TBLPTRU
236 /* do the copy loop */
239 /* determine if we have any more bytes to copy */
240 movlb __do_cinit_curr_byte_1_1
241 movf __do_cinit_curr_byte_1_1, 1, 1
243 bnz copy_one_byte // copy_one_byte
244 movf __do_cinit_curr_byte_1_1 + 1, 1, 1
252 /* decrement byte counter */
253 decf __do_cinit_curr_byte_1_1, 1, 1
254 bnc copy_loop // copy_loop
255 decf __do_cinit_curr_byte_1_1 + 1, 1, 1
261 /* restore the table pointer for the next entry */
262 /* TBLPTR = data_ptr */
264 movff __do_cinit_data_ptr_1_1, _TBLPTRL
265 movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH
266 movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU
276 /* emit done label */