Глава 7.
К А Н А Л Ы
И П О Т О К И
Перемещение информации между программой
и периферийными устройствами управляется с
помощью каналов и потоков. Желательно
представлять канал, как физическое уст-
ройство, получающее информацию (телевизор,
принтер), или выдающая ее (клавиатура), а
поток как дорожку, по которой данные долж-
ны перемещаться к каналу или от него.
В ZX-SPECTRUM без ZX-ИНТЕРФЕЙСА-1 раз-
личаются 4 канала. Они обозначаются еди-
ничными литерами:
S - выходной канал, данные пересылаемые
к этому каналу, высвечиваются в верхней
части экрана;
K - канал ввода/вывода, обслуживает
клавиатуры и нижнюю часть экрана;
P - выходной канал, данные посылаются
на принтер;
R - выходной канал, используемый только
редактором для ввода в буфер редактора
данных, считанных с клавиатуры.
Данные в каналы пересылаются подключе-
нием к ним потоков. Их мы имеем в распоря-
жении 16 (0... 15). После инициализации
системы следует подключение потоков 0 и 1
к каналу K, потока 2 к S, потока 34 к P.
Канал R недоступен из ZX-Бейсика.
Инструкции Бейсика PRINT, LPRINT,
INPUT, LIST, LLIST делают возможным доступ
ко всем этим каналам, полностью скрывая их
существование. В действительности необхо-
димы только 2 из них INPUT и LIST, а также
существующая система каналов и потоков.
Каждая из этих инструкций может быть ис-
пользована для пересылки информации любым
потоком. Для этой цели необходимо лишь
символом #K сигнализировать каким каналом
мы хотели бы воспользоваться.
Инструкция LLIST равнозначна LIST #3,
LIST это то же самое, что LLIST #2. Можно
также писать LIST #0 или LLIST #0, направ-
ляя печать в нижнюю часть экрана, но это
не очень практично, так как система не
позволяет выводить туда более 22-х экран-
ных операторов и часто сама очищает эту
область. Также и команда:
PRINT #1; "ЭТА НИЖНЯЯ ЧАСТЬ ЭКРАНА"
вызовет печать текста в нижней части
экрана, также как INPUT, зато
PRINT #3; "О! У ТЕБЯ ДАЖЕ ЕСТЬ ПРИН-
ТЕР"
перешлет данный текст на принтер. Сам
PRINT равнозначен PRINT #2. Иногда может
быть выгодно использование
INPUT #2;" СООБЩИ СВОЕ ИМЯ"; #0; A$,
что вызовет вывод директивы не в нижней
части экрана, а в верхней. #0 перед A$
необходим, так как канал S является только
выходным каналом и из него нельзя читать.
В распоряжении пользователя остаются
потоки с номерами от 4 до 15. Перед их ис-
пользованием необходимо соответствующие
потоки подключить к каналам, которые долж-
ны их обслуживать. Для этого служит инст-
рукция OPEN #K;" L", где #K является выра-
жением, дающем в результате число между 4
и 15, а L - алфавитно-цифровым выражением,
дающим в результате 1 литеру, идентифици-
рующую канал (в "голом" SPECTRUM должны
быть K, S или P). Например, после команды
OPEN #6;" P" инструкция LIST #6 будет
действовать как LLIST. Также и PRINT #6
может быть использован вместо LPRINT.
После использования данного потока пе-
ред подключением его к другому каналу обя-
зательно его отключение. Для этого служит
команда CLOSE #K. Хорошее правило рекомен-
дует закрывать каналы (отключать от них
потоки ) сразу же после их использования.
Это может быть важно для периферийных уст-
ройств (позволит им, к примеру, выключать
контролируемые ими устройства). Потоки от
0 до 3 автоматически подключаются к своим
каналам и их закрытие нецелесообразно, т.
к. система подключит их опять. Попытки
подключения их к другим каналам могут
иметь неопределенные последствия, включая
крах системы. Также нельзя закрывать пото-
ки, которые не подключены ни к какому ка-
налу (см. главу "Ошибки системы").
"Голый" ZX-SPECTRUM не дает возможности
оценить достоинства такой системы переме-
щения информации (особенно когда не возни-
кает необходимость совместной работы с
уровня ZX-Бейсика с нетиповыми периферий-
ными устройствами). Выявляются они только
после подключения ZX-ИНТЕРФЕЙСА-1, при ра-
боте с микродрайвом или в компьютерной се-
ти.
Важнейшей пользой, приносимой системой
каналов и потоков является ее большая гиб-
кость, определяемая легкость управления
новыми каналами. На практике это позволяет
значительно упростить конструкции интер-
фейсов путем размещения в памяти компьюте-
ра необходимых программ, обслуживающих
данные устройства (что также снижает рас-
ходы). Включение собственных каналов в
систему Бейсика требует тогда только 2 ,
обычно очень простых и коротких дополни-
тельных процедур в машинном коде. Правда
теоретически для этой цели могло бы хва-
тить инструкций IN и OUT, но в случае уст-
ройств, требующих подачи сигналов от нес-
кольких микросекунд до нескольких десятков
микросекунд, это так и останется теорией.
Для пользователей данного устройства
немаловажным является также удобство напи-
сания программ. Значительно проще исполь-
зовать PRINT #K или INPUT #K, чем каждый
раз дописывать в ZX-Бейсик процедуры, го-
товящие данные, а затем высылающие их по
одному знаку.
Перед тем, как будут объяснены способы
организации собственных каналов, мы должны
знать как SPECTRUM хранит необходимую ин-
формацию о них и о потоках, а также как он
ими пользуется.
В области памяти начинающейся с адреса,
хранимой системой переменной CHANS (#5C4F
(23631)) до PROG-1 размещены базовые дан-
ные о каналах. Они имеют стандартный фор-
мат. Описание каждого канала занимает 5
байт и имеет форму:
____________________________________
| | | |
| АДРЕС | РАЗМЕР | ЗНАЧЕНИЕ |
|-------|---------|------------------|
| X | 2 байта | Адрес выводной |
| | | процедуры канала |
| X + 2 | 2 байта | Адрес выводной |
| | | процедуры канала |
| X + 4 | 1 байт | Код литеры канала|
|_______|_________|__________________|
Процедура вывода будет вызываться с ко-
дом очередного символа в регистре A. Про-
цедура ввода, чтобы беспрепятственно взаи-
модействовать с ZX-Бейсиком, должна пос-
тавлять коды очередных знаков, распозна-
ваемых системой и сигнализировать доступ-
ность данных установкой указателя C. От-
сутствие входных данных должно сигнализи-
роваться обнулением указателя C (CARRY-пе-
ренос) и Z (ZERO-ноль).
Часто случается, что данное устройство
является односторонним. Тогда как адрес
процедуры обработки некорректной операции
выдает положение (обычно в ROM) процеду-
ры:
RST 0008
DEFB КОД
код соответствующего сообщения об ошиб-
ке (содержимое ячейки, следующей за RST 8)
выбирается как параметр.
После инициализации системы область ин-
формации о каналах занимает 20 байт+1,
содержащий указатель конца области
(#80(128)). Они содержат:
________________________________________
| | |
| АДРЕС | |
|----------|-----------------------------
| CHANS | Адрес процедуры, пишущей в |
| | нижней части экрана |
| +2 | Адрес процедуры, считывающей|
| | данные с клавиатуры |
| +4 | "K" идентификатор канала |
|----------|-----------------------------|
| +5 | Адрес процедуры, пишущей в |
| | верхней части экрана |
| +7 | Адрес процедуры, сигнализи- |
| | рующей ошибку |
| +9 | "S" идентификатор канала |
|----------|-----------------------------|
| +10 | Адрес процедуры, вводящей |
| | считанные данные в буфер |
| | редактора |
| +12 | Адрес процедуры, сигнализи- |
| | рующей ошибку |
| +14 | "R" идентификатор канала |
|----------|-----------------------------|
| +15 | Адрес процедуры, обслужива- |
| | ющей принтер |
| +17 | Адрес процедуры, сигнализи- |
| | рующей ошибку |
| +19 | "P" идентификатор канала |
|----------|-----------------------------|
| +20 | #80 (128) указатель конца |
| | области |
|----------|-----------------------------|
| +21 | Начало области PROG |
|__________|_____________________________|
Как видно в этой области нет места для
размещения данных о новых каналах. Из су-
ществующих для модификации подойти может
лишь P, так как остальные автоматически
открываются системой. Это не является наи-
лучшим способом, т. к. позволяет опреде-
лить только один дополнительный канал, а
также делает невозможным одновременное
использование принтера. Выгоднее сдвинуть
весь блок PROG-1 до STEND на соответствую-
щее число байт вместе с модификацией сис-
темных переменных.
Проще всего это делается системной про-
цедурой MAKE_ROM. Менее элегантно, но
столь же действенно, размещение информации
о новых каналах где-нибудь в области сис-
темных переменных на 38 байтах, начиная с
SIRMS #5C10 (23568). Для каждого потока
предназначается 2 байта. Адрес 5 байт,
описывающих данный канал, имеет вид
CHANS+X-1, где X содержимое 2 байт, свя-
занных с данным потоком. Описание потока с
номером K размещается с адреса
SIRMS+6+2+K.
В момент подключения потока к каналу
этим ячейкам присваиваются соответствующие
значения. Сколько раз в программе появится
инструкция INPUT #K или PRINT #K, столько
раз на основе данных из таблицы, STRMS
назначается адрес соответствующей процеду-
ры и помещается в системной переменной
CURCHL 5C51 (23633). Далее, в случае пишу-
щей инструкции, очередные символы загру-
жаются в накопитель и вызывается эта про-
цедура. В случае чтения из накопителя вы-
бираются очередные знаки, если они доступ-
ны (выставлен указатель C). Неактивные по-
токи помечаются нулем в соответствующем
месте таблицы STRMS.
Как видно, эта система действительно
очень эластична и подключение новых кана-
лов нетрудоемко. Проблема только в том,
что инструкции OPEN и CLOSE работают лишь
со стандартными идентификаторами каналов
K, S, P. Подключение и отключение потоков
от новых каналов (модификация данных в
STRMS, а также переменной CURCHL) должны
быть выполнены программой. Это требует пе-
ресылки дополнительных сигналов, инициали-
зирующих данное устройство или информирую-
щих его о завершении сеанса работы.
В конце неприятная новость для облада-
телей ZX-ИНТЕРФЕЙСА-1: после подключения
этого устройства к SPECTRUM изменяются
форматы хранения данных о каналах и пото-
ках и приведенные выше соображения не
удается применить.