*####################################################################### * 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