В В О Д И В Ы В О Д
Вопросы ввода и вывода - одни из самых простых в
программировании на машинноми языке. Возникают ситуации,
когда ЦП необходимо получить информацию из внешнего мира,
например, с клавиатуры или кассетного магнитофона. Что
касаетя ЦП, то для него это совершенно чуждый мир, и как
любой добропорядрочный ЦП, он никогда из дома не отлучается.
Самое большее, что он может сделать - это открыть дверь и
получить доставленные вещи. ЦП не знает и не хочет знать, как
работает кассетный магнитофон. Все, что ему нужно знать - это
к какой двери доставит свои товары посыльный от кассетного
магнитофона. У Z80 есть выбор до 256 дверей, но реальное
число, доступное конкретному ЦП, - это результат решений,
принятых производителями аппаратуры. Что касается
"Синклера",имеются только клавиатура,печатающее устройство и
кассетный магнитофон. Еще одно, о чем ЦП не хочет знать, это
как передаются данные. Все, что его касается, это то, что при
вводе и при выводе он получает 8-битовый байт. Клавиатура и
кассетный магнитофон расположены за дверью номер FEH
(десятичное 254), так что для получения данных с клавиатуры
вы применяете команд
IN A,(FE)
Теперь вы можете задать себе вопрос, как 40 клавиш
на клавиатуре организованы так, что они представляются
8-битовыми байтами.
Ответ для вас будет, скорее всего, неожиданным -
клавиатура за один раз передает информацию только от 5
клавиш. Значание регистра A определяет в момент открытия
двери, какая группа из 5 клавиш будет просматриваться.
Клавиатура разделена на 4 ряда, каждый из которых содержит
два блока по 5 клавиш.
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 N/L <= 6
0 => SFT Z X C V B N M . SPC
Легко видеть, что имеется 8 блоков литер и мы,
поэтому, можем увязать их с 8 битами регистра A. Все биты
регистра A устанавливаются в положение "включено" за
исключением одного бита, задающего подлежащий чтению блок. Вы
можете представлять это себе как секретный знак-рукопожатие.
Когда ЦП идет к двери за информацией, рукопожатие определяет,
какую часть информации он получит.
Чтобы прочитать клавиши из блока "1 2 3 4 5", должен
быть выключен бит 3 регистра A:
A = 1 1 1 1 0 1 1 1 = F7
Содержимое посланной с клавиатуры информамции
поступает в регистр A, в его младшие биты:
клавиша "1" -> бит 0 регистра A
клавиша "2" -> бит 1 регистра A
Вы можете считать, что информация поступает в
регистр A сначала с внешних сторон клавиатуры, так что и "0"
и "1" попадут в бит 0 регистра A.
Для некоторых игр вам может понадобиться позволить
считывать весь верхний ряд, причем весь его можно читать
одной командой (а не двумя, как потребовалось бы при чтении
одного блока за раз). Для этого посыльного обманывают, чтобы
он выдал вам сразу две порции информации:
A = 1 1 1 0 0 1 1 1 = E7
Обратите внимание, что оба бита "3" и "4" выключены.
Такое рукопожатие говорит посыльному, что ЦП нужна информация
из блоков 3 и 4, и именно ее он и получит. Конечно, две
порции информации оказываются перемешанными, так что вы не
сможете сказать, была нажата клавиша "0" или "1", например,
обе установят бит 0 регистра A:
"1" или "0" -> бит 0 регистра A
"2" или "9" -> бит 1 регистра A
Это полезно для динамических игр, поскольку
позволяет использовать клавиши "5" и "8" в качестве указателя
направления движения направо и налево, хотя они и находятся в
разных блоках клавиатуры.
Обратите внимание, что если вы применяете команду
IN R,(C),
где регистр C задает используемую вами дверь, то содержимое
регистра B определяет, какой блок клавиатуры выбирается.
Другие двери, представляющие для вас интерес, - двери
ввода-вывода с кассетного магнитофона. Это дверь FE, как
сказано выше. Основная возникающая проблема связана с
синхронизацией ввода и вывода данных. Проблемы такого типа
требуют большого опыта программирования на машинном языке и
вычисления времени выполнения каждой команды.
Команда OUT также применяется для генерирования
звукового сигнала на "Спектрум" и установления цвета
окаймления. На странице руководства "Спектрум"
рассматривается команда OUT в языке "Бейсик", а
программирование команды на машинном языке в точности такое
же. Иными словами, биты 0, 1 и 2 определяют цвет окаймления,
бит 3 посылает импульс на гнезда MIC и EAR, а бит 4 посылает
импульс на внутренний громкоговоритель. Чтобы изменить цвет
окаймления, нужно загрузить в регистр A соответствующее
значение цвета, а затем выполнить команду OUT (FE),A.
Обратите внимание, что это лишь TEMPORARY (временное)
изменение цвета окаймления. Чтобы постоянно изменить цвет
окаймления, вы должны выполнить приведенную выше команду OUT
и так же изменить значение ячейки памяти 23624,
представляющую собой переменную BORDCR операционной системы.
Причина этого состоит в том, что аппаратура
"Спектрум" (чип ULA "Спектрум") управляет цветом окаймления и
она получает информацию о нем, просматривая содержимое этой
ячейки памяти. Вы можете предотвратить всю эту волынку ЦП с
цветом окаймления только заблокировав все прерывания (команда
DI). Обратите внимание, что некоторые подпрограммы в ПЗУ
разблокируют прерывания (команда EI).
САМОСТОЯТЕЛЬНАЯ ГЕНЕРАЦИЯ ЗВУКОВОГО СИГНАЛА
Вы можете сгенерировать свой собственный звуковой
сигнал на "Спектрум", но для пользователей, имеющих только
16К памяти с произвольным доступом имеются определенные
ограничения, порождаемые особенностями аппаратуры.
Поскольку экран постоянно обновляется, аппаратура
регулярно прерывает выполнение заданий Z80 для того, чтобы
показать, что находится в файле дисплея. Это выполняется
путем снижения напряжения в схеме WAIT. В результате
оказывается невозможным создание какой бы то ни было
программы, требующей точной или регулярной синхронизации,
поскольку невозможно предсказать результаты синхронизации с
помощью этих прерываний WAIT. Конструкция "Спектрум" такова,
что прерывание Z80 осуществляется при попытке обработки
информации, содержащейся в первых 16К памяти с произвольным
доступом. Такого прерывания не происходит, если программа и
данные, к которым осуществляется доступ Z80, находятся в ПЗУ
или верхних 32К памяти.
Обобщить все это в терминах, понятных непосвященным,
можно следующим образом: вы можете воспроизводить звуки и
шумы с помощью команды OUT на ЭВМ с 16К памяти, но это не
будут чистые ноты. Обойти это можно с помощью программы BEEP
из ПЗУ.(см. главу о средствах "Спектрум"). Для генерации
звука вы должны послать импульс для включения
громкоговорителя (или/и на гнездо MIC, если его нужно
усиливать). Затем, спустя некоторое время, вам нужно послать
другой импульс для его выключения. Затем, спустя еще
некоторое время, вновь включить и т.д.....
Таким образом создается звук. Интервал времени между
двумя последовательными включениями громкоговорителя
определяет чистоту звука, продолжительность интервала
времени, в течение которого громкоговоритель остается
включенным, в противоположность интервалу времени между
импульсами, может дать вам минимальную степень контроля
громкости звука.
Обратите внимание, что вы должны применять для
включения и выключения такое значение A, чтобы цвет
окаймления не изменялся. В противном случае частотная
характеристика полученного звука будет напоминать звуки
загрузки.
УПРАЖНЕНИЕ
Напишите программу, имитирующую звук сирены скорой
помощи (частота возрастает, а затем снижается), Обратите
внимание, что вы должны обеспечить звучание каждой частоты в
течение некоторого короткого интервала времени, прежде чем
перейти к следующей частоте.
ПРЕДСТАВЛЕНИЕ ДВОИЧНО-КОДИРОВАННЫХ ДЕСЯТИЧНЫХ ЧИСЕЛ
Двоично-кодированное представление по английски
сокращается как BCD (BINARY-CODED DECIMAL). Это один из
способов представления информации в десятичной форме.
Чтобы закодировать каждую из цифр от 0 до 9
необходимо всего 4 бита. В каждом байте можно закодировать
две цифры. Это называется двоично-кодированным десятичным
представлением.
Например:
0000 0000 - двоично-кодированное десятичное пред- ставление
десятичного числа 00.
1001 1001 - двоично-кодированное десятичное пред- ставление
десятичного числа 99.
Каково будет двоично-кодированное представление
чисел 58,10? Будет ли 1010 0000 допустимым
двоично-кодированным десятичным представлением числа?
АРИФМЕТИЧЕСКИЕ ДЕЙСТВИЯ НАД ДВОИЧНО-КОДИРОВАННЫМИ
ДЕСЯТИЧНЫМИ ЧИСЛАМИ
Эта странная система обозначений для представления
чисел может повести к потенциальным проблемам при сложении и
вычитании. Попробуем сложить следующие числа:
BCD 08 0000 1000
BCD 03 0000 0011
----------------------
BCD 11 0000 1011
Вы заметите, что результат второй операции неверен и
является недопустимым в представлении двоично-кодированного
десятичного числа. Для компенсации этих трудностей необходимо
применять особую команду DAA, называемую "десятичная
настройка арифметических действий", чтобы исправить результат
сложения (т.е. добавлять 6, если результат превышает 9).
Следующую трудность иллюстрирует тот же пример.
Будет генерироваться бит переноса из младшего разряда
двоично-кодирован- ного десятичного числа (самого первого) в
самый левый. Этот внутренний перенос должен быть учтен и
добавлен во второй разряд двоично-кодированного десятичного.
Для выявления этого переноса используется флаг
половинного переноса H.
LD A,12H : LOAD LITERAL BCD "12"
ADD A,24H : ADD LITERAL BCD "24"
DAA : DECIMAL ADJUST RESULT
LD (ADDR),A : STORE RESULT
LOAD LITERAL - загрузить литерал;
ADD LITERAL - добавить литерал;
DECIMAL ADJUST RESULT - десятичная настройка результата;
STORE RESULT - запоминание результата.
При программировании вам вряд ли потребуется
двоично-кодированное десятичное представление. Но неплохо
знать, что чип Z80 все-таки поддерживает это представление и
команда DAA облегчает жизнь небольшой группе пользователей
двоично-кодированного деся- тичного представления.
ПРЕРЫВАНИЯ
Прерывание - это посылаемый микропроцессору сигнал,
который может появиться в любое время и приостановить
выполнение текущей программы (программа даже не узнает об
этом).
Z80 предоставляет три механизма осуществления
прерываний: запрос шины (BUSRG), немаскируемое прерывание
(NMI) и обычное прерывание (INT).
Команда DI (блокировка прерывания) применяется для
сброса (маскирования), а команда EI (разблокирование
прерывания) - для установки (размаскирования).
В общем случае обычное прерывание приведет к тому,
что текущий счетчик команд будет помещен в стек, а управление
с помощью команды RST будет передано на нулевую страницу ПЗУ.
Для возвращения из прерывания требуется команда RETI (возврат
из прерывания).
При нормальном режиме работы у "Спектрум" прерывания
разблокированы (EI), и на самом деле программа прерывается 50
раз в секунду. Это прерывание позволяет программе ПЗУ
осуществлять сканирование клавиатуры.
Вам может понадобиться заблокировать прерывания в
вашей программе, поскольку это ускоряет выполнение. Вы
все-таки сможете получать информацию с клавиатуры при условии
использования своей собственной программы для этого.
Обязательно разблокируйте прерывания, когда закончите
выполнение программы, поскольку иначе система не сможет
получать информацию с клавиатуры.
КОМАНДА РЕСТАРТА (RST)
Это скорее всего "рудименты" чипа 8080,
реализованные в целях совместимости. Поэтому вы вряд ли
станете применять команду RST в своей программе. Команда RST
выполняет те же самые действия, что и вызов, но позволяет
совершать переход только по восьми адресам, расположенным в
первых 256 ячейках памяти: 00H, 08H, 10H, 18H, 20H,
28H,30H,38H.
Преимущество команды RST состоит в том, что часто
используемые подпрограммы можно вызвать, затрачивая на это
всего один байт. Кроме того, команда RST занимает меньше
времени, чем команда CALL.
Недостатком команды RST является то, что ее можно
применять только для обращения к одной из восьми приведенных
выше допустимых ячеек. Поскольку все эти ячейки расположены в
ПЗУ, вы можете воспользоваться этим преимуществом в своей
собственной программе. Есть, однако, возможность использовать
подпрограммы ПЗУ, если вы знаете, что они делают и, тем
самым, использовать команды RST.
Вы сможете больше узнать о командах RST из нашей
книги "UNDERSTANDING YOUR SPECTRUM", написанной доктором Яном
Логаном.