changeset 802:3a308921e135 basic09v010100 nos9l2v020100beta2 os9l2v030002beta2

New version of copy with OSK like features
author boisy
date Sun, 12 Jan 2003 23:08:10 +0000
parents e3a18315da10
children f72dd0b71aee
files level1/cmds/copy.asm
diffstat 1 files changed, 624 insertions(+), 277 deletions(-) [+]
line wrap: on
line diff
--- a/level1/cmds/copy.asm	Sun Jan 12 17:25:32 2003 +0000
+++ b/level1/cmds/copy.asm	Sun Jan 12 23:08:10 2003 +0000
@@ -5,315 +5,662 @@
 *
 * Ed.    Comments                                       Who YY/MM/DD
 * ------------------------------------------------------------------
-* 10     Reworked                                       RML
+*   9    From Tandy OS-9 Level One VR 02.00.00
+*  10    Reworked                                       RML
+*  11    Added useful options, made more robust         BGP 03/01/11
 
          nam   Copy
          ttl   File copy utility
 
-* Edition 10 rewrite 10/28/88 - RML
-
-         ifp1  
+         ifp1
          use   defsfile
          use   rbfdefs
-         endc  
+         endc
 
-tylg     set   Prgrm+Objct
+* Tweakable options
+DOHELP   set   1
+
+tylg     set   Prgrm+Objct   
 atrv     set   ReEnt+rev
 rev      set   $01
-edition  set   10
+edition  set   11
 
          mod   eom,name,tylg,atrv,start,size
 
-inpath   rmb   1          input path number
-outpath  rmb   1          output path number
-indevtyp rmb   1          input device type (1 = RBF)
-verify   rmb   1          verify on/off (1=on)
-bufsize  rmb   2          read/write buffer size
-fsizemsb rmb   2          msb's of file size
-fsizelsb rmb   2          lsb's of file size
-writemsb rmb   2          msb's of bytes written to output
-writelsb rmb   2          lsb's of bytes written to output
-single   rmb   1          single drive copy flag (1=yes)
-attribs  rmb   1          file attributes
-fdbuff   rmb   16         File Descriptor buffer
-optbuff  rmb   32         Path Descriptor Options Buffer
-stack    rmb   448        stack storage
-vfybuff  rmb   256        verify buffer
-buffer   rmb   $2000-.    read/write buffer (minimum..will expand with mem mod)
+STCKSIZE equ   64	our stack size
+DDIRBSIZ equ   64	destination directory buffer size
+
+         org   0
+rdbufptr rmb   2
+parmptr  rmb   2
+srcpath  rmb   1
+dstpath  rmb   1
+devtyp   rmb   1
+bufsiz   rmb   2
+srcflsiz rmb   4
+abortflg rmb   1
+quiet    rmb   1
+single   rmb   1
+rewrite  rmb   1
+filecnt  rmb   1
+srccnt   rmb   1
+srcmode  rmb   1
+wopt     rmb   1
+srcfname rmb   2
+dstfptr  rmb   2
+wfileptr rmb   2
+wfilelen rmb   2
+lstfopen rmb   2		pointer to name of last file attempted open
+lstfopln rmb   2		length of last file atteppted open
+srcattr  rmb   1
+fdbufcpy rmb   16
+optbuf   rmb   32
+wdest    rmb   DDIRBSIZ		portion after '-w='
+         rmb   DDIRBSIZ		additional space
+* Note: copy buffer must come just before the stack
+         IFGT  Level-1
+copybuff rmb   8*1024		8K default buffer for Level 2
+         ELSE
+copybuff rmb   512		512 byte default buffer for Level 1
+         ENDC
+stack    rmb   STCKSIZE
 size     equ   .
 
 name     fcs   /Copy/
          fcb   edition
 
-start    leas  vfybuff,u  set stack pointer to 512
-         pshs  u          save u reg
-         leau  <optbuff,u point u to 20th byte
-
-clearit  clr   ,-u        clear byte
-         cmpu  ,s         done ?
-         bhi   clearit    loop back
-         tfr   y,d        move in top of mem (after param area)
-         subd  ,s++       subtract current stack
-         subd  #$0300     and back off variable storage
-         clrb             round off to page bondary
-         std   <bufsize   buffer size
-         pshs  x          save x register
+SrcPmpt  fcc   /Ready SOURCE, hit C to continue: /
+SrcPmptL equ   *-SrcPmpt
+DstPmpt  fcc   /Ready DESTINATION, hit C to continue: /
+DstPmptL equ   *-DstPmpt
+CrRtn    fcb   C$CR
+         IFNE  DOHELP
+HlpMsg   fcb   C$LF
+         fcc   /Use: Copy [<opts>] <srcpath> [<dstpath>] [<opts>]/
+         fcb   C$LF
+         fcc   /   -a        abort on error/
+         fcb   C$LF
+         fcc   /   -p        don't print file nammes copied (with -w option only)/
+         fcb   C$LF
+         fcc   /   -r        rewrite destination/
+         fcb   C$LF
+         fcc   /   -s        single drive copy/
+         fcb   C$LF
+         fcc   /   -w=<dir>  copy files to <dir>/
+         fcb   C$LF
+         fcc   /   -x        look in execution directory for source/
+         fcb   C$CR
+HlpMsgL  equ   *-HlpMsg
+         ENDC
+PLIncmp  fcc   /copy: destination must be complete pathlist/
+         fcb   C$CR
+TooMany  fcc   /copy: must specify output directory if more than 2 files/
+         fcb   C$CR
+Copying  fcc   /copying /
+CopyingL equ   *-Copying
+CopyTo   fcc   / to /
+CopyToL  equ   *-CopyTo
+Cont     fcc   !Continue (y/n) ?!
+ContL    equ   *-Cont
+CantCpy  fcc   /copy: can't open /
+CantCpyL equ   *-CantCpy
+SpcDsh   fcc   / - /
+SpcDshL  equ   *-SpcDsh
 
-getopt   lda   ,x+        get a char
-         cmpa  #'-        was it a '-'??
-         beq   chkopt     yes..go check opt
-         cmpa  #C$CR      was it a <cr>??
-         bne   getopt     no..check next char
-         bra   openin     else done..go finish processing
-
-chkopt   ldd   ,x+        get next 2 chars
-         eora  #'S        check if its an S
-         anda  #$DF       make upper case
-         lbne  sndinstr   not an s.. send instructions
-         cmpb  #$30       else check if next char is number or letter
-         lbhs  sndinstr   yup...send instructions
-         inc   <single    set s option
-         bra   getopt     and check next char
+*   +-----------------+  <--  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
 
-openin   puls  x          restore line pointer
-         lda   #READ.     open first file
-         os9   I$Open
-         lbcs  chkerr     error..go see what it was
-         sta   <inpath    save path number
-         pshs  x          save second path name start
-         leax  <fdbuff,u  point to FD buffer
-         ldy   #FD.SEG    bytes to read
-         ldb   #SS.FD     get file descriptor
-         os9   I$GetStt
-         puls  x          restore line pointer
-         bcs   getintyp   skip this on eror
-         tst   <single    single drive copy ?
-         beq   getintyp   no..skip this stuff
-         lda   ,x         get first char of path name
-         ldb   #E$BPNam   load bad path name error message
-         cmpa  #PDELIM    was it a path separaor ?
-         bne   errjump    nope..error
+start    pshs  u,x
+         leax  <wdest,u
+         pshs   x
+clrnxt   clr   ,u+
+         cmpu  ,s
+         bne   clrnxt
+         leas  2,s
+         puls  x,u
+         leay  copybuff,u	point Y to copy buffer offset in U
+         stx   <parmptr		save parameter pointer
+         sty   <rdbufptr	save pointer to buffer
+         tfr   s,d		place top of stack in D
+         pshs  y		save Y on stack
+         subd  ,s++		get size of space between copybuf and X
+         subd  #STCKSIZE	subtract out our stack
+         std   <bufsiz		size of our buffer
+         lbsr  SkipSpcs         move past any spaces on command line
+         cmpa  #C$CR		CR?
+         lbeq  ShowHelp		if so, show help
+GetNChr  lda   ,x+
+         cmpa  #C$CR		CR?
+         lbeq  CpyFiles		branch if so
+         cmpa  #'-		option?
+         beq   GetDash
+         inc   <filecnt         must be a file
+         lbsr  SkipNSpc         else go past non-spaces
+ChkDash  lbsr  SkipSpcs         and any following spaces
+         bra   GetNChr          and check for Cr
+GetDash  lda   #C$SPAC
+         sta   -1,x
+GetDash2 ldd   ,x+		load option char and char following
+         anda  #$5F
+         cmpa  #'S		single drive copy?
+         bne   IsItA		branch if not
+         inc   <single
+         lbra  FixCmdLn
+IsItA    cmpa  #'A		abort option?
+         bne   IsItP		branch if not
+         inc   <abortflg
+         bra   FixCmdLn
+IsItP    cmpa  #'P		supress output?
+         bne   IsItX		branch if not
+         inc   <quiet
+         bra   FixCmdLn
+IsItX    cmpa  #'X		execution dir?
+         bne   IsItW		branch if not
+         lda   #EXEC.		else get EXEC.
+         sta   <srcmode		and save as source mode
+         bra   FixCmdLn
+IsItW    cmpa  #'W		directory specification?
+         bne   IsItR		branch if not
+         tst   <wopt		already specified?
+         bne   BadOpt		show help if so
+         cmpb  #'=		2nd char =?
+         bne   BadOpt		show help if not
+         inc   <wopt		else tag wopt as specified
+         ldb   #C$SPAC		get space
+         stb   -$01,x		write over w
+         stb   ,x+		and = sign, inc X to dest dir
+* check for valid char after -w=
+         lda   ,x
+         cmpa  #C$SPAC
+         lbeq  ShowHelp         
+         cmpa  #C$COMA
+         lbeq  ShowHelp         
+         cmpa  #C$CR
+         lbeq  ShowHelp         
+         leay  <wdest,u		point Y to parameber buffer
+         sty   <dstfptr		save pointer to destination file
+         tfr   y,d		transfer Y to D
+         addd  #DDIRBSIZ	add size
+         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
+         lda   #PDELIM		get pathlist delimiter
+         sta   -$01,y		save slash at end (for building path later)
+         sty   <wfileptr	save pointer for -w pathlist file copying
+         leas  $02,s		kill stack
+         lbra  ChkDash
+L035D    leas  $02,s
+         ldb   #$BF		else buffer size too small
+         orcc  #Carry
+         lbra  Exit
+IsItR    cmpa  #'R		rewrite?
+         bne   BadOpt		branch if not
+         inc   <rewrite
+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?
 
-getintyp pshs  x          save out path name start
-         lda   <inpath    get path number
-         bsr   getopts    get option section
-         lda   ,x         get device type
-         sta   <indevtyp  save it
-         ldb   #PREAD.+EXEC.+READ.+WRITE.  default attributes...read,write,execute,public
-         cmpa  #DT.RBF    was device type RBF ?
-         bne   openout    nope...don't get file size/attributes
-         pshs  u,x        save registers
-         lda   <inpath    get path number
-         ldb   #SS.Size   Get File size
-         bsr   getstat    do the GetStt call..exit on error
-         stx   <fsizemsb  save 2 msb's of file size
-         stu   <fsizelsb  save 2 lsb's of file size
-         puls  u,x        restore registers
-         ldb   <PD.ATT-PD.OPT,x   get file attributes
+BadOpt   puls  x
+         lbra  ShowHelp
 
-openout  stb   <attribs   save attributes
-         ldx   ,s         get start of second path name
-         lbsr  destsnd    send destination msg
-         lda   #UPDAT.    open file for update
-         ldb   <attribs   get attributes
-         os9   I$Create   create the file
-         puls  x          restore x register
-         bcc   open010    no error..skip this
-         inc   <verify    set verify off
-         lda   #WRITE.    open filein write only mode
-         ldb   <attribs   get atributes
-         os9   I$Create   create the file
-         bcs   errjump    exit on error
-
-open010  sta   <outpath   save second path number
-         bsr   getopts    get option section
-         ldb   ,x         get device type
-         cmpb  #DT.RBF    was it RBF
-         beq   setvfy     yup...skip this
-         inc   <verify    set verify off
-         bra   mainloop   and skip all this
-
-errjump  lbra  errexit    nope....error
-
-getopts  leax  <optbuff,u point to buffer
-         ldb   #SS.Opt    get option section of path descritor
-
-getstat  os9   I$GetStt
-         bcs   errjump    exit on error
+CopyToW  ldx   <srcfname	get ptr to next file to process
+* In case the source file name has a / in it (i.e. /dd/x/y/fname),
+* we go past the file and then back up to either the first / we
+* encounter, or a space (be sure we don't go past parmptr)
+         lda   ,x
+         cmpa  #C$CR		carriage return?
+         lbeq  ExitOk		yep, no more files
+         lbsr  SkipNSpc		skip over filename
+* X points to first char after file name (space, comma or CR)
+L038B    cmpx  <parmptr         are we at start of command line?
+         beq   PlugIt2		if so, we can't go further back
+         lda   ,-x		get byte
+         cmpa  #PDELIM		path delimiter?
+         beq   PlugIt           branch if so
+         cmpa  #C$SPAC		space?
+         beq   PlugIt           branch if so
+         cmpa  #C$COMA		comma?
+         beq   PlugIt           branch if so
+         bra   L038B		else get next char 
+PlugIt   leax  1,x		go forward 1
+PlugIt2  ldy   <wfileptr	get address past xxxx/ (specified by -w=)
+         lbsr  StrCpy		copy filenamme
+         std   <wfilelen	save file length
+         lda   #C$CR		get CR
+         sta   ,y		and terminate
+*         ldx   <wopt
+*         stx   <wfileptr
          rts   
 
-setvfy   tst   <verify    do we want verify on
-         bne   setsiz     nope...dont set driver verify on
-         ldb   #1         verify
-         stb   PD.VFY-PD.OPT,x        turn verify on
-         ldb   #SS.OPT    set options
-         os9   I$SetStt
-         bcs   errjump    exit on error
-
-setsiz   lda   <indevtyp  get device type
-         cmpa  #DT.RBF    is it an RBF file
-         bne   mainloop   nope...dont preset file size
-         pshs  u          save register
-         lda   <outpath   get out path number
-         ldb   #SS.Size   set file size
-         ldx   <fsizemsb  get 2 msb's of in file size
-         ldu   <fsizelsb  get 2 lsb's of in file size
-         os9   I$SetStt   set the size
-         bcs   errjump    exit on error
-         puls  u          restore register
-         lda   <outpath   get out path number
-         leax  <fdbuff,u  point to FD buffer
-         ldy   #FD.SEG    number of bytes to write
-         ldb   #SS.FD     write out the FD (for dates,etc.)
-         os9   I$SetStt
-
-mainloop leax  buffer,u   point to buffer
-         clra             source drive code
-         lbsr  chkdrive   send source switch msg
-         lda   <inpath    get in path number
-         ldy   <bufsize   get buffer size
-         os9   I$Read     read a block
-         bcs   chkeof2    if error..go check which one
-         lbsr  destsnd    send destination switch msg
-         lda   <outpath   get out path number
-         os9   I$Write    write the block out
-         bcs   errjump    exit on error
-         tst   <verify    are we verifying ?
-         bne   chkeof     skip this
-         pshs  u,y        save registers
-         ldx   <writemsb  get 2 msb's of last write
-         ldu   <writelsb  get 2 lsb's of last write
-         lda   <outpath   get out path number
-         os9   I$Seek
-         bcs   errjump    exit on error
-         ldu   2,s        get original u back
-         leau  buffer,u   point to buffer start
-         ldd   ,s         get bytes written
-         addd  <writelsb  add on to current 2 lsb positions
-         std   <writelsb  save them
-         ldd   ,s         get bytes written
-         bcc   vfy000     skip if no carry
-         leax  1,x        bump up 2 msb's
-         stx   <writemsb  and save them
+* At this point options are processed, so we need to start copying files
+CpyFiles 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
+         lbsr  SkipSpcs		skip any leading spaces
+         tst   <wopt		-w specified?
+         beq   L03C5		branch if not
+         stx   <srcfname	else save start of parameter pointer as next file
+         clr   <single		no single option with -w
+L03BE    bsr   CopyToW		copy file at <srcfname to -w buffer
+         bra   OpenSrc
+* This code handles single file copy (i.e. copy file1 file2)
+* or a single disk copy (i.e. copy -s abc)
+L03C5    lbsr  GetSDFl		else get source/destination files
+         bcc   L03D4		branch if we got both ok
+         tst   <single		is this a single drive copy?
+         lbne  PListErr		if not, user didn't specify enough files
+         lbcs  Exit		if error, exit
+* test for right number of files
+L03D4    lda   <filecnt		get total file count
+         cmpa  #2               should be no more than two files
+         ble   OpenSrc
+         leax  TooMany,pcr
+         lbsr  WrLine
+         lbra  ExitOk
+OpenSrc  ldx   <srcfname	get file to open
+         pshs  x
+         lbsr  StrLen		get length
+         std   <lstfopln	save length
+         puls  x
+         lda   #READ.		read mode
+         ora   <srcmode		or in any additional modes (i.e. EXEC.)
+         stx   <lstfopen	save pointer to last file open var
+         os9   I$Open   	open source file
+         bcc   L03FA		branch if open ok
+         cmpx  <srcfname	did open go past pathlist?
+         bne   OpenFail		branch if so
+         lbsr  SkipNSpc         else skip over failed filename
+         lbsr  SkipSpcs         and any trailing spaces
+OpenFail stx   <srcfname	save updated pathlist pointer (points to next file on cmd line)
+         lbra  ShutDown
+L03FA    sta   <srcpath		save source path
+         pshs  a		save path
+         lbsr  SkipSpcs		destroy any leading spaces
+         stx   <srcfname	and save pointer to next source filename
+         lbsr  StrLen		get length
+         std   <lstfopln	save length
+         puls  a		get path off stack
+         leax  <fdbufcpy,u	point to FD buffer
+         ldy   #FD.SEG		number of bytes
+         ldb   #SS.FD
+         os9   I$GetStt 	get file's file descriptor
+         bcs   L041B		branch if error
+         tst   <single		single drive copy?
+         beq   L041B		branch if not
+         lda   [<dstfptr,u]	get first char of destination filename
+         ldb   #E$BPNam		prepare for possible error
+         cmpa  #PDELIM		path has leading slash?
+         lbne  PListErr		if not, show error
+L041B    lda   <srcpath		get source path
+         leax  <optbuf,u	point to options buffer
+         clrb			was: ldb #SS.Opt
+         os9   I$GetStt 	get path options
+         lbcs  ShutDown		branch if error
+         lda   ,x		get device type
+         sta   <devtyp		save
+         ldb   #$0F
+         cmpa  #DT.RBF		rbf device?
+         bne   L0449		branch if not
+         pshs  u,x		save regs
+         lda   <srcpath		get source path
+         ldb   #SS.Size
+         os9   I$GetStt 	get size
+         lbcs  ShutDown
+         stx   <srcflsiz	save file size
+         stu   <srcflsiz+2
+         puls  u,x		restore regs
+         ldb   <PD.ATT-PD.OPT,x	get source file's attributes
+L0449    stb   <srcattr		save
+         lda   #$01
+         lbsr  SwapDsk		check for single disk copy and prompt if necessary
+L0450    ldx   <dstfptr		point to destination file
+         pshs  x
+         lbsr  StrLen		get length
+         std   <lstfopln	save length
+         puls  x
+         lda   #WRITE.		write mode
+         ldb   <srcattr		get source attributes
+         stx   <lstfopen
+         os9   I$Create 	create file
+         bcc   L048B		branch if create ok
+         tst   <rewrite		rewrite flag set?
+         lbeq  ShutDown		branch if no
+         cmpb  #E$CEF		file already exists?
+         lbne  ShutDown		branch if any other error
+L047A    os9   I$Delete 	delete file first
+         lbcs  ShutDown		branch if error
+         bra   L0450		else try opening again
+L048B    sta   <dstpath		save destination path
+         tst   <wopt		w option specified?
+         beq   GetOpts		branch iff not
+         tst   <quiet		p option specified?
+         bne   GetOpts		branch if so
+         pshs  a		else save dest path on stack
+         leax  >Copying,pcr	else print 'Copying...'
+         ldy   #CopyingL
+         lbsr  WritSOut		write it to stdout
+         ldx   <wfileptr	get pointer to file being copied
+         ldy   <wfilelen	get file name length
+         lbsr  WritSOut		print file name
+         leax  >CopyTo,pcr	print ' to '
+         ldy   #CopyToL
+         lbsr  WritSOut		write it to stdout
+         ldx   <dstfptr		get pointer to file being copied
+         lbsr  WrLine		print file with CR
+         puls  a		restore dest path
+GetOpts  leax  <optbuf,u	point to option buffer
+         clrb			was: ldb #SS.Opt
+         os9   I$GetStt 	get options
+         lbcs  ShutDown		branch if error
+         ldb   ,x		get device type
+         cmpb  #DT.RBF		rbf?
+         bne   CopyLoop		if not rbf device, don't get file size or fd seg
+L04B4    lda   <devtyp		get device type
+         cmpa  #DT.RBF		rbf?
+         bne   CopyLoop		branch if not
+         pshs  u		save our statics ptr
+         lda   <dstpath		else get dest path
+         ldb   #SS.Size		and setstat option
+         ldx   <srcflsiz	get file size of source
+         ldu   <srcflsiz+2
+         os9   I$SetStt 	and set dest file to same size
+         lbcs  ShutDown		branch if error
+         puls  u		restore U
+         lda   <dstpath		get dest path
+         leax  <fdbufcpy,u	point to file desc. buffer
+         ldy   #FD.SEG		get size
+         ldb   #SS.FD
+         os9   I$SetStt 	write src fd seg to dest file
+* Copy loop is here
+CopyLoop ldx   <rdbufptr	get ptr to read buffer
+         clra  			A = 0 = source prompt if needed
+         lbsr  SwapDsk		check for single disk copy and prompt if so
+         lda   <srcpath		get source path
+         ldy   <bufsiz		get buffer size
+         os9   I$Read   	read it!
+         bcs   L0558		branch if error
+         lda   #$01		A = 1 = dest prompt
+         lbsr  SwapDsk		check for single disk copy and prompt if so
+         lda   <dstpath		get dest path
+         os9   I$Write  	write it out!
+         lbcs  ShutDown		branch if error
+         lda   <srcpath		get source path
+         ldb   #SS.EOF
+         os9   I$GetStt 	are we at end of file?
+         bcc   CopyLoop		branch if not
+         cmpb  #E$EOF		end of file error?
+         beq   L0561		branch if so
+L0558    cmpb  #E$EOF		end of file rror?
+         bne   ShutDown		branch if not
+         lda   #$01		prompt destination flag
+         lbsr  SwapDsk		check for single drive copy and prompt if necessary
+L0561    lda   <dstpath		get destination path
+         os9   I$Close  	close that file
+         bcs   ShutDown		branch if error
+         clr   <dstpath		else clear dest path
+         lda   <srcpath		get source path
+         os9   I$Close  	close it
+         bcs   ShutDown		branch if error
+         clr   <srcpath		clear src path
+         tst   <wopt		-w specified
+         lbeq  ExitOk		branch if not
+         lbra  L03BE
 
-vfy000   ldy   #$0100     chars to read for verify
-         std   ,s         save it
-         tsta             did we write more than 255 bytes ?
-         bne   vfy010     yes...only read 256
-         tfr   d,y        else xfer amount we did write
-
-vfy010   ldx   2,s        get u register
-         leax  $200,x     point to start of verify buffer
-         lda   <outpath   get output path number
-         os9   I$Read     read a block in
-         bcs   errexit    exit on error
-
-vfy020   lda   ,u+        get char from in buffer
-         cmpa  ,x+        get char from out buffer
-         bne   snderr1    not equal...send write verfiy msg
-         leay  -1,y       decrement read count
-         bne   vfy020     if more..loop back
-         ldd   ,s         get write count back
-         subd  #$0100     subtract verify buffer size
-         bhi   vfy000     if more left...loop back
-         puls  u,y        else restore registers
-
-chkeof   lda   <inpath    get in path number
-         ldb   #SS.EOF    check for end of file
-         os9   I$GetStt
-         bcc   mainloop   nope...loop back
-         cmpb  #E$EOF     are we at end of file ?
-         beq   closeout   yes...close file
-
-
-chkeof2  cmpb  #E$EOF     check for end of file
-         bne   errexit    nope...error exit
-         bsr   destsnd    send msg for disk switch
-
-closeout lda   <outpath   get out path number
-         os9   I$Close    close the file
-         bcc   exitok     exit w/o error if o.k.
-         bra   errexit    else error exit
-
-errmsg1  fcb   C$BELL
-         fcc   /Error - write verification failed./
-         fcb   C$CR
-
-snderr1  leax  errmsg1,pcr address of 'write verify failed' msg
-         bsr   sndline    send it
-         comb             set carry
-         ldb   #$01       set error
-         bra   errexit    exit
-
-chkerr   cmpb  #E$BPNam   was it bad path name
-         bne   errexit    error exit
-
-sndinstr leax  Help,pcr   get instructions
-         bsr   sndline    send them
-exitok   clrb  
-errexit  os9   F$Exit
-
-sndline  ldy   #256       max chars to send
-         lda   #1         std out
-         os9   I$WritLn   write the line
+* Entry: X = ptr to data to write, Y = length
+WritSOut lda   #$01		standard out
+         os9   I$Write  	write it
          rts   
 
-* Send message and wait for disk switch for single drive copy
-
-destsnd  lda   #1         set flag for destination message
+PListErr leax  >PLIncmp,pcr
+         bsr   WrLine
+         bra   ExitOk
 
-chkdrive tst   <single    are we doing single drive copy
-         beq   msgrts     nope..just exit
-         pshs  y,x        else save registers
+ShutDown pshs  b
+         lda   <srcpath		get source path
+         beq   L05AA		branch if none
+         os9   I$Close  	close it
+L05AA    lda   <dstpath		get dest path
+         beq   L05B1		branch if none
+         os9   I$Close  	close it
+L05B1    clr   <srcpath		clear source path
+         clr   <dstpath		and destination
+         leax  >CantCpy,pcr	else show can't copy error
+         ldy   #CantCpyL
+         bsr   WritSOut		write out
+         ldx   <lstfopen	show filename that failed
+         ldy   <lstfopln	get length
+         bsr   WritSOut
+         leax  >SpcDsh,pcr
+         ldy   #SpcDshL
+         bsr   WritSOut		write out
+         puls  b
+PrintErr os9   F$PErr   	print error
+         tst   <wopt		-w used?
+         beq   ExitOk		branch if not
+         tst   <abortflg	abort flag set?
+         bne   ExitOk		branch if so
+AskAgain leax  >Cont,pcr	point to continue prompt
+         ldy   #ContL		get length
+         bsr   WritSOut		write
+         clra                   ADDED +BGP+
+         ldx   <rdbufptr	get pointer at readbuf
+         ldy   #$0002		2 bytes
+         os9   I$ReadLn 	read form stdin
+         lda   ,x		get byte at X
+         anda  #$5F
+         cmpa  #'Y		user wants to continue?
+         lbeq  L03BE		branch if so
+         cmpa  #'N		no?
+         beq   ExitOk		branch if so
+         bra   AskAgain		else ask again
 
-sndsrc   pshs  a          save drive flag
-         tsta             do we want source drive ?
-         bne   snddst     nope..do destination message
-         leax  srcmsg,pcr point to 'source' msg
-         ldy   #srcmsgsz  chars to send
-         bra   msgsnd     go send it
+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
 
-srcmsg   fcc   /Ready SOURCE/
-srcmsgsz equ   *-srcmsg
+* Write line passed in X
+WrLine   ldy   #$00A0
+WrNBytes lda   #$01
+         os9   I$WritLn 
+         rts   
 
-dstmsg   fcc   /Ready DESTINATION/
-dstmsgsz equ   *-dstmsg
-
-cntmsg   fcc   /, hit C to continue: /
-cntmsgsz equ   *-cntmsg
-
-
-snddst   leax  dstmsg,pcr point to 'destination' msg
-         ldy   #dstmsgsz  chars to send
+* Prompt User for Source or Destination Disk
+SwapDsk  tst   <single		single disk copy?
+         beq   NoSwap		branch if not
+         pshs  y,x
+L0626    pshs  a
+         tsta  
+         bne   L0635
+         leax  >SrcPmpt,pcr	point to source prompt
+         ldy   #SrcPmptL	get size
+         bra   L063D		write it and get input
+L0635    leax  >DstPmpt,pcr	point to dest prompt
+         ldy   #DstPmptL	get size
+L063D    bsr   WrNBytes		write it
+         leax  ,-s		point to stack for temp buffer
+         ldy   #$0001		one byte
+         clra  			from std in
+         os9   I$Read   	read byte from user
+         lda   ,s+		get char
+         eora  #'C
+         anda  #$DF
+         beq   L0657		branch if C
+         bsr   L065E
+         puls  a
+         bne   L0626
+L0657    bsr   L065E
+         puls  a
+         puls  y,x
+NoSwap   rts   
+L065E    pshs  y,x,a
+         lda   #$01
+         leax  >CrRtn,pcr
+         ldy   #80
+         os9   I$WritLn 
+         puls  pc,y,x,a
 
-msgsnd   lda   #1         std out
-         os9   I$Write    write it
-         leax  cntmsg,pcr point to 'hit C ...'
-         ldy   #cntmsgsz  get size of message
-         os9   I$Write    write it
-         leax  ,-s        back up for dummy buffer
-         ldy   #1         chars to read
-         clra             std in
-         os9   I$Read     read one char
-         lda   ,s+
-         pshs  y,x,a      save registers
-         leax  crmsg,pcr  point to <cr>
-         bsr   sndline    write it
-         puls  y,x,a      restore registers
-         eora  #'C        check if its a C
-         anda  #$DF       make it upper case
-         puls  a          restore drive status
-         bne   sndsrc     loop back & send message
-         puls  y,x        restore registers
-msgrts   rts   
+* StrLen
+*
+* Entry:
+*   X = ptr to string (space, comma or CR terminated)
+* Exit:
+*   D = length of string
+*   X = ptr to byte after string
+StrLen   pshs  u
+         ldu   #$0000
+StrLenLp lda   ,x+
+         cmpa  #C$SPAC
+         beq   StrLenEx
+         cmpa  #C$COMA
+         beq   StrLenEx
+         cmpa  #C$CR
+         beq   StrLenEx
+         leau  1,u
+         bra   StrLenLp
+StrLenEx tfr   u,d
+         puls  u,pc
+
+* StrCpy
+*
+* Entry:
+*   X = ptr to src string
+*   Y = ptr to dest string
+* Exit:
+*   D = number of bytes copied
+*   X = ptr to byte after original string
+*   X = 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
+
+* Skip over spaces and commas
+*
+* Entry:
+*   X = ptr to string
+* 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
 
-Help     fcc   /Use: Copy <Path1> <Path2> [-s]/
-         fcb   C$LF
-         fcc   /  -s = single drive copy/
-         fcc   / (Path2 must be complete pathlist)/
-         fcb   C$CR
-crmsg    fcb   C$CR
+* Skip over non-spaces and non-commas
+*
+* Entry:
+*   X = ptr to string
+* Exit:
+*   X = ptr to first non-whitespace char
+*   A = non-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
+
+* Get source file in <srcfname and destination file in <dstfptr
+GetSDFl  leay  <srcfname,u	point X to next file pointer
+         bsr   SrchFile		skip white spaces, look for name on cmd line
+         bcs   L067D		branch if end
+         inc   <srccnt		else increment souce count
+         leay  <dstfptr,u	point Y to destination file
+         bsr   SkipSpcs		destroy any leading spaces
+         bsr   SrchFile		skip white spaces, look for name on cmd line
+L067D    rts   
 
-         emod  
+* Starting at X, parse for a filename, skipping leading white spaces
+SrchFile lda   ,x
+         cmpa  #C$CR		CR?
+         beq   L06A2		branch if so
+         stx   ,y		else store X at Y
+SkipFile bsr   SkipNSpc         skip non-spaces
+ParseOk  clrb  			clear B
+         rts  			return 
+L06A2    tst   <srccnt		any file specified?
+         bne   L06AA		branch if so
+BadPName ldb   #E$BPNam		else no source was specified
+         coma  
+         rts   
+
+L06AA    ldx   <srcfname	get pointer
+L06AC    lda   ,x+		get char
+         cmpa  #C$SPAC		space?
+         beq   L06C4		branch if so
+         cmpa  #C$COMA		comma?
+         beq   L06C4		branch if so
+         cmpa  #C$CR		carriage return?
+         beq   L06C4		branch if so
+         cmpa  #PDELIM		pathlist delimiter?
+         bne   L06AC		branch if not
+         clr   <srccnt		else clear file count
+         stx   ,y		and store
+         bra   L06AC		continue parsing
+L06C4    tst   <srccnt		file count 0?
+         beq   L06D2		branch if so
+         tst   <srcmode		source mode? (exec or data dir)
+         beq   BadPName		branch if data
+         ldx   <srcfname	else get pointer
+         stx   ,y		save
+         bra   ParseOk		branch 
+L06D2    lda   -$02,x
+         cmpa  #PDELIM
+         beq   BadPName
+         bra   ParseOk
+
+         emod
 eom      equ   *
          end