Mercurial > hg > Members > kono > nitros9-code
annotate level1/cmds/ngu.asm @ 902:bffd011cbef3
Made more changes
author | boisy |
---|---|
date | Sat, 18 Jan 2003 14:53:34 +0000 |
parents | 053078ef1289 |
children | c04528763543 |
rev | line source |
---|---|
820 | 1 ******************************************************************** |
2 * NGU - The "Next Great Utility" | |
3 * | |
4 * $Id$ | |
5 * | |
6 * NGU is a template for writing utilities under OS-9/6809. It has | |
7 * robust option handling and is littered with comments to help you | |
8 * write your own utilities. | |
9 * | |
10 * NGU uses a two-pass method for parsing the command line. On the | |
11 * first pass, dash options are processed and internal flags are set | |
12 * accordingly. As the options are processed, they are cleared to | |
13 * spaces so that they won't be present on the second pass. | |
14 * | |
902 | 15 * e.g. |
16 * 1st pass: ngu -x foo1 -y foo2 -t=bar1 -ab | |
17 * 2nd pass: ngu foo1 foo2 | |
18 * | |
19 * For the second pass, NGU parses the remaining arguments, which don't | |
20 * begin with -. Presumably these are filenames or other names that are to be | |
820 | 21 * processed. |
22 * | |
23 * Features: | |
823 | 24 * - Written for 6809 and 6309 processors in fast, compact |
25 * assembly language. | |
26 * | |
820 | 27 * - Both options and files can be specified anywhere |
28 * on the command line | |
29 * (i.e ngu -a test1 -b test2 -c=foo) | |
30 * | |
902 | 31 * - Multiple options can be combined behind one dash: |
820 | 32 * (i.e ngu -ab test1 -c=foo test2 test3) |
33 * | |
34 * - Several useful assembly routines are provided for | |
35 * copying strings and determining string length. | |
36 * | |
37 * Limitations: | |
823 | 38 * - Only single character option names can be processed. |
902 | 39 * Multi-character option names (i.e. -delete) aren't supported. |
820 | 40 * |
902 | 41 * - The current file counter is one byte, counting a maximum |
820 | 42 * of 255 files. |
43 * | |
44 * Ed. Comments Who YY/MM/DD | |
45 * ------------------------------------------------------------------ | |
46 * 1 Put your development info here BGP 03/01/11 | |
47 | |
48 nam NGU | |
49 ttl The "Next Great Utility" | |
50 | |
51 ifp1 | |
52 use defsfile | |
53 use rbfdefs | |
54 endc | |
55 | |
56 * Here are some tweakable options | |
57 DOHELP set 1 1 = include help info | |
58 STCKSIZE set 64 our stack size in bytes | |
59 COPTSIZ set 64 max size of C option's parameter | |
60 | |
61 * Module header definitions | |
62 tylg set Prgrm+Objct | |
63 atrv set ReEnt+rev | |
64 rev set $01 | |
65 edition set 1 | |
66 | |
67 mod eom,name,tylg,atrv,start,size | |
68 | |
69 * Your utility's static storage vars go here | |
70 org 0 | |
902 | 71 * These vars are used by the base template and shouldn't be removed |
820 | 72 parmptr rmb 2 pointer to our command line params |
73 bufptr rmb 2 pointer to user expandable buffer | |
74 bufsiz rmb 2 size of user expandable buffer | |
902 | 75 filecnt rmb 1 |
76 * These vars are used for this example, it will probably change for you | |
820 | 77 gota rmb 1 |
78 gotb rmb 1 | |
79 coptflg rmb 1 1 = this option has been processed once already | |
823 | 80 cleartop equ . everything up to here gets cleared at start |
820 | 81 copt rmb COPTSIZ buffer for what follows after -c= |
82 * Next is a user adjustable buffer with # modifier on command line. | |
902 | 83 * Some utilities won't need this flexibility, some will. |
820 | 84 * Currently set up to be larger for Level 2 than Level 1 |
85 * Note: this buffer must come just before the stack | |
86 IFGT Level-1 | |
87 bigbuff rmb 8*1024 8K default buffer for Level 2 | |
88 ELSE | |
89 bigbuff rmb 512 512 byte default buffer for Level 1 | |
90 ENDC | |
91 * Finally the stack for any PSHS/PULS/BSR/LBSRs that we might do | |
92 stack rmb STCKSIZE | |
93 size equ . | |
94 | |
95 * The utility name and edition goes here | |
821 | 96 name fcs /NGU/ |
820 | 97 fcb edition |
98 | |
99 * Place constant strings here | |
100 IFNE DOHELP | |
101 HlpMsg fcb C$LF | |
102 fcc /Use: NGU [<opts>] <path> [<path>] [<opts>]/ | |
103 fcb C$LF | |
104 fcc / -a option 1/ | |
105 fcb C$LF | |
106 fcc / -b option 2/ | |
107 fcb C$LF | |
822 | 108 fcc / -c=f option 3/ |
109 fcb C$LF | |
823 | 110 CR fcb C$CR |
820 | 111 HlpMsgL equ *-HlpMsg |
112 ENDC | |
821 | 113 UnkOpt fcc /unknown option: / |
114 UnkOptL equ *-UnkOpt | |
820 | 115 |
116 * Here's how registers are set when this process is forked: | |
117 * | |
118 * +-----------------+ <-- Y (highest address) | |
119 * ! Parameter ! | |
120 * ! Area ! | |
121 * +-----------------+ <-- X, SP | |
122 * ! Data Area ! | |
123 * +-----------------+ | |
124 * ! Direct Page ! | |
125 * +-----------------+ <-- U, DP (lowest address) | |
126 * | |
127 * D = parameter area size | |
128 * PC = module entry point abs. address | |
129 * CC = F=0, I=0, others undefined | |
130 | |
823 | 131 * The start of the program is here. |
820 | 132 * Before any command line processing is done, we clear out |
823 | 133 * our static memory from U to cleartop, then determine the |
134 * size of our data area (minus the stack). | |
820 | 135 start pshs u,x save registers for later |
823 | 136 leax <cleartop,u point to end of area to zero out |
820 | 137 IFNE H6309 |
821 | 138 subr u,x subtract U from X |
139 tfr x,w and put X in W | |
140 clr ,-s put a zero on the stack | |
141 tfm s,u+ and use TFM to clear starting at U | |
142 leas 1,s clean up the stack | |
820 | 143 ELSE |
144 pshs x save end pointer on stack | |
145 clrnxt clr ,u+ clear out | |
146 cmpu ,s done? | |
147 bne clrnxt branch if not | |
148 leas 2,s else clear stack | |
149 ENDC | |
150 puls x,u and restore our earlier saved registers | |
151 leay bigbuff,u point Y to copy buffer offset in U | |
152 stx <parmptr save parameter pointer | |
153 sty <bufptr save pointer to buffer | |
154 tfr s,d place top of stack in D | |
155 IFNE H6309 | |
156 subr y,d | |
157 ELSE | |
158 pshs y save Y on stack | |
159 subd ,s++ get size of space between copybuf and X | |
160 ENDC | |
161 subd #STCKSIZE subtract out our stack | |
162 std <bufsiz size of our buffer | |
163 | |
164 * At this point we have determined our buffer space and saved pointers | |
821 | 165 * for later use. Now we will parse the command line for options that |
854 | 166 * begin with a dash. |
167 * Note that X will NOT point to a space, but to either a CR (if no | |
168 * parameters were passed) or the first non-space character of the | |
169 * parameter. | |
170 * Here we merely grab the byte at X into A and test for end of line, | |
902 | 171 * exiting if so. Utilities that don't require arguments should |
172 * comment out the following three lines. | |
854 | 173 lda ,x get first char |
820 | 174 cmpa #C$CR CR? |
175 lbeq ShowHelp if so, no parameters... show help and exit | |
176 GetChar lda ,x+ get next character on cmd line | |
177 cmpa #C$CR CR? | |
178 lbeq DoNGU if so, do whatever this utility does | |
179 cmpa #'- is it an option? | |
180 beq GetDash if so, process it | |
181 inc <filecnt else must be a non-option argument (file) | |
182 lbsr SkipNSpc move past the argument | |
183 ChkDash lbsr SkipSpcs and any following spaces | |
184 bra GetChar start processing again | |
185 GetDash lda #C$SPAC get a space char | |
186 sta -1,x and wipe out the dash from the cmd line | |
187 GetDash2 ldd ,x+ load option char and char following | |
822 | 188 ora #$20 make lowercase |
189 IsItA cmpa #'a is it this option? | |
820 | 190 bne IsItB branch if not |
191 inc <gota | |
829
a114971abd3b
Changed the name of a def because it collided with Level 2
boisy
parents:
823
diff
changeset
|
192 bra FixCmdLn |
822 | 193 IsItB cmpa #'b is it this option? |
820 | 194 bne IsItC branch if not |
195 inc <gotb | |
196 bra FixCmdLn | |
822 | 197 IsItC cmpa #'c is it this option? |
820 | 198 bne BadOpt branch if not |
199 tst <coptflg was this option already specified? | |
200 bne BadOpt show help if so | |
201 cmpb #'= 2nd char =? | |
823 | 202 lbne ShowHelp show help if not |
820 | 203 inc <coptflg else tag this option as parsed |
204 ldb #C$SPAC get space | |
205 stb -$01,x write over c | |
206 stb ,x+ and = sign, inc X to dest dir | |
207 * check for valid char after -c= | |
208 lda ,x | |
209 cmpa #C$SPAC | |
210 lbeq ShowHelp | |
211 cmpa #C$CR | |
212 lbeq ShowHelp | |
213 leay <copt,u point Y to parameber buffer | |
214 tfr y,d transfer Y to D | |
215 addd #COPTSIZ | |
216 pshs b,a save updated ptr value | |
217 ldb #C$SPAC get space | |
218 L0339 lda ,x get byte at X | |
219 stb ,x+ store space at X and inc | |
220 sta ,y+ save loaded byte at Y and inc | |
221 cmpy ,s are we at end? | |
222 beq L035D branch if so (buffer too small) | |
223 cmpa #C$SPAC else is char in A a space? | |
224 beq L0350 branch if so | |
225 cmpa #C$CR cr? | |
226 bne L0339 get next byte if not | |
227 L0350 leax -1,x | |
228 sta ,x restore previous A | |
229 leas $02,s kill stack | |
230 lbra ChkDash | |
231 L035D leas $02,s | |
232 ldb #$BF else buffer size too small | |
233 orcc #Carry | |
234 lbra Exit | |
235 FixCmdLn lda #C$SPAC get space | |
236 sta -$01,x and wipe out option character | |
237 cmpb #'0 | |
238 lblt ChkDash start dash option processing again | |
239 lbra GetDash possibly another option following? | |
240 | |
241 * We branch here if we encounter an unknown option character | |
821 | 242 * A = bad option character |
243 BadOpt leax UnkOpt,pcr | |
244 ldy #UnkOptL | |
245 ldb #C$CR | |
246 pshs d save bad option and CR on stack | |
247 lda #$02 stderr | |
248 os9 I$Write | |
249 leax ,s point X at option char on stack | |
250 os9 I$WritLn print option and CR | |
251 puls d clean up stack | |
252 lbra ShowHelp | |
820 | 253 |
254 | |
255 * At this point options are processed. | |
256 * We load X with our parameter pointer and go down the command line | |
257 * looking at each file to process (options have been wiped out with | |
258 * spaces) | |
823 | 259 * |
260 * Note, the following two instructions may not be needed, depending on | |
261 * if your utility requires a non-option on the command line. | |
820 | 262 DoNGU tst <filecnt we should have at least one file on cmdline |
263 lbeq ShowHelp if not, exit with error | |
264 ldx <parmptr get our parameter pointer off stack | |
823 | 265 DoLoop lbsr SkipSpcs skip any leading spaces |
266 cmpa #C$CR end of parameters? | |
267 beq ExitOk if so, end the utility | |
268 pshs x save pointer to arg | |
269 bsr ProcFile process file at X | |
270 puls x get arg pointer | |
271 lbsr SkipNSpc skip the argument we just processed | |
272 bra DoLoop | |
273 | |
274 * This routine processes one file at a time. | |
275 * Entry: X = ptr to argument on the command line. | |
276 * On exit, X can point to the argument or past it. | |
277 * Note that there are NO leading spaces. | |
278 * They have been skipped by the caller. | |
279 * The following code just echos the command line argument, followed | |
280 * by a carriage return. | |
281 ProcFile | |
282 pshs x save ptr | |
283 lda #$01 standard output | |
284 bsr StrLen get length of argument in Y | |
285 puls x recover ptr | |
286 os9 I$Write write name out | |
287 leax CR,pcr point to carriage return | |
288 os9 I$WritLn write it out | |
289 rts | |
820 | 290 |
291 ShowHelp equ * | |
292 IFNE DOHELP | |
293 leax >HlpMsg,pcr point to help message | |
294 ldy #HlpMsgL get length | |
295 lda #$02 std error | |
296 os9 I$WritLn write it | |
297 ENDC | |
298 ExitOk clrb clear carry | |
299 Exit os9 F$Exit and exit | |
300 | |
301 * This routine counts the number of non-whitespace characters | |
302 * starting at X | |
303 * | |
304 * Entry: | |
305 * X = ptr to string (space, comma or CR terminated) | |
306 * Exit: | |
823 | 307 * Y = length of string |
820 | 308 * X = ptr to byte after string |
823 | 309 StrLen pshs a |
310 ldy #$0000 | |
820 | 311 StrLenLp lda ,x+ |
312 cmpa #C$SPAC | |
313 beq StrLenEx | |
314 cmpa #C$CR | |
315 beq StrLenEx | |
823 | 316 leay 1,y |
820 | 317 bra StrLenLp |
823 | 318 StrLenEx puls a,pc |
820 | 319 |
320 * This routine copies a string of text from X to Y until | |
321 * a whitespace character or CR is encountered | |
322 * | |
323 * Entry: | |
324 * X = ptr to src string | |
325 * Y = ptr to dest string | |
326 * Exit: | |
327 * D = number of bytes copied | |
328 * X = ptr to byte after original string | |
329 * Y = ptr to byte after copied string | |
330 StrCpy pshs u | |
331 ldu #$0000 | |
332 CopyFnLp lda ,x+ | |
333 cmpa #C$SPAC | |
334 beq CopyFnEx | |
335 cmpa #C$CR | |
336 beq CopyFnEx | |
337 sta ,y+ | |
338 leau 1,u | |
339 bra CopyFnLp | |
340 CopyFnEx tfr u,d | |
341 puls u,pc | |
342 | |
343 * This routine skip over spaces and commas | |
344 * | |
345 * Entry: | |
346 * X = ptr to data to parse | |
347 * Exit: | |
348 * X = ptr to first non-whitespace char | |
349 * A = non-whitespace char | |
350 SkipSpcs lda ,x+ | |
351 cmpa #C$SPAC | |
352 beq SkipSpcs | |
353 leax -1,x | |
354 rts | |
355 | |
821 | 356 * This routine skips over everything but spaces, commas and CRs |
820 | 357 * |
358 * Entry: | |
359 * X = ptr to data to parse | |
360 * Exit: | |
361 * X = ptr to first whitespace char | |
362 * A = whitespace char | |
363 SkipNSpc lda ,x+ | |
364 cmpa #C$SPAC | |
365 beq EatOut | |
366 cmpa #C$CR | |
367 bne SkipNSpc | |
368 EatOut leax -1,x | |
369 rts | |
370 | |
371 emod | |
372 eom equ * | |
373 end |