home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / DIR / PUSH_POP.ZIP / POPD12.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-07-25  |  13.6 KB  |  488 lines

  1. ;**************************  POPD.ASM  ************************************
  2. ;
  3. ;     POPD.ASM version 1.2
  4. ;
  5. ;    Usage:
  6. ;        POPD
  7. ;         Will change to the most recently stored directory on 
  8. ;         the stack.
  9. ;        POPD +n
  10. ;         Will delete the directory stored in position n from
  11. ;         the bottom of the stack, starting at one on the bottom.
  12. ;    Purpose: This program will either change to the topmost directory
  13. ;        on the stack created by PUSHD v. 1.1 (first usage), OR
  14. ;        will delete from the stack the directory stored at position
  15. ;        n, where 1 is the bottom of the stack.  In either case, 
  16. ;        the program will compress the stack, to remove any empty
  17. ;        storage space, and will update the position for the next
  18. ;        storage accordingly.
  19. ;    Preconditions: 
  20. ;        1) PUSHD must be hooked to interrupt 13.
  21. ;        2) PUSHD must have the same commands from beginning
  22. ;         to after definition of push6d, so that it knows how
  23. ;         to access the resident code of PUSHD.  (This includes
  24. ;         the fact that there are 6 locations for directory storage
  25. ;         which are 67 bytes in size.)
  26. ;        3) PUSHD must have the signature "PUSHD VERSION 1.1".
  27. ;        4) PUSHD must look for 7788 in ax and 7789 in bx for
  28. ;         a call to int 13.
  29. ;        5) PUSHD must put the value of 7789 into ax and 7788
  30. ;         into bx upon calling int 13 by DIRS, if PUSHD is installed.
  31. ;        6) PUSHD will set the data segment to be equal to the data
  32. ;         segment that PUSHD used to install itself.
  33. ;        7) DS:[nextpush] (ds of PUSHD installation) must hold
  34. ;         the location of the next empty directory stack location.
  35. ;    Postconditions:
  36. ;        1) An appropriate error message will be printed out on
  37. ;         standard error, OR
  38. ;        2) DS:[nextpush] will be decremented by one directory
  39. ;         storage unit (67 bytes) AND EITHER:
  40. ;        2a) the current directory will become the directory on
  41. ;         top of the stack (usage #1) OR
  42. ;        2b) the current directory will remain the same, but the
  43. ;         targeted directory (1-6) will be deleted with the 
  44. ;         directories on the stack above shifted down one storage
  45. ;         unit.
  46. ;        3) An error code will be generated.
  47. ;    Error Codes:
  48. ;        0) Successful completion.
  49. ;          249) Error popping directory.
  50. ;          250) Directory Stack is empty.
  51. ;          251) Command Line parameter exceeds Directory Stack depth.
  52. ;          252) Illegal Characters on the Command Line.
  53. ;          253) Command Line parameter not in valid directory range (1-6).
  54. ;          254) Invalid Command Line delimiter.
  55. ;          255) PUSHD is not installed.
  56. ;    Version changes:
  57. ;        POPD v. 1.2:    July 23, 1990.
  58. ;            enhanced code using suggestions from David
  59. ;             Kirschbaum (Toad Hall).
  60. ;            "cleaned out" directory stack characters that 
  61. ;             were left after a POPD, which might not be over-
  62. ;             written on next PUSHD.
  63. ;        POPD v. 1.1:    July 14, 1990.
  64. ;            added "+n" option.
  65. ;            changed hooked interrupt to 13 from 16.
  66. ;            added error codes for abnormal termination.
  67. ;            changed writes from vector 9 to vector 40h of 
  68. ;             int 21h.
  69. ;            changed program termination from int 20h to vector
  70. ;             4Cxxh int 21h, where xx represents the error code
  71. ;             generated.
  72. ;            removed stack wrap around.
  73. ;        POPDIR v. 1.0: Copyright 1986, Ziff-Davis Publishing Co.
  74. ;            From PC Magazine, May 27, 1986
  75. ;            No changes.
  76. ;    Future Enhancements:
  77. ;        1) Change the "n" parameters so that it refers to the
  78. ;         top of the stack, not the bottom (RELATIVE from the top
  79. ;         NOT ABSOLUTE from the bottom).
  80. ;        2) Make program an .EXE file.
  81. ;        3) Correct error caused by 3 or more blanks on the
  82. ;         end of the command line tail.
  83. ;        4) Add a help option, ?, from the command line.
  84. ;        5) Add -c option to clear ALL directories on stack.
  85. ;        6) Add -n option to clear n topmost directories on stack.
  86. ;
  87. ;    Created by:
  88. ;      (from ideas based in UNIX and from PC Magazine's POPDIR.COM)
  89. ;        William P. Sarra
  90. ;            CIS:71041,347
  91. ;            arpa: sarra@TOPAZ.RUTGERS.EDU
  92. ;    uucp: ...{ames,cbosgd, harvard, moss}!rutgers!topaz.rutgers.edu!sarra
  93. ;
  94. ;*****************************************************************************
  95.  
  96. main    group    CSEG
  97. CSEG    segment    public    para    'code'
  98.     ASSUME    CS:MAIN,DS:MAIN,ES:MAIN,SS:MAIN
  99.  
  100. org    80h
  101. cmd_line    label byte
  102.  
  103. org    100h                ;.COM file
  104.  
  105. BEGIN:    jmp    Start            ;program starts here
  106.  
  107. signature    db    'PUSHD VERSION 1.1'
  108. SIG_LEN        equ    $-signature
  109.  
  110. savedint13    dd    ?        ;used to be identical to pushd
  111.  
  112. nextpush    dw    offset MAIN:push1d    ;next place to save a dir
  113.  
  114. push1d    db    67 dup (0)
  115. push2d    db    67 dup (0)
  116. push3d    db    67 dup (0)
  117. push4d    db    67 dup (0)
  118. push5d    db    67 dup (0)
  119. push6d    db    67 dup (0)
  120.  
  121. ;up to here must be EXACTLY identical in PUSHD, POPD and DIRS.
  122.  
  123. ;****************************************************************
  124. ;
  125. ;    Data Section.
  126. ;
  127. ;****************************************************************
  128.  
  129. not_inst    db    'Must run PUSHD.COM before POPD.COM'
  130.         db    ' will do anything.',13,10,10
  131. NOT_INST_LN    equ    $-not_inst
  132. errpop1        db    'Error popping the current directory',13,10,10
  133. ERRPOP1_LN    equ    $-errpop1
  134. empty_stack    db    'No directories on the stack.',13,10
  135. EMPTY_STACK_LN    equ    $-empty_stack
  136.  
  137. BLANK        equ    20h        ;' '
  138. DELIMITER    equ    2Bh        ;'+'
  139.  
  140. LOW_LIMIT    equ    31h        ;'1'
  141. UP_LIMIT    equ    36h        ;'6'
  142.  
  143. bad_delim    db    'Invalid Delimiter.',13,10
  144. BAD_DELIM_LN    equ    $-bad_delim
  145. in_dir_msg    db    'Valid directories range between 1 and 6.',13,10
  146. IN_DIR_MSG_LN    equ    $-in_dir_msg
  147. bs_online    db    'Invalid Command Line Parameters.',13,10
  148. BS_ONLINE_LN    equ    $-bs_online
  149. not_pushed    db    'Parameter exceeds Directory Stack depth.',13,10
  150. NOT_PUSHED_LN    equ    $-not_pushed
  151.  
  152. params        db    ?        ;storage for command line tail
  153.  
  154. targ_dir    dw    offset main:push1d    ;address storage
  155.  
  156. ;*******************************************************************
  157. ;
  158. ;    Code Starts.
  159. ;
  160. ;*******************************************************************
  161.  
  162. START:
  163.  
  164.     ;get and store command line tail as it may get destroyed
  165.  
  166.     cld
  167.  
  168. ;v1.2    I entirely rewrote this section.  What a kludge!
  169.  
  170.     mov    si,offset cmd_line        ;command line tail
  171.     lodsb                    ;snarf length byte, bump SI
  172.  
  173.     ;SI -> first char (probably a space!)
  174.  
  175.     xor    ah,ah                ;clear msb
  176.     mov    cx,ax                ;into CX
  177.     push    ax                ;save length on stack for later
  178.     jcxz    INST_CHK            ;CX is 0, branch
  179.  
  180.     ;We have a non-null command line
  181.  
  182.     mov    di,offset MAIN:params        ;store since it may get
  183.     rep    movsb                ;destroyed
  184.  
  185. INST_CHK:
  186.  
  187.     ;is PUSHD already installed ?
  188.  
  189.     mov    ax,7788h            ;signature request
  190.     mov    bx,7789h            ;signature request
  191.     mov    si,offset MAIN:signature    ;point ds:si to signature
  192.     int    13h                ;is it installed ?
  193.     
  194.     ASSUME    DS:CSEG            ;assume TSR's DS    v1.2
  195.     
  196.     cmp    bx,7788h            ;were ax and bx switched ?
  197.     jne    NOTINSTALLED            ;no
  198.     cmp    ax,7789h            ;were ax and bx switched ?
  199.     je    ISINSTALLED        ;v1.2
  200.  
  201. NOTINSTALLED:
  202.  
  203.     ;PUSHD is not installed, terminate with an error message.
  204.  
  205.     mov    dx,offset MAIN:not_inst        ;error message
  206.     mov    cx,NOT_INST_LN
  207.     mov    al,0FFH            ;ERRORLEVEL        v1.2
  208.     jmp    Msg_Term        ;display, terminate    v1.2
  209.  
  210. ISINSTALLED:
  211.  
  212.     ; check for command line parameters
  213.  
  214.     pop    cx            ;get saved cx
  215.     push    DS            ;store current ds
  216.  
  217.     mov    ax,CS            ;v1.2
  218.     mov    DS,ax            ;v1.2
  219.     ASSUME    DS:MAIN            ;reminder            v1.2
  220.  
  221.     or    cx,cx            ;check for no parameters
  222.     jnz    ERR1
  223.     jmp    CHK_STACK
  224.  
  225. ERR1:    mov    di,offset MAIN:params
  226.     mov    al,BLANK        ;remove leading blanks
  227.     repe    scasb
  228.     dec    di
  229.     inc    cx
  230.     mov    si,di            ;save position
  231.     lodsb                ;snarf first char, bump SI    v1.2
  232.     cmp    al,BLANK        ;space?                v1.2
  233.  
  234.     jne    ERR2
  235.     jmp    CHK_STACK        ;only blanks on tail
  236. ERR2:
  237.     cmp    al,DELIMITER        ;is it '+' delimiter?        v1.2
  238.     je    CHK_VALUE
  239.  
  240.     ;Current character is not valid -- Print error message and exit
  241.  
  242.     mov    dx,offset MAIN:bad_delim    ;bad delimiter message
  243.     mov    cx,BAD_DELIM_LN
  244.     mov    al,0FEH            ;ERRORLEVEL        v1.2
  245.     jmp    Msg_Term        ;display, terminate    v1.2
  246.  
  247. CHK_VALUE:
  248.  
  249.     ;check that parameter values are within specified limits
  250.  
  251.     dec    cx
  252.  
  253. ;v1.2    Recoded
  254.     lodsb                ;snarf digit after '+', bump SI
  255.     cmp    al,UP_LIMIT        ;above '6'?
  256.     ja    INVALID_DIR        ;yep, bogus
  257.     cmp    al,LOW_LIMIT        ;below '1'?'
  258.     jnb    FINISH_CHK        ;nope, in range ['1'..'6']
  259.  
  260. INVALID_DIR:
  261.     
  262.     ;invalid directory number -- print message and exit
  263.  
  264.     mov    dx,offset MAIN:in_dir_msg    ;error message
  265.     mov    cx,IN_DIR_MSG_LN
  266.     mov    al,0FDH                ;ERRORLEVEL    v1.2
  267.     jmp    Msg_Term            ;display, terminate    v1.2
  268.  
  269. FINISH_CHK:
  270.  
  271.     ;continue checking for invalid characters on the command line
  272.     ; after getting valid characters.
  273.  
  274.     dec    cx            ;decr cmdline count for digit    v1.2
  275.     jcxz    VALID_DIR
  276.  
  277.     mov    ah,al            ;save digit            v1.2
  278.     mov    al,BLANK        ;check for following nonblank
  279.     repne    scasb            ;characters
  280.     mov    al,ah            ;replace digit            v1.2
  281.  
  282.     jcxz    VALID_DIR
  283.  
  284.     ;Invalid characters on the command line -- print message and
  285.     ; exit
  286.  
  287.     mov    dx,offset MAIN:bs_online    ;error message
  288.     mov    cx,BS_ONLINE_LN
  289.     mov    al,0FCH                ;ERRORLEVEL        v1.2
  290.     jmp    Msg_Term            ;display, terminate    v1.2
  291.  
  292. VALID_DIR:
  293.  
  294.     ;get stack location of targeted directory
  295.  
  296.     xor    ah,ah            ;clear ah    v1.2
  297.     mov    cx,67            ;multiplier    v1.2
  298.     sub    al,'1'            ;'0'..'5' range
  299.     mul    cx            ;directory offset    v1.2
  300.     add    ax,offset MAIN:push1d    ;base directory buffer    v1.2
  301.     mov    targ_dir,ax        ;save it    v1.2
  302.  
  303. CHK_DIR:
  304.  
  305.     ;check that the directory stack depth is at least to
  306.     ; the targeted directory location
  307.  
  308.     pop    DS                ;restore ds
  309.     ASSUME DS:CSEG        ;reminder    v1.2
  310.  
  311.     mov    bp,DS:[nextpush]        ;get location of last
  312.     sub    bp,67                ;pushed directory
  313.     cmp    bp,CS:[targ_dir]        ;make sure directory stack
  314.     jge    PROCESS_DIRS            ;is deep enough for params
  315.  
  316.     ;the parameter number "n" exceeds the depth of the directory stack
  317.     ; print a message and exit with an error
  318.  
  319.     mov    dx,offset MAIN:not_pushed    ;error message
  320.     mov    cx,NOT_PUSHED_LN
  321.     mov    al,0FBH                ;ERRORLEVEL    v1.2
  322.     jmp    Msg_Term            ;display, terminate    v1.2    
  323.  
  324. PROCESS_DIRS:
  325.  
  326.     ;stack is deep enough, if the targeted directory location is
  327.     ; at the top of the stack, simply decrement ds:[nextpush],
  328.     ; effectively erasing the top directory and exit successfully.
  329.  
  330.     jne    NOT_TOP            ;check on popping top of stack, set
  331.     mov    DS:[nextpush],bp    ;nextpush to be top of current stack
  332.     jmp    SHORT EXITING
  333.  
  334. NOT_TOP:
  335.  
  336.     ;targeted directory is in the middle of stack, so decrement
  337.     ; DS:[nextpush] to reflect stack deletion, set the current location
  338.     ; to be the targeted stack location, and...
  339.  
  340.     mov    DS:[nextpush],bp    ;set nextpush to top of stack
  341.     mov    bp,CS:[targ_dir]    ;set bp to be targeted directory
  342.     mov    ax,DS            ;v1.2
  343.     mov    ES,ax            ;v1.2
  344.     ASSUME    ES:CSEG            ;reminder     v1.2
  345.     
  346. ;handy constants    v1.2
  347.     mov    dx,DS:[nextpush]    ;v1.2
  348.     mov    ax,67            ;v1.2
  349.     mov    bx,bp            ;v1.2
  350.  
  351. DIR_LOOP:
  352.  
  353.     ;...cycle through the stack copying the contents of the directory
  354.     ; above the current location into the current location...
  355.  
  356.     add    bp,ax            ;go to next pushed directory    v1.2
  357.     cmp    bp,dx            ;DS:[nextpush]    v1.2
  358.     je    LAST_DIR        ;found the last directory
  359.     mov    si,bp            ;copy contents to
  360.     mov    di,bx            ;targ_dir    v1.2
  361.     mov    cx,ax            ;67    v1.2
  362.     rep    movsb
  363.     add    bx,ax            ;targ_dir,67    v1.2
  364.     jmp    SHORT DIR_LOOP        ;continue
  365.  
  366. LAST_DIR:
  367.  
  368.     ;...until the last directory is copied into the nearest lower
  369.     ; storage location
  370.  
  371.     mov    si,bp            ;one more copy
  372.     mov    di,bx            ;targ_dir v1.2
  373.     mov    cx,ax            ;67    v1.2
  374.     rep    movsb
  375.     jmp    SHORT EXITING        ;exit successfully
  376.  
  377. CHK_STACK:
  378.  
  379.     ;handle parameterless command
  380.  
  381.     ;get the location of the directory most recently saved by pushd
  382.     ; (top of stack)
  383.  
  384.     pop    DS                ;restore ds
  385.     ASSUME DS:CSEG            ;reminder    v1.2
  386.  
  387.     mov    bp,DS:[nextpush]        ;get the next push location
  388.     sub    bp,67                ;back up one to the last push
  389.     cmp    DS:[nextpush],offset MAIN:push1d    ;empty stack?
  390.     jne    NOTEMPTY            ;no
  391.  
  392.     ;directory stack is empty (ds:[nextpush] = location of first
  393.     ; storage location) -- print message and exit with error
  394.  
  395.     mov    dx,offset MAIN:empty_stack    ;error message
  396.     mov    cx,EMPTY_STACK_LN
  397.     mov    al,0FAH                ;ERRORLEVEL    v1.2
  398.     jmp    Msg_Term            ;display terminate    v1.2
  399.  
  400. NOTEMPTY:
  401.  
  402.     ;directory stack is not empty -- change to directory on top of 
  403.     ; stack
  404.  
  405.     ;set the current directory 
  406.  
  407.     mov    dx,bp            ;load DS:dx with directory to set
  408.     mov    ah,3bh            ;dos function number
  409.     int    21h            ;set current dir back
  410.     jc    ERRPOP            ;branch on error
  411.  
  412.     ;set the current drive if previous commands are successful  
  413.  
  414.     mov    al,DS:[bp]            ;get drive letter from path
  415.     sub    al,'A'                ;convert to binary (0=A, 1=B)
  416.     mov    dl,al
  417.     mov    ah,0eh                ;dos function number
  418.     int    21h                ;set drive
  419.     jc    ERRPOP
  420.  
  421.     mov    DS:[nextpush],bp    ;update [nextpush] if successful
  422.  
  423. EXITING:
  424.  
  425.     ;clear up previous directory storage    v1.2
  426.  
  427.     mov    ax,DS                ;v1.2
  428.     mov    ES,ax                ;v1.2
  429.     ASSUME    ES:CSEG                ;reminder    v1.2
  430.  
  431.     mov    cx,67                ;v1.2
  432.     mov    di,DS:[nextpush]        ;v1.2
  433.     mov    al,BLANK            ;v1.2
  434.     rep    stosb                ;v1.2
  435.  
  436.     ;exit successfully with no message
  437.  
  438.     mov    ax,4c00h
  439.     int    21h                 ;exit
  440.  
  441. ERRPOP:
  442.  
  443.     ;An error occurred while attempting to change to targeted
  444.     ; directory -- print error message and exit with error
  445.  
  446.     mov    dx,offset MAIN:errpop1        ;error message
  447.     mov    cx,ERRPOP1_LN
  448.     mov    al,0F9H            ;ERRORLEVEL    v1.2
  449. ;    jmp    Msg_Term        ;display, terminate    v1.2
  450.  
  451. ;*********************************************************************
  452. ;
  453. ;    PROCEDURE:    Msg_Term
  454. ;
  455. ;    Purpose: This procedure will handle the printing of error messages
  456. ;        and termination with the correct errorlevel.
  457. ;    Preconditions: 
  458. ;        DX = error message address.
  459. ;        CX = error message length.
  460. ;        AL = ERRORLEVEL.
  461. ;    Postconditions: 
  462. ;        The program will be terminated with the appropriate
  463. ;         error message printed on standard error and with the
  464. ;         the errorlevel stored in al.
  465. ;
  466. ;***************************************************************************
  467.  
  468. Msg_Term    PROC    NEAR
  469. ;v1.2    Common routine to display error messages and terminate.
  470.  
  471.     push    CS            ;insure this is so
  472.     pop    DS
  473.     ASSUME    DS:MAIN
  474.  
  475.     push    ax                ;save ERRORLEVEL in AL
  476.     mov    bx,2                ;write to stderr
  477.     mov    ah,40h                ;dos function number
  478.     int    21h                ;show error message
  479.     pop    ax                ;restore ERRORLEVEL in AL
  480.     mov    ah,4CH                ;terminate process
  481.     int    21h
  482.  
  483. Msg_Term    ENDP
  484.  
  485.     
  486. CSEG    ends
  487. end    BEGIN                ;start execution at BEGIN
  488.