home *** CD-ROM | disk | FTP | other *** search
- Title ReMark.ASM -- Replaces TurboPower DISABLE Version 2.8
- 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
- add si,2 ; Advance to Code and
- mov cx,3 ; Copy the Stored Code
- rep movsw ; into the Watch Code
- 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
- push cs ; Restore Extra Segment
- pop es ; Register to Program
- 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
- add di,2 ; Code Byte Positions
- mov cx,6 ; Copy six
- rep movsb ; Code Bytes
- jmp short Next02 ; Loop Until All Copied
- Exit02: push cs ; Restore Extra Segment
- pop es ; Register to Program
- 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
- push ds ; Else Point to
- pop es ; 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: push cs ; Insure Data Segment
- pop ds ; Register is Restored
- 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
-