home *** CD-ROM | disk | FTP | other *** search
/ TopWare Tools / TOOLS.iso / tools / top1190 / watch.asm < prev    next >
Encoding:
Assembly Source File  |  1989-05-31  |  13.7 KB  |  405 lines

  1. ;WATCH.ASM Version 3.1 30-May-1989 03:10
  2. ;resident routine watches programs going resident
  3. ;and keeps a list of changes to interrupt vectors
  4. ;in an internal data structure
  5. ; written for MASM (version 4 or later) or TASM
  6. ; by Kim Kokkonen, TurboPower Software
  7. ; telephone: 408-438-8606, Compuserve 72457,2131
  8. ;
  9. ; VERSION 2.2  3/4/87
  10. ;   First release, version to be consistent with MAPMEM.PAS
  11. ; VERSION 2.3  5/1/87
  12. ;   Sets up a separate stack for the interrupt handlers
  13. ;     to solve problem first noticed with EMMCACHE and WATCH
  14. ;   Changes approach - store all vector information in RAM buffers
  15. ;   No disk access at all by WATCH
  16. ;   Better check for multiple installation
  17. ;   Changed to use MASM
  18. ; VERSION 2.4  5/17/87
  19. ;   for consistency with RELEASE
  20. ; VERSION 2.5  5/28/87
  21. ;   save flags in int21 handler
  22. ; VERSION 3.1  5/30/89 for use with UnMark and ReMark 3.1
  23. ;   by Tom Gilbert's Heart & Mind includes TurboPower 2.8
  24. ;   NO [F]Mark INT vectors
  25. ;   Change method to avoid reinstallation
  26. ;   Nul Vchg area => vpos to simplify debugging
  27.  
  28. Cseg      segment public para
  29.           assume  cs:Cseg, ds:nothing, es:nothing, ss:nothing
  30.  
  31.           org     080H
  32. cmdline   label   byte                 ;pointer to command line
  33.  
  34.           org     100H
  35. ComEntry: jmp     init
  36.  
  37. ;resident data section follows
  38.  
  39. ;put the following in the MAP file
  40. public bmesg,origv,prevv,vpos,vchg
  41. ;      0E20h, 620h,0A20h,104h,220h
  42.  
  43. ;resident data structures not part of COM file
  44. vchg        equ 220H            ;location of data area (>= offset bmesg)
  45. vrecsize    equ 8               ;bytes per vector change record
  46. vsize       equ 80H*vrecsize    ;size of vector change area in bytes
  47.                                 ;space for 128 changes of vector here
  48. ;vector table buffers
  49. origv       equ vchg+vsize      ;location of original vector table
  50. veclen      equ 400H            ;size of vector table in bytes
  51. prevv       equ origv+veclen    ;location of current vector table
  52. newstackpos equ prevv+veclen    ;location of newstack
  53. ssize       equ 0080H           ;number of bytes in temporary stack
  54.  
  55. newloc      equ newstackpos+ssize ;where installation code relocated
  56.             even
  57. vpos        dw  0               ;next position to write in data area
  58.  
  59. ;temporary stack used by interrupt handler
  60. newss       dw  0               ;segment of temporary stack
  61. newsp       dw  0               ;initial stack pointer
  62.  
  63. ;information saved about the calling program
  64. oldss       dw  ?               ;stack segment
  65. oldsp       dw  ?               ;stack pointer
  66. curpsp      dw  ?               ;program segment
  67.  
  68. ;id code for a PSP data block
  69. pspid       equ 0FFFFH          ;id used to indicate a PSP block
  70.  
  71. ;previous interrupt handlers
  72. dos_int     label dword
  73. old21       dw 2 dup (?)        ;old int21 vector
  74. tsr_int     label dword
  75. old27       dw 2 dup (?)        ;old int27 vector
  76.  
  77. ;***********************************************************************
  78. ;interrupt handler for int21
  79. newint21 proc  near
  80.          assume ds:nothing
  81.          pushf                  ;save flags
  82.          cmp    ah,31H
  83.          jne    ex21
  84.          call   checkvec        ;call routine to check vector table
  85. ex21:    popf
  86.          jmp    dos_int         ;transfer control to old int21 vector
  87. newint21 endp
  88.  
  89. ;***********************************************************************
  90. ;interrupt handler for int27
  91. newint27 proc  near
  92.          assume ds:nothing
  93.          call   checkvec
  94. ex27:    jmp    tsr_int         ;transfer control to old int27 vector
  95. newint27 endp
  96.  
  97. ;***********************************************************************
  98.  
  99. ;procedure checkvec
  100. ;  compares vectors to previous installation
  101. ;  writes vector change information
  102. ;  stores a new vector buffer
  103.  
  104. checkvec proc  near
  105.        assume ds:nothing
  106.  
  107. ;save current stack
  108.         mov     oldss,ss
  109.         mov     oldsp,sp
  110.  
  111. ;switch to our stack
  112.         cli
  113.         mov     ss,newss
  114.         mov     sp,newsp
  115.         sti
  116. ;store registers
  117.         push    ax
  118.         push    bx
  119.         push    cx
  120.         push    dx
  121.         push    si
  122.         push    di
  123.         push    ds
  124.         push    es
  125. ;get DS set up as CS
  126.         mov     ax,cs
  127.         mov     ds,ax
  128.         assume  ds:Cseg
  129.         mov     ah,51H      ;get current PSP
  130.         pushf               ;by simulated INT
  131.         call    dos_int     ;bx returns PSP
  132.         call    vechdr      ;store PSP segment of program going resident
  133.         call    cmpvec      ;scan vector table for changes from buffer
  134.         mov     di,prevv    ;save the new version of the vector table
  135.         call    savevec
  136. ;restore registers
  137.         pop     es
  138.         pop     ds
  139.         assume  ds:nothing
  140.         pop     di
  141.         pop     si
  142.         pop     dx
  143.         pop     cx
  144.         pop     bx
  145.         pop     ax
  146. ;restore stack
  147.         cli
  148.         mov     ss,oldss
  149.         mov     sp,oldsp
  150.         sti
  151.         ret
  152. checkvec endp
  153.  
  154. ;***********************************************************************
  155. ;procedure vechdr
  156. ;  writes a header to the vector data area for this new TSR
  157. ;  on entry:
  158. ;    bx has PSP of the new TSR
  159. ;
  160. vechdr  proc near
  161.         assume  ds:Cseg
  162.         cmp     vpos,vsize-vrecsize       ;assure room for next record
  163.         ja      vecex                     ;ignore if no room
  164.         push    di
  165.         mov     di,vpos                   ;index into vchg array
  166.         mov     word ptr [di+vchg],pspid  ;store id word
  167.         mov     word ptr [di+vchg+2],bx   ;store PSP value two words in
  168.                                           ;record left unitialized
  169.         add     vpos,vrecsize             ;move to next data element
  170.         pop     di
  171.  
  172. vecex:  ret
  173. vechdr  endp
  174.  
  175. ;***********************************************************************
  176. ;procedure wrchg
  177. ;  writes information about changed vectors to the data area
  178. ;  on entry
  179. ;    ax has changed vector number
  180. ;    ds points to segment 0
  181. ;  on exit:
  182. ;    flags changed
  183. ;
  184. wrchg   proc    near
  185.         assume  ds:nothing, es:nothing
  186.         cmp     vpos,vsize-vrecsize ;assure room for next record
  187.         ja      wrcex
  188.  
  189.         push    ax
  190.         push    si
  191.         push    di
  192.  
  193.         mov     di,vpos             ;index into vchg array
  194.         mov     cs:[di+vchg],ax     ;store interrupt vector number
  195.  
  196.         mov     si,ax
  197.         shl     si,1
  198.         shl     si,1                ;get address of vector
  199.         mov     ax,[si]             ;get offset of vector
  200.         mov     cs:[di+vchg+2],ax   ;store vector offset
  201.         mov     ax,[si+2]           ;get segment
  202.         mov     cs:[di+vchg+4],ax   ;store segment
  203.                                     ;one word in record left unused
  204.         add     vpos,vrecsize       ;move to next data element
  205.  
  206.         pop     di
  207.         pop     si
  208.         pop     ax
  209.  
  210. wrcex:  ret
  211. wrchg   endp
  212.  
  213. ;***********************************************************************
  214. ;procedure cmpvec
  215. ;  compares vectors in buffer to those in use
  216. ;  writes numbers of those different to data area
  217. ;  on entry:
  218. ;    bx has program's PSP
  219. ;  on exit:
  220. ;    ax,si,di destroyed
  221. ;    flags changed
  222. ;
  223. cmpvec  proc   near
  224.         push    ds
  225.         push    es
  226.         assume  es:nothing
  227.         mov     es,bx           ;If NO " T"
  228.         cmp word ptr es:[65h],'T '
  229.         jne     dovecs          ;then NOT [F]Mark
  230.         cmp word ptr es:[67h],'RS'
  231.         je      cvexit          ;else " TSR" is [F]Mark
  232.  
  233. dovecs: assume ds:nothing
  234.         xor     si,si           ;source offset 0
  235.         mov     ds,si           ;source address segment 0
  236.         mov     ax,cs
  237.         mov     es,ax
  238.         xor     ax,ax           ;vector counter
  239.         mov     di,prevv        ;destination offset
  240.         cld                     ;upward direction
  241.  
  242. nexvec: cmpsw                   ;compare offsets
  243.         je      cmpseg          ;compare segments if offsets equal
  244.         call    wrchg           ;write changed vector
  245.         cmpsw                   ;compare next word, ignore result
  246.         jmp short vecinc
  247.  
  248. cmpseg: cmpsw                   ;compare segments
  249.         je      vecinc
  250.         call    wrchg           ;write changed vector
  251.  
  252. vecinc: inc     ax              ;next vector number
  253.         cmp     ax,00FFH
  254.         jbe     nexvec          ;continue until 256 vectors checked
  255.  
  256. cvexit: pop     es
  257.         pop     ds
  258.         ret
  259. cmpvec  endp
  260.  
  261. ;***********************************************************************
  262. ;procedure savevec
  263. ;  saves image of interrupt vectors
  264. ;  on entry:
  265. ;    di has destination offset
  266. ;  on exit:
  267. ;    ax,cx,si,di destroyed
  268. ;    flags changed
  269. ;
  270. savevec proc   near
  271.         assume ds:nothing, es:nothing
  272.         push    ds
  273.         push    es
  274.         xor     si,si           ;offset 0
  275.         mov     ds,si           ;source address segment 0
  276.         mov     ax,cs
  277.         mov     es,ax           ;destination always in this code segment
  278.         mov     cx,200H         ;512 integers to store
  279.         cld                     ;copy up
  280.         rep     movsw           ;copy vectors to our table
  281.         pop     es
  282.         pop     ds
  283.         ret
  284. savevec endp                    ;of proc savevec
  285.  
  286. ;***********************************************************************
  287. ;resident portion above
  288. ;temporary portion below
  289. ;***********************************************************************
  290.  
  291. ;temporary strings
  292.         even
  293. bmesg   db  13,10,'Cannot install WATCH more than once....',13,10,36
  294. mesg    db  13,10,'WATCH 3.1 successfully installed',13,10,36
  295. pname   db  'TSR WATCHER'
  296. plen    equ $-pname             ;length of string
  297.  
  298. ;***********************************************************************
  299. ;install new handlers for DOS go-resident services
  300. init    proc   near
  301.         assume ds:Cseg
  302. ;search for a previous installation after DOS Master Environment
  303.         mov     ah,52h          ;Use Undocumented Interrupt
  304.         int     21h             ; to locate DOS CONFIG.SYS
  305.         mov     ax,es:[bx-2]    ;Use its
  306.         mov     es,ax           ;MCB and
  307.         inc     ax              ;Block to
  308.         add     ax,es:[3]       ; add in
  309.         mov     es,ax           ;lengths to
  310.         inc     ax              ;location of
  311.         add     ax,es:[3]       ;environment
  312.         mov     es,ax           ;MCB to begin
  313.         mov     bx,cs           ;comparisons
  314. watchs: inc     ax              ;If next segment
  315.         mov     es,ax           ;to be compared
  316.         cmp     ax,bx           ;is NOT before here
  317.         jnc     success         ;then NO other Watch
  318.         mov     si,offset pname ;else compare pname
  319.         mov     di,81h          ;with command line
  320.         mov     cx,plen         ;"TSR WATCHER"
  321.         rep     cmpsb           ;If NO match
  322.         jne     watchs          ;then loop
  323. ;error exit
  324.         mov     dx,offset bmesg ;else error message
  325.         mov     ah,09H          ;NOT more than once
  326.         int     21H             ;DOS print string
  327.         mov     ax,4C01H        ;exit with error
  328.         int     21H
  329. success:                        ;print a success message
  330.         mov     dx,offset mesg  ;start of message to write
  331.         mov     ah,09H
  332.         int     21H             ;DOS print string
  333.  
  334. ;relocate ourselves out of the way of the vector tables
  335.         mov     ax,cs
  336.         mov     es,ax
  337.         mov     di,newloc+10H
  338.         push    di                  ;will act as a return address
  339.         mov     si,offset newstk
  340.         mov     cx,lastcode-newstk
  341.         rep     movsb               ;move code
  342.         ret                         ;"return" to the relocated code
  343.  
  344. ;initialize location of WATCH stack
  345. newstk: mov     newsp,newstackpos+ssize
  346.         mov     newss,cs            ;stack seg is code seg
  347.         push    es
  348.  
  349. ;get int 21H vector
  350.         mov     ax,3521H        ;GetVector DOS function call
  351.         int     21H
  352.         mov     old21,bx        ;store first word of old21
  353.         mov     old21[2],es     ;store second word
  354.  
  355. ;get int 27H vector
  356.         mov     ax,3527H        ;GetVector DOS function call
  357.         int     21H
  358.         mov     old27,bx        ;store first word of old27 (offset)
  359.         mov     old27[2],es     ;store second word (segment)
  360.         pop     es
  361.         push    es
  362.         mov     es,es:[2Ch]
  363.         mov     ah,49h          ; Release Environment and
  364.         int     21h             ; put an id label at
  365.         mov     ax,cs           ; offset 80H so other programs
  366.         mov     es,ax           ; can recognize WATCH
  367.         mov     cx,plen         ;length of name string
  368.         mov     si,offset pname ;offset of name string
  369.         mov     di,offset cmdline ;offset of DOS command line
  370.         cld                     ;transfer in forward direction
  371.         mov     al,cl
  372.         stosb                   ;store length byte first
  373.         rep     movsb           ;transfer characters
  374.         xor     ax,ax           ;nul-out
  375.         mov     di,vchg         ;vector change
  376.         mov     cx,200h         ;table area
  377.         rep     stosw
  378.  
  379. ;store image of original vector table in origv following vchg table
  380.         mov     ax,offset savevec
  381.         call    ax              ;absolute call works as code is moved
  382.  
  383. ;store it again in the current vector table prevv which follows origv
  384.         mov     ax,offset savevec
  385.         call    ax              ;absolute call works as code is moved
  386.  
  387. ;install the new vectors
  388.         mov     ax,2521H
  389.         mov     dx,offset newint21
  390.         int     21H
  391.         mov     ax,2527H
  392.         mov     dx,offset newint27
  393.         int     21H
  394.  
  395. ;terminate and stay resident
  396.         mov     dx,(newloc+15) shr 4
  397.         mov     ax,3100H        ;return success code
  398.         int     21H
  399.  
  400. lastcode:
  401. init    endp
  402.  
  403. Cseg    ends
  404.         end     ComEntry
  405.