Initial revision
[ssr] / StraySrc / SDLS / DLLManager / s / misc
1 ;
2 ; misc.s
3 ;
4 ; Miscellaneous things for DLL Manager
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Dynamic Linking System (SDLS)
12 ;
13 ; SDLS is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; SDLS is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with SDLS. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard stuff -------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sh.wSpace
35
36 GET sh.messages
37
38 ;----- Some magic numbers ---------------------------------------------------
39
40 misc_entkrnl EQU 4*48 ;48 kernel entries
41 misc_entclib EQU 4*183 ;183 CLib entries
42 misc_wspkrnl EQU &31C ;&31C bytes of kernel vars
43 misc_wspclib EQU &B48 ;&B48 bytes of clib vars
44 misc_clibVer EQU 5 ;Current CLib version
45
46 ;----- External routines ----------------------------------------------------
47
48 AREA |DLLM$$Code|,CODE,READONLY
49
50 ; --- misc_getCLib ---
51 ;
52 ; On entry: --
53 ; On exit: --
54
55 EXPORT misc_getCLib
56 misc_getCLib ROUT
57
58 BIC R14,R14,#V_flag ;Clear error indicator
59 STMFD R13!,{R1-R6,R14} ;Store registers nicely
60
61 ; --- Allocate workspace for SharedCLibrary to corrupt ---
62 ;
63 ; The SharedCLibrary wants some workspace that it can
64 ; initialise. We're not actually using it, so we don't need
65 ; any workspace, although it still wants some. So we
66 ; allocate some for a bit, and get rid of it again.
67
68 MOV R0,#6 ;Allocate space for CLib
69 LDR R4,=misc_wspkrnl ;Amount of space for kernel
70 LDR R5,=misc_wspclib ;Amount of space for C lib
71 ADD R3,R3,#1024 ;Add an extra 1K for luck
72 ADD R3,R4,R5 ;Amount of space reqd
73 SWI XOS_Module ;Try to allocate memory
74 LDMVSFD R13!,{R1-R6,PC} ;Return if it failed
75
76 ; --- Set up stub table temporarily on the stack ---
77
78 SUB R13,R13,#44 ;Reserve space for stub table
79 MOV R0,R13 ;Point to base of table
80 STR R2,[R0,#12] ;Store workspace pointer
81 ADD R2,R2,R4 ;Limit of kernel space
82 STR R2,[R0,#16] ;Store workspace pointer
83 STR R2,[R0,#32] ;Store as Clib pointer
84 ADD R2,R2,R5 ;Limit of C lib space
85 STR R2,[R0,#36] ;Store as C lib limit
86
87 ; --- Set up pointers to branch table in the stub block ---
88
89 ADR R2,misc__stubs ;Point to entry point table
90 LDR R4,=misc_entkrnl ;Get size of kernel entries
91 LDR R5,=misc_entclib ;Get size of C lib entries
92 STR R2,[R0,#4] ;Store kernel entry start
93 ADD R2,R2,R4 ;Limit of kernel entries
94 STR R2,[R0,#8] ;Store kernel entry limit
95 STR R2,[R0,#24] ;Store C lib entry start
96 ADD R2,R2,R5 ;Limit of C lib entries
97 STR R2,[R0,#28] ;Store C lib entry limit
98
99 ; --- Finish off the stub table ---
100
101 MOV R2,#1 ;Kernel chunk ID
102 STR R2,[R0,#0] ;Store in correct place
103 MOV R2,#2 ;C lib chunk ID
104 STR R2,[R0,#20] ;Store in correct place
105 MOV R2,#-1 ;Chunk table end marker
106 STR R2,[R0,#40] ;Store at end of table
107
108 ; --- Get the branch table from the C Library ---
109
110 LDR R1,[R0,#36] ;Get limit of that space
111 ADD R2,R1,#1024 ;Point to end of block
112 MOV R3,#-1 ;No zero-inited space
113 MOV R4,#0 ;No static data to move
114 MOV R5,#-1 ;No static data to move
115 MOV R6,#&1000 ;4096 byte stack please :-)
116 SWI XSharedCLibrary_LibInitModule ;Do the stuff
117 ADRVSL R5,msg_errNoCLib ;If it failed, point to err
118 MOVVC R5,#0 ;Otherwise, clear error mark
119
120 ; --- Tidy up the stack and the temporary space ---
121
122 MOV R0,#7 ;Free that memory I nabbed
123 LDR R2,[R13,#12] ;Get pointer to the space
124 ADD R13,R13,#44 ;Move stack pointer back
125 SWI XOS_Module ;Free it now
126 LDMVSFD R13!,{R1-R6,PC} ;If that failed, return error
127 MOVS R0,R5 ;Copy error pointer
128 LDMNEFD R13!,{R1-R6,R14} ;If there was an error, unstk
129 ORRNES PC,R14,#V_flag ;And quit with V set
130
131 ; --- Make sure the library was new enough ---
132
133 CMP R6,#misc_clibVer ;Ensure returned version
134 ADRLTL R0,msg_errOldCLib ;If too low, point to error
135 LDMFD R13!,{R1-R6,R14} ;Get registers anyway
136 ORRLTS PC,R14,#V_flag ;If too old, quit with V set
137 BICS PC,R14,#V_flag ;Otherwise, clear V flag
138
139 LTORG
140
141 ; --- misc_copyStubs ---
142 ;
143 ; On entry: R0 == pointer to stubs table
144 ; On exit: --
145
146 EXPORT misc_copyStubs
147 misc_copyStubs ROUT
148
149 STMFD R13!,{R0-R3,R14} ;Preserve registers
150 ADR R1,misc__stubs ;Get pointer to stub table
151
152 LDR R14,[R1,#0] ;Load the first entry
153 CMP R14,#0 ;Has it been filled in?
154 BLEQ misc_getCLib ;No -- find C library stuff
155 BVS %80misc_copyStubs ;If it failed, return error
156
157 LDR R0,[R13],#4 ;Load branch table pointer
158 LDR R2,=misc_entkrnl+misc_entclib ;Get size of table
159 SUB R3,R1,R0 ;Find ptr_diff 'tween tables
160 MOV R3,R3,LSR #2 ;Shift off bottom two 0 bits
161
162 SUBS R2,R2,#4 ;Decrement counter for table
163 00misc_copyStubs
164 LDR R14,[R1,R2] ;Get the word from the table
165 ADD R14,R14,R3 ;Relocate to destination
166 BIC R14,R14,#&FF000000 ;Clear some bits, for safety
167 ORR R14,R14,#&EA000000 ;Add on the opcode nicely
168 STR R14,[R0,R2] ;Store in destination table
169 SUBS R2,R2,#4 ;Decrement counter for table
170 BGE %00misc_copyStubs ;Continue if anything left
171
172 LDMFD R13!,{R1-R3,R14} ;Return if complete
173 BICS PC,R14,#V_flag ;Return with no errors
174
175 80misc_copyStubs
176 ADD R13,R13,#4 ;Don't restore R0
177 LDMFD R13!,{R1-R3,R14} ;Restore registers
178 ORRS PC,R14,#V_flag ;And return with V set
179
180 LTORG
181
182 ; --- misc_strcmp ---
183 ;
184 ; On entry: R0 == pointer to string A
185 ; R1 == pointer to string B
186 ; R2 == 0 => case insensitive, 1 => case sensitive
187 ;
188 ; On exit: Flags as appropriate
189 ;
190 ; Recently bodged to allow space-separated strings, which CLIGuard approves
191 ; of more.
192
193 EXPORT misc_strcmp
194 misc_strcmp ROUT
195
196 STMFD R13!,{R0,R1,R3,R4,R14}
197 00misc_strcmp LDRB R3,[R0],#1 ;Get a character from A
198 LDRB R4,[R1],#1 ;And one from B
199
200 CMP R2,#0 ;Do we want to do case xlate?
201 BNE %10misc_strcmp ;No -- miss it out then
202
203 SUB R14,R3,#'a' ;Subtract the bottom limit
204 CMP R14,#26 ;Is it a lower case letter?
205 BICLO R3,R3,#&20 ;Yes -- convert to upper
206 SUB R14,R4,#'a' ;Subtract the bottom limit
207 CMP R14,#26 ;Is it a lower case letter?
208 BICLO R4,R4,#&20 ;Yes -- convert to upper
209
210 10misc_strcmp CMP R3,#&21 ;Is that the end of A?
211 MOVCC R3,#0 ;Yes -- pretend it's null
212 CMP R4,#&21 ;Is that the end of B?
213 MOVCC R4,#0 ;Yes -- pretend it's null
214
215 CMP R3,R4 ;How do they match up?
216 LDMNEFD R13!,{R0,R1,R3,R4,PC} ;If NE, return condition
217 CMP R3,#0 ;Is this the end?
218 BNE %00misc_strcmp ;No -- loop again
219 LDMFD R13!,{R0,R1,R3,R4,PC} ;Return to caller
220
221 LTORG
222
223 ; --- misc_memcpy ---
224 ;
225 ; On entry: R0 == pointer to destination
226 ; R1 == pointer to source
227 ; R2 == length to copy
228 ; On exit: --
229
230 EXPORT misc_memcpy
231 misc_memcpy ROUT
232
233 STMFD R13!,{R1-R9,R14} ;Stack registers
234
235 ; --- Do the fast copy of most of the data ---
236
237 00misc_memcpy SUBS R2,R2,#32 ;Check there's 32 bytes left
238 LDMGEIA R1!,{R3-R9,R14} ;Load 8 words (32 bytes)
239 STMGEIA R0!,{R3-R9,R14} ;And store in workspace
240 BGE %00misc_memcpy ;Try for another one
241
242 ; --- Now do a word-by-word copy ---
243
244 ADD R2,R2,#32 ;Reinstate the byte count
245 01misc_memcpy SUBS R2,R2,#4 ;Check there's 4 bytes left
246 LDRGE R14,[R1],#4 ;Load 1 word (4 bytes)
247 STRGE R14,[R0],#4 ;And store in workspace
248 BGE %01misc_memcpy ;Try for another one
249
250 LDMFD R13!,{R1-R9,PC}^ ;Return to caller
251
252 LTORG
253
254 ; --- misc_zinit ---
255 ;
256 ; On entry: R0 == pointer to base of area
257 ; R1 == pointer to limit
258 ; On exit: --
259
260 EXPORT misc_zinit
261 misc_zinit ROUT
262
263 STMFD R13!,{R1-R8,R14} ;Stack registers
264
265 ; --- Set up *lots* of zeroes ---
266
267 MOV R2,#0
268 MOV R3,#0
269 MOV R4,#0
270 MOV R5,#0
271 MOV R6,#0
272 MOV R7,#0
273 MOV R8,#0
274 MOV R14,#0
275
276 ; --- Do the fast copy of most of the data ---
277
278 SUB R1,R1,R0 ;Convert limit to length
279
280 00misc_zinit SUBS R1,R1,#32 ;Check there's 32 bytes left
281 STMGEIA R0!,{R2-R8,R14} ;And store in workspace
282 BGE %00misc_zinit ;Try for another one
283
284 ; --- Now do a word-by-word copy ---
285
286 ADD R1,R1,#32 ;Reinstate the byte count
287 01misc_zinit SUBS R1,R1,#4 ;Check there's 4 bytes left
288 STRGE R14,[R0],#4 ;And store in workspace
289 BGE %01misc_zinit ;Try for another one
290
291 LDMFD R13!,{R1-R8,PC}^ ;Return to caller
292
293 LTORG
294
295 ; --- misc_strcpy ---
296 ;
297 ; On entry: R0 == destination string
298 ; R1 == source string
299 ; On exit: R0 == pointer to terminator of destination
300
301 EXPORT misc_strcpy
302 misc_strcpy ROUT
303
304 STMFD R13!,{R1,R14} ;Keep return address safe
305 00misc_strcpy LDRB R14,[R1],#1 ;Get a byte from source
306 CMP R14,#' ' ;Is it a control character
307 MOVLT R14,#0 ;Yes -- translate to a 0
308 STRB R14,[R0],#1 ;Store in destination
309 BGE %00misc_strcpy ;No -- copy another byte
310 SUB R0,R0,#1 ;Point back at terminator
311 LDMFD R13!,{R1,PC}^ ;Return to caller
312
313 ; --- misc__subst ---
314 ;
315 ; On entry: R0 == Pointer to error message skeleton
316 ; R1 == Filler 1
317 ; R2 == Filler 2
318 ; R3 == Filler 3
319 ; R4 == Filler 4
320 ; R5 == Pointer to buffer
321 ; On exit: --
322
323 misc__subst ROUT
324
325 STMFD R13!,{R1-R5,R14} ;Save some registers
326
327 00misc__subst LDRB R14,[R0],#1 ;Get an input character
328 CMP R14,#'%' ;Is it a '%' sign?
329 BEQ %01misc__subst ;Yes -- deal with it
330 02misc__subst STRB R14,[R5],#1 ;Not special, so store it
331 CMP R14,#0 ;Is it the end of input?
332 BNE %00misc__subst ;No -- get another one
333 LDMFD R13!,{R1-R5,PC}^ ;And return to caller
334
335 01misc__subst LDRB R14,[R0],#1 ;Get the next character
336 SUB R1,R14,#'0' ;Get the index
337 CMP R1,#4 ;Is it in range?
338 BCS %02misc__subst ;No -- just ignore the '%'
339 LDR R1,[R13,R1,LSL #2] ;Load appropriate register
340
341 03misc__subst LDRB R14,[R1],#1 ;Get an input byte
342 CMP R14,#&20 ;Is it the end of the string?
343 STRCSB R14,[R5],#1 ;No -- store it in output
344 BCS %03misc__subst ;... and get another one
345 B %00misc__subst ;Yes -- read main string
346
347 LTORG
348
349 ; --- misc_error ---
350 ;
351 ; On entry: R0 == Pointer to error message skeleton
352 ; R1 == Filler 1
353 ; R2 == Filler 2
354 ; R3 == Filler 3
355 ; R4 == Filler 4
356 ; On exit: R0 == Pointer to constructed error in misc__errorBuf
357
358 EXPORT misc_error
359 misc_error ROUT
360
361 STMFD R13!,{R5,R14}
362 ADR R5,misc__errorBuf ;Point to error buffer
363 LDR R14,[R0],#4 ;Read the error's number
364 STR R14,[R5],#4 ;And store in the new buffer
365 BL misc__subst ;Do the substitution
366 SUB R0,R5,#4 ;Point at the buffer
367 LDMFD R13!,{R5,PC}^ ;And return to caller
368
369 LTORG
370
371 ; --- misc_subst ---
372 ;
373 ; On entry: R0 == Pointer to error message skeleton
374 ; R1 == Filler 1
375 ; R2 == Filler 2
376 ; R3 == Filler 3
377 ; R4 == Filler 4
378 ; On exit: R0 == Pointer to constructed string in misc__errorBuf
379
380 EXPORT misc_subst
381 misc_subst ROUT
382
383 STMFD R13!,{R5,R14}
384 ADR R5,misc__errorBuf ;Point to error buffer
385 BL misc__subst ;Do the substitution
386 MOV R0,R5 ;Point at the buffer
387 LDMFD R13!,{R5,PC}^ ;And return to caller
388
389 LTORG
390
391 ;----- That's all folks -----------------------------------------------------
392
393 END