Ввод/вывод
Установка текущего потока: CALL 5633 (#1601)
Подпрограмма устанавливает текущим поток, номер которого указан
в регистре А (см. «Архитектура ZX Spectrum»). Операционная система
ZX Spectrum предоставляет пользователю 4 потока:
поток 0 и 1 — ввод с клавиатуры, вывод на служебный экран; K
поток 2 — вывод на основной экран; S
поток 3 - вывод на принтер; P
Потоки с номерами от 4 до 15 открываются при подключении различных внешних устройств (дисковых накопи-
телей, контроллеров сети и т. п.).
Вывод символа в поток: RST 16 (#0010)
Подпрограмма выводит в текущий поток символ, код которого занесен
в регистр А. Процедура может быть также использована для смены параметров вывода на экран (аналогично
выполнению операторов INK, PAPER, TAB, AT и др.). Для этого необходимо вывести в поток соответствующий
управляющий код (см. «Контрольные коды ZX Spectrum») и сразу за ним — требуемый аргумент (номер цвета,
позицию печати и т. д.).
Контроль нажатия клавиши BREAK: CALL 8020 (#1F54)
Процедура сбрасывает флаг переноса CY, если в момент ее выполнения *) Регистр IY должен настраиваться на
ERR NR также, когда в программе используется режим прерываний 1 и прерывания разрешены.
нажимается клавиша Break (Caps Shift/Space), в противном случае флаг устанавливается.
Очистка всего экрана: CALL 3435 (#OD6B)
Подпрограмма очищает основной и служебный экраны и, в соответствии с системными переменными ATTR_P
(23693) и BORDCR (23624),
устанавливает атрибуты.
После выполнения этой и следующей процедуры текущим устанавливается поток номер 1.
Очистка служебного экрана: CALL 3438 (#OD6E)
Подпрограмма очищает служебный экран, атрибуты для которого устанавливаются в соответствии с системной
переменной BORDCR (23624).
Скроллинг экрана: CALL 3582 (#ODFE)
Процедура перемещает содержимое основного экрана вверх на одну
символьную строку.
Изображение точки на экране: CALL 8933 (#22Е5)
Координаты точки задаются содержимым регистровой пары ВС. В
регистр В заносится значение координаты Y (0...175), в С — координаты X(0...255). Атрибуты знакоместа, в
которое попадает точка, задаются системной переменной ATTR_P (23693).
Вывод числа в поток в десятичной форме
Для вывода в текущий поток целых чисел последовательно вызовите
две подпрограммы:
CALL 11563 (#2D2B)
CALL 11747 (#2DE3)
Первая подпрограмма помещает число в стек калькулятора, вторая — выводит его в текущий поток. Число,
предназначенное для вывода, должно находиться в регистровой паре ВС. Незначащие нули игнорируются.
Ввод символа с клавиатуры
Для опроса клавиатуры чаще всего используют системные переменные LAST_K (23560) и FLAGS (23611). При
установленном режиме прерываний 1 и разрешенных прерываниях, переменная LAST_K содержит код последней
нажатой клавиши, а 5-й бит переменной FLAGS устанавливается при нажатии любой клавиши. Таким образом,
ожидание нажатия произвольной клавиши можно организовать с помощью следующей подпрограммы:
KEY EI ;разрешение прерываний
RES 5,(IY+1) ;сброс 5-го бита системной
;переменной FLAGS
LOOP BIT 5,(IY+1) ;клавиша нажата?
JR Z,LOOP ;переход на LOOP, если не нажата
LD A,(IY—50) ;чтение кода нажатой клавиши
;из системной переменной LAST_K
RET ;возврат из подпрограммы
Приведенная подпрограмма ждет нажатия любой клавиши и возвращает ее код в аккумуляторе.
Ожидание ввода: CALL 5598 (#15DE)
Подпрограмма осуществляет ввод из текущего потока. По окончании ввода одного байта процедура проверяет
флаг переноса CY. Если он установлен, происходит выход из подпрограммы, в противном случае проверяется
флаг нуля Z. Если Z установлен, процедура ввода повторяется. При условии Z=0 управление передается опе-
рационной системе, которая выдает сообщение 8 End of file.
Если текущим установлен поток 1 (обычно — канал "К"), подпрограмма осуществляет опрос клавиатуры, и
после нажатия клавиши помещает ее код в аккумулятор. Однако существует сложность: если бит 3 системной
переменной TVFLAG (23612) установлен, то параллельно вводу символов с клавиатуры на служебном экране
будет отображаться содержимое буфера редактора.
Звуковой сигнал: CALL 949 (#О3В5)
Перед вызовом подпрограммы в регистровые пары HL и DE помещаются числа (0...65535), пропорциональные,
соответственно, частоте звукового сигнала и его длительности. При этом нужно учитывать линейную зависи-
мость между частотой и длительностью — чем выше тон, тем короче звук. Необходимые значения рассчитывают-
ся следующим образом:
HL = (437500/f)-30.125 DE = f * t
где f — частота в Гц, t — время в сек.
Например, для воспроизведения в течении 1 секунды ноты «ДО» первой октавы (частота примерно 261 Гц) в
HL необходимо поместить число 1646, а в DE — число 261.
Печать сообщений: CALL 3082 (#ОСОА)
Для выполнения этой подпрограммы в регистровую пару DE загружается начальный адрес таблицы сообщений,
в регистр А — номер сообщения в ней. Первое сообщение имеет номер 0. Первым байтом в таблице должен сто-
ять код 128 (#80). Для задания конца сообщения старший бит его последнего байта должен быть установлен в
единицу.
Пример:
LD А,0 ;печать первого
CALL PR_MES ;сообщения в таблице
PR_MES LD DE,MES_TAB
CALL 3082 ;вывод сообщения на основной экран
RET
MES_TAB DEFB #80 ;начало таблицы
DEFM "ENTR" ;начало сообщения "ENTRY"
DEFB "Y"@#80 ;конец сообщения
DEFM "ENTRY " ;второе сообщение "ENTRY 2"
DEFB "2"@#80
Изображение окружности: CALL 9005 (#232D)
Параметры кружности предварительно помещаются в стек калькулятора в следующем порядке: X, Y (коорди-
наты центра окружности) и Z (радиус). Сделать это можно с помощью специальной подпрограммы, размещенной
по адресу 11560 (#2D28), которая заносит в стек калькулятора содержимое аккумулятора.
Следует учитывать, что процедура изображения окружности изменяет значение системной переменной COORDS
(23677/78) .
В качестве примера приведем следующую программу:
LD НЬ,(23677) ;запоминаем текущие
PUSH HL ;координаты (COORDS)
LD А,Х ;координата X (от 0 до 255)
CALL #2D28 ;запись аккумулятора в стек
LD A,Y ;координата Y (от 0 до 175)
CALL #2D28 ;запись аккумулятора в стек
LD А^ ;Z - радиус
CALL #2D28 ;запись аккумулятора в стек
CALL #232D ;изображение окружности
POP HL ;восстанавливаем
LD (23677),HL ;координаты (COORDS)
Изображение линии: CALL 9399 (#24B7), CALL 9402 (#24ВА)
Для процедуры изображения линии, расположенной с адреса 9399(#24В7), параметры передаются так же, как
и для процедуры изображения окружности — через стек калькулятора. На практике удобнее пользоваться под-
программой по адресу 9402 (#24ВА) , параметрами для которой являются значения регистровой пары ВС и сис-
темной переменной COORDS(23677/78). В регистры В и С записываются соответственно величины смещений отно-
сительно текущих координат Y (0...175) и X (0...255), содержащихся в системной переменной COORDS.
Знаки смещений по Y и X задаются в регистрах D и Е соответственно записью в них следующих значений: +1
(#01) — положительное, -1 (#FF) — отрицательное.
С использованием CALL 9402 (#24ВА) можно легко реализовать ассемблерный эквивалент команды: Бейсика
DRAW. Например, результат выполнения следующей программы аналогичен выполнению команды: DRAW 0,20:
LD ВС,#1400 ; 20,0
LD DE,#0101 ; знаки смещений
CALL 9402
Для изображения отрезка с координатами начала (127,87) и смещением конца (-20,40) перед вызовом под-
программы необходимо настроить системную переменную COORDS
LD L,127 ;стартовые координаты Х=127
LD Н,87 ;и Y=87
LD (23677),HL записываются в COORDS
LD С,20 ;смещение по X
LD Е,—1 ;задается равным —20
LD В,40 ;смещение по Y -
LD D,1 ;равным +40
CALL 9402 ;изображение отрезка
Очистка части экрана: CALL 3652 (#0Е44)
Подпрограмма служит для очистки нижней части экрана. Количество строк, которые необходимо очистить,
указывается в регистре В.
Скроллинг части экрана: CALL 3584 (#0Е00)
Подпрограмма перемещает вверх на одну символьную строку нижнюю часть экрана. В регистр В записывается
число, на единицу меньшее количества строк, которые необходимо переместить.
Загрузка и запись файлов на магнитофон
Как правило, файл, записанный на магнитной ленте, состоит из двух блоков, первый из которых называется
заголовком и содержит информацию о файле (тип, длина и т. п.), второй — собственно данные. Подпрограмма
ПЗУ загружает и обрабатывает заголовок и на основе полученной информации загружает данные.
Длина заголовка составляет 17 байт:
байт 0 — тип файла:
0 — бейсик-программа;
1 —числовой массив;
2 — символьный массив ;
3 — двоичный (кодовый) файл.
байты 1...10 — имя файла;
байты 11, 12 —длина блока данных;
байты 13, 14 — для типа 0: номер строки автозапуска;
— для типа 3: начальный адрес загрузки;
байт 14 — для типов 1 и 2 — имя и тип массива в
следующей форме:
биты 0...4 — имя массива (А. ..Z);
бит 5 — 0, если массив числовой;
бит 6 — 1, если массив символьный;
бит 7 — всегда установлен;
байты 15,16 — длина бейсик-программы.
Загрузка файла без заголовка: CALL 1366 (#0556)
Процедура предназначена для загрузки с ленты блока кодов и проверки записи. Она используется следующим
образом:
LD !Х,<начальный адрес>
LD DЕ,<длина блока>
LD А, <флаг>
SCF
CALL 1366 ;вызов процедуры загрузки
RET
В индексный регистр IX загружается адрес ячейки памяти, начиная с которой будет производиться проверка
или загрузка блока кодов. В регистровую пару DE помещается длина загружаемого файла в байтах, а в регистр
А — так называемый флаговый байт. Он равен нулю, если ожидается заголовок, и 255 — если тело файла (воз-
можны и другие значения флагового байта). Загрузка кодового блока будет производиться, если перед выполне-
нием процедуры был установлен флаг CY, проверка блока — если CY сброшен.
По возврату из процедуры, если загрузка (проверка) произведена успешно, флаг CY устанавливается, в про-
тивном случае — сбрасывается.
Прервать загрузку (проверку) блока можно, нажав клавишу Break, при этом на экран выдается сообщение BREAK
— CONT repeats. Для запрещения прерывания загрузки нужно несколько изменить программу вызова процедуры:
LD !Х,<начальный адрес>
LD DE^amim блока>
LD А, <флаг>
SCF
INC D
ЕХ AF,AF'
DEC D
DI
LD A,15 ;номер начального цвета бордюра + 8
OUT (254) ,A
CALL 1378
LD А,7 ;восстановление цвета бордюра
OUT (254) ,А
EI
RET
Если при возврате из этой подпрограммы флаг переноса равен нулю,
то это означает, что либо загрузка (проверка) произведена с ошибкой, либо во время загрузки была нажата
клавиша Break. Более точно установить причину ошибочного завершения операции можно, опросив клавиатуру.
Запись файла без заголовка; CALL 1218 (#04С2)
Подпрограмма служит для записи данных на магнитофон и вызывается аналогично процедуре загрузки:
LD IX,<начальный адрес>
LD DЕ,<длиIна блока в байтах>
LD А,<флаг>
CALL 1218
RET
При нажатии клавиши Break выполнение процедуры будет прервано и выдано сообщение BREAK — CONT repeats,
чего можно избежать, запустив процедуру не с адреса 1218, а с 1222.
Написание собственных подпрограмм
обработки ошибок бейсик-интерпретатора
Процедура выхода по ошибке расположена в ПЗУ с адреса 8 и вызывается следующим образом:
RST 8
DEFB <код сообщения>
При выполнении процедуры указанный код записывается в переменную ERR NR(23610), затем с помощью сис-
темной переменной ERR_SP(23613/14") восстанавливается стек и процессор переходит к выполнению процедуры
обработки ошибок. Изменив адрес, хранящийся в переменной ERR_SP, можно подключить собственные подпро-
граммы обработки ошибок.
Предположим, Вы поместили свою процедуру обработки ошибок с адреса 40000 (пусть, к примеру, она гене-
рирует звуковой сигнал, после чего обработка ошибок продолжается обычным образом). Для подключения этой
процедуры можно воспользоваться следующей программой:
LD HL, (23613)
LD BC,40000
LD E, (HL)
LD (HL),C
INC HL
LD D, (HL)
LD (HL),B
LD (ERR_RET),DE
RET
ERR_RET DEFW 0
ORG 40000
LD HL, 1646
LD DE,261
CALL 949
LD HL,(ERR_RET)
JP (HL)
После выполнения этой программы при возникновении любых ошибок будет выполняться процедура, располо-
женная по адресу 40000. Локальная переменная ERR_RET используется для сохранения предыдущего адреса воз-
врата по ошибке.