Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

СРС N 7



" Манипулятор мышь"

Все общение с мышью в 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, чтобы получить номер строки и столбца соответственно.

В большинстве случаев эта функция не используется в программах, так как для того, чтобы реагировать на нажатие кнопки или перемещение мыши в заданную область, требуется вызывать это прерывание постоянно, что приводит к трате процессорного времени. Функции 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,3start: mov ax,12h int 10h; видеорежим 640x480 mov ax,0; инициализировать мышь int 33h mov ax,1; показать курсор мыши int 33h mov ax,000Ch; установить обработчик событий мыши mov cx,0002h; событие - нажатие левой кнопки mov dx,offset handler; ES:DX - адрес обработчика int 33h mov ah,0; ожидание нажатия любой клавиши int 16h mov ax,000Ch mov cx,0000h; удалить обработчик событий мыши int 33h 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; спрятать курсор мыши перед выводом на экран int 33h 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; показать курсор мыши int 33h retf; выход из обработчика - команда RETF first_point: call putpixel1b; вывод одной точки (при первом вызове) jmp short exit_handler; Процедура рисования прямой линии с использованием алгоритма Брезенхама; Ввод: СХ, 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 - dxcycle: 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 * dxfractlt0: 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 - dycycle2: cmp dx,word ptr previous_Y; основной цикл выполняется, je exit_bres; пока Y не станет равным previous_Y, cmp di,0; если DI > 0, jl fractlt02 add cx,word ptr X_increment; перейти к следующему X sub di,bx; и уменьшить DI на 2 * dyfractlt02: 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; направление изменения YX_increment dw -1; направление изменения Xsome_label:; метка, используемая для переопределения; сегмента-источника для lods с DS на ES end start

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

Примечание: Приведенную реализацию этого алгоритма можно значительно ускорить, использовав самомодифицирующийся код, то есть после проверки на направление прямой в начале алгоритма вписать прямо в дальнейший текст программы команды INС СХ, DEC CX, INС DX и DEC DX вместо команд сложения этих регистров с переменными X_increment и Y_increment. Самомодифицирующийся код часто применяется при программировании для DOS, но во многих многозадачных системах текст программы загружается в область памяти, защищенную от записи, так что в последнее время область применения этого приема становится ограниченной.

Реализация программы " Манипулятор мышь"

Познакомиться с различными режимами работы манипулятора мышь, режимами его работы в ПЭВМ IBM PC.

Вводятся новые элементы программирования на Ассемблере. Создание и использование макросов на Ассемблере. Водятся новые команды EQU, TEST.

Порядок выполнения работы:

1. Загрузите драйвер мыши (mouse.com).

2. Работа с программой PMOUSE0l.ASM (прерывания обслуживания мыши).

2.1 Проанализировать программу PMOUSE01.ASM.

2.2 Разобрать логику работы программы PMOUSE01.ASM, занести программу в тетрадь, откомментировать каждую команду.

2.3 Создать.ехе модуль PMOUSE01, запустить его на выполнение.

2.4 Проанализировать результаты работы программы PMOUSE01.ЕХЕ.

2.5 Запустите на выполнение программу PMOUSE0.EXE (программа русифицирована).

2.6 Русифицируйте программу PMOUSE01.ASM (с точно такими сообщениями как в программе PMOUSE0.EXE), измените форму курсора мыши.

3. К отчету представить:

3.1 Продемонстрировать работающую программу PMOUSE01 с внесенными требуемыми изменениями.

3.2 Представить текст программы PMOUSE1 с внесенными изменениями и комментариями.

3.3 Представить блок-схему программы PMOUSE01.

Контрольные вопросы:

1. Перечислите способы наиболее часто используемые для подключения манипулятора мышь к компьютеру IBM PC.

2. Перечислите типы программного интерфейса манипулятора мышь.

3. Перечислите программы (драйверы) для работы с манипулятором мышь.

4. Перечислите функции прерывания INT ЗЗН, связанные с обслуживанием манипулятора мышь.

5. с помощью конфигурационных файлов DOS.

6. Приведите пример загрузки драйвера манипулятора мышь в верхнюю область памяти.

7. Перечислите функции драйвера манипулятора мышь.

8. Преимущества использования макросов в программировании на языке ассемблер.

9. Назначение директивы присваивания языка ассемблер, приведите пример (фрагмент программы).

10.Использование подпрограмм при программировании на языке ассемблер.

Контрольные вопросы:

1. Перечислите адреса портов параллельного адаптера.

2. Перечислите стандартные функции BIOS для работы с принтером.

3. Опишите основные функции MS-DOS для работы с принтером.

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

5. Какие типы принтеров получили наибольшее распространение, достоинства и недостатки.

6. Перечислите типы используемых интерфейсов для подключения принтеров.

Примечания: 1.В файлах ASCII.TXT и PRINTER.TXT представлена справочная информация.

СРС №8





Дата публикования: 2015-10-09; Прочитано: 280 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.012 с)...