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