; MyMouse, Internal Services, Copr. 1993,1994 Matthias Kppe

		INCLUDE	mymodef.asm
		INCLUDE	grserv.asm

		PUBLIC	MakeContain, MakeMouseContained, MSaveRegs, \
			MRestoreRegs, DummyCC, ChangeAndNew, NewCursor, \
			CritCont, Exposed, UpdateMouse, DoUpdateMouse, \
			DetMouseMode, GetMode, GetIntNum, GetMPort, \
			SetMousePagePtr, ServiceTblNone, CopyServiceTbl, \
			FlushUpdate

CODE		SEGMENT BYTE PUBLIC

;
; Copyright notice
;
		DB	"MyMouse Copr. Matthias Kppe"

;
; Import gr services and make them public
;

	Def_Mapping

;
; Fit point to rectangle
;

MakeContain	PROC FAR
		ARG	R: DWORD, P: DWORD = ArgSize
		push	bp
		mov	bp, sp
		PUSH	DS
		LDS	SI, R
		LES	DI, P
		MOV	CX, ES:[DI].TPoint.x
		MOV	DX, ES:[DI].TPoint.y
		LODSW
		CMP	CX, AX
		JGE	SHORT @@1
		XCHG	CX, AX
@@1:		LODSW
		CMP	DX, AX
		JGE	SHORT @@2
		XCHG	DX, AX
@@2:		LODSW
		CMP	CX, AX
		JL	SHORT @@3
		DEC	AX
		XCHG	CX, AX
@@3:		LODSW
		CMP	DX, AX
		JL	SHORT @@4
		DEC	AX
		XCHG	DX, AX
@@4:		XCHG	CX, AX
		STOSW
		XCHG	DX, AX
		STOSW
		POP	DS
		pop	bp
		retf	ArgSize
MakeContain	ENDP

MakeMouseContained	PROC NEAR
		MOV	SI, OFFSET MouseArea
		CLD
		MOV	CX, MouseWhere.x
		MOV	DX, MouseWhere.y
		LODSW
		CMP	CX, AX
		JGE	SHORT @@1
		XCHG	CX, AX
@@1:		LODSW
		CMP	DX, AX
		JGE	SHORT @@2
		XCHG	DX, AX
@@2:		LODSW
		CMP	CX, AX
		JL	SHORT @@3
		DEC	AX
		XCHG	CX, AX
@@3:		LODSW
		CMP	DX, AX
		JL	SHORT @@4
		DEC	AX
		XCHG	DX, AX
@@4:    	MOV	MouseWhere.x, CX
		MOV	MouseWhere.y, DX
		retn
MakeMouseContained	ENDP

;
; Saving / Restoring VGA Registers
;

	Def_MapSync

MSaveRegs	PROC NEAR
		CLD
		MOV	DI, OFFSET RegArea
		MOV	AX, DS
		MOV	ES, AX
		MOV	DX, 03C4H		; SC
		IN	AL, DX			; Index
		STOSB
		MOV	DX, 03CEH		; GC
		IN	AL, DX			; Index
		STOSB
		MOV	AL, 3			; Data Rotate
		OUT	DX, AL
		INC	DX
		IN	AL, DX
		DEC	DX
		STOSB
		MOV	AL, 1			; Enable Set/Reset
		OUT	DX, AL
		INC	DX
		IN	AL, DX
		DEC	DX
		STOSB
		MOV	AL, 8			; Bit Mask
		OUT	DX, AL
		INC	DX
		IN	AL, DX
		DEC	DX
		STOSB
		MOV	AL, 5			; Graphics Mode
		OUT	DX, AL
		INC	DX
		IN	AL, DX
		STOSB
		MOV	DX, 03C4H		; SC
		MOV	AL, 2			; Map Mask
		OUT	DX, AL
		INC	DX
		IN	AL, DX
		STOSB
ifdef MustSyncMapping
		SyncMapping
endif
		mov	ax, WindowNum
		stosw
		retn
MSaveRegs	ENDP

MRestoreRegs	PROC NEAR
		CLD
		MOV	SI, OFFSET RegArea
		add	si, 2			; skip indexes
		MOV	DX, 03CEH		; GC
		MOV	AH, 3			; Data Rotate
		LODSB
		XCHG	AH, AL
		OUT	DX, AX
		MOV	AH, 1			; Enable Set/Reset
		LODSB
		XCHG	AH, AL
		OUT	DX, AX
		MOV	AH, 8			; Bit Mask
		LODSB
		XCHG	AH, AL
		OUT	DX, AX
		INC	SI
		MOV	DX, 03C4H		; SC
		MOV	AH, 2			; Map Mask
		LODSB
		XCHG	AH, AL
		OUT	DX, AX

		lodsw
;		cmp	ax, WindowNum
;		jz	@@1
		xchg	ax, dx
		call	CallMapAddr
@@1:
		MOV	SI, OFFSET RegArea
		MOV	DX, 03C4H		; SC
		LODSB
		OUT	DX, AL			; index
		MOV	DX, 03CEH		; GC
		LODSB
		OUT	DX, AL			; index
		retn
MRestoreRegs	ENDP

;
; Dummy ChangeCursor service
;

DummyCC		PROC FAR
		MOV	AX, CursorNum
		MOV	NewNum, AX
		retf
DummyCC		ENDP

;
; Handling cursor shapes
;

ChangeAndNew	PROC NEAR
		MOV	InService, 1
		CALL	ChangeCursor
					; jmp NewCursor
ChangeAndNew	ENDP

NewCursor	PROC NEAR
		MOV	InService, 1
		MOV	AX, NewNum
		CMP	AX, CursorNum
		JE	@@1
		MOV	WORD PTR CursorPtr [0], 0
		MOV	WORD PTR CursorPtr [2], 0
		PUSH	AX
		CALL	GetMCursor
		CMP	WORD PTR CursorPtr [0], 0
		JNZ	@@1
		CMP	WORD PTR CursorPtr [2], 0
		JNZ	@@1
		PUSH	0
		CALL	GetMouseCursor
@@1:		MOV	InService, 0
		retn
NewCursor       ENDP

;
; Visibility detection
;

CritCont	PROC NEAR
		MOV	AL, MousePage
		CMP	AL, CriticalPage
		JNZ	@@1
		MOV	BX, 0FFFFH
		CMP	GrFlags, 1
		JZ	SHORT @@3
		MOV	BX, 0FFF8H
@@3:    	LES	SI, CursorPtr
		MOV	CX, MouseWhere.x
		SUB	CX, ES:[SI+4]
		MOV	DX, CX
		AND	CX, BX
		CMP	CX, CriticalArea.B.X
		JGE	SHORT @@1		; rechts daneben
		MOV	AX, ES:[SI+2]
		SHL	AX, 3
		ADD	DX, AX
		MOV	CX, CriticalArea.A.X
		AND	CX, BX
		CMP	DX, CX
		JL 	SHORT @@1		; links daneben
		MOV	CX, MouseWhere.y
		SUB	CX, ES:[SI+6]
		CMP	CX, CriticalArea.B.Y
		JGE	SHORT @@1		; drunter
		ADD	CX, ES:[SI]
		CMP	CX, CriticalArea.A.Y
		JL 	SHORT @@1		; drber
		MOV	AX, 1
		retn
@@1:		XOR	AX, AX
		retn
CritCont	ENDP

Exposed		PROC NEAR
		XOR	AX, AX
		CMP	AX, MouseHidden
		JZ	SHORT @@1
		CALL	CritCont
@@1:		XOR	AL, 1
		retn
Exposed		ENDP

GetYEnd		PROC NEAR
		les	di, CursorPtr
		add	ax, es:[di]
		sub	ax, es:[di+6]
		retn
GetYEnd		ENDP

;
; Updating mouse
;

DoUpdateMouse	PROC NEAR
		CMP	Update, 0
		JZ	SHORT @@1
		CALL	MSaveRegs
		CALL	SaveLatches
		TEST	Update, 1
		JZ	SHORT @@2
		CALL    RestoreScreen
@@2:		TEST	Update, 2
		JZ	SHORT @@3
		CALL	SaveScreen
		CALL	DrawMouse
@@3:		CALL	RestoreLatches
		CALL	MRestoreRegs
		MOV	Update, 0
@@1:		retn
DoUpdateMouse	ENDP

FlushUpdate	PROC NEAR
		cmp	Update, 0
		jz	SHORT @@0
		mov	bl, 0
		call	DoSetRetrace
		mov	bl, 0
		call	DoSetClock
		call	DoUpdateMouse
@@0:		retn
FlushUpdate	ENDP

UpdateMouse	PROC NEAR
		call	FlushUpdate
		MOV	AX, MouseWhere.x
		CMP	AX, LastWhere.x
		JNE	SHORT @@1
		MOV	DX, MouseWhere.y
		CMP	DX, LastWhere.y
		JE	SHORT @@2
@@1:    	MOV	AL, IsDrawn
		AND	ax, 1
		MOV	Update, AL		; set Restore flag
		jz	SHORT @@4
		mov	ax, MouseWhere.y
		call	GetYEnd
@@4:		mov	YEnd, ax
		CALL	ChangeAndNew		; get new shape
		CALL	Exposed
		MOV	IsDrawn, AL
		SHL	AL, 1
		jz	SHORT @@5
		or	Update, AL
		jz	SHORT @@0
		mov	ax, LastWhere.Y
		call	GetYEnd
		cmp	ax, YEnd
		jna	SHORT @@5
		mov	YEnd, ax
		jmp	SHORT @@6
@@5:		OR	Update, AL
		jz	SHORT @@0
@@6:		cmp	TimingState, 1		; retrace/clock functionable
		jnz	SHORT @@3
		mov	bl, 1			; retrace on
		call	DoSetRetrace
		jmp	SHORT @@0
@@3:		CALL	DoUpdateMouse		; direct update
@@0:		MOV	AX, MouseWhere.x
		MOV	LastWhere.x, AX
		MOV	AX, MouseWhere.y
		MOV	LastWhere.y, AX
@@2:		MOV	AL, MouseButtons
		MOV	LastButtons, AL
		retn
UpdateMouse     ENDP

;
; Mouse mode services
;

DetMouseMode	PROC NEAR
		MOV	AL, MouseMode.Mode
		AND	AL, mm_Mode
		CMP	AL, mmDriver
		JZ	SHORT @@1
		CMP	AL, mmAuto
		JNZ	@@2
		MOV	AX, 0042h		; Mouse Systems: Get Storage Reqs
		INT	33h
		INC	AX			; successful?
		MOV	AL, mmSystem
		JZ	SHORT @@2
		MOV	AL, mmMicro
@@2:            and	MouseMode.Mode, NOT mm_Mode
		or	MouseMode.Mode, AL
		MOV	AX, 0024h		; Get Software ver and Mouse type
		INT	33h
		MOV	AH, MouseMode.Info
		MOV	AL, AH
		AND	AX, mm_Port + HIGH mm_IRQ
		CMP	AH, HIGH mmPortAuto
		JNZ	SHORT @@3
		CMP	CL, 3
		MOV	AH, HIGH mmPort1
		JNZ	SHORT @@3
		MOV	AH, HIGH mmPort2
@@3:		CMP	AL, HIGH mmIRQAuto
		JNZ	SHORT @@4
		MOV	AL, CL
		SHL	AL, 4
@@4:		OR	AH, AL
		MOV	MouseMode.Info, AH
@@1:		retn
DetMouseMode	ENDP

GetMode		PROC NEAR
		mov	al, MouseMode.Mode
		and	al, mm_Mode
		retn
GetMode		ENDP

GetIntNum	PROC NEAR
		MOV	AL, MouseMode.Info
		SHR	AL, 4
		ADD	AL, 8			; IntNum = IRQ + 8
		retn
GetIntNum	ENDP

GetMPort	PROC NEAR
		MOV	AL, MouseMode.Info
		AND	AL, HIGH mm_Port
		CMP	AL, HIGH mmPort1
		MOV	ES, Seg0040
		MOV	AX, ES:[Port1]
		JZ	SHORT @@1
		MOV	AX, ES:[Port2]
@@1:		retn
GetMPort	ENDP

;
; Service table handling
;

Dummy		PROC NEAR			; actually FAR
		retf
Dummy		ENDP

ServiceTblNone	PROC NEAR
		DW	Dummy
		DW	Dummy
		DW	Dummy
		DW	Dummy
		DW	Dummy
ServiceTblNone	ENDP

CopyServiceTbl	PROC NEAR
		ARG	p: DWORD = ArgSize
		push	bp
		mov	bp, sp
		push	ds ds
		pop	es
		MOV	CX, 5
		LDS	SI, p
		lea	di, DrawMouse		; MOV DI, OFFSET DrawMouse
		CLD
		MOV	AX, CS
@@1:		MOVSW
		STOSW
		LOOP	@@1
		pop	ds bp
		retn	ArgSize
CopyServiceTbl	ENDP

;
; Other services
;

SetMousePagePtr	PROC NEAR
		MOV	AL, MousePage
		XOR	AH, AH
		push	ax ax
		call	PageLinear
		mov	WORD PTR MousePageLinear[0], ax
		mov	WORD PTR MousePageLinear[2], dx
		CALL	PageAddr
		MOV	WORD PTR MousePagePtr[0], AX
		MOV	WORD PTR MousePagePtr[2], DX
		retn
SetMousePagePtr	ENDP

CODE		ENDS

		END
