chiark / gitweb /
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