home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Multimedia & CD-ROM 3
/
mmcd03-jun1995-cd.iso
/
utils
/
various
/
utils-1
/
install.asm
< prev
next >
Wrap
Assembly Source File
|
1991-06-24
|
14KB
|
293 lines
;****************************************************************************
; INSTALL inserts a bookmark in memory that allows TSRs installed above it
; to be uninstalled. Its syntax is
;
; INSTALL [bookmark]
;
; where "bookmark" is the name of the bookmark. This parameter can be
; passed to REMOVE when a TSR is uninstalled. Only the first 32 characters
; of the bookmark name are used.
;****************************************************************************
code segment
assume cs:code
org 100h
begin: jmp init
nextblock dw 0FFFFh ;Pointer to next block
bookmark db "(No Name)",24 dup (0Dh);Bookmark name
signature db 0,1,2,"INSTALL",2,1,0 ;Program signature
vectors dw 512 dup (?) ;Interrupt vectors
prog_id db ? ;Multiplex ID number
int2Fh dd ? ;Interrupt 2FH vector
;****************************************************************************
; MPLEX_INT handles interrupt 2FH. If, on entry, AH is set to INSTALL's
; multiplex ID number, MPLEX_INT uses the value in AL as a function code.
; The functions supported are:
;
; 00H Returns FFH in AL to indicate the program is installed
; and returns the address of its signature in ES:DI.
;****************************************************************************
mplex_int proc far
pushf ;Save FLAGS register
cmp ah,cs:[prog_id] ;Branch if AH holds the
je mplex2 ; multiplex ID
popf ;Restore FLAGS
jmp cs:[int2Fh] ;Pass the interrupt on
;
; Function 00H verifies that the program is installed.
;
mplex2: popf ;Restore FLAGS
or al,al ;Branch if function code
jnz mplex3 ; is other than 00H
mov al,0FFh ;Set AL to FFH
push cs ;Point ES:DI to the program
pop es ; signature
mov di,offset signature
mplex3: iret ;Return from interrupt
mplex_int endp
;****************************************************************************
; Data that will be discarded when the program becomes memory-resident.
;****************************************************************************
helpmsg db "Places a bookmark in memory that allows TSRs to "
db "be uninstalled.",13,10,13,10
db "INSTALL [bookmark]",13,10,13,10
db " bookmark Name of the bookmark being installed."
db 13,10,13,10
db "Once a bookmark is placed, TSRs installed above "
db "it in memory can be",13,10
db "uninstalled with INSTALL's companion program, "
db "REMOVE.",13,10,"$"
errmsg1 db "Requires DOS 3.0 or higher",13,10,"$"
errmsg2 db "INSTALL cannot be loaded high",13,10,"$"
errmsg3 db "Program could not be installed",13,10,"$"
msg1 db "Bookmark created. Use REMOVE to remove it."
db 13,10,"$"
;****************************************************************************
; INIT makes the program resident in memory.
;****************************************************************************
assume cs:code,ds:code
init proc near
cld ;Clear direction flag
mov si,81h ;Point SI to command line
call scanhelp ;Scan for "/?" switch
jnc checkver ;Branch if not found
mov ah,09h ;Display help text and exit
mov dx,offset helpmsg ; with ERRORLEVEL=0
int 21h
mov ax,4C00h
int 21h
;
; Check the DOS version and make sure the program isn't loaded high.
;
checkver: mov dx,offset errmsg1 ;Exit if DOS version
mov ah,30h ; is less than 3.0
int 21h
cmp al,3
jae checkaddr
error: mov ah,09h ;Display error message and
int 21h ; exit with ERRORLEVEL=1
mov ax,4C01h
int 21h
checkaddr: mov dx,offset errmsg2 ;Exit if program is loaded
mov ax,cs ; at segment A000H or
cmp ax,0A000h ; higher
jae error
;
; Parse the command line.
;
call findchar ;Advance to first character
jc copy ;Branch if no parameters
mov di,offset bookmark ;Point DI to buffer
mov cx,32 ;Initialize counter
parse1: lodsb ;Get a character
cmp al,"a" ;Capitalize it if it's
jb parse2 ; between "a" and "z"
cmp al,"z"
ja parse2
and al,0DFh
parse2: stosb ;Store it
cmp al,0Dh ;Branch if was a carriage
je copy ; return
loop parse1 ;Loop back for more
;
; Copy the interrupt vector table from low memory.
;
copy: push ds ;Save DS
sub si,si ;Point DS:SI to 0000:0000
mov ds,si
assume ds:nothing
mov di,offset vectors ;Point DI to storage area
mov cx,512 ;Initialize counter
cli ;Disable interrupts
rep movsw ;Copy the vector table
sti ;Enable interrupts
pop ds ;Restore DS
assume ds:code
;
; Install the program.
;
call check_install ;Branch if a copy of INSTALL
jnc install_full ; is not already installed
mov di,offset nextblock ;Point DI to NEXTBLOCK
install1: cmp word ptr es:[di],0FFFFh ;Branch if this is not the
jne install2 ; last block in the chain
mov word ptr es:[di],cs ;Record the address of this
jmp short install_part ; block if it is
install2: mov es,es:[di] ;Point ES to next block in
jmp install1 ; the chain and loop back
install_full: call mplex_id ;Find a multiplex ID number
mov dx,offset errmsg3 ;Error if none available
jc error
mov prog_id,ah ;Save the ID number
mov ax,352Fh ;Hook interrupt 2FH
int 21h
mov word ptr int2Fh,bx
mov word ptr int2Fh[2],es
mov ax,252Fh
mov dx,offset mplex_int
int 21h
install_part: mov ah,49h ;Get the segment address of
mov es,ds:[2Ch] ; the environment block
int 21h ; and free the segment
mov ah,09h ;Display message verifying
mov dx,offset msg1 ; the installation
int 21h
mov ax,3100h ;Terminate with function 31H
mov dx,(offset helpmsg - offset code + 15) shr 4
int 21h
init endp
;****************************************************************************
; FINDCHAR advances SI to the next non-space or non-comma character.
; On return, carry set indicates EOL was encountered.
;****************************************************************************
findchar proc near
lodsb ;Get the next character
cmp al,20h ;Loop if space
je findchar
cmp al,2Ch ;Loop if comma
je findchar
dec si ;Point SI to the character
cmp al,0Dh ;Exit with carry set if end
je eol ; of line is reached
clc ;Clear carry and exit
ret
eol: stc ;Set carry and exit
ret
findchar endp
;****************************************************************************
; SCANHELP scans the command line for a /? switch. If found, carry returns
; set and SI contains its offset. If not found, carry returns clear.
;****************************************************************************
scanhelp proc near
push si ;Save SI
scanloop: lodsb ;Get a character
cmp al,0Dh ;Exit if end of line
je scan_exit
cmp al,"?" ;Loop if not "?"
jne scanloop
cmp byte ptr [si-2],"/" ;Loop if not "/"
jne scanloop
add sp,2 ;Clear the stack
sub si,2 ;Adjust SI
stc ;Set carry and exit
ret
scan_exit: pop si ;Restore SI
clc ;Clear carry and exit
ret
scanhelp endp
;****************************************************************************
; CHECK_INSTALL returns carry set if the program is already installed,
; carry clear if it's not. If carry returns set, AH holds the program's
; multiplex ID number.
;****************************************************************************
check_install proc near
mov ax,8000h ;Initialize AH and AL
mov cx,80h ;Initialize count
chinst1: push ax ;Save AX and CX
push cx
sub di,di ;Set ES and DI to 0
mov es,di
int 2Fh ;Interrupt 2Fh
cmp al,0FFh ;Nothing here if AL isn't
jne chinst2 ; equal to FFH
mov si,offset signature ;See if program signature
mov cx,13 ; appears at the address
repe cmpsb ; returned in ES:DI
jne chinst2 ;Branch if it does not
pop cx ;Clear the stack and exit
pop ax ; with carry set
stc
ret
chinst2: pop cx ;Retrieve AX and CX
pop ax
inc ah ;Next multiplex ID
loop chinst1 ;Loop until done
clc ;Exit with carry clear
ret
check_install endp
;****************************************************************************
; MPLEX_ID searches for an unused multiplex ID number. If one is found,
; it is returned in AH with carry clear. Carry set means no multiplex
; ID numbers are currently available.
;****************************************************************************
mplex_id proc near
mov ax,8000h ;Initialize AH and AL
mov cx,80h ;Initialize count
mxid1: push ax ;Save AX and CX
push cx
int 2Fh ;Interrupt 2Fh
or al,al ;Branch if AL=0
jz mxid2
pop cx ;Retrieve AX and CX
pop ax
inc ah ;Increment ID number
loop mxid1 ;Loop until done
stc ;Exit with carry set
ret
mxid2: pop cx ;Clear the stack and exit
pop ax ; with carry clear
clc
ret
mplex_id endp
code ends
end begin