上面2篇文章《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》和《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》给出了图形代码,本篇给出鼠标管理TC函数汇编码文件。该代码很简单,而且对速度没很高的要求,完全可用纯C/C++写,但是在DOS年代,即使速度稍有提高以及代码长度缩短,也愿意用汇编码或插入汇编;鼠标功能使用int 33h,要在程序中使用鼠标,必须安装鼠标驱动程序(指纯DOS环境),鼠标驱动一般有2种形式,一是mouse.sys,必须在DOS下的config.sys文件中安装:device=mouse.sys,另外一种是mouse.com,不必在config.sys中安装,在autoexec.bat或者其它批命令文件或者直接在DOS命令行中运行后,以TSR形式驻留内存。
#ifndef__MOUSE__
#define __MOUSE__
extern int MouseFlag;
#ifdef__cplusplus
extern " C " {
#endif
/* 初始化,如鼠标存在,MouseFlag=1,否则MouseFlag=0,返回该值 */
int Mouse_Init( void );
/* 置鼠标位置到X,Y */
void Mouse_SetXY( int x, int y);
/* 取鼠标当前位置到X,Y */
void Mouse_GetXY( int * x, int * y);
/* 打开鼠光标 */
void Mouse_Show( void );
/* 关闭鼠光标 */
void Mouse_Hide( void );
/* 如鼠光标在坐标(x1,y1)-(x2,y2)内返回1,否则返回0 */
int Mouse_InBox( int x1, int y1, int x2, int y2);
/* 取按钮按下信息b=0左按钮,b=1右按钮,b=2中按钮 */
int Mouse_Press( int b);
/* 取按钮放开信息b=0左按钮,b=1右按钮,b=2中按钮 */
int Mouse_Rel( int b);
/* 返回当前按钮状态,有按钮按下返回非0,否则返回0 */
int Mouse_State( void );
/* 设置鼠光标类型,X,Y为光标热点,Pattern为光标点阵地址 */
void Mouse_SetCursor( int X, int Y, void far * Pattern);
#ifdef__cplusplus
}
#endif
#endif
includetasm_c.inc
DATASEG
PUBLIC_MouseFlag
_MouseFlagdw 0
MouseCurFlagdw 0
CODESEG
PUBLIC_Mouse_Init
PUBLIC_Mouse_SetXY
PUBLIC_Mouse_GetXY
PUBLIC_Mouse_Show
PUBLIC_Mouse_Hide
PUBLIC_Mouse_State
PUBLIC_Mouse_Press
PUBLIC_Mouse_Rel
PUBLIC_Mouse_InBox
PUBLIC_Mouse_SetCursor
;
;Mouse_Init( void )
;
PROC_Mouse_Init
cmp[word_MouseFlag], 0
jne@@ 1
xorax,ax
int 33h
cmpax, 0
je@@ 1
mov[_MouseFlag],bx
xorcx,cx
xordx,dx
movax, 4
int 33h
@@ 1 :
movax,[_MouseFlag]
ret
ENDP
;
; void Mouse_SetXY( int x, int y)
;
PROC_Mouse_SetXY
ARGx:word,y:word
movcx,[x]
movdx,[y]
movax, 3
int 33h
ret
ENDP
;
; void Mouse_GetXY( int * x, int * y)
;
PROC_Mouse_GetXY
ARGx:DPTR_,y:DPTR_
movax, 3
int 33h
LES_bx,[x]
mov[ES_bx],cx
LES_bx,[y]
mov[ES_bx],dx
ret
ENDP
;
; void Mouse_Show( void )
;
PROC_Mouse_Show
cmp[word_MouseFlag], 0
je@@ 1
cmp[wordMouseCurFlag], 0
jne@@ 1
movax, 1
int 33h
mov[wordMouseCurFlag], 1
@@ 1 :
ret
ENDP
;
; void Mouse_Hide( void )
;
PROC_Mouse_Hide
cmp[word_MouseFlag], 0
je@@ 1
cmp[wordMouseCurFlag], 0
je@@ 1
movax, 2
int 33h
mov[wordMouseCurFlag], 0
@@ 1 :
ret
ENDP
;
; void Mouse_SetCursor( int x, int y, void far * prttern)
;
PROC_Mouse_SetCursor
ARGx:word,y:word,prttern:farptr
movax, 9
movbx,[x]
movcx,[y]
lesdx,[dwordprttern]
int 33h
ret
ENDP
;
; int Mouse_State( void )
;
PROC_Mouse_State
movax, 3
int 33h
movax,bx
ret
ENDP
;
; int Mouse_Press( int b)
;
PROC_Mouse_Press
ARGb:word
movax, 5
movbx,[b]
int 33h
movax,bx
ret
ENDP
;
; int Mouse_Rel( int b)
;
PROC_Mouse_Rel
ARGb:word
movax, 6
movbx,[b]
int 33h
movax,bx
ret
ENDP
;
; int Mouse_InBox( int x1, int y1, int x2, int y2)
;
PROC_Mouse_InBox
ARGx1:word,y1:word,x2:word,y2:word
movax,[_MouseFlag]
cmpax, 0
je@@ 3
movax, 3
int 33h
xorax,ax
movbx,[x1]
cmpbx,[x2]
jle@@ 1
xchgbx,[x2]
@@ 1 :
cmpcx,bx
jl@@ 3
cmpcx,[x2]
jg@@ 3
movbx,[y1]
cmpbx,[y2]
jle@@ 2
xchgbx,[y2]
@@ 2 :
cmpdx,bx
jl@@ 3
cmpdx,[y2]
jg@@ 3
movax, 1
@@ 3 :
ret
ENDP
;
END
上面的文件中使用的插入文件tasm_c.inc和编译文件在《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》中,鼠标函数也可由C++(Trubo C++或者Borland C++)直接调用。如果有人喜欢OO,正好我发现还有个C++的鼠标汇编文件,一并贴在下面供参考,不过其中的函数都是static的:
#ifndef__MOUSE_HPP
#define __MOUSE_HPP
const int
// 定义鼠标按钮状态常量
MO_LEFT_PRESS = - 256 , // 左边按钮按下
MO_RIGHT_PRESS = - 257 , // 右边按钮按下
MO_LEFT_REL = - 258 , // 左边按钮放开
MO_RIGHT_REL = - 259 , // 右边按钮放开
MO_LEFT_DOUBLE = - 260 , // 左边按钮双击
MO_RIGHT_DOUBLE = - 261 , // 右边按钮双击
MO_STATE = - 262 ; // 鼠标拖动
class Mouse
{
public :
// 初始化,如鼠标存在,返回1,否则返回0
static int Init( void );
// 置鼠标位置到X,Y
static void SetXY( int x, int y);
// 返回鼠光标当前的位置
static void GetXY( int & x, int & y);
// 返回鼠标驱动程序安装状态,1已安装,0未安装
static int DriveFlag();
// 打开鼠光标
static void Show( void );
// 关闭鼠光标
static void Hide( void );
// 如鼠光标在坐标(x1,y1)-(x2,y2)内返回1,否则返回0
static int InBox( int x1, int y1, int x2, int y2);
// 如鼠光标在文本坐标(Row1,Col1)-(Row2,Col2)内返回1,否则返回0
static int InTextBox( int Row1, int Col1, int Row2, int Col2);
// 设置鼠光标类型,X,Y为光标热点,Pattern为光标点阵地址
static void SetCursor( int X, int Y, void far * Pattern);
// 返回鼠标按钮状态,如鼠标不存在或未动作,返回0,否则返回状态值(见状态常量)
static int GetMouse();
};
#endif
下面是鼠标功能C++函数汇编码文件,其中可以看到C++函数名称管理的方式,这个文件没包括在《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》的MAKEFILE中,必须单独编译:
includetasm_c.inc
MO_LEFT_PRESSequ - 256
MO_RIGHT_PRESSequ - 257
MO_LEFT_RELequ - 258
MO_RIGHT_RELequ - 259
MO_LEFT_DOUBLEequ - 260
MO_RIGHT_DOUBLEequ - 261
MO_STATEequ - 262
PUBLIC@Mouse@Init$qv
PUBLIC@Mouse@SetXY$qii
PUBLIC@Mouse@Show$qv
PUBLIC@Mouse@Hide$qv
PUBLIC@Mouse@InBox$qiiii
PUBLIC@Mouse@InTextBox$qiiii
PUBLIC@Mouse@SetCursor$qiinv
PUBLIC@Mouse@GetMouse$qv
PUBLIC@Mouse@DriveFlag$qv
IFLDATA
PUBLIC@Mouse@GetXY$qmit1
ELSE
PUBLIC@Mouse@GetXY$qrit1
ENDIF
DATASEG
MouseFlagdw 0
MouseCurFlagdw 0
MouseTimedd 0
CODESEG
PROC@Mouse@Init$qv
movax,[wordMouseFlag]
orax,ax
jnz@@ 1
int 33h
orax,ax
jz@@ 1
xorcx,cx
xordx,dx
movax, 4
int 33h
movax, 1
mov[MouseFlag],ax
@@ 1 :
ret
ENDP
PROC@Mouse@SetXY$qii
ARGx:word,y:word
cmp[wordMouseFlag], 0
je@@ 1
movcx,[x]
movdx,[y]
movax, 4
int 33h
@@ 1 :
ret
ENDP
PROC@Mouse@Show$qv
cmp[wordMouseFlag], 0
je@@ 1
cmp[wordMouseCurFlag], 0
jne@@ 1
movax, 1
int 33h
mov[wordMouseCurFlag], 1
@@ 1 :
ret
ENDP
PROC@Mouse@Hide$qv
cmp[wordMouseFlag], 0
je@@ 1
cmp[wordMouseCurFlag], 0
je@@ 1
movax, 2
int 33h
mov[wordMouseCurFlag], 0
@@ 1 :
ret
ENDP
PROC@Mouse@SetCursor$qiinv
ARGx:word,y:word,prttern:farptr
cmp[wordMouseFlag], 0
je@@ 1
movax, 9
movbx,[x]
movcx,[y]
lesdx,[dwordprttern]
int 33h
@@ 1 :
ret
ENDP
PROC@Mouse@InBox$qiiii
ARGx1:word,y1:word,x2:word,y2:word
cmp[wordMouseFlag], 0
jz@@ 3
movax, 3
int 33h
movax,[x2]
movbx,[x1]
cmpbx,ax
jle@@ 1
xchgbx,ax
@@ 1 :
cmpbx,cx
jg@@ 3
cmpax,cx
jl@@ 3
movax,[y2]
movbx,[y1]
cmpbx,ax
jle@@ 2
xchgbx,ax
@@ 2 :
cmpbx,dx
jg@@ 3
cmpax,dx
jl@@ 3
movax, 1
jmp short @@ 4
@@ 3 :
xorax,ax
@@ 4 :
ret
ENDP
PROC@Mouse@InTextBox$qiiii
ARGRow1:word,Col1:word,Row2:word,Col2:word
cmp[MouseFlag], 0
jz@@ 3
movax, 3
int 33h
movbx,cx
movax,[Row2]
cmpax,[Row1]
jge@@ 1
xchgax,[Row1]
@@ 1 :
movcl, 3
shlax,cl
addax, 7
cmpax,dx
jl@@ 3
movax,[Row1]
shlax,cl
cmpax,dx
jg@@ 3
movax,[Col2]
cmpax,[Col1]
jge@@ 2
xchgax,[Col1]
@@ 2 :
shlax,cl
addax, 7
cmpax,bx
jl@@ 3
movax,[Col1]
shlax,cl
cmpax,bx
jg@@ 3
movax, 1
jmp short @@ 4
@@ 3 :
xorax,ax
@@ 4 :
ret
ENDP
IFLDATA
PROC@Mouse@GetXY$qmit1
ELSE
PROC@Mouse@GetXY$qrit1
ENDIF
ARGx:DPTR_,y:DPTR_
movax, 3
int 33h
LES_bx,[x]
mov[ES_bx],cx
LES_bx,[y]
mov[ES_bx],dx
ret
ENDP
PROC@Mouse@DriveFlag$qv
movax,[MouseFlag]
ret
ENDP
PROC@Mouse@GetMouse$qv
movax,[MouseFlag]
orax,ax
jz@@ 5
xorbx,bx
movax, 5
int 33h
movax,MO_LEFT_PRESS
orbx,bx
jnz@@ 3
movbx, 1
movax, 5
int 33h
movax,MO_RIGHT_PRESS
orbx,bx
jnz@@ 3
xorbx,bx
movax, 6
int 33h
orbx,bx
jz@@ 1
movax,MO_LEFT_REL
jmp short @@ 5
@@ 1 :
movbx, 1
movax, 6
int 33h
jz@@ 2
movax,MO_RIGHT_REL
jmp short @@ 5
@@ 2 :
movax, 3
int 33h
xorax,ax
testbx, 3
jz@@ 5
movax,MO_STATE
jmp short @@ 5
@@ 3 :
pushax
movah,2ch
int 21h
popax
subdx,[wordMouseTime]
sbbcx,[wordMouseTime + 2 ]
orcx,cx
jnz@@ 4
cmpdx, 30
jg@@ 4
subax, 4
mov[wordMouseTime],cx
mov[wordMouseTime + 2 ],cx
jmp short @@ 5
@@ 4 :
add[wordMouseTime],dx
adc[wordMouseTime + 2 ],cx
@@ 5 :
ret
ENDP
;
END
下一篇给出一个XMS内存管理文件代码。
再次声明,这几篇文章的代码是1995年前的东西,用现在的眼光去看它们,还不知道是不是C函数,只能供初学者们借鉴参考。至于是否有错误,我就不得而知了,不过,我以前使用时,没出过什么问题。有错误或建议,请来信:maozefa@hotmail.com