X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Fpic16%2Fstartup%2Fcrt0iz.c;h=a3ae4722d9362f1a51a411c150298faaab9179fc;hb=b0b7280ea424f5b1f1a0071e7fedd7e46b1365a0;hp=ea6c7da084fe6090916297c2133e1a926898a0a3;hpb=93a5bd697ecc846637ce8e797e0bc3a08167aee5;p=fw%2Fsdcc diff --git a/device/lib/pic16/startup/crt0iz.c b/device/lib/pic16/startup/crt0iz.c index ea6c7da0..a3ae4722 100644 --- a/device/lib/pic16/startup/crt0iz.c +++ b/device/lib/pic16/startup/crt0iz.c @@ -7,6 +7,24 @@ * * based on Microchip MPLAB-C18 startup files * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * * $Id$ */ @@ -22,81 +40,83 @@ extern TABLAT; extern POSTINC0; extern POSTDEC0; +#if 1 /* global variable for forcing gplink to add _cinit section */ char __uflags = 0; +#endif /* external reference to the user's main routine */ extern void main (void); /* prototype for the startup function */ -void _entry (void) _naked interrupt 0; -void _startup (void); +void _entry (void) __naked __interrupt 0; +void _startup (void) __naked; /* prototype for the initialized data setup */ -void _do_cinit (void); +void _do_cinit (void) __naked; /* * entry function, placed at interrupt vector 0 (RESET) */ -void _entry (void) _naked interrupt 0 +void _entry (void) __naked __interrupt 0 { - _asm goto __startup _endasm; + __asm goto __startup __endasm; } -void _startup (void) +void _startup (void) __naked { - _asm - // Initialize the stack pointer - lfsr 1, _stack_end - lfsr 2, _stack_end - clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR + __asm + // Initialize the stack pointer + lfsr 1, _stack_end + lfsr 2, _stack_end + clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR - // initialize the flash memory access configuration. this is harmless - // for non-flash devices, so we do it on all parts. - bsf 0xa6, 7, 0 - bcf 0xa6, 6, 0 - - _endasm ; + // initialize the flash memory access configuration. this is harmless + // for non-flash devices, so we do it on all parts. + bsf 0xa6, 7, 0 + bcf 0xa6, 6, 0 + __endasm ; - /* cleanup the RAM */ - _asm - /* load FSR0 with top of RAM memory */ - movlw 0xff - movwf _FSR0L, 0 - movlw 0x0e - movwf _FSR0H, 0 + /* cleanup the RAM */ + __asm + /* load FSR0 with top of RAM memory */ + ; movlw 0xff + ; movwf _FSR0L, 0 + setf _FSR0L + movlw 0x0e + movwf _FSR0H, 0 - /* place a 1 at address 0x00, as a marker - * we haven't reached yet to it */ - movlw 1 - movwf 0x00, 0 + /* place a 1 at address 0x00, as a marker + * we haven't reached yet to it */ + ; movlw 1 + ; movwf 0x00, 0 + setf 0x00 - /* load WREG with zero */ - movlw 0x00 + /* load WREG with zero */ + movlw 0x00 clear_loop: - movwf _POSTDEC0, 0 - movf 0x00, 1, 0 - bnz clear_loop - _endasm ; + clrf _POSTDEC0 + movf 0x00, w + bnz clear_loop + __endasm ; + _do_cinit(); - _do_cinit(); - - /* Call the user's main routine */ - main (); + /* Call the user's main routine */ + main(); loop: - /* return from main will lock up */ - goto loop; + /* return from main will lock up */ + goto loop; } /* the cinit table will be filled by the linker */ -extern code struct +extern __code struct { unsigned short num_init; struct _init_entry { @@ -107,178 +127,176 @@ extern code struct } cinit; -#define tblrdpostinc tblrd*+ +#define TBLRDPOSTINC tblrd*+ + +#define prom 0x00 /* 0x00 0x01 0x02*/ +#define curr_byte 0x03 /* 0x03 0x04 */ +#define curr_entry 0x05 /* 0x05 0x06 */ +#define data_ptr 0x07 /* 0x07 0x08 0x09 */ + +/* + * static short long _do_cinit_prom; + * static unsigned short _do_cinit_curr_byte; + * static unsigned short _do_cinit_curr_entry; + * static short long _do_cinit_data_ptr; + */ /* the variable initialisation routine */ -void _do_cinit (void) +void _do_cinit (void) __naked { /* - * we'll make the assumption in the following code that these statics - * will be allocated into the same bank. + * access registers 0x00 - 0x09 are not saved in this function */ - static short long prom; - static unsigned short curr_byte; - static unsigned short curr_entry; - static short long data_ptr; - - - /* TBLPTR = &cinit */ - _asm - movlw low(_cinit) - movwf _TBLPTRL, 0 - movlw high(_cinit) - movwf _TBLPTRH, 0 - movlw upper(_cinit) - movwf _TBLPTRU, 0 - _endasm; + __asm + ; TBLPTR = &cinit + movlw low(_cinit) + movwf _TBLPTRL + movlw high(_cinit) + movwf _TBLPTRH + movlw upper(_cinit) + movwf _TBLPTRU - /* curr_entry = cinit.num_init */ - _asm - movlb __do_cinit_data_ptr_1_1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry_1_1, 1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry_1_1+1, 1 - _endasm; - - - //while (curr_entry) { - _asm + ; curr_entry = cinit.num_init + ; movlb data_ptr + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_entry + + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_entry+1 + + ; while (curr_entry) { test: - bnz done1 - tstfsz __do_cinit_curr_entry_1_1, 1 - bra cont1 + bnz cont1 ;;done1 + tstfsz curr_entry, 1 + bra cont1 done1: - goto done + goto done cont1: - _endasm; + ; Count down so we only have to look up the data in _cinit once. - /* Count down so we only have to look up the data in _cinit - * once. - * - * At this point we know that TBLPTR points to the top of the current - * entry in _cinit, so we can just start reading the from, to, and - * size values. - */ - _asm - - /* read the source address low */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1, 1 + ; At this point we know that TBLPTR points to the top of the current + ; entry in _cinit, so we can just start reading the from, to, and + ; size values. + + ; read the source address low + TBLRDPOSTINC + movf _TABLAT, w + movwf prom - /* source address high */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1 + 1, 1 - - /* source address upper */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1 + 2, 1 - - /* skip a byte since it's stored as a 32bit int */ - tblrdpostinc - - /* read the destination address directly into FSR0 */ - /* destination address low */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _FSR0L, 0 - - /* destination address high */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _FSR0H, 0 - - /* skip two bytes since it's stored as a 32bit int */ - tblrdpostinc - tblrdpostinc - - /* read the destination address directly into FSR0 */ - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte_1_1, 1 - tblrdpostinc - movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte_1_1+1, 1 - - /* skip two bytes since it's stored as a 32bit int */ - tblrdpostinc - tblrdpostinc - _endasm; - - //prom = data_ptr->from; - //FSR0 = data_ptr->to; - //curr_byte = (unsigned short) data_ptr->size; - /* the table pointer now points to the next entry. Save it - * off since we'll be using the table pointer to do the copying - * for the entry */ - - /* data_ptr = TBLPTR */ - _asm - movff _TBLPTRL, __do_cinit_data_ptr_1_1 - movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1 - movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2 - _endasm; + ; source address high + TBLRDPOSTINC + movf _TABLAT, w + movwf prom + 1 + + ; source address upper + TBLRDPOSTINC + movf _TABLAT, w + movwf prom + 2 + + ; skip a byte since it is stored as a 32bit int + TBLRDPOSTINC + + ; read the destination address directly into FSR0 + ; destination address low + TBLRDPOSTINC + movf _TABLAT, w + movwf _FSR0L + + ; destination address high + TBLRDPOSTINC + movf _TABLAT, w + movwf _FSR0H + + ; skip two bytes since it is stored as a 32bit int + TBLRDPOSTINC + TBLRDPOSTINC + + ; read the size of data to transfer to destination address + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_byte + + TBLRDPOSTINC + movf _TABLAT, w + movwf curr_byte+1 + + + ; skip two bytes since it is stored as a 32bit int + TBLRDPOSTINC + TBLRDPOSTINC + + ; prom = data_ptr->from; + ; FSR0 = data_ptr->to; + ; curr_byte = (unsigned short) data_ptr->size; + + ; the table pointer now points to the next entry. Save it + ; off since we will be using the table pointer to do the copying + ; for the entry + ; data_ptr = TBLPTR + + movff _TBLPTRL, data_ptr + movff _TBLPTRH, data_ptr + 1 + movff _TBLPTRU, data_ptr + 2 - /* now assign the source address to the table pointer */ - /* TBLPTR = prom */ - _asm - movff __do_cinit_prom_1_1, _TBLPTRL - movff __do_cinit_prom_1_1 + 1, _TBLPTRH - movff __do_cinit_prom_1_1 + 2, _TBLPTRU - _endasm; - - /* do the copy loop */ - _asm - - /* determine if we have any more bytes to copy */ - movlb __do_cinit_curr_byte_1_1 - movf __do_cinit_curr_byte_1_1, 1, 1 + ; now assign the source address to the table pointer + ; TBLPTR = prom + + movff prom, _TBLPTRL + movff prom + 1, _TBLPTRH + movff prom + 2, _TBLPTRU + + ; do the copy loop + + ; determine if we have any more bytes to copy + ; movlb curr_byte + movf curr_byte, w + copy_loop: - bnz copy_one_byte // copy_one_byte - movf __do_cinit_curr_byte_1_1 + 1, 1, 1 - bz done_copying + bnz copy_one_byte ; copy_one_byte + movf curr_byte + 1, w + bz done_copying copy_one_byte: - tblrdpostinc - movf _TABLAT, 0, 0 - movwf _POSTINC0, 0 + TBLRDPOSTINC + movf _TABLAT, w + movwf _POSTINC0 - /* decrement byte counter */ - decf __do_cinit_curr_byte_1_1, 1, 1 - bnc copy_loop // copy_loop - decf __do_cinit_curr_byte_1_1 + 1, 1, 1 + ; decrement byte counter + decf curr_byte, f + bc copy_loop ; copy_loop + decf curr_byte + 1, f - bra copy_loop + bra copy_one_byte done_copying: - _endasm; - - /* restore the table pointer for the next entry */ - /* TBLPTR = data_ptr */ - _asm - movff __do_cinit_data_ptr_1_1, _TBLPTRL - movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH - movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU - _endasm; - /* next entry... */ - curr_entry--; + ; restore the table pointer for the next entry + ; TBLPTR = data_ptr + movff data_ptr, _TBLPTRL + movff data_ptr + 1, _TBLPTRH + movff data_ptr + 2, _TBLPTRU + + + decf curr_entry, f + bc do_next + decf curr_entry + 1, f + +do_next: + ; next entry... + ; _do_cinit_curr_entry--; - _asm - goto test; + goto test; - /* emit done label */ + ; emit done label done: - _endasm; + return + __endasm; }