С подключением до системного 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

С подключением до системного



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

Рассмотрим процесс взаимодействия системы с клавиатурой.


Работой клавиатурой управляет - контроллер клавиатуры - 8048 - однокристальная микро ЭВМ. В его функцию входит распознавание нажатой клавиши и помещения закрепленного за ней кода в своей выходной порт 60h. Код клавиши называется скен-кодом и является, по существу, порядковым номером клавиши. При этом каждой клавише присвоено 2 скен-кода, отличающиеся друг от друга на 80h Один скен-код (меньший) код, кажется, засылается в порт 60h при нажатии на клавишу, другой (Больший) - код опускания - при опускании.

Для 83-клавишной клавиатуры код опускания = коду нажатия +80H (10000000В). Поэтому проверить отпущена ли клавиша? Очень просто - проверить старший разряд. Это справедливо для большинства клавиш расширенной (101-клавиша) клавиатуры. Однако для дополнительных клавиш и некоторых комбинаций клавиш - скен-коды имеют старший байт, установленный

в 1 даже при нажатии на клавишу.

Скен-код 01h - клавиша Esc

02h -!/1

03h - @/2 и т.д. слева направо по верхнему ряду клавиатуры. После клавиши BaskSpace последовательная нумерация возобновляется с клавиши Tab в ряду QWERTY. После перечисления клавиш пишущей машинки нумерация продолжается на функциональных клавишах, а далее - на дополнительных.

Итак, скен-код однозначно указывает на нажатую клавишу, однако по нему нельзя определить, работает ли пользователь на нижнем или верхнем регистре, Т.о., очевидно, что определение введенного символа должно включать в себя не только считывание скен-кода нажатой клавиши, но и определение того, не были ли перед этим нажаты, например, клавиши "Shift" или "Caps Lock" (фиксация верхнего регистра). Этим анализом занимается программа пред. От клавиатуры Int 09h.

Программа Int 09h, помимо порта 60h, работает еще с 2-мя областями оперативной памяти: кольцевым буфером ввода, расположенных по адресам от 40h:1Eh до 40h:3Dh и байтом флагов клавиатуры КВ-FLAG, находящимся по адресу 40h:17h, где фиксируется состояние управляющих клавиш.

 

 
 

 


 

 

Программа Int 09h, получив управление в результате прерывания от клавиатуры, считывает из порта 60h скен-код и анализирует его. Если скен-код принадлежит одной из управляющих клавиш (в программе есть спец. таблица ложная) и представляет собой нажатие, в байте КВ-FLAG флагов клавиатуры устанавливается (флаг) бит, соответствующий нажатой клавише. Например, при нажатии на правый Shift устанавливается в 1 бит Æ КВ-FLAG и т.д. Биты фалов сохраняют свое состояние, пока клавиши (по одиночке или в любых комбинациях) остаются нажатыми. Если клавиша отпускается, программа Int 09h получает

скен-код отпускания и сбрасывает соответствующий бит в байте флагов.

В компьютерах АТ имеется второй байт флагов клавиатуры, находящийся по адресу 40h:18h и отражающий состояние управления клавиш на расширенной (101-клавишной) клавиатуре назначения байтов этого байта.

Второй байт флагов клавиатуры КВ-FLAG1 (40h:18h)

 

 


При нажатии обычной, не управляющей клавиши, программа Int 09h счи-тывает из порта 60h ее скен-код нажатия и по таблице трансляции скен-кодов в коды ASCII формирует двухбайтовый код - в старшем байте - скен-код, в младшем байте - код ASCII. Каждому скен-коду соответствует, как минимум, два кода ASCII. (Т.к. за клавишей закреплено, как минимум, не менее 2-х символов)

а/А 1 и! и т.д.

­­ -- Скен-код одни, а ASCII коды - разные.

В процессе трансляции Int 09h анализирует состояние флагов.

Например, клавиша Q имеет скен-код 10h

код ASCII Q - 51h, а буква q – 71h.

Т.о. если нажата Q, то Int 09h формирует 1071h, но, если Q нажата при нажатой клавише Shift, то будет сформирован двухбайтовый код 1051h. 1051h будет сформирован и при режиме (Caps Lock). Однако, если включен режим (Caps Lock) и нажата клавиша Shift, то будет сформирован код 1071h, т.к. в этом случае (Shift) переводит клавиатуру в режим нижнего регистра (строчные буквы).

Полученный двухбайтовый код засылается в кольцевой буфер ввода, который служит для синхронизации процессов ввода данных с клавиатуры и приема их выполняемой программой. Объем буфера 16 слов, при этом коды символов извлекаются из него в том же порядке, в каком они в него поступали. За состоянием буфера следят 2 указателя. В хвостовом указателе (слово по адресу 40:1Сh)

 

40h:1А BUFFER_HEAD DW?; указатель головного симв.

40h:1С BUFFER_TAIL DW?; указатель хвостового симв.

; HEAD = TAIL - указывает, что буфер пустой

40h:1Eh КВ_BUFFER DW 16 DUP (?);кольцевой буфер

 

хранится адрес первой свободной ячейки, в головных (слово по адресу 40h:1Аh) - адрес самого старого кода, принятого с клавиатуры и еще не введенного программой. Оба адреса представляют собой смещения относительно начала области данных BIOS, т.е. числа от 1Еh до 3Сh. В начале работы, когда буфер пуст, оба указателя и хвостовой, и головной, указывают на первую ячейку буфера.

Программа Int 09h, сформировав двухбайтовый код, помещает его в буфер по адресу, находящемуся в хвостовом указателе, после чего этот адрес увеличивается на 2, указывая опять на первую свободную ячейку, каждое последующее нажатие на клавишу добавляет в буфер очередной двухбайтовый код и смещает хвостовой указатель.

Выполняемая программа, желая получить код нажатой клавиши, должна обратиться либо к файлам ввода с клавиатуры DOS (прерывание Int 21h) или BIOS (прер.Int16h). Системные программы с помощью драйвера консоли считывают из кольцевого буфера содержимое ячейки, адрес которой находится в головном указателе, и увеличивает этот адрес на 2. Т.о. программный запрос на ввод с клавиатуры фактически выполняет прием кода не с клавиатуры, а из кольцевого буфера.

Хвостовой указатель, перемещаясь по буферу в процессе занесения в него кодов, наконец, доходит до конца буфера (адрес 40h:ЗСh). В этом случае при поступлении очередного кода адрес в указателе не увеличивается, а, наоборот, уменьшается на длину буфера. Тем самым указатель возвращается в начало буфера, затем продолжает перемещаться по буферу до его конца, опять возвращается в начало и так далее по кольцу. Аналогичные манипуляции выполняются и с головным указателем.

Равенство адресов в обоих указателях свидетельствует о том, что буфер пуст. Если при этом программа поставила запрос на ввод символа с клавиатуры, то драйвер консоли будет получать поступления кода в буфер, после чего этот код будет передан в программу. Если же хвостовой указатель, перемещаясь по буферу

в процессе его заполнения, подошел к головному указателю и с обратной стороны, прием новых кодов блокируется, а нажатие на клавиши возбуждает звуковые сигналы. Это происходит в том случае, если оператор нажимает на клавиши,

а программа не обращается к клавиатуре.

Если компьютер не выполняет никакой программы, то активной является программа командного процессора COMMAND.СОМ. COMMAND.СОМ поставить запрос к DOS на ввод с клавиатуры, с помощью функции ОАh прерывания 21h, ожидает ввода с клавиатуры очередной команды пользователя. Как только

в кольцевом буфере ввода появляется очередной код символа, функция ОАh переносит его во внутренний буфер DOS, очищая при этом кольцевой буфер ввода, а также выводит символ на экран. При нажатии на "Enter" формируется код 13 (0Dh). Получив код 13 функция 0Ah завершает свою работу, а командный процессор предполагает, что ввод команды закончен, анализирует содержимое буфера DOS и приступает к выполнению введенной команды. При этом командный процессор работает с кодами ASCII.

Если выполняемой программе не нужен ввод с клавиатуры, а оператор нажал какие-то клавиши, то с помощью Int 09h символы будут накапливаться в кольцевом буфере ввода. Так можно ввести до 15 символов. Естественно, они не будут отображены на экране. Когда программа завершится, управление будет передано COMMAND.СОМ, который обнаружит наличие символов в кольцевом буфере, извлечет их оттуда и отобразит на экране. Такой ввод с клавиатуры называют ввод с упереждением.

Рассмотрим, что происходит при нажатии на клавиши, которым не назначены отображаемые на экране символы. Это, например, функциональные клавиши (F1), (F2),... (F12), клавиши управления курсором стрелки, (Home), (End), (PgUp), (PgDn) и др. При нажатии этих клавиш в кольцевой буфер ввода (КБВ) засылается расширенный код ASCII, в котором младший байт = 0, а старший является скен-кодом нажатой клавиши. Расширенный код ASCII поступает в КБВ и в случае нажатия комбинаций управляющих и функциональных клавиш. Например, (Shift)/(F1), (Сtrl)/ (Home) и т.д. В этом случае, в старший байт помещается уже

не скен-код клавиши, а некоторый код, специально назначенный этой комбинации клавиш. Естественно, что такого кода нет среди обычных скен-кодов. Например, клавиша (F1), скен-код, который равен ЗВh, может игнорировать следующие расширенные коды ASCII:

(F1) ЗВ00h

(Alt)/(F1) 6800h

(Ctrl)/(F1) 5Е00h

(Shift)/(F1) 5400h

 

Рассмотрим пример обработчика прерывателя 09h с подключением до системного.

 

; поле данных резидентной секции

old_09h DD?

 

new_09h proc far

push АХ; Сохраним используемый регистр

in AL, 60h; Введем скен-код

сmp AL, 44h; Это скен-код (F10)?

je hotkey; Да

роp АХ; Восстановим АХ

jmp CS:old_09h; В системный обработчик без возврата

 

hotkey:

; Разрешим дальнейшую работу клавиатуры

in AL, 61h; Введем содержимое порта В

or AL, 80h; Установим старший бит

jmp $+2

out 61h, AL; И вернем в порт В

and AL, 7Fh; Снова разрешим работу клавиатуры

out 61h, AL; Сбросив старший бит в порту В

;Пошлем приказ EOI

mov AL, 20h

out 20h, AL

рор АХ

iret

new_09h endp

 

 

Секция инициализации обычная и здесь не проводится при нажатии любой клавиши, а также при ее отпускании процессор передает управление нашему обработчику new_09h. Затем из порта 60h вводится скен-код нажатой клавиши, который сравнивается с 44h - скен-код (F10). Если была нажата другая клавиша, управление передается системному обработчику.

В реальной ситуации управление будет передано русификатору, который заменяет ASCII коды латинских букв на ASCII коды русских букв, если в данный момент был включен режим кириллицы.

Если нажата (F10), переходим на метку hotkey, здесь необходимо на короткое время установить, а потом сбросить старший байт порта В контроллера клавиатуры. Это сообщает контроллеру о приеме скен-кода и разрешает дальнейшую работу клавиатуры. Затем в контроллер прерываний посылается команда Е0I. Обработчик ничего не делает, но не разрешает выгрузить Norton Commander.

Обработчик работает при запрещенных прерываниях. Программа очень коротка и это допустимо и при этом мы не нарушаем работу системного обработчика, который получает управление при запрещенных прерываниях.

Усложним пример. Пусть в качестве горячей клавиши будет (Alt)/(F10). Для того, чтобы обнаружить клавишу (Alt), следует обратиться к слову флагов клавиатуры.

 

 

new_09h proc far

push АХ; Сохраним используемый регистр

in AL, 60h; Введем скен-код

сmp AL, 44h; Это скен-код (F10)?

je gogo; Да

exit1:роp АХ; Восстановим АХ

jmp CS:old_09h; В системный обработчик без возврата

 

gogo: push ES; Сохраним ES

mov AХ, 40h; Настроим ES на начало

mov ES, АХ; Данных BIOS

mov AL, ES: [17h]; Получим слово флагов клавиатуры

рор ES; Восстановим ES – он больше не нужен

сmр AL, 08h; (Alt) уже нажата?

je hotkey; Да

jmp exit1; Нет, в системный обработчик

hotkey:

; Разрешим дальнейшую работу клавиатуры

in AL, 61h; Введем содержимое порта В

or AL, 80h; Установим старший бит

jmp $+2

out 61h, AL; И вернем в порт В

and AL, 7Fh; Снова разрешим работу клавиатуры

out 61h, AL; Сбросив старший бит в порту В

;Пошлем приказ EOI

mov AL, 20h

out 20h, AL

рор АХ

iret

new_09h endp

 

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 328; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.221.141.44 (0.031 с.)