Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
Показать сообщение отдельно
ФедосеевПавел
Модератор
3417 / 1914 / 815
Регистрация: 01.02.2015
Сообщений: 6,454
22.01.2017, 20:21

FAQ для раздела Assembler, MASM, TASM - Assembler

22.01.2017, 20:21. Просмотров 66769. Ответов 62
Метки (Все метки)

Кратко о работе с мышью в DOS с помощью сервисного прерывания int 33h

на примере учебного задания

Манипулятор "мышь" может физически подключаться к одному из портов COM, PS/2 или USB. В каждом из этих случаев работа на "нижнем" уровне будет очень сильно различаться. Кроме того, для разных "мышей" различаться может даже формат обмена данными. Поэтому, ещё в эпоху DOS разработчики постарались упростить работу программистам, в части взаимодействия пользовательской программы с мышью (её драйвером). Это выразилось созданием в драйвере почти унифицированного пользовательского интерфейса. Взаимодействие программы с драйвером реализовано через сервисное прерывание int 33h.

Таким образом, вся работа с мышью, свелась к конфигурированию мыши в начале программы, после которого взаимодействие происходит без (ну или почти без) дальнейшего участия программиста.

Я отдаю себе отчёт, что на форуме будут находится студенты, а не разработчики, поэтому обзор будет очень упрощённым и кратким.

Источниками для более подробного изучения работы с мышью могут послужить материалы изВзаимодействие с драйвером происходит через пользовательское прерывание int 33h. Для этого в регистр ax загружают номер вызываемой функции, при необходимости заполняют соответствующие регистры и вызывают int 33h. Как видно из описания Ральфа Брауна, некоторые функции стандартны, а некоторые присущи конкретным драйверам. К примеру, в исходниках и в документации CuteMouse видно, что данный драйвер поддерживает функции от 00h до 21h.

Итак. Я привык к разработке сверху вниз, поэтому и пояснения буду приводить в этом порядке. Не вижу смысла в перепечатывании справочной информации по функциям int 33h.

Возьму для обозначения цели задачу http://www.cyberforum.ru/assembler-dos/thread1904880.html
Составить программу по управлению манипулятором «мышь». Если координаты курсора «мышь» лежат в диапазоне 0<x<300 и 0<y<100 , то курсор мыши имеет форму «+» в противном случае – «0».
Из основной программы нужно уточнить возможность работы с мышью через int 33h. Вызываем функцию MouseInit (AX=0000h), которая в регистре AX вернёт результат инициализации - успех или неудача (отсутствие самой мыши или не установлен драйвер). Естественно, если нет возможности работы с мышью, то нет нужды её конфигурировать и дальше.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
        ;попытка инициализации мыши
        call    MouseInit
        cmp     ax,     MouseInitOk
        je      @@MouseInitOk
        ;если инициализация не удалась - вывести сообщение
        ;и завершить программу
        mov     ah,     09h
        lea     dx,     msgMouseFault
        int     21h
        jmp     @@Exit
 
@@MouseInitOk:
После подтверждения возможности работы с мышью, пробуем её сконфигурировать. Настроек не много:
  • Настройка ограничения перемещения указателя (функции AX=0007h, AX=0008h).
  • Настройка формы курсора в графическом режиме, атрибутов курсора в текстовом режиме (функции AX=0009h, AX=000Ah).
Далее можно работать с мышкой просто опрашивая её состояние (позицию, нажатия кнопок) в рабочем цикле программы. Но это неудобно. Поэтому определяют процедуру пользовательского обработчика событий мыши (перемещение, нажатия кнопок). Эту процедуру будет вызывать драйвер при возникновении необходимости.
При установке обработчика указывается условие, когда он будет вызываться драйвером. Условий раз-два и обчёлся - перемещение, нажатие или отпускание одной из кнопок. Условия можно совмещать - к примеру, нажатие левой кнопки и отпускание правой
Assembler
1
2
3
4
5
6
7
8
        ;установить пользовательский обработчик событий "мыши"
        push    es
        mov     ax,     seg MyMouseHandler
        mov     es,     ax
        mov     dx,     offset  MyMouseHandler
        mov     cx,     MouseEvent_PressLeftButton OR MouseEvent_ReleaseRightButton
        call    MouseSetHandler
        pop     es
Сам обработчик опишу позже, т.к. сейчас идёт описание основной программы.

Вызываем функцию "показать курсор" (AX=0001h). С этого момента на экране виден курсор мыши.

Собственно настройку можно считать завершённой. Далее выполняется основная часть программы.
Единственно, нужно сделать примечание по поводу дополнительных манипуляций с мышью на этом этапе.
Функцию "спрятать курсор" (AX=0002h) рекомендуется вызывать каждый раз перед тем, как произвести какие-либо изменения на том участке экрана, где находится курсор. Этим Вы избежите проблем, возникающих из-за взаимодействия курсора с данными на экране. После завершения изменений вызывается функция "показать курсор" и работа продолжается.

После завершения основной части программы следует выполнить действия по завершению работы с мышью. Этих действий немного: спрятать курсор и удалить пользовательский обработчик прерывания.
Assembler
1
2
3
4
5
6
        ;завершение работы с "мышью"
        ;спрятать курсор
        call    MouseHideCursor
        ;удалить пользовательский обработчик прерывания
        mov     cx,     MouseEvent_None
        call    MouseSetHandler
Вот собственно и вся работа с мышью из основной программы.

Теперь осталось пояснить работу пользовательского обработчика. Ведь именно в нём выполнялась основная часть работы по учебному заданию (смена формы курсора в зависимости от его позиции).
Собственный обработчик событий мыши - процедура с "дальним вызовом", поэтому завершается командой retf. На вход процедуре драйвером передаются в регистрах следующие данные
Код
АХ содержит условие вызова,
ВХ - состояние кнопок,
СХ, DX - X- и Y-координаты курсора,
SI, DI - счетчики последнего перемещения по горизонтали и вертикали
      (единицы измерения для этих счетчиков - мики, 1/200 дюйма),
DS - сегмент данных драйвера мыши.
Т.е. всё, что можно опрашивать в "рукопашном" режиме, поступает в обработчик сразу при возникновении события.

Возвращаемые координаты совпадают с пиксельными координатами соответствующей точки на экране в большинстве графических режимов, кроме 04, 05, 0Dh, 13h, в которых Х-координату мыши нужно разделить на 2, чтобы получить номер столбца соответствующей точки на экране. В текстовых режимах обе координаты надо разделить на 8, чтобы получить номер строки и столбца соответственно.

Ещё нужно отметить, что сегмент данных указывает не на пользовательские данные, а на сегмент данных драйвера, поэтому потребуются некоторые манипуляции, чтобы "дотянуться" к переменным своей программы.

Для выполнения поставленной учебной задачи нужно сверить границы регионов и в зависимости от номера региона изменить форму курсора. По содержимому CX и DX выбираем текущий регион. Далее, для каждого региона по значению переменной с номером текущей формы курсора оценивается, требуется ли изменение формы, или форма курсора соответствует региону. При необходимости - вызывается функция изменения формы курсора.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
;Обработчик событий "мыши"
;вход
;АХ содержит условие вызова,
;ВХ - состояние кнопок,
;СХ, DX - X- и Y-координаты курсора,
;SI, DI - счетчики последнего перемещения по горизонтали и вертикали
;      (единицы измерения для этих счетчиков - мики, 1/200 дюйма),
;DS - сегмент данных драйвера мыши.
;выход
; - нет
MyMouseHandler  proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    es
 
        ;загрузка в ax текущего номера курсора
        mov     ax,     seg MouseCurrentCursor
        mov     es,     ax
        mov     si,     offset MouseCurrentCursor
        mov     ax,     es:[si]
 
        ;выяснение, в каком регионе находится курсор
        shr     cx,     1       ;для графического видеорежима 13h нужно разделить на 2 координату X курсора
        cmp     cx,     0
        jb      @@SecondRegion
        cmp     cx,     300
        ja      @@SecondRegion
        cmp     dx,     0
        jb      @@SecondRegion
        cmp     dx,     100
        ja      @@SecondRegion
 
@@FirstRegion:
        ;для первого региона:
        ;если текущий курсор равен курсору для первого региона, то выйти
        ;иначе установить требуемый курсор и выйти
        cmp     ax,     0001h
        je      @@Exit
        call    MouseCursorCross
        mov     MouseCurrentCursor,     0001h
        jmp     @@Exit
 
@@SecondRegion:
        ;для второго региона:
        ;если текущий курсор равен курсору для второго региона, то выйти
        ;иначе установить требуемый курсор и выйти
        cmp     ax,     0002h
        je      @@Exit
        call    MouseCursorRectangle
        mov     MouseCurrentCursor,     0002h
        jmp     @@Exit
 
@@Exit:
        pop     es
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        retf
MyMouseHandler  endp
Вот собственно и всё.

Целиком учебная программа приведена в теме http://www.cyberforum.ru/assembler-dos/thread1904880.html
В примечании R71MT очень хорошо видна форма курсора "крест" при представлении масок в двоичном коде. Стоит обратить внимание на такой способ представления формы курсора, т.к. она позволяет создавать и редактировать сразу в коде.
2
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.01.2017, 20:21
Готовые ответы и решения для Assembler FAQ для раздела Assembler, MASM, TASM:

Глоссарий для раздела Assembler, MASM, TASM
Thread, AFP, Charles Kludge, 6a6kin, Убежденный, Ethereal, выкладывайте свои...

Организация тем в разделе Assembler, MASM, TASM
Всем привет! Друзья, возник вопрос: как лучше организовать темы в разделе...

Полезные макросы для MASM и TASM
Не претендую на создание чего-то нового и гениального, но макросы довольно...

MASM, TASM, FASM: что выбрать для программирования в ядре
Какой асемлер выбрать для проганья в едре? вынь

Видеоуроки по Ассемблеру MASM/TASM (для DOS) на русском языке
Всем доброго времени суток. Вобщем, ищу видеоуроки на русском языке по...

Есть ли компиляторы Tasm или Masm для 64-разрядных систем
Есть ли компиляторы Tasm или Masm для 64-разрядной с-мы??? если есть просьба...

62
FAQ для раздела Assembler, MASM, TASM Assembler    
Другие темы раздела
Assembler this system does not support fullscreen mode http://www.cyberforum.ru/assembler/thread882161.html
this system does not support fullscreen mode В чем может быть ошибка?
Assembler Assembler для процессоров фирмы Intel Уважаемые форумчане! Подскажите пожалуйста каково буде содержание регистра ECX в десятичном формате после выполнения следующей программы: MOV ECX,28 CLD MOV AL,100 LEA... http://www.cyberforum.ru/assembler/thread882032.html
проверка оборудования Assembler
прошу помощи. напишите код с комментариями. заранее спасибо. для компьютера на своем рабочем столе определить: - тип компьютера; - версию MS-DOS; - число дисковых накопителей; - тип и число...
Assembler Ассемблер.повторное нажатие клавиши и использование таймера
tasm Есть программа, в которой прорисовывается фигура и при нажатии любой клавиши должна начинаться смена цвета. Подскажите, пожалуйста, как сделать, чтобы при повторном нажатии той же клавиши или...
Assembler Запрет на удаление файла http://www.cyberforum.ru/assembler/thread880013.html
Задача: Резидентная программа по горячей клавише выводит окно, в котором с помощью клавиш 'стрелка вверх' и 'стрелка вниз' выбирается режим работы с файлами, т.е. тип файлов, которые нельзя удалять....
Assembler Идентификация производителя монитора Здравствуйте, не первый день пытаюсь найти способ узнать (идентифицировать) производителя монитора. Например (из аиды64): ID монитора SAM0691 Программу нужно написать на TASM, нашёл только... подробнее
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru