home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
keyboard
/
ced_adds.arc
/
PUSHDIR.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-03-07
|
7KB
|
276 lines
; PUSHD/POPD Ver. 1.0
;
; PUSHD saves the current directory on a stack. With the command
; POPD you change automatically back to that saved directory.
; The program, once loaded, stays in RAM and works as an
; extension of the command interpreter.
;
; Copyright (C) 1987 by Urs Zurbuchen, Switzerland
;
; You may freely distribute this program unless you
; include the sources and don't touch this header.
; Commercial usage is prohibited.
;
; Requirements:
; This program requires that the command editor CED
; (by C.J. Dunford) is installed.
;
; Restrictions:
; The directory stack has enough room for 5 entries.
; Each entry uses 64 bytes of RAM for storage.
;
; Usage: PUSHD
; POPD
;
; Assembly: MASM pushd; MASM popd;
; LINK pushd; LINK popd;
; EXE2BIN pushd pushd.com EXE2BIN popd popd.com
;
; Author: Urs Zurbuchen
;
; Date: February 9, 1987
;
; Revisions:
; Date Who What
;
;----------------------------------------------------------------------
; adjust the following global according to the processor used
is_8088 equ 0 ; you won't have those fancy '286
; instructions if true
if is_8088
.8086
else
.286c ; this requires MASM 4.0
endif
; some global constants
cr equ 13 ; CarriageReturn
lf equ 10 ; LineFeed
space equ 32 ; (what do you guess :-)
tab equ 9 ; Tabulator
; definitions for the CED interface
ced equ 0ffh ; special DOS function for CED services
enqueue equ 0 ; Subfunction to CED: enqueue command
dequeue equ 1 ; Subfunction to CED: dequeue command
ced_dos equ 1 ; CED parameter: command at DOS prompt
ced_usr equ 2 ; CED parameter: command in user prg
; configurable constants
entries equ 5 ; max. number of directories to push
; some program specific constants DON'T TOUCH THEM !!!!
plength equ 65 ; pathname-buffer length (one entry)
p2 equ 6
; here follows the program section
cseg segment para public 'code'
assume cs:cseg, ds:cseg, es:cseg
; initialization
org 100h
;-----------------------
; Installation procedure
;-----------------------
main proc far
jmp install ; go to installation
; datastructures
pbuf db entries * plength dup (?) ; pathname buffer
pnum dw 0 ; "stack pointer"
; error messages
msg1$ db 'pushd/popd: no parameters allowed', cr, lf, '$'
msg2$ db 'pushd: stack full', cr, lf, '$'
msg3$ db 'popd: stack empty', cr, lf, '$'
msg4$ db 'pushd: cannot get current directory', cr, lf, '$'
msg5$ db 'popd: cannot change to saved directory', cr, lf, '$'
;--------------------
; the PUSHD procedure
;--------------------
pushd proc far
mov byte ptr [si],cr ; null out the users input
mov bp,dx
psh_1: mov al,byte ptr es:[bp] ; test for parameters
cmp al,cr ; end of input reached ?
jz psh_ok
inc bp
cmp al,space ; space and tab are ok at the tail
jz psh_1
cmp al,tab
jz psh_1
jmp err_noparam ; any other char is bad enough
psh_ok: push cs ; set data segment context
pop ds
mov ax,word ptr [pnum] ; is there any room left
cmp ax,5
jz err_noroom ; no: tell the user
; prepare for DOS call
mov si,ax ; make room for first '\'
if is_8088
mov cl,p2 ; adjust for the different processors
sal ax,cl
else
sal ax,p2
endif
add ax,offset pbuf ; compute buffer adress
add si,ax ; DS:SI points to 65-byte buffer area
inc si
mov dl,0 ; indicates current drive
push si
mov ah,47h ; get current directory
int 21h
pop si
jc err_fnerr1 ; tell user if we got an error
inc word ptr [pnum] ; increment "stack pointer"
mov byte ptr [si-1],'\' ; patch pathname
ret ; exit to CED
pushd endp
;-------------------
; the POPD procedure
;-------------------
popd proc far
mov byte ptr [si],cr ; null out the users input
mov bp,dx
pop_1: mov al,byte ptr es:[bp] ; test for parameters
cmp al,cr ; end of input reached ?
jz pop_ok
inc bp
cmp al,space ; space and tab are ok at the tail
jz pop_1
cmp al,tab
jz pop_1
jmp err_noparam ; any other char is bad enough
pop_ok: push cs ; set data segment context
pop ds
mov ax,word ptr [pnum] ; is there any pathname on the stack
or ax,ax
jz err_empty ; no: tell the user
dec ax ; prepare for DOS call
mov dx,ax
if is_8088
mov cl,p2 ; adjust for the different processors
sal ax,cl
else
sal ax,p2
endif
add ax,offset pbuf ; compute buffer adress
add dx,ax ; DS:DX points to 65-byte buffer area
mov ah,3bh ; change current directory
int 21h
jc err_fnerr2 ; tell user if we got an error
dec word ptr [pnum] ; decrement "stack pointer"
pop_end:
ret ; exit to CED
popd endp
;--------------
; error handler
;--------------
error proc near
err_noparam: ; no parameters allowed
push cs
pop ds
mov dx,offset msg1$
jmp err_common
err_noroom: ; no more room for push
mov dx,offset msg2$
jmp err_common
err_empty: ; stack is empty
mov dx,offset msg3$
jmp err_common
err_fnerr1: ; error in getting current directory
mov dx,offset msg4$
jmp err_common
err_fnerr2: ; error in changing to new directory
mov dx,offset msg5$
jmp err_common
err_common: ; common point for error output
mov ah,9 ; print string
int 21h
jmp pop_end
error endp
;-------------------------------------------------------------------
; This is the installation routine. It queues the two commands above
; into the CED command editor. It terminates but leaves the command
; routines resident.
;-------------------------------------------------------------------
install:
push cs
pop ds
push ds
pop es
mov ah,ced ; request CED service from DOS
mov al,enqueue ; enqueue a new command
mov bl,ced_dos ; PUSHD is only active at DOS prompt
mov si,offset pushd$ ; pointer to command name
mov di,offset pushd ; pointer to service routine
int 21h
jnc inst_next ; skip error handler
mov dx,offset msg_inst1$ ; only error 8 is possible here
inst_err:
mov ah,9 ; print string
int 21h
int 20h ; exit without staying resident
inst_next:
mov ah,ced ; request CED service once more
mov al,enqueue ; enqueue a new command
mov bl,ced_dos ; POPD is only active at the DOS prompt
mov si,offset popd$ ; pointer to command name
mov di,offset popd ; pointer to service routine
int 21h
jnc inst_ok ; no error: exit
mov ah,ced ; dequeue pushd if we can't
mov al,dequeue ; install popd
mov si,offset popd$ ; pointer to command name
int 21h ; no error possible for dequeue
mov dx,offset msg_inst2$ ; now, tell the user about the error
jmp inst_err
inst_ok:
mov dx,offset install ; ok: terminate/resident
int 27h
main endp
; messages for installation procedure
msg_inst1$ db 'install pushd: CED command list full', cr, lf, '$'
msg_inst2$ db 'install popd: CED command list full', cr, lf, '$'
; command names
pushd$ db 'pushd',cr
popd$ db 'popd',cr
cseg ends
end main