Графические устройства

         

Предварительные действия

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

Новое макроопределение

В примере 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 для вертикального направлений. В результате при движении по горизонтали СПМ и СПК изменяются синхронно, а при движении по вертикали СПК изменяется в два раза медленнее, чем СПМ.


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