Category : File Managers
Archive   : CDDPLUS.ZIP
Filename : CDD.ASM
Output of file : CDD.ASM contained in archive : CDDPLUS.ZIP
title CDD - Change Drive/Directory
name CDD
comment #
CDD.COM V1.00
-------------------------------------------------------------------------------
NAME
cdd Change drive and directory
SYNOPSIS
CDD [D:][\PATH]
where
D: is the desired destination drive
\PATH is the desired path
both drive and path are optional. If the command line is
blank, a help message is printed on the screen.
DESCRIPTION
This program is a clone of Bruce B. Thomson program of the same name.
It will change the drive, directory, or both the drive and directory.
This program is only command line driven. If the command line is
blank, a quick message on how to properly evoke this program is
displayed on the screen.
The program checks for the following errors:
a. The terminal drive is not the same as the one requested.
b. The termanal path is not the same as the one requested.
c. The DOS version is 2.0 or above.
In cases (a) and (b) above, CDD will return you to the starting drive
and path.
CAUTION
CDD does not check drive or path information before using it.
If the drive is changed to a floppy with the drive door open, the
DOS Critical Error Handler is called. A disk must be inserted in
the drive before the DOS Critical Error Handler will relinquish the
use of the computer to you. (There is a way to avoid this. Before
changing drives, use the DOS Absolute Read interrupt to read a sector.
This interrupt does not evoke the Critical Error Handler so this error
can be caught before it happens. The major problem is that this really
slows down the code because of the time it takes to read a sector.
I will leave the addition of this feature as a programming challange
for the user.)
AUTHOR
Raymond Moon - 2 May 87
Copyright (c) 1987
ALL RIGHTS RESERVED
HISTORY
Version - Date - Comments
1.00 2 May 87 - Orginal
#
;-------------------------------
; Required equates and macros.
@EXIT macro RTNCODE ;; Terminate program with return code
mov ax,4c&RTNCODE&h ; Request term with return code
int 21h ; Call PC-DOS
endm
@WRITE macro STRING,FH ;; DOS 2.0+ Write to File Macro
lea dx,STRING ; Load String addr in DX
mov cx,STRING&_LEN ; Load String Length in CX
mov bx,FH ; Load File Handle in BX
mov ah,40h ; Request DOS write to file/device
int 21h ; Call PC-DOS
endm
STDOUT equ 1
TAB equ 9
LF equ 0ah
CR equ 0dh
_MASK equ 0dfh
BLNK equ ' '
GRP group CSEG,DSEG,STRING ; All segments in same segment
assume cs:GRP,ds:GRP,es:GRP,ss:GRP
subttl Data Segments
page
STRING segment word public 'CONST'
public DOS_ERR, INVALID_DRIVE,BAD_PATH,LOGO
public HELP
DOS_ERR db 'Need DOS2.0+$'
INVALID_DRIVE db 'Invalid Drive Specification.'
INVALID_DRIVE_LEN equ $ - INVALID_DRIVE
BAD_PATH db 'Path Not Found.'
BAD_PATH_LEN equ $ - BAD_PATH
LOGO db 'CDD - Change Drive/Directory',CR,LF
db 'Copyright (c) 1987 MoonWare',CR,LF,LF
LOGO_LEN equ $ - LOGO
HELP db 'Evoke CDD with the following command line:',CR,LF,LF
db TAB,'CDD [D:][\PATH]',CR,LF
db TAB,TAB,'where',LF,TAB
db 'D: is the desired drive, optional',CR,LF
db TAB,TAB,TAB,'\PATH is the desired path, optional',CR,LF
HELP_LEN equ $ - HELP
db '***** Raymond Moon - 28 Apr 87 *****'
STRING ends
DSEG segment word public 'DATA'
public CURRENT_DRIVE
CURRENT_DRIVE db ?
DSEG ends
subttl Code Segment
page
CSEG segment para public 'CODE'
;-----------------------------
; Define ARGC, ARGV
PARM struc ; Passed parameter addressing
dw ?,? ; Saved IP and BP
ARGC dw ? ; Number of parameters passed
ARGV dw ? ; Array of pointers.
PARM ends
;-----------------------------
; Define all procedures as public for debugging
public MAIN, CMDLN, PRINT_HELP
;-----------------------------
; Define Command Line arguments located in the PSP
org 80h
PARM_LEN db ?
PARMS db 127 dup(?)
;-----------------------------
; MAIN procedure parses the Command Line
org 100h ; .COM file format
MAIN proc far
mov ah,30h ; Request DOS version
int 21h ; Call DOS
cmp al,2 ; Is it DOS 2.0+
jae MN0 ; Yes, continue
lea dx,DOS_ERR ; DX => Error message
mov ah,9 ; Request print string
int 21h ; Call DOS
int 20h ; Terminate program
MN0: cmp PARM_LEN,0 ; Are there any Command Line arguments
jne MN1 ; Yes, process them
call PRINT_HELP ; No, go print HELP
MN1: xor cx,cx ; Null CX
push cx ; This ensures last *argv ends in NUL
mov cl,PARM_LEN ; Get # of bytes in Command Line
inc cl ; Increment CL to ensure round up
and cx,0feh ; Force an even count
mov ax,sp ; Get SP
mov bp,sp ; Set BP to last byte of Cmd Ln
sub ax,cx ; Subtract PARM_LEN
mov sp,ax ; Reset SP, room on Stack
lea si,PARMS ; Load source addr in SI
mov di,sp ; Load destin addr in DI
cld ; Ensure Direction Flag is up
rep movsb ; Move Command Line onto the Stack
;-----------------------------
; Convert all blanks in the Command Line to Nul
mov bx,bp ; BX points to last byte of Cmd Ln
MN2: mov al,[bx] ; Get byte
cmp al,BLNK ; Is it a blank?
ja MN3 ; No, go set up to get another
xor al,al ; Nul AX
mov [bx],al ; Store Nul in [BX]
MN3: dec bx ; BX point to next byte
cmp bx,sp ; Are we through yet?
jnb MN2 ; No, go one mo' 'gin
;-----------------------------
; Build *argv[]. argc kept in CX. DX used as IN_WORD flag
xor cx,cx ; Set CX (argc) to 0
xor dx,dx ; Set DX to NOT_INWORD
mov bx,bp ; BX point to last byte
mov bp,sp ; BP now points to Top of Stack
MN4: mov al,[bx] ; Get byte
cmp al,0 ; Is it Nul?
jne MN5 ; No, it is a char
cmp dx,0 ; Was the last byte not a char?
je MN6 ; Yes, go on with the processing
xor dx,dx ; No, it was a char. Clear INWORD.
inc cx ; Increment argc
inc bx ; BX points to Cmd Ln arg
push bx ; Push addr onto stack
dec bx ; Reset BX
jmp short MN6 ; Go set up for another byte
MN5: inc dx ; Set DX to INWORD
MN6: dec bx ; BX point to next byte
cmp bx,bp ; Are we at the 1st byte yet?
jnb MN4 ; No, go process another
;-----------------------------
; Set up for and call CMDLN
push cx ; Push ARGC onto stack
call CMDLN ; Call Cmd Ln processor
MAIN endp
public PRINT_HELP
PRINT_HELP proc near
@WRITE HELP,STDOUT ; Print help
@EXIT 01
PRINT_HELP endp
public CMDLN
CMDLN proc near
push bp ; Save bp
mov bp,sp ; Set up frame pointer
;----------------------------
; Print LOGO
@WRITE LOGO,STDOUT ; Print LOGO
;----------------------------
; Find ':', break string into drive and path, set flags.
mov di,[bp].ARGV ; ES:DI => command line drive:path
mov al,':' ; AL = ':'
mov cx,64 ; Max, count
repne scasb ; Find ':'
cmp cx,0 ; Is there a ':'
jnz CN1 ; ':' found
;-----------------------------
; No ':' found => no drive specification. Go change path.
mov dx,[bp].ARGV ; DS:DX => path
mov ah,3bh ; Request change current directory
int 21h ; Call DOS
jc CN0 ; No error, continue
@EXIT 00 ; Exit
;----------------------------
; Error in changing path, tell user.
CN0: mov dl,CURRENT_DRIVE ; DL = old drive
mov ah,0eh ; Request select disk
int 21h ; Call DOS
@WRITE BAD_PATH,STDOUT ; Tell user
@EXIT 02 ; Exit
;-----------------------------
; Change drive. First get current drive.
CN1: mov ah,19h ; Request current drive
int 21h ; Call DOS
mov CURRENT_DRIVE,al ; Save it
mov si,[bp].ARGV ; SI = drive
and byte ptr [si],_MASK ; Convert to upper case
mov dl,byte ptr [si] ; DL = drive letter
sub dl,'A' ; Convert to drive specification
mov ah,0eh ; Request select disk
int 21h ; Call DOS
;----------------------------
; Determine if error occurred by comparing current drive with desired
; drive.
mov ah,19h ; Request current drive
int 21h ; Call DOS
cmp al,dl ; Are they equal?
je CN2 ; Yes, go change path
;----------------------------
; Error changing drive. Revert to old drive.
mov dl,CURRENT_DRIVE ; DL = old drive
mov ah,0eh ; Request select disk
int 21h ; Call DOS
;--------------------------
; Tell user of error and exit.
@WRITE INVALID_DRIVE,STDOUT ; Write error message
@EXIT 02 ; Exit with error code 2
;-----------------------------
; See if there is a path.
CN2: cmp byte ptr [di],0 ; Is it EOS
je CN3 ; Yes, go terminate
;-----------------------------
; Change of drive OK, go change path.
mov dx,di ; DS:DX => path
mov ah,3bh ; Request change current directory
int 21h ; Call DOS
jc CN4 ; No error, continue
CN3: @EXIT 00 ; Exit
;----------------------------
; Return to orginal drive, and tell user of problem.
CN4: mov dl,CURRENT_DRIVE ; DL = old drive
mov ah,0eh ; Request select disk
int 21h ; Call DOS
@WRITE BAD_PATH,STDOUT ; Tell user
@EXIT 02 ; Exit
CMDLN endp
CSEG ends
end MAIN
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/