(С) SKL-KEEPER aka Колесников Сергей
Ведущий раздела "Coding для "чайников"
__________________________________________
Для "чайников". Подробно об одном из
способов опроса клавиатуры.
Для начинающих "кодить" свои программы
неминуемо встает вопрос о том, а как же
организовать опрос клавиату-
ры? Ведь без этого ни одна
программа не обойдется, ка-
кой бы простой она не была!
Есть несколько способов
опроса клавиатуры, например,
с использованием системных
переменных KSTATE и LASTK.
Думаю, что эти способы вряд
ли вызывают затруднения в
понимании, поэтому на них не
стоит останавливаться. А вот
способ опроса клавиатуры,как
внешнего порта, хоть и изло-
жен в ряде компьютерных из-
даний, но изложен как-то не очень доходчи-
во и может быть не очень понятен. Вот на
нем мы и остановимся.
Этот способ, в отличие от вышеупомяну-
тых, можно применить для организации пере-
мещения объекта по экрану одновременно в
двух направлениях, или, например, для кон-
троля нажатия клавиши одновременно с дру-
гой клавишей (курсорные клавиши и т.п.).
Опрос клавиатуры этим способом является
единственно приемлемым в том случае, если
прерывания запрещены. Кстати, это обстоя-
тельство можно использовать для ускорения
работы Вашей программы. Поставьте DI перед
опросом клавиатуры,и процессор не будет 50
раз в секунду вызывать процедуру KEYSCAN.
Хоть и небольшая, но экономия времени!
Только не забудьте после выхода из проце-
дуры включить прерывания командой EI...
Напомню, что опрос клавиатуры этим спо-
собом производится по внешнему порту 254
(#FE HEX). Так как адрес порта клавиатуры
является двухбайтным числом, то #FE явля-
ется младшим байтом адреса порта, а стар-
ший должен быть предварительно установлен
в аккумуляторе.
Анализируются пять младших битов. При
этом, если клавиша нажата, то бит выключен
(наоборот, по сравнению с Кемпстон-джойс-
тиком). При этом способе проверяется сос-
тояние одной из половин ряда клавиатуры.
Рассмотрим рисунок клавиатуры:
N:БИТA│ 0│ 1│ 2│ 3│ 4║ 4│ 3│ 2│ 1│ 0│
──────┼──┼──┼──┼──┼──║──┼──┼──┼──┼──┤ N_
N_ 3 │ 1│ 2│ 3│ 4│ 5║ 6│ 7│ 8│ 9│ 0│4 П
П ├──┼──┼──┼──┼──║──┼──┼──┼──┼──┤ О
О 2 │ Q│ W│ E│ R│ T║ Y│ U│ I│ O│ P│5 Л
Л ├──┼──┼──┼──┼──║──┼──┼──┼──┼──┤ У
У 1 │ A│ S│ D│ F│ G║ H│ J│ K│ L│ENT6 Р
Р ├──┼──┼──┼──┼──║──┼──┼──┼──┼──┤ Я
Я 0 │CS│ Z│ X│ C│ V║ B│ N│ M│SS│SPC7 Д
Д └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘ А
А
3-#F7 4-#EF
2-#FB 5-#DF
1-#FD 6-#BF
0-#FE 7-#7F
Небольшое пояснение к рисунку. Над кла-
виатурой, по горизонтали, я проставил но-
мера битов, которые становятся активными
после нажатия определенной клавиши.По вер-
тикали пронумерованы номера полурядов.
Кстати, полуряды пронумерованы условно.
Теперь, к примеру, если мы нажмем клавишу
"1", значит, будет задействован третий по-
луряд, и активным будет нулевой бит.
А теперь рассмотрим конкретный пример:
нам надо организовать опрос клавиатуры на
нажатие клавиш: "1" и "2". В соответствии
с тем, какая клавиша нажата, будем менять
цвет бордюра (так нагляднее). Итак...
KEY HALT ;Ждем следующее прерывание
XOR A ;обнуляем аккумулятор.
LD A,#F7 ;заносим в аккумулятор
;наш полуряд (третий).
IN A,(#FE);младший бит адреса порта.
BIT 0,A ;определяем состоян. бита,
;соответствующ.клавише "1"
;если бит активен, то флаг
;Z=1, если нет, то Z=0.
JR Z,BLUE ;если Z=1, то операция
;JR Z... будет выполняться
;если Z=0, мы ее "проско-
;чили".
LD A,#F7 ;опять наш полуряд.
IN A,(#FE);опрос клавы.
BIT 1,A ;определяем состояние пер-
;вого бита, который соот-
;ветствует клавише "2".
JR Z,RED ;здесь аналогично предыду-
;щему.
JR KEY ;больше опрашивать ничего
;не надо, "зацикливаемся".
BLUE LD A,1 ;в аккумулят. - цвет синий
OUT (254),A; BORDER 1.
RET
RED LD A,2 ;двойка соответст. красному
OUT (254),A; BORBER 2.
RET
Надеемся, Вам стало все понятно. Обра-
тите внимание на то, что биты правого по-
луряда идут справа налево. Чтоб уж совсем
и навсегда разобраться с этим вопросом,
приведем для примера ту же программу, но
для другого полуряда.Организуем опрос кла-
виш: "9" и "0":
KEY HALT ;ждем следующее прерывание
XOR A ;обнуляем аккумулятор.
LD A,#EF ;заносим в аккумулятор
;наш полуряд (четвертый).
IN A,(#FE);младший бит адреса порта.
BIT 0,A ;определяем состоян. бита,
;соответствующ.клавише "0"
;если бит активен, то флаг
;Z=1, если нет, то Z=0.
JR Z,BLUE ;если Z=1, то операция
;JR Z,BLUE будет выпол-
;няться
LD A,#EF ;опять наш полуряд.
IN A,(#FE);опрос клавы.
BIT 1,A ;определяем состояние пер-
;вого бита, который соот-
;ветствует клавише "9".
JR Z,RED ;здесь аналогично предыду-
;щему.
JR KEY ;"зацикливаемся".
BLUE LD A,1
OUT (254),A
RET
RED LD A,2
OUT (254),A
RET
С этим покончили. А если нам понадо-
бится определить нажатие клавиши совместно
с CAPS SHIFT? Вот программка, где мы дела-
ем опрос нажатия клавиш "6" и "7" совмест-
но с CAPS SHIFT:
KEY HALT ;ожидаем прерывание.
XOR A ;обнулили аккумулятор.
LD A,#FE ;т.к. CAPS SHIFT находится
;в нулевом полуряду.
IN A,(#FE);опрос клавы.
BIT 0,A ;определяем состояние
;нулевого бита.
JR NZ,PROG;если клав. "CSh" не нажа-
;та, мы пойдем к метке
;PROG, где у нас какая-то
;своя программа, если же
;нажата, Z=1 и JR Z,PROG
;мы "проскочим".
LD A,#EF ;здесь берем 4 полуряд.
IN A,(#FE) ;опрос клавы.
BIT 3,A ;третий бит-клавиша "7".
CALL Z,BLUE;если нажата->метка BLUE.
LD A,#EF ;четвертый полуряд.
IN A,(#FE) ;опрос клавы.
BIT 4,A ;четвертый бит - кл."6".
CALL Z,RED ;если нажата ->метка RED.
PROG .......... ;здесь находится Ваша
.......... ;программа, например,
.......... ;опрос других клавиш.
JR KEY ;зацикливаемся.
BLUE LD A,1 ;тут уже все понятно...
OUT (254),A
RET
RED LD A,2
OUT (254),A
RET
Теперь, надеемся, вопросов по этой те-
ме не возникнет.
Следует заметить, что есть еще один
практически такой же способ опроса клавиа-
туры, который отличается от вышеизложенно-
го тем, что спецификация проверяемого ряда
находится в регистровой паре BC, а код на-
жатой клавиши передается в регистр А. То
есть:
LD BC,nnnn
IN A,(C) ;ввод данных из порта
;в аккумулятор.
Здесь nnnn - адрес внешнего порта, ус-
танавливаемого в BC. Надо только помнить,
что в регистре С будет #FE (постоянно), а
в В - значение, соответствующее номеру по-
луряда. Например, для нашей первой прог-
раммки вместо:
LD A,#F7
IN A,(#FE)
следует набрать:
LD BC,#F7FE
IN A,(C)
Еще одна небольшая тонкость.
Проверку бита 0 можно производить не
командой BIT 0,A, а командой RRCA, если
проверяемая клавиша крайняя на клавиатуре,
как, например, клавиши Q,A и P.
Как известно, RRCA означает ROTATE AC-
CUMULATOR RIGHT WITHOUT CARRY (вращать ак-
кумулятор вправо без флага переноса). Флаг
переноса хоть и изменяется с учетом резу-
льтата операции, но во вращении не участ-
вует.
Использование команды RRCA экономит па-
мять, т.к. это однобайтная команда. Когда
мы с ее помощью производим ротацию содер-
жимого аккумулятора вправо, при нажатии
проверяемой клавиши флаг С выключается
(C=0). Таким образом, вместо:
BIT 0,A
JR Z,BLUE
в нашей первой программе можно поставить
конструкцию:
RRCA
JR C,BLUE ;если клавиша не нажата,
;на что указывает установ-
;ленный бит, команда "про-
;скакивается".
А вот кусочек программы, с помощью ко-
торой можно проверить нажатие клавиш O и
P:
........
KEY1 LD A,#DF ;кл. O и P - 5 полуряд
IN A,(#FE)
RRCA ;клавиша P
JR C,LABEL1 ;метка условная.
;т.к. клавиши O и P находятся в одном по-
;луряду, выполнять команду IN дважды нет
;необходимости. Просто еще раз сдвинем би-
;ты аккумулятора вправо.
RRCA ;клавиша О
JR C,LABEL2
......... ;ну, и так далее.
Думаю, на этом можно и закончить.
В заключение хочу поблагодарить Рыль-
ских Андрея (ICB) за помощь в подготовке
статьи.
------------------------------------------
P.S. А нам, в свою очередь, хочется побла-
годарить Колесникова Сергея за его актив-
ную деятельность в плане подготовки статей
для журнала, и поздравить его с назначени-
ем на должность ведущего раздела. Нам дей-
ствительно приятно иметь дело с такими вот
людьми!!!
------------------------------------------