Предварительные действия
В данном разделе описана настройка драйвера и задачи на совместную работу.
Выполняемые при этом действия не зависят от того, как задача взаимодействует
с драйвером, — периодически обращаясь к нему, или в режиме прерываний.
Они заключаются в инициализации драйвера, установке границ рабочего поля
и исходной позиции курсора. Дополнительно может быть выбрана чувствительность
драйвера и курсора к перемещениям мыши. Настройка выполняется после установки
видеорежима и получения его характеристик.
Новое макроопределение
В примере 2.12 главы 2 были
описаны макроопределения PushReg и PopReg, которые неоднократно использовались
в примерах подпрограмм. Добавим к ним новое макроопределение, формирующее
команды запроса функций драйвера мыши. Оно почти не сокращает текст программы,
но делает его более наглядным и понятным. Описание макроопределения приведено
в примере 6.7, оно должно располагаться перед основным текстом программы.
Пример 6.7. Макроопределение для обращений к драйверу
мыши
Mouse macro fun ; номер функции задает параметр fun
mov ax, fun&h ; номер функции помещается в ах
int 33h ; обращение к драйверу
endm ; конец макроопределения.
Макровызов этого определения имеет вид Mouse fun, где вместо fun указывается
шестнадцатеричный номер вызываемой функции без буквы ь в конце. Обнаружив
вызов, Макроассемблер находит одноименное определение, обрабатывает его
и включает в задачу две команды. Первая из них пересылает в регистр ах
указанный в макровызове код fun, к которому добавляется буква b. Вторая
команда int ззь выполняет обращение в драйверу мыши. Например, на месте
макровызова Mouse 21 в тексте задачи окажутся две следующие команды:
mov ax, 21h ; запись в ах кода 21h
int 33h ; обращение к драйверу мыши
Замечание
Обратите внимание на то, что макровызов Mouse 2lh ассемблер воспримет
как ошибку. Поэтому если вы предпочитаете указывать букву h после кода,
то во второй строке примера 6.7 после слова fun надо убрать символы &h,
которые вызывают добавление буквы h к коду функции.
Инициализация драйвера нужна для того, чтобы
ликвидировать те изменения значений его внутренних переменных, которые
могли оставить после себя другие задачи. Если по каким-то причинам эти
изменения надо сохранить, то перед инициализацией производится сохранение
буфера состояния драйвера, о чем говорилось в конце предыдущего раздела.
Функция Mouse о выполняет инициализацию
драйвера и возвращает дополнительные данные в регистрах ах и bх.
Если драйвер мыши отсутствует в оперативной памяти, то регистр ах очищен.
Это может означать либо отсутствие соответствующего файла в
autoexec.bat или в config.sys. либо отсутствие или неисправность мыши.
В процессе установки драйвер анализирует наличие и тип мыши, и если
работа с ней невозможна, то установка не выполняется.
Если 15 регистре ах находится код OFFFFS-I, то инициализация выполнена
успешно. В таком случае в регистре bх указано количество имеющихся у мыши
кнопок.
После исполнения запроса Mouse 0 желательно
проверить содержимое регистров ах и bх. Если драйвер отсутствует, то дальнейшее
выполнение программы невозможно или для управления задачей должна использоваться
клавиатура. Аналогично, если задача рассчитана на работу с тремя кнопками,
а у мыши их только две, то придется либо прервать выполнение задачи, либо
настроить ее на работу только с двумя кнопками.
Функция Mouse 21 аналогична функции Mouse
0, но при ее исполнении не производится аппаратный сброс мыши и
не изменяются значения переменных, зависящих от ее технических характеристик.
В большинстве случаев это различие не принципиально.
Пределы перемещения и исходная позиция
При работе в режимах VESA основное назначение драйвера заключается в
отслеживании текущей позиции мыши и ее преобразовании в координаты курсора
на экране. Для того чтобы это преобразование было корректным, после инициализации
драйвера надо установить размер рабочего поля, указав его границы по горизонтали
и вертикали.
Функции Mouse 7 и Mouse 8 передают драйверу
предельные значения координат по горизонтали и вертикали. Миниматьное
значение координат х (для Mouse 7) или у (для Mouse б) помещаются в регистр
сх, а максимальное значение — в dx. Выходные параметры у обеих функций
отсутствуют.
Если рабочее поле занимает весь экран, то минимальные значения обеих
координат равны нулю (xmin = Ymin = о), а максимальные
зависят от разрешающей способности видеорежима, ПОЭТОМУ Xmax
= horsize, a Ymax = versize. Например,для режима VESA
101h Xmax = 640, a Ymax = 480.
После установки границ рабочего поля задается исходная позиция курсора.
Его конкретное расположение может быть произвольным, но обычно курсор
помещают в центр экрана.
Функция Mouse 4 перемещает курсор в заданную
позицию. Перед обращением к драйверу в регистры сх и dx помещаются значения
координат х и Y. Выходные параметры у функции отсутствуют.
Здесь имеется в виду тот курсор, который обычно рисует драйвер мыши.
Как уже говорилось, при установке режимов VESA драйвер не может
работать с курсором. Поэтому при выполнении данной функции указанная позиция
просто фиксируется в счетчиках драйвера, содержащих текущие координаты.
Для перемещения курсора в центр экрана значения координат составляют
х = horsize/2, Y = versize/2. После установки этих величин можно нарисовать
изображение курсора на экране.
Напомним, что при работе в стандартных видеорежимах IBM драйвер автоматически
определяет границы рабочего поля и принудительно помещает изображенис
курсора в центр экрана (если курсор включен).
Новые переменные
При выполнении подготовительных действий надо настроить не только драйвер,
но и задачу. В процессе выполнения задачи будет неоднократно анализироваться
перемещение мыши и состояние ее кнопок. Для того чтобы анализ был возможен,
в разделе данных программы должны быть зарезервированы перечисленные в
примере 6.8 переменные.
Пример 6.8. Переменные, используемые при работе с мышью
Winpnt dw 2 ; окно видеопамяти, в котором расположен курсор
Offspnt dw 22848 смещение изображения курсора в этом окне Xpointer dw
320 текущая X координата курсора (немер столбца)
Ypointer dw 240 текущая Y координата курсора (номер строки)
Mstatus db 0 текущее состояние манипулятора "мышь"
LBevent db 0 изменение состояния левой кнопки
RBevent db 0 изменение состояния правой кнопки
В переменных winpnt и offspnt
хранится адрес видеопамяти для левой верхней точки изображения
курсора, они уже использовались в примерах 6.4, 6.5 и 6.6 данной главы.
Переменные Xpointer и Ypointer
содержат тот же адрес, но представленный в виде номеров строки и столбца.
В примере 6.8 указаны их исходные значения для режима VESA ioih при условии,
что курсор находится в центре экрана. Вычисления значений этих четырех
переменных производится в примере 6.9.
Три последние переменные примера 6.8 имеют размер байта. В исходном
состоянии они должны быть очищены, что и делается при их описании. Mstatus
содержит данные о текущем состоянии манипулятора, a LBevent и RBevent
— коды конкретного состояния левой (LB) и правой (RB) кнопок мыши. Как
формируются текущие значения этих переменных, показано в примере 6.12.
Выполнение настройки. Способ выполнения всех описанных действий иллюстрирует
пример 6.9. Приведенный в нем фрагмент программы должен выполняться в
процессе подготовительных действий, но только после установки видеорежима
и получения его характеристик.
Пример 6.9. Настройка драйвера, задачи и первый вывод курсора
mouse 0 инициализация драйвера
; !! здесь желательно проверить содержимое регистров АХ и ВХ !!
хог сх, сх СХ = Xmin = Ymin = 0
rnov ax, horsize DX = Xmax = horsize
mouse 7 установка границ по горизонтали
mov dx, versize DX = Ymax = versize
mouse 8 установка границ по вертикали
mov сх, horsize СХ = horsize
shr ex, 01 центр экрана по горизонтали
shr dx, 01 центр экрана по вертикали
mouse 4 установка значений счетчика драйвера
mov Xpointer, сх Xpointer = 0,5 * horsize
mov Ypointer, dx Ypointer = 0,5 * versize
mov ax, versize AX = versize
inc ax AX = versize + i
mul ex DX:AX = (versize + 1) * horsize / 2
; В режимах direct color результат надо умножить на размер кода точки
mov Offspnt, ax сохраняем смещение рисунка курсора
mov ax, GrUnit AX = единица измерения размера окна
mul dl AX = DL * GrUnit (номер видеоокна)
add ax, Base_Win !! учитываем значение базового окна
mov Winpnt, ax сохраняем значение окна видеопамяти
call Showpnt первое построение рисунка курсора
При вычислении адреса видеопамяти по номеру строки и столбца надо учитывать
размер кода точки. Пример 6.9 предназначен для выполнения в режимах PPG,
когда код точки занимает 1 байт. Если ваша задача работает с режимами
direct color, то результат, вычисленный командой mul, надо дополнительно
умножить на размер кода точки. Подробнее об этом будет сказано при описании
примера 6.13.
Важно
Команда add ax, Base_win нужна только в том случае, если задача поддерживает
работу со страницами видеопамяти (см. раздел),
в остальных случаях ее надо исключить из текста примера.
В зависимости от способа построения изображения курсора в последней
команде примера 6.9 должна вызываться подпрограмма
showpnt (см. пример 6.5) или Tgipntr (см.
пример 6.4).
Чувствительность курсора и мыши
При установке драйвера по умолчанию выбирается режим работы, при котором
перемещение мыши на 1 дюйм по горизонтали или вертикали вызывает перемещение
курсора на 640 столбцов. или на 320 строк. Рассмотрим, как драйвер увязывает
перемещения мыши и курсора.
Во внутреннем буфере драйвера имеются четыре счетчика, содержащих количество
перемещений по вертикали и горизонтали. Два из них связаны с курсором,
а два с мышью. Условимся обозначать их как СПК (счетчик перемещений курсора)
и СПМ (счетчик перемещений мыши). Прикладные задачи могут изменять значения
СПК с помощью команды Mouse 4, но значения СПМ они могут только считывать.
Драйвер пересчитывает значения СПМ в значения СПК, используя для этого
специальные коэффициенты. При установке драйвера по умолчанию выбираются
такие значения коэффициентов, которые вызывают изменение содержимого СПМ
и СПК на 1 при каждом перемещении мыши в горизонтальном направлении, и
изменение значений СПМ на 1, а СПК — на 2 при каждом перемещении мыши
в вертикальном направлении. Прикладная задача или операционная система
могут изменить значения коэффициентов.
Функция Mouse 1A устанавливает, a Mouse
IB считывает значение коэффициента, задающего чувствительность СПМ к перемещениям
мыши.
Значения коэффициентов указываются или возвращаются драйвером в регистрах
bх (горизонтальное направление) и сх (вертикальное направление). Содержимое
bх и сх может изменяться от 0 до 100 и интерпретируется как проценты.
При задании больших значений они принудительно уменьшаются до 100 (64П).
За единицу принято 50% (код 32h), при котором содержимое СПМ изменяется
на 1 при каждом перемещении мыши. Значение 100% вызывает изменение содержимого
СПМ на 2 при каждом перемещении мыши. А при коэффициенте 25% оно будет
изменяться на 1 при двух перемещениях мыши.
Перемещение мыши принято измерять в mickey. Перевод этого термина автору
не известен, но, по сути, это величина обратная количеству точек на дюйм
(Dot Per inch или DPI). У современных манипуляторов DPI = 400, соответственно
1 mickey = 1/400 дюйма или примерно 0,06 миллиметра.
Функция Mouse OF устанавливает чувствительность
СПК к изменениям СПМ. Перед обращением к драйверу в регистрах сх и dx
указываются значения коэффициентов для горизонтального (сх) и вертикального
(dx) направлений. Эти коэффициенты указывают, на сколько единиц должно
измениться значение СПМ для того, чтобы значение СПК изменилось на 8 единиц.
При установке драйвера (по умолчанию) коэффициенты равны 8 для горизонтального
и 16 для вертикального направлений. В результате при движении по горизонтали
СПМ и СПК изменяются синхронно, а при движении по вертикали СПК изменяется
в два раза медленнее, чем СПМ.
|