summaryrefslogtreecommitdiff
path: root/digital/zigbit/bitcloud/stack/Components/HAL/avr/atmega1281/common/src/cstartup.s90
blob: ce20e61532325a04218a4831c76c8e7113e10c5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
;----------------------------------------------------------------------------
;
;   This module contains the AVR C and EC++ startup
;   routine and must usually be tailored to suit
;   customer's hardware.
;
;   File version:   $Revision: 1.13 $
;
;----------------------------------------------------------------------------
#include    <macros.m90>

;----------------------------------------------------------------------------
; Set up the INTVEC segment with a reset vector
;----------------------------------------------------------------------------
        MODULE    ?RESET

    COMMON  INTVEC:CODE:ROOT(1) ; Align at an even address

        EXTERN  ?BC_STARTUP
        PUBLIC  __bitcloud_start
        PUBLIC  ?RESET

    ORG $0
__bitcloud_start:
?RESET:
    XJMP    ?BC_STARTUP

        ENDMOD

;----------------------------------------------------------------------------
; Forward declarations of segments used in initialization
;----------------------------------------------------------------------------
    RSEG    CSTACK:DATA:NOROOT(0)
    RSEG    RSTACK:DATA:NOROOT(0)

;----------------------------------------------------------------------------
; Perform C initialization
;----------------------------------------------------------------------------
    MODULE  ?BC_STARTUP

    EXTERN  __low_level_init
    EXTERN  __segment_init
#ifdef _ECLIB_ECPP
    EXTERN  __call_ctors
#endif /* _ECLIB_ECPP */
    EXTERN  main
    EXTERN  exit
    EXTERN  _exit
    ; jump NULL handler
    EXTERN halWdtInit

;----------------------------------------------------------------------------
; If the return address stack is located in external SRAM, make sure that
; you have uncommented the correct code in __low_level_init!!!
;----------------------------------------------------------------------------
    RSEG    CODE:CODE:NOROOT(1)
    PUBLIC  ?BC_STARTUP
    PUBLIC  __RESTART
    EXTERN ?RESET

__RESTART:
?BC_STARTUP:
    XCALL   halWdtInit ; call stop wdt, read reset reason and jump NULL handler

#if A90_POINTER_REG_SIZE > 2
    PUBLIC  ?zero_reg_initialization

?zero_reg_initialization:
    CLR R15
    OUT RAMPD,R15
#endif

    REQUIRE ?SETUP_STACK
    REQUIRE ?RESET

    RSEG    CODE:CODE:NOROOT(1)
    PUBLIC  __RSTACK_in_external_ram

__RSTACK_in_external_ram:
    LDI     R16,0xC0
    OUT     0x35,R16    ;Enable the external SRAM with a wait state

    RSEG    CODE:CODE:NOROOT(1)
    PUBLIC  __RSTACK_in_external_ram_new_way
    EXTERN  __?XMCRA

__RSTACK_in_external_ram_new_way:
    LDI     R16,0x8C        ;SRE=1,SRL2=0,SRL1=0,SRL0=0,SRW11=1,SRW10=1,SRW01=0,SRW00=0
    STS     __?XMCRA,R16    ;Enable the external SRAM with maximum wait state.

;----------------------------------------------------------------------------
; Set up the CSTACK and RSTACK pointers.
;----------------------------------------------------------------------------
    RSEG    CODE:CODE:NOROOT(1)
    ;; Fill up stacks with repeated pattern 0xCD (same pattern is used by IAR stack gauge)
?FILL_RSTACK:
    LDI R16, 0xCD
    LDI X0, LOW(SFB(RSTACK))
    LDI Y0, LOW(SFE(RSTACK))    
#if A90_POINTER_REG_SIZE > 1
    LDI X1, HIGH(SFB(RSTACK))
    LDI Y1, HIGH(SFE(RSTACK))    
#else
    LDI X1, 0
    LDI Y1, 0
#endif    
?FILL_RSTACK_LOOP:
    ST X+, R16       
    CP X0, Y0
    CPC X1, Y1
    BRNE ?FILL_RSTACK_LOOP   

?FILL_CSTACK:    
    LDI X0, LOW(SFB(CSTACK))
    LDI Y0, LOW(SFE(CSTACK))    
#if A90_POINTER_REG_SIZE > 1
    LDI X1, HIGH(SFB(CSTACK))
    LDI Y1, HIGH(SFE(CSTACK))    
#else
    LDI X1, 0
    LDI Y1, 0
#endif
?FILL_CSTACK_LOOP:
    ST X+, R16
    CP X0, Y0
    CPC X1, Y1
    BRNE ?FILL_CSTACK_LOOP

?SETUP_STACK:
    ;; Return address stack (RSTACK)
    LDI R16,LOW(SFE(RSTACK)-1)
    OUT 0x3D,R16
#if A90_POINTER_REG_SIZE > 1
    LDI R16,HIGH(SFE(RSTACK)-1)
    OUT 0x3E,R16
#endif

    ;; Data stack (CSTACK)
    LDI Y0,LOW(SFE(CSTACK))
#if A90_POINTER_REG_SIZE > 1
#if MEMORY_MODEL == TINY_MEMORY_MODEL
    LDI Y1,0
#else
    LDI Y1,HIGH(SFE(CSTACK))
#endif
#if A90_POINTER_REG_SIZE > 2
    LDI Z0,HWRD(SFB(CSTACK))
    OUT     RAMPY,Z0
#endif
#endif

#if A90_POINTER_REG_SIZE > 2
; Nothing here, the things previously here has been done earlier.
#else
    REQUIRE ?call_low_level_init

;----------------------------------------------------------------------------
; Clear R15 so that it can be used as zero register by the code generator.
; The compiler will emit a "REQUIRE ?zero_reg_initialization" statement if
; this optimization has been enabled.
;----------------------------------------------------------------------------
    RSEG    CODE:CODE:NOROOT(1)
    PUBLIC  ?zero_reg_initialization

?zero_reg_initialization:
    CLR R15

;----------------------------------------------------------------------------
; Call __low_level_init to do low level initializatons. Modify the supplied
; __low_level_init module to add your own initialization code or to
; remove segment initialization (by returning 0).
;----------------------------------------------------------------------------
    RSEG    CODE:CODE:NOROOT(1)
#endif
    PUBLIC  ?call_low_level_init

?call_low_level_init:
    XCALL   __low_level_init

    REQUIRE ?cstartup_call_main

;----------------------------------------------------------------------------
; Call __segment_init to initialize segments.
;----------------------------------------------------------------------------
    RSEG    CODE:CODE:NOROOT(1)
    PUBLIC  ?need_segment_init

?need_segment_init:
    TST P0
    BREQ    ?skip_segment_init
    XCALL   __segment_init
?skip_segment_init:

;----------------------------------------------------------------------------
;   Call the constructors of all global objects. This code will only
;   be used if any EC++ modules defines global objects that need to
;   have its constructor called before main.
;----------------------------------------------------------------------------
#ifdef _ECLIB_ECPP
    RSEG    DIFUNCT:CODE:NOROOT(0)
    RSEG    CODE:CODE:NOROOT(1)

    PUBLIC  ?call_ctors

?call_ctors:
#ifdef __HAS_ELPM__
    LDI P0,LOW(SFB(DIFUNCT))
    LDI P1,LOW(SFB(DIFUNCT) >> 8)
    LDI P2,SFB(DIFUNCT) >> 16

    LDI Q0,LOW(SFE(DIFUNCT))
    LDI Q1,LOW(SFE(DIFUNCT) >> 8)
    LDI Q2,SFE(DIFUNCT) >> 16
#else
    LDI P0,LOW(SFB(DIFUNCT))
    LDI P1,SFB(DIFUNCT) >> 8

    LDI P2,LOW(SFE(DIFUNCT))
    LDI P3,SFE(DIFUNCT) >> 8
#endif

    XCALL   __call_ctors
#endif /* _ECLIB_ECPP */

;----------------------------------------------------------------------------
;   Call main
;----------------------------------------------------------------------------
    RSEG    CODE:CODE:NOROOT(1)

    PUBLIC  ?cstartup_call_main

?cstartup_call_main:
    XCALL   main
    XCALL   exit
    XJMP    _exit

    END

;----------------------------------------------------------------------------
;  $Log: cstartup.s90 $
;  Revision 1.13  2005/02/09 16:34:50Z  IPEO
;  Revision 1.12  2005/02/09 12:12:46Z  IPEO
;  Revision 1.11  2005/02/09 11:32:04Z  IPEO
;  Revision 1.10  2005/01/26 13:56:34Z  IPEO
;  Revision 1.9  2005/01/17 15:24:14Z  IPEO
;  Revision 1.8  2003/11/07 16:34:04Z  IPEO
;  Revision 1.7  2003/09/04 13:48:25Z  IPEO
;  Revision 1.6  2003/08/22 14:09:09Z  IPEO
;  Revision 1.5  2003/08/22 08:54:09Z  IPEO
;  Revision 1.4  2003/08/20 08:38:55Z  IPEO