Int 33h работа с мышью


Функции DOS, предназначенные для работы с мышью

Универсальный драйвер мыши был предложен фирмой Microsoft. Он обеспечивает унифицированный интерфейс для работы с манипуляторами «мышь» или «трекбол» любого типа. Драйвер позволяет выполнять свыше 40 различных функций. Все фирмы- из готовите л и манипуляторов делают драйверы для своих устройств совместимыми с драйвером Microsoft, но каждая фирма вносит в них усовершенствования, создавая программистам множество ненужных проблем. Кроме того, стандартные функции мыши в MS-DOS рассчитаны только на текстовые и устаревшие 16-цветные графические режимы: попытка обращения к ним при использовании видеорежимов SVGA, HiColor и TrueColor приводит в лучшем случае к «глюкам» на экране монитора, в худшем — к зависанию системы.

В отличие от устройств других типов, аппаратный интерфейс мыши стандартизирован гораздо лучше, чем программный, и работать с мышью желательно через аппаратуру. Использовать прерывания DOS необходимо только для устройств, не имеющих простого общепринятого интерфейса (например, подключенных через инфракрасный порт или шину USB). Мы не будем подробно рассматривать все функции MS-DOS, предназначенные для обслуживания мыши (см. [3, 10]), поскольку большая часть из них не работает должным образом в современных видеорежимах. Ниже перечислены только те функции, которые не взаимодействуют напрямую с видеоконтроллером и потому особых проблем не вызывают. При этом программист должен сам написать подпрограммы, обеспечивающие отображение курсора мыши и перемещение его по экрану в конкретном видеорежиме.

Прерывание 33h, функция OOOOh: проверить наличие драйвера мыши и произвести сброс

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

При вызове функции в регистр АХ должен быть помещен код 0.

После выполнения функции в случае отсутствия драйвера в регистре АХ будет возвращено значение 0. При наличии драйвера мыши в регистрах будет размещена следующая информация:

• в АХ — код FFFFh;

• в ВХ — код типа мыши (FFFFh — стандартная мышь Microsoft с двумя клавишами, любое другое значение — мышь нестандартная).

Параметры драйвера после сброса следующие:

• координаты курсора установлены на центр экрана;

• для отображения назначена видеостраница 0;

• курсор находится в невидимом состоянии, то есть не отображается на экране;

• курсору придана форма, действующая по умолчанию (в текстовых режимах — форма негативного прямоугольника, в графических режимах — форма стрелки);

• работа пользовательского обработчика сообщений мыши заблокирована;

• эмуляция светового пера разрешена;

• установлена чувствительность мыши к перемещению по горизонтали 8:8 микки на пиксел, по вертикали — 16:8 микки на пиксел;

• порог удвоения скорости равен 64 микки/с;

• область отображения курсора мыши охватывает весь экран.

Из всего перечисленного выше наиболее важным является то, что после сброса курсор на экран не отображается. При работе в текстовом режиме нужно вызвать функцию OOOlh, чтобы курсор появился на экране. В современных графических режимах курсор средствами драйвера не отображается или отображается неправильно, поэтому с точки зрения драйвера он должен оставаться скрытым, то есть функцию OOOlh вызывать нельзя.

Прерывание 33h, функция 0001 h: отобразить курсор мыши на экране

Функция OOOlh делает курсор мыши видимым.

При вызове функции в регистр АХ должен быть помещен код OOOlh.

Никаких выходных параметров функция не имеет.

Применять данную функцию можно только в текстовых режимах.

Прерывание 33h, функция 0002h: убрать курсор мыши с экрана

Функция 0002h делает курсор мыши невидимым.

При вызове функции в регистр АХ должен быть помещен код 0002h.

Выходных параметров функция не имеет.

Как в текстовых, так и в графических режимах курсор накладывается поверх изображения, искажая его, поэтому перед выводом курсора драйвер запоминает участок изображения под ним. Функция 0002h осуществляет стирание курсора и восстановление изображения. Данную функцию необходимо использовать перед перерисовкой изображения на экране или при перемещении курсора в другую позицию. Поскольку в современных графических режимах функция OOOlh не работает, то не применяется и обратная ей функция 0002И.

Прерывание 33h, функция 0003И: получить информацию о положении курсора и состоянии кнопок мыши

Функция 0003h позволяет определить текущее состояние кнопок мыши и текущее положение курсора.


При вызове функции в регистр АХ должен быть помещен код 0003И. После выполнения функции в регистрах будет возвращена следующая информация:

• в ВХ — текущее состояние кнопок мыши (бит 0 — состояние левой кнопки, бит 1 — состояние правой кнопки, бит 2 — состояние средней кнопки);

• в СХ — горизонтальная координата курсора (X);

• в ОХ — вертикальная координата курсора (Y).

Если кнопка мыши нажата, значение соответствующего бита регистра ВХ будет установлено в 1, если отпущена — в 0. Серьезный недостаток данной функции заключается в том, что невозможно определить, была ли нажата (отпущена) кнопка мыши в текущей позиции курсора, или это произошло ранее в другом месте экрана. Поэтому функция 0003h применяется только в графических видеорежимах — в подпрограмме, отвечающей за перемещение курсора по экрану. Для получения более точной информации о нажатиях и отпусканиях кнопок мыши используются функции 0005h и 0006h.

Прерывание 33h, функция 0004И: установить новое положение курсора

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

При вызове функции в регистры должна быть занесена следующая информация:

• в АХ – код 0004h;

• в СХ — горизонтальная координата курсора (X);

• в DX — вертикальная координата курсора (Y). Выходных параметров функция не имеет.

Положение координаты задается в пикселах относительно левого верхнего угла экрана, причем предполагается, что ось Y направлена сверху вниз.

Прерывание 33h, функция 0005И: получить информацию о нажатиях кнопок мыши

Функция 0005h позволяет получить текущее состояние всех кнопок мыши, а также определить, была ли нажата заданная кнопка, сколько раз ее нажимали с момента последнего опроса, и в какой позиции экрана было осуществлено последнее нажатие. При вызове функции в регистры должна быть занесена следующая информация:

• в АХ – код 0005h;

• в BX — номер кнопки, которую требуется опросить (0 — правая кнопка, 1 — левая кнопка, 2 — средняя кнопка).

После выполнения функции в регистрах будет возвращена следующая информация:

• в АХ — текущее состояние кнопок мыши (бит 0 — состояние левой кнопки, бит 1 — состояние правой кнопки, бит 2 — состояние средней кнопки);

• в ВХ — число нажатий на указанную кнопку с момента последнего вызова данной функции для данной кнопки;

• в СХ — горизонтальная координата курсора (X) в момент последнего нажатия указанной кнопки;

• в DX — вертикальная координата курсора (Y) в момент последнего нажатия указанной кнопки.

Прерывание 33h, функция 0006h: получить информацию об отпусканиях кнопок мыши

Функция 0006И позволяет получить текущее состояние всех кнопок мыши, а также определить, имело ли место отпускание заданной кнопки, сколько раз ее отпускали с момента последнего опроса, и в какой позиции экрана было осуществлено последнее отпускание.

При вызове функции в регистры должна быть занесена следующая информация:

• в ВХ — номер кнопки, которую требуется опросить (0 — правая кнопка, 1 — левая кнопка, 2 — средняя кнопка).

После выполнения функции в регистрах будет возвращена следующая информация:

• в АХ — текущее состояние кнопок мыши (бит 0 — состояние левой кнопки, бит 1 — состояние правой кнопки, бит 2 — состояние средней кнопки);>

• в ВХ — число отпусканий указанной кнопки с момента последнего вызова данной функции для данной кнопки;

• в СХ — горизонтальная координата курсора (X) в момент последнего отпускания указанной кнопки;

• в DX — вертикальная координата курсора (Y) в момент последнего отпускания указанной кнопки.

Прерывание 33h, функция 0007И: задать горизонтальный диапазон перемещения курсора


Функция 0007И служит для ограничения пределов горизонтального перемещения курсора.

При вызове функции в регистры должна быть занесена следующая информация:

• в СХ — координата левой границы перемещения курсора (Xmin);

• в DX — координата правой границы перемещения курсора (Хтах). Выходных параметров функция не имеет.

Функция 0007И используется совместно с функцией для задания на экране рабочего окна, за пределы которого не должен выходить курсор мыши. В простейшем случае функция применяется, чтобы предотвратить уход части изображения графического курсора за границу экрана.

Прерывание 33h, функция 0008h: задать вертикальный диапазон перемещения курсора

Функция 0008h служит для ограничения пределов вертикального перемещения курсора.

При вызове функции в регистры должна быть занесена следующая информация:

• в АХ – код 0008И;

• в СХ — координата верхней границы перемещения курсора (Ymm);

• в DX — координата нижней границы перемещения курсора (Y^). Выходных параметров функция не имеет.

Как и функция 0007И, данная функция чаще всего применяется, чтобы предотвратить уход части изображения курсора за границу экрана.

Прерывание 33h, функция OOOCh: задать подпрограмму пользователя обработчику прерывания мыши

Функция OOOCh позволяет пользователю установить собственный обработчик прерывания мыши.

При вызове функции в регистры должна быть занесена следующая информация:

• в АХ – код OOOCh;

• в СХ — маска условий вызова;

• в ES: DI — дальний указатель на подключаемую подпрограмму пользователя.

Выходных параметров функция не имеет.

При вызове подпрограммы драйвер передает ей параметры через регистры. В регистрах будут размещены следующие значения:

• в АХ — маска условий вызова;

• в ВХ — текущее состояние кнопок мыши (бит 0 — состояние левой кнопки, бит 1 — состояние правой кнопки, бит 2 — состояние средней кнопки);

• в СХ — горизонтальная координата курсора (X);

• в DX — вертикальная координата курсора (Y);

• в SI — горизонтальный отсчет (микки);

• в DI — вертикальный отсчет (микки);

• в DS — сегмент данных драйвера мыши.

Разряды маски условий вызова имеют следующее назначение (если разряд установлен в 1, то выполняется соответствующее действие):

• бит 0 — вызывать подпрограмму пользователя в случае перемещения мыши;

• бит 1 — вызывать подпрограмму пользователя при нажатии левой кнопки;

• бит 2 — вызывать подпрограмму пользователя при отпускании левой кнопки;

• бит 3 — вызывать подпрограмму пользователя при нажатии правой кнопки;


• бит 4 — вызывать подпрограмму пользователя при отпускании правой кнопки;

• бит 5 — вызывать подпрограмму пользователя при нажатии средней кнопки;

• бит 6 — вызывать подпрограмму пользователя при отпускании средней кнопки;

• биты 7-15 — зарезервированы.

Функция OOOCh очень полезна при работе в современных графических режимах — подпрограмма вывода курсора, подключенная к драйверу, может быть настроена на особенности конкретного видеорежима и даже на конкретный тип видеоконтроллера. Следовательно, при выводе курсора не будет возникать никаких побочных искажений изображения.

Прерывание 33h, функция OOOFh: изменить чувствительность мыши к перемещению

Илон Маск рекомендует:  Рисование точки и линии

Функция OOOFh позволяет управлять чувствительностью мыши. При вызове функции в регистры должна быть занесена следующая информация:

• в АХ — код OOOFh;

• в СХ — число микки на 8 пикселов по горизонтали (по умолчанию 8);

• в DX — число микки на 8 пикселов по вертикали (по умолчанию 16). Выходных параметров функция не имеет

Прерывание 33h, функция 0013h: задать порог удвоения скорости

Функция 0013h позволяет изменить порог удвоения скорости перемещения мыши. Если скорость перемещения мыши превышает заданный порог, то скорость перемещения курсора по экрану удваивается.

При вызове функции в регистры должна быть занесена следующая информация:

• в АХ — код 0013h;

• в DX — пороговая скорость в микки/с (по умолчанию равна 64 микки/с).

Выходных параметров функция не имеет.

Источник: Кулаков В. К90 Программирование на аппаратном уровне: специальный справочник (+дискета). 2-е издание. — СПб.: Питер, 2003. — 847 е.: ил.

Int 33h работа с мышью

Мышиные функции (для MS DOS )

Возможно вы спросите, зачем я занялся столь древним вопросом? Отвечу – на 1-м курсе Нижегородского Политехнического Университета, где учится мой сын, ему задали задачу (предмет – программирование):

“Графический экран, мышь.

В центре экрана нарисован прямоугольник.

Когда курсор мыши выходит за границу прямоугольника,

он позиционируется в центр прямоугольника.”

На лекциях им объяснялись прерывания для мыши (соответствующую лекцию можете посмотреть здесь, пусть меня извинит преподаватель за то, что я помещаю ее без разрешения). Кроме того им давалась информация по работе с графической библиотекой Borland (см. здесь).

В интернете ничего путного насчет досовских библиотек по работе с мышью мне не удалось найти. Поэтому пришлось программировать самому. Вспомнил свои функции на встроенном ассемблере для Borland C 2.0, которые я писал где-то в 1996-1997 годах, и переделал их под мышь. Особо подробно я расписывать не буду, вопрос древний, да и не платит мне никто за это. Сразу скажу, что все написанные функции я не тестировал, но по крайней мере часть их работает отлично. Если в комментариях по ходу программы не будет понятно что обозначает какой параметр функции – смотрите лекцию с «мышиными» прерываниями (выше). Все должно стать понятно.

Здесь можете скачать исполняемый файл (в архиве rar ). Чтоб он работал, в том же каталоге должен быть и файл Egavga . bgi (он прилагается в архиве).

А вот и сам текст программы. Заодно можно ознакомиться и с тем, как задействуется Борландовская графическая библиотека.

#define LEFT 270

#define RIGHT 370

#define BOTTOM 140


/* Сперва идут функции для работы с мышью*/

unsigned int TestMouseDriver(void) /* Проверка — есть ли драйвер мыши */

3. МЫШЬ

Вместе с появлением персональных компьютеров возникло и получило огромную популярность графическое устройство ввода информации — мышь. В настоящее время практически каждый персональный компьютер оснащен этим устройством. Более того, многие программы специально ориентированы на использование мыши. Например, графический редактор Picture Maker из пакета Story Editor. В этом редакторе вы можете сделать почти всю работу, не прикасаясь к клавиатуре (за исключением операции набора текстовых строк).

Что это за устройство и почему оно используется так же часто, как и клавиатура персонального компьютера?

Мышь — это небольшая коробочка с двумя или тремя клавишами, которая соединяется с компьютером тонким кабелем:

Рис. 2. Внешний вид мыши

Сверху на корпусе расположены кнопки. Обычно их две или три. Назначение этих кнопок полностью определяется программным обеспечением. Снизу виден шарик. Он обычно покрыт резиной для лучшего сцепления с поверхностью стола.

Все, что вам нужно делать с мышью — это катать ее по любой гладкой поверхности и нажимать на кнопки. Программное обеспечение свяжет перемещения мыши по поверхности стола с перемещениями, например, курсора по поверхности экрана. Перемещая мышь по столу (и, соответственно, курсор по экрану), вы можете указывать (выбирать) различные объекты, находящиеся на экране.

Для того, чтобы «выбрать» какой-нибудь объект, обычно требуется указать на этот объект курсором и нажать на одну из кнопок мыши.

Если вы откроете корпус мыши, вы увидите простой механизм, состоящий из шарика, двух осей с резиновыми валиками, двух дисков с отверстиями и четырех фотодатчиков:

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

В настоящее время изготовители компьютерного оборудования предлагают большой выбор мышей разного типа. Мыши отличаются не только внешним видом и количеством клавишей, но также и способом подключения к компьютеру, мыши могут иметь различную точность и различный программный интерфейс.

Можно выделить два наиболее часто используемых способа подключения мыши к компьютеру:

  • через последовательный порт (COM1, COM2);
  • через специальный адаптер, который вставляется в слот расширения материнской платы компьютера.

Выбирая мышь, используйте тот способ подключения, который вам более удобен. При этом не следует забывать о существовании компьютеров, не имеющих слотов расширения (обычно это компьютеры типа Lap-Top). Для таких компьютеров больше подойдет мышь, подключающаяся через последовательный порт.

Что касается программного интерфейса, то можно выделить два типа:

  • трехкнопочная мышь системы Mouse Systems
  • двухкнопочная мышь Microsoft

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

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

Как это не странно, ни BIOS, ни MS-DOS версий вплоть до 4.01 не содержат программной поддержки мыши. Для того, чтобы задействовать это устройство, вам надо использовать драйвер мыши или специальную резидентную программу, выполняющую функцию драйвера мыши. Как правило, это программное обеспечение поставляется вместе с мышью.

Для подключения драйвера мыши файл CONFIG.SYS должен содержать строку следующего вида:

Если используется резидентная программа, она обычно вызывается в файле AUTOEXEC.BAT:

Драйвер мыши выполняет следующие функции:

  • отслеживает перемещения курсора и нажатия на клавиши мыши;
  • рисует на экране курсор, повторяющий движения мыши в графическом или текстовом режимах;
  • предоставляет программам интерфейс для работы с мышью, основанный на вызове прерывания INT 33h.

Драйвер мыши, независимо от того, реализован он через устанавливаемый драйвер или резидентную программу, определяет обработчик прерывания INT 33h. Этот обработчик выполняет все операции, связанные с обслуживанием мыши:

  • сброс мыши и установка драйвера в исходное состояние;
  • включение/выключение курсора мыши;
  • установка курсора в определенное место экрана;
  • определение текущих координат курсора и текущего состояния клавиш;
  • определение координат курсора и состояния клавиш в момент нажатия на клавишу и в момент отпускания клавиши;
  • определение области на экране, в пределах которой может перемещаться курсор;
  • определение области на экране, в пределах которой курсор не будет виден;
  • определение формы графического и текстового курсоров;
  • определение величины перемещения мыши в сотых долях дюйма;
  • подключение к драйверу пользовательской процедуры, получающей управление при нажатии на заданную клавишу или при перемещении мыши;
  • запоминание и восстановление состояния драйвера;
  • управление эмуляцией светового пера;
  • управление скоростью движения курсора;
  • задание/определение используемой видеостраницы;
  • управление драйвером мыши.

Приведем подробное описание всех функций прерывния INT 33h, используемых при работе с мышью.

Bios INT 33h

Функция 00h —инициализировать драйвер мыши

Выход: AX: FFFFh в случае успеха,

0000h при неудаче


ВХ — количество кнопок мыши

Функция 01h — включить курсор мыши

Функция 02h —выключить курсор мыши

Функция 03h —возвратить позицию курсора и статус клавиш

Выход: ВХ — статус кнопок

Бит 0 — левая кнопка: 1 — нажата, 0 — не нажата

Бит 1 — правая кнопка: 1 — нажата, 0 — не нажата

Бит 2 — центральная кнопка: 1 — нажата, 0 — не нажата

СХ — Х-координата курсора

DX — Y-координата курсора

Функция 0Bh —возвратить относительную позицию мыши

Выход: СХ — относительное горизонтальное движение в mickey

DX — относительное вертикальное движение в mickey

Функция 1Ah —установить чувствительность

Выход: ВХ — чувствительность по оси Х (0-100)

СХ — чувствительность по оси Y (0-100)

DX — значение скорости, при которой чувствительность возрастает в 2 раза (0-100)

Как видите, функции драйвера вызываются через прерывание 33h. Мы записываем параметр в регистр АХ .и получаем результат в регистрах АХ, ВХ, СХ и DX. Я написал простую функцию для работы с мышью, она называется Squeeze_Mouse(). Эта функция может выполнять много действий — все зависит от передаваемых параметров. Прототип функции:

int Squeeze_Mouse(int command, int *x, int *y, int *buttons) ;

Кроме этого, я сделал несколько описаний, чтобы упростить работу с ней:

#define MOUSE_INT 0х33 // номер прерывания

#define MOUSE_RESET 0х00 // сброс мыши

#define MOUSE_SHOW 0х01 // показать мышь

#define MOUSE_HIDE 0х02 // погасить мышь

#define MOUSE BUTT_POS 0х03 // возвратить координаты

//и количество кнопок

#define MOUSE_SET_SENSITIVITY 0x1A // установить

//в пределах 0-100

#define MOUSE_MOTION_REL 0x0B // установить

Таким образом, если мы хотим получить координаты мыши, то должны написать следующее:

где mouse_x, mouse_y и mouse_buttons — локальные переменные для сохранения результатов.


Теперь обратим внимание на два способа, используемые для передачи координат мыши:

§ Драйвер мыши может возвращать абсолютные координаты. В этом случае значения Х и Y являются координатами мыши на экране. К примеру, если мышь находится в левом верхнем углу экрана, функция возвращает (0,0);

§ Драйвер мыши может возвращать относительные координаты. При этом возвращается разница координат от предыдущей посылки. Например, если мышь подвинулась на 20 микки по оси Х и на 10 по оси Y, то эти значения и будут возвращены. Для чтения в относительном режиме используйте константу MOUSE_MOTION_REL.

Еще несколько слов о мыши. Вы можете менять ее чувствительность к передвижению, используя константу MOUSE_SET_SENSITIVITY. Для этого подберите для переменных Х и Y значение от 1 до 100 и вызовите Squeeze_Mouse. Чувствительность мыши определяется как отношение пиксельного перемещения курсора мыши к одному микки.

Листинг 3.8 содержит демонстрационную программу, которая показывает использование мыши. Эта программа позволяет рисовать на экране, нажимая на левую кнопку мыши и менять цвет, используя правую кнопку.

Монтажная мышь без int33h

ALRIGHTY, поэтому я работал над сборкой достаточно долго, чтобы понять приличный код.

Я пытаюсь получить мышь вверх без int 33h главным образом потому, что нет 33h в VMware или Bochs (эмуляторы без MS-DOS).

Является ли мой код правильным? Я следил за OSDev Wiki и Cosmos С#

Непонятно из вопроса, каков ваш вопрос, если вы запрашиваете полный обзор кода + debug, то это AFAIK не является «хорошим» вопросом, но, по крайней мере, не дает некоторого намека на то, сколько проблем и какие из них могут будь там.

Я все еще занимал около 15 минут, чтобы быстро прочесть это, и сначала кажется, что я не работаю с плохим качеством, поэтому я не собираюсь вникать в больше, и я просто подытожу то, что мне не понравилось до сих пор (было бы вероятно, много больше, если бы я сделал полный обзор, но это займет гораздо больше времени, чем я готов вложить в это). И отказ от ответственности: я никогда не делал своего собственного обработчика мыши для ПК, поэтому я просто сравниваю ваш код с спецификациями из Wiki OSDev, если они ошибаются, мои предложения тоже будут.

Поскольку данные на клавиатуре и мыши отображаются для чтения на порту 0x60, необходимо иметь возможность указать, что именно. Чтобы узнать, имеются ли какие-либо доступные данные на порту 0x60 вообще, необходимо прочитать байт из порта 0x64. В этом байте из порта 0x64 бит 0 (value = 1) указывает, что байт доступен для чтения на порту 0x60. Дополнительный бит, бит №5 (value = 0x20), указывает, что этот следующий байт поступает от мыши, если бит установлен. Если вы посмотрите на RBIL, это говорит о том, что этот «бит мыши» специфичен для MCA, но это уже не так. Все ПК, которые поддерживают мыши PS2, используют этот бит, чтобы указать, что входящий байт был сгенерирован вспомогательным входным портом PS2.

Поэтому вы ждете, пока порт 0x64 не будет установлен в 1, но это означает, что данные с клавиатуры. В целом, cmp обычно не является хорошим выбором для тестирования бит, так как вы никогда не знаете, как будет изменяться значение управления в будущем, и может быть (выделено курсивом) FBATION EXAMPLE) новая функциональность b7, сигнализирующая о 1 беспроводной PS/2 в таком случае b0 и b5 могут все еще сигнализировать доступные данные от мыши, но вы никогда не поймаете их с помощью cmp и беспроводной мыши, так как b7 неожиданно устанавливается все время.

Код должен выглядеть больше:

Это слишком широк, вы уже настроили чип PIT 8253/8254, так что у вас есть некоторый источник времени, например, системное время DOS int 8 ?

Тогда самым простым способом может быть использование таких тиков таймера для реализации механизма тайм-аута.

Другой способ без таймера (часто используемый на языках высокого уровня) состоит в том, чтобы иметь фиксированный статический счетчик, чтобы ограничить цикл для запуска только так много раз, но с незапланированной сборкой и огромным разнообразием между скоростями ЦП, для некоторых процессоров 10000 циклов могут составлять одну десятую секунды, а для других один миллиард будет ровно сотой секунды, так что здесь не применимо, если вы не найдете какой-то источник надежной задержки (например, если чтение одного из портов 0x64 или 0x60 фактически занимает значительное количество время даже на современном ПК, тогда может работать фиксированный счетчик).

Работа с мышью

Все общение с мышью в DOS выполняется через прерывание 33h, обработчик которого устанавливает драйвер мыши, загружаемый обычно при запуске системы. Современные драйверы поддерживают около 60 функций, позволяющих настраивать разрешение мыши, профили ускорений, виртуальные координаты, настраивать дополнительные обработчики событий и т.п. Большинство этих функций требуются редко, сейчас рассмотрим основные:

INT 33h, AX = 0 — Инициализация мыши

AX = 0000h

Вывод:

АХ = 0000h, если мышь или драйвер мыши не установлены
АХ = FFFFh, если драйвер и мышь установлены
ВХ = число кнопок:

    0002 или FFFF — две
    0003 — три
    0000 — другое количество

Выполняется аппаратный и программный сброс мыши и драйвера.

INT 33h, AX = 1 — Показать курсор

AX = 0001h

INT 33h, AX = 2 — Спрятать курсор

AX = 0002h

Драйвер мыши поддерживает внутренний счетчик, управляющий видимостью курсора мыши. Функция 2 уменьшает значение счетчика на единицу, а функция 1 увеличивает его, но только до значения 0. Если значение счетчика — отрицательное число, он спрятан, если ноль — показан. Это позволяет процедурам, использующим прямой вывод в видеопамять, вызывать функцию 2 в самом начале и 1 — в самом конце, не заботясь о том, в каком состоянии был курсор мыши у вызвавшей эту процедуру программы.

INT 33h, AX = 3 — Определить состояние мыши

AX = 0003h


Вывод:

бит 0 — нажата левая кнопка

бит 1 — нажата правая кнопка

бит 2 — нажата средняя кнопка

СХ = Х-координата
DX = Y-координата

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

Int 33h работа с мышью

Группа: Модераторы
Сообщений: 4 824
Пол: Мужской
Реальное имя: Олег

Все операции, связанные с мышью, в программах выполняются посредством функций
прерывания int $33. Общий формат их вызова таков:

В отличии от остальных прерываний, функции которых определяются значением в регистре AH, прерывание INT $33 используют весь регистр AX.

Первой используемой в программе функцией этого прерывания должна быть функция $00 (инициализация мыши). Обычно эта команда используется только один раз — в самом начале программы. Для того, чтобы программы могли использовать мышь, предварительно необходимо загрузить драйвер. Этот драйвер обычно запускается командой в файле CONFIG.SYS или AUTOEXEC.BAT (В среде Windows драйвер мыши загружается согласно записи в реестре).

Ниже приведены основные термины, касающиеся мыши:

  • пиксель — наименьший адресуемый элемент экрана.
  • указатель мыши — в текстовом режиме это мерцающий прямоугольник в инверсном видеорежиме, в графическом режиме его вид может быть произвольным, но обычно это стрелка.
  • микки(шаг) — наименьшее расстояние, перемещение на которое мышь может зарегистрировать (т.е. расстояние регистрируемое датчиками мыши). Обычно 0.125 мм.
  • счетчик мыши — отсчитывает число микки (шагов), на которое мышь сместилась горизонтально или вертикально. Драйвер мыши отсчитывает эти перемещения и соответственно перемещает указатель мыши на экране.
  • пороговая скорость — определенная скорость перемещения
    (микки/с), при превышении которой скорость перемещения курсора по экрану удваивается. По умолчанию — 64 микки в секунду.

Рассмотрим основные функции прерывания INT $33.

Инициализация мыши
Для инициализации мыши необходимо вызвать функцию $00. Эта функция должна вызываться первой из всех команд обработчика. Для ее вызова необходимо поместить в регистр AX значение $00 и вызвать прерывание INT $33.

  • Приведенная функция пробует инициализировать мышь, и если мышь инициализирована, возвращает true.
    При инициализации, в регистр BX помещается количество кнопок у обнаруженной мыши. Поскольку не всегда требуется эта информация, можно вынести определение количества кнопок у мыши в отдельную функцию:
  • Функция возвращает количество кнопок у мыши. Эту функцию можно использовать в любом месте программы. (Это и есть тот случай, когда функцию $00 прерывания $33 вызывают второй раз).
    При инициализации мыши, указатель не появляется на экране.

    Отображение указателя мыши
    Для отображения указателя мыши на экране, необходимо использовать функцию $01.
    Драйвер мыши содержит флаг указателя, определяющий, должен ли указатель отображаться на экране. Указатель отображается, если флаг установлен в 0, и скрывается, если флаг установлен в любое другое значение. Изначально его значение -1. Функция $01 увеличивает его до 0, и курсор становится видим.

    Зарезервированное слово Assembler, которое было использовано в приведенной процедуре, указывает компилятору, что процедура целиком написана на ассемблере.

    Cокрытие указателя мыши
    Часто в процессе работы программы, требуется на время скрыть указатель мыши, например, при выводе графики. Для этого используют функцию $02.
    Следующая процедура, при вызове, скрывает указатель мыши:

    Перечисленные процедуры и функции можно так использовать в программе:

    Получение состояния мыши
    Функция $03 позволяет получить данные о текущем состоянии мыши.
    После вызова этой функции, в регистр BX помещается информация о состоянии кнопок, в регистр CX координата по горизонтали (х), а в регистр DX координата по вертикали (у)*(см. примечание!).
    Следующая процедура возвращает координаты указателя.

  • При написании программ, очень часто нужно проверять не находится ли указатель в заданной прямоугольной части экрана. (например на кнопке).
    Следующая процедура, возвращает true, если указатель находится в зоне x1,y1,x2,y2, где x1-левая граница зоны, x2 — правая граница, y1 — верхняя граница, y2 — нижняя граница.
  • Функция $03, как уже было сказано, возвращает состояние кнопок мыши.
  • Функция возвращает следующие значения:
    • 1 — если нажата левая кнопка.
    • 2 — если нажата правая кнопка.
    • 3 — если нажаты левая и правая кнопки
    • 4 — если нажата средняя кнопка (колесико)
    • 5 — если нажаты левая кнопка и колесико
    • 6 — если нажаты правая кнопка и колесико.
    • 7 — если нажаты все кнопки (2 кнопки и колесико).

    ——————————————
    * все координаты исчисляются в пикселях. Даже в текстовом режиме. Поэтому для перемещения указателя мыши, скажем на 3 стоку, надо указать координату 8*3 = 24 (на одну строку в текстовом режиме идет 8 пикселей.

    Установка указателя мыши в нужную позицию
    Для установки указателя мыши в нужную позицию (X,Y) используйте следующую процедуру:

    Не забудте умножить координаты на 8, если вы используете текстовый режим!

    Регистрация события нажатия клавиши.
    В модуль CRT включена очень полезная функция, возвращающая true, если была нажата клавиша, вот ее аналог для мыши. Функция возвращает true, если была нажата любая клавиша.

    Определение количества нажатий клавиш
    Для определения количества нажатия кнопок мыши используют функцию $05.
    Следующая функция возвращает количество нажатий левой(при num=0), средней(при num=2),правой(при num=1) кнопкой мыши с момента последнего вызова данной процедуры. И еще они возвращают координаты мыши при последнем нажатии данной клавиши.

    Например, если надо получить координаты мыши при последнем нажатии левой кнопки мыши, достаточно вызвать процедуру так:
    getnum(0,x,y);
    Для такого вызова функции, включите расширенный синтаксис директивой
    компилятору <$X+>или в настройках компилятора.


    Пределы перемещения указателя Если в программе требуется ограничить область перемещения указателя, то для этого необходимо использовать функции $07 и $08.
    Ограничение перемещения указателя по горизонтали.

  • Ограничение перемещения указателя по вертикали.
  • Чтение содержимого счетчиков перемещения мыши
    эта операция возвращает величины смещения мыши по вертикали и горизонтали (в микки) со времени последнего вызова процедуры.

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

    Дата добавления: 2014-11-28 ; просмотров: 574 ; Нарушение авторских прав

    «Мышь» является одним из периферийных устройств ПЭВМ и в данный момент стала практи­чески его неотъемлемой частью. Для работы с «мышью» применяются загружаемые драйверы устройства «мышь». Все такие драйверы следуют еди­ному стандарту, определенному фирмой Microsoft для ее драйвера MOUSE.СОМ в документе «Mouse User’s Guide». Точнее говоря, эти драйверы обязаны поддерживать определенный набор функций, но, по­мимо того, они могут иметь и дополнительные воз­можности. Мы рассмотрим только те функции кото­рые поддерживаются драйвером фирмы Microsoft.

    Обмен с драйвером мыши осуществляется обраще­нием к Int 33h; параметры функций задаются в регистрах АХ, ВХ, СХ и DX. Прежде чем вызывать функции драйвера, прикладная программа должна проверить, что драйвер мыши установлен. Для этого она должна выполнить следующие действия:

    — прочитать содержимое вектора Int 33h (адрес 0:0CCh); если он равен 0:0 или указывает на команду IRET, то драйвер не установлен;

    — если содержимое вектора отлично от нуля, то вызвать функция 00h; если эта функция вернет АХ=-1, то драйвер установлен и мышь инициализирована.

    Доступ к драйверу мыши посредством Int 33h может использоваться как ассемблерными програм­мами, так и программами, написанными на языках высокого уровня, например, на Бейсике, Си, Паскале, Фортране или Коболе.

    Программа работающая с мышью , должна учиты­вать следующие требования:

    1. Если программа перехватывает Int 10h, то она должна гарантировать, что функция 00h (сменить видеорежим) будет отработана драйвером мыши

    2. Драйвер мыши гарантирует правильность рабо­ты с экраном, если Ваша программа осуществляет вывод на экран через Int 10h или через ДОС. Если же вывод производится прямой записью в видеопамять, то программа должна вызвать функцию 02h (скрыть курсор) перед выводом и функцию 01h (показать курсор) после вывода.

    3. Вы можете работать с мышью двумя способами:

    Явно вызывая Int33h или задав свою программу обработки событий. В последнем случае драйвер будет вызывать Вашу подпрограмму всякий раз, когда произойдет заданное событие (см. функцию 0Ch).

    мышь с INT 33h в ASM не работает

    December 2020

    2.4k раз

    Я играл вокруг с сборки, компиляции для .com файлов с помощью NASM на Windows 7. По какой-то причине это не работает:

    Я думаю , что это должно повторяться run1 до тех пор , пока не будет мышь, а затем сделать то же самое с run2 . Затем программа должна бросить курить. Но, когда я выполняю эту программу, она ждет только одного щелчка мыши. Что мне нужно сделать , чтобы исправить это? заранее спасибо

    2 ответы

    Проблема заключается в том, что кнопка мыши остается нажатой в течение некоторого времени. Поэтому после того, как run1 вы должны ждать , пока кнопка релиз снова, а затем вы можете снова начать проверки второго щелчка.

    Я считаю , что это будет делать это (с комментариями).
    ( Код тестировался )

    В принципе, есть теперь 3 петли.
    1.) Подождите , пока кнопка будет нажата.
    2.) Дождитесь, чтобы кнопка была отпущена.
    3.) Подождите , пока кнопка будет нажата снова.

    Работа с мышью. Выполняется аппаратный и программный сброс мыши и драйвера.

      Любовь Бекетова 2 лет назад Просмотров:

    1 Работа с мышью Все общение с мышью в DOS выполняется через прерывание 33h, обработчик которого устанавливает драйвер мыши, загружаемый обычно при запуске системы. Современные драйверы поддерживают около 60 функций, позволяющих настраивать разрешение мыши, профили ускорений, виртуальные координаты, настраивать дополнительные обработчики событий и т.п. Большинство этих функций требуются редко, сейчас рассмотрим основные: INT 33h, AX = 0 Инициализация мышиввод: AX = 0000h Вывод: АХ = 0000h, если мышь или драйвер мыши не установлены АХ = FFFFh, если драйвер и мышь установлены ВХ = число кнопок: 0002 или FFFF две 0003 три 0000 другое количество Выполняется аппаратный и программный сброс мыши и драйвера. INT 33h, AX = 1 Показать курсорввод: AX = 0001h INT 33h, AX = 2 Спрятать курсорввод: AX = 0002h Драйвер мыши поддерживает внутренний счетчик, управляющий видимостью курсора мыши. Функция 2 уменьшает значение счетчика на единицу, а функция 1 увеличивает его, но только до значения 0. Если значение счетчика отрицательное число, он спрятан, если ноль показан. Это позволяет процедурам, использующим прямой вывод в видеопамять, вызывать функцию 2 в самом начале и 1 в самом конце, не заботясь о том, в каком состоянии был курсор мыши у вызвавшей эту процедуру программы. INT 33h, AX = 3 Определить состояние мышиввод: AX = 0003h Вывод: ВХ = состояние кнопок: бит 0 нажата левая кнопка бит 1 нажата правая кнопка бит 2 нажата средняя кнопка СХ = Х-координата DX = Y-координата Возвращаемые координаты совпадают с пиксельными координатами соответствующей точки на экране в большинстве графических режимов, кроме 04, 05, 0Dh, 13h, в которых Х-координату мыши нужно разделить на 2, чтобы получить номер столбца

    2 соответствующей точки на экране. В текстовых режимах обе координаты надо разделить на 8, чтобы получить номер строки и столбца соответственно. В большинстве случаев эта функция не используется в программах, так как для того, чтобы реагировать на нажатие кнопки или перемещение мыши в заданную область, требуется вызывать это прерывание постоянно, что приводит к трате процессорного времени. Функции 5 (определить положение курсора при последнем нажатии кнопки), 6 (определить положение курсора при последнем отпускании кнопки) и 0Bh (определить расстояние, пройденное мышью) могут помочь оптимизировать работу программы, самостоятельно следящей за всеми передвижениями мыши, но гораздо эффективнее указать драйверу самому следить за ее передвижениями (чем он, собственно, и занимается постоянно) и передавать управление в программу, как только выполнится заранее определенное условие, например пользователь нажмет на левую кнопку мыши. Такой сервис обеспечивает функция 0Ch установить обработчик событий. INT 33h, AX = 0Ch Установить обработчик событийввод: AX = 000Ch ES:DX = адрес обработчика СХ = условие вызова бит 0 любое перемещение мыши бит 1 нажатие левой кнопки бит 2 отпускание левой кнопки бит 3 нажатие правой кнопки бит 4 отпускание правой кнопки бит 5 нажатие средней кнопки бит 6 отпускание средней кнопки СХ = 0000h отменить обработчик Обработчик событий должен быть оформлен, как дальняя процедура (то есть завершаться командой RETF). На входе в процедуру обработчика АХ содержит условие вызова, ВХ состояние кнопок, СХ, DX X- и Y-координаты курсора, SI, DI счетчики последнего перемещения по горизонтали и вертикали (единицы измерения для этих счетчиков мики, 1/200 дюйма), DS сегмент данных драйвера мыши. Перед завершением программы установленный обработчик событий должен быть обязательно удален (вызов функции 0Ch с СХ = 0), так как иначе при первом же выполнении условия управление будет передано по адресу в памяти, с которого начинался обработчик. Функция 0Ch используется так часто, что у нее появилось несколько модификаций функция 14h, позволяющая установить одновременно три обработчика с разными условиями, и функция 18h, также позволяющая установить три обработчика и включающая в условие вызова состояние клавиш Shift, Ctrl и Alt. Воспользуемся обычной функцией 0Ch, чтобы написать простую программу для рисования. ; mousedr.asm ; Рисует на экране прямые линии с концами в позициях, указываемых мышью ;.model tiny.code org 100h ; СОМ-файл.186 ; для команды shr cx,3 start:

    3 mov ax,12h int 10h ; видеорежим 640×480 mov ax,0 ; инициализировать мышь mov ax,1 ; показать курсор мыши mov ax,000ch ; установить обработчик событий мыши mov cx,0002h ; событие — нажатие левой кнопки mov dx,offset handler ; ES:DX — адрес обработчика mov ah,0 ; ожидание нажатия любой клавиши int 16h mov ax,000ch mov cx,0000h ; удалить обработчик событий мыши mov ax,3 ; текстовый режим int 10h ret ; конец программы ; Обработчик событий мыши: при первом нажатии выводит точку на экран, ; при каждом дальнейшем вызове проводит прямую линию от предыдущей ; точки к текущей handler: push 0A000h pop es ; ES — начало видеопамяти push cs pop ds ; DS — сегмент кода и данных этой программы push сх ; СХ (Х-координата) и push dx ; DX (Y-координата) потребуются в конце mov ax, 2 ; спрятать курсор мыши перед выводом на экран cmp word ptr previous_x,-1 ; если это первый вызов, je first_point ; только вывести точку, call line_bresenham ; иначе — провести прямую exit_handler: pop dx ; восстановить СХ и DX pop сх mov previous_x,cx ; и запомнить их как предыдущие mov previous_y,dx ; координаты mov ax,1 ; показать курсор мыши retf ; выход из обработчика — команда RETF first_point: call jmp putpixel1b ; вывод одной точки (при первом вызове) short exit_handler ; Процедура рисования прямой линии с использованием алгоритма Брезенхама

    4 ; Ввод: СХ, DX — X, Y конечной точки ; previous_x,previous_y — X, Y начальной точки line_bresenham: mov ax, сх sub ax,previous_x ; AX = длина проекции прямой на ось X jns dx_pos ; если АХ отрицательный — neg ax ; сменить его знак, причем mov word ptr X_increment,1 ; координата X при выводе jmp short dx_neg ; прямой будет расти, dx_pos: mov word ptr X_increment,-1 ; а иначе — уменьшаться dx_neg: mov bx,dx sub bx,previous_y ; BX = длина проекции прямой на ось Y jns dy_pos ; если ВХ отрицательный — neg bx ; сменить его знак, причем mov word ptr Y_increment,1 ; координата Y при выводе jmp short dy_neg ; прямой будет расти, dy_pos: mov word ptr Y_increment,-1 ; а иначе — уменьшаться dy_neg: shl ax,1 ; удвоить значения проекций, shl bx,1 ; чтобы избежать работы с полуцелыми числами call putpixel1b ; вывести первую точку (прямая рисуется от ; CX,DX к previous_x,previous_y) cmp ax,bx ; если проекция на ось X больше, чем на Y: jna dx_le_dy mov di,ax ; DI будет указывать, в какую сторону мы shr di,1 ; отклонились от идеальной прямой neg di ; оптимальное начальное значение DI: add di,bx ; DI = 2 * dy — dx cycle: cmp ex,word ptr previous_x ; основной цикл выполняется, je exit_bres ; пока Х не станет равно previous_x cmp di,0 ; если DI > 0, jl fractlt0 add dx,word ptr Y_increment ; перейти к следующему Y sub di,ax ; и уменьшить DI на 2 * dx fractlt0: add cx,word ptr X_increment ; следующий Х (на каждом шаге) add di,bx ; увеличить DI на 2 * dy call putpixel1b ; вывести точку jmp short cycle ; продолжить цикл dx_le_dy: ; если проекция на ось Y больше, чем на X mov di,bx shr di,1 neg di ; оптимальное начальное значение DI: add di,ax ; DI = 2 * dx — dy cycle2: cmp dx,word ptr previous_y ; основной цикл выполняется, je exit_bres ; пока Y не станет равным previous_y, cmp di,0 ; если DI > 0,

    5 jl fractlt02 add cx,word ptr X_increment ; перейти к следующему X sub di,bx ; и уменьшить DI на 2 * dy fractlt02: add dx,word ptr Y_increment ; следующий Y (на каждом шаге) add di,ax ; увеличить DI на 2 * dy call putpixel1b ; вывести точку jmp short cycle2 ; продолжить цикл exit_bres: ret ; конец процедуры ; Процедура вывода точки на экран в режиме, использующем один бит для ; хранения одного пикселя. ; DХ = строка, СХ = столбец ; Все регистры сохраняются putpixel1b: pusha ; сохранить регистры xor bx,bx mov ax,dx ; AX = номер строки imul ах,ах,80 ; АХ = номер строки * число байт в строке push cx shr сх,3 ; СХ = номер байта в строке add ах,сх ; АХ = номер байта в видеопамяти mov di,ax ; поместить его в SI и DI для команд mov si,di ; строковой обработки pop cx ; СХ снова содержит номер столбца mov bx,0080h and cx,07h ; последние три бита СХ = ; остаток от деления на 8 = номер бита в байте, считая справа налево shr bx,cl ; теперь в BL установлен в 1 нужный бит lods es:byte ptr some_label ; AL = байт из видеопамяти or ax,bx ; установить выводимый бит в 1, ; чтобы стереть пиксель с экрана, эту команду OR можно заменить на ; not bx ; and ax,bx ; или лучше инициализировать ВХ не числом 0080h, а числом FF7Fh и использовать ; только and stosb ; и вернуть байт на место рора ; восстановить регистры ret ; конец previous_x dw -1 ; предыдущая Х-координата previous_y dw -1 ; предыдущая Y-координата Y_increment dw -1 ; направление изменения Y X_increment dw -1 ; направление изменения X some_label: ; метка, используемая для переопределения ; сегмента-источника для lods с DS на ES end start

    6 Алгоритм Брезенхама, использованный в этой программе, является самым распространенным алгоритмом рисования прямой. Существуют, конечно, и более эффективные алгоритмы, например алгоритм Цаолинь By, работающий на принципе конечного автомата, но алгоритм Брезенхама стал стандартом де-факто.

    Илон Маск рекомендует:  Тег style
  • Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL