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