home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / tbones07.zip / TSRINT.ASM < prev    next >
Assembly Source File  |  1991-01-20  |  12KB  |  310 lines

  1. ;************************
  2. PAGE    55,132          ;Format .LST listing file at 55 lines by 132 columns.
  3. TITLE   TSRINT Version 0.4 Jan 20 1991 Robert Curtis Davis
  4. SUBTTL  Introduction
  5. ;******************************************************************************
  6. ;
  7. ;       TSRINT.ASM      Version 0.4     Jan 20 91
  8. ;       A part of the TBONES software package.
  9. ;
  10. ;       Copyright (C) 1990, 1991 by Robert Curtis Davis,
  11. ;    All Rights Reserved.
  12. ;
  13. ;    DESCRIPTION:
  14. ;    Terminate-and-Stay-Resident (TSR) Program Template
  15. ;    for TSRs which are triggered by a specified Interrupt.
  16. ;    Such TSRs are said to "hook" the specified Interrupt.
  17. ;       This is a VERY basic program with few bells or whistles.
  18. ;
  19. ;    PURPOSE:
  20. ;    Provides a skeletal framework program for use in the design
  21. ;    of your own Hooked Interrupt TSRs.
  22. ;
  23. ;        
  24. ;        E-Mail address:
  25. ;                     Internet: sonny@trantor.harris-atd.com
  26. ;
  27. ;                      US Mail:
  28. ;                               430 Bahama Drive
  29. ;                               Indialantic, FL 32903
  30. ;
  31. ;    Use this as a starting point in the design of your TSR programs.
  32. ;
  33. ;*************************************************************************
  34. ;
  35. ; Special thanks to David Kirschbaum, whose Toad Hall Tweaks significantly
  36. ; improved T-BONES' code:
  37. ;
  38. ;v0.11, Toad Hall Tweak (25 Nov 90)
  39. ; - Idiosyncracies: I like my constant labels in all-upper-case (HOOK)
  40. ;   and my variable labels in lower-case (oldint).
  41. ; - Load ES directly with the PSP's environment segment.
  42. ;   No need to pass it through AX.
  43. ; - Load AX as a word rather than byte-by-byte.
  44. ; - Let the compiler do the arithmetic (figuring length of TSR code)
  45. ; - Use PROC NEAR and PROC FAR  (1) just for good programming practice,
  46. ;   and (2) to clarify the difference between that FAR interrupt server
  47. ;   and the other NEAR processes.
  48. ;**************************************************************************
  49. SUBTTL  Code Segment (Resident)
  50. PAGE
  51. ;**************************************************************************
  52. ;
  53. CodeSeg         segment
  54.                 assume CS:CodeSeg,DS:CodeSeg
  55. BeginDump       EQU     $       ;Roy Silvernail: Keep TASM 1.0 happy in
  56.                                 ;computing number of resident paragraphs.
  57. ;
  58.         org    2CH        ;ORG in PSP to pick up env. segment.
  59. envseg        label    word        ;environment segment        v0.11
  60. ;
  61.         org    100h        ;ORG for all COM programs.
  62. ;
  63. Entry           PROC    NEAR            ;v0.11
  64.         jmp    TSRinit        ;Jump over resident portion and
  65.                     ;initialize things and make code
  66.                     ;from CodeSeg to TSRinit resident.
  67. Entry           ENDP                    ;v0.11
  68. ;  
  69. ;    Old Interrupt Vector (Hooked Interrupt handler's original address) 
  70. ;    is stored here during TSR initialization:
  71. oldint        dd    ?    
  72. ;
  73. ;*************************************************************************
  74. ;
  75. ; Define which BIOS or DOS Interrupt this TSR is to hook into:
  76. ; For this TSR Template, choose the PrtScrn Interrupt 05h:
  77. HOOK        equ    05h            ;Hooked Interrupt number.
  78. ;
  79. ;    Any EQUates and storage areas needed by your New Interrupt handler
  80. ;    can be placed here also:
  81. ;
  82. bellgate    db    0    ;Gate closed (=1) when in Bell routine.
  83.                 ;Gate open (=0) when not in Bell routine.
  84. ;*************************************************************************
  85. ;
  86.         ASSUME    CS:CodeSeg,DS:NOTHING    ;v0.11
  87. NewInt          PROC    FAR                     ;v0.11
  88. ;
  89.                 pushf                   ;Simulate interrupt call to oldint:
  90.                 cli
  91.                 call    CS:oldint
  92. ;
  93.                 push    DS              ;Preserve DS.
  94. ;
  95.                 push    CS              ;Set up DS to CodeSeg   v0.11
  96.                 pop     DS
  97.                 ASSUME  DS:CodeSeg
  98. ;
  99. ;               The Bell "gate" shenanighans below keeps the MASSIVE number of
  100. ;               interrupts that can occur during the computer-scale
  101. ;               long, LONG time needed to ring the bell from overflowing the
  102. ;               system's internal stack (because of so many Int 10 calls) when
  103. ;               you hold down the Print Screen key for too long.
  104. ;
  105. ;               This "gate" technique is a good one to keep in
  106. ;               mind whenever you have a code region in an interrupt handler
  107. ;               that needs to be protected from re-entry:
  108. ;
  109.                 cmp     bellgate,0      ;Clear to enter routine?
  110.                 jne     BusyExit        ;If gate not open, Exit.
  111.                 mov     bellgate,1      ;Else, close gate & enter routine.
  112. ;
  113. ; Allow other interrupts:
  114.                 sti
  115. ;
  116.                 push    ax      ;Entry to TSR Routine:
  117.                 push    bx      ;Save all registers (DS is already pushed).
  118.         push    cx
  119.         push    dx
  120.         push    si
  121.         push    di
  122.         push    bp
  123.                 push    es
  124. ;
  125. ;*************************************************************************
  126. ;    Your code for the New Hooked Interrupt Handler TSR routine  
  127. ;    GOES HERE:
  128. ;    ( Here, a dummy routine has been placed which simply rings the
  129. ;      terminal Bell whenever the TSR is triggered. )
  130. ;
  131. ;    Announce this dummy TSR's trigger by a Bell signal:
  132. ;
  133.         mov    al,07h            ;al = ASCII Bell. 
  134.         mov    bh,0            ;Video page.
  135.         mov    cx,1            ;No. of bytes to write.
  136.         mov    ah,0Eh            ;BIOS Int10,OEh=TTY Screen.
  137.         Int    10h            ;Write ASCII Bell to screen.
  138. ;
  139. ;    End of Hooked Interrupt handler routine.
  140. ;***************************************************************************
  141. Exit:
  142.                 mov     bellgate,0
  143.                 pop     es                      ;Restore all registers
  144.         pop    bp
  145.         pop    di
  146.         pop    si
  147.         pop    dx
  148.         pop    cx
  149.         pop    bx
  150.         pop    ax
  151. ;
  152. BusyExit:
  153.                 pop     ds
  154.                 iret
  155. ;
  156. NewInt    ENDP                    ;v0.11
  157. ;    -END OF TSR's RESIDENT CODE-
  158. ;    Only the code above will remain locked in memory after the
  159. ;        TSR initialization performed below.
  160. ;*************************************************************************
  161. SUBTTL  TSR  Initialization Code (Nonresident). The "BOOSTER".
  162. PAGE
  163. ;*************************************************************************
  164. ;    BEGINNING OF TSR's INITIALIZATION CODE:
  165. ;       The following code is protected in RAM *ONLY* during initialization   
  166. ;               of the TSR that occurs when the TSR name is first entered    
  167. ;               at the DOS command level. All the following code is abandonned 
  168. ;               unprotected in RAM after the Terminate-and-Stay-Resident       
  169. ;               call to Function 31h of DOS Interrupt 21h below. This          
  170. ;               is allowed to happen because the code's work is complete at 
  171. ;               that point. The code will be overwritten as the memory which   
  172. ;               it temporarily occupied is needed by DOS for other purposes.   
  173. ;         I have seen this following section of code colorfully called
  174. ;        the TSR "Booster". And this is quite appropriate since the code
  175. ;        sits here, strapped to the very end of the code. It is of use
  176. ;        only during the initialization of the TSR, when it is used to
  177. ;        put the TSR into "orbit" (residency), and after which it is
  178. ;        "jettisoned" by the DOS TSR call, Int 21h, Fcn 31h.
  179. ;                                                                              
  180. TSRinit         PROC    NEAR    ;v0.11
  181. EndDump         EQU     $       ;Roy Silvernail: Keep TASM 1.0 happy in
  182.                                 ;computing number of resident paragraphs.
  183. ;
  184. ; TSRINT requires DOS Version 2 or later. Be sure DOS Version 1 not used:
  185. ;
  186. ;       Get DOS Version Number:
  187.                 mov     ah,30h                  ;Fcn 30h = Get DOS Version
  188.                 int     21h                     ;DOS Version = al.ah
  189. ;
  190. ;       If this is DOS v.1.x, this TSR cannot work, so go print message
  191. ;       and exit without installing:
  192.                 cmp     al,1         ;Is this DOS Version 1.x?
  193.                 ja      DOSverOK     ;If not, DOS version is OK.
  194. ;
  195. DOSver1:
  196. ;If here, DOS Version 1.x is being run and TSR won't work, so bail out:
  197. ;
  198.         mov    dx,OFFSET BailOutMsg    ;TBONES needs DOS 2.x or later.
  199.         mov    ah,09h            ;Say we're sorry, but NO GO
  200.         int    21h            ;via DOS.
  201.                 pop     bx                      ;Clear stack.
  202.         int    20h            ;Terminate without installing
  203.                         ;in only way DOS 1.x knows.
  204. ;
  205. BailOutMsg:
  206.                 db      0Dh,0Ah
  207.                 db      'Sorry. TSRBONES needs DOS v.2+. You have v.1.x'
  208.                 db      0Dh,0Ah,'$'
  209. ;
  210. DOSverOK:
  211. ;       If here, DOS version is 2.0 or later. TSR can work, so proceed.
  212. ;
  213. ;       To conserve memory, release from memory the copy of the DOS
  214. ;    Environment passed to this TSR (this, of course, assumes that
  215. ;    your Interrupt handler will not be written to reference this
  216. ;    de-allocated Environment. If you are going to need it, don't
  217. ;    de-allocate it.):
  218. ;
  219.         mov    ES,envseg        ;get environment segment v0.11
  220.                         ;from Program Segment Prefix.
  221.         mov    ah,49h            ;DOS Fcn 49h = Release Memory
  222.         int    21h            ;Release it via DOS interrupt.
  223. ;
  224. ; In order to make the TSR's command name show under the "owner" column in 
  225. ;    the "MAPMEM" command of Kim Kokkonen's excellent TSR Mark/Release 
  226. ;       package, allocate a tiny 1-paragraph "Pseudo-Environment" here which
  227. ;       contains nothing but the TSR name. This only costs 16 bytes in
  228. ;       TSR resident code:
  229. ;
  230. ; Allocate the memory needed by the tiny 'Pseudo-Environment":
  231.         mov    bx,1            ;Allocate one parag. (16bytes)
  232.         mov    ah,48h            ;and return allocation
  233.         int    21h            ;segment in ax via DOS call.
  234. ;
  235.                 mov     ES,ax                   ;Pseudo-Env. Segment to ES.
  236.         mov    si,OFFSET PseudoEnv    ;si=source string OFFSET.
  237.         mov    di,0            ;di=destination string OFFSET.
  238.         mov    cx,ENVLNGTH        ;cx=Bytes in Pseudo-Env.string.
  239.         cld                ;Forward string move direction.
  240.         rep    movsb    ;Move Pseudo-Env. string @ DS:si to ES:di
  241. ;
  242. ; Set PSP's Environment segment pointer to point to tiny Pseudo-Environment.
  243.         mov    envseg,ES    
  244. ;
  245. ;*****************************************************************************
  246. ; Hook the Interrupt:
  247. ;
  248. ;    Get Old Interrupt Vector:
  249.         mov    ax,3500H + HOOK        ;AH=DOS Fcn 35H, Get Int Vec
  250.                         ;AL=Hooked Interrupt number
  251.         int    21h            ;Old Int Vect.in ES:BX via DOS.
  252. ;
  253. ;    Save Old Interrupt Vector:
  254.         mov    Word Ptr oldint,bx    ;Save Offset of Old Interrupt.
  255.         mov    Word Ptr oldint+2,ES    ;save old interrupt seg    v0.11
  256. ;
  257. ;    Install New Interrupt Vector to this TSR's "NewInt:" Label:
  258.         mov    ax,2500H + HOOK        ;AH=DOS Fcn 25H=Set Int vec
  259.                         ; v0.11
  260.                         ;AL=Hooked Interrupt number
  261.         mov    dx,offset NewInt    ;dx=Offset of New Int Handler.
  262.         int    21h            ;Set New Int via DOS.
  263. ;
  264. ; Announce the TSR's Installation:
  265.         mov    dx,Offset InstallMsg    ;dx points to message.
  266.         mov    ah,09h            ;DOS Fcn. 09h=Display String.
  267.         int    21h            ;Display String via DOS.
  268. ;
  269. ; Lock resident code in memory via Terminate-and-Stay-Resident (TSR) DOS call:
  270. ;
  271. ;v0.11    DX requires size of resident code (in 16-byte paragraphs)
  272. ;    This awkward construct is required to keep
  273. ;    DOS Function 31h happy.  Notice how we first compute
  274. ;    the length of the TSR code in bytes [i.e., end of
  275. ;       the TSR code (EndDump) minus start of the TSR code
  276. ;       (0, our BeginDump)], round it up to the next whole paragraph ( + 0Fh),
  277. ;    and then divide by 16 (SHR 4) to get the number of resident paragraphs:
  278. ;
  279. ;       Thanks to Roy Silvernail, who made TASM 1.0 happy by defining the
  280. ;               constants BeginDump and EndDump, and using them in the
  281. ;               following statement:
  282. ;
  283.                 mov     dx,(EndDump-BeginDump+0FH)/16   ;DX = No.Paragraphs.
  284. ;
  285.         mov    ah,31h            ;DOS FCN 31h = TSR Call.
  286.         int    21h            ;Go Resident via DOS TSR call.
  287.                         ;Goodbye, Booster! 
  288. ;
  289. PseudoEnv:      DB      ' ',0,0,1,0,'TSRINT',0
  290. ENVLNGTH    EQU    $-PseudoEnv
  291. ;
  292. InstallMsg:
  293.         db    0Dh,0Ah
  294.         db    'YOUR HOOKED INTERRUPT TSR IS NOW INSTALLED.'
  295.         db    0Dh,0Ah
  296.         db    'Hooked Interrupt => PrtScrn (Int 05h)'
  297.         db    0Dh,0Ah,0Dh,0Ah
  298.                 db      'TSRINT Version 0.4'
  299.         db    0Dh,0Ah
  300.                 db      'Copyright (C) 1990, 1991 by Robert Curtis Davis'
  301.         db    0Dh,0Ah,'$'
  302. ;
  303. TSRinit         ENDP    ;v0.11
  304.  
  305. CodeSeg        ends
  306.         end    Entry
  307. ;
  308. ;*****************************************************************************
  309. 
  310.