home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
m
/
memres41.zip
/
RESDEL.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-07-24
|
27KB
|
598 lines
; Ed Jordan 201 Smallacombe Drive, Scranton, Pa. 18508
; program in the public domain
; version 1 - December 1986
; - improved segment addressing Jan 1987
; 1.1- correct error for passing dos environment string March 1987
; 2.0 command line switch to replace entire vector table
; 2.1 support for non-contiguous env blocks
; 2.1a fixed bug - correct for code address in vector table (Mar 88)
; 2.1b fixed bug again - exe and com files have different code segments
; 3.0 enhancements - help , switch for removal of more than one utility
; April 1988
; 4.0 fixed bug in vector routine - replaces earlier versions May 1988
; version 4.1 Rewrite of method of detecting memory blocks
po equ 39
cr equ 13
lf equ 10
el equ '$'
eof equ 1ah
esc equ 1bh
stdin equ 0
stdout equ 1
stderr equ 2
stdaux equ 3
stdprn equ 4
envsize equ 800h ; max size environment
stackseg segment stack para 'stack'
db 40 dup('stack')
stackseg ends
dataseg segment public para 'data'
mesg1 db cr,lf,'Deleting ',el
mesg2 db ' memory resident programs ...',cr,lf,el
mesg2a db ' memory resident program ...',cr,lf,el
mesg3 db 'A:\VECTOR.TBL',0
db 20 dup ('PATCH ')
db 'END PATCH AREA'
mesg4 db 'Replacing entire vector table ...',cr,lf,el
mesg5 db 'RESDEL.EXE - version 4.1',cr,lf
db 'by Ed Jordan July 1988',cr,lf,el
mesg6 db 'RESDEL \n<cr> (n= 1 to 9)',cr,lf
db 'RESDEL \R<cr> (delete all)',cr,lf,el
mesg7 db cr,lf,el
mesg8 db 'Vector(s) ',el
mesg9 db '- ',el
mesg10 db '- Not Applicable',cr,lf,el
mesg11 db 8,' ',8,el
error1 db ' not found.',cr,lf,el
error2 db 'Insufficient memory.',cr,lf,el
error3 db 'Error freeing allocated memory block.',cr,lf,el
error4 db 'Please do not try to delete DOS.',cr,lf,el
error5 db 'Unrecognized command.',el
error6 db '(Warning: Vector not located) ',el
error7 db cr,lf,'Warning: SHARE.EXE installed'
db cr,lf,'Do you want to proceed? (Y/N) ',el
handle dw ?
default_tbl dw 0
dos_seg dw ?
nxt_env dw ?
psp dw ?
last_psp dw ?
last_env dw ?
flag db ?
tr_tbl db '0123456789ABCDEF'
blocks dw 128 dup (0)
dataseg ends
codeseg segment public para 'code'
assume cs:codeseg,ds:dataseg,es:nothing,ss:stackseg
memret proc far
mov ax,dataseg
mov ds,ax
push es
pop ax
mov psp,ax
mov si,16h
mov ax,word ptr es:[si] ; parent seg
mov dos_seg,ax
call chk_share
jb ret2 ; exit
call read_chain
call load_default_tbl
jb ret2
call chk_cmd_line
jb ret2
lea dx,mesg1 ; delete
call print
mov dl,cl ; number
xor dl,30h
mov ah,2 ; print number
int 21h
cmp dl,31h ; number 1 ?
jnz ret6
lea dx,mesg2a
jmp short ret7
ret6: lea dx,mesg2 ; programs message
ret7: call print
jmp short ret4
ret1: mov ax,es
mov psp,ax
ret4: call find_psp ; look backwards
jb ret3
call fix_tbl ; es = last_psp
jb ret4
call free_mem ; free last psp
jb ret2
call find_env ; find env of psp
ret5: loop ret1 ; cx has count
jmp short ret2
ret3: lea dx,error4 ; error message
call print
ret2: mov ax,default_tbl
or ax,ax
jz ret8
mov es,ax
call free_mem
ret8: call exit
memret endp
chk_share proc near
mov ah,30h
int 21h ; dos version
cmp al,3 ; version 3 ?
jb cs6
mov ax,1000h ; get installed state
int 2fh ; multiplex interrupt
cmp al,0ffh ; installed ?
jz cs4
cs6: clc
jmp cs5
cs4: lea dx,error7 ; error message
call print
cs3: call get_response
cmp al,'Y'
jz cs1
cmp al,'N'
jz cs2
lea dx,mesg11 ; erase response
call print
jmp cs3 ; try again
cs2: stc ; flag to skip
cs1: lea dx,mesg7 ; cr lf
call print
cs5: ret
chk_share endp
chk_cmd_line proc near
lea dx,mesg5 ; title message
call print
mov ax,psp
mov es,ax
mov si,80h ; offset of cmd line
mov al,byte ptr es:[si]
or al,al
jnz ccl4
jmp ccl5
ccl8: lea dx,error5
call print
ccl5: lea dx,mesg6 ; help message
call print
jmp ccl7 ; no command line switch
ccl4: mov di,si
inc di ; start of cmd line
xor cx,cx
mov cl,al
mov al,'\' ; switch on cmd line
repne scasb
jcxz ccl5 ; no switch found
mov al,byte ptr es:[di]
call capital
cmp al,'R'
jz ccl6
cmp al,'0'
jb ccl8
cmp al,'9'
jg ccl8
xor al,30h ; make binary digit
jz ccl7
xor cx,cx ; in cx
mov cl,al
jmp ccl1
ccl6: lea dx,mesg4 ; replace whole table
call print
push es
push ds
xor ax,ax
xor si,si
xor di,di
mov es,ax
mov ax,default_tbl ; copy default table
mov ds,ax ; into vector table
mov cx,400h
cli ; hold interrupts
rep movsb ; ds:si to es:di
sti ; enable interrupts
pop ds
pop es
mov ax,default_tbl ; free memory for
mov es,ax ; the default table
call free_mem
ccl3: call find_psp ; find previous psp
jb ccl7
call free_mem ; free block
jb ccl1
call find_env ; free env block
jmp ccl3
ccl7: stc ; set carry flag
ccl1: ret
chk_cmd_line endp
capital proc near
cmp al,'a'
jb cap1
cmp al,'z'
jg cap1
xor al,20h
cap1: ret
capital endp
free_mem proc near
mov ah,49h ; es= block
int 21h
jnb fm1
lea dx,error3 ; if carry set
call print ; print error message
stc
fm1: ret
free_mem endp
fix_tbl proc near
db 0cch
cld
push bp
push es
push ds
push cx
lea dx,mesg8 ; vector message
call print
mov dx,ds ; save ds in dx
mov flag,'N' ; no vector default
xor ax,ax
mov es,ax ; start of vector tbl
xor si,si
mov cx,400h ; max size of table
mov bp,last_psp ; segment of earlier psp
mov bx,default_tbl ; set ds to default table
mov di,psp ; vector must be between
push es ; last_psp and psp
pop ds ; ds = es = 0
ft1: cmp si,cx
jnb ft2
lodsw
lodsw ; segment
cmp ax,bp ; compare with last_psp
jb ft1 ; must be = or higher
cmp ax,di ; psp of current program
jnb ft1 ; must be lower
call replace
call print_num
mov ds,dx
mov flag,'Y' ; vector located
xor ax,ax
mov ds,ax
jmp ft1
ft2: mov ds,dx
cmp flag,'Y'
jz ft3
lea dx,error6 ; vector not found message
call print
clc
ft3: pop cx
pop ds
pop es
pop bp
ret
fix_tbl endp
replace proc near
push di
push si
push ds
dec si
dec si
dec si
dec si
mov di,si
mov ds,bx ; table segment
movsw
movsw ; copy over 2 words
pop ds
pop si
pop di
ret
replace endp
print_num proc near
push ax
push bx
push cx
push ds
push si
mov ds,dx ; data seg
dec si ; adj to start of
dec si ; vector
dec si
dec si
mov ax,si ; offset of vector
shr ax,1
shr ax,1 ; divide by 4
mov ah,al
xchg ah,al
mov cl,4
shr al,cl
mov bx,offset tr_tbl
xlat tr_tbl
call print_al
mov al,ah
and al,0fh ; mask off high nibble
xlat tr_tbl
call print_al
mov al,' '
call print_al
pop si
pop ds
pop cx
pop bx
pop ax
ret
print_num endp
print_al proc near
push ax
push dx
mov dl,al
mov ah,2
int 21h
pop dx
pop ax
ret
print_al endp
find_psp proc near
mov si,bp ; end of block chain
lea dx,blocks ; beginning of chain
std ; reverse
fp1: cmp si,dx
jb fp2 ; end of loop
lodsw
mov bx,ax
lodsw
cmp ax,bx
jnz fp1
mov bp,si ; update
mov last_psp,ax ; save new psp
mov es,ax
jmp short fp3
fp2: stc
fp3: cld ; foreward
ret
find_psp endp
load_default_tbl proc near
lea dx,mesg3
call open_file
jnb ldt1
cld ; foreward
push es
push ds
pop es
mov di,dx ; path name
xor al,al ; look for 0 at end
mov cx,128 ; of path
repne scasb
std ; reverse direction
dec di
mov byte ptr es:[di],el
mov si,di
ldt7: lodsb
cmp al,'\'
jz ldt6
cmp al,':'
jnz ldt7
ldt6: inc si
inc si
cld ; foreward again
pop es
mov dx,si
call print
lea dx,error1
ltd4: call print
stc
jmp ldt2
ldt1: mov handle,ax
mov bx,200h
call set_memory
jnb ldt3
ldt5: lea dx,error2
jmp ltd4
ldt3: mov bx,40h ;paragraphs to request
call req_memory
jb ldt5
mov default_tbl,ax
mov bx,handle
mov cx,400h ;size of table
push ds
mov ds,ax
call read_file
pop ds
jb ldt2
mov bx,handle
call close_file
ldt2: ret
load_default_tbl endp
close_file proc near
mov ah,3eh
int 21h ; bx= handle
ret
close_file endp
read_file proc near
xor dx,dx ; ds:dx = buffer
mov ah,3fh ; cx= bytes
int 21h ; bx= handle
ret
read_file endp
req_memory proc near
mov ah,48h ; bx= paragraphs requested
int 21h
ret
req_memory endp
set_memory proc near
mov ah,4ah ; es= psp
int 21h ; bx= paragraphs
ret
set_memory endp
open_file proc near
mov ah,3dh ; ds:dx= asciiz
xor al,al ; read only
int 21h
ret
open_file endp
print proc near
push ax
mov ah,9 ; dos print message
int 21h ; function
pop ax ; ds:dx = message
ret
print endp
find_env proc near
db 0cch
push es
push cx
mov flag,'N'
mov bx,es ; save psp address
cld ; foreward
push ds
pop es
lea di,blocks ; start
mov dx,di ; at top
xor ax,ax ; of the chain
mov cx,128
repne scasw
dec di
dec di
dec di
dec di
mov si,di
std ; reverse
fe3: cmp si,dx
jb fe2
lodsw
mov nxt_env,ax
lodsw
cmp nxt_env,ax
jz fe3
cmp ax,bx ; psp match ?
jnz fe3
cmp ax,psp ; must not = psp
jz fe3
mov flag,'Y' ; found block
mov ax,nxt_env
mov last_env,ax
mov es,ax
call free_mem
jb fe4 ; exit error
jmp fe3
fe2: cmp flag,'N'
jz fe5
mov ax,last_env ; equal to last
cld ; foreward
mov es,ax ; es = env
xor di,di
xor al,al
mov cx,16 * envsize
fe8: repne scasb
cmp byte ptr es:[di],0 ; two zeros ?
jnz fe8
inc di
repne scasb ; look for one more 0
repne scasb ; point to end of name
dec di
mov byte ptr es:[di],el
std ; set direction flag
mov si,di
dec si
lea dx,mesg9 ; cr lf message
call print
push ds
push es
pop ds
fe7: lodsb
cmp al,'\' ; point to name minus
jz fe6 ; the path and drive
cmp al,':'
jnz fe7
fe6: inc si
inc si
mov dx,si
call print
pop ds
lea dx,mesg7
call print
jmp short fe4
fe5: lea dx,mesg10
call print
fe4: pop cx
pop es
cld ; clear direction flag
ret
find_env endp
get_response proc near
mov ah,1
int 21h
call capital
ret
get_response endp
read_chain proc near
db 0cch
cld
push es
push ds
mov bx,dos_seg
lea di,blocks
push ds
pop es
mov ax,bx
dec ax ; point to memory ctl blk
rc3: xor si,si
mov ds,ax ; 1st mem block
lodsb ; M or Z
cmp al,'Z' ; end of chain
jz rc1
lodsw ; get segment address
cmp ax,bx ; = dos seg ?
jz rc2
or ax,ax ; 0 ?
jz rc2
stosw ; save psp address
mov ax,ds
inc ax
stosw ; save block address
rc2: lodsw ; get size of block
mov dx,ds
inc dx
add ax,dx
jmp rc3
rc1: pop ds
pop es ; program
dec di
dec di
mov bp,di
ret
read_chain endp
exit proc near
jb e1
xor al,al
jmp short e2
e1: mov al,1 ; if carry set exit
e2: mov ah,4ch ; with code 1
int 21h
exit endp
codeseg ends
end