home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1987
/
14
/
remove.asm
< prev
next >
Wrap
Assembly Source File
|
1987-04-30
|
11KB
|
224 lines
;REMOVE.COM for the IBM Personal Computer - 1987 by Jeff Prosise
;
tsr_count equ 0103h ;pointer to installation count
segment_table equ 0105h ;pointer to wedge segment values
vector_table equ 0185h ;pointer to vector table
;
code segment para public 'code'
assume cs:code,ds:code
org 100h
begin: jmp remove ;skip data area
;
copyright db 'Copyright 1987 Ziff-Davis Publishing Co.'
author db 'Jeff Prosise'
;
errmsg1 db 13,10,'None installed',13,10,'$'
errmsg2 db 13,10,'Deinstallation failed',13,10,'$'
text1 db 13,10,'Number of installations: $'
text2 db 13,10,'Press ENTER to remove, ESC to abort',13,10,'$'
text3 db 13,10,'Deinstallation completed',13,10,'$'
data_segment dw ? ;Installation Data Table segment
last_segment dw ? ;temporary segment storage
mcb_start dw ? ;segment address of first MCB
count dw ? ;number of TSR's installed
;
;------------------------------------------------------------------------------
;REMOVE procedure is the main body of the program.
;------------------------------------------------------------------------------
remove proc near
;
;Make sure there is at least one TSR installed.
;
mov ah,44h ;call interrupt 1Ah, function 44h
xor bh,bh ;zero BH
int 1Ah
cmp bh,0FFh ;BH set to 0FFh on return?
je remove1 ;yes, then continue
lea dx,errmsg1 ;no, then there's nothing to remove
exit1: mov ah,9 ;print error message and exit
int 21h
ret
;
;Print list of all installed and verify that the deinstallation should proceed.
;
remove1: mov ah,9 ;print 'Number of installations:'
lea dx,text1
int 21h
mov ax,es:[tsr_count] ;retrieve installation count
mov count,ax ;save it
call print_number ;print the installation count
call print_crlf ;advance cursor 2 lines
call print_crlf
call print_tsr_list ;print list of TSR's installed
mov ah,9 ;request verification to proceed
lea dx,text2
int 21h
remove3: mov ah,0 ;get user response
int 16h
cmp al,13 ;was ENTER pressed?
je remove4 ;yes, then proceed
cmp al,27 ;was ESC pressed?
jne remove3 ;no, then try again
ret ;terminate
;
;Restore the interrupt vector table in low memory.
;
remove4: push ds ;save DS
mov ds,last_segment ;point DS to wedge PSP segment
assume ds:nothing
mov si,vector_table ;point SI to stored vectors
mov data_segment,es ;store IDT segment
xor ax,ax ;point ES:DI to main vector table
mov es,ax
xor di,di
mov cx,512 ;512 words to move
cli ;disable interrupts
rep movsw ;restore interrupt vector table
sti ;enable interrupts
;
;Determine the segment address of the first memory control block.
;
find: mov es,ax ;point ES to next segment
inc ax ;point AX to the one after it
cmp byte ptr es:[0],4Dh ;is MCB signature there?
jne find ;no, then loop
cmp ax,es:[1] ;does next segment own this one?
jne find ;no, then loop
mov mcb_start,es ;yes, then store it
;
;Scan all memory control blocks from the last wedge forward for PSP blocks.
;
mov ds,data_segment ;set DS to IDT segment
mov si,count ;calculate pointer into IDT
dec si
mov cl,2
shl si,cl
add si,segment_table
mov bx,[si] ;PSP segment of last wedge
remove5: dec bx ;address memory control block
mov es,bx
add bx,es:[3] ;calculate address of next MCB
inc bx
mov es,bx ;transfer address to ES
inc bx ;advance BX to block segment
cmp bx,es:[1] ;is this a PSP block?
jne remove5 ;no, then advance to next block
mov ax,cs ;get current PSP segment in AX
cmp bx,ax ;have we reached our own PSP?
je remove7 ;yes, then exit loop
;
;Deallocate all blocks that belong to the code whose PSP segment is in BX.
;
mov ax,mcb_start ;retrieve address of first MCB
remove6: mov es,ax ;point ES to MCB
remove6a: add ax,es:[3] ;calculate address of next MCB
inc ax
mov es,ax ;transfer address to ES
cmp byte ptr es:[0],5Ah ;last block in the chain?
je remove5 ;yes, then exit loop
cmp bx,es:[1] ;does the ownership word match?
jne remove6a ;no, then try next block
mov dx,ax ;save segment value in DX
inc ax ;advance AX to PSP block
mov es,ax ;transfer to ES
mov ah,49h ;deallocate block
int 21h
jc mem_error ;branch on error
mov ax,dx ;restore AX
jmp remove6 ;loop back for more
;
;Deallocate the memory used by the resident wedge left behind by INSTALL.
;
remove7: mov es,[si+2] ;point ES to wedge env segment
mov ah,49h ;deallocate block
int 21h
jc mem_error ;branch on error
mov es,[si] ;point ES to wedge PSP segment
mov ah,49h ;deallocate block
int 21h
jnc remove8 ;branch if no error
;
;Memory deallocation failed. Print message and terminate.
;
mem_error: pop ds ;set DS to code segment
assume ds:code
lea dx,errmsg2 ;point DS:DX to error text
jmp exit1 ;exit
;
;Memory was successfully deallocated. Decrement TSR count and exit.
;
remove8: pop ds ;restore DS
mov es,data_segment ;recover IDT segment
dec word ptr es:[tsr_count] ;decrement installation count
lea dx,text3 ;print message and exit
jmp exit1
remove endp
;
;------------------------------------------------------------------------------
;PRINT_NUMBER writes the number held in AL to the display.
;------------------------------------------------------------------------------
print_number proc near
aam ;convert value in AL to BCD in AX
add ax,3030h ;binary to ASCII
cmp ah,30h ;first digit zero?
je print1 ;yes, then don't print it
push ax ;save AX
mov dl,ah ;transfer digit to DL
mov ah,2 ;INT 21h function number
int 21h ;print the first digit
pop ax ;recover AX
print1: mov ah,2 ;INT 21h function number
mov dl,al ;transfer digit to DL
int 21h ;print the digit
ret
print_number endp
;
;------------------------------------------------------------------------------
;PRINT_TSR_LIST writes a list of all TSR's present in memory.
;Entry: ES - Installation Data Table segment
;------------------------------------------------------------------------------
print_tsr_list proc near
cld ;clear DF
mov cx,count ;get count of TSR's installed
mov di,segment_table ;point DI to wedge segment values
push ds ;save DS
assume ds:nothing
printnum1: mov ds,es:[di] ;get wedge segment address in DS
mov last_segment,ds ;store it for later
mov si,82h ;point SI to command line
cmp byte ptr [si-2],1 ;more than 1 character entered?
jbe printnum3 ;no, then no name defined
push cx ;save TSR count
mov cl,[si-2] ;get length of TSR name in CX
xor ch,ch
dec cx
printnum2: lodsb ;get a character
mov ah,2 ;print it
mov dl,al
int 21h
loop printnum2 ;loop until done
pop cx ;retrieve TSR count
printnum3: call print_crlf ;advance cursor to next line
add di,4 ;point ES:DI to next segment value
loop printnum1 ;loop until all names printed
pop ds ;restore DS
assume ds:code
ret
print_tsr_list endp
;
;------------------------------------------------------------------------------
;PRINT_CRLF advances the cursor to the beginning of the next line.
;------------------------------------------------------------------------------
print_crlf proc near
mov ah,2 ;print carriage return
mov dl,0Dh
int 21h
mov ah,2 ;print linefeed
mov dl,0Ah
int 21h
ret
print_crlf endp
;
code ends
end begin