Maus ansteuern ohne OS



  • Hi,
    für die Maus hat der Bios ja nix übrig. (Mehrdeutig)
    Also brauch man nen Treiber.
    1.)Gibts da vieleicht Standard PS/2 Maustreiber die ich benutzen kann?
    2.)Bzw. wie schreib ich mir nen Treiber.
    Was mir auch nicht klar ist:
    3.)) wie benutz ich ihn,
    3.1.)wo soll er hin (also einfach mit aufs Disketten Image? und wo da?),
    3.2.)was soll er sein (was compiliertes?, ne einfache Datei (wie TxT *g*))
    3.3.)in welcher Sprache schreib ich nen Treiber?

    Ich bedanke mich der Höflichkeit wegen an dieser Stelle bereits für jegliche Hilfestellungen.

    Mfg Demitrius



  • mein Tip: CuteMouse-Driver von Daniel Nagy ist OpenSource (komplett in ASM geschrieben) der hat PS2- und COM-Support mit Scrollrad-support, hab da mal eine version abgespeckt und OS-unabhängiggemacht, kann ich bei bedarf ja mal posten.



  • todo schrieb:

    kann ich bei bedarf ja mal posten.

    ja bitte bitte! 🙂



  • 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)


Anmelden zum Antworten