N
ok, hier ist er:
;PS2=1
WARN
j equ jmp short
movSeg macro dest,src
push src
pop dest
endm
saveFAR macro addr,segm,offs
mov word ptr addr[0],offs
mov word ptr addr[2],segm
endm
IFz macro var,addr
cmp var,0
jz addr
endm
IFnz macro var,addr
cmp var,0
jnz addr
endm
PS2serv macro serv,errlabel
mov ax,serv
int 15h
IFNB <errlabel>
jc errlabel
or ah,ah
jne errlabel
ENDIF
endm
PrintS macro addr
IFNB <addr>
IFDIFI <addr>,<dx>
mov dx,offset addr
ENDIF
ENDIF
push ds
push dx
mov al,PRINTF
call far ptr call_kernel
add sp,4
endm
POINT struc
X dw 0
Y dw 0
ends
.model tiny ; it is a COM file
include ..\Include\Krnl_API.Asi
.386
.data
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ INITIALIZATION PART DATA ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
mousetype db ? ; 1=MS, 2=LT, 3=MSys
_options db 0
OPT_PS2 equ 00000001b
OPT_SERIAL equ 00000010b
OPT_COMforced equ 00000100b
OPT_PS2after equ 00001000b
OPT_3button equ 00010000b
OPT_NOMSYS equ 00100000b
OPT_LEFTHAND equ 01000000b
;OPT_NOUMB equ 10000000b
f_installed db 0
f_ps2 db 0
Copyright db ' CuteMouse 1.73',0dh,0ah,0
S_already db ' Mouse driver already loaded',0dh,0ah
S_info db ' Installed at ',0
;IFNDEF PS2
S_atCOM db 'COM '
com_port db 0,' for ',0
S_drvMS db 'Microsoft mouse',0dh,0ah,0
S_drvMouse db 'Mouse Systems mouse',0dh,0ah,0
S_drvLogi db 'Logitech MouseMan',0dh,0ah,0
E_ps2not db ' Error: PS/2 not supported',0dh,0ah,0
;ELSE
S_drvPS2 db 'PS/2 port',0dh,0ah,0
;ENDIF
;S_unloaded db 'Driver successfully unloaded...',0dh,0ah,0
;S_notinst db 'Driver is not installed!',0dh,0ah,0
;E_option db 0dh,0ah,'Error: Invalid option',0dh,0ah
; db 'Enter /? on command line for help',0dh,0ah,0
E_find db ' Error: device not found',0dh,0ah,0
.code
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ UNINITIALIZED DATA ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;!!! WARNING: don't modify uninitialized data in initialization part,
; because them not copied to new TSR
;----- application state begins here -----
evendata
rangemax POINT ? ; horizontal/vertical range max
pos POINT ?
granpos POINT ?
mickey8 POINT ? ; mickeys per 8 pixel
evendata
StartInitArea = $
mickey POINT ?
remain POINT ?
evendata
LenInitArea1 = $ - StartInitArea ; cleared by setpos_04
rangemin POINT ? ; horizontal/vertical range min
evendata
LenInitArea2 = $ - StartInitArea ; cleared by setupvideo
callmask dw ? ; user call mask
buttstatus dw ? ; buttons status
BUTTLASTSTATE struc
counter dw ?
lastrow dw ?
lastcol dw ?
ends
buttpress BUTTLASTSTATE ?
BUTTLASTSTATE ?
BUTTLASTSTATE ?
BUTTLASTSTATE ?
buttrelease BUTTLASTSTATE ?
BUTTLASTSTATE ?
BUTTLASTSTATE ?
BUTTLASTSTATE ?
evendata
LenInitArea3 = $ - StartInitArea ; cleared by softreset_21
evendata
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ INITIALIZED DATA ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
evendata
StartTSRpart label
IDstring db 'CM1.73',0
IDstringlen = $ - IDstring
evendata
RILversion label
;----- FAR pointers storage -----
oldint33 dd ? ; old INT 33h handler address
;IFNDEF PS2
oldIRQaddr dd ? ; old IRQ handler address
;ENDIF
;----- driver state begins here -----
disabled? db 1 ; 1=driver disabled?
userprocunlock db 1 ; 0=user defined proc is in progress
;IFNDEF PS2
IO_address dw ? ; IO port number
IRQintnum dw 0; ?,0;25h ; INT number of selected IRQ
PICstate db ? ; indicates which bit to clear in PIC
IOdone db ? ; indicates processed mouse bytes
IObyte1 db ? ; buttons state in serial protocol
IObyte4 db ? ; middle button state
increment POINT ?
;ENDIF
evendata
maxcoord POINT ? ; max coordinate
granu POINT {X=0,Y=0}
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ IRQ HANDLERS ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;IFDEF PS2
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Enable PS/2
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: none
; Use: none
; Modf: AX, BX, ES
; Call: none
;
PS2enableIRQ proc
mov ah,1 ; set mouse on
movSeg es,cs
mov bx,offset PS2handler
@PS2set: push ax
PS2serv 0C207h ; es:bx=ptr to handler
pop bx
PS2serv 0C200h
ret
PS2enableIRQ endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Disable PS/2
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: none
; Use: none
; Modf: AX, BX, ES
; Call: none
;
PS2disableIRQ proc
xor ax,ax
mov es,ax
mov bx,ax
j @PS2set
PS2disableIRQ endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
PS2handler proc far
cld
push ds ax bx cx dx si di bp es
movSeg ds,cs
mov bp,sp
mov cx,[bp+24] ; Y
mov bx,[bp+26] ; X
mov ax,[bp+28] ; Status
neg cx ; reverse Y movement
test al,20h ; check Y sign bit
jz @@noyneg
mov ch,0
@@noyneg: test al,10h ; check X sign bit
jz @@noxneg
dec bh
@@noxneg: db 024h ; AND AL,byte
buttonsmask db ?
call mouseupdate
pop es bp di si dx cx bx ax ds
retf
PS2handler endp
;ELSE
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Enable serial interrupt in PIC
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: none
; Use: IO_address, PICstate
; Modf: AX, DX, IOdone, IObyte4
; Call: none
;
serial_enableIRQ proc
;---------- set communication parameters (speed, parity, etc.)
mov dx,[IO_address]
add dx,3
mov al,80h
out dx,al ; {3FBh} set DLAB on
sub dx,3
mov ax,96
out dx,ax ; {3F8h},{3F9h} 1200 baud
add dx,3
db 0B0h ; MOV AL,byte
COMLCR db ?
out dx,al ; {3FBh} DLAB off, no parity,
; stop=1, length=7/8
inc dx
mov al,0Bh
out dx,al ; {3FCh} DTR/RTS/OUT2 on
sub dx,3
mov al,1
out dx,al ; {3F9h} DR int enable
dec ax ; OPTIMIZE: instead MOV AL,0
mov [IOdone],al
mov [IObyte4],al
;----------
in al,21h ; {21h} get PIC mask
mov ah,[PICstate]
not ah
and al,ah ; enable serial interrupts
out 21h,al
ret
serial_enableIRQ endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Disable serial interrupt of PIC
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: none
; Use: PICstate, IO_address
; Modf: AL, DX
; Call: none
;
serial_disableIRQ proc
in al,21h ; {21h} get PIC mask
or al,[PICstate] ; disable serial interrupts
out 21h,al
;----------
mov dx,[IO_address]
add dx,3
mov al,0
out dx,al ; {3FBh} set DLAB off
inc dx
in al,dx ; {3FCh} modem ctrl
and al,0F3h
out dx,al ; {3FCh} OUT2 off
sub dx,3
mov al,0
out dx,al ; {3F9h} all interrupts off
ret
serial_disableIRQ endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
serial_IRQhandler proc far
cld
push ds ax bx cx dx si di bp es
movSeg ds,cs
mov al,20h
out 20h,al ; {20h} end of interrupt
mov dx,[IO_address]
add dx,5
in al,dx ; {3FDh} check for overrun
mov ah,al
sub dx,5
in al,dx ; {3F8h} flush receive buffer
mov cl,[IOdone]
mov ch,0
test ah,2
jz @@nooverrun ; jump if no overrun occured
mov [IOdone],ch ; zero counter
j @@exitIRQ
@@nooverrun: test ah,1
jz @@exitIRQ ; jump if data not ready
db 0E8h ; CALL NEAR to mouseproc
mouseproc dw ?
@@exitIRQ: jmp @rethandler
serial_IRQhandler endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Process mouse bytes the Microsoft/Logitech way
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
MSLGproc proc
test al,40h ; synchro check
jz @@MSLGbyte2 ; jump if non first byte
cmp cx,3 ; first byte after 3 bytes?
MSLGJUMP1 db ? ; jmp short for MS3/jne
db offset @@MSLGbyte1-offset MSLGJUMP1-2
mov [IObyte4],ch ; middle button released
@@MSLGbyte1: mov [IOdone],1 ; request next 2/3 bytes
mov [IObyte1],al
@@MSLGprocret: ret
@@MSLGbyte2: jcxz @@MSLGprocret ; skip nonfirst byte at start
inc [IOdone] ; request next byte
loop @@MSLGbyte3
mov byte ptr [increment.X],al ; store X increment LO
ret
@@MSLGbyte3: loop @@LGbyte4
mov cl,al
mov ah,[IObyte1]
mov al,0
shr ax,2 ; bits 1/0 - X increment HI
or al,byte ptr [increment.X]
mov bh,ah
cbw
xchg bx,ax ; X increment
mov al,0
shr ax,2 ; bits 3/2 - Y increment HI
or al,cl
mov ch,ah ; bits 5/4 - L/R buttons
cbw
xchg cx,ax ; Y increment
mov al,[IObyte4]
mov dl,al
and ax,304h ; clear service info
or al,ah
db 0B6h ; MOV DH,byte
MSLGJUMP2 db ? ; zero if MS3 mouse
xor dl,al ; zero if buttons not changed
or dx,bx
or dx,cx ; zero if mouse not moved
jz @@MSLGupdate3
j @@MSLGupdate
@@LGbyte4: mov [IOdone],ch ; CH=0, request next 3/4 bytes
MSLGJUMP3 dw ? ; nop for LT/j @@MSLGprocret
; MS mode defines only 3 bytes
mov cl,5
shl ax,cl
mov al,[IObyte4]
xor ah,al
and ah,4
jz @@MSLGprocret ; return if state not changed
xor cx,cx
xor bx,bx
@@MSLGupdate3: xor al,4 ; toggle middle button state
@@MSLGupdate: mov [IObyte4],al
j mouseupdate
MSLGproc endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Process mouse bytes the Mouse Systems way
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
MSMproc proc
cbw
jcxz @@MSMbyte1
dec cx
jz @@MSMbyte24
dec cx
jz @@MSMbyte3
loop @@MSMbyte5
@@MSMbyte24: add [increment.X],ax
@@MSMnext: inc [IOdone] ; request next byte
@@MSMprocret: ret
@@MSMbyte1: mov [IObyte1],al ; save buttons state
mov [increment.X],cx ; CX=0
and al,not 7
cmp al,80h ; sync check
jne @@MSMprocret
@@MSMbyte3: mov [increment.Y],ax
j @@MSMnext
@@MSMbyte5: mov [IOdone],ch ; CH=0
add ax,[increment.Y]
mov cx,ax
neg cx
mov bx,[increment.X]
mov al,[IObyte1] ; bits 2/1/0 - L/M/R buttons
not al ; (0 if pressed)
and al,7
test al,6 ; check the L and M state
jpe @@MSMupdate ; skip if the same
xor al,6 ; swap L and M buttons
@@MSMupdate: ;j mouseupdate
MSMproc endp
;ENDIF
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Update mouse status
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: AL (new buttons state)
; BX (X increment)
; CX (Y increment)
; Out: none
; Use: mickey8, granu, callmask
; Modf: AX, BX, CX, DX, mickey, remain, pos, granpos, buttstatus,
; userprocunlock
; Call: resolute, cutrangex, cutrangey, updatebutton, showcursor
;
mouseupdate proc
push ax
;---------- calculate X movement in pixels
mov ax,bx
or ax,ax ; is X movement 0?
jz @@xmov0 ; jump if yes
db 0B2h ; MOV DL,byte
mresolution0 db 1
call resolute
add [mickey.X],ax
shl ax,3
add ax,[remain.X]
cwd
idiv [mickey8.X]
mov [remain.X],dx
add ax,[pos.X]
call cutrangex
mov [pos.X],ax
xor dx,dx
div [granu.X]
mul [granu.X]
mov dx,ax
xchg ax,[granpos.X] ; the new column is ready
sub ax,dx ; X screen shift
@@xmov0:
;---------- calculate Y movement in pixels
jcxz @@ymov0 ; jump if Y movement is 0
xchg ax,cx
db 0B2h ; MOV DL,byte
mresolution1 db 1
call resolute
add [mickey.Y],ax
shl ax,3
add ax,[remain.Y]
cwd
idiv [mickey8.Y]
mov [remain.Y],dx
add ax,[pos.Y]
call cutrangey
mov [pos.Y],ax
xor dx,dx
div [granu.Y]
mul [granu.Y]
mov dx,ax
xchg ax,[granpos.Y] ; the new row is ready
sub ax,dx ; Y screen shift
@@ymov0:
;----------
or cx,ax ; if both are 0
neg cx ; then no carry flag
sbb cx,cx
neg cx ; and result 0, else 1
pop ax
test al,3 ; check the L and R buttons
LEFTHANDJUMP db ? ; JMP SHORT for PS2^LHAND/JPE
db offset @@updatebut-offset LEFTHANDJUMP-2
xor al,3 ; swap
@@updatebut: mov ah,al ; AH=buttons state
mov ch,al
xchg al,byte ptr [buttstatus]
xor ch,al ; CH=buttons change state
mov al,cl ; AL=unrolled change state
mov cl,2 ; indicate that 1 is pressed
mov bx,offset buttpress
call updatebutton
mov cl,8 ; indicate that 2 is pressed
mov bx,offset buttpress+SIZE BUTTLASTSTATE
call updatebutton
mov cl,20h ; indicate that 3 is pressed
mov bx,offset buttpress+(SIZE BUTTLASTSTATE)*2
call updatebutton
dec [userprocunlock]
jnz @@updatedone ; exit if user proc running
;---------- call User Defined Handler
mov bx,[buttstatus]
mov cx,[granpos.X]
mov dx,[granpos.Y]
mov si,[mickey.X]
mov di,[mickey.Y]
sti
and al,byte ptr [callmask] ; is there a user call mask?
jz @@updateshow ; exit if not
db 9Ah ; CALL FAR to userproc
userproc dd 0
movSeg ds,cs
;----------
@@updateshow:
@@updatedone: cli
inc [userprocunlock]
ret
mouseupdate endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Update one button status regs to new values
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: AL (unrolled button change state)
; AH (current button state)
; CL (press bit mask)
; CH (button change state)
; BX (offset to item of buttpress)
; Out: AX, CH
; Use: granpos
; Modf: BX, CL, buttpress, buttrelease
; Call: none
;
updatebutton proc
shr ah,1
jc @@updset ; jump if pressed
shl cl,1 ; indicate that is released
add bx,offset buttrelease-offset buttpress
@@updset: shr ch,1
jnc @@updret ; jump if button unchanged
or al,cl
inc [bx.counter]
push ax
mov ax,[granpos.Y]
mov [bx.lastrow],ax
mov ax,[granpos.X]
mov [bx.lastcol],ax
pop ax
@@updret: ret
updatebutton endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Use selected resolution
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: AX (X/Y increment)
; DL (multiplier)
; Out: AX (scaled increment)
; Use: none
; Modf: DX
; Call: none
;
resolute proc
or dl,dl
jnz @@resolute
sar ax,2
mov dl,al
and dl,0Fh ;*** ??? *** signed value
cmp dl,10
jbe @@resolute
mov dl,10
@@resolute: cmp dl,1 ; is resolution 1 or 0?
jbe @@resret ; exit if yes
cmp ax,3 ; was movement smaller than +3?
jb @@resret ; exit if yes
cmp ax,-3 ; was movement larger than -3?
ja @@resret ; exit if yes
cmp ax,8 ; was movement between +3 and +8?
jb @@ressmall ; jump if yes
cmp ax,-8 ; was movement between -3 and -8?
ja @@ressmall ; jump if yes
mov dh,0
imul dx ; else multiply it with resolution
ret
@@ressmall: shl ax,1 ; small movement -> multiply by 2
@@resret: ret
resolute endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Cut coordinate inside range
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
cutrangex proc
cmp ax,[rangemin.X]
jg @@cutxhi
mov ax,[rangemin.X]
@@cutxhi: cmp ax,[rangemax.X]
jl @@cutxret
mov ax,[rangemax.X]
@@cutxret: ret
cutrangex endp
cutrangey proc
cmp ax,[rangemin.Y]
jg @@cutyhi
mov ax,[rangemin.Y]
@@cutyhi: cmp ax,[rangemax.Y]
jl @@cutyret
mov ax,[rangemax.Y]
@@cutyret: ret
cutrangey endp
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ END OF IRQ HANDLERS ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Setup video regs values for current video mode
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: none
; Use: 0:449h, 0:463h, 0:487h, 0:488h, 0:4A8h; buffer
; Modf: *
; Call: @setcoords
;
setupvideo proc
mov [maxcoord.X],640
mov [maxcoord.Y],480
mov byte ptr granu.X[0],1
mov byte ptr granu.Y[0],1
;---------- set parameters for ranges and cursor position
@@setuprange: mov cx,LenInitArea2/2 ; clear area 2
j @setcoords
setupvideo endp
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ INT 33 HANDLER SERVICES ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
_ARG_ES_ equ word ptr [bp]
_ARG_BP_ equ word ptr [bp+2]
_ARG_DI_ equ word ptr [bp+4]
_ARG_SI_ equ word ptr [bp+6]
_ARG_DX_ equ word ptr [bp+8]
_ARG_CX_ equ word ptr [bp+10]
_ARG_BX_ equ word ptr [bp+12]
_ARG_AX_ equ word ptr [bp+14]
_ARG_DS_ equ word ptr [bp+16]
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 00 - Reset driver
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: [AX] = 0/FFFFh (not installed/installed)
; [BX] = 2/3/FFFFh (number of buttons)
; Use: none
; Modf: none
; Call: enabledriver_20, softreset_21
;
resetdriver_00 proc
call enabledriver_20
;j softreset_21
resetdriver_00 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 21 - Software reset
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: [AX] = 21h/FFFFh (not installed/installed)
; [BX] = 2/3/FFFFh (number of buttons)
; Use: shape, maxcoord, shift320, granu
; Modf: *
; Call: @setusershape
;
softreset_21 proc
db 0B0h ; MOV AL,byte
buttonscnt db ? ; buttons count (2/3)
cbw
mov [_ARG_BX_],ax
mov [_ARG_AX_],0FFFFh
mov [mickey8.X],8
mov [mickey8.Y],16
;;+* mov [doublespeed],64
mov cx,LenInitArea3/2 ; clear area 3
;----------
@setcoords: mov ax,[granu.Y]
dec ax
jz @@setrange ; jump if graphics mode
xor ax,ax
mov es,ax
mov ax,[granu.X]
mul word ptr es:[0:44Ah]
mov [maxcoord.X],ax
mov al,byte ptr es:[0:484h]
or al,al
jnz @@mulygranu
mov al,24
@@mulygranu: inc ax ; OPTIMIZE: AX instead AL
mul byte ptr [granu.Y]
mov [maxcoord.Y],ax
@@setrange: mov ax,[maxcoord.Y] ; set lower range
mov bx,ax
dec ax
mov [rangemax.Y],ax
mov ax,[maxcoord.X] ; set right range
dec ax
push cx
;mov cl,0 ;[shift320]
;shl ax,cl
pop cx
mov [rangemax.X],ax
shr bx,1
shr ax,1
inc ax
;----------
@setpos: cli
mov [pos.X],ax
xor dx,dx
div [granu.X]
mul [granu.X]
mov [granpos.X],ax
mov ax,bx
mov [pos.Y],ax
;xor dx,dx
div [granu.Y]
mul [granu.Y]
mov [granpos.Y],ax
movSeg es,cs
mov di,offset StartInitArea
xor ax,ax
rep stosw
ret
softreset_21 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 1F - Disable mouse driver
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: [AX] = 1Fh/FFFFh (success/unsuccess)
; [ES:BX] (old int33 handler)
; Use: oldint33, IRQintnum, oldIRQaddr, oldint10
; Modf: AX, DX, ES, disabled?, cursorhidden
; Call: INT 21/25, restorescreen, disableIRQ
;
disabledrv_1F proc
les ax,[oldint33]
mov [_ARG_BX_],ax
mov [_ARG_ES_],es
mov al,1
cmp [disabled?],al
je @ret
mov [disabled?],al
cmp f_ps2,1
je ps2_disable
call serial_disableIRQ
;IFNDEF PS2
;---------- restore old IRQ handler
push word ptr [oldIRQaddr]
push word ptr [oldIRQaddr+2]
push IRQintnum
mov al,SET_INT_VECT
call far ptr call_kernel
add sp,6
j @ret
;ENDIF
ps2_disable:
call PS2disableIRQ
;----------
@ret: ret
disabledrv_1F endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 20 - Enable mouse driver
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: [AX] = 20h/FFFFh (success/unsuccess)
; Use: IRQintnum
; Modf: AX, BX, DX, ES, disabled?, oldint10, oldIRQaddr
; Call: INT 21/25, setupvideo, enableIRQ
;
enabledriver_20 proc
cli
mov al,0
cmp [disabled?],al
je @@enabled
mov [disabled?],al
cmp f_ps2,1
je @@enabled
;IFNDEF PS2
;---------- set new IRQ handler
mov al,GET_INT_VECT
push IRQintnum
call far ptr call_kernel
add sp,2
saveFAR [oldIRQaddr],dx,ax
push seg serial_IRQhandler
push offset serial_IRQhandler
push IRQintnum
mov al,SET_INT_VECT
call far ptr call_kernel
add sp,6
;ENDIF
;----------
@@enabled: call setupvideo
;call @setcoords
cmp f_ps2,1
je PS2enableIRQ
jmp serial_enableIRQ
enabledriver_20 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 03 - Return position and button status
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: [BX] (buttons status)
; [CX] (column)
; [DX] (row)
; Use: buttstatus, granpos
; Modf: AX, CX, DX
; Call: none
;
status_03 proc
mov ax,[buttstatus]
mov cx,[granpos.X]
mov dx,[granpos.Y]
j @retBCDX
status_03 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 05 - Return button press data
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: BX (button number)
; Out: [AX] (buttons states)
; [BX] (press times)
; [CX] (last press column)
; [DX] (last press row)
; Use: buttpress
; Modf: AX
; Call: @retbuttstat
;
butpresdata_05 proc
mov ax,offset buttpress
j @retbuttstat
butpresdata_05 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 06 - Return button release data
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: BX (button number)
; Out: [AX] (buttons states)
; [BX] (release times)
; [CX] (last release column)
; [DX] (last release row)
; Use: butrelease, buttstatus
; Modf: AX, BX, CX, DX
; Call: none
;
buttreldata_06 proc
mov ax,offset buttrelease
@retbuttstat: and bx,7
ERRIF (6 ne SIZE BUTTLASTSTATE) "BUTTLASTSTATE structure size changed!"
shl bx,1
add ax,bx
shl bx,1
add bx,ax ; =AX+BX*SIZE BUTTLASTSTATE
mov ax,[buttstatus]
mov [_ARG_AX_],ax
xor ax,ax
xchg [bx.counter],ax
mov cx,[bx.lastcol]
mov dx,[bx.lastrow]
@retBCDX: mov [_ARG_CX_],cx
mov [_ARG_DX_],dx
@retBX: mov [_ARG_BX_],ax
ret
buttreldata_06 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 1B - Return mouse sensitivity
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: [BX] (number of mickeys per 8 pix
; [CX] horizontally/vertically)
; [DX] (threshold speed in mickeys/second)
; Use: mickey8, /doublespeed/
; Modf: AX, CX, DX
; Call: none
;
getsens_1B proc
mov ax,[mickey8.X]
mov cx,[mickey8.Y]
j @retBCDX
getsens_1B endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 07 - Define horizontal cursor range
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: CX (min column)
; DX (max column)
; Out: none
; Use: pos
; Modf: CX, DX, rangemin.X, rangemax.X
; Call: setpos_04
;
hrange_07 proc
cmp dx,cx
jb @@swminmaxx
xchg dx,cx
@@swminmaxx: mov [rangemin.X],dx
mov [rangemax.X],cx
@resetpos: mov dx,[pos.Y]
mov cx,[pos.X]
hrange_07 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 04 - Position mouse cursor
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: CX (column)
; DX (row)
; Out: none
; Use: rangemin, rangemax
; Modf: AX, BX
; Call: cutrangex, cutrangey, @setpos, @show
;
setpos_04 proc
mov ax,dx
call cutrangey
mov bx,ax
mov ax,cx
call cutrangex
mov cx,LenInitArea1/2 ; clear area 1
call @setpos
ret
setpos_04 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 08 - Define vertical cursor range
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: CX (min row)
; DX (max row)
; Out: none
; Use: none
; Modf: CX, DX, rangemin.Y, rangemax.Y
; Call: @resetpos
;
vrange_08 proc
cmp dx,cx
jb @@swminmaxy
xchg dx,cx
@@swminmaxy: mov [rangemin.Y],dx
mov [rangemax.Y],cx
j @resetpos
vrange_08 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 0F - Define Mickey/Pixel ratio
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: CX (number of mickeys per 8 pix
; DX horizontally/vertically)
; Out: none
; Use: none
; Modf: mickey8
; Call: none
;
micperpixel_0F proc
mov [mickey8.X],cx
mov [mickey8.Y],dx
ret
micperpixel_0F endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 14 - Exchange interrupt subroutines
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: CX (new call mask)
; ES:DX (new FAR routine)
; Out: [CX] (old call mask)
; [ES:DX] (old FAR routine)
; Use: callmask, userproc
; Modf: AX
; Call: intpar_0C
;
exchangeint_14 proc
mov ax,[callmask]
mov [_ARG_CX_],ax
mov ax,word ptr userproc[0]
mov [_ARG_DX_],ax
mov ax,word ptr userproc[2]
mov [_ARG_ES_],ax
exchangeint_14 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 0C - Define interrupt subroutine parameters
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: CX (call mask)
; ES:DX (FAR routine)
; Out: none
; Use: none
; Modf: userproc, callmask
; Call: none
;
intpar_0C proc
saveFAR [userproc],es,dx
mov [callmask],cx
ret
intpar_0C endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; 1A - Set mouse sensitivity
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: BX (number of mickeys per 8 pix
; CX horizontally/vertically)
; DX (threshold speed in mickeys/second)
; Out: none
; Use: none
; Modf: mickey8
;
setsens_1A proc
mov [mickey8.X],bx
mov [mickey8.Y],cx
setsens_1A endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Null function for not implemented calls
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
nullfunc proc
ret
nullfunc endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; INT 33 handler
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;funcsoffsets dw offset resetdriver_00
; dw offset nullfunc
; dw offset nullfunc
; dw offset status_03
; dw offset setpos_04
; dw offset butpresdata_05
; dw offset buttreldata_06
; dw offset hrange_07
; dw offset vrange_08
; dw offset nullfunc
; dw offset nullfunc
; dw offset nullfunc
; dw offset intpar_0C
; dw offset nullfunc
; dw offset nullfunc
; dw offset micperpixel_0F
; dw offset nullfunc
; dw offset nullfunc
; dw offset nullfunc
; dw offset nullfunc
; dw offset exchangeint_14
; dw offset nullfunc
; dw offset nullfunc
; dw offset nullfunc
; dw offset nullfunc
; dw offset nullfunc
; dw offset setsens_1A
; dw offset getsens_1B
; dw offset nullfunc
; dw offset nullfunc
; dw offset nullfunc
; dw offset disabledrv_1F
; dw offset enabledriver_20
; dw offset softreset_21
handler33 proc far
sti
or ah,ah
jz @@no_iret
iret
;IFNDEF PS2
mouseinfo db 0,2
;ELSE
;mouseinfo db 0,4
;ENDIF
@@no_iret:
cld
push ds
movSeg ds,cs
@@calltable: cmp al,21h
ja @iret
push ax bx cx dx si di bp es
mov bp,sp
push offset @rethandler
or al,al
jnz not_00
jmp resetdriver_00
not_00:
cmp al,3
jne not_03
jmp status_03
not_03:
cmp al,4
jne not_04
jmp setpos_04
not_04:
cmp al,5
jne not_05
jmp butpresdata_05
not_05:
cmp al,6
jne not_06
jmp buttreldata_06
not_06:
cmp al,7
jne not_07
jmp hrange_07
not_07:
cmp al,8
jne not_08
jmp vrange_08
not_08:
cmp al,0Ch
jne not_0C
jmp intpar_0C
not_0C:
cmp al,0Fh
jne not_0F
jmp micperpixel_0F
not_0F:
cmp al,14h
jne not_14
jmp exchangeint_14
not_14:
cmp al,1Ah
jne not_1A
jmp setsens_1A
not_1A:
cmp al,1Bh
jne not_1B
jmp getsens_1B
not_1B:
cmp al,1Fh
jne not_1F
jmp disabledrv_1F
not_1F:
cmp al,20h
jne not_20
jmp enabledriver_20
not_20:
cmp al,21h
jne not_21
jmp softreset_21
not_21:
pop ax
;shl ax,1
;mov si,ax
;call funcsoffsets[si]
@rethandler:
pop es bp di si dx cx bx ax
@iret: pop ds
iret
handler33 endp
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ END OF INT 33 SERVICES ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
evendata
EndTSRpart label
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Real Start ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@@devnotfound: mov dx,offset E_find ; 'Error: device not found'
@@restoredrv:
;mov ax,3533h
;int 21h
;mov al,GET_INT_VECT
;push 33h
;call far ptr call_kernel
;add sp,2
@@exiterrmsg: jmp EXITERRMSG
call_kernel:
Pop DWord Ptr _ret
Push Seg call_back
Push Offset call_back
DB 0EAh
_p_kernel DD 0
call_back:
Push @Data
Pop Ds
DB 0EAh
_ret DD 0
_install_mouse_driver:
_real_start: cld
Int GET_KERNEL_API_ADRESS
Mov DWord Ptr cs:[_p_kernel],EAx
cmp f_installed,1
je inst_ret
PrintS Copyright ; 'Cute Mouse Driver'
;call commandline ; examine command line
;IFNDEF PS2
call checkPS2
jnc @@ps2found
call checkCOMsloop
jnc @@mousefound
mov bh,3
PS2serv 0C205h,@@devnotfound ; initalize PS/2 pointing dev
mov dx,offset E_ps2not ; 'Error: PS/2 not supported'
j @@restoredrv
;ELSE
call checkPS2
jc @@devnotfound
;ENDIF
@@ps2found: mov f_ps2,1
mov Byte Ptr [mouseinfo+1],4
@@mousefound:
;---------- save old INT 33h handler
mov al,GET_INT_VECT
push 33h
call far ptr call_kernel
add sp,2
saveFAR [oldint33],ax,dx
;---------- set INT 33 handler
movSeg es,cs
push seg handler33
push offset handler33
push 33h
mov al,SET_INT_VECT
call far ptr call_kernel
add sp,6
mov dx,offset S_info ; 'Installed at'
;----------
PrintS
mov dx,offset S_drvPS2 ; 'PS/2 port'
Cmp f_ps2,1
JE @@printmode
;IFNDEF PS2
PrintS S_atCOM
mov dx,offset S_drvMS ; 'Microsoft mouse'
cmp [mousetype],2
jb @@printmode
mov dx,offset S_drvLogi ; 'Logitech MouseMan'
je @@printmode
mov dx,offset S_drvMouse ; 'Mouse Systems mouse'
;ELSE
;ENDIF
@@printmode: PrintS
cmp f_ps2,1
je ps2setup
call setupdriver
jmp setup_ok
ps2setup:
call setupdriver_ps2
setup_ok:
xor ax,ax
int 33h ; Reset driver
mov f_installed,1
inst_ret:
RetF
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Setup resident driver code and parameters
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
setupdriver proc
;---------- setup left hand mode handling
mov al,0EBh ; JMP SHORT
test [_options],OPT_LEFTHAND
jnz @@setlhand_s
mov al,07Ah ; JPE
@@setlhand_s: mov es:[LEFTHANDJUMP],al
;---------- setup buttons count and mask
mov ax,703h
test [_options],OPT_3button
jnz @@setbuttons_s
cmp [mousetype],1
jne @@setbuttons_s ; jump if no MS mode
mov ax,302h
@@setbuttons_s: mov es:[buttonscnt],al
;---------- setup serial mouse handler code
mov bx,offset MSMproc-offset mouseproc-2
cmp [mousetype],2
ja @@setmousep ; jump if Mouse Systems
mov bx,offset MSLGproc-offset mouseproc-2
mov cx,9090h ; NOP/NOP
mov dx,175h ; DL=JNE, DH=0 for MS3
je @@setMSLGproc ; jump if Logitech
mov cx,0EBh+(offset @@MSLGprocret-offset MSLGJUMP3-2) SHL 8
; JMP SHORT @@MSLGprocret
cmp al,2
je @@setMSLGproc ; jump if MS with 2 buttons
mov dx,0EBh ; DL=JMP SHORT
@@setMSLGproc: mov es:[MSLGJUMP1],dl
mov es:[MSLGJUMP2],dh
mov es:[MSLGJUMP3],cx
@@setmousep: mov es:[mouseproc],bx
;---------- copy (if required) other parameters
mov al,[mresolution0]
mov es:[mresolution0],al
mov al,[mresolution1]
mov es:[mresolution1],al
mov ax,word ptr [mouseinfo]
mov word ptr es:[mouseinfo],ax
mov al,[COMLCR]
mov es:[COMLCR],al
mov ax,[IO_address]
mov es:[IO_address],ax
mov al,[PICstate]
mov es:[PICstate],al
mov al,byte ptr [IRQintnum]
mov byte ptr es:[IRQintnum],al
ret
setupdriver endp
setupdriver_ps2 proc
;---------- setup left hand mode handling
mov al,0EBh ; JMP SHORT
test [_options],OPT_LEFTHAND
jz @@setlhand
mov al,07Ah ; JPE
@@setlhand: mov es:[LEFTHANDJUMP],al
;---------- setup buttons count and mask
mov ax,703h
test [_options],OPT_3button
jnz @@setbuttons
mov ax,302h
@@setbuttons: mov es:[buttonscnt],al
mov es:[buttonsmask],ah
;---------- copy (if required) other parameters
mov al,[mresolution0]
mov es:[mresolution0],al
mov al,[mresolution1]
mov es:[mresolution1],al
mov ax,word ptr [mouseinfo]
mov word ptr es:[mouseinfo],ax
ret
setupdriver_ps2 endp
;IFNDEF PS2
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Check given or all COM-ports for mouse connection
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
checkCOMsloop proc
mov [COMLCR],2
mov cx,1
push cx
test [_options],OPT_COMforced
jnz @@searchloop
pop cx
mov cl,4
@@setCOMloop: mov al,'5'
sub al,cl
push cx
call setCOMport
@@searchloop: call COMexist?
jc @@nextsearch
call detectmouse
@@nextsearch: pop cx
jnc @@searchret
loop @@setCOMloop
;---------- set Mouse Systems mouse mode
test [_options],OPT_NOMSYS
stc
jnz @@searchret
test [_options],OPT_COMforced
jnz @@setMSYS
mov al,'1'
call setCOMport
@@setMSYS: mov al,3
mov [COMLCR],al
mov [mousetype],al
call COMexist?
@@searchret: ret
checkCOMsloop endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Check if COM port available
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: Carry flag (COM port not exist)
; Use: IO_address
; Modf: AX, CX, DX
; Call: disableIRQ
;
COMexist? proc
cli
mov cx,[IO_address]
stc
jcxz @@comexret
push cx
call serial_disableIRQ
pop dx
add dx,3
mov al,0
out dx,al ; {3FBh} reset comm params
inc dx
in al,dx ; {3FCh} modem ctrl reg
and al,0E0h ; get reserved bits
mov ah,al
sub dx,3
in al,dx ; {3F9h} int enable reg
and al,0F0h ; get reserved bits
or al,ah ; AL must be 0 if port exists
neg al ; nonzero makes carry flag
@@comexret: sti
ret
COMexist? endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Check if mouse available
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: Carry flag (no mouse found)
; Use: IO_address, COMLCR
; Modf: AX, BX, CX, DX, SI, mousetype
; Call: none
;
detectmouse proc
mov si,[IO_address]
;---------- mouse hardware reset
mov dx,si
add dx,3
mov al,80h
out dx,al ; {3FBh} set DLAB on
mov dx,si
mov ax,96
out dx,ax ; {3F8h},{3F9h} 1200 baud
add dx,3
mov al,[COMLCR]
out dx,al ; {3FBh} DLAB off, no parity,
; stop=1, length=7/8
;---------- pulse (drop and raise) RTS signal
xor ax,ax
mov es,ax
inc dx
mov di,es:[46Ch]
@@wait1: cmp di,es:[46Ch]
je @@wait1 ; wait timer tick start
out dx,al ; {3FCh} DTR/RTS/OUT2 off
mov al,3
mov di,es:[46Ch]
@@wait2: cmp di,es:[46Ch]
je @@wait2 ; wait timer tick end
out dx,al ; {3FCh} DTR/RTS on, OUT2 off
;---------- detect if Microsoft or Logitech mouse present
mov bx,101h ; bl=no MS, bh=mousetype
mov cx,4 ; scan 4 first bytes
@@detectloop: call readCOMbyte
jc @@detdone
cmp al,'M'
jne @@checkLG
mov bl,0 ; Microsoft mouse found...
@@checkLG: cmp al,'3'
jne @@detectnext
mov bh,2 ; ...Logitech mouse found
@@detectnext: loop @@detectloop
@@skipdata: call readCOMbyte
jnc @@skipdata
@@detdone: mov [mousetype],bh ; save 1=MS or 2=Logitech
neg bl ; nonzero makes carry flag
ret
detectmouse endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
readCOMbyte proc
mov ah,2 ; length of silence in ticks
mov dx,si
add dx,5
@@timeloop: mov di,es:[46Ch]
@@waitloop: in al,dx ; {3FDh} line status reg
test al,1
jnz @@readret ; jump if data ready
cmp di,es:[46Ch]
je @@waitloop ; jump if same tick
dec ah
jnz @@timeloop ; wait next tick of silence
stc
ret
@@readret: mov dx,si
in al,dx ; {3F8h} receive byte
ret
readCOMbyte endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Set Mouse Port
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: AL (COM port letter)
; Out: none
; Use: none
; Modf: AL, com_port, IO_address
; Call: setIRQ
;
setCOMport proc
mov [com_port],al
sub al,'1'
xor bx,bx
mov es,bx
mov bl,al
shl bx,1
mov bx,es:400h[bx]
mov [IO_address],bx
shr al,1
mov al,4 ; IRQ4 for COM1/3
jnc setIRQ
dec ax ; OPTIMIZE: AX instead AL
; IRQ3 for COM2/4
setCOMport endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Set IRQ number
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: AL (IRQ number)
; Out: none
; Use: none
; Modf: AL, CL, PICstate, IRQintnum
; Call: none
;
setIRQ proc
mov mouseinfo[0],al
mov cl,al
add al,8
mov byte ptr IRQintnum,al
mov al,1
shl al,cl
mov [PICstate],al ; PIC interrupt enabler
ret
setIRQ endp
;ELSE
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Check for PS/2
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: none
; Out: Carry flag
; Use: none
; Modf: AX, BX, CX
; Call: none
;
checkPS2 proc
mov bh,3
PS2serv 0C205h,@@PSerror ; initialize mouse, bh=datasize
movSeg es,cs
mov bx,offset PS2handler
PS2serv 0C207h,@@PSerror ; mouse, es:bx=ptr to handler
xor bx,bx
mov es,bx
PS2serv 0C207h ; mouse, es:bx=ptr to handler
mov bh,3
PS2serv 0C203h,@@PSerror ; set mouse resolution bh
mov bh,1
PS2serv 0C200h,@@PSerror ; set mouse on
;clc
ret
@@PSerror: stc
ret
checkPS2 endp
;ENDIF
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Check if CuteMouse driver is installed
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;
; In: ES:BX (driver address)
; Out: Zero flag (zero if installed)
; ES (driver segment)
; Use: none
; Modf: AX, CX, SI, DI
; Call: none
;
checkCuteMouse proc
cmp ax,offset handler33
jne @ret2
mov es,dx
mov si,offset IDstring
mov di,si
mov cx,IDstringlen
rep cmpsb
@ret2: ret
checkCuteMouse endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Examine Command Line
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;commandline proc
; mov si,80h
; lodsb
; mov ah,0
; mov di,ax
; add di,si
;
;@@setoption: or [_options],ah
;newopt: cmp si,di
; jae @ret2
; lodsb
;@@newopt2: cmp al,' '
; jbe newopt
; cmp al,'/' ; option character?
; jne @badoption
; cmp si,di ; option itself there?
; jae @badoption
; lodsb
; mov ah,OPT_3button
; cmp al,'3' ; '/3' -> force 3-buttons mode
; je @@setoption
;
; and al,not 20h
;IFNDEF PS2
; cmp al,'S'
; jne @@noserial
; or [_options],OPT_SERIAL ; '/S' -> force serial mouse
; cmp si,di
; jae @ret2
; lodsb
; cmp al,'1'
; jb @@newopt2
; cmp al,'4'
; ja @@newopt2
; or [_options],OPT_COMforced
; call setCOMport ; '/Sc' -> set COM port
; cmp si,di
; jae @ret2
; lodsb
; cmp al,'2'
; jb @@newopt2
; cmp al,'7'
; ja @@newopt2
; sub al,'0'
; call setIRQ ; '/Sci' -> set IRQ line
; j newopt
;@@noserial:
;ENDIF
; ;mov ah,OPT_LEFTHAND
; ;cmp al,'L' ; '/L' -> set left hand mode
; ;je @@setoption
; ;cmp al,'R' ; '/R' -> set resolution
; ;je _resolution
; ;cmp al,'U' ; '/U' -> unload drv and exit
; ;je _unload
;
;@badoption: mov dx,offset E_option ; 'Invalid parameter'
EXITERRMSG: PrintS
RetF
;mov ax,4CFFh
;int 21h ; terminate, al=return code
;
;EXIT0MSG: PrintS
;EXIT0: mov ax,4C00h
; int 21h ; terminate, al=return code
;commandline endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Set Resolution option
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
;_resolution proc
; mov ah,'0'
; cmp si,di
; jae @@dupres
; lodsb ; first argument
; cmp al,'0'
; je @@setres
; jb @@fixupres
; cmp al,'9'
; ja @@fixupres
;
; mov ah,al
; cmp si,di
; jae @@setres
; lodsb ; second argument
; cmp al,'1'
; jb @@fixupres
; cmp al,'9'
; jbe @@setres
;
;@@fixupres: dec si ; fixup for command line ptr
;@@dupres: mov al,ah ; drop invalid argument
;
;@@setres: sub ax,'00'
; mov [mresolution0],ah
; mov [mresolution1],al
; jmp newopt
;_resolution endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Release driver and quit
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
_uninstall_mouse_driver proc
cmp f_installed,0
je uninst_ret
push ds es
mov ax,1Fh
int 33h ; disable CuteMouse driver
push word ptr [oldint33]
push word ptr [oldint33+2]
push 33h
mov al,SET_INT_VECT
call far ptr call_kernel
add sp,6
pop es ds
mov f_installed,0
uninst_ret:
retf
_uninstall_mouse_driver endp
Public _install_mouse_driver, _uninstall_mouse_driver, _options
End
ist nicht 100%ig OS-unabhängig (is von meinem nie fertiggewordenen OS... (TodoX)), d.h. an den stellen, wo call_kernel aufgerufen wird, muss man selber was entsprechendes schreiben, da es hier aber nur das setzen von int-vektoren betrifft, wird wohl niemand ein problem damit haben, PS2 geht nur beim Setzen von PS2 beim Assemblieren. Wichtig ist noch, dass an dieser Stelle keinerlei Code zum Anzeigen des Mousecursors ist, das war auch mein Ziel, da man dann in einer Hochsprache das bequemer schreiben kann bzw. an eigene bedürfnisse anpassen kann, die schnittstelle ist eine stark abgespeckte Dos-Int33h-Schnittstelle, wie sie allgemein bekannt ist, sind aber wiegesagt nur die wichtigsten funktionen implementiert (kann man ja auch im Code sehen, welche und welche nicht)