home *** CD-ROM | disk | FTP | other *** search
/ Bila Vrana / BILA_VRANA.iso / 005A / CDDBNG11.ZIP / CDD!.ASM next >
Assembly Source File  |  1995-08-23  |  15KB  |  569 lines

  1.     PAGE    60,132
  2.     TITLE    CDD! 1.1 replacement for 4DOS CDD command sets ERRORLEVEL=
  3.         ; changes drive and directory
  4. Comment |
  5.  
  6. ┌──────────────────────┐
  7. │ CDD! C:\MySub\MySub2 │
  8. │ CDD! C:\MySub\       │
  9. │ CDD! C:MySub           │
  10. │ CDD! ..           │
  11. │ CDD! D:\           │
  12. │ CDD! D:           │
  13. │ CDD! \           │
  14. │ CDD!               │
  15. │     ^watch the space │
  16. └──────────────────────┘
  17.  
  18. Written in Microsoft Assembler MASM 5.0
  19.  
  20.  
  21. by Roedy Green
  22. Canadian Mind Products
  23. #601 - 1330 Burrard Street
  24. Vancouver, BC
  25. Canada    V6Z 2B8
  26. (604) 685-8412
  27.  
  28. This program is copyrighted but free.  The source and object
  29. code may be used for any purpose except military.  You are free
  30. to copy it, sell it, modify it, or cannibalize it.  You can take
  31. out the credits if you want.  The only restriction, backed up by
  32. Canadian Mind Products standard very nasty penalties is that you
  33. must make sure none of it is ever used for a military purpose.
  34.  
  35. Version History:
  36. ================
  37.  
  38. Version 1.1
  39.     - change of address
  40.  
  41. Version 1.0
  42.     - This is the initial and hopefully last version.
  43.  
  44. Purpose
  45. =======
  46.  
  47. The CD command that comes with MS or PC DOS has three flaws:
  48. 1.  It does not set the ERRORLEVEL for Invalid directories.
  49. 2.  It fails when there is a trailing backslash on the name.
  50. 3.  You cannot hide its error messages with >NUL: redirection.
  51. 4.  It won't also change the drive for you in one step.
  52.  
  53. CDD! acts just like CD except that it fixes these four problems.
  54. CDD! is slower since it is must be loaded each time, whereas CD
  55. is internal to DOS.  It is similar to the 4DOS command CDD.
  56.  
  57. Samples of Use
  58. ==============
  59.  
  60. CDD! behaves just like the normal 4DOS CDD command except that it
  61. sets ERRORLEVEL to 1 if it fails because the directory requested
  62. does not exist.
  63.  
  64. CDD! C:\MYDIR\MYSUBDIR
  65. IF ERRORLEVEL 1 ECHO missing directory
  66.  
  67. CD   \MYDIR
  68. CDD! SUBDIR
  69. IF ERRORLEVEL 1 ECHO missing directory
  70.  
  71. CDD! \MYDIR\MYSUBDIR\
  72. IF ERRORLEVEL 1 ECHO missing directory
  73.  
  74. CDD! ..
  75. IF ERRORLEVEL 1 ECHO already at the root
  76.  
  77. CDD! D:\
  78. REM changes the current directory on D: to the root
  79.  
  80. CDD! D:
  81. REM displays the current directory on D:
  82.  
  83. CDD!
  84. REM displays the current directory.
  85.  
  86. Notes on How CDD! Works
  87. ======================
  88.  
  89. CDD! parses the command line looking for a subdirectory name.
  90.  
  91. If there is no command line, we display the current directory
  92. on the current drive using DOS function 47h.  In order to
  93. display the current drive, we uses DOS function 19h.
  94.  
  95. If there is simply a C: or D: we display the current directory
  96. on the requested drive using DOS function 47h, and make that the
  97. current drive using function 0Eh.  We pick up whatever is the
  98. current directory for that drive.  We don't necessarily go to
  99. the root.
  100.  
  101. If we find a full directory name e.g. XXX or  C:\MYSUB or C:\ we
  102. uses DOS function 3BH to attempt to change the current
  103. directory.
  104.  
  105. If the command succeeds we exit with errorlevel = 0.
  106.  
  107. If it fails we exit with errorlevel = 1.
  108.  
  109. | ; End of long comment
  110.  
  111. ; M A C R O S
  112.  
  113. CR    MACRO    ; Carriage return line feed
  114.     DB 0dh,0ah
  115.     ENDM
  116.  
  117. ;======
  118.  
  119. EOS    MACRO    ; marks end of display string
  120.     DB 0dh,0ah,'$'
  121.     ENDM
  122.  
  123. ;======
  124.  
  125.  
  126. CODE    SEGMENT PARA
  127.  
  128.     ASSUME    CS:CODE,DS:CODE,ES:CODE
  129.     ORG    100H
  130.  
  131. ;======================================
  132.  
  133. Start:    JMP    Main
  134. ;======================================
  135. ;    REGISTER CONVENTIONS
  136. ;    all registers are trashable in calls except BX and CX
  137. ;    BX always points to the start of the command string.
  138. ;    CX always counts number of chars in the command string
  139. ;    exclusive of nulls, leading and trailing blanks.
  140. ;    Because this is a com file, all segment registers are
  141. ;    stable equal to CS:
  142. ;======================================
  143. SAY    MACRO    Msg
  144. ;    display message on screen
  145.     LEA    DX,&Msg     ; use LEA rather than
  146.                 ; MOV Offset for more generality
  147.     MOV    AH,09h
  148.     INT    21h
  149.     ENDM
  150. ;======================================
  151. ;    Embedded but not displayed
  152.  
  153.  
  154. CopyrightMsg    label byte    ; does not display
  155.     CR
  156.     DB    '░▒▓█ CDD! 1.1 █▓▒░'
  157.     CR
  158.     DB    'Freeware to change the default drive and directory.'
  159.     CR
  160.     DB    'usage:  CDD!  C:\Mysub1\MySub2'
  161.     CR
  162.     DB    'Copyright (c) 1988, 1993 Roedy Green Canadian Mind Products'
  163.     CR
  164.     DB    '#601 - 1330 Burrard Street, Vancouver BC CANADA V6Z 2B8  (604) 685-8412'
  165.     CR
  166.     DB    'May be freely distributed and used for any purpose except military.'
  167.     EOS
  168.  
  169.  
  170. ;======================================
  171. Current DB    65d DUP (0)    ; work area
  172.                 ; for current directory name
  173.                 ; THIS IS NOT THE SAME AS THE
  174.                 ; COMMAND LINE.
  175. ;======================================
  176. NoSuchDriveMsg    LABEL    BYTE
  177.     DB    'Invalid drive',"$"
  178.  
  179. NoSuchDirMsg    LABEL    BYTE
  180.     DB    'Invalid directory',"$"
  181.  
  182. ColonSlashMsg    LABEL    BYTE
  183.     DB    ':\',"$"
  184.  
  185. CrLfMsg     LABEL    BYTE
  186.     DB    13,10,"$"
  187. ;========================================
  188. MLeading    PROC    Near
  189. ;    on entry BX is addr of string, CX its length
  190. ;    trims off any leading blanks, leaving result in BX CX
  191. ;    length may also be 0 or 1, but not -ve
  192. ;    If the entire string is blank the result is the null string
  193.     MOV    DI,BX
  194.     MOV    AL,20h        ; AL = blank  -- the search char
  195.     JCXZ    MLEADING2    ; jump if null string
  196.     REPE    SCASB        ; scan ES:DI forwards till hit non blank
  197.                 ; DI points just after it (wrap ok)
  198.                 ; CX is one too small, or 0 if none found
  199.     JE    MLEADING1    ; jump if entire string was blank
  200.     INC    CX        ; CX is length of remainder of string
  201. MLEADING1:
  202.     DEC    DI        ; DI points to non-blank
  203. MLEADING2:
  204.     MOV    BX,DI        ; put address back
  205.     RET
  206. MLeading    ENDP
  207. ;========================================
  208. MTrailing    PROC    Near
  209. ;    on entry BX is addr of string, CX its length
  210. ;    trims off any trailing blanks, leaving result in BX CX
  211. ;    length may also be 0 or 1, but not -ve
  212. ;    If the entire string is blank the result is the null string
  213.     MOV    DI,BX
  214.     ADD    DI,CX        ; calc addr last char in string
  215.     DEC    DI
  216.     MOV    AL,20h        ; AL = blank  -- the search char
  217.     JCXZ    MTRAILING1    ; jump if null string
  218.     STD
  219.     REPE    SCASB        ; scan ES:DI backwards till hit non blank
  220.                 ; DI points just ahead of it (wrap ok)
  221.                 ; CX is one too small, or 0 if none found
  222.     CLD
  223.     JE    MTRAILING1    ; jump if whole string was blank
  224.     INC    CX
  225. MTRAILING1:
  226.     RET
  227. MTrailing    ENDP
  228. ;========================================;====
  229. Parse    PROC    NEAR
  230. ;    Parse the command line to remove lead/trail blanks
  231. ;    and terminate by 2 nulls.
  232. ;    sample inputs
  233. ;    CDD!    C:\MySub\MySub2\
  234. ;    CDD! MySub2
  235. ;    CDD!
  236. ;    CDD!  D:\
  237. ;    CDD!  D:
  238. ;
  239. ;    When Done DS:BX points to start of string.
  240. ;    String will be terminated by 2 nulls
  241. ;    CX counts bytes in string exclusive of nulls
  242.                 ; counted string at HEX 80 PSP
  243.                 ; contains command line.
  244.                 ; Preceeded by unwanted spaces.
  245.                 ; possibly followed by unwanted spaces.
  246.                 ; currently missing a trailing null.
  247.     XOR    CH,CH
  248.     MOV    CL,DS:80h
  249.     MOV    BX,81h
  250.     CALL    Mleading    ; get rid of leading blanks
  251.     CALL    MTrailing    ; get rid of trailing blanks
  252.     MOV    DI,BX        ; calc addr of byte just past end
  253.     ADD    DI,CX
  254.     MOV    WORD PTR [DI],0 ; plop in pair of nulls after string
  255.     RET
  256. Parse    ENDP
  257. ;=======================================
  258. Analyze PROC    Near
  259. ;    On entry DS:BX points to start of string.
  260. ;    String will be terminated by nulls.
  261. ;    CX counts bytes in string exclusive of nulls.
  262. ;    We have to analyze the string and set
  263. ;    3 indicator bits in DX
  264. ;    1.  DrivePresent  0=no 4=yes
  265. ;    2.  SubdirPresent 0=no 2=yes
  266. ;    3.  SlashPresent  0=no 1=yes  - trailing slash
  267. ;    Handles case
  268. ;      123
  269. ;    0 000  CDD! __
  270. ;    1 001  CDD! \__
  271. ;    2 010  CDD! ABC__
  272. ;    3 011  CDD! ABC\__
  273. ;    4 100  CDD! C:__
  274. ;    5 101  CDD! C:\__
  275. ;    6 110  CDD! C:ABC__
  276. ;    7 111  CDD! C:ABC\__
  277. ;    We look first for drive, then slash, finally subdir
  278.     PUSH    BX
  279.     PUSH    CX
  280.     XOR    DX,DX            ; build indicator in DX
  281.     JCXZ    NoSubdir
  282.     CMP    BYTE PTR [BX+1],':'
  283.     JNE    NoDrive
  284.     ADD    DX,4            ; C: drive was present
  285.     ADD    BX,2            ; bypass drive
  286.     SUB    CX,2
  287.     JCXZ    NoSubdir
  288. NoDrive:
  289.     MOV    DI,BX
  290.     ADD    DI,CX            ; find end of string
  291.     CMP    BYTE PTR [DI-1],'\'
  292.     JNE    NoSlash
  293.                     ; was trailing slash
  294.     INC    DX
  295.     DEC    CX            ; bypass slash
  296. NoSlash:
  297.     JCXZ    NoSubdir        ; anything left -- the subdir
  298.     ADD    DX,2            ; Was Subir
  299. NoSubdir:
  300.                     ; DX contains analysis.
  301.     POP    CX            ; restore old length
  302.     POP    BX            ; restore old start
  303.     RET
  304.