2 * crt0iz.c - SDCC pic16 port runtime start code with
3 * initialisation and clear RAM
5 * Converted for SDCC and pic16 port
6 * by Vangelis Rokas (vrokas@otenet.gr)
8 * based on Microchip MPLAB-C18 startup files
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2, or (at your option) any
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * In other words, you are welcome to use, share and improve this program.
25 * You are forbidden to forbid anyone else to use, share and improve
26 * what you give them. Help stamp out software-hoarding!
28 * $Id: crt0iz.c 5183 2008-05-26 18:55:44Z tecodev $
42 /* global variable for forcing gplink to add _cinit section */
46 /* external reference to the user's main routine */
47 extern void main (void);
49 void _entry (void) __naked __interrupt 0;
50 void _startup (void) __naked;
51 void _do_cinit (void) __naked;
53 /* Access bank selector. */
58 * entry function, placed at interrupt vector 0 (RESET)
60 void _entry (void) __naked __interrupt 0
67 void _startup (void) __naked
70 ; Initialize the stack pointer
74 ; 1st silicon does not do this on POR
77 ; Initialize the flash memory access configuration.
78 ; This is harmless for non-flash devices, so we do it on all parts.
79 bsf 0xa6, 7, a ; EECON1.EEPGD = 1, TBLPTR accesses program memory
80 bcf 0xa6, 6, a ; EECON1.CFGS = 0, TBLPTR accesses program memory
85 ; Load FSR0 with top of RAM.
90 ; Place 0xff at address 0x00 as a sentinel.
99 /* Initialize global and/or static variables. */
102 /* Call the main routine. */
107 ; Returning from main will lock up.
113 /* the cinit table will be filled by the linker */
114 extern __code struct {
115 unsigned short num_init;
124 #define TBLRDPOSTINC tblrd*+
126 #define prom 0x00 /* 0x00 0x01 0x02*/
127 #define curr_byte 0x03 /* 0x03 0x04 */
128 #define curr_entry 0x05 /* 0x05 0x06 */
129 #define data_ptr 0x07 /* 0x07 0x08 0x09 */
131 /* the variable initialisation routine */
132 void _do_cinit (void) __naked
135 * access registers 0x00 - 0x09 are not saved in this function
146 ; curr_entry = cinit.num_init
153 movwf curr_entry + 1, a
156 movf curr_entry, w, a
159 movf curr_entry + 1, w, a
163 ; Count down so we only have to look up the data in _cinit once.
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
169 ; read the source address low
174 ; source address high
179 ; source address upper
184 ; skip a byte since it is stored as a 32bit int
187 ; read the destination address directly into FSR0
188 ; destination address low
193 ; destination address high
198 ; skip two bytes since it is stored as a 32bit int
202 ; read the size of data to transfer to destination address
209 movwf curr_byte + 1, a
211 ; skip two bytes since it is stored as a 32bit int
215 ; prom = data_ptr->from;
216 ; FSR0 = data_ptr->to;
217 ; curr_byte = (unsigned short) data_ptr->size;
219 ; the table pointer now points to the next entry. Save it
220 ; off since we will be using the table pointer to do the copying
224 movff _TBLPTRL, data_ptr
225 movff _TBLPTRH, data_ptr + 1
226 movff _TBLPTRU, data_ptr + 2
228 ; now assign the source address to the table pointer
231 movff prom + 1, _TBLPTRH
232 movff prom + 2, _TBLPTRU
238 movf curr_byte + 1, w, a
246 ; decrement byte counter
249 decf curr_byte + 1, f, a
253 ; restore the table pointer for the next entry
255 movff data_ptr, _TBLPTRL
256 movff data_ptr + 1, _TBLPTRH
257 movff data_ptr + 2, _TBLPTRU
259 ; decrement entry counter
260 decf curr_entry, f, a
262 decf curr_entry + 1, f, a