Source file: /~heha/hs/t_und_m.zip/SRC/MOUSEH.ASM

;Rollmaus-Treiber

	.386			;32bit-Segmente aktivieren
	include tvmm.inc	;Generelles
	include	debug.inc	;wegen Debugging
	include	vpicd.inc	;Interrupt-Controller
MOUSEH_Device_ID	equ	37FCh	;NICHT RESERVIERT!
MOUSEH_Major_Ver	equ	1
MOUSEH_Minor_Ver	equ	0

;=============================
ifdef DEBUG
	%OUT	!Assembliere Debugversion!
endif

	locals	@@

Declare_Virtual_Device  MOUSEH, MOUSEH_Major_Ver, MOUSEH_Minor_Ver,\
			MOUSEH_Control_Proc, MOUSEH_Device_ID,\
			Undefined_Init_Order,MOUSEH_API,MOUSEH_API

;*********************************************************
;*** Obligatorischer VxD-Botschafts-Funktionsverteiler ***
;*********************************************************
VxD_Locked_Code_Seg
BeginProc MOUSEH_Control_Proc
	Control_Dispatch Sys_VM_Init, MOUSEH_Init
	Control_Dispatch Sys_VM_Terminate, MOUSEH_Exit
	clc
	ret
EndProc MOUSEH_Control_Proc
VxD_Locked_Code_ends

MOUSEINFO struc
msExists        DB      0       ; true => mouse exists
msRelative      DB      0       ; true => relative coordinate
msNumButtons    DW      0       ; number of buttons on the mouse
msRate          DW      0       ; maximum rate of mouse input events
msXThresh       DW      0       ; threshold before acceleration
msYThresh       DW      0       ;
msXRes          DW      0       ; x resolution
msYRes          DW      0       ; y resolution
MOUSEINFO ends

;********************************************************
;*** Residenter Datenbereich und Konstantendefinition ***
;********************************************************
VxD_Locked_Data_Seg

IrqHand		dd	?	;IRQ-Griff

mouse_event	dd	?	;Callback-Adresse (in USER.EXE)
bytebuffer	db	4 dup (?)
bytecount	db	0
prevbuttons	db	0

VxD_Locked_Data_Ends

VxD_Locked_Code_Seg

;****************************
;*** Periodische Aktionen ***
;****************************

NewIrq12 PROC
	mov	eax,[IrqHand]
	VxDCall	VPICD_Phys_EOI
	in	al,64h
	not	al
	and	al,21h		;Mausdaten?
	stc
	jnz	@@e		;nein, IRQ weiterreichen
	in	al,60h		;Maus-Byte
	sti
	movzx	ecx,[bytecount]
	mov	[bytebuffer+ecx],al
	jecxz	@@1
	jmp	@@2
@@1:
	test	al,8		;kann 1. Byte sein?
	jz	@@e		;nein!
	cmp	al,0FAh		;ACK-Byte?
	je	@@e		;auch kein Mausdatenpaket
@@2:	inc	cl
	and	cl,3		;nur 0..3
	mov	[bytecount],cl
	jecxz	@@3
@@e:
	ret
@@3:	;mouse_event benachrichtigen
	mov	edx,dword ptr [bytebuffer]
	mov	eax,High_Pri_Device_Boost
	VMMCall	Get_Sys_VM_Handle
	mov	ecx,PEF_Wait_For_STI or PEF_Wait_Not_Crit or PEF_Always_Sched
	lea	esi,[call_mouse_event]
	xor	edi,edi		;Timeout sicherheitshalber auf Null
	VMMCall	Call_Priority_VM_Event
	ret

NewIrq12 ENDP

;******************************************
;*** Rückruf-Funktion ***
;******************************************

BeginProc call_mouse_event
;in EDX sind die vier Maus-Bytes enthalten
 INT 1
	Push_Client_State Uses_EDI
	VMMCall	Begin_Nest_Exec

	mov	al,DL
;Buttons in Zweierschritten aufblasen (L=left, R=right, M=middle)
	shl	eax,6			;AX = 0000000M RL000000
	and	ah,1
	add	ah,ah			;AX = 000000M0 RL000000
	add	eax,eax			;AX = 00000M0R L0000000
	add	ah,ah			;AX = 0000M0R0 L0000000
	add	eax,eax			;AX = 000M0R0L 00000000
	mov	al,ah			;AX = 000M0R0L 000M0R0L

	xchg	al,[prevbuttons]

	mov	ecx,eax			;AX =  new  old, CX =  new  old
	xchg	ah,al			;AX =  old  new, CX =  new  old
	not	ecx			;AX =  old  new, CX = /new /old
	and	ecx,eax			;CL = new AND NOT old = ButtonDown,
					;CH = old AND NOT new = ButtonUp
	add	ch,ch
	or	cl,ch			;interleave the bits: 00ududud
	mov	ch,0

	bt	EDX,4			;test for X negative
	sbb	ah,ah
	mov	al,DH
	mov	[ebp.Client_BX],ax

	bt	EDX,5			;test for Y negative
	sbb	ah,ah
	ror	EDX,16
	mov	al,DL
	neg	ax			;They don't know which direction is up
	mov	[ebp.Client_CX],ax

	or	ax,[ebp.Client_BX]	;Set movement bit if movement
	neg	ax
	adc	cl,cl			;CY einschieben, Nulltest
	mov	[ebp.Client_AX],cx
	mov	[ebp.Client_DX],3	;three buttons
	mov	[ebp.Client_SI],0	;zero extra info
	mov	[ebp.Client_DI],0	;zero extra info
	jnz	@@have_data
	or	DH,DH
	jz	@@no_data
@@have_data:
	or	DH,DH
	jz	@@no_wheel
	mov	al,-120			;change sign to reverse direction
	imul	DH
	mov	[ebp.Client_SI],ax
	mov	[ebp.Client_DI],4001h
	or	[ebp.Client_AL],40h	;deliver extra MButtonUp
@@no_wheel:

	movzx	edx,word ptr [mouse_event]
	mov	cx,word ptr [mouse_event+2]
	jcxz	@@no_data
	VMMCall	Simulate_Far_Call
	VMMCall	Resume_Exec
@@no_data:
	VMMCall	End_Nest_Exec
	Pop_Client_State Uses_ESI
@@e:
	ret
EndProc call_mouse_event

;***************************
;*** Neue API-Funktionen ***
;***************************

SendCommand1 PROC
;1-Byte-Kommando DH senden
	mov	al,0D4h
	out	64h,al
@@l1:	in	al,64h
	test	al,2
	jnz	@@l1
	mov	al,dh
	out	60h,al
	in	al,64h
	not	al
	test	al,21h		;Daten vorhanden?
	jnz	@@e
	in	al,60h		;Datum lesen
@@e:	ret
SendCommand1 ENDP

SendCommand2 PROC
;2-Byte-Kommando DH/DL senden
	call	SendCommand1
	xchg	dh,dl
	call	SendCommand1
	xchg	dh,dl
	ret
SendCommand2 ENDP

BeginProc MOUSEH_API
	mov	ax,[ebp.Client_AX]	;AX laden
	cmp	ah,4
	ja	@@e
Debug_Out "ApiCall Fkt=#AH"
	dec	ah
	jz	@@inquire
	dec	ah
	jz	@@enable
	dec	ah
	jz	@@disable
	dec	ah
	jz	@@getintvect
	mov	[ebp.Client_AX],100h	;Version
	jmp	@@e
@@inquire:
	Client_Ptr_Flat eax,ES,BX
	mov	dword ptr [eax.msExists],00030101h
	mov	[eax.msRate],34
	mov	[ebp.Client_AX],14	;14 Bytes Struktur-Länge
	jmp	@@e
@@enable:
	mov	ax,[ebp.Client_ES]
	shl	eax,16
	mov	ax,[ebp.Client_BX]
	mov	[mouse_event],eax

	mov	dh,0F4h		;aktivieren
	call	SendCommand1

	mov	eax,[IrqHand]
	VxDcall	VPICD_Physically_Unmask
	VxDcall	VPICD_Phys_EOI	;evtl. Verklemmer lösen
	jmp	@@e
@@disable:
	mov	eax,[IrqHand]
	VxDcall	VPICD_Physically_Mask

	mov	dh,0F5h
	call	SendCommand1	;deaktivieren
	jmp	@@e
@@getintvect:
	mov	ax,12
	mov	[ebp.Client_AX],ax
@@e:
	ret
EndProc MOUSEH_Api

;*********************
;*** Exit-Funktion ***
;*********************
MOUSEH_Exit proc
Debug_Out "MOUSEH_Exit"
	mov	eax,[IrqHand]
	VxDcall	VPICD_Force_Default_Behavior
	ret
MOUSEH_Exit endp

VxD_Locked_Code_Ends

;******************************
;*** Installations-Funktion ***
;******************************
VxD_IData_Seg
IrqDesc	VPICD_Irq_Descriptor <12,VPICD_Opt_Can_Share,OFFSET32 NewIrq12>
VxD_IData_Ends

VxD_ICode_Seg

BeginProc MOUSEH_Init
;* IRQ12 freischalten
Debug_Out "MOUSEH_Init"
	call	InitIntelliMouse
	lea	edi,IrqDesc
	VxDcall	VPICD_Virtualize_IRQ
	jc	@@e
	mov	[IrqHand],eax
@@e:
	ret
EndProc MOUSEH_Init

BeginProc InitIntelliMouse
	cli
	mov	al,0A8h		;Zusatzeinheit ansprechen
	out	64h,al
	mov	dh,0F6h		;Standard einstellen
	call	SendCommand1
	mov	dx,0F3C8h	;Magische Folge zur Aktivierung 4-Byte-Modus!
	call	SendCommand2
	mov	dl,64h
	call	SendCommand2
	mov	dl,50h
	call	SendCommand2
	sti
	ret
EndProc InitIntelliMouse

VxD_ICode_Ends

	END
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded