* src/pic16/device.c (Pics16[]): added devices 18F2550, 18F4331,
[fw/sdcc] / device / lib / pic16 / startup / crt0i.c
index 9459d62c3aa2c040a00b1d9651c9c75a3a1d5000..d8cfe434b83c321c3adf4ebbfde437373c40ad99 100644 (file)
@@ -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$
  */
 
@@ -21,8 +39,11 @@ extern FSR0H;
 extern TABLAT;
 extern POSTINC0;
 
+
+#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);
@@ -32,7 +53,7 @@ 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;
 
 
 /*
@@ -47,27 +68,27 @@ void _entry (void) _naked interrupt 0
 
 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
+    // 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 ;
+  _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;
 }
 
 
@@ -83,183 +104,172 @@ extern code struct
 } cinit;
 
 
-#define tblrdpostinc   tblrd*+
-
+#define TBLRDPOSTINC   tblrd*+
 
-#pragma udata access _do_cinit_prom, _do_cinit_curr_byte
-#pragma udata access _do_cinit_ curr_entry, _do_cinit_data_ptr
+#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;
+/*
+ * 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
    */
+  _asm
+      ; TBLPTR = &cinit
+    movlw low(_cinit)
+    movwf _TBLPTRL
+    movlw high(_cinit)
+    movwf _TBLPTRH
+    movlw upper(_cinit)
+    movwf _TBLPTRU
+       
+                  ; curr_entry = cinit.num_init
+                  ; movlb data_ptr
+    TBLRDPOSTINC
+    movf _TABLAT, w
+    movwf curr_entry
 
+    TBLRDPOSTINC
+    movf _TABLAT, w
+    movwf curr_entry+1
 
-       /* TBLPTR = &cinit */
-       _asm
-               movlw low(_cinit)
-               movwf _TBLPTRL, 0
-               movlw high(_cinit)
-               movwf _TBLPTRH, 0
-               movlw upper(_cinit)
-               movwf _TBLPTRU, 0
-       _endasm;
-
-       
-       /* curr_entry = cinit.num_init */
-       _asm
-               movlb __do_cinit_data_ptr
-               tblrdpostinc
-               movf _TABLAT, 0, 0
-               movwf __do_cinit_curr_entry, 1
-               tblrdpostinc
-               movf _TABLAT, 0, 0
-               movwf __do_cinit_curr_entry+1, 1
-       _endasm;
-
-
-       //while (curr_entry) {
-       _asm
+                  ; while (curr_entry) {
 test:
-       bnz done1
-       tstfsz __do_cinit_curr_entry, 1
-       bra cont1
+    bnz 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
+    ; 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
-
-               /* source address upper */
-               tblrdpostinc
-               movf _TABLAT, 0, 0
-               movwf __do_cinit_prom + 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
-               tblrdpostinc
-               movf _TABLAT, 0, 0
-               movwf __do_cinit_curr_byte+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
-               movff _TBLPTRH, __do_cinit_data_ptr + 1
-               movff _TBLPTRU, __do_cinit_data_ptr + 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 destination address directly into FSR0 
+    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, _TBLPTRL
-               movff __do_cinit_prom + 1, _TBLPTRH
-               movff __do_cinit_prom + 2, _TBLPTRU
-       _endasm;
-
-       /* do the copy loop */
-       _asm
-
-               /* determine if we have any more bytes to copy */
-               movlb __do_cinit_curr_byte
-               movf __do_cinit_curr_byte, 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
-               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
-               bnc copy_loop // copy_loop
-               decf __do_cinit_curr_byte + 1, 1, 1
+    ; decrement byte counter 
+    decf curr_byte, f
+    bnc copy_loop              ; copy_loop 
+    decf curr_byte + 1, f
 
-               bra copy_loop
+    bra copy_loop
 done_copying:
-       _endasm;
-  
-       /* restore the table pointer for the next entry */
-       /*  TBLPTR = data_ptr */
-       _asm
-               movff __do_cinit_data_ptr, _TBLPTRL
-               movff __do_cinit_data_ptr + 1, _TBLPTRH
-               movff __do_cinit_data_ptr + 2, _TBLPTRU
-       _endasm;
 
   
-       /* next entry... */
-       _do_cinit_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
+
+    dcfsnz curr_entry, f
+    decf curr_entry + 1, f
+
+    ; next entry...
+    ; _do_cinit_curr_entry--; 
 
-       _asm
-               goto test;
+    goto test;
 
-       /* emit done label */
+    ; emit done label 
 done:
-       _endasm;
+    return
+  _endasm;
 }