1 | ; @(#)crt0.s 1.3 96/05/31 14:40:27, AMD |
---|
2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
---|
3 | ; Copyright 1988, 1989, 1990 Advanced Micro Devices, Inc. |
---|
4 | ; |
---|
5 | ; This software is the property of Advanced Micro Devices, Inc (AMD) which |
---|
6 | ; specifically grants the user the right to modify, use and distribute this |
---|
7 | ; software provided this notice is not removed or altered. All other rights |
---|
8 | ; are reserved by AMD. |
---|
9 | ; |
---|
10 | ; AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS |
---|
11 | ; SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL |
---|
12 | ; DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR |
---|
13 | ; USE OF THIS SOFTWARE. |
---|
14 | ; |
---|
15 | ; So that all may benefit from your experience, please report any problems |
---|
16 | ; or suggestions about this software to the 29K Technical Support Center at |
---|
17 | ; 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or |
---|
18 | ; 0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118. |
---|
19 | ; |
---|
20 | ; Advanced Micro Devices, Inc. |
---|
21 | ; 29K Support Products |
---|
22 | ; Mail Stop 573 |
---|
23 | ; 5900 E. Ben White Blvd. |
---|
24 | ; Austin, TX 78741 |
---|
25 | ; 800-292-9263 |
---|
26 | ; |
---|
27 | ; /* $Id$ */ |
---|
28 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
---|
29 | |
---|
30 | .file "crt0.s" |
---|
31 | |
---|
32 | ; crt0.s version 3.3-0 |
---|
33 | ; |
---|
34 | ; This module gets control from the OS. |
---|
35 | ; It saves away the Am29027 Mode register settings and |
---|
36 | ; then sets up the pointers to the resident spill and fill |
---|
37 | ; trap handlers. It then establishes argv and argc for passing |
---|
38 | ; to main. It then calls _main. If main returns, it calls _exit. |
---|
39 | ; |
---|
40 | ; void = start( ); |
---|
41 | ; NOTE - not C callable (no lead underscore) |
---|
42 | ; |
---|
43 | .include "sysmac.h" |
---|
44 | ; |
---|
45 | ; |
---|
46 | .extern V_SPILL, V_FILL |
---|
47 | ; .comm __29027Mode, 8 ; A shadow of the mode register |
---|
48 | .comm __LibInit, 4 |
---|
49 | |
---|
50 | .text |
---|
51 | .extern _main, _exit, _atexit |
---|
52 | |
---|
53 | .word 0 ; Terminating tag word |
---|
54 | .global start |
---|
55 | start: |
---|
56 | sub gr1, gr1, 6 * 4 |
---|
57 | asgeu V_SPILL, gr1, rab ; better not ever happen |
---|
58 | add lr1, gr1, 6 * 4 |
---|
59 | |
---|
60 | ; |
---|
61 | ; Save the initial value of the Am29027's Mode register |
---|
62 | ; |
---|
63 | ; If your system does not enter crt0 with value for Am29027's Mode |
---|
64 | ; register in gr96 and gr97, and also the coprocessor is active |
---|
65 | ; uncomment the next 4 instructions. |
---|
66 | ; |
---|
67 | ; const gr96, 0xfc00820 |
---|
68 | ; consth gr96, 0xfc00820 |
---|
69 | ; const gr97, 0x1375 |
---|
70 | ; store 1, 3, gr96, gr97 |
---|
71 | ; |
---|
72 | ; const gr98, __29027Mode |
---|
73 | ; consth gr98, __29027Mode |
---|
74 | ; store 0, 0, gr96, gr98 |
---|
75 | ; add gr98, gr98, 4 |
---|
76 | ; store 0, 0, gr97, gr98 |
---|
77 | ; |
---|
78 | ; Now call the system to setup the spill and fill trap handlers |
---|
79 | ; |
---|
80 | const lr3, spill |
---|
81 | consth lr3, spill |
---|
82 | const lr2, V_SPILL |
---|
83 | syscall setvec |
---|
84 | const lr3, fill |
---|
85 | consth lr3, fill |
---|
86 | const lr2, V_FILL |
---|
87 | syscall setvec |
---|
88 | |
---|
89 | ; |
---|
90 | ; atexit(_fini) |
---|
91 | ; |
---|
92 | ; const lr0, _atexit |
---|
93 | ; consth lr0, _atexit |
---|
94 | ; const lr2,__fini |
---|
95 | ; calli lr0,lr0 |
---|
96 | ; consth lr2,__fini |
---|
97 | ; |
---|
98 | ; Now call _init |
---|
99 | ; |
---|
100 | ; const lr0, __init |
---|
101 | ; consth lr0, __init |
---|
102 | ; calli lr0,lr0 |
---|
103 | ; nop |
---|
104 | |
---|
105 | ; |
---|
106 | ; Get the argv base address and calculate argc. |
---|
107 | ; |
---|
108 | syscall getargs |
---|
109 | add lr3, v0, 0 ; argv |
---|
110 | add lr4, v0, 0 |
---|
111 | constn lr2, -1 |
---|
112 | argcloop: ; scan for NULL terminator |
---|
113 | load 0, 0, gr97, lr4 |
---|
114 | add lr4, lr4, 4 |
---|
115 | cpeq gr97, gr97, 0 |
---|
116 | jmpf gr97, argcloop |
---|
117 | add lr2, lr2, 1 |
---|
118 | ; |
---|
119 | ; Now call LibInit, if there is one. To aid runtime libraries |
---|
120 | ; that need to do some startup initialization, we have created |
---|
121 | ; a bss variable called LibInit. If the library doesn't need |
---|
122 | ; any run-time initialization, the variable is still 0. If the |
---|
123 | ; library does need run-time initialization, the library will |
---|
124 | ; contain a definition like |
---|
125 | ; void (*_LibInit)(void) = LibInitFunction; |
---|
126 | ; The linker will match up our bss LibInit with this data LibInit |
---|
127 | ; and the variable will not be 0. This results in the LibInit routine |
---|
128 | ; being called via the calli instruction below. |
---|
129 | ; |
---|
130 | const lr0, __LibInit |
---|
131 | consth lr0, __LibInit |
---|
132 | load 0, 0, lr0, lr0 |
---|
133 | cpeq gr96, lr0, 0 |
---|
134 | jmpt gr96, NoLibInit |
---|
135 | nop |
---|
136 | calli lr0, lr0 |
---|
137 | nop |
---|
138 | NoLibInit: |
---|
139 | |
---|
140 | ; |
---|
141 | ; Call RAMInit to initialize the data memory. |
---|
142 | ; |
---|
143 | ; The following code segment was used to create the two flavors of the |
---|
144 | ; run-time initialization routines (crt0_1.o, and crt0_2.o) as described |
---|
145 | ; in the User's Manual. If osboot is used to create a stand-alone |
---|
146 | ; application, or the call to RAMInit is made in the start-up routine, |
---|
147 | ; then the following is not needed. |
---|
148 | ; |
---|
149 | ; .ifdef ROM_LOAD |
---|
150 | ; .extern RAMInit |
---|
151 | ; |
---|
152 | ; const lr0, RAMInit |
---|
153 | ; consth lr0, RAMInit |
---|
154 | ; calli gr96, lr0 |
---|
155 | ; nop |
---|
156 | ; .else |
---|
157 | ; nop |
---|
158 | ; nop |
---|
159 | ; nop |
---|
160 | ; nop |
---|
161 | ; .endif |
---|
162 | |
---|
163 | ; |
---|
164 | ; Uncomment the following .comm, if you ARE NOT using osboot as released |
---|
165 | ; with the High C 29K product, AND plan to use the romcoff utility to |
---|
166 | ; move code and/or data sections to ROM. |
---|
167 | ; |
---|
168 | ; .comm RAMInit, 4 |
---|
169 | ; |
---|
170 | ; Furthermore, if the above is uncommented, then use the following logic |
---|
171 | ; to call the RAMInit function, if needed. |
---|
172 | ; |
---|
173 | ; const lr0, RAMInit |
---|
174 | ; consth lr0, RAMInit |
---|
175 | ; load 0, 0, gr96, lr0 |
---|
176 | ; cpeq gr96, gr96, 0 ; nothing there? |
---|
177 | ; jmpt gr96, endRAMInit ; yes, nothing to init |
---|
178 | ; nop |
---|
179 | ; calli gr96, lr0 ; no, then instruction found |
---|
180 | ; nop ; execute function. |
---|
181 | ; |
---|
182 | |
---|
183 | |
---|
184 | ; |
---|
185 | ; call main, passing it 2 arguments. main( argc, argv ) |
---|
186 | ; |
---|
187 | const lr0, _main |
---|
188 | consth lr0, _main |
---|
189 | calli lr0, lr0 |
---|
190 | nop |
---|
191 | ; |
---|
192 | ; call exit |
---|
193 | ; |
---|
194 | const lr0, _exit |
---|
195 | consth lr0, _exit |
---|
196 | calli lr0, lr0 |
---|
197 | add lr2, gr96, 0 |
---|
198 | ; |
---|
199 | ; Should never get here, but just in case |
---|
200 | ; |
---|
201 | loop: |
---|
202 | syscall exit |
---|
203 | jmp loop |
---|
204 | nop |
---|
205 | .sbttl "Spill and Fill trap handlers" |
---|
206 | .eject |
---|
207 | ; |
---|
208 | ; SPILL, FILL trap handlers |
---|
209 | ; |
---|
210 | ; Note that these Spill and Fill trap handlers allow the OS to |
---|
211 | ; assume that the only registers of use are between gr1 and rfb. |
---|
212 | ; Therefore, if the OS desires to, it may simply preserve from |
---|
213 | ; lr0 for (rfb-gr1)/4 registers when doing a context save. |
---|
214 | ; |
---|
215 | ; |
---|
216 | ; Here is the spill handler |
---|
217 | ; |
---|
218 | ; spill registers from [*gr1..*rab) |
---|
219 | ; and move rab downto where gr1 points |
---|
220 | ; |
---|
221 | ; rab must change before rfb for signals to work |
---|
222 | ; |
---|
223 | ; On entry: rfb - rab = windowsize, gr1 < rab |
---|
224 | ; Near the end: rfb - rab > windowsize, gr1 == rab |
---|
225 | ; On exit: rfb - rab = windowsize, gr1 == rab |
---|
226 | ; |
---|
227 | .global spill |
---|
228 | spill: |
---|
229 | sub tav, rab, gr1 ; tav = number of bytes to spill |
---|
230 | srl tav, tav, 2 ; change byte count to word count |
---|
231 | sub tav, tav, 1 ; make count zero based |
---|
232 | mtsr CR, tav ; set Count Remaining register |
---|
233 | sub tav, rab, gr1 |
---|
234 | sub tav, rfb, tav ; pull down free bound and save it in rab |
---|
235 | add rab, gr1, 0 ; first pull down allocate bound |
---|
236 | storem 0, 0, lr0, tav ; store lr0..lr(tav) into rfb |
---|
237 | jmpi tpc ; return... |
---|
238 | add rfb, tav, 0 |
---|
239 | ; |
---|
240 | ; Here is the fill handler |
---|
241 | ; |
---|
242 | ; fill registers from [*rfb..*lr1) |
---|
243 | ; and move rfb upto where lr1 points. |
---|
244 | ; |
---|
245 | ; rab must change before rfb for signals to work |
---|
246 | ; |
---|
247 | ; On entry: rfb - rab = windowsize, lr1 > rfb |
---|
248 | ; Near the end: rfb - rab < windowsize, lr1 == rab + windowsize |
---|
249 | ; On exit: rfb - rab = windowsize, lr1 == rfb |
---|
250 | ; |
---|
251 | .global fill |
---|
252 | fill: |
---|
253 | const tav, 0x80 << 2 |
---|
254 | or tav, tav, rfb ; tav = ((rfb>>2) | 0x80)<<2 == [rfb]<<2 |
---|
255 | mtsr IPA, tav ; ipa = [rfb]<<2 == 1st reg to fill |
---|
256 | ; gr0 is now the first reg to fill |
---|
257 | sub tav, lr1, rfb ; tav = number of bytes to fill |
---|
258 | add rab, rab, tav ; push up allocate bound |
---|
259 | srl tav, tav, 2 ; change byte count to word count |
---|
260 | sub tav, tav, 1 ; make count zero based |
---|
261 | mtsr CR, tav ; set Count Remaining register |
---|
262 | loadm 0, 0, gr0, rfb ; load registers |
---|
263 | jmpi tpc ; return... |
---|
264 | add rfb, lr1, 0 ; ... first pushing up free bound |
---|
265 | |
---|
266 | ; |
---|
267 | ; The __init function |
---|
268 | ; |
---|
269 | ; .sect .init,text |
---|
270 | ; .use .init |
---|
271 | ; .global __init |
---|
272 | ;__init: |
---|
273 | ; sub gr1,gr1,16 |
---|
274 | ; asgeu V_SPILL,gr1,gr126 |
---|
275 | ; add lr1,gr1,24 |
---|
276 | ; |
---|
277 | ; |
---|
278 | ; The __fini function |
---|
279 | ; |
---|
280 | ; .sect .fini,text |
---|
281 | ; .use .fini |
---|
282 | ; .global __fini |
---|
283 | ;__fini: |
---|
284 | ; sub gr1,gr1,16 |
---|
285 | ; asgeu V_SPILL,gr1,gr126 |
---|
286 | ; add lr1,gr1,24 |
---|
287 | ; |
---|
288 | .end |
---|