С.А. Мальцев
НЕСТАНДАРТНОЕ ПРИМЕНЕНИЕ КОМАНДЫ RESET
О назначении этой команды уже сообщалось в "ИНФО" [1]. RESET относится к командам управления машиной и осуществляет установку системных регистров БК в исходное состояние. Обычно, в программах на ассемблере RESET применяется для запрещения прерываний от клавиатуры (по векторам &О60 и &О274). Конечно, это можно сделать, установив командой BIS #100,@#177660 шестой разряд регистра состояния клавиатуры (адрес &О177660). Но BIS #100,@#177660 занимает в памяти БК 6 байт, a RESET - 2 байта. Поэтому чаще используют команду RESET.
Однако следует учитывать, что после выполнения команды RESET некоторое время регистр управления внешними устройствами (адрес &О177716) неверно реагирует на состояние клавиатуры: не устанавливается в 0 флаг состояния клавиатуры (разряд 6) при нажатии клавиши, восьмеричный код которой не оканчивается нулем. Для пояснения разберем работу программы из листинга 1 и ее модифицированного варианта из листинга 2. Сразу же после выполнения команды RESET (листинг 1) происходит проверка состояния клавиатуры через тестирование 6 разряда регистра управления внешними устройствами. Если ни одна клавиша на клавиатуре не нажата (6 разряд =1), то снова переходим на запрещение прерывания, а если нажата (6 разряд =0), то выполняется выход (возврат) из программы командой RTS R7. Опыт показывает, что возврат происходит только при нажатии клавиши с восьмеричным кодом, оканчивающимся на 0. Например, ПРОБЕЛ (код &О40), ЗАБОЙ (код &О30) и т.д. Немного изменим программу листинга 1, вставив задержку пустым циклом между проверкой состояния клавиатуры и командой RESET (листинг 2). Теперь возврат происходит при нажатии любой символьной клавиши БК. Следовательно, за время задержки регистр управления внешними устройствами "успевает прийти в себя".
Листинг 1.
A: RESET ;запрет прерывания
BIT #100,@#177716 ;нажата ли клавиша?
BNE А ;если нет, то сначала
RTS PC ;если да, то возврат.
Листинг 2.
A: RESET ; запрет прерывания
MOV #40000,R1 ; задержка
В: SOB R1,B
BIT #100,@#177716 ; нажата ли клавиша?
BNE А ; если нет, то сначала
RTS PC ; если да, то возврат
Однако существует другой, менее известный способ применения RESET. Эту команду можно использовать для распознавания одновременного нажатия 2 — 3 клавиш на клавиатуре БК. Дополним программу из листинга 2 блоком печати символа и зациклим оператором безусловного перехода BR, как в листинге 3. Установив регистр ЛАТ ЗАГЛ, запустим программу на выполнение. После запуска — на экране неподвижный курсор. Программа ожидает нажатия клавиши. Нажмем клавишу J (код &О112). Вследствие зацикленности нашей программы на экране будет печататься строка символов J, пока нажата клавиша. Теперь, не отпуская (!) клавишу J, нажмем клавишу С (код &О103). На экране печатается строчка... букв К (код &О113). Отпустим клавишу J, не отпуская С. Результат -строка букв С. Аналогично во время нажатия символьной клавиши можно переключать регистры СТР и ЗАГЛ, пользоваться регистрами СУ и HP. Однако не все комбинации клавиш можно использовать таким образом. Возможна такая ситуация, когда из двух клавиш одна обладает большим приоритетом, чем другая. Например, при работающей программе листинга 3 нажмем одну клавишу "курсор вверх" (код &О32) — курсор "побежит" вверх. Не отпуская "стрелку вверх", нажмём "стрелку вниз" (код &О33) — курсор перемещается вниз. Отпустим обе клавиши. Теперь нажмем сначала "стрелку вниз", потом (не отпуская первую клавишу) нажмем "стрелку вверх". Курсор будет двигаться вниз даже после нажатия "стрелки вверх". Это означает, что при одновременном нажатии "стрелки вверх" и "стрелки вниз" БК отдает предпочтение "стрелке вниз". Наконец, клавиши с восьмеричными кодами, оканчивающимися на 0, не представляют интереса, так как они не могут быть использованы для определения нажатия двух клавиш предложенным способом.
Листинг 3.
A: RESET ; запрет прерывания
MOV #40000,R1 ; задержка
В: SOB R1,B
BIT #100,<g>#177716 ; нажата ли клавиша?
BNE А ; если нет, то сначала
MOV@#177662,RO ; если да, то печать
ЕМТ 16
BR А ; зацикливание
Причиной столь странного поведения клавиатуры БК-0010.01 является действие команды RESET, вызывающей заполнение регистра данных клавиатуры (адрес &О177662) новым кодом. А этот код может отличаться от кодов нажатых в данный момент клавиш вследствие некорректного (двумя или тремя клавишами) замыкания шин клавиатуры. В обычном (без RESET) режиме заполнение регистра данных происходит только при отпускании нажатой клавиши и нажатия после этого другой.
При использовании в программах данного способа определения нажатия двух клавиш недостатками являются необходимость подбора клавиш (не все комбинации работают нужным образом) и невозможность блокирования клавиш с кодами, равными "комбинационным". Например, используя в программе клавиши J и С (комбинационный код &О113), нельзя запретить БК реагировать на отдельное нажатие одной клавиши К (код К тоже равен &О113). Несмотря на недостатки, возможности предложенного способа велики. Например, комбинируя нажатия трех клавиш J, С и :, на регистре ЛАТ ЗАГЛ можно получить семь различных кодов (J -&0112, С - &0103, : - &072, J+C - &О113, J+: - &О152, С+: -&О143, J+C+; - &О153). Такие комбинации могут быть использованы в динамических играх на БК. Данный эффект может быть применен не только на ассемблере, но и на языках высокого уровня — Бейсике, Фокале. Примером тому служит программа из листинга 4. Она может быть использована для подбора подходящей пары или тройки клавиш. Основа этой программы — подпрограмма в машинных кодах из двух команд RESET и RTS PC, размещенная в стековой памяти БК (строки 30-40 в листинге 4). Определяется подпрограмма стандартно: оператором DEF USR в строке 50. Вызов подпрограммы осуществляется в строке 60. В 90-й строке семиразрядный код с клавиатуры печатается в десятичной, восьмеричной, шестнадцатиричной и двоичной системах счисления. На Фокале для выполнения команды ассемблера RESET есть специальный оператор KILL.
Листинг 4.
10 CLS
20 ?"ИССЛЕДОВАНИЕ ВОЗМОЖНОСТЕЙ КЛАВИАТУРЫ БК. НАЖИМАЙТЕ КЛАВИШИ."
30 POKE &O400,&O5
40 РОКЕ &О402,&О207
50 DEF USR=&O400
60 A=USR(A)
70 IF INP(&O177716,&O100)<>0 THEN 70
80 B=PEEK(&O177662)
90 ?AT(0,5);"DEC:";B,"OCT: ";OCT$(B),"HEX: ";
HEX$(B),"BIN: "; BIN$(B)
100 GOTO 60
Литература
1. Зальцман Ю. Архитектура и Ассемблер БК // "Информатика и образование". — 1991. — №2.
Распознавание и преобразование в гипертекст: Владислав М. Антонов
2004 г.