1862
|
1 ********************************************************************
|
|
2 * Touch - Changes last modification date/time
|
|
3 *
|
|
4 * $Id$
|
|
5 *
|
|
6 * Edt/Rev YYYY/MM/DD Modified by
|
|
7 * Comment
|
|
8 * ------------------------------------------------------------------
|
|
9 * 2 2003/01/11 Boisy G. Pitre
|
|
10 * Rewrote touch from scratch, made almost 90% smaller than C version
|
|
11 * found in the OS-9 Development System.
|
|
12
|
|
13 nam Touch
|
|
14 ttl Changes last modification date/time
|
|
15
|
|
16 use defsfile.d
|
|
17
|
1868
|
18 rev set $00
|
|
19 edition set 2
|
|
20
|
1862
|
21 * Here are some tweakable options
|
|
22 DOHELP set 0 1 = include help info
|
|
23 STACKSZ set 128 estimated stack size
|
|
24 PARMSZ set 256 estimated parameter size
|
|
25 ZOPTSIZ set 64 max size of -z option's parameter
|
|
26
|
|
27 * Module header definitions
|
|
28 rev set $00
|
|
29 edition set 2
|
|
30
|
|
31 psect touch_a,Prgrm+Objct,ReEnt+rev,edition,200,start
|
|
32
|
|
33 * Your utility's static storage vars go here
|
1868
|
34 vsect dp
|
1862
|
35 parmptr rmb 2 pointer to our command line params
|
|
36 bufptr rmb 2 pointer to user expandable buffer
|
|
37 bufsiz rmb 2 size of user expandable buffer
|
|
38 * What follows are utility specific options
|
|
39 nocreate rmb 1
|
|
40 quiterr rmb 1
|
|
41 filemode rmb 1
|
|
42 filecnt rmb 1
|
|
43 zoptflg rmb 1 1 = this option has been processed once already
|
|
44 zpath rmb 1 path to -z file
|
1868
|
45 cleartop equ * everything up to here gets cleared at start
|
1862
|
46 zopt rmb ZOPTSIZ buffer for what follows after -c=
|
1868
|
47 endsect
|
|
48
|
1862
|
49 * Next is a user adjustable buffer with # modifier on command line.
|
|
50 * Some utilities won't need this, some will.
|
|
51 * Currently set up to be larger for Level 2 than Level 1
|
|
52 * Note: this buffer must come just before the stack
|
1868
|
53 vsect
|
1862
|
54 IFGT Level-1
|
|
55 bigbuff rmb 8*1024 8K default buffer for Level 2
|
|
56 ELSE
|
|
57 bigbuff rmb 512 512 byte default buffer for Level 1
|
|
58 ENDC
|
|
59 endsect
|
|
60
|
|
61 * Place constant strings here
|
|
62 IFNE DOHELP
|
|
63 HlpMsg fcb C$LF
|
|
64 fcc /Use: Touch [<opts>] <path> [<path>] [<opts>]/
|
|
65 fcb C$LF
|
|
66 fcc / -c = don't create files/
|
|
67 fcb C$LF
|
|
68 fcc / -q = don't quit on error/
|
|
69 fcb C$LF
|
|
70 fcc / -x = search execution directory/
|
|
71 fcb C$LF
|
|
72 fcc / -z = get files from standard input/
|
|
73 fcb C$LF
|
|
74 fcc / -z=<file> get files from <file>/
|
|
75 fcb C$LF
|
|
76 CR fcb C$CR
|
|
77 HlpMsgL equ *-HlpMsg
|
|
78 ENDC
|
|
79 UnkOpt fcc /unknown option: /
|
|
80 UnkOptL equ *-UnkOpt
|
|
81 CantTch fcc /can't touch "/
|
|
82 CantTchL equ *-CantTch
|
|
83 EndCant fcc /" - /
|
|
84 EndCantL equ *-EndCant
|
|
85
|
|
86 * Here's how registers are set when this process is forked:
|
|
87 *
|
|
88 * +-----------------+ <-- Y (highest address)
|
|
89 * ! Parameter !
|
|
90 * ! Area !
|
|
91 * +-----------------+ <-- X, SP
|
|
92 * ! Data Area !
|
|
93 * +-----------------+
|
|
94 * ! Direct Page !
|
|
95 * +-----------------+ <-- U, DP (lowest address)
|
|
96 *
|
|
97 * D = parameter area size
|
|
98 * PC = module entry point abs. address
|
|
99 * CC = F=0, I=0, others undefined
|
|
100
|
|
101 * The start of the program is here.
|
|
102 * Before any command line processing is done, we clear out
|
|
103 * our static memory from U to cleartop, then determine the
|
|
104 * size of our data area (minus the stack).
|
|
105 start pshs u,x save registers for later
|
1868
|
106 leax <cleartop point to end of area to zero out
|
1862
|
107 IFNE H6309
|
|
108 subr u,x subtract U from X
|
|
109 tfr x,w and put X in W
|
|
110 clr ,-s put a zero on the stack
|
|
111 tfm s,u+ and use TFM to clear starting at U
|
|
112 leas 1,s clean up the stack
|
|
113 ELSE
|
|
114 pshs x save end pointer on stack
|
|
115 clrnxt clr ,u+ clear out
|
|
116 cmpu ,s done?
|
|
117 bne clrnxt branch if not
|
|
118 leas 2,s else clear stack
|
|
119 ENDC
|
|
120 puls x,u and restore our earlier saved registers
|
|
121 leay bigbuff,u point Y to copy buffer offset in U
|
|
122 stx <parmptr save parameter pointer
|
|
123 sty <bufptr save pointer to buffer
|
|
124 tfr s,d place top of stack in D
|
|
125 IFNE H6309
|
|
126 subr y,d
|
|
127 ELSE
|
|
128 pshs y save Y on stack
|
|
129 subd ,s++ get size of space between copybuf and X
|
|
130 ENDC
|
|
131 subd #STACKSZ+PARMSZ subtract out our stack
|
|
132 std <bufsiz size of our buffer
|
|
133
|
|
134 * At this point we have determined our buffer space and saved pointers
|
|
135 * for later use. Now we will parse the command line for options that
|
|
136 * begin with -
|
|
137 lda ,x
|
|
138 cmpa #C$CR CR?
|
|
139 lbeq ShowHelp if so, no parameters... show help and exit
|
|
140 GetChar lda ,x+ get next character on cmd line
|
|
141 cmpa #C$CR CR?
|
|
142 lbeq DoTouch if so, do whatever this utility does
|
|
143 cmpa #'- is it an option?
|
|
144 beq GetDash if so, process it
|
|
145 inc <filecnt else must be a non-option argument (file)
|
|
146 lbsr SkipNSpc move past the argument
|
|
147 ChkDash lbsr SkipSpcs and any following spaces
|
|
148 bra GetChar start processing again
|
|
149 GetDash lda #C$SPAC get a space char
|
|
150 sta -1,x and wipe out the dash from the cmd line
|
|
151 GetDash2 ldd ,x+ load option char and char following
|
|
152 ora #$20 make lowercase
|
|
153 IsItC cmpa #'c is it this option?
|
|
154 bne IsItQ branch if not
|
|
155 sta <nocreate
|
|
156 lbra FixCmdLn
|
|
157 IsItQ cmpa #'q is it this option?
|
|
158 bne IsItX branch if not
|
|
159 inc <quiterr
|
|
160 lbra FixCmdLn
|
|
161 IsItX cmpa #'x is it this option?
|
|
162 bne IsItZ branch if not
|
|
163 lda #EXEC.
|
|
164 sta <filemode
|
|
165 bra FixCmdLn
|
|
166 IsItZ cmpa #'z is it this option?
|
|
167 bne BadOpt branch if not
|
|
168 tst <zoptflg was this option already specified?
|
|
169 bne BadOpt show help if so
|
|
170 sta <zoptflg else tag this option as parsed
|
|
171 cmpb #'= 2nd char =?
|
|
172 bne FixCmdLn
|
|
173 GetZFile ldb #C$SPAC get space
|
|
174 stb -$01,x write over c
|
|
175 stb ,x+ and = sign, inc X to dest dir
|
|
176 * check for valid char after -z=
|
|
177 lda ,x
|
|
178 cmpa #C$SPAC
|
|
179 lbeq ShowHelp
|
|
180 cmpa #C$COMA
|
|
181 lbeq ShowHelp
|
|
182 cmpa #C$CR
|
|
183 lbeq ShowHelp
|
|
184 leay <zopt,u point Y to parameber buffer
|
|
185 tfr y,d transfer Y to D
|
|
186 addd #ZOPTSIZ
|
|
187 pshs b,a save updated ptr value
|
|
188 ldb #C$SPAC get space
|
|
189 L0339 lda ,x get byte at X
|
|
190 stb ,x+ store space at X and inc
|
|
191 sta ,y+ save loaded byte at Y and inc
|
|
192 cmpy ,s are we at end?
|
|
193 beq L035D branch if so (buffer too small)
|
|
194 cmpa #C$SPAC else is char in A a space?
|
|
195 beq L0350 branch if so
|
|
196 cmpa #C$COMA coma?
|
|
197 beq L0350 branch if so
|
|
198 cmpa #C$CR cr?
|
|
199 bne L0339 get next byte if not
|
|
200 L0350 leax -1,x
|
|
201 sta ,x restore previous A
|
|
202 leas $02,s kill stack
|
|
203 * attempt to open a path to the file
|
|
204 pshs x
|
|
205 leax <zopt,u
|
|
206 lda #READ.
|
|
207 os9 I$Open
|
|
208 lbcs Exit
|
|
209 sta <zpath
|
|
210 puls x
|
|
211 lbra ChkDash
|
|
212 L035D leas $02,s
|
|
213 ldb #$BF else buffer size too small
|
|
214 orcc #Carry
|
|
215 lbra Exit
|
|
216 FixCmdLn lda #C$SPAC get space
|
|
217 sta -$01,x and wipe out option character
|
|
218 cmpb #'0
|
|
219 lblt ChkDash start dash option processing again
|
|
220 lbra GetDash possibly another option following?
|
|
221
|
|
222 * We branch here if we encounter an unknown option character
|
|
223 * A = bad option character
|
|
224 BadOpt leax UnkOpt,pcr
|
|
225 ldy #UnkOptL
|
|
226 ldb #C$CR
|
|
227 pshs d save bad option and CR on stack
|
|
228 lda #$02 stderr
|
|
229 os9 I$Write
|
|
230 leax ,s point X at option char on stack
|
|
231 os9 I$WritLn print option and CR
|
|
232 puls d clean up stack
|
|
233 lbra ShowHelp
|
|
234
|
|
235
|
|
236 * At this point options are processed.
|
|
237 * We load X with our parameter pointer and go down the command line
|
|
238 * looking at each file to process (options have been wiped out with
|
|
239 * spaces)
|
|
240 *
|
|
241 * Note, the following two instructions may not be needed, depending on
|
|
242 * if your utility requires a non-option on the command line.
|
|
243 DoTouch tst <zoptflg -z specified?
|
|
244 beq DoFiles no, do any files on command line
|
|
245 ReadZ lda <zpath
|
|
246 ldy #80
|
|
247 os9 I$ReadLn
|
|
248 lbsr SkipSpcs
|
|
249 cmpa #C$CR
|
|
250 beq ClosEx
|
|
251 bcs TestErr
|
|
252 bsr ProcFile
|
|
253 bra ReadZ
|
|
254 TestErr cmpb #E$EOF
|
|
255 lbne Exit
|
|
256 tsta
|
|
257 lbeq ExitOk
|
|
258 ClosEx os9 I$Close close path to -z= file
|
|
259 lbra ExitOk
|
|
260
|
|
261 DoFiles tst <filecnt we should have at least one file on cmdline
|
|
262 lbeq ShowHelp if not, exit with error
|
|
263 ldx <parmptr get our parameter pointer off stack
|
|
264 DoLoop lbsr SkipSpcs skip any leading spaces
|
|
265 cmpa #C$CR end of parameters?
|
|
266 beq ExitOk if so, end the utility
|
|
267 pshs x save pointer to arg
|
|
268 bsr ProcFile process file at X
|
|
269 puls x get arg pointer
|
|
270 lbsr SkipNSpc skip the argument we just processed
|
|
271 bra DoLoop
|
|
272
|
|
273 * This routine processes one file at a time.
|
|
274 * Entry: X = ptr to argument on the command line.
|
|
275 * On exit, X can point to the argument or past it.
|
|
276 * Note that there are NO leading spaces.
|
|
277 * They have been skipped by the caller.
|
|
278 * The following code just echos the command line argument, followed
|
|
279 * by a carriage return.
|
|
280 ProcFile
|
|
281 lda #WRITE.
|
|
282 ora <filemode
|
|
283 pshs x
|
|
284 os9 I$Open
|
|
285 puls x
|
|
286 bcc CloseIt
|
|
287 ora #DIR.
|
|
288 pshs x
|
|
289 os9 I$Open
|
|
290 puls x
|
|
291 bcc CloseIt
|
|
292 * open failed... should we do create?
|
|
293 tst <nocreate
|
|
294 beq DoCreate
|
|
295 ChkQuit bsr CantTouch
|
|
296 tst <quiterr
|
1868
|
297 beq ExitOk
|
1862
|
298 bra ProcRTS
|
|
299 DoCreate ldb #PREAD.+UPDAT.
|
|
300 pshs x
|
|
301 os9 I$Create
|
|
302 puls x
|
|
303 bcs ChkQuit
|
|
304 CloseIt os9 I$Close
|
|
305 ProcRTS rts
|
|
306
|
|
307 CantTouch
|
|
308 pshs x,b save pointer to file and error code
|
|
309 leax CantTch,pcr
|
|
310 lda #$02
|
|
311 ldy #CantTchL
|
|
312 os9 I$Write
|
|
313 ldx 1,s
|
|
314 pshs x
|
|
315 bsr StrLen
|
|
316 puls x
|
|
317 os9 I$Write
|
|
318 leax EndCant,pcr
|
|
319 ldy #EndCantL
|
|
320 os9 I$Write
|
|
321 puls b
|
|
322 os9 F$PErr
|
|
323 puls x,pc
|
|
324
|
|
325 ShowHelp equ *
|
|
326 IFNE DOHELP
|
|
327 leax >HlpMsg,pcr point to help message
|
|
328 ldy #HlpMsgL get length
|
|
329 lda #$02 std error
|
|
330 os9 I$WritLn write it
|
|
331 ENDC
|
|
332 ExitOk clrb clear carry
|
|
333 Exit os9 F$Exit and exit
|
|
334
|
|
335 * This routine counts the number of non-whitespace characters
|
|
336 * starting at X
|
|
337 *
|
|
338 * Entry:
|
|
339 * X = ptr to string (space, comma or CR terminated)
|
|
340 * Exit:
|
|
341 * Y = length of string
|
|
342 * X = ptr to byte after string
|
|
343 StrLen pshs a
|
|
344 ldy #$0000
|
|
345 StrLenLp lda ,x+
|
|
346 cmpa #C$SPAC
|
|
347 beq StrLenEx
|
|
348 cmpa #C$COMA
|
|
349 beq StrLenEx
|
|
350 cmpa #C$CR
|
|
351 beq StrLenEx
|
|
352 leay 1,y
|
|
353 bra StrLenLp
|
|
354 StrLenEx puls a,pc
|
|
355
|
|
356 * This routine copies a string of text from X to Y until
|
|
357 * a whitespace character or CR is encountered
|
|
358 *
|
|
359 * Entry:
|
|
360 * X = ptr to src string
|
|
361 * Y = ptr to dest string
|
|
362 * Exit:
|
|
363 * D = number of bytes copied
|
|
364 * X = ptr to byte after original string
|
|
365 * Y = ptr to byte after copied string
|
|
366 StrCpy pshs u
|
|
367 ldu #$0000
|
|
368 CopyFnLp lda ,x+
|
|
369 cmpa #C$SPAC
|
|
370 beq CopyFnEx
|
|
371 cmpa #C$COMA
|
|
372 beq CopyFnEx
|
|
373 cmpa #C$CR
|
|
374 beq CopyFnEx
|
|
375 sta ,y+
|
|
376 leau 1,u
|
|
377 bra CopyFnLp
|
|
378 CopyFnEx tfr u,d
|
|
379 puls u,pc
|
|
380
|
|
381 * This routine skip over spaces and commas
|
|
382 *
|
|
383 * Entry:
|
|
384 * X = ptr to data to parse
|
|
385 * Exit:
|
|
386 * X = ptr to first non-whitespace char
|
|
387 * A = non-whitespace char
|
|
388 SkipSpcs lda ,x+
|
|
389 cmpa #C$SPAC
|
|
390 beq SkipSpcs
|
|
391 cmpa #C$COMA
|
|
392 beq SkipSpcs
|
|
393 leax -1,x
|
|
394 rts
|
|
395
|
|
396 * This routine skips over everything but spaces, commas and CRs
|
|
397 *
|
|
398 * Entry:
|
|
399 * X = ptr to data to parse
|
|
400 * Exit:
|
|
401 * X = ptr to first whitespace char
|
|
402 * A = whitespace char
|
|
403 SkipNSpc lda ,x+
|
|
404 cmpa #C$SPAC
|
|
405 beq EatOut
|
|
406 cmpa #C$COMA
|
|
407 beq EatOut
|
|
408 cmpa #C$CR
|
|
409 bne SkipNSpc
|
|
410 EatOut leax -1,x
|
|
411 rts
|
|
412
|
|
413 endsect
|