home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 26 / CD_ASCQ_26_1295.iso / vrac / mouse03g.zip / MOUSE2G.ASM < prev    next >
Assembly Source File  |  1995-10-18  |  14KB  |  352 lines

  1.         Title   TSR Microsoft Mouse Driver - Full Version
  2. ;
  3. ;Author: G.B.Gustafson Oct 1995, gustafson@math.utah.edu
  4. ;
  5. ;REFERENCE: Two similar mouse TSR programs exist:
  6. ;
  7. ;    A similar but different TSR is in MENUMOUS.ASM sources from
  8. ;    jmbj@whuts.ATT.COM (BITTMAN). It is located in archive MENUMOUS.ARC;
  9. ;    see below for source directory on Internet.
  10. ;
  11. ;    The MENUMOUS sources break when used with the BUF160_5.ZIP device
  12. ;    driver that expands the keyboard buffer (it does work with the
  13. ;    default keyboard buffer of length 17). The source below for the
  14. ;    keyboard buffer stuffer works with the BUF160_5.ZIP driver.
  15. ;
  16. ;    A shareware product called ARRMOUSE.ZIP is available on Internet
  17. ;    anonymous FTP to wuarchive.wustl.edu in directory ~/mirrors/msdos.
  18. ;    The author is Seth W. Comstock (Version 1.0, March 1990). It has
  19. ;    some good features and should be investigated. See also the site
  20. ;    ftp://oak.oakland.edu/simtel/msdos/mouse/
  21. ;
  22. ;USE: The importance of the sources is educational value:
  23. ;
  24. ;     1. A simple, useful TSR that hooks the 2fh interrupt vector.
  25. ;     2. A keyboard buffer routine for stuffing keys. It will work
  26. ;        even if the keyboard buffer has been expanded.
  27. ;     3. Mouse driver example. Safe initialization and shutdown.
  28. ;        See notes below on the event handler.
  29. ;
  30. ;MOUSE SENSITIVITY. A curious feature in mouse code is sensitivity to
  31. ;movement: settling down on a character is subject to much error. In the
  32. ;code below this problem is attacked.
  33. ;
  34. ;    Ideally, the cursor should lock onto a line and not be bumped off
  35. ;    easily as the cursor scans left and right. Further, up and down
  36. ;    motion should lock the cursor onto a column. I should like to scan
  37. ;    up and down columns of numbers with the mouse exactly as I do with
  38. ;    the cursor keys. The code below is an attempt to realize these
  39. ;    features that falls short of perfection.
  40. ;
  41. ;MOUSE DRIVER DEFAULTS. The TSR resets the mouse driver and but sets no
  42. ;defaults for the mouse controls: X,Y sensitivity, doubler. If the TSR
  43. ;is unloaded, then the mouse driver is again reset to disable the event
  44. ;handler hook.
  45. ;
  46. ;RELEASE TSR. This TSR contains code to detect its own presence.
  47. ;Furthermore, it contains code to release it from memory. The code was
  48. ;written following the ideas of Al Williams, "DOS 5: A Developers Guide",
  49. ;page 516 (M&T Books 1992).
  50. ;
  51. ;    It is not safe to simply delete this TSR because of the mouse driver
  52. ;    event handler initialization. However, you can issue a mouse driver
  53. ;    reset and then it can be safely deleted by mark/release or resdel.
  54. ;
  55. ;WARRANTY. This source code carries no warranty. Its intended use is
  56. ;information. If you use it, then it was worth writing down: no
  57. ;permission is needed to copy and use this source. I repeat: this is not
  58. ;a software product, and it is serendipity if it happens to be useful.
  59. ;-GBG
  60. ;
  61. ;=========================Mouse Functions================================
  62. ;Mouse movement is mapped to cursor keys: up,down,left,right.
  63. ;Right button  ==> Esc Key   (ctrl-[, 27)
  64. ;Left button   ==> Enter Key (ctrl-M, 13)
  65. ;Settings here are for Znix mouse with ballistics /m2 /fdefault.pro
  66. ;Other ballistics tried and all are acceptable: /m1, /m3, /m4.
  67. ;Also tested on Merit Mouse Z-1000 (like Znix /m4 no ballistics).
  68. ;========================================================================
  69. ;
  70. code segment
  71.         org 100h
  72.         assume cs:code,ds:code,es:code
  73. begin:  jmp start
  74.  
  75. leftkey                 equ  4b00h
  76. rightkey                equ  4d00h
  77. upkey                   equ  4800h
  78. downkey                 equ  5000h
  79. retkey                  equ  1c0dh
  80. esckey                  equ  011bh
  81.  
  82. mouse                   equ  51         ;interrupt 33h
  83. resetmousedriver        equ   0         ;reset mouse driver
  84. pressmouse              equ   5         ;mouse button press status
  85. mousemotion             equ  11         ;mouse cursor motion
  86. seteventhandler         equ  12         ;set mask and event handler
  87. setsensitivity          equ  15         ;set horiz & vert sensitivity
  88. setdoublespeed          equ  19         ;set double-speed threshold
  89. eventmask               equ  0000000000001011b
  90. ;evenmask bits 0,1,4: movement, left & right press
  91.  
  92. horizontalsensitivity   dw  8           ;8=default mickeys/8 pixels
  93. verticalsensitivity     dw  16          ;16=default mickeys/8 pixels
  94. ;
  95. ;Mouse driver resets to 8 and 16 respectively with function 00h.
  96. ;Merit and Znix both worked well with settings 8,16.
  97. ;
  98. horizposition           dw   0          ;store mouse cursor position X
  99. vertposition            dw   0          ;store mouse cursor position Y
  100. ;
  101. mouseeventhandler proc far
  102.         push ax
  103.         push bx
  104.         push cx
  105.         push dx
  106.         push di
  107.         push ds                 ;ds=mouse driver data segment
  108.  
  109.         push cs
  110.         pop ds                  ;cs=ds=TSR data segment
  111. ;
  112. ;Press Mouse supplies: AX=Mouse event bits, BX=button status,
  113. ;                      CX=X mickeys, DX=Y mickeys.
  114. ;                      CX and DX are signed integers: up==+, right==+.
  115. ;                      Clears all button counts on each call.
  116. ;
  117.         test ax,010B            ;Press left button?
  118.         jz check_rightbutton    ;No? Then check right button.
  119.         mov cx,retkey           ;Yes. Then plug in RETURN key.
  120.         jmp short dostuffbuffer
  121. check_rightbutton:
  122.         test ax,01000B          ;press right button?
  123.         jz checkcursor          ;No? Then check cursor keys.
  124.         mov cx,esckey           ;Yes. Then plug in ESC key.
  125. dostuffbuffer:
  126.         call stuffbuffer        ;near function call
  127.         jmp return
  128. checkcursor:
  129.         mov ax,mousemotion      ;Has the mouse cursor moved?
  130.         int mouse               ;Clear mickey counts
  131.         mov ax,horizposition    ;save new horizontal position
  132.         add ax,cx               ;cx=X coord supplied by mouse driver
  133.         mov horizposition,ax
  134.         cmp ax,0                ;Has the mouse cursor moved?
  135.         je motionvertical       ;No change, then check vertical
  136.         jg motionhorizontal     ;Make positive
  137.         not ax
  138. motionhorizontal:
  139.         mov bx,horizontalsensitivity
  140.         cmp ax,bx
  141.         jl motionvertical       ;didn't move enough for a change
  142.         cmp horizposition,0
  143.         mov cx,rightkey
  144.         jg  stuffit1            ;If positive, then stuff cursor Right
  145.         mov cx,leftkey
  146. stuffit1:
  147.         jmp short stuffit2      ;Forget about vertical motion!
  148. motionvertical:
  149.         mov ax,vertposition     ;save new vertical position
  150.         add ax,dx               ;dx=Y coord supplied by mouse driver
  151.         mov vertposition,ax
  152.         cmp ax,0
  153.         je return               ;no change, all done
  154.         jg testvertsens         ;If positive, then stuff cursor Up
  155.         not ax
  156. testvertsens:
  157.         mov bx,verticalsensitivity
  158.         cmp ax,bx
  159.         jl return               ;didn't move enough for a change
  160.         cmp vertposition,0
  161.         mov cx,downkey
  162.         jg stuffit2
  163.         mov cx,upkey
  164. stuffit2:
  165.         call manystuffbuffer    ;stuff key CX into keyboard buffer
  166.         mov vertposition,0      ;reset vertical saved position
  167.         mov horizposition,0     ;reset horizontal saved position
  168. return:
  169.         pop ds
  170.         pop di
  171.         pop dx
  172.         pop cx
  173.         pop bx
  174.         pop ax
  175.         ret
  176. mouseeventhandler endp
  177.  
  178. manystuffbuffer proc near
  179. ; AX=amount in mickeys mouse cursor has moved.
  180. ; BX=sensitivity in mickeys
  181. ; CX=key scan code to stuff into keyboard buffer
  182. manyloop:
  183.         call stuffbuffer
  184.         sub ax,bx
  185.         cmp ax,bx               ;Full moves only
  186.         jge manyloop
  187.         ret
  188. manystuffbuffer endp
  189.  
  190. stuffbuffer proc near
  191.         cli                     ;Prevent interrupts from stuffing buffer
  192.         push es                 ;typeahead buffer start at *[0040:0080]
  193.         push si                 ;and end at *[0040:0082].
  194.         push di                 ;At segment 40h and offset 01ah is
  195.         push bx
  196.         mov di,40h              ;the offset into the typeahead buffer
  197.         mov es,di               ;for the character at the head. At
  198.         mov bx,es:[1ch]         ;segment 40h and offset 01ch is the
  199.         mov si,bx               ;offset into the typeahead buffer for
  200.         add bx,2                ;the last character. The buffer is full
  201.         cmp bx,es:[1ah]         ;if *[01ch]+2 == *[01ah].
  202.         je quit                 ;Full? Then don't add any more chars
  203.         cmp bx,es:[82h]         ;Offset less than end of buffer?
  204.         jl isroom               ;Yes. Then go ahead and stuff it.
  205.         mov bx,es:[80h]         ;Else wrap around to buffer start
  206. isroom:
  207.         mov es:[si],cx          ;CX=scan code to be stuffed
  208.         mov es:[1ch],bx         ;BX=new offset to last buffer character
  209. quit:   pop bx
  210.         pop di
  211.         pop si
  212.         pop es
  213.         sti                     ;let other routines stuff the buffer
  214.         ret                     ;near return
  215. stuffbuffer endp
  216.  
  217. ;
  218. ; Code below is for detection of second install and removal of TSR
  219. ; Motivated by Al Williams recommendations p 516, "Dos 5: A developers
  220. ; Guide", M&T Books 1992.
  221. ;
  222. old2fOFF        dw      0       ;Save here offset and segment
  223. old2fSEG        dw      0       ;of old multiplex 2fh interrupt vector
  224. SIG             equ     0cbh    ;Signature of this TSR, user invented.
  225. KILLTSR         equ     (SIG SHL 8)+SIG+1
  226. ;
  227. new2fINT:                       ;New 2fh interrupt goes here
  228.         cmp ah,SIG              ;Is it service SIG?
  229.         jnz new2fIRET           ;No, then vector to original 2fh loc.
  230.         cmp al,SIG+1            ;Is it service SIG+1?
  231.         jz remove               ;Then remove TSR from memory.
  232.         mov al,255              ;Otherwise, return indicator -1
  233. new2fIRET:
  234.         jmp dword ptr cs:[old2fOFF]
  235. remove:
  236.         push ds
  237.         push es
  238.         push bx
  239.         push dx
  240.  
  241.         mov ax,cs
  242.         mov ds,ax
  243.         mov ax,352fh            ;Is the present 2fh vector ours?
  244.         int 21h
  245.         cmp bx,offset new2fINT
  246.         mov al,1                ;Report bad remove
  247.         jnz removeEXIT          ;Must be unchanged to remove
  248.         cli                     ;Looks Ok, let's reload 2fh vector
  249.         lds dx,dword ptr old2fOFF
  250.         mov ax,252fh            ;Replace old 2fh vector
  251.         int 21h
  252.         sti
  253.         mov ax,cs               ;Now free TSR memory
  254.         mov es,ax               ;Get PSP
  255.         mov ah,49h              ;Free DOS alloc memory
  256.         int 21h                 ;Should return al==0
  257.         jc removeEXIT           ;Error on carry
  258.         mov ax,0
  259. removeEXIT:
  260.         pop dx
  261.         pop bx
  262.         pop es
  263.         pop ds
  264.         iret
  265. ;
  266. endresident label byte
  267. ;
  268. ;All resident code is above this point.
  269. ;All code below this point gets trashed by TSR exit.
  270. ;No unload of 100h PSP area.
  271. ;
  272. ;temporary strings
  273. mesg1   db     'Mouse TSR already installed',13,10,
  274.         db     'Remove it from memory? [N]: ','$'
  275. mesg2   db     13,10,'$'
  276. mesg3   db     'Mouse TSR remains in memory','$'
  277. mesg4   db     'TSR removed from memory','$'
  278. mesg5   db     'Cannot remove TSR from memory','$'
  279. mesg6   db     'Mouse device has no software driver','$'
  280. mesg7   db     'Mouse TSR successfully installed','$'
  281. ;
  282. printstring proc near
  283.         mov ah,9
  284.         int 21h
  285.         ret
  286. printstring endp
  287. ;
  288. start:
  289.         push cs
  290.         pop ds
  291.         mov ax,(SIG SHL 8)
  292.         int 2fh
  293.         cmp al,0ffh             ;TSR loaded?
  294.         jne success             ;No, tsr not loaded.
  295.         mov dx,offset mesg1     ; 'Mouse TSR already installed',13,10,
  296.         call printstring        ; 'Remove it from memory? [N]: ','$'
  297.         mov ah,1                ;Read a key.
  298.         int 21h
  299.         push ax                 ;Then print cr/lf pair
  300.         mov dx,offset mesg2     ; 13,10,'$'
  301.         call printstring        ; to the terminal
  302.         pop ax
  303.         and al,0dfh             ;make key upper case
  304.         cmp al,'Y'              ;and test for YES
  305.         mov dx,offset mesg3     ;'Mouse TSR remains in memory','$'
  306.         jne printandquit        ;FAIL if key was not 'Y'
  307.         mov ax,resetmousedriver ;reset mouse driver to defaults
  308.         int mouse               ;so mouse driver does not hang
  309.         mov ax,KILLTSR          ;otherwise kill TSR
  310.         int 2fh                 ;using MUX interrupt
  311.         or al,al                ;which returns zero if it worked
  312.         mov dx,offset mesg4     ;'TSR removed from memory','$'
  313.         jz printandquit
  314.         mov dx,offset mesg5     ;'Cannot remove TSR from memory','$'
  315.         jmp printandquit
  316.  
  317. success:
  318.         mov ax,resetmousedriver ;reset mouse driver to defaults
  319.         int mouse
  320.         cmp ax,0                ;bx=number of buttons, not used yet
  321.         mov dx,offset mesg6     ; 'Mouse device has no software driver','$'
  322.         je printandquit         ;exit if no mouse driver loaded
  323.         mov ax,cs               ;Hook mouse driver to event handler
  324.         mov es,ax               ;es=segment of event handler
  325.         mov dx,offset mouseeventhandler
  326.         mov ax,seteventhandler  ;mouse driver function code
  327.         mov cx,eventmask        ;signal mask for interrupt
  328.         int mouse
  329.         mov ax,352fh            ;get DOS interrupt vector 2fh
  330.         int 21h
  331.         mov [old2fSEG],es       ;save segment and offset
  332.         mov [old2fOFF],bx
  333.         mov es,cs:[2ch]         ;es=environment segment
  334.         mov ah,49h              ;free DOS alloc memory
  335.         int 21h
  336.         mov dx,offset mesg7     ; 'Mouse TSR successfully installed','$'
  337.         call printstring        ;print a success message
  338.         mov ax,cs               ;adjust to data segment
  339.         mov ds,ax
  340.         mov dx,offset new2fINT  ;install new 2fh interrupt vector
  341.         mov ax,252fh            ;at routine "new2fINT" in this code seg
  342.         int 21h
  343.         mov dx,(endresident-begin+100h+15)/16
  344.         mov ax,3100h            ;save resident code & exit.
  345.         int 21h
  346. printandquit:
  347.         call printstring        ;Print string ds:dx until '$' sentinel
  348.         mov ax,4ch              ;Then normal exit to dos.
  349.         int 21h
  350. code    ends
  351.         end begin
  352.