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