Mercurial > hg > Members > kono > nitros9-code
changeset 852:42a4f60582d8
Start of assembly touch utility -- still needs work
author | boisy |
---|---|
date | Wed, 15 Jan 2003 00:56:41 +0000 |
parents | 16b8c7dc0082 |
children | 5077ffa665a3 |
files | level1/cmds/touch.asm |
diffstat | 1 files changed, 398 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level1/cmds/touch.asm Wed Jan 15 00:56:41 2003 +0000 @@ -0,0 +1,398 @@ +******************************************************************** +* Touch - Changes last modification date/time +* +* $Id$ +* +* Syntax: Touch [<opts>] {<path> [<opts>]} +* Usage : update the date of a file +* Opts : +* -c = don't create files +* -q = don't quit on error +* -x = search execution directory +* -z = get file names from standard input +* -z=<file> get list of file names from <file> +* +* Ed. Comments Who YY/MM/DD +* ------------------------------------------------------------------ +* 1 Put your development info here BGP 03/01/11 + + nam Touch + ttl Changes last modification date/time + + ifp1 + use defsfile + use rbfdefs + endc + +* Here are some tweakable options +DOHELP set 1 1 = include help info +STCKSIZE set 64 our stack size in bytes +COPTSIZ set 64 max size of C option's parameter + +* Module header definitions +tylg set Prgrm+Objct +atrv set ReEnt+rev +rev set $01 +edition set 1 + + mod eom,name,tylg,atrv,start,size + +* Your utility's static storage vars go here + org 0 +parmptr rmb 2 pointer to our command line params +bufptr rmb 2 pointer to user expandable buffer +bufsiz rmb 2 size of user expandable buffer +* What follows are utility specific options +nocreate rmb 1 +quiterr rmb 1 +filemode rmb 1 +filecnt rmb 1 +zoptflg rmb 1 1 = this option has been processed once already +zpath rmb 1 path to -z file +cleartop equ . everything up to here gets cleared at start +zopt rmb COPTSIZ buffer for what follows after -c= +* Next is a user adjustable buffer with # modifier on command line. +* Some utilities won't need this, some will. +* Currently set up to be larger for Level 2 than Level 1 +* Note: this buffer must come just before the stack + IFGT Level-1 +bigbuff rmb 8*1024 8K default buffer for Level 2 + ELSE +bigbuff rmb 512 512 byte default buffer for Level 1 + ENDC +* Finally the stack for any PSHS/PULS/BSR/LBSRs that we might do +stack rmb STCKSIZE +size equ . + +* The utility name and edition goes here +name fcs /Touch/ + fcb edition + +* Place constant strings here + IFNE DOHELP +HlpMsg fcb C$LF + fcc /Use: Touch [<opts>] <path> [<path>] [<opts>]/ + fcb C$LF + fcc / -c = don't create files/ + fcb C$LF + fcc / -q = don't quit on error/ + fcb C$LF + fcc / -x = search execution directory/ + fcb C$LF + fcc / -z = get file names from standard input/ + fcb C$LF + fcc / -z=<file> get list of file names from <file>/ + fcb C$LF +CR fcb C$CR +HlpMsgL equ *-HlpMsg + ENDC +UnkOpt fcc /unknown option: / +UnkOptL equ *-UnkOpt +CantTch fcc /can't touch "/ +CantTchL equ *-CantTch +EndCant fcc /"/ + fcb C$CR + +* Here's how registers are set when this process is forked: +* +* +-----------------+ <-- Y (highest address) +* ! Parameter ! +* ! Area ! +* +-----------------+ <-- X, SP +* ! Data Area ! +* +-----------------+ +* ! Direct Page ! +* +-----------------+ <-- U, DP (lowest address) +* +* D = parameter area size +* PC = module entry point abs. address +* CC = F=0, I=0, others undefined + +* The start of the program is here. +* Before any command line processing is done, we clear out +* our static memory from U to cleartop, then determine the +* size of our data area (minus the stack). +start pshs u,x save registers for later + leax <cleartop,u point to end of area to zero out + IFNE H6309 + subr u,x subtract U from X + tfr x,w and put X in W + clr ,-s put a zero on the stack + tfm s,u+ and use TFM to clear starting at U + leas 1,s clean up the stack + ELSE + pshs x save end pointer on stack +clrnxt clr ,u+ clear out + cmpu ,s done? + bne clrnxt branch if not + leas 2,s else clear stack + ENDC + puls x,u and restore our earlier saved registers + lda #WRITE. + sta <filemode set up default file mode + leay bigbuff,u point Y to copy buffer offset in U + stx <parmptr save parameter pointer + sty <bufptr save pointer to buffer + tfr s,d place top of stack in D + IFNE H6309 + subr y,d + ELSE + pshs y save Y on stack + subd ,s++ get size of space between copybuf and X + ENDC + subd #STCKSIZE subtract out our stack + std <bufsiz size of our buffer + +* At this point we have determined our buffer space and saved pointers +* for later use. Now we will parse the command line for options that +* begin with - + lbsr SkipSpcs move past any spaces on command line + cmpa #C$CR CR? + lbeq ShowHelp if so, no parameters... show help and exit +GetChar lda ,x+ get next character on cmd line + cmpa #C$CR CR? + lbeq DoTouch if so, do whatever this utility does + cmpa #'- is it an option? + beq GetDash if so, process it + inc <filecnt else must be a non-option argument (file) + lbsr SkipNSpc move past the argument +ChkDash lbsr SkipSpcs and any following spaces + bra GetChar start processing again +GetDash lda #C$SPAC get a space char + sta -1,x and wipe out the dash from the cmd line +GetDash2 ldd ,x+ load option char and char following + ora #$20 make lowercase +IsItC cmpa #'c is it this option? + bne IsItQ branch if not + sta <nocreate + lbra FixCmdLn +IsItQ cmpa #'q is it this option? + bne IsItX branch if not + inc <quiterr + lbra FixCmdLn +IsItX cmpa #'x is it this option? + bne IsItZ branch if not + lda #EXEC. + ora <filemode + sta <filemode + bra FixCmdLn +IsItZ cmpa #'z is it this option? + bne BadOpt branch if not + tst <zoptflg was this option already specified? + bne BadOpt show help if so + sta <zoptflg else tag this option as parsed + cmpb #'= 2nd char =? + bne FixCmdLn +GetZFile ldb #C$SPAC get space + stb -$01,x write over c + stb ,x+ and = sign, inc X to dest dir +* check for valid char after -z= + lda ,x + cmpa #C$SPAC + lbeq ShowHelp + cmpa #C$COMA + lbeq ShowHelp + cmpa #C$CR + lbeq ShowHelp + leay <zopt,u point Y to parameber buffer + tfr y,d transfer Y to D + addd #COPTSIZ + pshs b,a save updated ptr value + ldb #C$SPAC get space +L0339 lda ,x get byte at X + stb ,x+ store space at X and inc + sta ,y+ save loaded byte at Y and inc + cmpy ,s are we at end? + beq L035D branch if so (buffer too small) + cmpa #C$SPAC else is char in A a space? + beq L0350 branch if so + cmpa #C$COMA coma? + beq L0350 branch if so + cmpa #C$CR cr? + bne L0339 get next byte if not +L0350 leax -1,x + sta ,x restore previous A + leas $02,s kill stack +* attempt to open a path to the file + pshs x + leax <zopt,u + lda #READ. + os9 I$Open + lbcs Exit + sta <zpath + puls x + lbra ChkDash +L035D leas $02,s + ldb #$BF else buffer size too small + orcc #Carry + lbra Exit +FixCmdLn lda #C$SPAC get space + sta -$01,x and wipe out option character + cmpb #'0 + lblt ChkDash start dash option processing again + lbra GetDash possibly another option following? + +* We branch here if we encounter an unknown option character +* A = bad option character +BadOpt leax UnkOpt,pcr + ldy #UnkOptL + ldb #C$CR + pshs d save bad option and CR on stack + lda #$02 stderr + os9 I$Write + leax ,s point X at option char on stack + os9 I$WritLn print option and CR + puls d clean up stack + lbra ShowHelp + + +* At this point options are processed. +* We load X with our parameter pointer and go down the command line +* looking at each file to process (options have been wiped out with +* spaces) +* +* Note, the following two instructions may not be needed, depending on +* if your utility requires a non-option on the command line. +DoTouch tst <filecnt we should have at least one file on cmdline + lbeq ShowHelp if not, exit with error + ldx <parmptr get our parameter pointer off stack +DoLoop lbsr SkipSpcs skip any leading spaces + cmpa #C$CR end of parameters? + beq ExitOk if so, end the utility + pshs x save pointer to arg + bsr ProcFile process file at X + puls x get arg pointer + lbsr SkipNSpc skip the argument we just processed + bra DoLoop + +* This routine processes one file at a time. +* Entry: X = ptr to argument on the command line. +* On exit, X can point to the argument or past it. +* Note that there are NO leading spaces. +* They have been skipped by the caller. +* The following code just echos the command line argument, followed +* by a carriage return. +ProcFile + lda <filemode + pshs x + os9 I$Open + puls x + bcc CloseIt +* open failed... should we do create? + tst <nocreate + beq DoCreate +ChkQuit bsr CantTouch + tst <quiterr + beq Exit + bra ProcRTS +DoCreate ldb #PREAD.+UPDAT. + os9 I$Create + bcs ChkQuit +CloseIt os9 I$Close +ProcRTS rts + +CantTouch + pshs x + leax CantTch,pcr + lda #$02 + ldy #CantTchL + os9 I$Write + ldx ,s + bsr StrLen + puls x + os9 I$Write + leax EndCant,pcr + os9 I$WritLn + puls x,pc + +ShowHelp equ * + IFNE DOHELP + leax >HlpMsg,pcr point to help message + ldy #HlpMsgL get length + lda #$02 std error + os9 I$WritLn write it + ENDC +ExitOk clrb clear carry +Exit os9 F$Exit and exit + +* This routine counts the number of non-whitespace characters +* starting at X +* +* Entry: +* X = ptr to string (space, comma or CR terminated) +* Exit: +* Y = length of string +* X = ptr to byte after string +StrLen pshs a + ldy #$0000 +StrLenLp lda ,x+ + cmpa #C$SPAC + beq StrLenEx + cmpa #C$COMA + beq StrLenEx + cmpa #C$CR + beq StrLenEx + leay 1,y + bra StrLenLp +StrLenEx puls a,pc + +* This routine copies a string of text from X to Y until +* a whitespace character or CR is encountered +* +* Entry: +* X = ptr to src string +* Y = ptr to dest string +* Exit: +* D = number of bytes copied +* X = ptr to byte after original string +* Y = ptr to byte after copied string +StrCpy pshs u + ldu #$0000 +CopyFnLp lda ,x+ + cmpa #C$SPAC + beq CopyFnEx + cmpa #C$COMA + beq CopyFnEx + cmpa #C$CR + beq CopyFnEx + sta ,y+ + leau 1,u + bra CopyFnLp +CopyFnEx tfr u,d + puls u,pc + +* This routine skip over spaces and commas +* +* Entry: +* X = ptr to data to parse +* Exit: +* X = ptr to first non-whitespace char +* A = non-whitespace char +SkipSpcs lda ,x+ + cmpa #C$SPAC + beq SkipSpcs + cmpa #C$COMA + beq SkipSpcs + leax -1,x + rts + +* This routine skips over everything but spaces, commas and CRs +* +* Entry: +* X = ptr to data to parse +* Exit: +* X = ptr to first whitespace char +* A = whitespace char +SkipNSpc lda ,x+ + cmpa #C$SPAC + beq EatOut + cmpa #C$COMA + beq EatOut + cmpa #C$CR + bne SkipNSpc +EatOut leax -1,x + rts + + emod +eom equ * + end