home *** CD-ROM | disk | FTP | other *** search
- *#######################################################################
- * PROGRAM COPY...File Copy Utility
- *
- * Dr. David C. Wilcox
- * DCW Industries, Inc.
- * 5354 Palm Dr., La Canada, CA 91011
- * 818/790-3844
- *
- * June 4, 1986
- *#####################################################################
- boot equ 00 *warm boot
- print equ 09 *print string
- curdsk equ 25 *return current disk
- chain equ 47 *chain to program
- lf equ 10 *line feed
- cr equ 13 *carriage return
- space equ 32 *ascii space
- bdos equ $0002 *BDOS entry point
- *#####################################################################
- * Special registers:
- *
- * a5 = address of DMA buffer
- * a6 = address of 1st parsed FCB
- * d4 = number of characters in the destination file
- * d5 = number of characters in the source file
- * d6 = adjusted number of characters in the DMA
- *#####################################################################
- *
- * Locate FCB and DMA (for portability)
- *
- link a6,#0 *mark stack frame
- move.l 8(a6),a0 *get base page address
- lea $80(a0),a5 *get address of DMA buffer
- lea $5c(a0),a6 *get address of 1st parsed file name
- clr.l d2 *make sure d2 is empty
- *
- * Check for no files specified
- *
- cmpi.b #space,$1(a6)
- bne start
- move.l #usage,d1 *if no parameters...
- move.w #print,d0 *display instructions
- trap #bdos
- jsr quit *and exit to CP/M
- *
- start: movea.l a5,a1 *point to DMA
- move.b (a1)+,d6 *put total characters in d6
- move.b d6,d2 *transfer to d2 which will be counter
- addq #8,d6 *adjust for 'PIP ' and '[RV]'
- *
- move.l #0,d5 *get the source file name
- movea.l #source,a0
- sfile1: move.b (a1)+,(a0)+
- addq #1,d5
- subq #1,d2 *no destination given...use
- beq msdos *the current disk and user
- cmpi.b #space,(a1)
- bne sfile1
- move.b #'[',(a0) *append the option separator
- addq #1,d5
- adda.l #1,a1 *skip over the space
- *
- move.l #0,d4 *now get the destination file name
- movea.l #dest,a0
- dfile1: move.b (a1)+,(a0)+
- addq #1,d4
- subq #1,d2 *make sure we're not out of characters
- blt error *before we find the null
- cmpi.b #0,(a1)
- bne dfile1
- bra parse
- *
- msdos: move.b #'[',(a0) *append the option separator
- addq #1,d5
- move.w #curdsk,d0 *get current disk
- trap #bdos
- add.b #65,d0 *make it ascii
- movea.l #dest,a0
- move.b d0,(a0)+ *save drive designator in dest
- move.b #':',(a0) *conclude with a ':'
- move.b #2,d4 *save character count in d4
- addq.b #2,d6 *adjust total character count
- *
- parse: jsr usrchk *check for copy across user areas
- *
- movea.l a5,a0 *point to the dma
- move.b d6,(a0)+ *put character count in first byte
- *
- movea.l #cmnd,a1 *now put 'PIP ' in next four bytes
- move.w #4,d2
- jsr movmem
- *
- movea.l #dest,a1 *destination file goes first
- move.b d4,d2
- jsr movmem
- *
- move.b #'=',(a0)+ *insert the '='
- *
- movea.l #source,a1 *source file goes last
- move.b d5,d2
- jsr movmem
- *
- movea.l #option,a1 *and finally we add 'RV]'
- move.w #3,d2
- jsr movmem
- *
- move.b #0,(a0) *and conclude with a null
- *
- move.w #chain,d0 *now let pip do the rest
- trap #bdos
- *#######################################################################
- * Subroutines
- *#######################################################################
- *
- * Display error message and quit
- *
- error:
- move.l #errmsg,d1
- move.w #print,d0
- trap #bdos
- *
- * Quit to CP/M
- *
- quit:
- move.w #boot,d0
- trap #bdos
- *
- * Copy d2 bytes from a1 to a0
- movmem:
- move.b (a1)+,(a0)+
- subq #1,d2
- bne movmem
- rts
- *
- * Check for source file user area
- *
- usrchk:
- movea.l #source,a1
- move.b d5,d2
- move.w #1,d1
- schek: cmpi.b #':',(a1)
- beq sdrv
- adda #1,a1
- addq #1,d1
- subq #1,d2
- bne schek
- bra dchek0 *no user specified...check destination
- sdrv: cmpi.b #2,d1 *is it the logged user?
- bne sdig1 *no...check number of digits
- bra dchek0 *yes...further action not required
- sdig1: cmpi.b #3,d1 *is it a single digit user?
- bne sdig2 *no...check for two digit user
- movea.l #source+1,a1 *get the user number
- move.b (a1),suser+1 *and store it in proper location
- move.b d5,d2
- subq #2,d2
- movea.l #source+2,a1 *rearrange source file syntax
- movea.l #source+1,a0
- jsr movmem
- move.w #2,d2 *now tag on the user specification
- movea.l #suser,a1
- jsr movmem
- addq #1,d5 *and adjust the character count
- addq #1,d6
- bra dchek0
- sdig2: cmpi.b #4,d1 *is it a two digit user?
- bne error *no...incorrect user number
- movea.l #source+1,a1 *get the two digit user number
- move.b (a1)+,suser+1 *and store it in proper location
- move.b (a1),suser+2
- move.b d5,d2
- subq #3,d2
- movea.l #source+3,a1 *rearrange source file syntax
- movea.l #source+1,a0
- jsr movmem
- move.w #3,d2 *now tag on the user specification
- movea.l #suser,a1
- jsr movmem
- addq #1,d5 *and adjust the character count
- addq #1,d6
- dchek0: movea.l #dest,a1 *check for destination file user area
- move.b d4,d2
- move.w #1,d1
- dchek: cmpi.b #':',(a1)
- beq ddrv
- adda #1,a1
- addq #1,d1
- subq #1,d2
- bne dchek
- rts *no user specified...we're all done
- ddrv: cmpi.b #2,d1 *is it the logged user?
- bne ddig1 *no...check number of digits
- rts *yes...further action not required
- ddig1: cmpi.b #3,d1 *is it a single digit user?
- bne ddig2 *no...check for two digit user
- movea.l #dest+1,a1 *get the user number
- move.b (a1),duser+2 *and store it in proper location
- move.b d4,d2
- subq #2,d2
- movea.l #dest+2,a1 *rearrange source file syntax
- movea.l #dest+1,a0
- jsr movmem
- move.w #3,d2 *now tag on the user specification
- movea.l #duser,a1
- jsr movmem
- move.b #']',(a0) *and add a left bracket
- addq #3,d4 *and adjust the character count
- addq #3,d6
- rts
- ddig2: cmpi.b #4,d1 *is it a two digit user?
- bne error *no...incorrect user number
- movea.l #dest+1,a1 *get the two digit user number
- move.b (a1)+,duser+2 *and store it in proper location
- move.b (a1),duser+3
- move.b d4,d2
- subq #3,d2
- movea.l #dest+3,a1 *rearrange source file syntax
- movea.l #dest+1,a0
- jsr movmem
- move.w #4,d2 *now tag on the user specification
- movea.l #duser,a1
- jsr movmem
- move.b #']',(a0) *and add a left bracket
- addq #3,d4 *and adjust the character count
- addq #3,d6
- rts
- *#####################################################################
- * Console Messages
- *#####################################################################
- cmnd: dc.b 'PIP '
- dest: ds.b 32
- source: ds.b 32
- duser: dc.b '[G',0,0
- suser: dc.b 'G',0,0
- even
- option: dc.b 'RV]'
- even
- usage: dc.b lf,cr
- dc.b '---------------------------------------'
- dc.b '---------------------------------------'
- dc.b lf,cr
- dc.b '| Correct usage: '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| COPY {ds[us]:}source file '
- dc.b ' <{dd[ud]:}destination file> |'
- dc.b lf,cr
- dc.b '| '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| ds = source drive '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| us = source user number '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| dd = destination drive '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| ud = destination user number'
- dc.b ' |'
- dc.b lf,cr
- dc.b '| '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| All PIP wildcard options are supported'
- dc.b '...the copy is verified |'
- dc.b lf,cr
- dc.b '| '
- dc.b ' |'
- dc.b lf,cr
- dc.b '| If destination is omitted, current drive '
- dc.b 'and user are assumed |',lf,cr
- dc.b '---------------------------------------'
- dc.b '---------------------------------------'
- dc.b lf,cr,'$'
- even
- errmsg: dc.b 'File name error...COPY aborted',cr,lf,'$'
- *#####################################################################
- end