crt.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * crt0iz-rloc.c - SDCC pic16 port runtime start code with
  3. * initialisation and RAM memory zero
  4. *
  5. * Converted for SDCC and pic16 port
  6. * by Vangelis Rokas (vrokas@otenet.gr)
  7. *
  8. * based on Microchip MPLAB-C18 startup files
  9. *
  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
  13. * later version.
  14. *
  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.
  19. *
  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.
  23. *
  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!
  27. *
  28. * $Id: crt0iz.c 3714 2005-04-02 13:13:53Z vrokas $
  29. */
  30. extern stack;
  31. extern stack_end;
  32. extern TBLPTRU;
  33. extern TBLPTRH;
  34. extern TBLPTRL;
  35. extern FSR0L;
  36. extern FSR0H;
  37. extern TABLAT;
  38. extern POSTINC0;
  39. extern POSTDEC0;
  40. #if 1
  41. /* global variable for forcing gplink to add _cinit section */
  42. char __uflags = 0;
  43. #endif
  44. /* external reference to the user's main routine */
  45. extern void main (void);
  46. /* prototype for the startup function */
  47. void _entry (void) __naked __interrupt 0;
  48. void _startup (void) __naked;
  49. /* prototype for the initialized data setup */
  50. void _do_cinit (void) __naked;
  51. /*
  52. * entry function, placed at interrupt vector 0 (RESET)
  53. */
  54. void _entry (void) __naked __interrupt 0
  55. {
  56. __asm goto __startup __endasm;
  57. }
  58. void _startup (void) __naked
  59. {
  60. __asm
  61. // Initialize the stack pointer
  62. lfsr 1, _stack_end
  63. lfsr 2, _stack_end
  64. clrf _TBLPTRU, 0 // 1st silicon doesn't do this on POR
  65. // initialize the flash memory access configuration. this is harmless
  66. // for non-flash devices, so we do it on all parts.
  67. bsf 0xa6, 7, 0
  68. bcf 0xa6, 6, 0
  69. __endasm ;
  70. /* cleanup the RAM */
  71. __asm
  72. /* load FSR0 with top of RAM memory */
  73. ; movlw 0xff
  74. ; movwf _FSR0L, 0
  75. setf _FSR0L
  76. movlw 0x0e
  77. movwf _FSR0H, 0
  78. /* place a 1 at address 0x00, as a marker
  79. * we haven't reached yet to it */
  80. ; movlw 1
  81. ; movwf 0x00, 0
  82. setf 0x00
  83. /* load WREG with zero */
  84. movlw 0x00
  85. clear_loop:
  86. clrf _POSTDEC0
  87. movf 0x00, w
  88. bnz clear_loop
  89. __endasm ;
  90. _do_cinit();
  91. /* Call the user's main routine */
  92. main();
  93. loop:
  94. /* return from main will lock up */
  95. goto loop;
  96. }
  97. /* the cinit table will be filled by the linker */
  98. extern __code struct
  99. {
  100. unsigned short num_init;
  101. struct _init_entry {
  102. unsigned long from;
  103. unsigned long to;
  104. unsigned long size;
  105. } entries[];
  106. } cinit;
  107. #define TBLRDPOSTINC tblrd*+
  108. #define prom 0x00 /* 0x00 0x01 0x02*/
  109. #define curr_byte 0x03 /* 0x03 0x04 */
  110. #define curr_entry 0x05 /* 0x05 0x06 */
  111. #define data_ptr 0x07 /* 0x07 0x08 0x09 */
  112. /*
  113. * static short long _do_cinit_prom;
  114. * static unsigned short _do_cinit_curr_byte;
  115. * static unsigned short _do_cinit_curr_entry;
  116. * static short long _do_cinit_data_ptr;
  117. */
  118. /* the variable initialisation routine */
  119. void _do_cinit (void) __naked
  120. {
  121. /*
  122. * access registers 0x00 - 0x09 are not saved in this function
  123. */
  124. __asm
  125. ; TBLPTR = &cinit
  126. movlw low(_cinit)
  127. movwf _TBLPTRL
  128. movlw high(_cinit)
  129. movwf _TBLPTRH
  130. movlw upper(_cinit)
  131. movwf _TBLPTRU
  132. ; curr_entry = cinit.num_init
  133. ; movlb data_ptr
  134. TBLRDPOSTINC
  135. movf _TABLAT, w
  136. movwf curr_entry
  137. TBLRDPOSTINC
  138. movf _TABLAT, w
  139. movwf curr_entry+1
  140. ; while (curr_entry) {
  141. test:
  142. bnz cont1 ;;done1
  143. tstfsz curr_entry, 1
  144. bra cont1
  145. done1:
  146. goto done
  147. cont1:
  148. ; Count down so we only have to look up the data in _cinit once.
  149. ; At this point we know that TBLPTR points to the top of the current
  150. ; entry in _cinit, so we can just start reading the from, to, and
  151. ; size values.
  152. ; read the source address low
  153. TBLRDPOSTINC
  154. movf _TABLAT, w
  155. movwf prom
  156. ; source address high
  157. TBLRDPOSTINC
  158. movf _TABLAT, w
  159. movwf prom + 1
  160. ; source address upper
  161. TBLRDPOSTINC
  162. movf _TABLAT, w
  163. movwf prom + 2
  164. ; skip a byte since it is stored as a 32bit int
  165. TBLRDPOSTINC
  166. ; read the destination address directly into FSR0
  167. ; destination address low
  168. TBLRDPOSTINC
  169. movf _TABLAT, w
  170. movwf _FSR0L
  171. ; destination address high
  172. TBLRDPOSTINC
  173. movf _TABLAT, w
  174. movwf _FSR0H
  175. ; skip two bytes since it is stored as a 32bit int
  176. TBLRDPOSTINC
  177. TBLRDPOSTINC
  178. ; read the size of data to transfer to destination address
  179. TBLRDPOSTINC
  180. movf _TABLAT, w
  181. movwf curr_byte
  182. TBLRDPOSTINC
  183. movf _TABLAT, w
  184. movwf curr_byte+1
  185. ; skip two bytes since it is stored as a 32bit int
  186. TBLRDPOSTINC
  187. TBLRDPOSTINC
  188. ; prom = data_ptr->from;
  189. ; FSR0 = data_ptr->to;
  190. ; curr_byte = (unsigned short) data_ptr->size;
  191. ; the table pointer now points to the next entry. Save it
  192. ; off since we will be using the table pointer to do the copying
  193. ; for the entry
  194. ; data_ptr = TBLPTR
  195. movff _TBLPTRL, data_ptr
  196. movff _TBLPTRH, data_ptr + 1
  197. movff _TBLPTRU, data_ptr + 2
  198. ; now assign the source address to the table pointer
  199. ; TBLPTR = prom
  200. movff prom, _TBLPTRL
  201. movff prom + 1, _TBLPTRH
  202. movff prom + 2, _TBLPTRU
  203. ; do the copy loop
  204. ; determine if we have any more bytes to copy
  205. ; movlb curr_byte
  206. movf curr_byte, w
  207. copy_loop:
  208. bnz copy_one_byte ; copy_one_byte
  209. movf curr_byte + 1, w
  210. bz done_copying
  211. copy_one_byte:
  212. TBLRDPOSTINC
  213. movf _TABLAT, w
  214. movwf _POSTINC0
  215. ; decrement byte counter
  216. decf curr_byte, f
  217. bc copy_loop ; copy_loop
  218. decf curr_byte + 1, f
  219. bra copy_one_byte
  220. done_copying:
  221. ; restore the table pointer for the next entry
  222. ; TBLPTR = data_ptr
  223. movff data_ptr, _TBLPTRL
  224. movff data_ptr + 1, _TBLPTRH
  225. movff data_ptr + 2, _TBLPTRU
  226. decf curr_entry, f
  227. bc do_next
  228. decf curr_entry + 1, f
  229. do_next:
  230. ; next entry...
  231. ; _do_cinit_curr_entry--;
  232. goto test;
  233. ; emit done label
  234. done:
  235. return
  236. __endasm;
  237. }