chiark / gitweb /
Initial revision
[ssr] / StraySrc / Sculptrix / sculptrix / s / vString
1 ;
2 ; vString.s
3 ;
4 ; Parses validation strings for Sculptrix
5 ;
6 ; © 1995-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sculptrix.
12 ;
13 ; Sculptrix 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 ; Sculptrix 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 Sculptrix.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32                 GET     libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36                 GET     sh.wSpace
37
38 ;----- Main code ------------------------------------------------------------
39
40                 AREA    |Module$$Code|,CODE,READONLY
41
42 ; --- vString_read ---
43 ;
44 ; On entry:     R1 == pointer to an icon block
45 ;
46 ; On exit:      CS if there's a border, and
47 ;                 R0 == border info word
48 ;                 R4 == pointer to `inverted' flag byte
49 ;               else CC and
50 ;                 R0, R4 preserved
51 ;
52 ; Use:          Reads an icon's validation string, and extracts relevant
53 ;               information.  The border info word contains what sort of
54 ;               graphics we have to plot around the icon, and any special
55 ;               options thrown in.  A string (for group borders etc.) is
56 ;               copied into the misc buffer if one was found.
57 ;
58 ;               The syntax of a Sculptrix validation string is as follows:
59 ;
60 ;                 `xb'<type>[<flags>][`,'<text>]
61 ;
62 ;               The <type> is a letter which determines what sort of border
63 ;               is to be drawn.  The <flags> modify the style of the border
64 ;               slightly.  Note that if the <type> is uppercase, then the
65 ;               border is inverted.  The <text> is only required for group
66 ;               boxes (type `g').  An unknown <type> causes the icon to be
67 ;               ignored.  Unknown <flags> are ignored.  If no text is
68 ;               specified, a null string is assumed by default.  Spaces
69 ;               are allowed in various sensible places.
70
71                 EXPORT  vString_read
72 vString_read    ROUT
73
74                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
75
76                 ; --- Find the validation string first ---
77
78                 MOV     R2,#0                   ;First call, this is
79 00              MOV     R0,#'x'                 ;Find the validation string
80                 BL      vString_find            ;Try to find the string
81                 BCC     %90vString_read         ;Can't find a Sculptrix cmd
82                 LDRB    R14,[R2,#1]             ;Load the subcommand code
83
84               [ :LNOT::DEF:only_new_commands
85                 SUB     R4,R14,#'0'             ;Convert to a digit
86                 CMP     R4,#10                  ;Is this recognised?
87                 BCC     %50vString_read         ;Yes -- deal with it
88               ]
89
90                 ORR     R14,R14,#&20            ;Make the command lowercase
91
92               [ :LNOT::DEF:only_new_commands
93                 CMP     R14,#'g'                ;Is it a group command?
94                 BEQ     %60vString_read         ;Yes -- deal with it
95               ]
96
97                 CMP     R14,#'s'                ;Is it a text+sprite?
98                 BEQ     %70vString_read         ;Yes -- deal with that too
99
100                 CMP     R14,#'b'                ;Is it the main `b' command?
101                 BNE     %b00                    ;No -- loop back for more
102
103                 ; --- Handle the new `xb' command ---
104
105                 MOV     R14,#0                  ;Initially terminate string
106                 STRB    R14,sculpt_misc         ;To avoid nasty problems
107                 ADD     R2,R2,#2                ;Skip past the command chars
108
109 00              LDRB    R3,[R2],#1              ;Load a byte from the string
110                 CMP     R3,#&20                 ;Is it a space character?
111                 BEQ     %b00                    ;Yes -- keep looking then
112                 CMP     R3,#';'                 ;End of the command?
113                 CMPNE   R3,#&1F                 ;Of of the whole string?
114                 BLS     %90vString_read         ;End of string -- abort now
115
116                 ORR     R0,R3,#&20              ;Make the char lowercase
117                 ADR     R1,vString__cnvTbl      ;Point to the table
118                 BL      vString__lookup         ;Look up letter in the table
119                 BCC     %90vString_read         ;Not found -- give up then
120                 MOV     R4,R0                   ;Get the command code
121
122                 TST     R3,#&20                 ;Is the command uppercase?
123                 EOREQ   R4,R4,#vsFlag_invert    ;Yes -- invert the border
124                 SUB     R3,R2,#1                ;Remember this offset
125
126                 ; --- Now read in the flags ---
127
128                 ADR     R1,vString__flags       ;Point to the flags table
129
130 00              LDRB    R14,[R2],#1             ;Load a byte from the string
131                 CMP     R14,#&20                ;Is it a space character?
132                 BEQ     %b00                    ;Yes -- keep looking then
133                 CMP     R14,#';'                ;End of the command?
134                 CMPNE   R14,#&1F                ;Of of the whole string?
135                 BLS     %f05                    ;End of string -- return
136                 CMP     R14,#','                ;Is it a comma?
137                 BEQ     %f00                    ;Yes -- handle the text then
138
139                 ORR     R0,R14,#&20             ;Make character lowercase
140                 BL      vString__lookup         ;Do the lookup
141                 EORCS   R4,R4,R0                ;And merge in the flag
142                 B       %b00                    ;Keep going until done
143
144                 ; --- Copy the text over and exit ---
145
146 00              BL      vString__copy           ;Copy the text over, please
147                 B       %80vString_read         ;Now return this to caller
148
149                 ; --- Deal with an empty string ---
150
151 05              AND     R14,R4,#&0000FF00       ;Extract the type code
152                 CMP     R14,#vsCode_group       ;Is this a group box?
153                 MOVEQ   R4,#vsBrd_ridge+vsFlag_fade+vsFlag_invert
154                 LDREQ   R14,sculpt_flags        ;Load the flags word
155                 TSTEQ   R14,#scFlag_acorn       ;Acorn style group box?
156                 BICEQ   R4,R4,#vsFlag_invert    ;No -- don't invert it then
157                 B       %80vString_read         ;Now return this to caller
158
159                 ; --- Conversion tables ---
160
161 vString__cnvTbl DCD     'a',vsBrd_action + vsFlag_slab
162                 DCD     'd',vsBrd_default + vsFlag_slab
163                 DCD     'i',vsBrd_action + vsFlag_invert
164                 DCD     'p',vsBrd_action + vsFlag_invert + vsFlag_fade
165                 DCD     'r',vsBrd_ridge
166                 DCD     'c',vsBrd_ridge + vsFlag_invert
167                 DCD     'w',vsBrd_write
168                 DCD     'o',vsBrd_offset
169                 DCD     'g',vsCode_group
170                 DCD     -1
171
172 vString__flags  DCD     'f',vsFlag_fade
173                 DCD     'i',vsFlag_invert
174                 DCD     -1
175
176                 ; --- Handle old-style `x<digit>' command ---
177
178               [ :LNOT::DEF:only_new_commands
179
180 50vString_read  MOV     R3,R2                   ;Remember this position
181                 ADR     R14,vString__oldTbl     ;Point to the table
182                 LDR     R4,[R14,R4,LSL #2]      ;Load the appropriate word
183                 CMP     R4,#-1                  ;Is there a zero there?
184                 BEQ     %90vString_read         ;Yes -- give up then
185                 LDRB    R14,[R3,#0]             ;Load the `X' character
186                 TST     R14,#&20                ;Is it uppercase?
187                 EOREQ   R4,R4,#vsFlag_invert    ;Yes -- invert the icon
188                 B       %80vString_read         ;Now return this to caller
189
190 vString__oldTbl DCD     vsCode_simple + vsBrd_action + vsFlag_slab
191                 DCD     vsCode_simple + vsBrd_ridge
192                 DCD     vsCode_simple + vsBrd_default + vsFlag_slab
193                 DCD     vsCode_simple + vsBrd_offset
194                 DCD     vsCode_simple + vsBrd_action
195                 DCD     -1                      ;Group box title -- withdrawn
196                 DCD     -1                      ;Group box title -- withdrawn
197                 DCD     vsCode_simple + vsBrd_write
198                 DCD     vsCode_simple + vsBrd_action + vsFlag_fade
199                 DCD     -1
200
201               ]
202
203                 ; --- Handle old-style `xg' command ---
204
205               [ :LNOT::DEF:only_new_commands
206
207 60vString_read  ADD     R3,R2,#1                ;Point to the `G'
208                 ADD     R2,R2,#3                ;Skip onto the text
209                 MOV     R4,#vsCode_group        ;Get a group title word
210                 BL      vString__copy           ;Copy the text over, please
211                 B       %80vString_read         ;Now return this to caller
212
213               ]
214
215                 ; --- Handle `xs' text+sprite command ---
216
217 70vString_read  ADD     R3,R2,#1                ;Point to the `S'
218                 ADD     R2,R2,#2                ;Skip onto the text
219                 MOV     R4,#vsCode_tns          ;Get the mystic word
220                 BL      vString__copy           ;Copy the text over, please
221                 B       %80vString_read         ;Now return this to caller
222
223                 ; --- Return values to caller ---
224
225 80vString_read  STR     R4,[R13,#4*0]           ;Store the information word
226                 STR     R3,[R13,#4*4]           ;And the invert flag address
227                 LDMFD   R13!,{R0-R4,R14}        ;Restore registers
228                 ORRS    PC,R14,#C_flag          ;And return with C set
229
230 90vString_read  LDMFD   R13!,{R0-R4,R14}        ;Restore registers
231                 BICS    PC,R14,#C_flag          ;And return with C clear
232
233                 LTORG
234
235 ; --- vString__copy ---
236 ;
237 ; On entry:     R0 == border type code
238 ;               R2 == pointer to tail of validation string
239 ;
240 ; On exit:      R2 moved on
241 ;
242 ; Use:          Copies the tail of the validation string into the misc
243 ;               buffer, transforming escape sequences correctly.
244
245 vString__copy   ROUT
246
247                 STMFD   R13!,{R0,R14}           ;Save some registers
248                 ADR     R0,sculpt_misc          ;Point to the buffer
249
250 00              LDRB    R14,[R2],#1             ;Load the next byte out
251                 CMP     R14,#';'                ;Is this the end?
252                 CMPNE   R14,#&1F                ;Check for end of string
253                 BLS     %f00                    ;Yes -- skip onwards then
254
255                 CMP     R14,#'\'                ;Is this an escape?
256                 STRNEB  R14,[R0],#1             ;Nothing special -- store
257                 BNE     %b00                    ;And loop back round
258
259                 LDRB    R14,[R2],#1             ;Load the next byte out
260                 CMP     R14,#&20                ;Check for end of string
261                 STRCSB  R14,[R0],#1             ;Nothing special -- store
262                 BCS     %b00                    ;And loop back round
263
264 00              MOV     R14,#0                  ;Zero terminate the string
265                 STRB    R14,[R0],#1             ;Store in the buffer
266                 LDMFD   R13!,{R0,PC}^           ;Return when done
267
268                 LTORG
269
270 ; --- vString__lookup ---
271 ;
272 ; On entry:     R0 == word to look for
273 ;               R1 == pointer to table
274 ;
275 ; On exit:      CS if found, and
276 ;                 R0 == word from table
277 ;               else CC and
278 ;                 R0 corrupted
279 ;
280 ; Use:          Looks a word in a table, and returns the corresponding other
281 ;               word.
282
283 vString__lookup ROUT
284
285                 STMFD   R13!,{R1,R14}           ;Save some registers
286 00              LDR     R14,[R1],#8             ;Load the next word
287                 CMP     R14,#-1                 ;Is this the end?
288                 CMPNE   R14,R0                  ;Do these match?
289                 BNE     %b00                    ;Neither -- go back then
290                 CMP     R14,R0                  ;Which one was it?
291                 LDREQ   R0,[R1,#-4]             ;Match -- load previous word
292                 LDMFD   R13!,{R1,R14}           ;Restore registers
293                 ORREQS  PC,R14,#C_flag          ;Return C set if found
294                 BICNES  PC,R14,#C_flag          ;Return C clear if not
295
296                 LTORG
297
298 ; --- vString_find ---
299 ;
300 ; On entry:     R0 == character to find in block (not case-sensitive)
301 ;               R1 == pointer to icon block
302 ;               R2 == old pointer to search from, or 0
303 ;
304 ; On exit:      R0 == character forced to lower case
305 ;               CS if found, and
306 ;                 R2 points to command string
307 ;               else CC and
308 ;                 R2 corrupted
309 ;
310 ; Use:          Tries to find a validation string command in the given
311 ;               icon block.
312
313                 EXPORT  vString_find
314 vString_find    ROUT
315
316                 BIC     R14,R14,#C_flag         ;Assume we won't find it
317                 STMFD   R13!,{R3,R14}           ;Preserve for later use
318
319                 ; --- Ensure the icon is text and indirected ---
320
321                 LDR     R3,[R1,#16]             ;Get flags word
322                 TST     R3,#1<<23               ;Is it deleted?
323                 MOVEQ   R14,#&100               ;Can't put 101 in one instr
324                 ORREQ   R14,R14,#&01            ;Check indirect and text
325                 ANDEQ   R3,R3,R14               ;Mask the bits off
326                 CMPEQ   R3,R14                  ;Were they both set?
327                 LDMNEFD R13!,{R3,PC}^           ;No -- return huffily
328
329                 ; --- Find the validation string ---
330
331                 LDR     R3,[R1,#24]             ;Get pointer to valid string
332                 CMP     R3,#-1                  ;Is it empty?
333                 LDMEQFD R13!,{R3,PC}^           ;No -- return huffily
334
335                 ; --- Start from the right index ---
336
337                 ORR     R0,R0,#&20              ;Make valid char lower case
338                 CMP     R2,#0                   ;Is it the start?
339                 ADDNE   R2,R2,#1                ;No -- miss out one char
340                 BNE     %30vString_find         ;And skip this command
341                 MOV     R2,R3                   ;Start at the beginning
342
343                 ; --- Check the first char of a validation string ---
344
345 10vString_find  LDRB    R14,[R2],#1             ;Get a byte from string
346                 ORR     R3,R14,#&20             ;Make lower case
347                 CMP     R3,R0                   ;Is it a match?
348                 SUBEQ   R2,R2,#1                ;Point back to character
349                 LDMEQFD R13!,{R3,R14}           ;And return
350                 ORREQS  PC,R14,#C_flag          ;Set C on exit for this
351                 MOV     R3,#0                   ;Not an excaped character
352
353                 ; --- Skip ahead to the next validation string ---
354
355 20vString_find  CMP     R14,#' '                ;Is it a control char?
356                 LDMCCFD R13!,{R3,PC}^           ;Yes -- return
357                 CMP     R3,#1                   ;Are we escaping?
358                 MOVEQ   R3,#0                   ;Yes -- done that now
359                 BEQ     %30vString_find         ;So skip this bit
360                 CMP     R14,#';'                ;Is it a semicolon?
361                 BEQ     %10vString_find         ;Yes -- try a new command
362                 CMP     R14,#'\'                ;Is it a backslash?
363                 MOVEQ   R3,#1                   ;Yes -- escape next char
364 30vString_find  LDRB    R14,[R2],#1             ;Get another character
365                 B       %20vString_find         ;And try again
366
367                 LTORG
368
369 ;----- Border codes and flags -----------------------------------------------
370
371                 ^       0
372 vsCode_simple   #       &0100                   ;A simple border
373 vsCode_group    #       &0100                   ;A group box border
374 vsCode_tns      #       &0100                   ;Text+sprite icon
375
376                 ^       0
377 vsBrd_action    #       1                       ;Standard action button
378 vsBrd_default   #       1                       ;Default action button
379 vsBrd_ridge     #       1                       ;A ridge type border
380 vsBrd_write     #       1                       ;A writable border
381 vsBrd_offset    #       1                       ;Offset pressed-in border
382
383 vsFlag_invert   EQU     (1<<31)                 ;Icon border is inverted
384 vsFlag_fade     EQU     (1<<30)                 ;Icon border is faded
385 vsFlag_slab     EQU     (1<<29)                 ;Icon may be slabbed
386
387 ;----- That's all, folks ----------------------------------------------------
388
389                 END