home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / SYSUTL / TSRWRK32.ZIP / REMARK.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-06-06  |  15.6 KB  |  530 lines

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