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