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