home *** CD-ROM | disk | FTP | other *** search
- Title TSR Microsoft Mouse Driver - Full Version
- ;
- ;Author: G.B.Gustafson Feb 1992, gustafson@math.utah.edu.Internet.
- ;
- ;REFERENCE: Two similar mouse TSR programs exist:
- ;
- ; A similar but different TSR is in MENUMOUS.ASM sources from
- ; jmbj@whuts.ATT.COM (BITTMAN). It is located in archive MENUMOUS.ARC;
- ; see below for source directory on Internet.
- ;
- ; The MENUMOUS sources break when used with the BUF160_5.ZIP device
- ; driver that expands the keyboard buffer (it does work with the
- ; default keyboard buffer of length 17). The source below for the
- ; keyboard buffer stuffer works with the BUF160_5.ZIP driver.
- ;
- ; A shareware product called ARRMOUSE.ZIP is available on Internet
- ; anonymous FTP to wuarchive.wustl.edu in directory ~/mirrors/msdos.
- ; The author is Seth W. Comstock (Version 1.0, March 1990). It has
- ; some good features and should be investigated.
- ;
- ;USE: The importance of the sources is educational value:
- ;
- ; 1. A simple, useful TSR that hooks the 2fh interrupt vector.
- ; 2. A keyboard buffer routine for stuffing keys. It will work
- ; even if the keyboard buffer has been expanded.
- ; 3. Mouse driver example. Safe initialization and shutdown.
- ; See notes below on the event handler.
- ;
- ;MOUSE SENSITIVITY. A curious feature in mouse code is sensitivity to
- ;movement: settling down on a character is subject to much error. In the
- ;code below this problem is attacked.
- ;
- ; Ideally, the cursor should lock onto a line and not be bumped off
- ; easily as the cursor scans left and right. Further, up and down
- ; motion should lock the cursor onto a column. I should like to scan
- ; up and down columns of numbers with the mouse exactly as I do with
- ; the cursor keys. The code below is an attempt to realize these
- ; features that falls short of perfection.
- ;
- ;MOUSE DRIVER DEFAULTS. The TSR resets the mouse driver and but sets no
- ;defaults for the mouse controls: X,Y sensitivity, doubler. If the TSR
- ;is unloaded, then the mouse driver is again reset to disable the event
- ;handler hook.
- ;
- ;RELEASE TSR. This TSR contains code to detect its own presence.
- ;Furthermore, it contains code to release it from memory. The code was
- ;written following the ideas of Al Williams, "DOS 5: A Developers Guide",
- ;page 516 (M&T Books 1992).
- ;
- ; It is not safe to simply delete this TSR because of the mouse driver
- ; event handler initialization. However, you can issue a mouse driver
- ; reset and then it can be safely deleted by mark/release or resdel.
- ;
- ;WARRANTY. This source code carries no warranty. Its intended use is
- ;information. If you use it, then it was worth writing down: no
- ;permission is needed to copy and use this source. I repeat: this is not
- ;a software product, and it is serendipity if it happens to be useful.
- ;-GBG
- ;
- ;=========================Mouse Functions================================
- ;Mouse movement is mapped to cursor keys: up,down,left,right.
- ;Right button ==> Esc Key (ctrl-[, 27)
- ;Left button ==> Enter Key (ctrl-M, 13)
- ;Settings here are for Znix mouse with ballistics /m2 /fdefault.pro
- ;Other ballistics tried and all are acceptable: /m1, /m3, /m4.
- ;Also tested on Merit Mouse Z-1000 (like Znix /m4 no ballistics).
- ;========================================================================
- ;
- code segment
- org 100h
- assume cs:code,ds:code,es:code
- begin: jmp start
-
- leftkey equ 4b00h
- rightkey equ 4d00h
- upkey equ 4800h
- downkey equ 5000h
- retkey equ 1c0dh
- esckey equ 011bh
-
- mouse equ 51 ;interrupt 33h
- resetmousedriver equ 0 ;reset mouse driver
- pressmouse equ 5 ;mouse button press status
- mousemotion equ 11 ;mouse cursor motion
- seteventhandler equ 12 ;set mask and event handler
- setsensitivity equ 15 ;set horiz & vert sensitivity
- setdoublespeed equ 19 ;set double-speed threshold
- eventmask equ 0000000000001011b
- ;evenmask bits 0,1,4: movement, left & right press
-
- horizontalsensitivity dw 8 ;8=default mickeys/8 pixels
- verticalsensitivity dw 16 ;16=default mickeys/8 pixels
- ;
- ;Mouse driver resets to 8 and 16 respectively with function 00h.
- ;Merit and Znix both worked well with settings 8,16.
- ;
- horizposition dw 0 ;store mouse cursor position X
- vertposition dw 0 ;store mouse cursor position Y
- ;
- mouseeventhandler proc far
- sti
- push ax
- push bx
- push cx
- push dx
- push di
- push ds ;ds=mouse driver data segment
-
- push cs
- pop ds ;cs=ds=TSR data segment
- cld
- ;
- ;Press Mouse supplies: BX=button status, CX=X mickeys, DX=Y mickeys.
- ; CX and DX are signed integers: up==+, right==+.
- ; Clears all button counts on each call.
- ;
- mov ax,pressmouse ;get status of button press
- mov bx,0 ;for left button
- int mouse
- and ax,1 ;Press left button?
- jz check_rightbutton ;No? Then check right button.
- mov cx,retkey ;Yes. Then plug in RETURN key.
- call stuffbuffer ;near function call
- check_rightbutton:
- mov ax,pressmouse ;get status of button press
- mov bx,2 ;for right button
- int mouse
- and ax,2 ;press right button?
- jz checkcursor ;No? Then check cursor keys.
- mov cx,esckey ;Yes. Then plug in ESC key.
- call stuffbuffer ;near function call
- checkcursor:
- mov ax,mousemotion ;Has the mouse cursor moved?
- int mouse
- mov ax,horizposition ;save new horizontal position
- add ax,cx ;cx=X coord supplied by mouse driver
- mov horizposition,ax
- cmp ax,0 ;Has the mouse cursor moved?
- je motionvertical ;No change, then check vertical
- jg motionhorizontal ;Make positive
- not ax
- motionhorizontal:
- mov bx,horizontalsensitivity
- cmp ax,bx
- jl motionvertical ;didn't move enough for a change
- cmp horizposition,0
- mov cx,rightkey
- jg stuffit1 ;If positive, then stuff cursor Right
- mov cx,leftkey
- stuffit1:
- jmp stuffit2 ;Forget about vertical motion!
- motionvertical:
- mov ax,vertposition ;save new vertical position
- add ax,dx ;dx=Y coord supplied by mouse driver
- mov vertposition,ax
- cmp ax,0
- je return ;no change, all done
- jg testvertsens ;If positive, then stuff cursor Up
- not ax
- testvertsens:
- mov bx,verticalsensitivity
- cmp ax,bx
- jl return ;didn't move enough for a change
- cmp vertposition,0
- mov cx,downkey
- jg stuffit2
- mov cx,upkey
- stuffit2:
- call manystuffbuffer ;stuff key CX into keyboard buffer
- mov vertposition,0 ;reset vertical saved position
- mov horizposition,0 ;reset horizontal saved position
- return:
- pop ds
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- mouseeventhandler endp
-
- manystuffbuffer proc near
- ; AX=amount in mickeys mouse cursor has moved.
- ; BX=sensitivity in mickeys
- ; CX=key scan code to stuff into keyboard buffer
- manyloop:
- call stuffbuffer
- sub ax,bx
- cmp ax,bx ;Full moves only
- jge manyloop
- ret
- manystuffbuffer endp
-
- stuffbuffer proc near
- cli ;Prevent interrupts from stuffing buffer
- push es ;typeahead buffer start at *[0040:0080]
- push si ;and end at *[0040:0082].
- push di ;At segment 40h and offset 01ah is
- push bx
- mov di,40h ;the offset into the typeahead buffer
- mov es,di ;for the character at the head. At
- mov bx,es:[1ch] ;segment 40h and offset 01ch is the
- mov si,bx ;offset into the typeahead buffer for
- add bx,2 ;the last character. The buffer is full
- cmp bx,es:[1ah] ;if *[01ch]+2 == *[01ah].
- je quit ;Full? Then don't add any more chars
- cmp bx,es:[82h] ;Offset less than end of buffer?
- jl isroom ;Yes. Then go ahead and stuff it.
- mov bx,es:[80h] ;Else wrap around to buffer start
- isroom:
- mov es:[si],cx ;CX=scan code to be stuffed
- mov es:[1ch],bx ;BX=new offset to last buffer character
- quit: pop bx
- pop di
- pop si
- pop es
- sti ;let other routines stuff the buffer
- ret ;near return
- stuffbuffer endp
-
- ;
- ; Code below is for detection of second install and removal of TSR
- ; Motivated by Al Williams recommendations p 516, "Dos 5: A developers
- ; Guide", M&T Books 1992.
- ;
- old2fOFF dw 0 ;Save here offset and segment
- old2fSEG dw 0 ;of old multiplex 2fh interrupt vector
- SIG equ 0cah ;Signature of this TSR, user invented.
- KILLTSR equ (SIG SHL 8)+SIG+1
- ;
- new2fINT: ;New 2fh interrupt goes here
- cmp ah,SIG ;Is it service SIG?
- jnz new2fIRET ;No, then vector to original 2fh loc.
- cmp al,SIG+1 ;Is it service SIG+1?
- jz remove ;Then remove TSR from memory.
- mov al,255 ;Otherwise, return indicator -1
- new2fIRET:
- jmp dword ptr cs:[old2fOFF]
- remove:
- push ds
- push es
- push bx
- push dx
-
- mov ax,cs
- mov ds,ax
- mov ax,352fh ;Is the present 2fh vector ours?
- int 21h
- cmp bx,offset new2fINT
- mov al,1 ;Report bad remove
- jnz removeEXIT ;Must be unchanged to remove
- cli ;Looks Ok, let's reload 2fh vector
- lds dx,dword ptr old2fOFF
- mov ax,252fh ;Replace old 2fh vector
- int 21h
- sti
- mov ax,cs ;Now free TSR memory
- mov es,ax ;Get PSP
- mov ah,49h ;Free DOS alloc memory
- int 21h ;Should return al==0
- jc removeEXIT ;Error on carry
- mov ax,0
- removeEXIT:
- pop dx
- pop bx
- pop es
- pop ds
- iret
- ;
- endresident label byte
- ;
- ;All resident code is above this point.
- ;All code below this point gets trashed by TSR exit.
- ;No unload of 100h PSP area.
- ;
- ;temporary strings
- mesg1 db 'Mouse TSR already installed',13,10,
- db 'Remove it from memory? [N]: ','$'
- mesg2 db 13,10,'$'
- mesg3 db 'Mouse TSR remains in memory','$'
- mesg4 db 'TSR removed from memory','$'
- mesg5 db 'Cannot remove TSR from memory','$'
- mesg6 db 'Mouse device has no software driver','$'
- mesg7 db 'Mouse TSR successfully installed','$'
- ;
- printstring proc near
- mov ah,9
- int 21h
- ret
- printstring endp
- ;
- start:
- push cs
- pop ds
- mov ax,(SIG SHL 8)
- int 2fh
- cmp al,0ffh ;TSR loaded?
- jne success ;No, tsr not loaded.
- mov dx,offset mesg1 ; 'Mouse TSR already installed',13,10,
- call printstring ; 'Remove it from memory? [N]: ','$'
- mov ah,1 ;Read a key.
- int 21h
- push ax ;Then print cr/lf pair
- mov dx,offset mesg2 ; 13,10,'$'
- call printstring ; to the terminal
- pop ax
- and al,0dfh ;make key upper case
- cmp al,'Y' ;and test for YES
- mov dx,offset mesg3 ;'Mouse TSR remains in memory','$'
- jne printandquit ;FAIL if key was not 'Y'
- mov ax,resetmousedriver ;reset mouse driver to defaults
- int mouse ;so mouse driver does not hang
- mov ax,KILLTSR ;otherwise kill TSR
- int 2fh ;using MUX interrupt
- or al,al ;which returns zero if it worked
- mov dx,offset mesg4 ;'TSR removed from memory','$'
- jz printandquit
- mov dx,offset mesg5 ;'Cannot remove TSR from memory','$'
- jmp printandquit
-
- success:
- mov ax,resetmousedriver ;reset mouse driver to defaults
- int mouse
- cmp ax,0 ;bx=number of buttons, not used yet
- mov dx,offset mesg6 ; 'Mouse device has no software driver','$'
- je printandquit ;exit if no mouse driver loaded
- mov ax,cs ;Hook mouse driver to event handler
- mov es,ax ;es=segment of event handler
- mov dx,offset mouseeventhandler
- mov ax,seteventhandler ;mouse driver function code
- mov cx,eventmask ;signal mask for interrupt
- int mouse
- mov ax,352fh ;get DOS interrupt vector 2fh
- int 21h
- mov [old2fSEG],es ;save segment and offset
- mov [old2fOFF],bx
- mov es,cs:[2ch] ;es=environment segment
- mov ah,49h ;free DOS alloc memory
- int 21h
- mov dx,offset mesg7 ; 'Mouse TSR successfully installed','$'
- call printstring ;print a success message
- mov ax,cs ;adjust to data segment
- mov ds,ax
- mov dx,offset new2fINT ;install new 2fh interrupt vector
- mov ax,252fh ;at routine "new2fINT" in this code seg
- int 21h
- mov dx,(endresident-begin+100h+15)/16
- mov ax,3100h ;save resident code & exit.
- int 21h
- printandquit:
- call printstring ;Print string ds:dx until '$' sentinel
- mov ax,4ch ;Then normal exit to dos.
- int 21h
- code ends
- end begin
-