Аппаратное обеспечение персонального компьютера

Программа MSDRIVER


Программа MSDRIVER иллюстрирует способ работы с драйвером событий.

Исходный текст драйвера событий, составленный на языке ассемблера, представлен в листинге 3.5.

Листинг 3.5. Файл msdriver\handler.asm

;**

;.Name       ms_handl

;.Title      Драйвер событий

;

;.Descr      Драйвер событий вызывается драйвером мыши,

;            когда происходит какое-нибудь событие из числа

;            заданных при установке драйвера событий.

;            Функция не должна вызываться из программы

;            пользователя, ее вызывает только драйвер мыши.

;



;.Proto      void far ms_handl(void);

;

;.Params     Не используются

;**

       DOSSEG

DGROUP  GROUP   _DATA

_DATA   SEGMENT WORD PUBLIC 'DATA'

_DATA   ENDS

_TEXT   SEGMENT WORD PUBLIC 'CODE'

       ASSUME  cs:_TEXT, ds:DGROUP, ss:DGROUP

; Флаг вызова драйвера событий

extrn   _ms_flag:word

; Внешние переменные для записи содержимого регистров

extrn   _ms_bx:word

extrn   _ms_cx:word

extrn   _ms_dx:word

extrn   _ms_si:word

extrn   _ms_di:word

extrn   _ms_ds:word

public  _ms_handl

_ms_handl   proc far

       mov     _ms_ds, ds

; Так как на входе в драйвер событий регистр DS указывает на

; сегмент данных драйвера мыши, устанавливаем его на сегмент

; данных программы;

       push    ax

       mov     ax, DGROUP

       mov     ds, ax

       pop     ax

       mov     _ms_bx, bx

       mov     _ms_cx, cx

       mov     _ms_dx, dx

       mov     _ms_si, si

       mov     _ms_di, di

; Устанавливаем флаг вызова драйвера в 1, сигнализируя

; программе о том, что произошло событие.

       mov     _ms_flag, 1

       ret

_ms_handl   endp

_TEXT   ENDS

       END

При вызове этот драйвер вызове устанавливает глобальную переменную _ms_flag в единицу, затем переписывает содержимое всех нужных регистров в соответствующие глобальные переменные.

Программа, установив драйвер событий и сбросив флаг _ms_flag, может выполнять какие-либо действия (например, вывод на экран движущегося изображения), постоянно проверяя флаг _ms_flag.
Как только произойдет какое-либо событие ( нажатие или отпускание клавиши мыши, перемещение мыши) драйвер событий установит флаг в единицу. Программа при этом может узнать состояние мыши, прочитав содержимое глобальных переменных _ms_bx, _ms_dx, и т.д.

Исходный текст программы MSDRIVER представлен в листинге 3.6.

Листинг 3.6. Файл msdriver\msdriver.с

// =====================================================

// Работа с драйвером событий

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//            или

//         http://www.dials.ccas.ru/frolov

// =====================================================

#include <dos.h>

#include <stdio.h>

#include <conio.h>

union REGS reg;

struct SREGS segregs;

extern void far MS_HANDL(void);

void ms_seth(int mask, void (far *hand)());

// Флаг драйвера событий. При вызове драйвер событий

// запишет в эту переменную значение 1

unsigned MS_FLAG;

// Область для содержимого регистров на входе

// в драйвер событий.

unsigned MS_BX;

unsigned MS_CX;

unsigned MS_DX;

unsigned MS_SI;

unsigned MS_DI;

unsigned MS_DS;

int main (void)

{

  MS_FLAG=0;

  // Инициализируем мышь

  reg.x.ax = 0;

  int86(0x33, &reg, &reg);

 

  if(reg.x.bx == 0)

  {  

    printf("Mouse not found\n");

    return -1;

  }

  // Подключаем драйвер событий, устанавливаем маску таким

  // образом, чтобы драйвер вызывался при нажатии на левую

  // или правую клавиши мыши

  ms_seth(2 | 8, MS_HANDL);

  // Включаем курсор

  reg.x.ax = 1;

  int86(0x33, &reg, &reg);

  // Ожидаем вызова драйвера событий.

  for(;;)

  {

    if(MS_FLAG)

    {

      printf("\nRegisters on driver entry:"

        "\nms_bx: %0X"

        "\nms_cx: %0X"

        "\nms_dx: %0X"

        "\nms_si: %0X"

        "\nms_di: %0X"

        "\nms_ds: %0X",

        MS_BX, MS_CX, MS_DX, MS_SI, MS_DI, MS_DS);

        printf("\nPress any key...");

        getch();

        return 0;

     }

  }

}

void ms_seth(int mask, void (far *hand)())

{

  reg.x.ax = 0x14;

  reg.x.cx = mask;

  reg.x.dx = FP_OFF(hand);

  segregs.es = FP_SEG(hand);

  int86x(0x33,&reg,&reg,&segregs);

}


Содержание раздела