СИСТЕМНЫЕ ПЕРЕМЕННЫЕ
Интерпретатору Бейсика для «служебного
пользования» в компьютере отводится специальная область
оперативной памяти. В ячейках этой области хранятся настроечные
параметры интерпретатора, а также данные, необходимые для обработки
бейсик-прог-рамм. Читая содержимое этих ячеек, можно узнать много
интересного о состоянии компьютера. Записывая же в них необходимые нам
значения, можно влиять на работу компьютера.
Эти ячейки памяти называют системными переменными. У каждой из переменных есть свое имя и фиксированное положение в памяти17.
speotrum-бейсик
Многие из системных переменных1
непосредственного отношения к Бейсику не имеют, но использование
некоторых из них намного расширяет возможности программиста, тем более,
что изменять значения системных переменных можно с помощью операторов
Бейсика.
Чтение содержимого памяти_
РЕЕК
Память ZX Spectrum состоит из множества
отдельных ячеек, в каждой из которых может быть записано число от 0 до
255 (байт). Всего ячеек 65535. Для того чтобы различать ячейки, каждой
из них приведено в соответствие число от 0 до 65535, называемое адресом.
С помощью оператора РЕЕК прямо из Бейсика можно читать содержимое любых
ячеек памяти. Выполним в непосредственном режиме оператор
print реек 23560 13
По сути, мы выяснили, что в ячейке памяти с адресом 23560 записано число 13. «Зациклим» считывание этой ячейки:
10 print реек 23560 20 go то 10 run 13
Вполне естественно, что первоначальный
результат выполнения программы будет таким же, как и при выполнении
строки. Но если теперь, не останавливая программу, нажимать разные
клавиши, на экране будут появляться коды соответствующих символов.
Итак, мы познакомились с системной переменной LASTJK (адрес 23560), в которой постоянно хранится код последней нажатой клавиши.
В некоторых случаях пользоваться системной переменной LAST_K предпочтительнее, чем функцией inkey$. Ведь inkey$
возвращает символ клавиши, нажатой именно в момент ее выполнения, и
требует обязательного «зацикливания» программы на опросе
клавиатуры. Переменная LAST_K сохраняет код клавиши и после ее
отпускания. Это позволяет после завершения программой каких-либо
действий проверить, была ли нажата клавиша в момент выполнения этих
действий.
Системный счетчик
23672/73/7418. Они носят общее название «системная переменная FRAMES».
После включения или сброса компьютера
содержимое всех трех ячеек обнуляется. По прошествии 1/50 секунды в
ячейку 23762 записывается число 1. И далее, через каждые 1/50 секунды
ее содержимое увеличивается на 1. При достижении значения 255 ячейка
23762 обнуляется, а содержимое ячейки 23673 увеличивается на 1. И,
соответственно, когда переполняется ячейка 23673 (записанное в ней
значение достигает 255), к содержимому ячейки 23674 прибавляется 1.
Следовательно, в нашем распоряжении имеются часы, отсчитывающие время с
момента включения компьютера с точностью в 1/50 секунды непрерывно в
течение
(255+255x256+255x256x256)/50=335544,3 секунд,
то есть 3 суток и еще 21 часа. Потом все сначала.
Для определения числа полных секунд, прошедших с момента включения или сброса компьютера, нужно рассчитать следующее выражение:
LET T=INT((65536*PEEK 23674+256+РЕЕК 23673+РЕЕК 23672)/50)
Таким образом можно смоделировать на компьютере часы:
10 INPUT "Час ";hour
20 INPUT "Минуты ";min
30 POKE 23674,0: POKE 23673,0: POKE 23672,0
40 LET t=PEEK 23672+2569*PEEK 23673+65536+PEEK 23674+
hour* 180000+min*3000 50 LET h=!NT (t/180000) 60 LET h$=STR$ h
70 IF LEN h$=1 THEN LET h$="0"+h$ 80 LET h$=h$(
TO 2)+":" 90 LET m=INT ((t-h* 180000)/3000) 100 LET m$=STR$ m 110 IF
LEN m$=1 THEN LET m$="0"+m$ 120 LET m$=m$( TO 2)+":" 130 LET s=INT
((t—h* 180000—m*3000)/50) 140 LET s$=STR$ s
150 IF LEN s$=1 THEN LET s$="0"+s$ 160 LET s$=s$( TO 2) 170 PRINT AT 20,24;h$;m$;s$ 180 GO TO 40
Эти «часы» можно включить в любую
программу. Следует только учитывать, что на время ожидания ввода данных
операторами INPUT вывод времени на экран будет остановлен19.
Чтобы задержка была не так заметна, лучше из программы, моделирующей
часы, исключить строки 130... 160 и убрать переменную s$ из строки 170,
то есть не выводить на экран секунды.
Запись в память_
РОКЕ
Запись чисел в память производится с помощью
оператора РОКЕ. Вслед за ним через запятую располагаются два значения:
адрес от 0 до 65535 и заносимое в память по указанному адресу число от
0 до 255.
Невидимая точка на экране_
Оператор DRAW начинает чертить отрезок линии
или дуги от последней выставленной на экране точки. Координаты этой
точки он берет из системной переменной COORDS. В ячейках с адресами
23677 и 23678 этой переменной хранятся, соответственно, значения
координат х
и у последней выставленной на экран точки. Зная это, можно, не
выставляя точки с помощью оператора PLOT, записывать начальную
координату для DRAW сразу в переменную COORDS:
10 РОКЕ 23677,100: РОКЕ 23678, 100 20 DRAW 50, 50
Другое полезное применение в программе
переменной COORDS — это получение из нее с помощью РЕЕК
информации о координатах последней выставленной точки.
Окраска экрана
Оперируя системными переменными, можно добиться того, что невозможно сделать с помощью обычных операторов и функций Бейсика.
Например, в Бейсике нет оператора, изменяющего
все атрибуты служебного экрана (оператор BORDER устанавливает только
цвет фона). Задать их можно только, записывая соответствующие значения
в системную переменную BORDCR (адрес 23624). Число, которое необходимо
записать по этому адресу, формируется по принципу, изложенному в
описании функции ATTR (см. стр. 55).
Определяя через системную переменную BORDCR цвет фона служебного экрана, мы одновременно задаем цвет бордюра.
Точно также, выполнив лишь один оператор РОКЕ 23693, X
- можно задать атрибуты и основного экрана
(вместо привычных INK, PAPER, FLASH и BRIGHT). 23693 — это адрес
системной переменной ATTRJP, значение которой определяет
«окрас» основного экрана. X — число, которым
зашифрованы атрибуты. Может, этот способ сложнее, но он короче и
изящнее.
Другие операции с экраном
Оперируя системными переменными, можно менять
привычные характеристики Бейсика ZX Spectrum. Например, можно увеличить
основной экран: занять под него все 24 строки. Для этого нужно
модифицировать содержимое системной переменной DFJSZ (адрес 23659),
задающей количество строк в служебном экране:
роке 23659,0
Правда, в этом случае следует исключить в
программе вывод на служебный экран, иначе не оберешься беды. Когда же
без служебного экрана не обойтись (при работе с оператором INPUT или
при ожидании вывода сообщения, например, о завершении работы программы)
необходимо восстановить содержимое DF_SZ:
роке 23659.2
Существует системная переменная SCR_CT
(адрес 23692), задающая количество строк текста, передвигаемых вверх по
экрану без запроса scroll?. Требуемое значение этой переменной
устанавливается только из программы (изменить SCR_CT в непосредственном
режиме невозможно).
Настройка клавиатуры
Меняя значения системных переменных REPDEL (адрес 23561) и REPPER
(23562), можно по своему вкусу настроить клавиатуру компьютера. В
переменной REPDEL хранится число, определяющее величину задержки (в
1/50 сек) между нажатием клавиши и началом автоматического повторения
нажатия {автоповтора). REPPER задает период автоповтора (также в 1/50 сек).
При желании можно изменить длительность
звучания сигнала, возникающего при нажатии клавиш. Число,
пропорциональное времени его звучания, содержится в системной
переменной PIP (23609).
Звуковой сигнал, возникает и при переполнении
буфера редактора и некоторых других ошибках. Длительность сигнала
регулируется значением системной переменной RASP (23608).
Полезная информация о памяти
Например, нас может заинтересовать длина написанной бейсик-программы. Выберем из системных переменных PROG (23635/36) и VARS (23627/28) адреса начала бейсик-программы и начала области бейсик-переменных и вычтем одно из другого:
print (реек 23635+256*реек 23635)-(реек 23627+256*реек 23628)
Под системные переменные, хранящие значения
адресов, отводятся по две ячейки памяти, поскольку в одну ячейку можно
записать число не более 255. Для записи числа до 65535 (максимальный
адрес памяти ZX Spectrum) его разбивают на два числа. Сначала делят на
255, после чего остаток от деления заносят в первую ячейку (младший
байт), а целую часть — во вторую (старший байт). Например, число
64768 разобьется на два байта так:
LET L=64768-25620INT(64768/256): REM Младший байт LET H=INT(64768/256): REM Старший байт
Умение записывать значения адресов в системные
переменные может пригодиться, например, при оперировании с символами,
определяемыми пользователем (см. стр. 56). Адрес начала области памяти,
в которой размещается информация об этих символах, хранится в системной
переменной UDG (адреса 23675/76). Изменяя ее содержимое, можно
определить несколько наборов символов и по необходимости в программе
переходить с одного на другой.
Аналогично можно переключать и основной набор
символов. Стандартный набор символов ZX Spectrum «зашит» в
постоянном запоминающем устройстве (ПЗУ), начиная с адреса 15616. Под
хранение этого адреса выделена системная переменная CHARS (адреса
23606/07). Зная это, мы можем создать в памяти (или загрузить с
магнитофона как кодовый блок) новый набор символов и, переписав
значение CHARS, переключить на него работу компьютера. Как создавать
символы, мы описывали в разделе, посвященном псевдографике.
Переопределяя адрес начала текущего набора символов, необходимо
помнить, что первые 32 кода (от 0 до 31) являются управляющими и им не
соответствуют никакие символы. Поэтому адрес начала размещения символов
больше числа, записанного в CHARS, на 256 (32x8)*. Следовательно,
загрузив новый набор символов по адресу 64768, для подключения его в
CHARS нужно записать число 64512 (64768-256)21.
Мы рассказали далеко не о всех системных
переменных. Многим из неупомянутых трудно придумать какое-либо
практическое применение в бейсик-программах. Для понимания назначения
других недостаточно знаний, которые можно почерпнуть из этой книги.
Полный список системных переменных и их описание можно найти в [1].