Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Мышь

58K
22 ноября 2010 года
Aндрей
17 / / 21.11.2010
Нужна помощь. Помогите пожалуйста добавить вывод сигнала при нажатии кнопки мыши.

Код:
; mousedr.asm
;Рисует на экране прямые линии, оканчивающиеся в позициях, которые указываются мышью.
;
                .model  tiny
                .code
                org             100h                            ; COM-файл.
                .186                                            ; Для команжы shr cx, 3.
start:
                mov             ax, 12h
                int             10h                             ; Видеорежим 640*480.
                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            cx                              ; CX (X-координата) и DX(Y-координата)
                push            dx                              ; потребуются в конце.
               
                mov             ax, 2                           ; Спрятать курсор мыши перед выводом на экран.
                int             33h
               
                cmp             word ptr previous_X, -1            ; Если это первый вызов,
                je              first_point                     ; только вывести точку.
               
                call            line_bresenham                     ; Иначе - провести прямую.                                                  
 
exit_handler:
                pop             dx                              ; Восстановить CX и DX
                pop             cx
                mov             previous_X, cx                     ; и запомнить их как предыдущие
                mov             previous_Y, dx                     ; координаты.
               
                mov             ax, 1                           ; Показать курсор мыши.
                int             33h
               
                retf                                            ; Выход из обработчика - команда RETF.
               
first_point:
                call            putpixellb                      ; Вывод одной точки (при первом вызове).
                jmp             short exit_handler
 
; Процедура рисования прямой линии с использованием алгоритма Брезенхама.
; Вывод CX, DX - X, Y начальной точки.
; previous_X, previous_Y - X, Y начальной точки.
               
line_bresenham:
                mov             ax, cx
                sub             ax, previous_X                     ; AX = длина проекции прямой на ось X.
                jns             dx_pos                             ; Если AX отрицательный -
                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                             ; Если BX отрицательный -
                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            putpixellb                      ; Вывести первую точку (прямая рисуется от
                                                                ; 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             cx, word ptr previous_X            ; Основной цикл выполняется,
                je              exit_bres                       ; пока X не станет равное 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        ; Следующий X (на каждом шаге).
                add             di, bx                          ; Увеличить на DI на 2 * dy.
                call            putpixellb                      ; Вывести точку.                                                                                                                ;!!!!!
                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,
                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            putpixellb                      ; вывести точку,
                jmp             short cycle2                    ; продолжить цикл.
exit_bres:
                ret                                             ; Конец процедуры.
 
; Процедура вывода точки на экран в режиме, использующем один бит для
; хранения одного пикселя.
; DX = строка, CX = столбец.
; Все регистры сохраняются.
58K
22 ноября 2010 года
Aндрей
17 / / 21.11.2010
продолжение

Код:
putpixellb:
                pusha                                           ; Сохранить регистры.
                xor             bx, bx
                mov             ax, dx                          ; AX = номер строки.
                imul            ax, ax, 80                      ; AX = номер строки x число байтов в строке.
                push            cx
                shr             cx, 3                           ; CX = номер байта в строке.
                add             ax, cx                          ; AX = номер байта в видеопамяти.
                mov             di, ax                          ; Поместить его в SI и DI для команд
                mov             si, di                          ; строковой обработки.
               
                pop             cx                              ; CX снова содержит номер столбца.
                mov             bx, 0080h
                and             cx, 07h                            ; Последние три бита CX =
                                                                ; остаток от деления на 8 = номер бита в байте
                                                                ; считая справа налево.
                shr             bx, cl                          ; Теперь в BL установлен в 1 нужный бит.
 
                lods            es: byte ptr some_label            ; AL = байт из видеопамяти.
                ;or             ax, bx                          ; Установить выводимый бит в 1,
; Чтобы стереть пиксел с экрана, эту команду OR  можно заменить на
 not bx
 and ax, bx
; или лучше инициализировать BX не числом 0080h, а числом FF7Fh и использовать
; только and
                stosb                                           ; И вернуть байт на место.
                popa                                            ; Восстановить регистры.
                ret                                             ; Конец.
               
previous_X                      dw      -1                      ; Предыдущая X-координата.
previous_Y                      dw      -1                      ; Предыдущая Y-координата.
Y_increment                     dw      -1                      ; Направление изменения Y.
X_increment                     dw      -1                      ; Направление изменения X.
some_label:                                                     ; Метка, используемая для переопределения
                                                                ; сегмента-источника для lods с DS на ES.
                end     start
252
24 ноября 2010 года
koderAlex
1.4K / / 07.09.2005
вывод какого сигнала ? куда выводить ?
58K
24 ноября 2010 года
Aндрей
17 / / 21.11.2010
Просто чтобы при нажатии левой кнопки мыши звучал какой-нибудь один звук..
252
25 ноября 2010 года
koderAlex
1.4K / / 07.09.2005
включение динамика:
 
Код:
mov al,10110110b
out 43h,al
mov al,0dh
out 42h,al
mov al,11h
out 42h,al
in al,61h
or al,00000011b
out 61h,al


выключение динамика:
 
Код:
in al,61h
and al,11111100b
out 61h,al

ваша программа очень корявая . отрисовку на экран в обработчике прерывания никто не делает . обработчик прерывания должен выпольнять минимальные действия с источником прерывания , а обработка данных производится в основном цикле программы .
58K
06 декабря 2010 года
Aндрей
17 / / 21.11.2010
Разобрался с динамиком, исп. вот эту функцию:
 
Код:
mov ah, 2
mov dl, 07h; функция вывода сигнала
int 21h


Объясните пожалуйста вот это место в программе.
 
Код:
previous_X                      dw      -1                      ; Предыдущая X-координата.
previous_Y                      dw      -1                      ; Предыдущая Y-координата.
Y_increment                     dw      -1                      ; Направление изменения Y.
X_increment                     dw      -1                      ; Направление изменения X.
some_label:                                                     ; Метка, используемая для переопределения
                                                                ; сегмента-источника для lods с DS на ES.
252
06 декабря 2010 года
koderAlex
1.4K / / 07.09.2005
так программа ещё и не ваша ? :)

код в проге объявляет четыре двухбайтовых переменных с начальным значением =0xFFFF
а метка - она и в африке метка )
58K
06 декабря 2010 года
Aндрей
17 / / 21.11.2010
Нет, я ее набирал из учебника: "Зубков - Assembler для DOS, Windows и UNIX"
А "-1" это просто типо первоначальные значения?
252
06 декабря 2010 года
koderAlex
1.4K / / 07.09.2005
да, начальное
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог