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

  1. Title   ReMark.ASM -- Replaces TurboPower DISABLE Version 2.8
  2. Cseg    Segment Public Para   ;Version 3.1 30-May-1989 - 03:10
  3.         Assume  cs:Cseg,ds:Cseg
  4.         Org 0100h
  5. Main    Proc    Far
  6.         Jmp Start
  7. UsageMsg    DB  13,'   ',9,10
  8. DB 'ReMark replaces DISABLE ver 2.8 by TurboPower Software',13,10,9
  9. DB '======================================================',13,10,9
  10. DB 'ReMark, like DISABLE, allows ReEnabling a DisAbled TSR',13,10,9
  11. DB 'or DisAbling an active TSR while leaving it in memory.',13,10,10,9
  12. DB 'Watch MUST be installed ahead of the TSR to ReMark.',13,10,10,9
  13. DB 'If ShowTSRs displays an "owner" name of "command", you',13,10,9
  14. DB 'MUST use the PSP address for the TSR which is reported',13,10,9
  15. DB 'in the first column of the line for the TSR displayed.',13,10,10,9
  16. DB 'ReMark accepts the following command line syntax:',13,10,10,9,9
  17. DB 'ReMark [TSRname or PSPaddress][/option]',13,10,10,9,'Options:'
  18. DB 9,9,9,'/D(eActivate)',13,10,9,9,9,9,9,'/A(ctivate)',13,10,10,9
  19. DB 'If NO "/"option is entered, ReMark will show STATUS.',13,10,10,9
  20. DB 'ReMark with NO VALID TSR/PSP will display this help.'
  21.  
  22. CRLF        DB  13,10,"$",8,32,26       ; You can >TYPE ReMark.COM
  23.  
  24. NoWatch     DB  9,9,9,' NO'
  25. WatchID     DB  ' TSR WATCHER'          ; Watch identifier @ 81h
  26.             DB  ' is installed!$'
  27.  
  28. NoName      DB  9,9,9,9,'Cannot find requested TSR='
  29. Command     DB  9 DUP('$')              ; Command Parameter
  30.             DB  9 DUP('!'),'$'          ; Invalid Extension
  31. AlreadyM    DB  ' Already$'
  32. IsActive    DB  ' is Active$'
  33. NoSpaceM    DB  ", due to WATCH full, can't be"
  34. Disabled    DB  ' DisAbled$'
  35. Remarked    DB  ' ReEnAbled$'
  36.  
  37. ReMflag     DB  ?                       ; 0 if Active or 1 if DisAbled
  38. ReQflag     DB  0                       ; 0 for STATUS, 1="A" or -1="D"
  39.  
  40. ParLen      DW  0                       ; Length of Command Parameter
  41. ErrLvl      DW  4C00h                   ; Used on Exit to DOS
  42. WatchF      DW  0                       ; PSP of Watch if found
  43. WatchPos    DW  ?                       ; Value of WATCH "vpos" @[104h]
  44. BufferPos   DW  ?                       ; Working position Offset/Value
  45.  
  46. WatchCode   equ offset buffer           ; Storage for Patch/Restore Code
  47. WatchBuf    equ WatchCode + 100h        ; Watch VectorChange Area Copy
  48. WatchVec    equ WatchBuf + 400h         ; Storage for WATCH "origv" Vecs
  49. WatchNew    equ WatchVec + 400h         ; New Watch VectorChange Buffer
  50. MCBbuf      equ WatchNew + 400h         ; Storage for MCB records
  51.  
  52. Start:  xor     ax,ax                   ; Zero
  53.         mov     cx,2048                 ; data
  54.         mov     di,WatchCode            ; buffer
  55.         rep     stosw                   ; words
  56.         mov     si,81h                  ; Get User
  57.         mov     di,offset Command       ; Command
  58.  
  59. Ploop:  lodsb                           ; If Byte
  60.         cmp     al,13                   ; is End
  61.         je      Pexit                   ; Then Exit
  62.         cmp     al,"!"                  ; Else Skip
  63.         jc      Ploop                   ; Spaces or Below
  64.         cmp     al,"a"                  ; Insure that
  65.         jb      Pluck                   ; Alphabetic
  66.         cmp     al,"z"                  ; Characters
  67.         ja      Pluck                   ; Become
  68.         and     al,5Fh                  ; UPPER case
  69. Pluck:  cmp     al,"/"                  ; If Switch
  70.         je      Parse                   ; Then Parse
  71.         stosb                           ; Else Store
  72.         jmp     short Ploop             ; Name or PSP
  73. Parse:  lodsb                           ; Get Switch
  74.         and     al,5Fh                  ; UPPER case
  75.         cmp     al,"A"                  ; If NOT "A"ctivate
  76.         jne     Pl4aD                   ; Then Check "D"eActivate
  77.         inc     ReQflag                 ; Else "A" ReQuest
  78. Pl4aD:  cmp     al,"D"                  ; If NOT "D"eActivate
  79.         jne     Ploop                   ; Then Loop Until End
  80.         dec     ReQflag                 ; Else "D" ReQuest
  81.         jmp     short Ploop             ;  and Loop Until End
  82.  
  83. Pexit:  sub     di,offset Command       ; If any Command
  84.         jnz     SaveL                   ; Then Save Length
  85.         jmp     Usage                   ; Else Give Help
  86.  
  87. SaveL:  mov     ParLen,di               ; Store Length
  88.         mov     ah,52h                  ; Undocumented
  89.         int     21h                     ; Function
  90.         mov     di,es:[bx-2]            ; obtains
  91.         mov     es,di                   ; MCB of DOS
  92.         inc     di                      ; Config.Sys
  93.         mov     si,MCBbuf               ; Initialize Source and
  94.         xor     bx,bx                   ; Basic Index Pointers
  95.  
  96. MCBlp:  add     di,es:[3]               ; Advance so as to
  97.         mov     es,di                   ; Point to MCB and
  98.         inc     di                      ; Next Paragraph
  99.         mov     [si+bx+0],es            ; Store MCB
  100.         mov     dx,es:[1]               ; Get and Store
  101.         mov     [si+bx+2],dx            ; Block Address
  102.         mov     ax,es:[3]               ; and Block
  103.         mov     [si+bx+4],ax            ; Length
  104.         call    DoFlags                 ; Copy Watch/Flag TSR
  105.         add     bx,8                    ; Advance to Next and
  106.         cmp     byte ptr es:[0],"Z"     ; Loop Until Last MCB
  107.         jne     MCBlp
  108.         push    ds                      ; Restore Extra Segment
  109.         pop     es                      ; Register to DATA
  110.         cmp     word ptr WatchF,0       ; If Any Watch was Found
  111.         jnz     IfTSR                   ; Then Check If TSR Found
  112.         mov     dx,offset NoWatch       ; Else NO TSR WATCHER
  113.         mov     byte ptr ErrLvl,1       ; Error Level and
  114.         mov     ah,9                    ; Warning Message
  115.         int     21h                     ; Give Help on Exit
  116.         jmp     short Usage
  117. IfTSR:  mov     ax,-1                   ; Scan for FFFFh
  118.         mov     di,si                   ; in MCB Buffer
  119.         mov     cx,bx                   ; Record
  120.         shr     cx,1                    ; Words
  121.         repne   scasw                   ; If None
  122.         jne     NoFind                  ; Then NO TSR
  123.         mov     bx,es:[di-6]            ; Else Get PSP
  124.         mov     di,WatchBuf             ; Point to Watch Copy
  125.         mov     cx,WatchPos             ; Set Counter to
  126.         shr     cx,1                    ; Number of Words
  127. WatchS: repne   scasw                   ; If NO More Blocks
  128.         jcxz    NoFind                  ; Then NO TSR Found
  129.         cmp     bx,es:[di]              ; Else If NOT PSP
  130.         jne     WatchS                  ; Then Search On
  131.         add     di,6                    ; Else Save Position of
  132.         mov     BufferPos,di            ; First TSR ChangeBlock
  133.         mov     ax,es:[di]              ; Get Block ID and Set
  134.         mov     ReMflag,ah              ; 0 to Dis or 1 to ReEn Able
  135.         mov     ah,9
  136.         mov     dx,offset CRLF          ; Display New Line
  137.         int     21h
  138.         mov     dx,offset Command       ; Display Command
  139.         int     21h
  140.         call    Toggle                  ; Set Status
  141.         mov     ah,9                    ; Display New
  142.         int     21h                     ; Status and
  143.         mov     dx,offset CRLF          ; New Line
  144.         int     21h                     ; Before Exit
  145.         jmp     short Exit
  146. NoFind: mov     ah,9                    ; Display TSR
  147.         mov     dx,offset NoName        ; NOT Found
  148.         int     21h                     ; Message and
  149.         mov     byte ptr ErrLvl,2       ; Set Error Level
  150. Usage:  mov     ah,9                    ; Display ReMark
  151.         mov     dx,offset UsageMsg      ; Usage Message
  152.         int     21h
  153. Exit:   mov     ax,ErrLvl               ; Error Level
  154.         int     21h                     ; Exit to DOS
  155. Main    EndP
  156.  
  157. Toggle  Proc
  158.         mov     bp,WatchPos             ; Copy Old WATCH "vpos"
  159.         xor     dx,dx                   ; Zero ChangeCode Index
  160.         mov     si,WatchBuf             ; Copy WATCH Blocks
  161.         mov     cx,BufferPos            ; from 1st through
  162.         sub     cx,si                   ; TSR ID WATCH Block
  163.         mov     di,WatchNew             ; Into NEW WATCH Buffer
  164.         add     WatchPos,si             ;  and Set Limit for Loop
  165.         rep     movsb
  166.         mov     al,ReQflag              ; If a "/A" or "/D"
  167.         or      al,al                   ; Parameter ReQuest
  168.         jnz     ReQest                  ; Then Process ReQuest
  169.         add     al,ReMflag              ; Else Report
  170.         mov     dx,offset IsActive      ; "is Active"
  171.         jz      RePort                  ;     or
  172.         mov     dx,offset Disabled      ; " DisAbled"
  173. RePort: jmp     ReTurn                  ; Current Status
  174.  
  175. ReQest: add     al,ReMflag              ; If Combined Status
  176.         cmp     al,2                    ; and ReQuest => 2
  177.         jnc     ReLoop                  ; Then Something to Do
  178.         mov     dx,offset AlreadyM      ; Else Report "Already"
  179.         push    ax                      ; Preserving Combined
  180.         mov     ah,9                    ; Flags in AL
  181.         int     21h                     ; Register
  182.         pop     ax                      ; Report
  183.         mov     dx,offset Disabled      ; "DisAbled"
  184.         cmp     al,1                    ; Unless for
  185.         jne     RePort                  ; Flags = 1
  186.         mov     dx,offset IsActive      ; "is Active"
  187.         jmp     short RePort
  188. ReLoop: mov     ax,[si]                 ; Get Block ID
  189.         cmp     ax,-1                   ; If New TSR
  190.         je      ReDone                  ; Or If End
  191.         cmp     si,WatchPos             ; of Blocks
  192.         jnc     ReDone                  ; Then Exit Loop
  193.         cmp     ah,1                    ; Else If to be
  194.         je      LoopOk                  ; ReEnAbled
  195.         cmp     si,WatchVec             ; Or If More Room
  196.         jc      LoopOk                  ; Then Continue
  197.         mov     byte ptr ErrLvl,3       ; Else Set Error Level 3 for
  198.         mov     dx,offset NoSpaceM      ; No Space to DisAble and
  199.         jmp     short ReTurn            ; Error Exit from Toggle
  200.  
  201. LoopOk: mov     cx,8                    ; Set Move Counter
  202.         mov     bx,[si+4]               ; Get Segment and
  203.         mov     ax,[si+2]               ; Offset of Vector
  204.         cmp     byte ptr ReMflag,0      ; If Zero to DisAble
  205.         je      UnLoop                  ; Then DisAble Vector
  206.         mov     byte ptr [si+1],0       ; Else Flag ReEnAbled
  207.         sub     bp,cx                   ; Reduce WATCH "vpos"
  208.         rep     movsb                   ; Copy Vector Block
  209.         push    di                      ; Preserve Position
  210.         mov     di,WatchCode            ; While Storing Code
  211.         add     di,dx                   ; Contained in Change
  212.         stosw                           ; Vector for Segment
  213.         mov     ax,bx                   ; and Offset Obtained
  214.         stosw                           ; from Vector Block
  215.         add     si,2                    ; Advance to Code and
  216.         mov     cx,3                    ; Copy the Stored Code
  217.         rep     movsw                   ; into the Watch Code
  218.         add     dx,10                   ; Update Code Index
  219.         pop     di                      ; Restore Position
  220.         jmp     short ReLoop            ; Loop Until Vectors Done
  221.  
  222. ReDone: mov     cx,WatchBuf             ; Restore Watch
  223.         sub     WatchPos,cx             ; Position to Offset
  224.         mov     cx,MCBbuf               ; If NO More
  225.         sub     cx,di                   ; Blocks Remain
  226.         jcxz    WatchW                  ; Then Update WATCH
  227.         rep     movsb                   ; Else Copy Remaining
  228. WatchW: mov     es,WatchF               ; Update WATCH Next
  229.         mov     es:[104h],bp            ; Vector Position "vpos"
  230.         mov     di,220h                 ; Copy ChangeBlock Area
  231.         mov     cx,200h                 ; from the New WATCH
  232.         mov     si,WatchNew             ; ChangeBlock Table
  233.         rep     movsw
  234.         push    cs                      ; Restore Extra Segment
  235.         pop     es                      ; Register to Program
  236.         mov     si,WatchCode            ; Point to Code Table
  237.         add     dx,si                   ; Calculate Limit
  238.         call    ReCodeP                 ; ReCode TSR Vectors
  239.         cmp     byte ptr ReMflag,0      ; If TSR WAS Active
  240.         je      Code02                  ; Then Code 02 Blocks
  241.         mov     dx,offset Remarked      ; Else "ReEnAbled"
  242. ReTurn: ret
  243.  
  244. UnLoop: mov     byte ptr [si+1],1       ; Flag Vector as Active
  245.         add     bp,cx                   ; Increase WATCH "vpos"
  246.         rep     movsb                   ; Copy ChangeBlock 01
  247.         mov     cx,[si-8]               ; Recover Vector Number
  248.         mov     ch,2                    ; Start ChangeBlock 02
  249.         mov     es:[di],cx              ; with Block ID Vector 02
  250.         add     di,8                    ;  and Leave Rest Blank
  251.         push    di                      ; Preserve Destination,
  252.         push    ax                      ; Current Offset and
  253.         push    bx                      ; Segment for TSR Vector
  254.         xor     ch,ch                   ; Isolate Vector Number
  255.         mov     bx,cx                   ; Make Index to
  256.         shl     bx,1                    ; Double Word
  257.         shl     bx,1                    ; Original Vector
  258.         mov     di,WatchVec             ; WATCH Table
  259.         mov     ax,es:[di+bx]           ; Initialize Offset
  260.         mov     bx,es:[di+bx+2]         ; and Segment Words
  261.         mov     di,WatchBuf             ; Look for Latest
  262. PVloop: add     di,8                    ; Previous Until
  263.         cmp     di,BufferPos            ; If Reach Current
  264.         jnc     PVdone                  ; Then Done Looking
  265.         cmp     cl,es:[di]              ; Else If Wrong Number
  266.         jne     PVloop                  ; Or If a Vector
  267.         cmp     byte ptr es:[di+1],2    ; 02 ChangeBlock
  268.         je      PVloop                  ; Then Keep Looking
  269.         mov     ax,es:[di+2]            ; Else UpDate Offset
  270.         mov     bx,es:[di+4]            ; and Segment Until NO
  271.         jmp     short PVloop            ; More Previous Matches
  272. PVdone: mov     di,WatchCode            ; Point to Code for
  273.         add     di,dx                   ; Vector Number
  274.         mov     es:[di+7],bx            ; Set Segment and
  275.         mov     es:[di+5],ax            ; Offset for Patch to
  276.         mov     byte ptr es:[di+4],0EAh ; JMP to Previous Vector
  277.         pop     bx                      ; Restore Segment and
  278.         pop     ax                      ; Offset for Patch Code
  279.         mov     es:[di+2],bx            ; Store Segment and
  280.         mov     es:[di],ax              ; Offset for Patch Code
  281.         add     dx,10                   ; UpDate Code Index
  282.         pop     di                      ; Restore Position
  283.         jmp     ReLoop                  ; Loop Until Done
  284.  
  285. Code02: mov     es,WatchF               ; Point to WATCH
  286.         mov     di,BufferPos            ; ChangeBlock
  287.         sub     di,WatchBuf             ; ahead of TSR 02
  288.         add     di,220h                 ; ChangeBlock and
  289.         mov     si,WatchCode            ; Store Code Before Patch
  290.  
  291. Next02: add     di,8                    ; If Next Block is
  292.         cmp     byte ptr es:[di+1],2    ; NOT a 02 ChangeBlock
  293.         jne     Exit02                  ; Then End Code Storage
  294.         add     si,4                    ; Else Set Pointers to
  295.         add     di,2                    ; Code Byte Positions
  296.         mov     cx,6                    ; Copy six
  297.         rep     movsb                   ; Code Bytes
  298.         jmp     short Next02            ; Loop Until All Copied
  299. Exit02: push    cs                      ; Restore Extra Segment
  300.         pop     es                      ; Register to Program
  301.         mov     dx,offset Disabled      ; Return "DisAbled"
  302.         jmp     ReTurn
  303. Toggle  EndP
  304.  
  305. BP2PSP  Proc
  306.         push    bp                      ; Preserve
  307.         push    ax                      ; PSP and
  308.         push    bx                      ; General
  309.         push    cx                      ; Working
  310.         push    dx                      ; Registers
  311.         mov     cx,4                    ; Set Shift Register
  312.         cmp     ParLen,cx               ; If NOT 4 digit
  313.         jne     B2Pxit                  ; Then NOT a PSP
  314.         mov     si,offset Command       ; Else Point to PSP
  315.         mov     bx,4096                 ; Set Divide Register
  316. B2Plp:  xor     dx,dx                   ; Zero Extension
  317.         mov     ax,bp                   ; Get PSP Value
  318.         div     bx                      ; Calculate Digit
  319.         mov     bp,dx                   ; Store Remainder
  320.         or      al,30h                  ; If ASCII Digit
  321.         cmp     al,3Ah                  ; is Decimal
  322.         jc      B2Padj                  ; Then ASCII is Ok
  323.         add     al,7                    ; Else HEX Convert
  324.  
  325. B2Padj: push    cx                      ; Reset Shift
  326.         mov     cx,4                    ; Register and
  327.         shr     bx,cl                   ; Adjust Divisor
  328.         inc     si                      ; and PSP Position
  329.         pop     cx                      ; Restore Counter
  330.         cmp     al,ds:[si-1]            ; While Digits Match
  331.         loope   B2Plp                   ; Loop for 4 Digits
  332.  
  333. B2Pxit: pop     dx                      ; Restore
  334.         pop     cx                      ; General
  335.         pop     bx                      ; Working
  336.         pop     ax                      ; Registers
  337.         pop     bp                      ; and PSP Address
  338.         ret
  339. BP2PSP  EndP
  340.  
  341. DoFlags Proc
  342.         push    si                      ; Preserve
  343.         push    di                      ; Pointers and
  344.         push    es                      ; Segment Register
  345.         sub     dx,di                   ; If a Program
  346.         jz      ChkPgm                  ; Then Check It
  347.         xor     dx,dx                   ; Else Zero Flags
  348.         jmp     DFexit
  349. ChkPgm: mov     es,di                   ; Look in
  350.         mov     di,65h                  ; Program
  351.         mov     cx,4                    ; for ID of
  352.         mov     si,offset WatchID       ; an [F]Mark
  353.         rep     cmpsb                   ; If NOT [F]Mark
  354.         jne     Watch?                  ; Then Check Watch
  355.         jmp     DFexit                  ; Else Can't ReMark
  356. Watch?: mov     cx,11                   ; If "TSR WATCHER"
  357.         mov     di,81h                  ; Universal ID for
  358.         mov     si,offset WatchID+1     ; Watch is NOT in
  359.         rep     cmpsb                   ; Program Command Line
  360.         jne     ChkPSP                  ; Then Check PSP Command
  361.         mov     WatchF,es               ; Else Store Address
  362.         mov     di,es:[104h]            ;  and "vpos" Vector
  363.         mov     WatchPos,di             ; Position (Next Offset)
  364.         mov     di,WatchBuf             ; Point to Storage Area
  365.         push    ds                      ; Exchange Data and
  366.         push    es                      ; Extra Segment
  367.         pop     ds                      ; Registers and
  368.         pop     es                      ; Copy WATCH ChangeBlocks
  369.         mov     si,220h                 ;  and WATCH "origv" Vecs
  370.         mov     cx,400h                 ; Data Words
  371.         rep     movsw                   ; Into Storage
  372.         jmp     short DFexit
  373. ChkPSP: mov     bp,es                   ; If PSP Does NOT Match
  374.         call    BP2PSP                  ; Command Parameter
  375.         jne     ChkTSR                  ; Then Check By Name
  376.         mov     dx,-1                   ; Else Flag TSR Block
  377.         jmp     short DFexit
  378. ChkTSR: push    bx                      ; Preserve Index
  379.         mov     ax,3000h                ; If DOS
  380.         int     21h                     ; Version
  381.         pop     bx                      ; Index Restored
  382.         cmp     al,3                    ; is < 3
  383.         jc      DFexit                  ; Then NO Name
  384.         push    ds                      ; Else Point to
  385.         pop     es                      ; Data of
  386.         mov     di,MCBbuf               ; MCB Buffer
  387.         mov     cx,bx                   ; Set Counter to
  388.         shr     cx,1                    ; Words in Buffer
  389.         mov     ax,bp                   ; If TSR PSP is NOT
  390.         repne   scasw                   ; Found for Env Block
  391.         jne     DFexit                  ; Then NO Name
  392.         mov     ax,es:[di-4]            ; Else Point to
  393.         mov     es,ax                   ; Environment MCB
  394.         mov     di,es:[3]               ; Convert Length in
  395.         mov     cl,4                    ; Paragraphs to
  396.         shl     di,cl                   ; Bytes and
  397.         inc     ax                      ; Advance to
  398.         mov     es,ax                   ; Environment
  399.         mov     cx,di                   ; Set Counter
  400.         xor     di,di                   ; Scan Environment
  401.         xor     ax,ax                   ;  for Double Null
  402. ScanLp: repne   scasb                   ; If 1st Null NOT
  403.         dec     cx                      ; Followed by 2nd
  404.         scasb                           ; Then Continue
  405.         jcxz    DFexit                  ; Until Environment Ends
  406.         jne     ScanLp                  ; OR Until Double Null
  407.         mov     al,"."                  ; Scan for ".EXT"
  408.         repne   scasb                   ; If NO Extent DOT
  409.         jcxz    DFexit                  ; Then NO TSR Name
  410.         mov     cx,ParLen               ; Else Use Length
  411.         dec     di                      ; From ".EXT" DOT to
  412.         sub     di,cx                   ; Find Start of Name
  413.  
  414.         mov     si,offset Command       ; Compare TSR Names
  415.  
  416. NameLp: lodsb                           ; If Comand and
  417.         mov     ah,es:[di]              ; Environment
  418.         inc     di                      ; Subsequent
  419.         and     ah,5Fh                  ; UPPER case
  420.         cmp     ah,al                   ; Bytes Match
  421.         loope   NameLp                  ; Then Check All
  422.         jne     DFexit                  ; Else NO Name
  423.  
  424.         mov     dx,-1                   ; Flag Block if Match
  425. DFexit: push    cs                      ; Insure Data Segment
  426.         pop     ds                      ; Register is Restored
  427.         pop     es                      ; Restore Segment
  428.         pop     di                      ; Destination and
  429.         pop     si                      ; Source Pointers
  430.         mov     [si+bx+6],dx            ; Set MCB Flags
  431.         ret
  432. DoFlags EndP
  433.  
  434. ReCodeP Proc
  435.         cli                             ; Hold Interrupts
  436.         push    di                      ; Preserve Offset,
  437.         push    es                      ; Extra Segment
  438.         push    ax                      ; and General
  439.         push    bx                      ; Registers
  440.         push    cx
  441. ReCode: push    dx                      ; Preserve Limit
  442.         lodsw                           ; Get and Set
  443.         mov     di,ax                   ; Offset and
  444.         lodsw                           ; Segment for
  445.         mov     es,ax                   ; Code Exchange
  446.         mov     bx,es:[di]              ; Get Old and
  447.         lodsw                           ; New two Bytes
  448.         xchg    ax,bx                   ; Exchange Source
  449.         mov     ds:[si-2],ax            ; Code in Memory
  450.         mov     cx,es:[di+2]            ; from Old Code in
  451.         lodsw                           ; Destination Memory
  452.         xchg    ax,cx                   ; Leaving New Code 6
  453.         mov     ds:[si-2],ax            ; Bytes in Registers
  454.         mov     dx,es:[di+4]            ; [BX] has new 1 & 2
  455.         lodsw                           ; [CX] has new 3 & 4
  456.         xchg    ax,dx                   ; [DX] has new 5 & 6
  457.         mov     ds:[si-2],ax            ; Source has Old Code
  458.         mov     es:[di+4],dx            ; Store
  459.         mov     es:[di+2],cx            ; New
  460.         mov     es:[di],bx              ; Code
  461.         pop     dx
  462.         cmp     si,dx                   ; Exchange Watch Codes
  463.         jc      ReCode                  ; Until Reach Limit
  464.         sti                             ; Allow Interrupts
  465.         pop     cx                      ; Restore
  466.         pop     bx                      ; Working,
  467.         pop     ax                      ; Segment
  468.         pop     es                      ; and Offset
  469.         pop     di                      ; Registers
  470.         ret
  471. ReCodeP EndP
  472.  
  473. align   16
  474. buffer  equ     $
  475. Cseg    EndS
  476.         End     Main
  477.  
  478.         The ReMark replacement for DISABLE has been written as an
  479.         exercise in assembly language programming.  The credit for
  480.         this TSR management system belongs to Kim Kokkonen and the
  481.         TurboPower Software Company.   You are welcome to the code
  482.         and TurboPower Software to the glory.
  483.  
  484.                             from
  485.                                     Tom Gilbert's Heart & Mind
  486.