home *** CD-ROM | disk | FTP | other *** search
- ;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