chiark / gitweb /
Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[ssr] / StraySrc / MiscToys / CurrDir / s / currDir
1 ;
2 ; currDir.s
3 ;
4 ; Puts the current directory in a code variable
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; CurrDir is free software; you can redistribute it and/or modify
12 ; it under the terms of the GNU General Public License as published by
13 ; the Free Software Foundation; either version 2, or (at your option)
14 ; any later version.
15 ;
16 ; CurrDir is distributed in the hope that it will be useful,
17 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ; GNU General Public License for more details.
20 ;
21 ; You should have received a copy of the GNU General Public License
22 ; along with CurrDir.  If not, write to the Free Software Foundation,
23 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25 ;----- Standard header ------------------------------------------------------
26
27                 GET     libs:header
28                 GET     libs:swis
29
30 ;----- External dependencies ------------------------------------------------
31
32                 IMPORT  version
33                 IMPORT  |Image$$RW$$Limit|
34
35 ;----- Main code ------------------------------------------------------------
36
37                 AREA    |Asm$$Code|,CODE,READONLY
38                 ENTRY
39
40 ; --- main ---
41 ;
42 ; On entry:     --
43 ;
44 ; On exit:      Via OS_Exit
45 ;
46 ; Use:          Installs the CurrDir variable.
47
48 main            ROUT
49
50                 ; --- Check for RISC OS 3 ---
51
52                 MOV     R0,#129                 ;Read OS version number
53                 MOV     R1,#0
54                 MOV     R2,#255
55                 SWI     OS_Byte
56                 CMP     R1,#&A3                 ;Check for RISC OS 3
57                 BLO     cd__badOSVer            ;Wrong -- make an error
58
59                 ; --- Parse the command line arguments ---
60
61                 ADRL    R12,|Image$$RW$$Limit|  ;Find the program end
62                 SWI     OS_GetEnv               ;Read the command line
63 cd__skipLoop    LDRB    R14,[R0],#1             ;Get next byte from this
64                 CMP     R14,#32                 ;Is it the end of the name?
65                 BHI     cd__skipLoop            ;No -- go round again
66 cd__spaceLoop   CMP     R14,#32                 ;Is this a space?
67                 LDREQB  R14,[R0],#1             ;Yes -- get another byte
68                 BEQ     cd__spaceLoop           ;And go round again
69                 SUB     R1,R0,#1                ;Point at nonspace char
70                 ADR     R0,cd__cliDef           ;Point to the command defn
71                 MOV     R2,R12                  ;Point to my output buffer
72                 MOV     R3,#256                 ;And get its size
73                 SWI     OS_ReadArgs             ;Read the arguments nicely
74
75                 ; --- Check for help ---
76
77                 LDR     R14,[R12,#8]            ;Load the help flag
78                 CMP     R14,#0                  ;Is it set?
79                 BNE     cd__help                ;Yes -- then give help
80
81                 ; --- Now find the variable name ---
82
83                 LDR     R4,[R12,#0]             ;Load the name value
84                 CMP     R4,#0                   ;Is it set?
85                 ADREQ   R4,cd__defaultName      ;No -- point to a default
86
87                 ; --- Do the right thing ---
88
89                 LDR     R14,[R12,#12]           ;Load the `remove' flag
90                 CMP     R14,#0                  ;Is it set?
91                 BNE     cd__remove              ;Yes -- remove the variable
92
93                 ; --- Load the maximum length of the string ---
94
95                 LDR     R1,[R12,#4]             ;Load the length value
96                 CMP     R1,#0                   ;Is it zero?
97                 MOVEQ   R2,#-1                  ;Yes -- have a very big max
98                 BEQ     cd__gotLength           ;And skip onwards
99                 MOV     R0,#10+(1<<31)          ;Default is base 10
100                 SWI     OS_ReadUnsigned         ;Read the value nicely
101                 CMP     R2,#20                  ;Is the length OK?
102                 BLO     cd__badLength           ;No -- that's an error
103 cd__gotLength   STR     R2,cd__maxLen           ;Store the length in code
104
105                 ; --- Set the variable value ---
106
107                 MOV     R0,R4                   ;Point to the variable name
108                 ADR     R14,cd__varBase         ;Point to the variable base
109                 LDMIA   R14,{R1,R2}             ;Load the base and length
110                 MOV     R3,#0                   ;No context value
111                 MOV     R4,#16                  ;This is a code variable
112                 SWI     OS_SetVarVal            ;Install the variable nicely
113                 SWI     OS_Exit
114
115                 ; --- Remove an installed variable ---
116
117 cd__remove      MOV     R0,R4                   ;Point to the variable name
118                 MOV     R2,#-1                  ;Remove the variable
119                 MOV     R3,#0                   ;No context value
120                 MOV     R4,#16                  ;Remove code variable
121                 SWI     OS_SetVarVal            ;Remove the variable
122                 SWI     OS_Exit
123
124 cd__cliDef      DCB     "var,maxlen=length,help/S,remove/S",0
125 cd__defaultName DCB     "CSD",0
126
127 cd__badOSVer    ADR     R0,cd__ro3Only          ;Point to the error message
128                 SWI     OS_GenerateError        ;Report the error
129
130 cd__ro3Only     DCD     1
131                 DCB     "currDir only works on RISC OS 3.00 or later",0
132
133 cd__badLength   ADR     R0,cd__minSize          ;Point to the error message
134                 SWI     OS_GenerateError        ;Report the error
135
136 cd__minSize     DCD     1
137                 DCB     "Maximum length must be at least 20",0
138
139 cd__varBase     DCD     cd__variable
140                 DCD     cd__varEnd-cd__variable+512
141
142                 ; --- Return help on the program ---
143
144 cd__help        ADR     R0,cd__helpText         ;Point to the help text
145                 MOV     R1,#0                   ;Use the default dictionary
146                 ADR     R2,version              ;Point to the version string
147                 SWI     OS_PrettyPrint          ;Print the string
148                 SWI     OS_Exit
149
150 cd__helpText    DCB     27,0,13
151                 DCB     13
152                 DCB     "Syntax: currDir [-var <variableName>] "
153                 DCB     "[-maxlen <length>] [-remove]",13
154                 DCB     13
155                 DCB     "Sets a variable (by default the variable 'CSD', "
156                 DCB     "although you can change this) to contain the name "
157                 DCB     "of the currently selected directory.",13
158                 DCB     13
159                 DCB     "Optionally, you can set a maximum length.  If you "
160                 DCB     "do, the directory name will be shortened to only "
161                 DCB     "display the name of the filing system, disk name "
162                 DCB     "(if present), and the tail end of the path.",13
163                 DCB     0
164
165 ;----- The code variable ----------------------------------------------------
166
167 cd__variable    ROUT
168
169                 B        cd__cantWrite          ;Handle attempt to write
170
171                 ; --- Perform the read operation ---
172
173                 STMFD   R13!,{R3-R5,R12,R14}    ;Save some registers
174                 ADR     R12,cd__buffer          ;Set up the buffer pointer
175                 MOV     R0,#37                  ;Canonicalise path
176                 ADR     R1,cd__atSign           ;Point to the `@' magic char
177                 MOV     R2,R12                  ;Point at the buffer
178                 MOV     R3,#0                   ;No path variable
179                 MOV     R4,#0                   ;No path variable still
180                 MOV     R5,#512                 ;The size of my buffer
181                 SWI     XOS_FSControl           ;Read the canonical path
182                 ADRVS   R2,cd__unset            ;If not point at default
183
184                 ; --- Count the length ---
185
186                 MOV     R0,R12                  ;Point at the buffer
187                 MOV     R1,R12                  ;Start truncate at beginning
188                 MOV     R2,#0                   ;Current length
189                 MOV     R3,#0                   ;Current state
190
191 00cd__variable  LDRB    R14,[R0],#1             ;Load the next byte
192                 CMP     R14,#32                 ;Is this the string end?
193                 BLO     %10cd__variable         ;Yes -- skip to the end
194                 ADD     R2,R2,#1                ;Bump the length counter
195                 CMP     R14,#':'                ;Is it a colon?
196                 BEQ     %02cd__variable         ;Yes -- handle it then
197                 CMP     R14,#'%'                ;Is it a library?
198                 CMPNE   R14,#'$'                ;Or a root spec?
199                 CMPNE   R14,#'&'                ;Or a URD spec?
200                 MOVEQ   R1,R0                   ;Yes -- truncate here
201                 CMP     R14,#'.'                ;Is it a dot?
202                 BNE     %00cd__variable         ;No -- go round again
203
204                 ; --- We found a dot ---
205
206                 CMP     R3,#2                   ;Did we find two colons?
207                 SUBEQ   R1,R0,#1                ;Yes -- truncate here
208                 MOVEQ   R3,#3                   ;And don't do it again
209                 B       %00cd__variable         ;Go round again
210
211                 ; --- Found a colon -- check it out ---
212
213 02cd__variable  CMP     R3,#0                   ;How many colons matched?
214                 MOVEQ   R1,R0                   ;None yet -- truncate here
215                 CMPNE   R3,#1                   ;Or maybe we've had one
216                 ADDEQ   R3,R3,#1                ;Bump the counter
217                 B       %00cd__variable         ;Go round again
218
219                 ; --- Check the length now ---
220
221 10cd__variable  LDR     R5,cd__maxLen           ;Load the maximum length
222                 SUBS    R4,R2,R5                ;Are we OK here?
223                 BLS     %30cd__variable         ;Yes -- skip onwards then
224
225                 ; --- Truncate the string ---
226                 ;
227                 ; R4 is how many bytes we have to lose.
228
229                 ADD     R0,R1,R4                ;Point to where we copy from
230                 MOV     R2,#3                   ;Countdown for ellipsis
231 20cd__variable  LDRB    R14,[R0],#1             ;Load the byte out
232                 CMP     R14,#32                 ;Is this the end of it all?
233                 BLO     %25cd__variable         ;Yes -- skip to end then
234                 SUBS    R2,R2,#1                ;No -- decrement countdown
235                 MOVGE   R14,#'.'                ;Substitute a dot if needed
236                 STRB    R14,[R1],#1             ;Store the byte in buffer
237                 B       %20cd__variable         ;No -- go round again then
238
239 25cd__variable  STRB    R14,[R1],#1             ;Store the byte in buffer
240                 MOV     R2,R5                   ;Length is in R2 on exit
241
242                 ; --- Return the variable ---
243
244 30cd__variable  MOV     R0,R12                  ;Point to the string
245                 LDMFD   R13!,{R3-R5,R12,PC}^    ;Return to caller
246
247 cd__maxLen      DCD     0
248 cd__atSign      DCB     "@",0
249 cd__unset       DCB     "<Unset>",0
250
251                 ; --- Make an error about writing to the variable ---
252
253 cd__cantWrite   ADR     R0,cd__writeMsg         ;Point to error
254                 ORRS    PC,R14,#V_flag          ;And return it
255
256 cd__writeMsg    DCD     1
257                 DCB     "Can't write current directory variables",0
258
259                 ALIGN
260
261 cd__buffer
262
263 cd__varEnd
264
265 ;----- That's all, folks ----------------------------------------------------
266
267                 END