1;-----------------------------------------------------------------------
2;
3; This file contains the M16C C startup routine and must usually
4; be tailored to suit customer's hardware.
5;
6; Copyright 2002 IAR Systems. All rights reserved.
7;
8; $Revision: 1.16 $
9;
10;-----------------------------------------------------------------------
11
12        MODULE  ?cstart
13
14        PUBLIC  __program_start
15        PUBLIC  __data16_init
16        PUBLIC  __data16_zero
17        PUBLIC  ?cstart_call_ctors
18
19        EXTERN  main
20        EXTERN  exit
21        EXTERN  __call_ctors
22        EXTERN  __low_level_init
23        EXTERN  ?GENERIC_MOVE_LONG_L08
24        EXTERN  RelocatableVectTbl
25
26        ;------------------------------------------------------
27        ; Useful macros
28        ;------------------------------------------------------
29
30        ; Load 24-bit constant value to (high,low)
31LD24    MACRO   value,high,low
32        MOV.B   #BYTE3(value),high
33        MOV.W   #LWRD(value),low
34        ENDM
35
36        ; Load 32-bit constant value to (high,low)
37LD32    MACRO   value,high,low
38        MOV.W   #HWRD(value),high
39        MOV.W   #LWRD(value),low
40        ENDM
41
42        ; Load a stack-pointer with last even address of segment
43LDSTACK MACRO   segment,reg
44        LDC     #sfe(segment), reg
45        ENDM
46
47
48        ;------------------------------------------------------
49        ; __program_start - Reset vector should point to here.
50        ;
51        ; Calls __low_level_init to perform initialization
52        ; before initializing segments and calling main.
53        ; If the function returns 0 no segment initialization
54        ; should take place.
55        ;
56        ; Link with your own version of __low_level_init to
57        ; override the default action: do nothing but return 1.
58        ;------------------------------------------------------
59
60        RSEG    CSTACK
61        RSEG    ISTACK
62        RSEG    CSTART:CODE:NOROOT
63	REQUIRE	call_main
64
65__program_start:
66        LDC     #sfe(ISTACK),   ISP                             ; Set up interrupt stack
67        FCLR    U                                               ; Select interrupt stack
68        LDC     #sfe(CSTACK),   SP                              ; Set up C         stack
69        LDINTB  #RelocatableVectTbl                             ; Set up INTB register
70        JSR.A   __low_level_init                                ; Call __low_level_init
71
72        ;-----------------------------------------------------------
73        ; Run-time test whether we should do segment initialization
74        ;-----------------------------------------------------------
75        TST.B   R0L,            R0L
76        JNE     do_segment_init
77        JMP     skip_segment_init
78
79do_segment_init:
80
81        ;------------------------------------------------------
82        ; Perform segment initialization of DATA16 memory.
83        ;------------------------------------------------------
84
85        RSEG    DATA16_Z
86        RSEG    CSTART:CODE:NOROOT
87
88__data16_zero:
89        MOV.W   #sizeof(DATA16_Z), R3
90        MOV.W   #sfb(DATA16_Z),    A1
91        MOV.B   #0, R0L
92        SSTR.B
93
94        RSEG    DATA16_I
95        RSEG    DATA16_ID
96        RSEG    CSTART:CODE:NOROOT
97
98__data16_init:
99        MOV.W   #sizeof(DATA16_ID), R3
100        MOV.W   #sfb(DATA16_I),     A1
101        LD24    sfb(DATA16_ID),     R1H, A0
102        SMOVF.B
103
104
105
106        RSEG    CSTART:CODE:NOROOT
107skip_segment_init:
108        ; Fall through to next required CSTART segment part
109
110
111        ;------------------------------------------------------
112        ; Call constructors
113        ;------------------------------------------------------
114
115        RSEG    DIFUNCT
116        RSEG    CSTART:CODE:NOROOT
117
118        PUBLIC  ?cstart_call_ctors
119        EXTERN  __call_ctors
120
121?cstart_call_ctors:
122        PUSH.W  #HWRD(sfe(DIFUNCT))
123        PUSH.W  #LWRD(sfe(DIFUNCT))
124        LD32    sfb(DIFUNCT),R2,R0
125        JSR.A   __call_ctors
126
127
128        ; Fall through to next required CSTART segment part
129
130
131        ;------------------------------------------------------
132        ; Call main and exit
133        ;------------------------------------------------------
134
135        ; This segment part is marked as ROOT, since it must
136        ; be preserved by the linker.
137        ;
138        RSEG    CSTART:CODE:NOROOT
139
140call_main:
141        MOV.W   #0, R0  ; Call main with argc = 0
142        JSR.A   main
143        JMP.A   exit    ; Argument to exit is return value of main
144
145        ;------------------------------------------------------
146        ; Fixed interrupt table.
147        ;
148        ; We install all fixed interrupts in a segment called
149        ; INTVEC1. All fixed interrupts have a hard coded name.
150        ; Write an interrupt handler in C using this name, with
151        ; no vector specification, and it will replace the
152        ; default handler.
153        ;------------------------------------------------------
154
155        EXTERN  __undefined_instruction_handler
156        EXTERN  __overflow_handler
157        EXTERN  __break_instruction_handler
158        EXTERN  __address_match_handler
159        EXTERN  __single_step_handler
160        EXTERN  __watchdog_timer_handler
161        EXTERN  __DBC_handler
162        EXTERN  __NMI_handler
163
164        ; Labels for the ID Code Check Function.
165        ; (To be initialized in the linker file)
166        EXTERN  _ID_CODE_1
167        EXTERN  _ID_CODE_2
168        EXTERN  _ID_CODE_3
169        EXTERN  _ID_CODE_4
170        EXTERN  _ID_CODE_5
171        EXTERN  _ID_CODE_6
172        EXTERN  _ID_CODE_7
173        EXTERN  _OFS_VALUE
174
175	PUBLIC ??intvec_start
176
177        COMMON INTVEC1:NOROOT
178??intvec_start:
179        DC24    __undefined_instruction_handler
180        DC8     _ID_CODE_1
181        DC24    __overflow_handler
182        DC8     _ID_CODE_2
183        DC24    __break_instruction_handler
184        DC8     0
185        DC24    __address_match_handler
186        DC8     _ID_CODE_3
187        DC24    __single_step_handler
188        DC8     _ID_CODE_4
189        DC24    __watchdog_timer_handler
190        DC8     _ID_CODE_5
191        DC24    __DBC_handler
192        DC8     _ID_CODE_6
193        DC24    __NMI_handler
194        DC8     _ID_CODE_7
195        DC24    __program_start              ; Reset vector
196        DC8     _OFS_VALUE
197
198        ENDMOD
199
200
201        ;------------------------------------------------------
202        ; Default handlers for fixed interrupts
203        ;------------------------------------------------------
204
205        MODULE  __undefined_instruction
206        EXTERN  ??reit
207        REQUIRE ??reit
208        PUBLIC  __undefined_instruction_handler
209        RSEG    CSTART:CODE:NOROOT(1)
210__undefined_instruction_handler:
211        ; Fall through to ??reit
212        ENDMOD
213
214        MODULE  __overflow
215        EXTERN  ??reit
216        REQUIRE ??reit
217        PUBLIC  __overflow_handler
218        RSEG    CSTART:CODE:NOROOT(1)
219__overflow_handler:
220        ; Fall through to ??reit
221        ENDMOD
222
223        MODULE  __break_instruction
224        EXTERN  ??reit
225        REQUIRE ??reit
226        PUBLIC  __break_instruction_handler
227        RSEG    CSTART:CODE:NOROOT(1)
228__break_instruction_handler:
229        ; Fall through to ??reit
230        ENDMOD
231
232        MODULE  __address_match
233        EXTERN  ??reit
234        REQUIRE ??reit
235        PUBLIC  __address_match_handler
236        RSEG    CSTART:CODE:NOROOT(1)
237__address_match_handler:
238        ; Fall through to ??reit
239        ENDMOD
240
241        MODULE  __single_step
242        EXTERN  ??reit
243        REQUIRE ??reit
244        PUBLIC  __single_step_handler
245        RSEG    CSTART:CODE:NOROOT(1)
246__single_step_handler:
247        ; Fall through to ??reit
248        ENDMOD
249
250        MODULE  __watchdog_timer
251        EXTERN  ??reit
252        REQUIRE ??reit
253        PUBLIC  __watchdog_timer_handler
254        RSEG    CSTART:CODE:NOROOT(1)
255__watchdog_timer_handler:
256        ; Fall through to ??reit
257        ENDMOD
258
259        MODULE  __DBC
260        EXTERN  ??reit
261        REQUIRE ??reit
262        PUBLIC  __DBC_handler
263        RSEG    CSTART:CODE:NOROOT(1)
264__DBC_handler:
265        ; Fall through to ??reit
266        ENDMOD
267
268        MODULE  __NMI
269        EXTERN  ??reit
270        REQUIRE ??reit
271        PUBLIC  __NMI_handler
272        RSEG    CSTART:CODE:NOROOT(1)
273__NMI_handler:
274        ; Fall through to ??reit
275        ENDMOD
276
277        ;------------------------------------------------------
278        ; Return from interrupt
279        ;------------------------------------------------------
280        MODULE    __reit
281        PUBLIC  ??reit
282        RSEG    CSTART:CODE:NOROOT(1)
283	EXTERN ??intvec_start
284	REQUIRE ??intvec_start
285??reit:
286        REIT
287
288        ENDMOD
289
290
291        ;------------------------------------------------------
292        ; FUNCTION: __low_level_init
293        ;
294        ; You can replace this routine by linking with your
295        ; own version.
296        ;
297        ; The default action is to do nothing and return 1.
298        ;------------------------------------------------------
299
300        MODULE  __low_level_init
301        PUBLIC  __low_level_init
302        RSEG    CSTART:CODE:NOROOT
303
304__low_level_init:
305        MOV.B   #1,R0L
306        RTS
307
308        ENDMOD
309
310
311        ;------------------------------------------------------
312        ;  __overflow - This variable is used by the intrinsic
313        ;               functions __RMPA_W_overflow and
314        ;               __RMPA_B_overflow.
315        ;------------------------------------------------------
316
317        MODULE  __overflow
318        PUBLIC  __overflow
319        EXTERN  __data13_zero
320
321        RSEG    DATA13_Z:NEAR:NOROOT
322
323__overflow:
324        DC8     0
325        REQUIRE __data13_zero
326
327        END
328