Turbo C使用的汇编函数 -- 鼠标管理函数

来源:互联网 发布:上海电信it研发中心 编辑:程序博客网 时间:2024/04/27 22:48

http://blog.csdn.net/maozefa/archive/2007/09/16/1786815.aspx

 

        上面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形式驻留内存。

/*  mouse.h */

#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
; mouse.asm

    include    tasm_c.inc

    DATASEG

    PUBLIC    _MouseFlag

_MouseFlag    dw    0
MouseCurFlag    dw    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
    xor    ax, ax
    int    33h
    cmp    ax, 0
    je    @@1
    mov    [_MouseFlag], bx
    xor    cx, cx
    xor    dx, dx
    mov     ax, 4
    int    33h
@@1:
    mov    ax, [_MouseFlag]
    ret
ENDP
;
; void Mouse_SetXY(int x, int y)
;
PROC    _Mouse_SetXY

    ARG    x : word, y : word

    mov    cx, [x]
    mov    dx, [y]
    mov    ax, 3
    int    33h
    ret
ENDP
;
; void Mouse_GetXY(int *x, int *y)
;
PROC    _Mouse_GetXY

    ARG    x : DPTR_, y : DPTR_

    mov    ax, 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     [word MouseCurFlag], 0
    jne    @@1
    mov    ax, 1
    int    33h
    mov    [word MouseCurFlag], 1
@@1:
    ret
ENDP
;
; void Mouse_Hide(void)
;
PROC    _Mouse_Hide

    cmp    [word _MouseFlag], 0
    je    @@1
    cmp     [word MouseCurFlag], 0
    je    @@1
    mov    ax, 2
    int    33h
    mov    [word MouseCurFlag], 0
@@1:
    ret
ENDP
;
; void Mouse_SetCursor(int x, int y, void far *prttern)
;
PROC    _Mouse_SetCursor

    ARG    x : word, y : word, prttern : far ptr

    mov    ax, 9
    mov    bx, [x]
    mov    cx, [y]
    les    dx, [dword prttern]
    int    33h
    ret
ENDP
;
; int Mouse_State(void)
;
PROC    _Mouse_State

    mov    ax, 3
    int    33h
    mov    ax, bx
    ret
ENDP
;
; int Mouse_Press(int b)
;
PROC    _Mouse_Press

    ARG    b : word

    mov    ax, 5
    mov    bx, [b]
    int    33h
    mov    ax, bx
    ret
ENDP
;
; int Mouse_Rel(int b)
;
PROC    _Mouse_Rel

    ARG    b : word

    mov    ax, 6
    mov    bx, [b]
    int    33h
    mov    ax, bx
    ret
ENDP
;
; int Mouse_InBox(int x1, int y1, int x2, int y2)
;
PROC    _Mouse_InBox

    ARG    x1 : word, y1 : word, x2 : word, y2 : word

    mov    ax, [_MouseFlag]
    cmp    ax, 0
    je    @@3
    mov    ax, 3
    int    33h
    xor    ax, ax
    mov    bx, [x1]
    cmp    bx, [x2]
    jle    @@1
    xchg    bx, [x2]
@@1:
    cmp    cx, bx
    jl    @@3
    cmp    cx, [x2]
    jg    @@3
    mov    bx, [y1]
    cmp    bx, [y2]
    jle    @@2
    xchg    bx, [y2]
@@2:
    cmp    dx, bx
    jl    @@3
    cmp    dx, [y2]
    jg    @@3
    mov    ax, 1
@@3:
    ret
ENDP
;
    END
        上面的文件中使用的插入文件tasm_c.inc和编译文件在《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》中,鼠标函数也可由C++(Trubo C++或者Borland C++)直接调用。如果有人喜欢OO,正好我发现还有个C++的鼠标汇编文件,一并贴在下面供参考,不过其中的函数都是static的:

//  mouse.hpp

#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中,必须单独编译:

; mouse.asm

    include    tasm_c.inc

MO_LEFT_PRESS    equ    -256
MO_RIGHT_PRESS    equ    -257
MO_LEFT_REL    equ    -258
MO_RIGHT_REL    equ    -259
MO_LEFT_DOUBLE    equ    -260
MO_RIGHT_DOUBLE    equ    -261
MO_STATE    equ    -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
IF LDATA
    PUBLIC    @Mouse@GetXY$qmit1
ELSE
    PUBLIC    @Mouse@GetXY$qrit1
ENDIF

    DATASEG

MouseFlag    dw    0
MouseCurFlag    dw    0
MouseTime    dd    0

    CODESEG

PROC    @Mouse@Init$qv

    mov    ax, [word MouseFlag]
    or    ax, ax
    jnz    @@1
    int    33h
    or    ax, ax
    jz    @@1
    xor    cx, cx
    xor    dx, dx
    mov     ax, 4
    int    33h
    mov    ax, 1
    mov    [MouseFlag], ax
@@1:
    ret
ENDP

PROC    @Mouse@SetXY$qii

    ARG    x : word, y : word

    cmp    [word MouseFlag], 0
    je    @@1
    mov    cx, [x]
    mov    dx, [y]
    mov    ax, 4
    int    33h
@@1:
    ret
ENDP

PROC    @Mouse@Show$qv

    cmp    [word MouseFlag], 0
    je    @@1
    cmp     [word MouseCurFlag], 0
    jne    @@1
    mov    ax, 1
    int    33h
    mov    [word MouseCurFlag], 1
@@1:
    ret
ENDP

PROC    @Mouse@Hide$qv

    cmp    [word MouseFlag], 0
    je    @@1
    cmp     [word MouseCurFlag], 0
    je    @@1
    mov    ax, 2
    int    33h
    mov    [word MouseCurFlag], 0
@@1:
    ret
ENDP

PROC    @Mouse@SetCursor$qiinv

    ARG    x : word, y : word, prttern : far ptr
    cmp    [word MouseFlag], 0
    je    @@1
    mov    ax, 9
    mov    bx, [x]
    mov    cx, [y]
    les    dx, [dword prttern]
    int    33h
@@1:
    ret
ENDP

PROC    @Mouse@InBox$qiiii

    ARG    x1 : word, y1 : word, x2 : word, y2 : word

    cmp    [word MouseFlag], 0
    jz    @@3
    mov    ax, 3
    int    33h
    mov    ax, [x2]
    mov    bx, [x1]
    cmp    bx, ax
    jle    @@1
    xchg    bx, ax
@@1:
    cmp    bx, cx
    jg    @@3
    cmp    ax, cx
    jl    @@3
    mov    ax, [y2]
    mov    bx, [y1]
    cmp    bx, ax
    jle    @@2
    xchg    bx, ax
@@2:
    cmp    bx, dx
    jg    @@3
    cmp    ax, dx
    jl    @@3
    mov    ax, 1
    jmp    short @@4
@@3:
    xor    ax, ax
@@4:
    ret
ENDP

PROC    @Mouse@InTextBox$qiiii

    ARG    Row1 : word, Col1 : word, Row2 : word, Col2 : word

    cmp    [MouseFlag], 0
    jz    @@3
    mov    ax, 3
    int    33h
    mov    bx, cx
    mov    ax, [Row2]
    cmp    ax, [Row1]
    jge    @@1
    xchg    ax, [Row1]
@@1:
    mov    cl, 3
    shl    ax, cl
    add    ax, 7
    cmp    ax, dx
    jl    @@3
    mov    ax, [Row1]
    shl    ax, cl
    cmp    ax, dx
    jg    @@3
    mov    ax, [Col2]
    cmp    ax, [Col1]
    jge    @@2
    xchg    ax, [Col1]
@@2:
    shl    ax, cl
    add    ax, 7
    cmp    ax, bx
    jl    @@3
    mov    ax, [Col1]
    shl    ax, cl
    cmp    ax, bx
    jg    @@3
    mov    ax, 1
    jmp    short @@4
@@3:
    xor    ax, ax
@@4:
    ret
ENDP

IF LDATA

PROC    @Mouse@GetXY$qmit1

ELSE

PROC    @Mouse@GetXY$qrit1

ENDIF

    ARG     x : DPTR_, y : DPTR_
    mov    ax, 3
    int    33h
    LES_    bx, [x]
    mov    [ES_ bx], cx
    LES_    bx, [y]
    mov    [ES_ bx], dx
    ret
ENDP

PROC    @Mouse@DriveFlag$qv

    mov    ax, [MouseFlag]
    ret
ENDP

PROC    @Mouse@GetMouse$qv

    mov    ax, [MouseFlag]
    or    ax, ax
    jz    @@5
    xor    bx, bx
    mov    ax, 5
    int    33h
    mov    ax, MO_LEFT_PRESS
    or    bx, bx
    jnz    @@3
    mov    bx, 1
    mov    ax, 5
    int    33h
    mov    ax, MO_RIGHT_PRESS
    or    bx, bx
    jnz    @@3
    xor    bx, bx
    mov    ax, 6
    int    33h
    or    bx, bx
    jz    @@1
    mov    ax, MO_LEFT_REL
    jmp    short @@5
@@1:
    mov    bx, 1
    mov    ax, 6
    int    33h
    jz    @@2
    mov    ax, MO_RIGHT_REL
    jmp    short @@5
@@2:
    mov    ax, 3
    int    33h
    xor    ax, ax
    test    bx, 3
    jz    @@5
    mov    ax, MO_STATE
    jmp    short @@5
@@3:
    push    ax
    mov    ah, 2ch
    int    21h
    pop    ax
    sub    dx, [word MouseTime]
    sbb    cx, [word MouseTime+2]
    or    cx, cx
    jnz    @@4
    cmp    dx, 30
    jg    @@4
    sub    ax, 4
    mov    [word MouseTime], cx
    mov    [word MouseTime+2], cx
    jmp    short @@5
@@4:
    add    [word MouseTime], dx
    adc    [word MouseTime+2], cx
@@5:
    ret
ENDP
;
    END
        下一篇给出一个XMS内存管理文件代码。

        再次声明,这几篇文章的代码是1995年前的东西,用现在的眼光去看它们,还不知道是不是C函数,只能供初学者们借鉴参考。至于是否有错误,我就不得而知了,不过,我以前使用时,没出过什么问题。有错误或建议,请来信:maozefa@hotmail.com

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/maozefa/archive/2007/09/16/1786815.aspx