GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — MS-DOS/v2.0/source/COPY.ASM at main · microsoft/MS-DOS
This repository was archived by the owner on Apr 25, 2024. It is now read-only.
Expand file tree/ Copy pathCOPY.ASMMore file actions 580 lines (538 loc) · 20 KB / Copy pathCOPY.ASMFile metadata and controls580 lines (538 loc) · 20 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 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 |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |