Основные функции интерфейса прикладной программы с
Краткое описание функций прерывания ЗЗh
Функция инициализации (АХ=0000h)
При вызове: АХ=ООООh
Возврат: АХ - состояние оборудования:
АХ = 0000h - отсутствует драйвер «мыши» или манипулятор;
АХ = FFFFh - «мышь» готова к работе;
ВХ - количество кнопок манипулятора:
ВХ = 0000h - не две кнопки;
ВХ = 0002h - две кнопки (Microsoft mode);
ВХ = 000Зh - три кнопки (Mouse mode).
Выбор типа курсора в текстовом режиме (АХ=0000h)
При вызове: АХ=000АХ – выбор типа курсора:
ВХ = 00 – программируемый курсор;
ВХ = 01 – «жесткий» курсор;
СХ – АND - маска для программируемого курсора или номер верхней скэн-линии для «жесткого» курсора;
ВХ – ХOR - маска для программируемого курсора или номер нижней скэн-линии для «жесткого» курсора;
Возврат: нет.
Установка курсора в графическом режиме (АХ=0009h)
При вызове: АХ = 0009h
ВХ – номер столбца «горячего пятна» курсора;
СХ – номер строки «горячего пятна» курсора;
ЕS:ВХ – указатель на 32 слова масок: 16 слов АND-маски и 16 слов ХOR-маски;
Возврат: нет.
Установка границ перемещения курсора (АХ=0007h, АХ=0008h)
При вызове: АХ=0007h – установка вертикальных границ перемещения курсора «мыши».
АХ=0008h – установка горизонтальных границ перемещения курсора «мыши».
СХ – минимальная граница перемещения курсора «мыши».
ВХ – максимальная граница перемещения курсора «мыши».
Возврат: нет.
Функции включения/выключения курсора (АХ=0001h, АХ=0002h)
При вызове:АХ=0001h – включить курсор «мыши».
АХ=0002h – выключить курсор «мыши».
Возврат:нет.
Чтение позиции курсора и состояния кнопок «мыши» (АХ=0003h)
При вызове: АХ=ОООЗh
Возврат: ВH – байт состояния кнопок манипулятора:
бит 0 – состояние левой кнопки;
бит 1 - состояние правой кнопки;
бит 2 - состояние средней кнопки (для Моuse mode);
СХ – горизонтальная координата курсора «мыши»;
ВХ – вертикальная координата курсора «мыши».
Установка курсора «мыши» в новое место экрана (АХ=0004h)
При вызове: АХ – 0004h - установка вертикальных границ перемещения курсора «мыши».
СХ – горизонтальная координата курсора «мыши».
DХ – вертикальная координата курсора «мыши».
Возврат:нет.
манипулятором «мышь»
Подготовительные операции программы
Для работы по управлению манипулятором и организации ввода информации прикладная программа выполняет различные функции прерывания ЗЗh. В настоящее время большинство драйверов «мыши» поддерживают стандарт, введенный фирмой Мicrosoft для различных функций прерывания ЗЗh. Многие системы программирования имеют в своем составе библиотечные функции, выполняющие обращение к той или иной функции прерывания ЗЗh. Библиотечные функции работают медленнее, чем непосредственное обращение к прерыванию ЗЗh из прикладной программы. Кроме того, многие программисты в нашей стране используют неполные или даже несанкционированные копии систем программирования, в которых библиотеки поддержки манипулятора отсутствуют или работают некорректно. Поэтому в дальнейшем приводятся примеры непосредственного обращения к прерыванию ЗЗh, а не библиотечные функции ТuгЬо С.
Каждая программа, использующая для ввода информации манипулятор «мышь», должна выполнить ряд подготовительных операций:
1) определить, инсталлирован ли драйвер «мыши»;
2) задать вид и форму курсора манипулятора;
3) описать границы перемещения курсора «мыши» по экрану;
4) описать «чувствительность» курсора, равную числу «микки», приходящихся на один пиксел экрана по горизонтали и вертикали;
5) установить порог «удвоенной» скорости курсора «мыши»;
6) «включить» курсор манипулятора (сделать его видимым на экране);
7) установить курсор в начальную позицию на экране в соответствии с нуждами программы.
Многие из этих действий помогает осуществить функция инициализации и определения текущего состояния драйвера манипулятора (АХ = 0000h). Ниже приводится спецификация этой функции. При вызове:
АХ – 0000h Возврат: АХ – состояние оборудования:
0000h – отсутствует драйвер «мыши» (отсутствует аппаратура, не загружен драйвер);
FFFFh – «мышь» готова к работе; ВХ – количество кнопок манипулятора:
0003h – не две кнопки;
0002h – две кнопки (режим Мicrosoft mode);
000Зh – три кнопки (режим Мouse mode).
При выполнении функции АХ = 0000h драйвер манипулятора приводится в состояние по умолчанию:
1) курсор манипулятора установлен в центре экрана и выключен;
2) чувствительность манипулятора по вертикали равна 2 микки/пиксел, по горизонтали – 1 микки/пиксел;
3) порог удвоенной скорости установлен равным 64 микки/с;
4)установлена форма курсора по умолчанию; 5) координаты левого верхнего угла области перемещения курсора манипулятора соответствуют координатам (0, 0), а координаты нижнего правого угла области перемещения манипулятора – максимальным координатам текущего видеорежима минус 1.
Если необходимо установить значения, отличающиеся от значений по умолчанию, используются функции установки формы курсора, границ его перемещения, задания значений чувствительности и порога удвоенной скорости.
Для определения того, работоспособна ли «мышь», необходимо выполнить функцию АХ = 0000h и проанализировать возврат в АХ. Если АХ = – 1, это указывает на готовность манипулятора к работе. Здесь следует сделать два замечания. Первое из них состоит в том, что операционная система MS-DOS «цепляет» при загрузке за вектор прерывания ЗЗh «заглушку» из единственной инструкции IRET. Поэтому выполнение инструкции INT ЗЗh даже при отсутствии драйвера не порождает никаких проблем. Второе замечание заключается в том, что успешное завершение инициализации не означает, однако, что аппаратура адаптера или самого манипулятора исправна, а свидетельствует только о том, что загружен драйвер «мыши». В ряде случаев драйвер «мыши» передает в манипулятор заранее заданную последовательность cлов информации. Эти слова вызывают в манипуляторе генерацию ответного «эха», анализ которого позволяет драйверу однозначно опознать «свою» аппаратуру манипулятора и проверить исправность цепей приема информации адаптера асинхронной последовательной связи.
Приводимый далее фрагмент С-кода иллюстрирует использование функции инициализации манипулятора «мышь».
Инициализация «мыши».
АХ = 0
Geninterrupt (0x33);
If (AX = = 0)
Puts (НЕТ мыши!);
exit(-1).
Успешное завершение инициализации позволяет продолжить работу прикладной программы по подготовке к использованию «мыши». Следующая операция связана с определением типа и формы курсора. Драйверы «мыши» в текстовом режиме работы видеоадаптера поддерживают два типа курсора:
1) «жесткий», совпадающий с обычным курсором текстового режима в форме нескольких сплошных телевизионных строк в пределах знакоместа;
2) программируемый, представляющий собой знакоместо с измененным атрибутом символа и, возможно, со специфицированным пользователем символом. Курсор «мыши» в текстовом режиме перемещается по знакоместам экрана. Выбор типа и параметров курсора «мыши» в текстовом режиме работы видеоадаптера выполняется с помощью функции АХ = 0Ah прерывания 33h, спецификация которой приводится далее.
При вызове:
АХ – 000Ah – установка курсора «мыши» в текстовом режиме; ВХ – выбор типа курсора:
00 – программируемый курсор;
01 – «жесткий» курсор; СХ – AND-маска (маска экрана) для программируемого курсора или номер верхней скэн-линии для «жесткого» курсора; DX – XOR-маска (маска курсора) для программируемого курсора или номер нижней скэн-линии для жесткого курсора Возврат: нет.
Если выбран «жесткий» курсор, то курсор мыши на экране имеет форму обычного текстового. Преимуществом такого курсора является то, что на экране присутствует только один привычный курсор и при любой операции ввода информации спользованием функций MS-DOS (например, функций стандартного ввода-вывода) кypcор «мыши» автоматически перемещается в текущую текстовую позицию BlOSa. Это не означает, однако, что драйвер «мыши» при перемещении курсора обновляет слово текущей позиции курсора в области данныхBlOSa. Поэтому без дополнительных усилий со стороны программиста не удается поместить символ на экране впозицию, на которую указывает курсор «мыши».
При формировании программируемого текстового курсора используется: 1) слово видеопамяти, образованное символом и атрибутом знакоместа экрана, в котором находится курсор манипулятора – screen word; 2) AND-маска – AND mask; 3) XOR-маска – XOR mask. Результирующее представление курсора на экране формируется поразрядными логическими операциями по формуле
screen _ word = screen _ word AND AND _ mask XOR XOR _ mask
При перемещении курсора в другую позицию предыдущее содержимое видеобуфера восстанавливается. Таким образом, пользователь может установить различные формы программируемого текстового курсора «мыши». Например, задание AND_mask = 00FFh и XOR_mask = хх00h приведет к тому, что текстовый курсор будет прямоугольником, сохраняющим любой предыдущий символ, атрибут которого хх. Младшая шестнадцатеричная цифра будет задавать цвет контура символа, а старшая – цвет фона. При этом, однако, возможно «исчезновение» курсора, если атрибут символа уже был равен хх. Распространенным является программируемый текстовый курсор со следующими значениями: AND_mask = FFFFh и XOR_mask = 7700h. В этом случае инвертируется как цвет фона, так и цвет атрибута, что гарантирует видимость курсора и не изменяет символ в позиции курсора. Нетрудно добиться того, чтобы курсор «мыши» на экране отображался в виде нужного символа. Например, для того чтобы, текстовый курсор «мыши» имел форму «птички» (ASCII-код FBh), необходимо задать такие маски: AND_mask – 0000h и XOR_mask – xxFBh, где хх задает атрибут символа курсора. Общеупотребительной является практика изменения формы текстового курсора для индикации обнаруженного нажатия той или иной кнопки манипулятора «мышь».
Далее приводится текст Си-функции задания параметров курсора манипулятора «мышь» для текстового режима работы адаптера.
Установка заданной формы курсора в текстовом режиме. Параметр int mode – выбирает либо «жесткий» (0), либо программируемый курсор (1). Если выбран программируемый курсор, AND_mask задает маску экрана, a XOR_mask – маску курсора. В противном случае AND_mask задает номер верхней скэн-линии, a XOR_mask – номер нижней скэн-линии.
include <dos.h>
void set_text_cursor(1nt mode, unsigned int AND_mask,
unsigned int XOR_ mask)
struct REGPACK r;
r.r_ax = 0x0a;
r. r_bx = mode;
r. r_cx = AND_mask;
r.r_dx = XOR_mask;
intr(0x33, &r);
В графическом режиме работы видеоадаптера может быть описана любая собственная форма курсора в пределах прямоугольника 16 х 16 пикселов. Курсор в графическом режиме описывается двумя масками размером 16 х 16 бит каждая. Одна из масок называется AND – маской (маской экрана), другая –XOR –маской (маской курсора). При перемещении курсора предыдущее содержимое экрана восстанавливается драйвером «мыши». Маски, комбинируясь, определяют способ обработки текущего кода цвета пиксела на экране. Результаты обработки представлены в табл. 4. 1. Табл. 4. 1. Формирования кода цвета пикселов изображения курсора «мыши» в графическом режиме:
Бит AND-маски | Бит XOR-маски | Цвет пиксела на экране |
Цвет фона | ||
Белый цвет | ||
Текущий цвет пиксела | ||
Побитовая инверсия текущего цвета пиксела |
С помощью различных масок можно установить любую форму курсора и добиться его видимости на любом фоне. Для режимов 4, 5 и 13h используются только четные столбцы в битовых масках; в противном случае курсор при использовании матрицы 16 х 16 имел бы слишком большие размеры. Для остальных режимов «прореживание» столбцов масок курсора не выполняется.
В графических режимах, кроме формы курсора, описывается так называемое «горячее пятно» (hot spot) в относительных координатах, за точку отсчета которых принят верхний левый угол прямоугольника 16 х 16 пикселов. «Горячее пятно» – это тот пиксел, на который указывает в данный момент графический курсор. Описание курсора манипулятора «мышь» в графическом режиме выполняет функция АХ = 9 прерывания 33h. Далее приводится ее спецификация. При вызове:
АХ – 0009Н – установка курсора «мыши» в графическом режиме; ВХ – номер столбца «горячего пятна» курсора относительно верхнего левого угла прямоугольника курсора; СХ – номер строки «горячего пятна» курсора относительно верхнего левого угла прямоугольника курсора; ES:DX – указатель на 32 слова масок: первые 16 слов образуют AND-маску, следующие 16 слов – XOR-маску. Использование битов этих масок иллюстрирует табл. 4.1.
Возврат: нет.
Приведем текст Си-функции установки графического курсора манипулятора «мышь».
Установка заданной формы курсора в графическом режиме. Параметры char hot spot row, char hot spot col – относительные координаты «горячего пятна» курсора «мыши» в прямоугольнике курсора; unsigned int far screen and cursor masks – указатель на две подряд расположенные маски экрана и курсора; первые 16 слов массива образуют маску экрана, следующие 16 – маску курсора.
include <dos.h>
void set_graph_cursor( int hot_spot_row,
int hot_spot_column,
unsigned int far screen_and_cursor_masks);
struct REGPACK r;
r. r_ax = 9;
r.r_bx = hot_spot_column;
r.r_cx = hot_spot_row;
r.r_es=FP_SEG(screen_and_cursor_masks);
r.r_dх=FP_QFF(screen_and_cursor_masks);
intr(0x33, &r);
Для получения графического курсора, видимого на любом фоне, поступают следующим образом. Маску экрана (AND-маскy) задают состоящей из слов FFFFh, а маску курсора (XOR-маску) описывают так, чтобы в ней стояли единицы в тех битах, которые образуют очертание курсора, а нули – во всех остальных битах маски. В качестве примера приводится вызов функции set graph cursor 0 для задания графического курсора в форме наклонной стрелки.
XOR-маскаотображения курсора в виде стрелки
2 с/с 16 с/с
1000 0000 0000 0000 0x80001100 0000 0000 0000 0xC000
1010 0000 0000 0000 0хC000
1001 0000 0000 0000 0x9000
1010 1000 0000 0000 0хА800
1011 0100 0000 0000 0хB400
1011 1010 0000 0000 0хBA00
1011 1101 0000 0000 0хBD00
1011 1110 1000 0000 0хBE80
1011 1111 0100 0000 0хBF40
1011 1111 1010 0000 0xBFА0
1011 1111 1101 0000 0хBFD0
1011 1111 1110 0000 0xBFE0
1010 1110 0000 0000 0хAE00
1010 0011 0000 0000 0хАЗ00
1110 0011 0000 0000 0хЕЗ00
static unsigned screen_and cursor_masks AND-маска
Oxffff, Oxffff, Oxffff, Oxffff,
Oxffff, Oxffff, Oxffff, Oxffff,
Oxffff, Oxffff, Oxffff, Oxffff,
Oxffff, Oxffff, Oxffff, Oxffff
Текст исходной программы
.model small
.stack 256
.data
stat db ?
col dw ?
row dw ?
color db 1
flag db 0
rezult db '000$'
mult10 db 10
mes_er db 'мышь не установлена', 13, 10, '$'
mes db 'пpогpамма завеpшена', 13, 10, '$'
mask_m dw 16 dup(0ffffh)
dw 8000h, 0c000h, 0a000h, 9000h
dw 0a800h, 0b400h, 0ba00h, 0bd00h
dw 0be80h, 0bf40h, 0bfa0h, 0bfd0h
dw 0bfe0h, 0ae00h, 0a300h, 0e300h
.code
cursor_on proc near
mov ax, 01
int 33h
ret
cursor_on endp
cursor_off proc near
mov ax, 2
int 33h
ret
cursor_off endp
mouse_stat proc near
mov ax, 3
int 33h
ret
mouse_stat endp
pixel proc near
call cursor_off
mov ah, 0Ch
mov al, color
mov bh, 0
int 10h
call cursor_on
ret
pixel endp
speed proc near
mov ax, 000fh
mov cx, 64
mov dx, 64
int 33h
mov ax, 0013h
mov dx, 64
int 33h
ret
speed endp
text_curc proc near
mov ax, 000AH
mov bx, 01
int 33h
ret
text_curc endp
write proc near
mov bx, 3
cicle:
idiv mult10
add ah, 30h
mov [si+bx-1], ah
mov ah, 0
dec bx
jnz cicle
mov ah, 09
mov dx, offset rezult
int 21h
ret
write endp
go: mov ax, @data
mov ds, ax
mov ax, 0
int 33h
cmp ax, 0
jne ner
jmp er
ner:
mov ax, 10h
int 10h
mov ax, 9
xor bx, bx
xor cx, cx
push ds
pop es
lea dx, mask_m
int 33h
call speed
call cursor_on
call mouse_stat
mov col, cx
mov row, dx
next:
mov ah, 02
mov bh, 00
mov dx, 00
int 10h
mov ax, col
lea si, rezult
call write
mov ah, 02
mov bh, 0
mov dx, 0005h
int 10h
mov ax, row
call write
mov dx, row
mov cx, col
mov ah, 1
int 16h
jz nosym
mov ah, 0
int 16h
cmp al, 27
je ex
nosym:
mov flag, 0
call mouse_stat
mov stat, bl
cmp col, cx
je rov_lab
mov col, cx
mov flag , 1
rov_lab:
cmp row, dx
je pix
mov row , dx
mov flag, 1
pix:
mov bl, stat
and bl, 2
cmp bl, 2
je nextc
mov bl, stat
and bl, 1
cmp bl, 1
jne next
cmp flag, 0
je next
call pixel
jmp next
ex:
call cursor_off
lea dx, mes
jmp exit
nextc:
inc color
jmp next
er:
lea dx, mes_er
exit:
mov ax, 3
int 10h
mov ah, 9
int 21h
mov ax, 4c00h
int 21h
End go
Результат работы исходной программы
Текст доработанной программы
.model small
.stack 256
.data
stat db ?
col dw ?
row dw ?
color db 1
flag db 0
rezult db '000$'
mult10 db 10
mesx db 'x =$'
mesy db 'y =$'
mes_er db 'мышь не установлена', 13, 10, '$'
mes db 'пpогpамма завеpшена', 13, 10, '$'
mask_m dw 16 dup(0ffffh)
dw 8000h, 0c000h, 0a000h, 9000h
dw 8000h, 0c000h, 0a000h, 9000h
dw 8000h, 0c000h, 0a000h, 9000h
dw 8000h, 0c000h, 0a000h, 9000h
; dw a800h, 0b400h, 0ba00h, 0bd00h
; dw 0be80h, 0bf40h, 0bfa0h, 0bfd0h
; dw 0bfe0h, 0ae00h, 0a300h, 0e300h
.code
cursor_on proc near
mov ax, 01
int 33h
ret
cursor_on endp
cursor_off proc near
mov ax, 2
int 33h
ret
cursor_off endp
mouse_stat proc near
mov ax, 3
int 33h
ret
mouse_stat endp
pixel proc near
call cursor_off
mov ah, 0Ch
mov al, color
mov bh, 0
int 10h
call cursor_on
ret
pixel endp
speed proc near
mov ax, 000fh
mov cx, 64
mov dx, 64
int 33h
mov ax, 0013h
mov dx, 64
int 33h
ret
speed endp
text_curc proc near
mov ax, 000AH
mov bx, 01
int 33h
ret
text_curc endp
write proc near
mov bx, 3
cicle:
idiv mult10
add ah, 30h
mov [si+bx-1], ah
mov ah, 0
dec bx
jnz cicle
mov ah, 09
mov dx, offset rezult
int 21h
ret
write endp
go: mov ax, @data
mov ds, ax
mov ax, 0
int 33h
cmp ax, 0
jne ner
jmp er
ner:
mov ax, 10h
int 10h
mov ax, 9
xor bx, bx
xor cx, cx
push ds
pop es
lea dx, mask_m
int 33h
call speed
call cursor_on
call mouse_stat
mov col, cx
mov row, dx
mov ah, 02
mov bh, 00
mov dx, 0000h
int 10h
mov ah, 9
lea dx, mesx
int 21h
mov ah, 02
mov bh, 00
mov dx, 0009h
int 10h
mov ah, 9
lea dx, mesy
int 21h
next:
mov ah, 02
mov bh, 00
mov dx, 0004h
int 10h
mov ax, col
lea si, rezult
call write
mov ah, 02
mov bh, 0
mov dx, 000Dh
int 10h
mov ax, row
call write
mov dx, row
mov cx, col
mov ah, 1
int 16h
jz nosym
mov ah, 0
int 16h
cmp al, 27
je ex
nosym:
mov flag, 0
call mouse_stat
mov stat, bl
cmp col, cx
je rov_lab
mov col, cx
mov flag , 1
rov_lab:
cmp row, dx
je pix
mov row , dx
mov flag, 1
pix:
mov bl, stat
and bl, 2
cmp bl, 2
je nextc
mov bl, stat
and bl, 1
cmp bl, 1
jne next
cmp flag, 0
je next
call pixel
jmp next
ex:
call cursor_off
lea dx, mes
jmp exit
nextc:
inc color
jmp next
er:
lea dx, mes_er
exit:
mov ax, 3
int 10h
mov ah, 9
int 21h
mov ax, 4c00h
int 21h
End go
Результат модифицированной программы