home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Bila Vrana
/
BILA_VRANA.iso
/
005A
/
CDDBNG11.ZIP
/
CDD!.ASM
next >
Wrap
Assembly Source File
|
1995-08-23
|
15KB
|
569 lines
PAGE 60,132
TITLE CDD! 1.1 replacement for 4DOS CDD command sets ERRORLEVEL=
; changes drive and directory
Comment |
┌──────────────────────┐
│ CDD! C:\MySub\MySub2 │
│ CDD! C:\MySub\ │
│ CDD! C:MySub │
│ CDD! .. │
│ CDD! D:\ │
│ CDD! D: │
│ CDD! \ │
│ CDD! │
│ ^watch the space │
└──────────────────────┘
Written in Microsoft Assembler MASM 5.0
by Roedy Green
Canadian Mind Products
#601 - 1330 Burrard Street
Vancouver, BC
Canada V6Z 2B8
(604) 685-8412
This program is copyrighted but free. The source and object
code may be used for any purpose except military. You are free
to copy it, sell it, modify it, or cannibalize it. You can take
out the credits if you want. The only restriction, backed up by
Canadian Mind Products standard very nasty penalties is that you
must make sure none of it is ever used for a military purpose.
Version History:
================
Version 1.1
- change of address
Version 1.0
- This is the initial and hopefully last version.
Purpose
=======
The CD command that comes with MS or PC DOS has three flaws:
1. It does not set the ERRORLEVEL for Invalid directories.
2. It fails when there is a trailing backslash on the name.
3. You cannot hide its error messages with >NUL: redirection.
4. It won't also change the drive for you in one step.
CDD! acts just like CD except that it fixes these four problems.
CDD! is slower since it is must be loaded each time, whereas CD
is internal to DOS. It is similar to the 4DOS command CDD.
Samples of Use
==============
CDD! behaves just like the normal 4DOS CDD command except that it
sets ERRORLEVEL to 1 if it fails because the directory requested
does not exist.
CDD! C:\MYDIR\MYSUBDIR
IF ERRORLEVEL 1 ECHO missing directory
CD \MYDIR
CDD! SUBDIR
IF ERRORLEVEL 1 ECHO missing directory
CDD! \MYDIR\MYSUBDIR\
IF ERRORLEVEL 1 ECHO missing directory
CDD! ..
IF ERRORLEVEL 1 ECHO already at the root
CDD! D:\
REM changes the current directory on D: to the root
CDD! D:
REM displays the current directory on D:
CDD!
REM displays the current directory.
Notes on How CDD! Works
======================
CDD! parses the command line looking for a subdirectory name.
If there is no command line, we display the current directory
on the current drive using DOS function 47h. In order to
display the current drive, we uses DOS function 19h.
If there is simply a C: or D: we display the current directory
on the requested drive using DOS function 47h, and make that the
current drive using function 0Eh. We pick up whatever is the
current directory for that drive. We don't necessarily go to
the root.
If we find a full directory name e.g. XXX or C:\MYSUB or C:\ we
uses DOS function 3BH to attempt to change the current
directory.
If the command succeeds we exit with errorlevel = 0.
If it fails we exit with errorlevel = 1.
| ; End of long comment
; M A C R O S
CR MACRO ; Carriage return line feed
DB 0dh,0ah
ENDM
;======
EOS MACRO ; marks end of display string
DB 0dh,0ah,'$'
ENDM
;======
CODE SEGMENT PARA
ASSUME CS:CODE,DS:CODE,ES:CODE
ORG 100H
;======================================
Start: JMP Main
;======================================
; REGISTER CONVENTIONS
; all registers are trashable in calls except BX and CX
; BX always points to the start of the command string.
; CX always counts number of chars in the command string
; exclusive of nulls, leading and trailing blanks.
; Because this is a com file, all segment registers are
; stable equal to CS:
;======================================
SAY MACRO Msg
; display message on screen
LEA DX,&Msg ; use LEA rather than
; MOV Offset for more generality
MOV AH,09h
INT 21h
ENDM
;======================================
; Embedded but not displayed
CopyrightMsg label byte ; does not display
CR
DB '░▒▓█ CDD! 1.1 █▓▒░'
CR
DB 'Freeware to change the default drive and directory.'
CR
DB 'usage: CDD! C:\Mysub1\MySub2'
CR
DB 'Copyright (c) 1988, 1993 Roedy Green Canadian Mind Products'
CR
DB '#601 - 1330 Burrard Street, Vancouver BC CANADA V6Z 2B8 (604) 685-8412'
CR
DB 'May be freely distributed and used for any purpose except military.'
EOS
;======================================
Current DB 65d DUP (0) ; work area
; for current directory name
; THIS IS NOT THE SAME AS THE
; COMMAND LINE.
;======================================
NoSuchDriveMsg LABEL BYTE
DB 'Invalid drive',"$"
NoSuchDirMsg LABEL BYTE
DB 'Invalid directory',"$"
ColonSlashMsg LABEL BYTE
DB ':\',"$"
CrLfMsg LABEL BYTE
DB 13,10,"$"
;========================================
MLeading PROC Near
; on entry BX is addr of string, CX its length
; trims off any leading blanks, leaving result in BX CX
; length may also be 0 or 1, but not -ve
; If the entire string is blank the result is the null string
MOV DI,BX
MOV AL,20h ; AL = blank -- the search char
JCXZ MLEADING2 ; jump if null string
REPE SCASB ; scan ES:DI forwards till hit non blank
; DI points just after it (wrap ok)
; CX is one too small, or 0 if none found
JE MLEADING1 ; jump if entire string was blank
INC CX ; CX is length of remainder of string
MLEADING1:
DEC DI ; DI points to non-blank
MLEADING2:
MOV BX,DI ; put address back
RET
MLeading ENDP
;========================================
MTrailing PROC Near
; on entry BX is addr of string, CX its length
; trims off any trailing blanks, leaving result in BX CX
; length may also be 0 or 1, but not -ve
; If the entire string is blank the result is the null string
MOV DI,BX
ADD DI,CX ; calc addr last char in string
DEC DI
MOV AL,20h ; AL = blank -- the search char
JCXZ MTRAILING1 ; jump if null string
STD
REPE SCASB ; scan ES:DI backwards till hit non blank
; DI points just ahead of it (wrap ok)
; CX is one too small, or 0 if none found
CLD
JE MTRAILING1 ; jump if whole string was blank
INC CX
MTRAILING1:
RET
MTrailing ENDP
;========================================;====
Parse PROC NEAR
; Parse the command line to remove lead/trail blanks
; and terminate by 2 nulls.
; sample inputs
; CDD! C:\MySub\MySub2\
; CDD! MySub2
; CDD!
; CDD! D:\
; CDD! D:
;
; When Done DS:BX points to start of string.
; String will be terminated by 2 nulls
; CX counts bytes in string exclusive of nulls
; counted string at HEX 80 PSP
; contains command line.
; Preceeded by unwanted spaces.
; possibly followed by unwanted spaces.
; currently missing a trailing null.
XOR CH,CH
MOV CL,DS:80h
MOV BX,81h
CALL Mleading ; get rid of leading blanks
CALL MTrailing ; get rid of trailing blanks
MOV DI,BX ; calc addr of byte just past end
ADD DI,CX
MOV WORD PTR [DI],0 ; plop in pair of nulls after string
RET
Parse ENDP
;=======================================
Analyze PROC Near
; On entry DS:BX points to start of string.
; String will be terminated by nulls.
; CX counts bytes in string exclusive of nulls.
; We have to analyze the string and set
; 3 indicator bits in DX
; 1. DrivePresent 0=no 4=yes
; 2. SubdirPresent 0=no 2=yes
; 3. SlashPresent 0=no 1=yes - trailing slash
; Handles case
; 123
; 0 000 CDD! __
; 1 001 CDD! \__
; 2 010 CDD! ABC__
; 3 011 CDD! ABC\__
; 4 100 CDD! C:__
; 5 101 CDD! C:\__
; 6 110 CDD! C:ABC__
; 7 111 CDD! C:ABC\__
; We look first for drive, then slash, finally subdir
PUSH BX
PUSH CX
XOR DX,DX ; build indicator in DX
JCXZ NoSubdir
CMP BYTE PTR [BX+1],':'
JNE NoDrive
ADD DX,4 ; C: drive was present
ADD BX,2 ; bypass drive
SUB CX,2
JCXZ NoSubdir
NoDrive:
MOV DI,BX
ADD DI,CX ; find end of string
CMP BYTE PTR [DI-1],'\'
JNE NoSlash
; was trailing slash
INC DX
DEC CX ; bypass slash
NoSlash:
JCXZ NoSubdir ; anything left -- the subdir
ADD DX,2 ; Was Subir
NoSubdir:
; DX contains analysis.
POP CX ; restore old length
POP BX ; restore old start
RET