📄 mouse.asm
字号:
;*
;* COW : Character Oriented Windows
;*
;* mouse.asm : mouse input control
title mouse - Mouse control code for COW KERNEL INPUT
include kernel.inc
include uevent.inc ;* for mouse messages
include inscr.inc ;* INST info
include inmou.inc
PROJECT_QB_QC = 0
ifdef PROJECT_QB
PROJECT_QB_QC = -1
endif
ifdef PROJECT_QC
PROJECT_QB_QC = -1
endif
PROJECT_QB_QC = -1 ;UNDONE - Remove this
if PROJECT_QB_QC
%out Mouse driver for QuickBASIC or QuickC
endif
;----------------------------------------------------------------------------
;* * Mouse Status
MOUSE_MOVE equ 01H
LEFT_BUTTON_DOWN equ 02H
LEFT_BUTTON_UP equ 04H
RIGHT_BUTTON_DOWN equ 08H
RIGHT_BUTTON_UP equ 10H
MOUSE_MASK equ 1FH
;----------------------------------------------------------------------------
sBegin DATA
assumes DS,DGROUP
externB <axMac, ayMac>
externB <instCur>
;* * For drawing lockout
externB <ayDrawing, fMouseLockedOut>
externB <ayMouse>
sEnd DATA
;----------------------------------------------------------------------------
sBegin BSS
assumes DS,DGROUP
;* PUBLIC
externB <fMousePresent> ;* TRUE => mouse present
;* PRIVATE
externB <axMouse>
externW <sstMouse>
externB <fMouseOn> ;* TRUE => mouse on
IFDEF MOUSE_SWAP
externB <fSwapButton> ;* TRUE => reverse buttons
ENDIF ;MOUSE_SWAP
externB <instCur>
if PROJECT_QB_QC
staticW cmdInitMouse,0
endif
sEnd BSS
;----------------------------------------------------------------------------
sBegin INIT
assumes CS,INIT
assumes DS,DGROUP
assumes SS,DGROUP
;********** FInitMouse **********
;* entry : n/a
;* * Initialize mouse if present
;* exit : TRUE => ok (even if not present), FALSE => initialize error
cProc FInitMouse,<FAR,PUBLIC,ATOMIC>,<SI>
cBegin FInitMouse
;* * Test for mouse vector present
mov ax,3533H
int 21H ; Get interrupt vector for int 33H
mov ax,es
or ax,bx
jnz @F
J_noMouse:
jmp noMouse
@@:
ifdef KANJI
; this is not for KANJI, but some dos makes int33 going to halt
; it is not enough to check verctor is zero or not.
; we have to find out mouse driver be or not.
push di ; save DI
push ds ; save DS
push cs
pop ds
mov si, initOffset MouseID ; points to mouse secret message
mov cx, offset MouseIDend - offset MouseID ; strlen of message
mov di, bx ; before entry point
sub di, cx ; back to the message
cld
rep cmpsb
pop ds ; restore DS
pop di ; restore DI
jz MouseIDend
J_noMouse_0:
mov al, 0 ; make sure NOMOUSE
jmp short J_noMouse
MouseID DB "*** This is Copyright 1983 Microsoft ***"
MouseIDend:
xor di, di
mov es, di ; clear es and di
mov ax, 'm'
int 33h
mov ax, es
or ax, di
jz J_noMouse_0 ; too old version
cmp byte ptr es:[di], 6 ; check version number
jb J_noMouse_0 ; ver6 or later?
endif ; KANJI
;* * Test for mouse driver present
if PROJECT_QB_QC
mov ax, [cmdInitMouse]
else
xor ax,ax
endif
int 33H
or ax,ax
jz J_noMouse
if PROJECT_QB_QC
mov ax,33 ; try software reset
cmp [cmdInitMouse],ax ; already initialized to software?
je @F ; brif so -- got one
;
; 33 is an undocumented mouse call, if the mouse driver is not our's,
; then it may ignore `software reset (33)' so do a full hardware reset
; if we fail the software reset.
;
int 33h ;
inc ax ; -1 means Microsoft mouse
jnz @F ; brif not Microsoft mouse
mov [cmdInitMouse],33 ; From now on a software reset is
; sufficient.
@@:
endif
;* * Set initial mouse mapping type
xor bx,bx
mov cx,077FFH
mov dx,07700H
mov ax,10
int 33H
;* * Set mouse event handler
mov ax,SEG kernelBase
mov es,ax
mov dx,offset MouseInterrupt
mov cx,MOUSE_MASK
mov ax,12 ;* set mouse extension
int 33H
mov si,8 ; 8 is used a lot
mov ax,si
mul axMac
sub ax,si
mov dx,ax ; max = 8 pixels from the right.
mov cx,3 ; min = 3 pixels from the left.
mov ax,7
int 33h ; Set horizontal range.
xor cx,cx
mov cl,instCur.inftInst.dyCharInft
or cl,cl
jnz @F
mov cx,si ; assume 8 char high (text mode)
@@: ; cx = dyChar
mov al,ayMac
mul cl
shr cx,1
sub ax,cx ; max = (dyChar / 2)
mov dx,ax ; pixels from the bottom.
mov cx,4 ; min = 4 pixels from the top.
mov ax,si
int 33h ; Set vertical range.
AssertNE al,0
if PROJECT_QB_QC
mov cl, 3
xor dx,dx
mov dl, [ayMouse]
shl dx, cl
xor ax,ax
mov al, [axMouse]
shl ax, cl
mov cx, ax
mov ax, 4
int 33H
endif
noMouse:
mov fMousePresent,al
mov ax,0001 ;* always return ok
mov fMouseOn,ah ;* mouse is off
cEnd FInitMouse
sEnd INIT
;----------------------------------------------------------------------------
sBegin EXIT
assumes CS,EXIT
assumes SS,DATA
assumes DS,DATA
;********** EndMouse **********
;* entry : n/a
;* * Reset mouse if present
;* exit : n/a
cProc EndMouse,<PUBLIC, FAR, ATOMIC>
cBegin EndMouse
xor ax,ax
cmp fMousePresent,al
jz EndMouseExit
mov fMouseOn,al
if NOT PROJECT_QB_QC
mov fMousePresent,al
mov ax,33
int 33H ; turn off mouse by resetting it.
else
mov ax, 33 ;Try Software reset first
int 33H
inc ax
jz @F
xor ax,ax ;If that fails do a hardware reset
int 33H
@@:
endif
EndMouseExit:
cEnd EndMouse
sEnd EXIT
;----------------------------------------------------------------------------
;* * Fixed : Mouse enable called by MessageBox etc.
sBegin KERNEL
assumes CS,KERNEL
assumes SS,DATA
assumes DS,DATA
;********** FEnableMouse **********
;* entry : fOn => whether mouse should be on or off
;* * Change state of mouse according to fOn
;* exit : AX = previous mouse state, always FALSE if no mouse
cPublic FEnableMouse,<ATOMIC>
parmW fOn
cBegin FEnableMouse
StartPublic
mov al,fMousePresent
or al,al
jz already_ok ; no driver => ret FALSE
mov al,fMouseOn ; old state
or al,al ; ZR/NZ -> now off/on.
mov cx,fOn ; cx == 0 => turn off
jcxz mouse_off
jnz already_ok ; Bail if it's already on.
test instCur.finstInst,finstDisableMouse
jnz already_ok ; on not allowed now.
mov ax,1 ; Actually turn mouse on.
int 33H
;* * find current mouse position to set axMouse & ayMouse
mov ax,3
int 33H ;* CX = horiz, DX = vertical position
cCall SetMousePixelPos
mov al,0ffh ;* new state
jmp short mouse_new_state
mouse_off:
jz already_ok ; Bail if it's already off.
mov ax,2 ; Actually turn mouse off.
int 33H
xor al,al
mouse_new_state:
mov fMouseOn,al
not al ;* old state
already_ok:
xor ah,ah ; clear high order portion
StopPublic
cEnd FEnableMouse
;********** SetMousePos **********
;* entry : axNewPos
;* ayNewPos
;* * Place the mouse cursor somewhere on the screen. Text only so far.
;* exit : n/a
cPublic SetMousePos,<ATOMIC>
parmW axNewPos
parmW ayNewPos
cBegin SetMousePos
StartPublic
mov ax,ayNewPos
AssertEq ah,0
cmp fMousePresent,ah
jz PM99
mov ayMouse,al
mov cl,instCur.inftInst.dyCharInft
or cl,cl
jnz @F
mov cl,8 ;* default 8 pixels high
@@:
mul cl
mov dx,ax
IFDEF LATER
-- characters other than 8 pixels wide (graphics modes)
ENDIF
mov cx,axNewPos
AssertEq ch,0
mov axMouse,cl
shl cx,1
shl cx,1
shl cx,1
mov ax,4
int 33H ;* Set Mouse Cursor Position.
PM99:
StopPublic
cEnd SetMousePos
;********** SetMouseCursor **********
;
; entry : pmcb = far pointer to a Mouse Cursor Block
;
; Set the mouse cursor shape, both text and graphics.
;
; Hercules 48K RAMFont mode means that the 16 bits of the current character
; are interpreted as the top 4 bits being attribute, and the lower 12 bits
; being character. And, those high 4 bits aren't color attributes, they're
; character attributes: boldface, reverse, overstrike, underline. So, for
; 48K RAMFont, we want the mouse cursor to be able to set the character (low
; word) but not screw up the attribute. Thus we make the mouse cursor toggle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -