📄 mouse5.asm
字号:
;*
;* COW : Character Oriented Windows
;*
;* mouse5.asm : mouse input control (DOS 5)
title mouse - Mouse control code for COW KERNEL (DOS 5)
include kernel.inc
include uevent.inc ;* MK_ values & mouse messages
include inscr.inc
include inmou.inc ;* MK_ values & mouse messages
include mouse5.inc ;* DOS 5 specific info
;*****************************************************************************
IFDEF DEBPUB
PUBLIC MouseThread, ProcessRecord
ENDIF ;DEBPUB
;*****************************************************************************
cbBuffer EQU 128
;----------------------------------------------------------------------------
sBegin DATA
assumes DS,DGROUP
externB <axMac, ayMac> ;* screen size
externB <ayMouse>
externB <instCur>
externB <ayDrawing, fMouseLockedOut> ; for drawing lockout
staticB fEnableMonitor,0 ;* TRUE => monitor is on
EVEN
areamouOff AreaMou <0, 0, 0, 0>
;* * Info for Mouse monitor thread *
staticW idThread,? ;* Thread ID
dw 64 dup (?)
labelW ThreadStack ;* Thread stack
DataBuffer MouseRcd <> ;* DataBuffer for mouse records
EVEN
staticW Bytecnt,? ;* mouse monitor record length
staticW hDevice,? ;* mouse device handle
staticW hMonitor,? ;* mouse monitor handle
staticW hPointer,? ;* mouse pointer handle
staticB BufferI, ,cbBuffer ;* Monitor buffer In
staticB BufferO, ,cbBuffer ;* Monitor buffer Out
staticB mstateOld, 0 ;* old mouse state
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>
sEnd BSS
;----------------------------------------------------------------------------
;*****************************************************************************
sBegin INIT
assumes CS,INIT
assumes DS,DGROUP
szMouse db 'MOUSE$',0 ;* device string name
szPointer db 'POINTER$',0 ;* pointer string name
;********** FInitMouse **********
;* entry : n/a
;* * Initialize mouse if present
;* exit : TRUE (1) => ok (even if mouse not present), FALSE (0) => error
init_noMouse:
xor ax,ax
jmp init_ok
cProc FInitMouse,<FAR,PUBLIC>
localW wAction ;* ignored
localV rgwPtrPos,4 ;* row, col
cBegin FInitMouse
;* * if second time initialize, just enable mouse -- the monitor
;* * and monitor thread should be still running
cmp fMousePresent,0
je @F ;* try init
jmp done_thread_start ;* thread already started
@@:
;* * OPEN Mouse device
PushArg <cs, initOffset(szMouse)>
PushArg <ds, dataOffset(hDevice)>
lea ax,wAction
PushArg <ss, ax>
xor ax,ax
PushArg <ax, ax> ; filesize (zero)
PushArg <ax> ; file attribute (zero)
push 1 ; open flag (open existing file)
push 0000000011000000b ; open mode
; DWFRRRRRISSSRAAA (private, deny none, read only)
PushArg <ax, ax> ; reserved
call DosOpen
or ax,ax
jnz init_noMouse
;* * Open monitor
PushArg <cs, initOffset(szMouse)>
PushArg <ds, dataOffset(hMonitor)>
cCall DosMonOpen
or ax,ax
jnz init_error2
;* * Register monitor
mov WORD PTR BufferI,cbBuffer
mov WORD PTR BufferO,cbBuffer
PushArg <hMonitor>
PushArg <ds, dataOffset(BufferI)>
PushArg <ds, dataOffset(BufferO)>
PushArg <2> ; Posflag = 2 (back)
PushArg <-1> ; index = -1 (current group)
cCall DosMonReg
or ax,ax
init_error2:
jnz init_error
;* * create mouse thread
PushArg <SEG kernelBase, kernelOffset(MouseThread)>
PushArg <ds, dataOffset(idThread)>
PushArg <ds, dataOffset(ThreadStack)>
cCall DosCreateThread
or ax,ax
jnz init_error
;* * bump priority of mouse thread
PushArg <2> ; scope = 2 (thread)
PushArg <3> ; class = 3 (time-critical)
PushArg <15> ; delta = 15(???)
PushArg <idThread>
cCall DosSetPrty
or ax,ax
jnz init_error
done_thread_start:
;* * open pointer
PushArg <cs, initOffset(szPointer)>
PushArg <ds, dataOffset(hPointer)>
cCall MouOpen
or ax,ax
jnz init_error
;* * get current mouse position
lea bx,rgwPtrPos
cCall MouGetPtrPos,<ds, bx, hPointer> ;* (ds == ss)
or ax,ax
jnz init_error
mov al,byte ptr [bx]
mov ayMouse,al
mov al,byte ptr [bx]+3
mov axMouse,al
;* * everything enabled
mov al,1
init_ok:
mov fEnableMonitor,al
mov fMousePresent,al
mov ax,sp ;* success
init_end:
mov fMouseOn,0
cEnd FInitMouse
init_error:
xor ax,ax ;* return error
;-- mov fMousePresent,0 ;* already off
jmp init_end
sEnd INIT
;*****************************************************************************
sBegin EXIT
assumes CS,EXIT
assumes DS,DATA
;********** EndMouse **********
;* entry : n/a
;* * Reset mouse if present
;* * change thread into a literal copy monitor
;* * we can't kill the mouse monitor thread at this time so we
;* * just nullify the effect of the monitor -- the monitor stays
;* * hooked and will remain in literal copy mode until we re-init
;* * the mouse or the main process terminates.
;* exit : n/a
cProc EndMouse,<PUBLIC, FAR>
localV mrcdT,<SIZE MouseRcd> ;* mouse record
cBegin EndMouse
cmp fMousePresent,0
je mouse_already_off
cCall DisableMouse
mov fEnableMonitor,0
;* * end use of pointer
cCall MouClose,<hPointer>
;* * NOTE: Keep fMousePresent flag set
mov fMouseOn,0
mouse_already_off:
cEnd EndMouse
sEnd EXIT
;*****************************************************************************
;* * Discardable Mouse Functions *
sBegin MOUSE
assumes CS,MOUSE
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,<>
parmW fOn
cBegin FEnableMouse
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.
cCall MouDrawPtr,<hPointer> ; Actually turn mouse on.
mov al,0ffh ; New state.
jmp short mouse_new_state
mouse_off:
jz already_ok ; Bail if it's already off.
cCall DisableMouse
xor al,al
mouse_new_state:
mov fMouseOn,al
not al ;* old state
already_ok:
xor ah,ah ; clear high order portion
cEnd FEnableMouse
;********** DisableMouse **********
;* entry/exit: n/a
;* * Disable the mouse
cProc DisableMouse, <NEAR>
cBegin DisableMouse
;* * fill in record for turning mouse off (invalidate entire region)
xor ah,ah
mov al,ayMac
dec al
mov areamouOff.dayArea,ax ;* not real height
;* documentation wrong
mov al,axMac
dec al
mov areamouOff.daxArea,ax ;* not real width
;* documentation wrong
PushArg <ds, dataOffset(areamouOff)>
PushArg <hPointer>
cCall MouRemovePtr ; Actually turn mouse off.
cEnd DisableMouse
;********** SetMousePos **********
;* entry : axNewPos
;* ayNewPos
;* * Place the mouse cursor somewhere on the screen.
;* exit : n/a
cPublic SetMousePos,<>
parmW axNewPos
parmW ayNewPos
cBegin SetMousePos
mov ax,ayNewPos
AssertEq ah,0
cmp fMousePresent,ah
jz PM99
mov ayMouse,al
mov ax,axNewPos
AssertEq ah,0
mov axMouse,al
lea ax,ayNewPos
cCall MouSetPtrPos,<ss,ax,hPointer>
AssertEq ax,0
PM99:
cEnd SetMousePos
;********** SetMouseCursor **********
;
; entry : pmcb = far pointer to a Mouse Cursor Block
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -