From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/COPY.ASM | 579 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 579 insertions(+) create mode 100644 v2.0/source/COPY.ASM (limited to 'v2.0/source/COPY.ASM') diff --git a/v2.0/source/COPY.ASM b/v2.0/source/COPY.ASM new file mode 100644 index 0000000..0456a4f --- /dev/null +++ b/v2.0/source/COPY.ASM @@ -0,0 +1,579 @@ +TITLE COMMAND COPY routines. + + INCLUDE COMSW.ASM + +.xlist +.xcref + INCLUDE DOSSYM.ASM + INCLUDE DEVSYM.ASM + INCLUDE COMSEG.ASM +.list +.cref + + INCLUDE COMEQU.ASM + +DATARES SEGMENT PUBLIC + EXTRN VERVAL:WORD +DATARES ENDS + +TRANDATA SEGMENT PUBLIC + EXTRN BADARGS:BYTE,BADCD:BYTE,BADSWT:BYTE,COPIED_PRE:BYTE + EXTRN COPIED_POST:BYTE + EXTRN INBDEV:BYTE,OVERWR:BYTE,FULDIR:BYTE,LOSTERR:BYTE + EXTRN NOSPACE:BYTE,DEVWMES:BYTE,NOTFND:BYTE +TRANDATA ENDS + +TRANSPACE SEGMENT PUBLIC + EXTRN MELCOPY:BYTE,SRCPT:WORD,MELSTART:WORD,SCANBUF:BYTE + EXTRN DESTFCB2:BYTE,SDIRBUF:BYTE,SRCTAIL:WORD,CFLAG:BYTE + EXTRN NXTADD:WORD,DESTCLOSED:BYTE,ALLSWITCH:WORD,ARGC:BYTE + EXTRN PLUS:BYTE,BINARY:BYTE,ASCII:BYTE,FILECNT:WORD + EXTRN WRITTEN:BYTE,CONCAT:BYTE,DESTBUF:BYTE,SRCBUF:BYTE + EXTRN SDIRBUF:BYTE,DIRBUF:BYTE,DESTFCB:BYTE,FRSTSRCH:BYTE + EXTRN FIRSTDEST:BYTE,DESTISDIR:BYTE,DESTSWITCH:WORD,STARTEL:WORD + EXTRN DESTTAIL:WORD,DESTSIZ:BYTE,DESTINFO:BYTE,INEXACT:BYTE + EXTRN CURDRV:BYTE,DESTVARS:BYTE,RESSEG:WORD,SRCSIZ:BYTE + EXTRN SRCINFO:BYTE,SRCVARS:BYTE,USERDIR1:BYTE,NOWRITE:BYTE + EXTRN RDEOF:BYTE,SRCHAND:WORD,CPDATE:WORD,CPTIME:WORD + EXTRN SRCISDEV:BYTE,BYTCNT:WORD,TPA:WORD,TERMREAD:BYTE + EXTRN DESTHAND:WORD,DESTISDEV:BYTE,DIRCHAR:BYTE +TRANSPACE ENDS + + +; ************************************************** +; COPY CODE +; + +TRANCODE SEGMENT PUBLIC BYTE + + EXTRN RESTUDIR:NEAR,CERROR:NEAR,SWITCH:NEAR,DISP32BITS:NEAR + EXTRN PRINT:NEAR,TCOMMAND:NEAR,ZPRINT:NEAR,ONESPC:NEAR + EXTRN RESTUDIR1:NEAR,FCB_TO_ASCZ:NEAR,CRLF2:NEAR,SAVUDIR1:NEAR + EXTRN SETREST1:NEAR,BADCDERR:NEAR,STRCOMP:NEAR,DELIM:NEAR + EXTRN UPCONV:NEAR,PATHCHRCMP:NEAR,SCANOFF:NEAR + + EXTRN CPARSE:NEAR + + EXTRN SEARCH:NEAR,SEARCHNEXT:NEAR,DOCOPY:NEAR,CLOSEDEST:NEAR + EXTRN FLSHFIL:NEAR,SETASC:NEAR,BUILDNAME:NEAR,COPERR:NEAR + + PUBLIC COPY,BUILDPATH,COMPNAME,ENDCOPY + + +ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING + +DOMELCOPY: + cmp [MELCOPY],0FFH + jz CONTMEL + mov SI,[SRCPT] + mov [MELSTART],si + mov [MELCOPY],0FFH +CONTMEL: + xor BP,BP + mov si,[SRCPT] + mov bl,'+' +SCANSRC2: + mov di,OFFSET TRANGROUP:SCANBUF + call CPARSE + test bh,80H + jz NEXTMEL ; Go back to start + test bh,1 ; Switch ? + jnz SCANSRC2 ; Yes + call SOURCEPROC + call RESTUDIR1 + mov di,OFFSET TRANGROUP:DESTFCB2 + mov ax,PARSE_FILE_DESCRIPTOR SHL 8 + INT int_command + mov bx,OFFSET TRANGROUP:SDIRBUF + 1 + mov si,OFFSET TRANGROUP:DESTFCB2 + 1 + mov di,[SRCTAIL] + call BUILDNAME + jmp MELDO + + +NEXTMEL: + call CLOSEDEST + xor ax,ax + mov [CFLAG],al + mov [NXTADD],ax + mov [DESTCLOSED],al + mov si,[MELSTART] + mov [SRCPT],si + call SEARCHNEXT + jz SETNMELJ + jmp ENDCOPY2 +SETNMELJ: + jmp SETNMEL + +COPY: +; First order of buisness is to find out about the destination +ASSUME DS:TRANGROUP,ES:TRANGROUP + xor ax,ax + mov [ALLSWITCH],AX ; no switches + mov [ARGC],al ; no arguments + mov [PLUS],al ; no concatination + mov [BINARY],al ; Binary not specifically specified + mov [ASCII],al ; ASCII not specifically specified + mov [FILECNT],ax ; No files yet + mov [WRITTEN],al ; Nothing written yet + mov [CONCAT],al ; No concatination + mov [MELCOPY],al ; Not a Mel Hallerman copy + mov word ptr [SCANBUF],ax ; Init buffer + mov word ptr [DESTBUF],ax ; Init buffer + mov word ptr [SRCBUF],ax ; Init buffer + mov word ptr [SDIRBUF],ax ; Init buffer + mov word ptr [DIRBUF],ax ; Init buffer + mov word ptr [DESTFCB],ax ; Init buffer + dec ax + mov [FRSTSRCH],al ; First search call + mov [FIRSTDEST],al ; First time + mov [DESTISDIR],al ; Don't know about dest + mov si,81H + mov bl,'+' ; include '+' as a delimiter +DESTSCAN: + xor bp,bp ; no switches + mov di,offset trangroup:SCANBUF + call CPARSE + PUSHF ; save flags + test bh,80H ; A '+' argument? + jz NOPLUS ; no + mov [PLUS],1 ; yes +NOPLUS: + POPF ; get flags back + jc CHECKDONE ; Hit CR? + test bh,1 ; Switch? + jz TESTP2 ; no + or [DESTSWITCH],BP ; Yes, assume destination + or [ALLSWITCH],BP ; keep tabs on all switches + jmp short DESTSCAN + +TESTP2: + test bh,80H ; Plus? + jnz GOTPLUS ; Yes, not a separate arg + inc [ARGC] ; found a real arg +GOTPLUS: + push SI + mov ax,[STARTEL] + mov SI,offset trangroup:SCANBUF ; Adjust to copy + sub ax,SI + mov DI,offset trangroup:DESTBUF + add ax,DI + mov [DESTTAIL],AX + mov [DESTSIZ],cl ; Save its size + inc cx ; Include the NUL + rep movsb ; Save potential destination + mov [DESTINFO],bh ; Save info about it + mov [DESTSWITCH],0 ; reset switches + pop SI + jmp short DESTSCAN ; keep going + +CHECKDONE: + mov al,[PLUS] + mov [CONCAT],al ; PLUS -> Concatination + shl al,1 + shl al,1 + mov [INEXACT],al ; CONCAT -> inexact copy + mov dx,offset trangroup:BADARGS + mov al,[ARGC] + or al,al ; Good number of args? + jz CERROR4J ; no, not enough + cmp al,2 + jbe ACOUNTOK +CERROR4J: + jmp CERROR ; no, too many +ACOUNTOK: + mov bp,offset trangroup:DESTVARS + cmp al,1 + jnz GOT2ARGS + mov al,[CURDRV] ; Dest is default drive:*.* + add al,'A' + mov ah,':' + mov [bp.SIZ],2 + mov di,offset trangroup:DESTBUF + stosw + mov [DESTSWITCH],0 ; no switches on dest + mov [bp.INFO],2 ; Flag dest is ambig + mov [bp.ISDIR],0 ; Know destination specs file + call SETSTARS +GOT2ARGS: + cmp [bp.SIZ],2 + jnz NOTSHORTDEST + cmp [DESTBUF+1],':' + jnz NOTSHORTDEST ; Two char file name + or [bp.INFO],2 ; Know dest is d: + mov di,offset trangroup:DESTBUF + 2 + mov [bp.ISDIR],0 ; Know destination specs file + call SETSTARS +NOTSHORTDEST: + mov di,[bp.TTAIL] + cmp byte ptr [DI],0 + jnz CHKSWTCHES + mov dx,offset trangroup:BADCD + cmp byte ptr [DI-2],':' + jnz CERROR4J ; Trailing '/' error + mov [bp.ISDIR],2 ; Know destination is d:/ + or [bp.INFO],6 + call SETSTARS +CHKSWTCHES: + mov dx,offset trangroup:BADSWT + mov ax,[ALLSWITCH] + cmp ax,GOTSWITCH + jz CERROR4J ; Switch specified which is not known + +; Now know most of the information needed about the destination + + TEST AX,VSWITCH ; Verify requested? + JZ NOVERIF ; No + MOV AH,GET_VERIFY_ON_WRITE + INT int_command ; Get current setting + PUSH DS + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + XOR AH,AH + MOV [VERVAL],AX ; Save current setting + POP DS +ASSUME DS:TRANGROUP + MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 ; Set verify + INT int_command +NOVERIF: + xor bp,bp ; no switches + mov si,81H + mov bl,'+' ; include '+' as a delimiter +SCANFSRC: + mov di,offset trangroup:SCANBUF + call CPARSE ; Parse first source name + test bh,1 ; Switch? + jnz SCANFSRC ; Yes, try again + or [DESTSWITCH],bp ; Include copy wide switches on DEST + test bp,BSWITCH + jnz NOSETCASC ; Binary explicit + cmp [CONCAT],0 + JZ NOSETCASC ; Not Concat + mov [ASCII],ASWITCH ; Concat -> ASCII copy if no B switch +NOSETCASC: + push SI + mov ax,[STARTEL] + mov SI,offset trangroup:SCANBUF ; Adjust to copy + sub ax,SI + mov DI,offset trangroup:SRCBUF + add ax,DI + mov [SRCTAIL],AX + mov [SRCSIZ],cl ; Save its size + inc cx ; Include the NUL + rep movsb ; Save this source + mov [SRCINFO],bh ; Save info about it + pop SI + mov ax,bp ; Switches so far + call SETASC ; Set A,B switches accordingly + call SWITCH ; Get any more switches on this arg + call SETASC ; Set + call FRSTSRC + jmp FIRSTENT + +ENDCOPY: + CALL CLOSEDEST +ENDCOPY2: + MOV DX,OFFSET TRANGROUP:COPIED_PRE + CALL PRINT + MOV SI,[FILECNT] + XOR DI,DI + CALL DISP32BITS + MOV DX,OFFSET TRANGROUP:COPIED_POST + CALL PRINT + JMP TCOMMAND ; Stack could be messed up + +SRCNONEXIST: + cmp [CONCAT],0 + jnz NEXTSRC ; If in concat mode, ignore error + mov dx,offset trangroup:SRCBUF + call zprint + CALL ONESPC + mov dx,offset trangroup:NOTFND + jmp COPERR + +SOURCEPROC: + push SI + mov ax,[STARTEL] + mov SI,offset trangroup:SCANBUF ; Adjust to copy + sub ax,SI + mov DI,offset trangroup:SRCBUF + add ax,DI + mov [SRCTAIL],AX + mov [SRCSIZ],cl ; Save its size + inc cx ; Include the NUL + rep movsb ; Save this sorce + mov [SRCINFO],bh ; Save info about it + pop SI + mov ax,bp ; Switches so far + call SETASC ; Set A,B switches accordingly + call SWITCH ; Get any more switches on this arg + call SETASC ; Set + cmp [CONCAT],0 + jnz LEAVECFLAG ; Leave CFLAG if concatination +FRSTSRC: + xor ax,ax + mov [CFLAG],al ; Flag destination not created + mov [NXTADD],ax ; Zero out buffer + mov [DESTCLOSED],al ; Not created -> not closed +LEAVECFLAG: + mov [SRCPT],SI ; remember where we are + mov di,offset trangroup:USERDIR1 + mov bp,offset trangroup:SRCVARS + call BUILDPATH ; Figure out everything about the source + mov si,[SRCTAIL] ; Create the search FCB + return + +NEXTSRC: + cmp [PLUS],0 + jnz MORECP +ENDCOPYJ2: + jmp ENDCOPY ; Done +MORECP: + xor bp,bp ; no switches + mov si,[SRCPT] + mov bl,'+' ; include '+' as a delimiter +SCANSRC: + mov di,offset trangroup:SCANBUF + call CPARSE ; Parse first source name + JC EndCopyJ2 ; if error, then end (trailing + case) + test bh,80H + jz ENDCOPYJ2 ; If no '+' we're done + test bh,1 ; Switch? + jnz SCANSRC ; Yes, try again + call SOURCEPROC +FIRSTENT: + mov di,FCB + mov ax,PARSE_FILE_DESCRIPTOR SHL 8 + INT int_command + mov ax,word ptr [SRCBUF] ; Get drive + cmp ah,':' + jz DRVSPEC1 + mov al,'@' +DRVSPEC1: + sub al,'@' + mov ds:[FCB],al + mov ah,DIR_SEARCH_FIRST + call SEARCH + pushf ; Save result of search + call RESTUDIR1 ; Restore users dir + popf + jz NEXTAMBIG0 + jmp SRCNONEXIST ; Failed +NEXTAMBIG0: + xor al,al + xchg al,[FRSTSRCH] + or al,al + jz NEXTAMBIG +SETNMEL: + mov cx,12 + mov di,OFFSET TRANGROUP:SDIRBUF + mov si,OFFSET TRANGROUP:DIRBUF + rep movsb ; Save very first source name +NEXTAMBIG: + xor al,al + mov [NOWRITE],al ; Turn off NOWRITE + mov di,[SRCTAIL] + mov si,offset trangroup:DIRBUF + 1 + call FCB_TO_ASCZ ; SRCBUF has complete name +MELDO: + cmp [CONCAT],0 + jnz SHOWCPNAM ; Show name if concat + test [SRCINFO],2 ; Show name if multi + jz DOREAD +SHOWCPNAM: + mov dx,offset trangroup:SRCBUF + call ZPRINT + call CRLF2 +DOREAD: + call DOCOPY + cmp [CONCAT],0 + jnz NODCLOSE ; If concat, do not close + call CLOSEDEST ; else close current destination + jc NODCLOSE ; Concat flag got set, close didn't really happen + mov [CFLAG],0 ; Flag destination not created +NODCLOSE: + cmp [CONCAT],0 ; Check CONCAT again + jz NOFLUSH + CALL FLSHFIL ; Flush output between source files on CONCAT + ; so LOSTERR stuff works correctly + TEST [MELCOPY],0FFH + jz NOFLUSH + jmp DOMELCOPY + +NOFLUSH: + call SEARCHNEXT ; Try next match + jnz NEXTSRCJ ; Finished with this source spec + mov [DESTCLOSED],0 ; Not created or concat -> not closed + jmp NEXTAMBIG ; Do next ambig + +NEXTSRCJ: + jmp NEXTSRC + + + +BUILDPATH: + test [BP.INFO],2 + jnz NOTPFILE ; If ambig don't bother with open + mov dx,bp + add dx,BUF ; Set DX to spec + mov ax,OPEN SHL 8 + INT int_command + jc NOTPFILE + mov bx,ax ; Is pure file + mov ax,IOCTL SHL 8 + INT int_command + mov ah,CLOSE + INT int_command + test dl,devid_ISDEV + jnz ISADEV ; If device, done + test [BP.INFO],4 + jz ISSIMPFILE ; If no path seps, done +NOTPFILE: + mov dx,word ptr [BP.BUF] + cmp dh,':' + jz DRVSPEC5 + mov dl,'@' +DRVSPEC5: + sub dl,'@' ; A = 1 + call SAVUDIR1 + mov dx,bp + add dx,BUF ; Set DX for upcomming CHDIRs + mov bh,[BP.INFO] + and bh,6 + cmp bh,6 ; Ambig and path ? + jnz CHECKAMB ; jmp if no + mov si,[BP.TTAIL] + cmp byte ptr [si-2],':' + jnz KNOWNOTSPEC + mov [BP.ISDIR],2 ; Know is d:/file + jmp short DOPCDJ + +KNOWNOTSPEC: + mov [BP.ISDIR],1 ; Know is path/file + dec si ; Point to the / +DOPCDJ: + jmp short DOPCD + +CHECKAMB: + cmp bh,2 + jnz CHECKCD +ISSIMPFILE: +ISADEV: + mov [BP.ISDIR],0 ; Know is file since ambig but no path + return + +CHECKCD: + call SETREST1 + mov ah,CHDIR + INT int_command + jc NOTPDIR + mov di,dx + xor ax,ax + mov cx,ax + dec cx + repne scasb + dec di + mov al,[DIRCHAR] + mov [bp.ISDIR],2 ; assume d:/file + cmp al,[di-1] + jz GOTSRCSLSH + stosb + mov [bp.ISDIR],1 ; know path/file +GOTSRCSLSH: + or [bp.INFO],6 + call SETSTARS + return + + +NOTPDIR: + mov [bp.ISDIR],0 ; assume pure file + mov bh,[bp.INFO] + test bh,4 + retz ; Know pure file, no path seps + mov [bp.ISDIR],2 ; assume d:/file + mov si,[bp.TTAIL] + cmp byte ptr [si],0 + jz BADCDERRJ2 ; Trailing '/' + cmp byte ptr [si],'.' + jz BADCDERRJ2 ; If . or .. pure cd should have worked + cmp byte ptr [si-2],':' + jz DOPCD ; Know d:/file + mov [bp.ISDIR],1 ; Know path/file + dec si ; Point at last '/' +DOPCD: + xor bl,bl + xchg bl,[SI] ; Stick in a NUL + call SETREST1 + mov ah,CHDIR + INT int_command + xchg bl,[SI] + retnc +BADCDERRJ2: + JMP BADCDERR + +SETSTARS: + mov [bp.TTAIL],DI + add [bp.SIZ],12 + mov ax,('.' SHL 8) OR '?' + mov cx,8 + rep stosb + xchg al,ah + stosb + xchg al,ah + mov cl,3 + rep stosb + xor al,al + stosb + return + + +COMPNAME: + PUSH CX + PUSH AX + MOV si,offset trangroup:SRCBUF + MOV di,offset trangroup:DESTBUF + MOV CL,[CURDRV] + MOV CH,CL + CMP BYTE PTR [SI+1],':' + JNZ NOSRCDRV + LODSW + SUB AL,'A' + MOV CL,AL +NOSRCDRV: + CMP BYTE PTR [DI+1],':' + JNZ NODSTDRV + MOV AL,[DI] + INC DI + INC DI + SUB AL,'A' + MOV CH,AL +NODSTDRV: + CMP CH,CL + jnz RET81P + call STRCOMP + jz RET81P + mov ax,[si-1] + mov cx,[di-1] + push ax + and al,cl + pop ax + jnz RET81P ; Niether of the mismatch chars was a NUL +; Know one of the mismatch chars is a NUL +; Check for ".NUL" compared with NUL + cmp al,'.' + jnz CHECKCL + or ah,ah + jmp short RET81P ; If NUL return match, else no match +CHECKCL: + cmp cl,'.' + jnz RET81P ; Mismatch + or ch,ch ; If NUL return match, else no match +RET81P: + POP AX + POP CX + return + +TRANCODE ENDS + + END + \ No newline at end of file -- cgit v1.2.3