home *** CD-ROM | disk | FTP | other *** search
- ;************************
- PAGE 55,132 ;Format .LST listing file at 55 lines by 132 columns.
- TITLE TSRINT Version 0.4 Jan 20 1991 Robert Curtis Davis
- SUBTTL Introduction
- ;******************************************************************************
- ;
- ; TSRINT.ASM Version 0.4 Jan 20 91
- ; A part of the TBONES software package.
- ;
- ; Copyright (C) 1990, 1991 by Robert Curtis Davis,
- ; All Rights Reserved.
- ;
- ; DESCRIPTION:
- ; Terminate-and-Stay-Resident (TSR) Program Template
- ; for TSRs which are triggered by a specified Interrupt.
- ; Such TSRs are said to "hook" the specified Interrupt.
- ; This is a VERY basic program with few bells or whistles.
- ;
- ; PURPOSE:
- ; Provides a skeletal framework program for use in the design
- ; of your own Hooked Interrupt TSRs.
- ;
- ;
- ; E-Mail address:
- ; Internet: sonny@trantor.harris-atd.com
- ;
- ; US Mail:
- ; 430 Bahama Drive
- ; Indialantic, FL 32903
- ;
- ; Use this as a starting point in the design of your TSR programs.
- ;
- ;*************************************************************************
- ;
- ; Special thanks to David Kirschbaum, whose Toad Hall Tweaks significantly
- ; improved T-BONES' code:
- ;
- ;v0.11, Toad Hall Tweak (25 Nov 90)
- ; - Idiosyncracies: I like my constant labels in all-upper-case (HOOK)
- ; and my variable labels in lower-case (oldint).
- ; - Load ES directly with the PSP's environment segment.
- ; No need to pass it through AX.
- ; - Load AX as a word rather than byte-by-byte.
- ; - Let the compiler do the arithmetic (figuring length of TSR code)
- ; - Use PROC NEAR and PROC FAR (1) just for good programming practice,
- ; and (2) to clarify the difference between that FAR interrupt server
- ; and the other NEAR processes.
- ;**************************************************************************
- SUBTTL Code Segment (Resident)
- PAGE
- ;**************************************************************************
- ;
- CodeSeg segment
- assume CS:CodeSeg,DS:CodeSeg
- BeginDump EQU $ ;Roy Silvernail: Keep TASM 1.0 happy in
- ;computing number of resident paragraphs.
- ;
- org 2CH ;ORG in PSP to pick up env. segment.
- envseg label word ;environment segment v0.11
- ;
- org 100h ;ORG for all COM programs.
- ;
- Entry PROC NEAR ;v0.11
- jmp TSRinit ;Jump over resident portion and
- ;initialize things and make code
- ;from CodeSeg to TSRinit resident.
- Entry ENDP ;v0.11
- ;
- ; Old Interrupt Vector (Hooked Interrupt handler's original address)
- ; is stored here during TSR initialization:
- oldint dd ?
- ;
- ;*************************************************************************
- ;
- ; Define which BIOS or DOS Interrupt this TSR is to hook into:
- ; For this TSR Template, choose the PrtScrn Interrupt 05h:
- HOOK equ 05h ;Hooked Interrupt number.
- ;
- ; Any EQUates and storage areas needed by your New Interrupt handler
- ; can be placed here also:
- ;
- bellgate db 0 ;Gate closed (=1) when in Bell routine.
- ;Gate open (=0) when not in Bell routine.
- ;*************************************************************************
- ;
- ASSUME CS:CodeSeg,DS:NOTHING ;v0.11
- NewInt PROC FAR ;v0.11
- ;
- pushf ;Simulate interrupt call to oldint:
- cli
- call CS:oldint
- ;
- push DS ;Preserve DS.
- ;
- push CS ;Set up DS to CodeSeg v0.11
- pop DS
- ASSUME DS:CodeSeg
- ;
- ; The Bell "gate" shenanighans below keeps the MASSIVE number of
- ; interrupts that can occur during the computer-scale
- ; long, LONG time needed to ring the bell from overflowing the
- ; system's internal stack (because of so many Int 10 calls) when
- ; you hold down the Print Screen key for too long.
- ;
- ; This "gate" technique is a good one to keep in
- ; mind whenever you have a code region in an interrupt handler
- ; that needs to be protected from re-entry:
- ;
- cmp bellgate,0 ;Clear to enter routine?
- jne BusyExit ;If gate not open, Exit.
- mov bellgate,1 ;Else, close gate & enter routine.
- ;
- ; Allow other interrupts:
- sti
- ;
- push ax ;Entry to TSR Routine:
- push bx ;Save all registers (DS is already pushed).
- push cx
- push dx
- push si
- push di
- push bp
- push es
- ;
- ;*************************************************************************
- ; Your code for the New Hooked Interrupt Handler TSR routine
- ; GOES HERE:
- ; ( Here, a dummy routine has been placed which simply rings the
- ; terminal Bell whenever the TSR is triggered. )
- ;
- ; Announce this dummy TSR's trigger by a Bell signal:
- ;
- mov al,07h ;al = ASCII Bell.
- mov bh,0 ;Video page.
- mov cx,1 ;No. of bytes to write.
- mov ah,0Eh ;BIOS Int10,OEh=TTY Screen.
- Int 10h ;Write ASCII Bell to screen.
- ;
- ; End of Hooked Interrupt handler routine.
- ;***************************************************************************
- Exit:
- mov bellgate,0
- pop es ;Restore all registers
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ;
- BusyExit:
- pop ds
- iret
- ;
- NewInt ENDP ;v0.11
- ; -END OF TSR's RESIDENT CODE-
- ; Only the code above will remain locked in memory after the
- ; TSR initialization performed below.
- ;*************************************************************************
- SUBTTL TSR Initialization Code (Nonresident). The "BOOSTER".
- PAGE
- ;*************************************************************************
- ; BEGINNING OF TSR's INITIALIZATION CODE:
- ; The following code is protected in RAM *ONLY* during initialization
- ; of the TSR that occurs when the TSR name is first entered
- ; at the DOS command level. All the following code is abandonned
- ; unprotected in RAM after the Terminate-and-Stay-Resident
- ; call to Function 31h of DOS Interrupt 21h below. This
- ; is allowed to happen because the code's work is complete at
- ; that point. The code will be overwritten as the memory which
- ; it temporarily occupied is needed by DOS for other purposes.
- ; I have seen this following section of code colorfully called
- ; the TSR "Booster". And this is quite appropriate since the code
- ; sits here, strapped to the very end of the code. It is of use
- ; only during the initialization of the TSR, when it is used to
- ; put the TSR into "orbit" (residency), and after which it is
- ; "jettisoned" by the DOS TSR call, Int 21h, Fcn 31h.
- ;
- TSRinit PROC NEAR ;v0.11
- EndDump EQU $ ;Roy Silvernail: Keep TASM 1.0 happy in
- ;computing number of resident paragraphs.
- ;
- ; TSRINT requires DOS Version 2 or later. Be sure DOS Version 1 not used:
- ;
- ; Get DOS Version Number:
- mov ah,30h ;Fcn 30h = Get DOS Version
- int 21h ;DOS Version = al.ah
- ;
- ; If this is DOS v.1.x, this TSR cannot work, so go print message
- ; and exit without installing:
- cmp al,1 ;Is this DOS Version 1.x?
- ja DOSverOK ;If not, DOS version is OK.
- ;
- DOSver1:
- ;If here, DOS Version 1.x is being run and TSR won't work, so bail out:
- ;
- mov dx,OFFSET BailOutMsg ;TBONES needs DOS 2.x or later.
- mov ah,09h ;Say we're sorry, but NO GO
- int 21h ;via DOS.
- pop bx ;Clear stack.
- int 20h ;Terminate without installing
- ;in only way DOS 1.x knows.
- ;
- BailOutMsg:
- db 0Dh,0Ah
- db 'Sorry. TSRBONES needs DOS v.2+. You have v.1.x'
- db 0Dh,0Ah,'$'
- ;
- DOSverOK:
- ; If here, DOS version is 2.0 or later. TSR can work, so proceed.
- ;
- ; To conserve memory, release from memory the copy of the DOS
- ; Environment passed to this TSR (this, of course, assumes that
- ; your Interrupt handler will not be written to reference this
- ; de-allocated Environment. If you are going to need it, don't
- ; de-allocate it.):
- ;
- mov ES,envseg ;get environment segment v0.11
- ;from Program Segment Prefix.
- mov ah,49h ;DOS Fcn 49h = Release Memory
- int 21h ;Release it via DOS interrupt.
- ;
- ; In order to make the TSR's command name show under the "owner" column in
- ; the "MAPMEM" command of Kim Kokkonen's excellent TSR Mark/Release
- ; package, allocate a tiny 1-paragraph "Pseudo-Environment" here which
- ; contains nothing but the TSR name. This only costs 16 bytes in
- ; TSR resident code:
- ;
- ; Allocate the memory needed by the tiny 'Pseudo-Environment":
- mov bx,1 ;Allocate one parag. (16bytes)
- mov ah,48h ;and return allocation
- int 21h ;segment in ax via DOS call.
- ;
- mov ES,ax ;Pseudo-Env. Segment to ES.
- mov si,OFFSET PseudoEnv ;si=source string OFFSET.
- mov di,0 ;di=destination string OFFSET.
- mov cx,ENVLNGTH ;cx=Bytes in Pseudo-Env.string.
- cld ;Forward string move direction.
- rep movsb ;Move Pseudo-Env. string @ DS:si to ES:di
- ;
- ; Set PSP's Environment segment pointer to point to tiny Pseudo-Environment.
- mov envseg,ES
- ;
- ;*****************************************************************************
- ; Hook the Interrupt:
- ;
- ; Get Old Interrupt Vector:
- mov ax,3500H + HOOK ;AH=DOS Fcn 35H, Get Int Vec
- ;AL=Hooked Interrupt number
- int 21h ;Old Int Vect.in ES:BX via DOS.
- ;
- ; Save Old Interrupt Vector:
- mov Word Ptr oldint,bx ;Save Offset of Old Interrupt.
- mov Word Ptr oldint+2,ES ;save old interrupt seg v0.11
- ;
- ; Install New Interrupt Vector to this TSR's "NewInt:" Label:
- mov ax,2500H + HOOK ;AH=DOS Fcn 25H=Set Int vec
- ; v0.11
- ;AL=Hooked Interrupt number
- mov dx,offset NewInt ;dx=Offset of New Int Handler.
- int 21h ;Set New Int via DOS.
- ;
- ; Announce the TSR's Installation:
- mov dx,Offset InstallMsg ;dx points to message.
- mov ah,09h ;DOS Fcn. 09h=Display String.
- int 21h ;Display String via DOS.
- ;
- ; Lock resident code in memory via Terminate-and-Stay-Resident (TSR) DOS call:
- ;
- ;v0.11 DX requires size of resident code (in 16-byte paragraphs)
- ; This awkward construct is required to keep
- ; DOS Function 31h happy. Notice how we first compute
- ; the length of the TSR code in bytes [i.e., end of
- ; the TSR code (EndDump) minus start of the TSR code
- ; (0, our BeginDump)], round it up to the next whole paragraph ( + 0Fh),
- ; and then divide by 16 (SHR 4) to get the number of resident paragraphs:
- ;
- ; Thanks to Roy Silvernail, who made TASM 1.0 happy by defining the
- ; constants BeginDump and EndDump, and using them in the
- ; following statement:
- ;
- mov dx,(EndDump-BeginDump+0FH)/16 ;DX = No.Paragraphs.
- ;
- mov ah,31h ;DOS FCN 31h = TSR Call.
- int 21h ;Go Resident via DOS TSR call.
- ;Goodbye, Booster!
- ;
- PseudoEnv: DB ' ',0,0,1,0,'TSRINT',0
- ENVLNGTH EQU $-PseudoEnv
- ;
- InstallMsg:
- db 0Dh,0Ah
- db 'YOUR HOOKED INTERRUPT TSR IS NOW INSTALLED.'
- db 0Dh,0Ah
- db 'Hooked Interrupt => PrtScrn (Int 05h)'
- db 0Dh,0Ah,0Dh,0Ah
- db 'TSRINT Version 0.4'
- db 0Dh,0Ah
- db 'Copyright (C) 1990, 1991 by Robert Curtis Davis'
- db 0Dh,0Ah,'$'
- ;
- TSRinit ENDP ;v0.11
-
- CodeSeg ends
- end Entry
- ;
- ;*****************************************************************************
-