Из журнала Deja Vu #09, Кемерово, 1999 (С) 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|ENT 6 Р Р +--+--+--+--+--+--+--+--+--+--+ Я Я 0 |CS| Z| X| C| V| B| N| M|SS|SPC 7 Д Д +--+--+--+--+--+--+--+--+--+--+ А А 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. А нам, в свою очередь, хочется побла- годарить Колесникова Сергея за его актив- ную деятельность в плане подготовки статей для журнала, и поздравить его с назначени- ем на должность ведущего раздела. Нам дей- ствительно приятно иметь дело с такими вот людьми!!! ------------------------------------------