]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/HCS12_CodeWarrior_banked/Sources/Start12.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / HCS12_CodeWarrior_banked / Sources / Start12.c
1 /*****************************************************\r
2       start12.c - standard startup code\r
3    The startup code may be optimized to special user requests\r
4  ----------------------------------------------------\r
5    Copyright (c) Metrowerks, Basel, Switzerland\r
6                All rights reserved\r
7                   Do not modify!\r
8 \r
9 Note: ROM libraries are not implemented in this startup code\r
10 Note: C++ destructors of global objects are NOT yet supported in the HIWARE Object File Format.\r
11       To use this feature, please build your application with the ELF object file format.\r
12  *****************************************************/\r
13 \r
14 #include "hidef.h"\r
15 #include "start12.h"\r
16 \r
17 /* Macros to control how the startup code handles the COP: */\r
18 /* #define _DO_FEED_COP_  : do feed the COP  */\r
19 /* #define _DO_ENABLE_COP_: do enable the COP  */\r
20 /* #define _DO_DISABLE_COP_: disable the COP */\r
21 /* Without defining any of these, the startup code does NOT handle the COP */\r
22 \r
23 #pragma DATA_SEG __NEAR_SEG STARTUP_DATA /* _startupData can be accessed using 16 bit accesses. This is needed because it contains the stack top, and without stack, far data cannot be accessed */\r
24 struct _tagStartup _startupData;  /*   read-only: */\r
25                                   /*   _startupData is allocated in ROM and */\r
26                                   /*   initialized by the linker */\r
27 #pragma DATA_SEG DEFAULT\r
28 #if defined(FAR_DATA)\r
29 #include "non_bank.sgm"\r
30 /* the init function must be in non banked memory if banked variables are used */\r
31 /* because _SET_PAGE is called, which may change any page register. */\r
32 \r
33 #ifdef __cplusplus\r
34   extern "C"\r
35 #endif\r
36 void _SET_PAGE(void);             /* the inline assembler needs a prototype */\r
37                                   /* this is a runtime routine with a special */\r
38                                   /* calling convention, dont use it in c code! */\r
39 static void Init(void);\r
40 static void Fini(void);\r
41 #else\r
42 #include "default.sgm"\r
43 #if defined( __BANKED__) || defined(__LARGE__)\r
44 static void __far Init(void);\r
45 static void __far Fini(void);\r
46 #endif /* defined( __BANKED__) || defined(__LARGE__) */\r
47 #endif /* FAR_DATA */\r
48 \r
49 \r
50 /* define value and bits for Windef Register */\r
51 #ifdef HC812A4\r
52 #define WINDEF (*(volatile unsigned char*) 0x37)\r
53 #if defined( __BANKED__) || defined(__LARGE__) || defined(__PPAGE__)\r
54 #define __ENABLE_PPAGE__ 0x40\r
55 #else\r
56 #define __ENABLE_PPAGE__ 0x0\r
57 #endif\r
58 #if defined(__DPAGE__)\r
59 #define __ENABLE_DPAGE__ 0x80\r
60 #else\r
61 #define __ENABLE_DPAGE__ 0x0\r
62 #endif\r
63 #if defined(__EPAGE__)\r
64 #define __ENABLE_EPAGE__ 0x20\r
65 #else\r
66 #define __ENABLE_EPAGE__ 0x0\r
67 #endif\r
68 #endif  /* HC812A4 */\r
69 \r
70 #ifdef _HCS12_SERIALMON\r
71       /* for Monitor based software remap the RAM & EEPROM to adhere\r
72          to EB386. Edit RAM and EEPROM sections in PRM file to match these. */\r
73 #define ___INITRM      (*(volatile unsigned char *) 0x0010)\r
74 #define ___INITRG      (*(volatile unsigned char *) 0x0011)\r
75 #define ___INITEE      (*(volatile unsigned char *) 0x0012)\r
76 #endif\r
77 \r
78 #if defined(_DO_FEED_COP_)\r
79 #define __FEED_COP_IN_HLI()  } __asm movb #0x55, _COP_RST_ADR; __asm movb #0xAA, _COP_RST_ADR; __asm {\r
80 #else\r
81 #define __FEED_COP_IN_HLI() /* do nothing */\r
82 #endif\r
83 \r
84 #if !defined(FAR_DATA) && (defined( __BANKED__) || defined(__LARGE__))\r
85 static void __far Init(void)\r
86 #else\r
87 static void Init(void)\r
88 #endif\r
89  {\r
90 /* purpose:     1) zero out RAM-areas where data is allocated   */\r
91 /*              2) copy initialization data from ROM to RAM     */\r
92 /*              3) call global constructors in C++              */\r
93 /*   called from: _Startup, LibInits                            */\r
94    __asm {\r
95 ZeroOut:\r
96 #if defined(__HIWARE_OBJECT_FILE_FORMAT__) && defined(__LARGE__)\r
97              LDX   _startupData.pZeroOut:1  ; in the large memory model in the HIWARE format, pZeroOut is a 24 bit pointer\r
98 #else\r
99              LDX   _startupData.pZeroOut    ; *pZeroOut\r
100 #endif\r
101              LDY   _startupData.nofZeroOuts ; nofZeroOuts\r
102              BEQ   CopyDown                 ; if nothing to zero out\r
103 \r
104 NextZeroOut: PSHY                           ; save nofZeroOuts\r
105 #ifdef FAR_DATA\r
106              LDAB  1,X+                     ; load page of destination address\r
107              LDY   2,X+                     ; load offset of destination address\r
108              __PIC_JSR(_SET_PAGE)           ; sets the page in the correct page register\r
109 #else   /* FAR_DATA */\r
110              LDY   2,X+                     ; start address and advance *pZeroOut (X = X+4)\r
111 #endif  /* FAR_DATA */\r
112              LDD   2,X+                     ; byte count\r
113 #ifdef  __OPTIMIZE_FOR_SIZE__               /* -os, default */\r
114 NextWord:    CLR   1,Y+                     ; clear memory byte\r
115              __FEED_COP_IN_HLI()            ; feed the COP if necessary /*lint !e505 !e522 asm code */\r
116              DBNE  D, NextWord              ; dec byte count\r
117 #else\r
118              LSRD                           ; /2 and save bit 0 in the carry\r
119              PSHX\r
120              LDX   #0\r
121 LoopClrW:    STX   2,Y+                     ; Word-Clear\r
122              __FEED_COP_IN_HLI()            ; feed the COP if necessary /*lint !e505 !e522 asm code */\r
123              DBNE  D, LoopClrW\r
124              PULX\r
125              BCC   LastClr                  ; handle last byte\r
126              CLR   1,Y+\r
127 LastClr:\r
128 #endif\r
129              PULY                           ; restore nofZeroOuts\r
130              DEY                            ; dec nofZeroOuts\r
131              BNE  NextZeroOut\r
132 CopyDown:\r
133 #ifdef __ELF_OBJECT_FILE_FORMAT__\r
134              LDX   _startupData.toCopyDownBeg ; load address of copy down desc.\r
135 #else\r
136              LDX   _startupData.toCopyDownBeg:2 ; load address of copy down desc.\r
137 #endif\r
138 NextBlock:\r
139              LDD   2,X+                     ; size of init-data -> D\r
140              BEQ   funcInits                ; end of copy down desc.\r
141 #ifdef FAR_DATA\r
142              PSHD                           ; save counter\r
143              LDAB  1,X+                     ; load destination page\r
144              LDY   2,X+                     ; destination address\r
145              __PIC_JSR(_SET_PAGE)           ; sets the destinations page register\r
146              PULD                           ; restore counter\r
147 #else  /* FAR_DATA */\r
148              LDY   2,X+                     ; load destination address\r
149 #endif /* FAR_DATA */\r
150 \r
151 #ifdef  __OPTIMIZE_FOR_SIZE__               /* -os, default */\r
152 Copy:        MOVB  1,X+,1,Y+                ; move a byte from ROM to the data area\r
153              __FEED_COP_IN_HLI()            ; feed the COP if necessary /*lint !e505 !e522 asm code */\r
154              DBNE  D,Copy                   ; copy-byte loop\r
155 #else\r
156              LSRD                           ; /2 and save bit 0 in the carry\r
157 Copy:        MOVW  2,X+,2,Y+                ; move a word from ROM to the data area\r
158              __FEED_COP_IN_HLI()            ; feed the COP if necessary /*lint !e505 !e522 asm code */\r
159              DBNE  D,Copy                   ; copy-word loop\r
160              BCC   NextBlock                ; handle last byte?\r
161              MOVB  1,X+,1,Y+                ; copy the last byte\r
162 #endif\r
163              BRA   NextBlock\r
164 funcInits:                                  ; call of global construtors is only in c++ necessary\r
165 #if defined(__cplusplus)\r
166 #if defined(__ELF_OBJECT_FILE_FORMAT__)\r
167 #if defined( __BANKED__) || defined(__LARGE__)\r
168              LDY   _startupData.nofInitBodies; load number of cpp.\r
169              BEQ   done                     ; if cppcount == 0, goto done\r
170              LDX   _startupData.initBodies  ; load address of first module to initialize\r
171 nextInit:\r
172              LEAX   3,X                     ; increment to next init\r
173              PSHX                           ; save address of next function to initialize\r
174              PSHY                           ; save cpp counter\r
175              CALL  [-3,X]                   ; use double indirect call to load the page register also\r
176              PULY                           ; restore cpp counter\r
177              PULX                           ; restore actual address\r
178              DEY                            ; decrement cpp counter\r
179              BNE    nextInit\r
180 #else  /* defined( __BANKED__) || defined(__LARGE__) */\r
181 \r
182              LDD   _startupData.nofInitBodies; load number of cpp.\r
183              BEQ   done                     ; if cppcount == 0, goto done\r
184              LDX   _startupData.initBodies  ; load address of first module to initialize\r
185 nextInit:\r
186              LDY   2,X+                     ; load address of first module to initialize\r
187              PSHD\r
188              PSHX                           ; save actual address\r
189              JSR   0,Y                      ; call initialization function\r
190              PULX                           ; restore actual address\r
191              PULD                           ; restore cpp counter\r
192              DBNE D, nextInit\r
193 #endif /* defined( __BANKED__) || defined(__LARGE__) */\r
194 #else /* __ELF_OBJECT_FILE_FORMAT__  */\r
195              LDX   _startupData.mInits      ; load address of first module to initialize\r
196 #if defined( __BANKED__) || defined(__LARGE__)\r
197 nextInit:    LDY   3,X+                     ; load address of initialization function\r
198              BEQ   done                     ; stop when address  == 0\r
199                                             ; in common environments the offset of a function is never 0, so this test could be avoided\r
200 #ifdef __InitFunctionsMayHaveOffset0__\r
201              BRCLR -1,X, done, 0xff         ; stop when address  == 0\r
202 #endif  /* __InitFunctionsMayHaveOffset0__ */\r
203              PSHX                           ; save address of next function to initialize\r
204              CALL  [-3,X]                   ; use double indirect call to load the page register also\r
205 #else  /* defined( __BANKED__) || defined(__LARGE__) */\r
206 nextInit:\r
207              LDY   2,X+                     ; load address of first module to initialize\r
208              BEQ   done                     ; stop when address of function == 0\r
209              PSHX                           ; save actual address\r
210              JSR   0,Y                      ; call initialization function\r
211 #endif /* defined( __BANKED__) || defined(__LARGE__) */\r
212              PULX                           ; restore actual address\r
213              BRA   nextInit\r
214 #endif  /* __ELF_OBJECT_FILE_FORMAT__  */\r
215 done:\r
216 #endif /* __cplusplus */\r
217    }\r
218 }\r
219 \r
220 #if defined( __ELF_OBJECT_FILE_FORMAT__) && defined(__cplusplus )\r
221 \r
222 #if !defined(FAR_DATA) && (defined( __BANKED__) || defined(__LARGE__))\r
223 static void __far Fini(void)\r
224 #else\r
225 static void Fini(void)\r
226 #endif\r
227 {\r
228 /* purpose:     1) call global destructors in C++ */\r
229    __asm {\r
230 #if defined( __BANKED__) || defined(__LARGE__)\r
231 \r
232              LDY   _startupData.nofFiniBodies; load number of cpp.\r
233              BEQ   done                     ; if cppcount == 0, goto done\r
234              LDX   _startupData.finiBodies  ; load address of first module to finalize\r
235 nextInit2:\r
236              LEAX   3,X                     ; increment to next init\r
237              PSHX                           ; save address of next function to finalize\r
238              PSHY                           ; save cpp counter\r
239              CALL  [-3,X]                   ; use double indirect call to load the page register also\r
240              PULY                           ; restore cpp counter\r
241              PULX                           ; restore actual address\r
242              DEY                            ; decrement cpp counter\r
243              BNE    nextInit2\r
244 #else  /* defined( __BANKED__) || defined(__LARGE__) */\r
245 \r
246              LDD   _startupData.nofFiniBodies; load number of cpp.\r
247              BEQ   done                     ; if cppcount == 0, goto done\r
248              LDX   _startupData.finiBodies  ; load address of first module to finalize\r
249 nextInit2:\r
250              LDY   2,X+                     ; load address of first module to finalize\r
251              PSHD\r
252              PSHX                           ; save actual address\r
253              JSR   0,Y                      ; call finalize function\r
254              PULX                           ; restore actual address\r
255              PULD                           ; restore cpp counter\r
256              DBNE D, nextInit2\r
257 #endif /* defined( __BANKED__) || defined(__LARGE__) */\r
258 done:;\r
259    }\r
260 }\r
261 #endif\r
262 \r
263 \r
264 #include "non_bank.sgm"\r
265 \r
266 #pragma MESSAGE DISABLE C12053 /* Stack-pointer change not in debugging-information */\r
267 #pragma NO_FRAME\r
268 #pragma NO_ENTRY\r
269 #pragma NO_EXIT\r
270 \r
271 #ifdef __cplusplus\r
272   extern "C"\r
273 #endif\r
274 \r
275 /* The function _Startup must be called in order to initialize global variables and to call main */\r
276 /* You can adapt this function or call it from your startup code to implement a different startup */\r
277 /* functionality. */\r
278 \r
279 /* You should also setup the needed IO registers as WINDEF (HC12A4 only) or the COP registers to run */\r
280 /* on hardware */\r
281 \r
282 /* to set the reset vector several ways are possible : */\r
283 /* 1. define the function with "interrupt 0" as done below in the first case */\r
284 /* 2. add the following line to your prm file : VECTOR ADDRESS 0xfffe _Startup */\r
285 /* of course, even more posibilities exists */\r
286 /* the reset vector must be set so that the application has a defined entry point */\r
287 \r
288 #define STARTUP_FLAGS_NOT_INIT_SP   (1<<1)\r
289 \r
290 #if defined(__SET_RESET_VECTOR__)\r
291 void __interrupt 0 _Startup(void) {\r
292 #else\r
293 void _Startup(void) {\r
294 #endif\r
295 /*  purpose:    1)  initialize the stack\r
296                 2)  initialize the RAM, copy down init data etc (Init)\r
297                 3)  call main;\r
298     parameters: NONE\r
299     called from: _PRESTART-code generated by the Linker \r
300                  or directly referenced by the reset vector */\r
301   for(;;) { /* forever: initialize the program; call the root-procedure */\r
302       if (!(_startupData.flags&STARTUP_FLAGS_NOT_INIT_SP)) {\r
303         /* initialize the stack pointer */\r
304         INIT_SP_FROM_STARTUP_DESC(); /*lint !e522 asm code */ /* HLI macro definition in hidef.h */\r
305       }\r
306 \r
307 #ifdef _HCS12_SERIALMON\r
308       /* for Monitor based software remap the RAM & EEPROM to adhere\r
309          to EB386. Edit RAM and EEPROM sections in PRM file to match these. */\r
310       ___INITRG = 0x00;  /* lock registers block to 0x0000 */\r
311       ___INITRM = 0x39;  /* lock Ram to end at 0x3FFF */\r
312       ___INITEE = 0x09;  /* lock EEPROM block to end at 0x0fff */\r
313 #endif\r
314       \r
315       /* Here user defined code could be inserted, the stack could be used */\r
316 #if defined(_DO_DISABLE_COP_)\r
317       _DISABLE_COP();\r
318 #endif \r
319 \r
320       /* Example : Set up WinDef Register to allow Paging */\r
321 #ifdef HC812A4 /* HC12 A4 derivative needs WINDEF to configure which pages are available */\r
322 #if  (__ENABLE_EPAGE__ != 0 ||  __ENABLE_DPAGE__ != 0 || __ENABLE_PPAGE__ != 0)\r
323       WINDEF= __ENABLE_EPAGE__ | __ENABLE_DPAGE__  | __ENABLE_PPAGE__;\r
324 #endif\r
325 #endif\r
326       Init(); /* zero out, copy down, call constructors */\r
327       /* Here user defined code could be inserted, all global variables are initilized */\r
328 #if defined(_DO_ENABLE_COP_)\r
329       _ENABLE_COP(1);\r
330 #endif\r
331 \r
332       /* call main() */\r
333       (*_startupData.main)();\r
334 \r
335       /* call destructors. Only done when this file is compiled as C++ and for the ELF object file format */\r
336       /* the HIWARE object file format does not support this */\r
337 #if defined( __ELF_OBJECT_FILE_FORMAT__) && defined(__cplusplus )\r
338       Fini();\r
339 #endif\r
340 \r
341    } /* end loop forever */\r
342 }\r