home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1987 / 14 / remove.asm < prev    next >
Assembly Source File  |  1987-04-30  |  11KB  |  224 lines

  1. ;REMOVE.COM for the IBM Personal Computer - 1987 by Jeff Prosise
  2. ;
  3. tsr_count          equ 0103h                ;pointer to installation count
  4. segment_table      equ 0105h                ;pointer to wedge segment values
  5. vector_table       equ 0185h                ;pointer to vector table
  6. ;
  7. code          segment para public 'code'
  8.               assume cs:code,ds:code
  9.               org 100h
  10. begin:        jmp remove                    ;skip data area
  11. ;
  12. copyright     db 'Copyright 1987 Ziff-Davis Publishing Co.'
  13. author        db 'Jeff Prosise'
  14. ;
  15. errmsg1       db 13,10,'None installed',13,10,'$'
  16. errmsg2       db 13,10,'Deinstallation failed',13,10,'$'
  17. text1         db 13,10,'Number of installations: $'
  18. text2         db 13,10,'Press ENTER to remove, ESC to abort',13,10,'$'
  19. text3         db 13,10,'Deinstallation completed',13,10,'$'
  20. data_segment  dw ?                          ;Installation Data Table segment
  21. last_segment  dw ?                          ;temporary segment storage
  22. mcb_start     dw ?                          ;segment address of first MCB
  23. count         dw ?                          ;number of TSR's installed
  24. ;
  25. ;------------------------------------------------------------------------------
  26. ;REMOVE procedure is the main body of the program.
  27. ;------------------------------------------------------------------------------
  28. remove        proc near
  29. ;
  30. ;Make sure there is at least one TSR installed.
  31. ;
  32.               mov ah,44h                    ;call interrupt 1Ah, function 44h
  33.               xor bh,bh                     ;zero BH
  34.               int 1Ah
  35.               cmp bh,0FFh                   ;BH set to 0FFh on return?
  36.               je remove1                    ;yes, then continue
  37.               lea dx,errmsg1                ;no, then there's nothing to remove
  38. exit1:        mov ah,9                      ;print error message and exit
  39.               int 21h
  40.               ret
  41. ;
  42. ;Print list of all installed and verify that the deinstallation should proceed.
  43. ;
  44. remove1:      mov ah,9                      ;print 'Number of installations:'
  45.               lea dx,text1
  46.               int 21h
  47.               mov ax,es:[tsr_count]         ;retrieve installation count
  48.               mov count,ax                  ;save it
  49.               call print_number             ;print the installation count
  50.               call print_crlf               ;advance cursor 2 lines
  51.               call print_crlf
  52.               call print_tsr_list           ;print list of TSR's installed
  53.               mov ah,9                      ;request verification to proceed
  54.               lea dx,text2
  55.               int 21h
  56. remove3:      mov ah,0                      ;get user response
  57.               int 16h
  58.               cmp al,13                     ;was ENTER pressed?
  59.               je remove4                    ;yes, then proceed
  60.               cmp al,27                     ;was ESC pressed?
  61.               jne remove3                   ;no, then try again
  62.               ret                           ;terminate
  63. ;
  64. ;Restore the interrupt vector table in low memory.
  65. ;
  66. remove4:      push ds                       ;save DS
  67.               mov ds,last_segment           ;point DS to wedge PSP segment
  68.               assume ds:nothing
  69.               mov si,vector_table           ;point SI to stored vectors
  70.               mov data_segment,es           ;store IDT segment
  71.               xor ax,ax                     ;point ES:DI to main vector table
  72.               mov es,ax
  73.               xor di,di
  74.               mov cx,512                    ;512 words to move
  75.               cli                           ;disable interrupts
  76.               rep movsw                     ;restore interrupt vector table
  77.               sti                           ;enable interrupts
  78. ;
  79. ;Determine the segment address of the first memory control block.
  80. ;
  81. find:         mov es,ax                     ;point ES to next segment
  82.               inc ax                        ;point AX to the one after it
  83.               cmp byte ptr es:[0],4Dh       ;is MCB signature there?
  84.               jne find                      ;no, then loop
  85.               cmp ax,es:[1]                 ;does next segment own this one?
  86.               jne find                      ;no, then loop
  87.               mov mcb_start,es              ;yes, then store it
  88. ;
  89. ;Scan all memory control blocks from the last wedge forward for PSP blocks.
  90. ;
  91.               mov ds,data_segment           ;set DS to IDT segment
  92.               mov si,count                  ;calculate pointer into IDT
  93.               dec si
  94.               mov cl,2
  95.               shl si,cl
  96.               add si,segment_table
  97.               mov bx,[si]                   ;PSP segment of last wedge
  98. remove5:      dec bx                        ;address memory control block
  99.               mov es,bx
  100.               add bx,es:[3]                 ;calculate address of next MCB
  101.               inc bx
  102.               mov es,bx                     ;transfer address to ES
  103.               inc bx                        ;advance BX to block segment
  104.               cmp bx,es:[1]                 ;is this a PSP block?
  105.               jne remove5                   ;no, then advance to next block
  106.               mov ax,cs                     ;get current PSP segment in AX
  107.               cmp bx,ax                     ;have we reached our own PSP?
  108.               je remove7                    ;yes, then exit loop
  109. ;
  110. ;Deallocate all blocks that belong to the code whose PSP segment is in BX.
  111. ;
  112.               mov ax,mcb_start              ;retrieve address of first MCB
  113. remove6:      mov es,ax                     ;point ES to MCB
  114. remove6a:     add ax,es:[3]                 ;calculate address of next MCB
  115.               inc ax
  116.               mov es,ax                     ;transfer address to ES
  117.               cmp byte ptr es:[0],5Ah       ;last block in the chain?
  118.               je remove5                    ;yes, then exit loop
  119.               cmp bx,es:[1]                 ;does the ownership word match?
  120.               jne remove6a                  ;no, then try next block
  121.               mov dx,ax                     ;save segment value in DX
  122.               inc ax                        ;advance AX to PSP block
  123.               mov es,ax                     ;transfer to ES
  124.               mov ah,49h                    ;deallocate block
  125.               int 21h
  126.               jc mem_error                  ;branch on error
  127.               mov ax,dx                     ;restore AX
  128.               jmp remove6                   ;loop back for more
  129. ;
  130. ;Deallocate the memory used by the resident wedge left behind by INSTALL.
  131. ;
  132. remove7:      mov es,[si+2]                 ;point ES to wedge env segment
  133.               mov ah,49h                    ;deallocate block
  134.               int 21h
  135.               jc mem_error                  ;branch on error
  136.               mov es,[si]                   ;point ES to wedge PSP segment
  137.               mov ah,49h                    ;deallocate block
  138.               int 21h
  139.               jnc remove8                   ;branch if no error
  140. ;
  141. ;Memory deallocation failed.  Print message and terminate.
  142. ;
  143. mem_error:    pop ds                        ;set DS to code segment
  144.               assume ds:code
  145.               lea dx,errmsg2                ;point DS:DX to error text
  146.               jmp exit1                     ;exit
  147. ;
  148. ;Memory was successfully deallocated.  Decrement TSR count and exit.
  149. ;
  150. remove8:      pop ds                        ;restore DS
  151.               mov es,data_segment           ;recover IDT segment
  152.               dec word ptr es:[tsr_count]   ;decrement installation count
  153.               lea dx,text3                  ;print message and exit
  154.               jmp exit1
  155. remove        endp
  156. ;
  157. ;------------------------------------------------------------------------------
  158. ;PRINT_NUMBER writes the number held in AL to the display.
  159. ;------------------------------------------------------------------------------
  160. print_number  proc near
  161.               aam                           ;convert value in AL to BCD in AX
  162.               add ax,3030h                  ;binary to ASCII
  163.               cmp ah,30h                    ;first digit zero?
  164.               je print1                     ;yes, then don't print it
  165.               push ax                       ;save AX
  166.               mov dl,ah                     ;transfer digit to DL
  167.               mov ah,2                      ;INT 21h function number
  168.               int 21h                       ;print the first digit
  169.               pop ax                        ;recover AX
  170. print1:       mov ah,2                      ;INT 21h function number
  171.               mov dl,al                     ;transfer digit to DL
  172.               int 21h                       ;print the digit
  173.               ret
  174. print_number  endp
  175. ;
  176. ;------------------------------------------------------------------------------
  177. ;PRINT_TSR_LIST writes a list of all TSR's present in memory.
  178. ;Entry:  ES - Installation Data Table segment
  179. ;------------------------------------------------------------------------------
  180. print_tsr_list proc near
  181.               cld                           ;clear DF
  182.               mov cx,count                  ;get count of TSR's installed
  183.               mov di,segment_table          ;point DI to wedge segment values
  184.               push ds                       ;save DS
  185.               assume ds:nothing
  186. printnum1:    mov ds,es:[di]                ;get wedge segment address in DS
  187.               mov last_segment,ds           ;store it for later
  188.               mov si,82h                    ;point SI to command line
  189.               cmp byte ptr [si-2],1         ;more than 1 character entered?
  190.               jbe printnum3                 ;no, then no name defined
  191.               push cx                       ;save TSR count
  192.               mov cl,[si-2]                 ;get length of TSR name in CX
  193.               xor ch,ch
  194.               dec cx
  195. printnum2:    lodsb                         ;get a character
  196.               mov ah,2                      ;print it
  197.               mov dl,al
  198.               int 21h
  199.               loop printnum2                ;loop until done
  200.               pop cx                        ;retrieve TSR count
  201. printnum3:    call print_crlf               ;advance cursor to next line
  202.               add di,4                      ;point ES:DI to next segment value
  203.               loop printnum1                ;loop until all names printed
  204.               pop ds                        ;restore DS
  205.               assume ds:code
  206.               ret
  207. print_tsr_list endp
  208. ;
  209. ;------------------------------------------------------------------------------
  210. ;PRINT_CRLF advances the cursor to the beginning of the next line.
  211. ;------------------------------------------------------------------------------
  212. print_crlf    proc near
  213.               mov ah,2                      ;print carriage return
  214.               mov dl,0Dh
  215.               int 21h
  216.               mov ah,2                      ;print linefeed
  217.               mov dl,0Ah
  218.               int 21h
  219.               ret
  220. print_crlf    endp
  221. ;
  222. code          ends
  223.               end begin
  224.