*
* 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$
*/
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 {
} 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;
}