ZX-Ревю 1991 №2 1990 г.

Секреты ПЗУ - продолжение.


2. Обслуживание клавиатуры.

Все процедуры, которые входят в этот раздел, служат для того, чтобы установить факт нажатия клавиши (или двух, если одна из них SHIFT) и после преобразований выдать код символа (токена или код управления), соответствующий данной клавише, в зависимости от того, в каком режиме эта клавиша была нажата (K,L,C^).

Прежде, чем подробно рассматривать входящие сюда процедуры, кратко обрисуем логику их работы.

1. Сначала выполняется сканирование клавиатуры по 8-ми полурядам [1, стр. 90], а внутри каждого полуряда - по 5-ти столбцам (от внешней клавиши к внутренней). Сканируются 40 основных клавиш. Определяются порядковые номера нажатых клавиш (от 0 до 27H).

2. Клавиша считается нажатой только если продолжительность ее удержания составила не менее 5-ти циклов прерываний, а поскольку в течение этих 5-ти циклов могла быть нажата и другая клавиша, то организуются две группы системных переменных. В первой группе ведется счет 5-ти циклов, а во второй "ловится" следующая клавиша. Далее наоборот.

3. По порядковому номеру клавиши из таблицы 0205-022B определяется "главный код" нажатой клавиши. Это как бы код символа (буквы или цифры), написанного на этой клавише. Причем он соответствует заглавной букве (с CAPS SHIFT). Тот факт, что клавиша могла быть нажата без CAPS SHIFT или с SYMBOL SHIFT или в режиме "Е", здесь пока не учитывается.

4. В зависимости от того, в каком режиме находилась клавиатура, по "главному коду" из таблиц 0205-028D определяется "окончательный код" клавиши, который уже представляет код символа (буквы или цифры), код токена ключевого слова или управляющий код (код управления курсором, код управления цветом, позицией печати и т.п.). Коды "Спектрума" см. [3].

По тексту статьи многократно встречаются ссылки на различные системные переменные. Их список и назначение можно найти в [3].

028Е-02ВЕ - Подпрограмма сканирования клавиатуры.

В результате работы этой подпрограммы регистр Е возвращает значение от 0 до 27H, которое указывает на то, какая клавиша из 40 основных была нажата. Если никакая, то FFH.

Регистр D возвращает значение, которое указывает на то, какая SHIFT-клавиша была при этом нажата. Если никакая, то FFH. Если одновременно были нажаты обе SHIFT-клавиши, то D содержит значение для CAPS-SHIFT, а Е - для SYMBOL-SHIFT. Если никакие клавиши не нажаты, то DE возвращает FFFFH.

Если по ошибке нажаты три клавиши, или если нажаты две клавиши ни одна из которых не SHIFT, то флаг нуля (Z-флаг регистра F) выключается.

Клавиатура условно разбивается на 8 рядов по 5 клавиш в каждом ряду.

Сначала клавишам присваивается значение 2F, а затем, сканируя по рядам, а внутри каждого ряда по столбцам, из этого числа вычитается по 8 за каждый столбец и по 1 за каждый ряд, тем самым на выходе для любой нажатой клавиши регистр Е будет содержать соответствующий ей номер от 0 до 27H. В регистре D будет 28, если одновременно нажат CAPS SHIFT или 19, если нажат SYMBOL SHIFT.

Эта подпрограмма включает в себя следующие процедуры:

028E-0295 - KEY-SCAN

Выполняет начальные установки HL,DE,BC.

0296-029E - KEY-LINE

Чтение данных с порта клавиатуры (FE, см. [1, стр. 89]), определение столбца нажатой

клавиши.

029F - 02A0 - KEY-3KEYS

Выход, если нажаты сразу три клавиши.

02А1-02АА - KEY-BITS

Вычисление номера нажатой клавиши по ряду и столбцу.

02АВ-02ВЕ - KEY-DONE

Возврат к 028Е, если не все ряды просканированы. Выход с установлением номера нажатой второй клавиши, если все.

02BF-030F - подпрограмма обслуживания клавиатуры.

Эта подпрограмма вызывается всякий раз, когда происходит маскируемое прерывание, т.е. нормально - каждые 20 мкс. определяет, какая клавиша была нажата и вводит ее окончательный код в системную переменнур LAST-K, при этом включает бит 5 системной переменной FLAGS, что указывает на факт нажатия новой клавиши.

02BF-02C5 - KEYBOARD

Это точка входа. Отсюда вызывается KEY-SCAN, т.е. подпрограмма сканирования клавиатуры.

02C6-02D0 - K-ST LOOP

Проверка первой группы системных переменных KSTATE0...KSTATE3. Если она свободна, то переход на 02D1, а если занята, то счетчик 5-ти циклов уменьшается на 1.

02D1-02F0 - K-CH-SET

Здесь выполняется обработка системных переменных KSTATE0...KSTATE7.

Интересной особенностью является то, что они разделены на две группы -KSTATE0...KSTATE3 и KSTATE4...KSTATE7. Использование двух групп позволяет производить определение нажатой клавиши в одной группе, в то время как другая группа определяет удержание предыдущей клавиши. Группа освобождается для приема новой клавиши только если клавиша была нажата в течение не менее чем 5-ти циклов опроса клавиатуры, т.е. в течение не менее 1/10 доли секунды.

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

02F1-0307 - K-NEW

Отсюда начинается обработка новой нажатой клавиши. Сначала инициализируются системные переменные KSTATE0...KSTATE3 (или KSTATE4...KSTATE5, в зависимости от того, какая группа свободна к приему).

В KSTATE0 (KSTATE4) поступает "главный" код нажатой клавиши.

В KSTATE1 (KSTATE5) устанавливается число 5 (для счетчика пяти повторений).

В KSTATE2 (KSTATE6) вводится значение системной переменной REPDEL (нормально 0.7 сек.).

В KSTATE3 (KSTATE7) после декодирования засылается "окончательный" код нажатой клавиши, зависящий от того, в каком регистре находилась клавиатура в момент нажатия. Декодирование выполняется вызовом процедуры K-DECODE по адресу 0333.

0308-030F - K-END

Финишные операции. В системную переменную LAST-K засылается код символа (токена), соответствующего нажатой клавише. Включается бит 5 системной переменной FLAGS как сигнал о том, что новый код принят.

0310-031D K-REPEAT

Вспомогательная процедура, вызывается более мощной K-CH-SET (02D1).

Процедура обрабатывает длительно нажатую клавишу. Если клавиша нажата более 0.7 сек. в первый раз (установлено системной переменной SEPDEL), то ее действие повторяется. В последующем ее действие повторяется, если она остается нажатой более 0.1 сек. (установлено системной переменной REPPER).

031Е-032В - K-TEST

Вспомогательная процедура. Вызывается более мощной K-CH-SET (02D1). Служит для анализа результатов работы KEY-SCAN и выяснения по состоянию регистров D и Е, была ли вообще нажата какая-либо клавиша, и если да, то с SHIFT или нет.

На выходе из нее регистр D обнулен, а информация о SHIFT-клавише, хранившаяся в нем, сохраняется теперь в регистре B.

032C-0332 - K-MAIN

Используя данные, содержащиеся в DE по результатам работы KEY-SCAN (0201) эта процедура отыскивает в таблицах клавиатуры (0205-028B) код символа (токена), соответствующий нажатой клавише.

Подпрограмма декодирования клавиатуры.

При входе в эту подпрограмму в регистре Е содержится "главный" код нажатой клавиши, значение переменной FLAGS - в регистре D, значение MODE - в регистре C, а информация о нажатой SHIFT-клавише - в регистре В.

0333-0340 - K-DECODE

Распределяет обработку по процедурам, в зависимости от того, цифровая или буквенная клавиша была нажата и от состояния режима клавиатуры (MODE).

Если была нажата цифровая клавиша, то далее следует переход к процедуре K-DIGIT (0367).

Если клавиша буквенная, то в режиме "Е" переход к процедуре K-E-LET (0341), а в режимах "К", "L", "С" - к процедуре K-KLC-LET(034F).

0341-0349 - K-E-LET

Если клавиатура находилась в режиме "Е", то для поиска "окончательного кода" устанавливается базовый адрес таблицы 022С-0245, если никакая SHIFT-клавиша не была нажата, в противном случае поиск производится по таблице 0246-025F. После установки базового адреса для поиска в таблице вызывается процедура

K-LOOK-UP (034A).

034А-034Е - K-LOOK-UP

По установленному базовому адресу (в регистре HL) и "главному" коду (в регистре DE) производит выборку из таблиц клавиатуры 022C-0245; 0246-025F; 0260-0269; 026А-0283; 0284-028D "окончательного" кода.

034F-0363 - K-KLC-LET

Выполняет поиск окончательного кода по главному коду для режимов клавиатуры "К", "L", "С".

Если клавиатура находилась в режиме "К", вызывается подпрограмма K-TOKENS (0364), где к "главному" коду прибавляется число А5Н (десятиричное 165).

В режиме "L" сначала решается вопрос о том, была задействована при этом клавиша SYMBOL SHIFT или нет. Если да, то в HL вводится базовый адрес таблицы 026А-0263 и вызывается K-LOOK-UP. Если нет, то к главному коду добавляется 20Н (десятиричное 32) -этот случай соответствует вводу строчной буквы.

0364-0366 - K-TOKENS

Определяет "окончательный" код для токенов, который отличается от "главного" на А5Н (десятиричное 165).

Пример:

Буква A - код 65 десятиричный.

Токен NEW - 230;

Буква J - код 74,

Токен LOAD - 239, 0367-0381 K-DIGIT

Здесь рассматривается случай нажатия цифровой клавиши, а также клавиш ENTER (0DH), SPACE (20H) и обеих клавиш SHIFT (0ЕН). В последних трех случаях выполняется возврат, а для цифровой клавиши происходит следующее:

Если она нажата в режимах "К", "L", "С" - переход на процедуру K-KLC-DGT (039D).

Если в режиме "G" - переход в K-GRA-DGT (0389).

Если в режиме "Е", то проверяется клавиша SYMBOL SHIFT. Если она нажата, т.е. вводится токен, то вводится базовый адрес таблицы 0284-028D и выполняется переход на K-LOOK-UP (034A) для вычисления "окончательного" кода. Если же SYMBOL SHIFT не нажата, то для клавиш 0...7 это означает ввод цветового кода PAPER или INK в зависимости от состояния CAPS SHIFT. Особый случай здесь представляют клавиши 8 и 9, которые в режиме "Е" задают цветовые атрибуты BRIGHT и FLASH, что и анализируется в следующей процедуре K-8-&-9.

0382-0388 - К-8-&-9. 0389-039С - K-GRA-DGT.

Здесь устанавливаются коды символов блочной графики (символы с 80H по 8FH), а также коды перехода в графический режим GRAPHICS (0FH), и код DELETE (0CH). 039D-03B1 - K-KLC-DGT.

Выдает "окончательный" код цифрового символа, записанного на клавише, но для символа "@" выполняет переход на 03В2. 03В2-03В4 - K-@-CHAR. Выдает "окончательный" код символа @.

3. Управление звуковым динамиком

Динамик управляется состоянием 4-го бита в команде OUT, использующей порт 254 (FE HEX).

Рассмотрим ноту "ДО" первой октавы, которая имеет частоту 261,63 Гц. Чтобы динамик воспроизвел эту ноту, данный бит должен поочередно включаться и выключаться каждую 1/523.26 долю секунды.

В стандартном "Спектруме" применен кварц с частотой 3,5МГц и для получения ноты "ДО" необходимо, чтобы команда OUT выдавалась процессором после каждых 6689 тактов. Задержку для этого выполняет замедляющий цикл, организованный в подпрограмме BEEPER.

Подпрограмма BEEPER

При входе в эту подпрограмму пара DE должна содержать произведение частоты звукового сигнала на время его звучания (в секундах): f х t

Пара HL, в свою очередь, должна содержать рассчитанную продолжительность замедляющего цикла, измеренную в тактах, деленных на четыре, минус число 30.125 которое компенсирует естественную задержку, возникающую при исполнении машинокодовых команд. Пример:

для воспроизведения ноты "ДО" в течение 1 секунды.

f = 261.63 Гц; t = 1 сек,

INT (f*t) = 261 = 0105 HEX

в регистре DE - 0105.

6689/4 -30,125 = 1642 = 066А HEX.

В регистре HL - 066А.

Подпрограмма BEEPER содержит следующие процедуры. 03B5-03D0 - BEEPER.

Выполняет исходные установки и начинает отсчет 16-х долей потребного количества тактов процессора (вместо 4-х долей). Возникающий при этом остаток от 0 до 3 компенсируется последующим переходом в соответствующую точку от 03D1 до 03D4. 03D1- BE-IX+3 здесь происходит 03D2- BE-IX+2 компенсация 03D3- BE-IX+1 возникшего 03D4- BE-IX+0 остатка. 03D6-03F1 - BE-H&L-LF,

Здесь организуется первый полуцикл колебания динамика. 03F2-03F5 - BE-AGAIN. Организация второго полуцикла.

03F6-03F7 - BE-END.

Завершение подпрограммы.

Подпрограмма ВЕЕР (03F8-046B)

Эта подпрограмма составлена частично в машинном коде, а частично в коде калькулятора. Служит для выдачи звукового сигнала заданной высоты и заданной продолжительности из интерпретатора БЕЙСИКа.

Математическими расчетами здесь занимаются процедуры, записанные в кодах калькулятора, а необходимыми проверками - машинокодовые процедуры. Точка входа -03F8. После исполнения всех необходимых расчетов, подпрограмма ВЕЕР использует для выдачи звука подпрограмму BEEPER как процедуру низшего уровня.

При входе в подпрограмму на стеке калькулятора должна находиться высота ноты, а под ней число, представляющее длительность звучания. Оба числа должны быть записаны в интегральной упакованной форме, иначе будет вызвана процедура 046С для выдачи сообщения об ошибке. Подробнее о работе калькулятора, об операциях со стеком и об интегральной и интегральной упакованной формах записи чисел с плавающей точкой см. в наших разработках [1,2,3].

046C-046D - REPORT-B.

Процедура выдает сообщение об ошибке "INTEGER OUT OF RANGE", если числа на вершине стека калькулятора заданы неверно. Обработка ошибки выполняется вызовом RST 0008 с подачей кода-перехватчика (Иоок-кода)0А.

046Е-04А9 - SEMI-TONE TABLE.

Здесь в этой таблице записаны в интегральной (пятибайтной) форме рассчитанные значения частот для 12-ти основных музыкальных полутонов первой октавы (ДО, ДО-диез....СИ).

04АА-04С1 - "PROGRAM NAME".

Эта процедура не имеет отношения к "Спектруму". Она осталась в ПЗУ как наследство от его предшественника компьютера ZX-81 и не была удалена своевременно при разработке ПЗУ.

* * *

Продолжение следует.

В следующем выпуске мы начнем рассмотрение процедур, обслуживающих ввод/вывод с кассетного магнитофона.

Литература

[1]. Первые шаги в машинном коде Z-80.

[2]. Практикум по программированию в машинных кодах Z-80.

[3]. Справочник по программированию в машинных кодах Z-80.

[4]. Большие возможности Вашего "Спектрума".




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
ZX in the world - Спешу сообщить, что моя BBS в скором времени перейдет на нормальный серверный режим.
От авторов - Вот пролетела еще одна неделя.
От авторов - O содержании журнала.
Лоцман - Мамонтовая пещера - история возниконовения жанра ADVENTURE.
Сплошные приколы - Как избавить вашу квартиру от мышей.

В этот день...   23 ноября