home *** CD-ROM | disk | FTP | other *** search
- Title ReMark.ASM -- Replaces TurboPower DISABLE Version 2.8
- ;v3.2 Toad Hall Tweak
-
- CSEG Segment Public Para ;Version 3.1 30-May-1989 - 03:10
- ASSUME CS:CSEG,DS:CSEG
-
- Org 0100h
-
- Main Proc Far
-
- Jmp Start
-
- UsageMsg DB 13,' ',9,10
- DB 'ReMark replaces DISABLE ver 2.8 by TurboPower Software',13,10,9
- DB '======================================================',13,10,9
- DB 'ReMark, like DISABLE, allows ReEnabling a DisAbled TSR',13,10,9
- DB 'or DisAbling an active TSR while leaving it in memory.',13,10,10,9
- DB 'Watch MUST be installed ahead of the TSR to ReMark.',13,10,10,9
- DB 'If ShowTSRs displays an "owner" name of "command", you',13,10,9
- DB 'MUST use the PSP address for the TSR which is reported',13,10,9
- DB 'in the first column of the line for the TSR displayed.',13,10,10,9
- DB 'ReMark accepts the following command line syntax:',13,10,10,9,9
- DB 'ReMark [TSRname or PSPaddress][/option]',13,10,10,9,'Options:'
- DB 9,9,9,'/D(eActivate)',13,10,9,9,9,9,9,'/A(ctivate)',13,10,10,9
- DB 'If NO "/"option is entered, ReMark will show STATUS.',13,10,10,9
- DB 'ReMark with NO VALID TSR/PSP will display this help.'
-
- crlf DB 13,10,"$",8,32,26 ; You can >TYPE ReMark.COM
-
- nowatch$ DB 9,9,9,' NO'
- watchid$ DB ' TSR WATCHER' ; Watch identifier @ 81h
- DB ' is installed!$'
-
- noname$ DB 9,9,9,9,'Cannot find requested TSR='
- command$ DB 9 DUP('$') ; Command Parameter
- DB 9 DUP('!'),'$' ; Invalid Extension
- alreadyM DB ' Already$'
- isactive DB ' is Active$'
- nospaceM DB ", due to WATCH full, can't be"
- disabled$ DB ' DisAbled$'
- remarked$ DB ' ReEnAbled$'
-
- reMflag DB ? ; 0 if Active or 1 if DisAbled
- reQflag DB 0 ; 0 for STATUS, 1="A" or -1="D"
-
- parlen DW 0 ; Length of Command Parameter
- errlvl DW 4C00h ; Used on Exit to DOS
- watchF DW 0 ; PSP of Watch if found
- watchpos DW ? ; Value of WATCH "vpos" @[104h]
- bufferpos DW ? ; Working position Offset/Value
-
- WATCHCODE equ offset BUFFER ; Storage for Patch/Restore Code
- WATCHBUF equ WATCHCODE + 100h ; Watch VectorChange Area Copy
- WATCHVEC equ WATCHBUF + 400h ; Storage for WATCH "origv" Vecs
- WATCHNEW equ WATCHVEC + 400h ; New Watch VectorChange Buffer
- MCBBUF equ WATCHNEW + 400h ; Storage for MCB records
-
- Start: xor ax,ax ; Zero
- mov cx,2048 ; data
- mov di,WATCHCODE ; buffer
- rep stosw ; words
- mov si,81h ; Get User
- mov di,offset command$ ; Command
-
- Ploop: lodsb ; If Byte
- cmp al,13 ; is End
- je Pexit ; Then Exit
- cmp al,"!" ; Else Skip
- jc Ploop ; Spaces or Below
- cmp al,"a" ; Insure that
- jb Pluck ; Alphabetic
- cmp al,"z" ; Characters
- ja Pluck ; Become
- and al,5Fh ; UPPER case
- Pluck: cmp al,"/" ; If Switch
- je Parse ; Then Parse
- stosb ; Else Store
- jmp short Ploop ; Name or PSP
- Parse: lodsb ; Get Switch
- and al,5Fh ; UPPER case
- cmp al,"A" ; If NOT "A"ctivate
- jne Pl4aD ; Then Check "D"eActivate
- inc reQflag ; Else "A" ReQuest
- Pl4aD: cmp al,"D" ; If NOT "D"eActivate
- jne Ploop ; Then Loop Until End
- dec reQflag ; Else "D" ReQuest
- jmp short Ploop ; and Loop Until End
-
- Pexit: sub di,offset command$ ; If any Command
- jnz SaveL ; Then Save Length
- jmp Usage ; Else Give Help
-
- SaveL: mov parlen,di ; Store Length
- mov ah,52h ; Undocumented
- int 21h ; Function
- mov di,ES:[bx-2] ; obtains
- mov ES,di ; MCB of DOS
- inc di ; Config.Sys
- mov si,MCBBUF ; Initialize Source and
- xor bx,bx ; Basic Index Pointers
-
- MCBlp: add di,ES:[3] ; Advance so as to
- mov ES,di ; Point to MCB and
- inc di ; Next Paragraph
- mov [si+bx+0],es ; Store MCB
- mov dx,ES:[1] ; Get and Store
- mov [si+bx+2],dx ; Block Address
- mov ax,ES:[3] ; and Block
- mov [si+bx+4],ax ; Length
- call DoFlags ; Copy Watch/Flag TSR
- add bx,8 ; Advance to Next and
- cmp byte ptr ES:[0],"Z" ; Loop Until Last MCB
- jne MCBlp
- push DS ; Restore Extra Segment
- pop ES ; Register to DATA
- cmp word ptr watchF,0 ; If Any Watch was Found
- jnz IfTSR ; Then Check If TSR Found
- mov dx,offset nowatch$ ; Else NO TSR WATCHER
- mov byte ptr errlvl,1 ; Error Level and
- mov ah,9 ; Warning Message
- int 21h ; Give Help on Exit
- jmp short Usage
-
- IfTSR: mov ax,-1 ; Scan for FFFFh
- mov di,si ; in MCB Buffer
- mov cx,bx ; Record
- shr cx,1 ; Words
- repne scasw ; If None
- jne NoFind ; Then NO TSR
-
- mov bx,ES:[di-6] ; Else Get PSP
- mov di,WATCHBUF ; Point to Watch Copy
- mov cx,watchpos ; Set Counter to
- shr cx,1 ; Number of Words
- WatchS: repne scasw ; If NO More Blocks
- jcxz NoFind ; Then NO TSR Found
-
- cmp bx,ES:[di] ; Else If NOT PSP
- jne WatchS ; Then Search On
-
- add di,6 ; Else Save Position of
- mov bufferpos,di ; First TSR ChangeBlock
- mov ax,ES:[di] ; Get Block ID and Set
- mov reMflag,ah ; 0 to Dis or 1 to ReEn Able
- mov ah,9
- mov dx,offset crlf ; Display New Line
- int 21h
- mov dx,offset command$ ; Display Command
- int 21h
- call Toggle ; Set Status
- mov ah,9 ; Display New
- int 21h ; Status and
- mov dx,offset crlf ; New Line
- int 21h ; Before Exit
- jmp short Exit
-
- NoFind: mov ah,9 ; Display TSR
- mov dx,offset noname$ ; NOT Found
- int 21h ; Message and
- mov byte ptr errlvl,2 ; Set Error Level
- Usage: mov ah,9 ; Display ReMark
- mov dx,offset UsageMsg ; Usage Message
- int 21h
- Exit: mov ax,errlvl ; Error Level
- int 21h ; Exit to DOS
- Main EndP
-
- Toggle Proc
- mov bp,watchpos ; Copy Old WATCH "vpos"
- xor dx,dx ; Zero ChangeCode Index
- mov si,WATCHBUF ; Copy WATCH Blocks
- mov cx,bufferpos ; from 1st through
- sub cx,si ; TSR ID WATCH Block
- mov di,WATCHNEW ; Into NEW WATCH Buffer
- add watchpos,si ; and Set Limit for Loop
- rep movsb
- mov al,reQflag ; If a "/A" or "/D"
- or al,al ; Parameter ReQuest
- jnz ReQest ; Then Process ReQuest
-
- add al,reMflag ; Else Report
- mov dx,offset isactive ; "is Active"
- jz RePort ; or
- mov dx,offset disabled$ ; " DisAbled"
- RePort: jmp ReTurn ; Current Status
-
- ReQest: add al,reMflag ; If Combined Status
- cmp al,2 ; and ReQuest => 2
- jnc ReLoop ; Then Something to Do
-
- mov dx,offset alreadyM ; Else Report "Already"
- push ax ; Preserving Combined
- mov ah,9 ; Flags in AL
- int 21h ; Register
- pop ax ; Report
- mov dx,offset disabled$ ; "DisAbled"
- cmp al,1 ; Unless for
- jne RePort ; Flags = 1
- mov dx,offset isactive ; "is Active"
- jmp short RePort
-
- ReLoop: mov ax,[si] ; Get Block ID
- cmp ax,-1 ; If New TSR
- je ReDone ; Or If End
- cmp si,watchpos ; of Blocks
- jnc ReDone ; Then Exit Loop
- cmp ah,1 ; Else If to be
- je LoopOk ; ReEnAbled
- cmp si,WATCHVEC ; Or If More Room
- jc LoopOk ; Then Continue
- mov byte ptr errlvl,3 ; Else Set Error Level 3 for
- mov dx,offset nospaceM ; No Space to DisAble and
- jmp short ReTurn ; Error Exit from Toggle
-
- LoopOk: mov cx,8 ; Set Move Counter
- mov bx,[si+4] ; Get Segment and
- mov ax,[si+2] ; Offset of Vector
- cmp byte ptr reMflag,0 ; If Zero to DisAble
- je UnLoop ; Then DisAble Vector
- mov byte ptr [si+1],0 ; Else Flag ReEnAbled
- sub bp,cx ; Reduce WATCH "vpos"
- rep movsb ; Copy Vector Block
- push di ; Preserve Position
- mov di,WATCHCODE ; While Storing Code
- add di,dx ; Contained in Change
- stosw ; Vector for Segment
- mov ax,bx ; and Offset Obtained
- stosw ; from Vector Block
- ;v3.2 add si,2 ; Advance to Code and
- ;v3.2 mov cx,3 ; Copy the Stored Code
- ;v3.2 rep movsw ; into the Watch Code
- inc si ;advance to code.. v3.2
- inc si ;v3.2
- movsw ;v3.2
- movsw
- movsw
- add dx,10 ; Update Code Index
- pop di ; Restore Position
- jmp short ReLoop ; Loop Until Vectors Done
-
- ReDone: mov cx,WATCHBUF ; Restore Watch
- sub watchpos,cx ; Position to Offset
- mov cx,MCBBUF ; If NO More
- sub cx,di ; Blocks Remain
- jcxz WatchW ; Then Update WATCH
- rep movsb ; Else Copy Remaining
- WatchW: mov ES,watchF ; Update WATCH Next
- mov ES:[104h],bp ; Vector Position "vpos"
- mov di,220h ; Copy ChangeBlock Area
- mov cx,200h ; from the New WATCH
- mov si,WATCHNEW ; ChangeBlock Table
- rep movsw
- mov si,CS ; Restore Extra Segment v3.2
- mov ES,si ; Register to Program v3.2
- mov si,WATCHCODE ; Point to Code Table
- add dx,si ; Calculate Limit
- call ReCodeP ; ReCode TSR Vectors
- cmp byte ptr reMflag,0 ; If TSR WAS Active
- je Code02 ; Then Code 02 Blocks
-
- mov dx,offset remarked$ ; Else "ReEnAbled"
- ReTurn: ret
-
- UnLoop: mov byte ptr [si+1],1 ; Flag Vector as Active
- add bp,cx ; Increase WATCH "vpos"
- rep movsb ; Copy ChangeBlock 01
- mov cx,[si-8] ; Recover Vector Number
- mov ch,2 ; Start ChangeBlock 02
- mov ES:[di],cx ; with Block ID Vector 02
- add di,8 ; and Leave Rest Blank
- push di ; Preserve Destination,
- push ax ; Current Offset and
- push bx ; Segment for TSR Vector
- xor ch,ch ; Isolate Vector Number
- mov bx,cx ; Make Index to
- shl bx,1 ; Double Word
- shl bx,1 ; Original Vector
- mov di,WATCHVEC ; WATCH Table
- mov ax,ES:[di+bx] ; Initialize Offset
- mov bx,ES:[di+bx+2] ; and Segment Words
- mov di,WATCHBUF ; Look for Latest
- PVloop: add di,8 ; Previous Until
- cmp di,bufferpos ; If Reach Current
- jnc PVdone ; Then Done Looking
- cmp cl,ES:[di] ; Else If Wrong Number
- jne PVloop ; Or If a Vector
- cmp byte ptr ES:[di+1],2 ; 02 ChangeBlock
- je PVloop ; Then Keep Looking
- mov ax,ES:[di+2] ; Else UpDate Offset
- mov bx,ES:[di+4] ; and Segment Until NO
- jmp short PVloop ; More Previous Matches
-
- PVdone: mov di,WATCHCODE ; Point to Code for
- add di,dx ; Vector Number
- mov ES:[di+7],bx ; Set Segment and
- mov ES:[di+5],ax ; Offset for Patch to
- mov byte ptr ES:[di+4],0EAh ; JMP to Previous Vector
- pop bx ; Restore Segment and
- pop ax ; Offset for Patch Code
- mov ES:[di+2],bx ; Store Segment and
- mov ES:[di],ax ; Offset for Patch Code
- add dx,10 ; UpDate Code Index
- pop di ; Restore Position
- jmp ReLoop ; Loop Until Done
-
- Code02: mov ES,watchF ; Point to WATCH
- mov di,bufferpos ; ChangeBlock
- sub di,WATCHBUF ; ahead of TSR 02
- add di,220h ; ChangeBlock and
- mov si,WATCHCODE ; Store Code Before Patch
-
- Next02: add di,8 ; If Next Block is
- cmp byte ptr ES:[di+1],2 ; NOT a 02 ChangeBlock
- jne Exit02 ; Then End Code Storage
- add si,4 ; Else Set Pointers to
- ;v3.2 add di,2 ; Code Byte Positions
- ; mov cx,6 ; Copy six
- ; rep movsb ; Code Bytes
- inc di ;v3.2
- inc di
- movsw
- movsw
- movsw
- jmp short Next02 ; Loop Until All Copied
-
- Exit02:
- ;v3.2 push CS ; Restore Extra Segment
- ;v3.2 pop ES ; Register to Program
- mov dx,CS ;restore ES v3.2
- mov ES,dx
- mov dx,offset disabled$ ; Return "DisAbled"
- jmp ReTurn
- Toggle EndP
-
- BP2PSP Proc
- push bp ; Preserve
- push ax ; PSP and
- push bx ; General
- push cx ; Working
- push dx ; Registers
- mov cx,4 ; Set Shift Register
- cmp parlen,cx ; If NOT 4 digit
- jne B2Pxit ; Then NOT a PSP
-
- mov si,offset command$ ; Else Point to PSP
- mov bx,4096 ; Set Divide Register
- B2Plp: xor dx,dx ; Zero Extension
- mov ax,bp ; Get PSP Value
- div bx ; Calculate Digit
- mov bp,dx ; Store Remainder
- or al,30h ; If ASCII Digit
- cmp al,3Ah ; is Decimal
- jc B2Padj ; Then ASCII is Ok
- add al,7 ; Else HEX Convert
-
- B2Padj: push cx ; Reset Shift
- mov cx,4 ; Register and
- shr bx,cl ; Adjust Divisor
- inc si ; and PSP Position
- pop cx ; Restore Counter
- cmp al,DS:[si-1] ; While Digits Match
- loope B2Plp ; Loop for 4 Digits
-
- B2Pxit: pop dx ; Restore
- pop cx ; General
- pop bx ; Working
- pop ax ; Registers
- pop bp ; and PSP Address
- ret
- BP2PSP EndP
-
- DoFlags Proc
- push si ; Preserve
- push di ; Pointers and
- push ES ; Segment Register
- sub dx,di ; If a Program
- jz ChkPgm ; Then Check It
- xor dx,dx ; Else Zero Flags
- jmp DFexit
-
- ChkPgm: mov ES,di ; Look in
- mov di,65h ; Program
- mov cx,4 ; for ID of
- mov si,offset watchid$ ; an [F]Mark
- rep cmpsb ; If NOT [F]Mark
- jne Watch? ; Then Check Watch
- jmp DFexit ; Else Can't ReMark
-
- Watch?: mov cx,11 ; If "TSR WATCHER"
- mov di,81h ; Universal ID for
- mov si,offset watchid$+1 ; Watch is NOT in
- rep cmpsb ; Program Command Line
- jne ChkPSP ; Then Check PSP Command
- mov watchF,ES ; Else Store Address
- mov di,ES:[104h] ; and "vpos" Vector
- mov watchpos,di ; Position (Next Offset)
- mov di,WATCHBUF ; Point to Storage Area
- push DS ; Exchange Data and
- push ES ; Extra Segment
- pop DS ; Registers and
- pop ES ; Copy WATCH ChangeBlocks
- mov si,220h ; and WATCH "origv" Vecs
- mov cx,400h ; Data Words
- rep movsw ; Into Storage
- jmp short DFexit
-
- ChkPSP: mov bp,es ; If PSP Does NOT Match
- call BP2PSP ; Command Parameter
- jne ChkTSR ; Then Check By Name
- mov dx,-1 ; Else Flag TSR Block
- jmp short DFexit
-
- ChkTSR: push bx ; Preserve Index
- mov ax,3000h ; If DOS
- int 21h ; Version
- pop bx ; Index Restored
- cmp al,3 ; is < 3
- jc DFexit ; Then NO Name
-
- mov ax,DS ; Else Point to v3.2
- mov ES,ax ; Data of
- mov di,MCBBUF ; MCB Buffer
- mov cx,bx ; Set Counter to
- shr cx,1 ; Words in Buffer
- mov ax,bp ; If TSR PSP is NOT
- repne scasw ; Found for Env Block
- jne DFexit ; Then NO Name
-
- mov ax,ES:[di-4] ; Else Point to
- mov ES,ax ; Environment MCB
- mov di,ES:[3] ; Convert Length in
- mov cl,4 ; Paragraphs to
- shl di,cl ; Bytes and
- inc ax ; Advance to
- mov ES,ax ; Environment
- mov cx,di ; Set Counter
- xor di,di ; Scan Environment
- xor ax,ax ; for Double Null
- ScanLp: repne scasb ; If 1st Null NOT
- dec cx ; Followed by 2nd
- scasb ; Then Continue
- jcxz DFexit ; Until Environment Ends
- jne ScanLp ; OR Until Double Null
-
- mov al,"." ; Scan for ".EXT"
- repne scasb ; If NO Extent DOT
- jcxz DFexit ; Then NO TSR Name
-
- mov cx,parlen ; Else Use Length
- dec di ; From ".EXT" DOT to
- sub di,cx ; Find Start of Name
-
- mov si,offset command$ ; Compare TSR Names
-
- NameLp: lodsb ; If Comand and
- mov ah,ES:[di] ; Environment
- inc di ; Subsequent
- and ah,5Fh ; UPPER case
- cmp ah,al ; Bytes Match
- loope NameLp ; Then Check All
- jne DFexit ; Else NO Name
-
- mov dx,-1 ; Flag Block if Match
- DFexit:
- ;v3.2 push CS ; Insure Data Segment
- ;v3.2 pop DS ; Register is Restored
- mov di,CS ;restore DS v3.2
- mov DS,di ;v3.2
- pop ES ; Restore Segment
- pop di ; Destination and
- pop si ; Source Pointers
- mov [si+bx+6],dx ; Set MCB Flags
- ret
- DoFlags EndP
-
- ReCodeP Proc
- cli ; Hold Interrupts
- push di ; Preserve Offset,
- push ES ; Extra Segment
- push ax ; and General
- push bx ; Registers
- push cx
- ReCode: push dx ; Preserve Limit
- lodsw ; Get and Set
- mov di,ax ; Offset and
- lodsw ; Segment for
- mov ES,ax ; Code Exchange
- mov bx,ES:[di] ; Get Old and
- lodsw ; New two Bytes
- xchg ax,bx ; Exchange Source
- mov DS:[si-2],ax ; Code in Memory
- mov cx,ES:[di+2] ; from Old Code in
- lodsw ; Destination Memory
- xchg ax,cx ; Leaving New Code 6
- mov DS:[si-2],ax ; Bytes in Registers
- mov dx,ES:[di+4] ; [BX] has new 1 & 2
- lodsw ; [CX] has new 3 & 4
- xchg ax,dx ; [DX] has new 5 & 6
- mov DS:[si-2],ax ; Source has Old Code
- mov ES:[di+4],dx ; Store
- mov ES:[di+2],cx ; New
- mov ES:[di],bx ; Code
- pop dx
- cmp si,dx ; Exchange Watch Codes
- jc ReCode ; Until Reach Limit
-
- sti ; Allow Interrupts
- pop cx ; Restore
- pop bx ; Working,
- pop ax ; Segment
- pop ES ; and Offset
- pop di ; Registers
- ret
- ReCodeP EndP
-
- align 16
- BUFFER equ $
-
- CSEG EndS
- End Main
-
- The ReMark replacement for DISABLE has been written as an
- exercise in assembly language programming. The credit for
- this TSR management system belongs to Kim Kokkonen and the
- TurboPower Software Company. You are welcome to the code
- and TurboPower Software to the glory.
-
- from
- Tom Gilbert's Heart & Mind