home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / PCACHSRC.ZIP / DOSTSR16.ASM < prev    next >
Assembly Source File  |  1992-07-29  |  9KB  |  341 lines

  1. ;DOSTSR16.ASM
  2. ;This is a skeleton DOS TSR, that hooks INT-16h.
  3. ;All it does is detect a hot key (<alt-z>) and then activates.
  4. ;Upon activation it accepts further keyboard input and displays
  5. ;characters on the screen.  Another <alt-z> will deactivate the TSR.
  6. ;Shows how to safely synchronise a TSR with DOS.
  7. ;Note that the only reason I put ".286" directive in is because I
  8. ;have used the PUSHA and POPA instructions.
  9.  
  10. ;...................................................
  11. .286
  12. int16    SEGMENT BYTE PUBLIC 'CODE'
  13.     ASSUME    cs:int16,ds:int16
  14.     ORG    100h
  15. install:    jmp start
  16. oldoffivt2F    DW    0    ;save old int-2F vector here.
  17. oldsegivt2F    DW    0    ;    /
  18. winloaded    DB    0    ;set when Windows is loaded, & viceversa.
  19. winmode        DB    0    ;bit-0=1 if Standard, =0 if Enhanced.
  20. oldoffivt16    DW    0    ;save old keyboard vector here.
  21. oldsegivt16    DW      0    ;    /
  22. oldoffivt28    DW    0    ;old int-28h
  23. oldsegivt28    DW    0    ;    /
  24. tsrpspseg    DW    0    ;seg addr of psp, this tsr.
  25. dosbusyoff    DW    0    ;far addr of dos busy flag
  26. dosbusyseg    DW    0    ;    /
  27. isrbusy        DB    0    ;set if this isr already in use.
  28. isrwanted    DB    0    ;set=isr tried to start but indos stopped it
  29. oldpspseg    DW    0    ;seg addr of psp prior to interrupt.
  30. oldsp        DW    0    ;stack prior to interrupt.
  31. oldss        Dw    0    ;    /
  32. oldctrlc    DB    0    ;ctrl-c on/off
  33. oldoffivt1B    DW    0    ;old vectors
  34. oldsegivt1B    DW    0    ;    /
  35. oldoffivt23    DW    0    ;    /
  36. oldsegivt23    DW    0    ;    /
  37. oldoffivt24    DW    0    ;    /
  38. oldsegivt24    DW    0    ;    /
  39. localstack    DB    511 DUP(0)
  40. localendstack    DW    0    ;top of stack
  41. ;....................................................................
  42. runtime16:
  43. ;this is now the "signaller".  it is entered at every keypress...
  44. ;but only when in a DOS VM or in standard real-mode...
  45. ;
  46. ;this is particular to int-16h (test if reading a char)....
  47.     cmp    ah,0
  48.     je    firsthurdle
  49.     cmp    ah,10h
  50.     je    firsthurdle
  51. chain:  jmp    DWORD PTR cs:oldoffivt16    ;chain to old int-16
  52. ;
  53. firsthurdle:
  54. ;give some thought to reentrancy... avoid potential problems with a flag...
  55.     cmp    cs:isrbusy,0
  56.     jne    chain        ;this isr already in use!
  57. secondhurdle:
  58. ;now test for the hot-key...
  59.     pushf
  60.     call    DWORD PTR cs:oldoffivt16    ;call old int-16.
  61.     cmp    ax,2C00h    ;<alt-z>
  62.     je    thirdhurdle
  63.     iret
  64. thirdhurdle:
  65.     mov    cs:isrwanted,1    ;to tell int-28 that we want to popup.
  66. ;before doing anything, we need to synchronise with dos...
  67. ;however the test for the "indos" flag does not work when COMMAND.COM
  68. ;is running... int-16 called with indos set....
  69.     push    ax
  70.     push    bx
  71.     push    es
  72.     les    bx,DWORD PTR cs:dosbusyoff
  73.     mov    al,es:[bx]    ;get dos-busy flag
  74.     or    al,al
  75.     pop    es
  76.     pop    bx
  77.     pop    ax
  78.     jnz    chain        ;get out, as dos is busy.
  79. ;
  80. vvv:    mov    cs:isrbusy,1    ;lay claim to this isr.
  81.     mov    cs:isrwanted,0    ;clear this, since we're in.
  82. zzz:    sti            ;now allow interrupts.
  83. ;(note that if this was a hardware interrupt, would need EOI here also).
  84.     nop
  85. ;now get the regs setup for the isr... let's use a local stack...
  86.     cli
  87.     mov    cs:oldss,ss
  88.     mov    cs:oldsp,sp
  89.     mov    ss,cs:tsrpspseg ;can do this since es=cs=ds at install.
  90.     mov    sp,OFFSET cs:localendstack
  91.     sti
  92.     push    es    ;save working registers
  93.     push    ds    ;    /
  94.     pusha        ;    /
  95.     push    cs    ;set ds == cs
  96.     pop    ds    ;    /
  97. ;get the seg addr of the old psp (of program prior to interrupt)...
  98.     mov    ah,62h
  99.     int    21h    ;-->bx
  100.     mov    oldpspseg,bx
  101. ;set dos to use psp of this tsr...
  102.     mov    bx,tsrpspseg    ;(saved during install)
  103.     mov    ah,50h
  104.     int    21h
  105. ;one other thing that you should do is save the "break" setting
  106. ;and turn it off, so key entries such as ctrl-c can't upset our isr.
  107. ;firstly, get the vectors...
  108.     mov    ax,351Bh
  109.     int    21h
  110.     mov    oldoffivt1B,bx
  111.     mov    oldsegivt1B,es
  112.     mov    ax,3523h
  113.     int    21h
  114.     mov    oldoffivt23,bx
  115.     mov    oldsegivt23,es
  116.     mov    ax,3524h
  117.     int    21h
  118.     mov    oldoffivt24,bx
  119.     mov    oldsegivt24,es
  120.     mov    ax,3300h    ;is ctrl-c checking turned on?
  121.     int    21h        ;dl=1 enabled
  122.     mov    oldctrlc,dl
  123. ;now hook them...
  124.     mov    ax,251Bh
  125.     mov    dx,OFFSET runtime1B
  126.     int    21h
  127.     mov    ax,2523h
  128.     mov    dx,OFFSET runtime23
  129.     int    21h
  130.     mov    ax,2524h
  131.     mov    dx,OFFSET runtime24
  132.     int    21h
  133.     mov    ax,3301h    ;ctrl-c testing
  134.     xor    dl,dl        ;turned off.
  135.     int    21h
  136.  
  137. ;should also save extended error information (funcs 5D, 59)
  138. ; and the DTA (disk transfer area).
  139. ;Note that all of the above is reversed upon isr exit.
  140. ;
  141. ;a confirmation that we got this far!...
  142.     call longbeep
  143.  
  144. ;..............................................................
  145. ;this is it... this is where we do whatever the tsr is supposed to do...
  146. ;let's display a char on screen and wait for another key...
  147. ppp:    mov    ah,0        ;get char from key buffer.
  148.     int    16h        ;(goes to old vector, as isrbusy is set).
  149.     cmp    ax,2C00h
  150.     je    backtohost
  151.     mov    ah,9        ;display a char
  152.     mov    bl,70h        ;attribute/colour
  153.     mov    bh,0        ;video page
  154.     mov    cx,1        ;just one char
  155.     int    10h
  156.     jmp    ppp
  157.  
  158. backtohost:
  159. ;.......
  160. exit4:
  161.     mov    ah,50h    ;restore host psp
  162.     mov    bx,oldpspseg
  163.     int    21h
  164. ;restore old break vectors & ctrl-c testing...
  165.     push    ds
  166.     mov    ax,251Bh
  167.     lds    dx,DWORD PTR cs:oldoffivt1B
  168.     int    21h
  169.     mov    ax,2523h
  170.     lds    dx,DWORD PTR cs:oldoffivt23
  171.     int    21h
  172.     mov    ax,2524h
  173.     lds    dx,DWORD PTR cs:oldoffivt24
  174.     int    21h
  175.     pop    ds
  176.     mov    ax,3301h    ;restore ctrl-c checking state.
  177.     mov    dl,oldctrlc
  178.     int    21h
  179. ;......
  180.     popa        ;restore registers.
  181.     pop    ds    ;    /
  182.     pop    es    ;    /
  183.     cli
  184.     mov    ss,cs:oldss    ;restore host stack
  185.     mov    sp,cs:oldsp    ;    /
  186.     mov    cs:isrbusy,0    ;isr no longer in use
  187.     mov    cs:isrwanted,0    ;isr doesnt want to popup.
  188. exit:    iret
  189. ;....................................................................
  190. runtime2F:
  191. ;also entered if try to reload this tsr... install sends AX=CC00
  192. ;if this signature, return with AX=CC01 to say already loaded...
  193.     cmp    ah,0CCh        ;note can use this mechanism to send
  194.     jne    nextsig        ; messages to the tsr from a dosapp:
  195.     cmp    al,0        ;is it an install test?(value in AL=0)
  196.     je    installtest
  197.     iret
  198. installtest: mov al,1        ;flag can't load.
  199.     jmp    SHORT chain2F
  200. nextsig:
  201.  
  202. ;entered when Windows loads, with AX=1605h, and when Windows unloads,
  203. ;with AX=1606h....
  204. ;detect when Windows loads, and set a flag ...
  205.     sti            ;documentation says this req'd.
  206.     cmp    ax,1605h    ;test if Win is loading
  207.     jne    notload
  208.     cmp    cx,0        ;this must always be 0, else error.
  209.     jne    loaderror
  210.     mov    cs:winloaded,1
  211.     mov    cs:winmode,dl
  212.     jmp    SHORT chain2F
  213. notload: cmp    ax,1606h    ;test if Win is unloading.
  214.     jne    notunload
  215.     mov    cs:winloaded,0
  216.     jmp    SHORT chain2F
  217. notunload:
  218.  
  219.  
  220. loaderror:
  221. chain2F:
  222.     jmp DWORD PTR cs:oldoffivt2F
  223. ;..................................................................
  224. runtime28:
  225. ;this isr is required because of the peculiar way COMMAND.COM works!
  226.     pushf
  227.     call    DWORD PTR CS:oldoffivt28    ;call old int-28
  228.     push    ds
  229.     push    es
  230.     pusha
  231.     push    cs
  232.     pop    ds
  233. ;is dos busy...
  234.     les    bx,DWORD PTR dosbusyoff
  235.     mov    al,es:[bx]    ;get indos flag
  236.     or     al,al
  237.     jz    mmm        ;if set, then we can popup.
  238. ;find out if isr wants to popup...
  239.     cmp    isrwanted,0
  240.     jz    mmm
  241.     pushf
  242.     call    FAR PTR vvv    ;calls runtime16 as an interrupt.
  243. mmm:    popa
  244.     pop    es
  245.     pop    ds
  246.     iret
  247. ;............................................................
  248. runtime24: xor    al,al
  249. runtime1B:
  250. runtime23: iret
  251. ;................................................................
  252. longbeep:
  253.     pusha
  254.     mov    al,0B6h        ;turn on loudspeaker
  255.     out    43h,al
  256.     mov    bx,07C5h
  257.     mov    al,bl
  258.     out    42h,al
  259.     mov    al,bh
  260.     out    42h,al
  261.     in    al,61h
  262.     or    al,3
  263.     out    61h,al
  264.     mov    cx,0ffffh
  265. xxx:    nop
  266.     pusha            ;just to kill time
  267.     popa
  268.     loop    xxx
  269.     in    al,61h        ;turn off loudspeaker
  270.     and    al,0FCh
  271.     out    61h,al
  272.     popa
  273.     ret
  274. ;................................................................
  275. endprog:    ;everything past here dumped when made resident.
  276. start:
  277.  
  278. ;save ptr to psp...
  279.     mov    tsrpspseg,es    ;if com, they all pt to it!
  280. ;is this tsr already installed?... i have given it a signature of CCh...
  281.     mov    ax,0CC00h        ;AL=0 is install-test code for my 2F handler.
  282.     int    2Fh        ;multiplex interrupt (that we will hook)
  283.     or    al,al        ;AL=non-0 means abort.
  284.     jnz    abortload
  285. ;get the addr of the dos-busy flag...
  286.     mov    ah,34h
  287.     int    21h        ;-->es:bx
  288.     mov    dosbusyoff,bx
  289.     mov    dosbusyseg,es
  290. ;
  291. ;hook int-2Fh vector in ivt.  Windows calls this with AX=1605h when it loads,
  292. ;with regs telling useful info, such as if loading in Standard or
  293. ;Enhanced mode....
  294.     mov    ax,352Fh        ;get int-2F vector in ivt.
  295.     int    21h            ;    /
  296.     mov    oldoffivt2F,bx    ;save it
  297.     mov    oldsegivt2F,es    ;    /
  298.     mov    ax,252Fh    ;hook int-2F
  299.     lea    dx,runtime2F    ;set ivt vector.
  300.     int    21h            ;    /
  301. ;
  302. ;hook keypresses ...
  303.     mov    ax,3516h          ;get int-16h vector in ivt.
  304.     int    21h            ;    /
  305.     mov    oldoffivt16,bx    ;save it
  306.     mov    oldsegivt16,es    ;    /
  307.     mov    ax,2516h      ;hook int-16
  308.     lea    dx,runtime16    ;set ivt vector.
  309.     int    21h            ;    /
  310. ;
  311. ;hook int-28h. COMMAND.COM calls this when idling & reading the keyboard...
  312. ;unfortunately when entering int-16 from COMMAND.COM, indos always set,
  313. ;but at int 28h call it is safe...
  314.     mov    ax,3528h
  315.     int    21h
  316.     mov    oldoffivt28,bx
  317.     mov    oldsegivt28,es
  318.     mov    ax,2528h
  319.     lea    dx,runtime28
  320.     int    21h
  321. ;
  322. ;free the environment block ... ###(this may upset int-2F/1687h)
  323. ;    mov    es,ds:[2Ch]    ;pointer to seg. addr. of env. block
  324. ;    mov    ah,49h        ;deallocate memory
  325. ;    int    21h        ;    /
  326. ;
  327.     lea    dx,endprog+17  ;point past all code in this module.
  328.     shr    dx,4    ;compute # paragraphs to keep.
  329.     mov    ax,3100h    ;terminate and stay resident.
  330.     int    21h    ;    /
  331. abortload:
  332.     call    longbeep
  333.     mov    ax,4C00h    ;don't make resident.
  334.     int    21h
  335.  
  336. ;...............................................................
  337. int16    ENDS
  338.     END    install
  339.  
  340.  
  341.