home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
mousecur.asm
< prev
next >
Wrap
Assembly Source File
|
1989-09-20
|
13KB
|
463 lines
;MOUSECURsor for Microsoft Mouse drivers - 9/87, upgraded 9/89
;Based on Jeff Prosise's MOUSEKEY.
;------------------------------------------------------------
; Microsoft MOUSE.COM or MOUSE.SYS, or a compatible driver must be installed.
; Works with the Mouse Systems MSMOUSE driver, but takes less total RAM.
; MOUSER works with ANY PROGRAM that accepts the cursor keys.
; Mouse speed and buttons can be programmed.
; The cursor keys continue to work as usual. Programs with mouse drivers work
; independently of MOUSER.
; --------------------------------------------------------------------------
; PARAMETERS
; MOUSER Hn Vn Lnn Mnn Rnn ?
; ? = help (also appears if invalid command line params are entered)
; Hn, Vn n=1 to 9 - sets Horizontal or Vertical cursor speed
; Lx, Mx, Rx - x=character or 2-digit decimal ASCII value:
; Left, Middle, or Right button values
; Digit values above 31 are treated as 'extended' keys.
; Params are all optional, in any order, with any delimiters.
; --------------------------------------------------------------------------
; ABOUT TSR AND RELOADING
; Only one copy of MOUSER ever loads; after that, only the parameters
; are updated whenever the program is run.
; Some programs disable MOUSER; you can put MOUSER in the application's
; .BAT startup file, after the application program, to turn the mouse back on.
; Programs (like ACAD) with internal mouse drivers are commonly guilty of this.
; --------------------------------------------------------------------------
cr equ 0Dh
lf equ 0Ah
code segment byte public 'code'
assume cs:code, ds:code, es:code
org 100h
Start: jmp Install
ResFinder db 'MOUSER CODE' ;Used to determine if MOUSER is resident
vdelay db 8 ;vertical divider (set by Vn)
hdelay db 8 ;horizontal divider (set by Hn)
lkey dw 0Dh ;keycode for left button (set by Lnn)
rkey dw 1Bh ;keycode for right button (set by Rnn)
mkey dw 5200h ;keycode for middle button (set by Mnn)
vcount dw 0 ;vertical mickeys since last update
hcount dw 0 ;horizontal
UpDnPointer dw 0
LeRiPointer dw 0 ;keycode below is at 011Eh in code
keycode db 4Dh,4Bh,50h,48h ;codes for rt/left/dn/up cursor keys
;------------------------------------------------------------------------------
;This routine gets a FAR CALL from the Microsoft driver when the mouse is
; moved or a button is pressed.
mouse: push ds
mov dx,cs
mov ds,dx
mov dx,lkey
test ax,2 ;bit 1, left button pressed ?
jnz PutAndRet ;yes, jump
mov dx,rkey
test ax,8 ;bit 3, right button ?
jnz PutAndRet
mov dx,mkey
test ax,32 ;bit 5, middle button ?
jz Move ;no, must be mouse move
PutAndRet:
mov ax,dx
call PutCode
MouseRet:
pop ds
retf
; - - - - - - - - - - - - - - - - - - - - - - - -
;Move the cursor.
;hdelay & vdelay are input as Hn Vn params, 1-slow to 8-fast, and converted
;for decrementing to divide by 128-slow to 1-fast. It skips that number of
; mickeys (mouse increments) before responding.
Move: mov ax,0Bh ;read mouse motion counters
int 33h ; CX=hor, DX=vert count
mov LeRiPointer,0 ;point to Right keycode
mov UpDnPointer,2 ;point to Down keycode
;accumulate motion, use totals. No total exceeds +/- 32K.
add hcount,cx
jno NoHorOflo
jns HorPos
mov hcount,-32768
HorPos:
mov hcount,32767
NoHorOflo:
add vcount,dx
jno NoVertOflo
jns VertPos
mov vcount,-32768
VertPos:
mov vcount,32767
NoVertOflo:
cmp vcount,0 ;vertical count positive?
jge VDirSet
inc UpDnPointer ;point to Up code
VDirSet:
cmp hcount,0 ;horizontal count positive?
jge DivideEm
inc LeRiPointer ;point to Left code
; Now the pointers point to the proper key code for the accumulated motion.
; The counts still are signed.
;Ideally, this would alternate hor & vert codes for diagonal moves.
DivideEm:
mov ax,vcount
cwd ;extend AX to DX:AX
mov cl,vdelay
xor ch,ch
idiv cx
mov vcount,dx ;signed remainder
mov cx,ax ;CX has no. of codes to insert, signed
or cx,cx
jz DoHor
jns VertNotNeg
neg cx
VertNotNeg:
mov bx,UpDnPointer
mov ah,ds:[bx+keycode]
call MovePut
;now do the same for horiz motion
DoHor: mov ax,hcount
cwd
mov cl,hdelay
xor ch,ch
idiv cx
mov hcount,dx ;signed remainder
mov cx,ax
or cx,cx ;filter out zero to insert
jnz HorSome
jmp MouseRet
HorSome:
jns HorNotNeg
neg cx
HorNotNeg:
mov bx,LeRiPointer
mov ah,ds:[bx+keycode] ;get keycode from table
call MovePut
jmp MouseRet
MovePut:
xor al,al ;zero AL for extended keycode
PutLoop:
call PutCode
loop PutLoop ;sets CX=1 if buffer full, so will exit
ret
; - - - - - - - - - - - - - - - - - - - - - - - -
;Put the keycode in AX into the keyboard buffer.
PutCode:
push ds
push bx
mov bx,40h ;point DS to BIOS data area
mov ds,bx
cli ;disable interrupts
mov bx,ds:[1Ch] ;buffer tail
mov dx,bx
add dx,2 ;calculate next buffer position
cmp dx,ds:[82h] ;did we overshoot the buffer end?
jnz insert1 ;no, continue
mov dx,ds:[80h] ;yes, wrap around to buffer start
insert1:
cmp dx,ds:[1Ah] ;buffer head - is the buffer full?
jnz DoInsert ;no, do it
mov cx,1 ;to exit calling loop
jmp InsDone
DoInsert:
mov ds:[bx],ax
mov bx,dx ;advance &
mov ds:[1Ch],bx ; store new pointer
InsDone:
sti
pop bx
pop ds
ret
;- - - - - - - end of resident portion - - - - - - -
Banner db cr,lf,'MOUSECUR 10/87 by Paul Noeldner, Madison, WI'
db ' - - - hacked by J. E. Arkay 9/89'
db cr,lf,'$'
helpmsg db 'Cursor enabler for Microsoft Mouse drivers.'
db cr,lf,lf
db 'You can set the speed for easy pointing and the buttons for common keys.'
db cr,lf
db ' Put it in .BAT files, to set it up for your applications.'
jnkhelp db cr,lf,lf
db 'Example:',cr,lf
db ' MOUSECUR H5 V5 L13 R27 M82 shows default parameters.',cr,lf
db ' MOUSECUR H1 V2 M/ Slower cursor (for 123-style menus)'
db cr,lf
db ' MOUSECUR V7 L73 M81 R27 Faster with PGUP/PGDN (for browsing)'
db cr,lf,lf
db ' Hn, Vn Horizontal, Vertical speed 1-8 (default 5 if not entered)'
db cr,lf
db ' Lx, Mx, Rx Button characters or decimal ASCII key codes'
db cr,lf
db ' All params are optional, in any order, with any delimiter.'
db cr,lf
db ' ASCII values over 31 decimal are taken to be extended keys.'
db cr,lf,lf
db ' Commonly used keys (see a BASIC manual for more):'
db cr,lf
db '03 - CTRL-C 09 - TAB 13 - RETURN 27 - ESC'
db cr,lf
db '71 - HOME 73 - PGUP 78 - GRAY + 79 - END 81 - PGDN'
db cr,lf
db '82 - INSERT 83 - DELETE 59 THRU 68 - F1 THRU F10'
db cr,lf,lf,'$'
NoDriverMsg db cr,lf,' DRIVER MISSING: Install MOUSE.SYS, MOUSE.COM,'
db ' MSMOUSE.COM, etc.',cr,lf,lf,'$'
junkmsg db cr,lf,' INVALID PARAMETER - CHECK THIS SCREEN',7,'$'
loadmsg db 'Mouse Cursor Installed',cr,lf,lf,'$'
AdjustedMsg db 'Mouse Parameters Adjusted ',cr,lf,lf,'$'
endparm dw 81h ;offset of end of params
posted db 'N' ;is MOUSER already loaded ?
DigitFlag db 'N' ;found a digit in command line
Install:
mov dx,OFFSET Banner
mov ah,9
int 21h
mov ax,0 ;check Microsoft driver is installed and reset.
int 33h
or ax,ax
jnz DrvrOK ;AX=0FFFFh if installed OK
mov dx,OFFSET NoDriverMsg
jmp MsgExit
DrvrOK: call parms ;process command line params
call Find ;if MOUSECUR is resident, update params
cmp posted,'Y'
jnz TSR ;if not, install this copy
mov dx,OFFSET AdjustedMsg
jmp MsgExit
TSR: mov ah,9
mov dx,OFFSET loadmsg
int 21h
mov ax,0Ch ;activate Microsoft driver
mov cx,101011b ;'call mask'- call if mouse moved, or button press
mov dx,OFFSET mouse ;point ES:DX to our routine
int 33h ;pass address to mouse driver
;de-allocate the Environment Block, we don't need it
; NOTE: This sometimes leaves a uselessly small unused Block
push es
xor ax,ax
xchg ax,word ptr CS:2Ch ;Environment Block addr in the PSP
or ax,ax
jz GoRes ;skip it if there is no Env
mov es,ax
mov ah,49h ;free allocated RAM
int 21h
GoRes: pop es
mov dx,offset Banner ;bytes to stay resident
add dx,15 ;allow for fractional para
mov cl,4
shr dx,cl ;paras to stay resident
mov ax,3100h ;go TSR
int 21h
; - - - - - - - - - - - - - - - - - - -
;Process command line params (if any)
parms: mov si,80h ;point at input param length in PSP
mov ah,0
mov al,[si] ;length of params
add ax,80h ;compute end of params
mov endparm,ax ;remember it
inc si ;skip initial space in input params
parmloop:
inc si
cmp si,endparm ;at end of params ?
jle parse ;if not, process it
ret ;if so, done with setup
parse: mov al,[si] ;get next character
cmp al,' ' ;skip blanks
jz parmloop
cmp al,'/' ;skip slashes
jz parmloop
cmp al,',' ;skip commas
jz parmloop
help: cmp al,'?' ;show help?
jnz case
mov dx,OFFSET helpmsg
MsgExit:
mov ah,9
int 21h
mov ax,4C01h ;exit w/Errorlevel = 1
int 21h
case: cmp al,91 ;upper case?
jl upper
sub al,32 ;convert lower to upper case
upper: call parmcheck ;see if H, V, L, R
jmp parmloop ;continue parsing
;Check for Horizontal and Vertical Speed, Left/Right/Both button control values
parmcheck:
cmp al,'H' ;horizontal speed param ?
jnz parmv
call digedit ;next byte to AL
cmp DigitFlag,'Y'
jnz junk ;error if not
cmp al,8
ja junk
call CvtSpeed
mov hdelay,ah
ret ;back to parsing params
parmv: cmp al,'V' ;vertical speed param ?
jnz parml
call digedit ;next byte to AL
cmp DigitFlag,'Y'
jnz junk ;error if not
cmp al,8
ja junk
call CvtSpeed
mov vdelay,ah
ret
CvtSpeed:
mov ah,80h
sub al,1 ;DEC AL will not set the C flag !!
jc CvtRet ;if speed input was 0, use speed 1
mov cl,al
shr ah,cl ;each number is a factor of 2
CvtRet: ret
parml: cmp al,'L' ;left button param ?
jnz parmr
call dighex ;get 2 ASCII bytes to AX
mov lkey,ax ;left button key code
ret
parmr: cmp al,'R' ;right button param ?
jnz parmb
call dighex ;get 2 ASCII bytes to AX
mov rkey,ax ;right button key code
ret
parmb: cmp al,'M' ;middle button param ?
jnz junk ;error if not
call dighex ;get 2 ASCII bytes to AX
mov mkey,ax ;both buttons key code
ret
junk: mov dx,OFFSET junkmsg
mov ah,9
int 21h
mov dx,OFFSET jnkhelp ;help, error message for invalid parms
jmp MsgExit
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;Check for other copies of this program in memory by walking MCB's.
;See HOTBOOT3 for how to avoid the copy in the disk buffer with shorter code.
;If MOUSER is already resident, params are updated in that copy of the program.
Find: push ax
push bx
push cx
push dx
push es
cld ;compare UPward
mov ah,52h ;get DOS list of lists
int 21h
mov bx,es:[bx-2] ;starting MCB seg address
inc bx ;for first DEC below
FindLoop:
dec bx
mov es,bx ;point to the MCB
add bx,es:[3]
inc bx ;length + 1 points next MCB
inc bx ;and 1 more points next block
mov es,bx
mov ax,cs
cmp bx,ax ;BX and ES up to present CS ?
jae NoCopies
mov si,offset ResFinder ;point DS:SI to our signature
mov di,si ;look the same place in both segs
mov cx,11 ;length of 'MOUSER CODE'
repz cmpsb ;DS:[SI] - ES:[DI] and inc SI & DI
jnz FindLoop ;if not same, check next block
;Post params in current resident MOUSER
mov posted,'Y' ;flag we've done this
mov al,vdelay ;copy from this loaded copy
mov es:vdelay,al ; to resident copy
mov al,hdelay
mov es:hdelay,al
mov ax,lkey
mov es:lkey,ax
mov ax,rkey
mov es:rkey,ax
mov ax,mkey
mov es:mkey,ax
;Re-activate the Microsoft driver
mov ax,0Ch ;set driver active
mov cx,00101011b ;'call mask', move or button press (not release)
mov dx,offset mouse ;ES:DX points installed Mouse routine
int 33h
NoCopies:
pop es
pop dx
pop cx
pop bx
pop ax
ret
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;ASCII digits to hex routine
dighex: call digedit ;get next byte into AL
cmp DigitFlag,'Y'
jz digcon
ret ;otherwise got literal in AX
digcon: mov bx,ax ;save hi digit
call digedit ;get next byte
cmp DigitFlag,'Y'
jz ItsOK
jmp junk ;error if not
ItsOK: xchg ax,bx ;hi byte to AX, lo byte to BX
mov cx,10
mul cx ;AX=hi byte times 10
add ax,bx ;now AX=value
cmp al,' ' ;is number < 20h ?
jl setok ;yes, set as is
mov ah,al ;make higher nos the high byte, and
xor al,al ; null the low byte for extended keycode
setok: ret
;Get value of ASCII digit or literal into AL with AH=0
digedit:
mov DigitFlag,'N' ;assume literal, not digit
inc si
mov al,[si] ;get next byte
mov ah,al ;save literal value
sub al,30h ;convert digit to hex
jl liter ;if < 0, is literal
cmp al,9
jg liter ;if not digit, is literal
mov DigitFlag,'Y'
xor ah,ah
ret
liter: mov al,ah ;use literal character
xor ah,ah
ret ;back to param scan
code ends
end Start