|
Echo
#03
31 марта 1997 |
|
Книга - Тайники ZX-Spectrum: Системные переменные Бейсика.

Глава 6.
С И С Т Е М Н Ы Е
П Е Р Е М Е Н Н Ы Е
Системные переменные хранятся с адреса
#5C00 (23552) до области, занимаемой прог-
раммой Бейсик. Программы из памяти ROM ис-
пользуют ее для запоминания информации,
описывающей состояние компьютера. Ниже бу-
дут рассмотрены те переменные, которые мо-
гут модифицироваться и использоваться
программистом. Остальные лучше не трогать,
так как это может привести к порче опера-
ционной системы. Описываемые переменные
разделим (согласно специфических функций,
а не положения в памяти) на 5 групп:
- хранящие важные для системы адреса;
- обслуживающие клавиатуру;
- описывающие состояние системы;
- связанные с каналами и потоками;
- обслуживающие экран телевизора.
6. 1 Важные для системы адреса
ERR_SP #5C3D (23613) STKEND #5C65 (23653)
VARS #5C4B (23627) RAMTOP #5CB2 (23730)
PROG #5C53 (23635) P_RAMT #5CB4 (23732)
E_LINE #5C59 (23641) CHANS #5C36 (23606)
WORKSP #5C61 (23649) UDG #5C7B (23675)
STKBOT #5C63 (23651)
Применение этих переменных описано в
предыдущей главе. Естественным использова-
нием этих переменных может быть перерасп-
ределение размеров свободной памяти, либо
занятой программой, переменными и т. д.
Только переменная RAMTOP может быть легко
модифицирована из Бейсика посредством
CLEAR K. К сожалению, эта команда имеет
также и другие побочные действия, что вре-
менами делает ее использование невозмож-
ным.
P_RAMT
Содержит адрес последней, физически
присутствующей в компьютере, ячейки памя-
ти. Следовательно, может быть использована
для распознавания программой в какой моде-
ли компьютера ZX-SPECTRUM она загружена
(16K или 48K).
CHARS
Благодаря этой переменной можно опреде-
лить собственные формы вывода. После раз-
мещения их в память RAM под адресом K дос-
таточно задать переменной CHARS значение
K-256. Начиная с этого момента, все текс-
ты, включая программный листинг, будут пе-
чататься нашими новыми знаками. Этим спо-
собом можно изменить очертания всех симво-
лов с кодами от 32 до 127. Следует под-
черкнуть, что так модифицируется только
очертания знаков, но не их значения, кото-
рые зависят от кодов символов. Можно ис-
пользовать эту переменную для трюков, де-
лающих текст программы абсолютно нечитае-
мым. Достаточно уменьшить значение CHARS
на 8, и тогда в распечатке программы труд-
но будет найти какой-либо смысл. Зато над-
писи, выводимые запущенной на выполнение
программой, останутся разборчивыми, если
будут заблаговременно сдвинуты на одно
значение кода, т. е. в исходном тексте по-
местим "B" вместо "A", "O" вместо "N" и т.
д..
UDG
Польза от размещения этого адреса в
списке для переменных состоит в том, что
этот блок мы можем перемещать в памяти.
Столь же ценной является возможность ис-
пользования нескольких наборов нетиповых
символов одновременно. В этом случае, пе-
ред выводом данного знака требуется моди-
фицировать UDG, присваивая переменной зна-
чение набора, необходимого в данный мо-
мент. Модификация остальных переменных
этой группы очень опасна и может легко
привести к сбою и зависанию операционной
системы.
ERR_SP
Эта переменная указывает основание ма-
шинного стека. Там, в свою очередь, поме-
щен адрес процедуры в памяти ROM, отвечаю-
щей за обслуживание всех ошибочных ситуа-
ций, требующих прерывание программы и вы-
дачи соответствующего сообщения. Под ошиб-
кой здесь понимается также и нормальное
завершение программы, сигнализируемое
сообщением 0 OK. Страстные программисты,
знающие ассемблер Z80 могут, благодаря
этому, писать собственные программы обра-
ботки ошибок, что позволяет, между прочим,
добавление новых команд к языку. Модифика-
ция ERR_SP с уровня Бейсика всегда ведет к
краху системы в момент возникновения си-
туаций, требующих вывода любого сообщения.
Это часто используется для защиты програм-
мы от несанкционированного просмотра и ко-
пирования. Этот метод в соединении с за-
писью программ с помощью SAVE F LINE..., а
также с исключением возможности считывания
программы инструкцией MERGE обычно пол-
ностью позволяет обезопасить программу от
менее грамотных пиратов. К сожалению, спа-
сения от многочисленных копирующих прог-
рамм нет.
6. 2 Переменные, обслуживающие клавиа-
туру
KSTATE #5C00 (23552)
Эта переменная построена из 8 байт и
используется для чтения клавиатуры и обс-
луживания самоповторяемости клавиш. Для
программиста лишь ячейка с адресом #5C04
(23556) может иметь значение. Она содержит
значение 255, если ни одна клавиша не на-
жата, или код основного значения нажатой
клавиши в режиме C (большая литера алфави-
та или цифра). PEEK 23556 дает поэтому
тот же самый эффект, что и CODE INKEY$ в
режиме C. Достоинством является факт, что
значение не зависит от состояния курсора
(L или C). В случае нажатия нескольких
клавиш одновременно всегда будет распозна-
на первая (INKEY$ в такой ситуации может
игнорировать все). Клавиши <CS> и <SS>,
нажимаемые по отдельности, не воздействуют
на нашу ячейку, но нажатые вместе дают код
14. Кроме того, комбинации <CS/9>, <CS/3>,
<CS/4>, <CS/2> выдают соответственно коды
15, 4, 5, 6 (эти коды ловит также CODE
INKEY$).
LAST_K #5C08 (23560)
Эта байтовая переменная хранит код пос-
ледней нажатой клавиши, независимо от то-
го, нажимают на нее или нет. В случае на-
жатия нескольких - будет запомнен код пер-
вой. В отличие от предыдущей переменной,
LAST_K следит за состоянием курсора. С
этой переменной частично связана следующая
переменная.
FLAGS #5C3B (23611)
Сколько раз переменная LAST_K принимает
новое значение, столько раз пятый бит пе-
ременной FLAGS устанавливается в 1. Это
важно, если мы желаем распознать многок-
ратное нажатие на одну и ту же клавишу. В
свою очередь, третий бит этой переменной,
вместе с содержимым MODE, позволяет рас-
познать в какой ситуации относительно чте-
ния клавиатуры должен быть использован
курсор K. Однако, эту информацию можно ис-
пользовать лишь с уровня ассемблера. 7 бит
переменной FLAGS сигнализирует системе,
что пришла выполняемая команда с клавиату-
ры или из программы. Размещенная в прог-
рамме инструкция POKE 23611, 0 прервет ее
выполнение сообщением 0 OK.
REPDEL #5C09 (23651) и REPPER #5C0A
(23652)
Две эти переменные необходимо рассмат-
ривать одновременно. Первая из них опреде-
ляет как долго надо нажимать клавишу, что-
бы заработал автоповтор, а вторая опреде-
ляет время между считыванием с клавиатуры.
В обеих переменных время дано в 1/50 се-
кунды. По началу эти переменные инициали-
зированы значениями 35 и 5, что обозна-
чает, что нажатая клавиша после 0. 7 сек
начинает саморазмножаться с темпом 10 зна-
ков в сек. В процессе считывания с клавиа-
туры эти значения можно уменьшить до 0.
Придавая им значения 0, добиваются наи-
большей остановки, продолжающейся столько
же, сколько PAUSE 256. Занесение в эти
ячейки значения 1 приводят к тому, что ра-
бота со SPECTRUM становится трудной, но
возможной (ввод любой директивы с клавиа-
туры будет требовать от оператора отличной
реакции и чувствительности в пальцах).
RASP #5C38 (23608) и PIP #5C39 (23609)
Эти переменные определяют звук, сопро-
вождающий ввод данных. RASP задает дли-
тельность (в 1/50 сек) предупредительного
ворчания, когда SPECTRUM не желает больше
считывать данные. Начальное значение
RASP=64 (1. 26 сек). PIP определяет дли-
тельность звука, подтверждающего нажатие
клавиши. Начальное значение PIP=0. Стоит
помнить, что RASP и PIP, в отличие от
большинства других системных переменных,
не инициализируются заново инструкцией
NEW.
6. 3 Переменные состояния системы
Эти переменные позволяют системе конт-
ролировать ситуацию и верно интерпретиро-
вать очередные программные строки.
NEWPPC #5C42 (23618) и NSPPC #5C44
(23620)
Первая из них (2 байта) содержит номер
строки, а вторая (1 байт) осуществляет пе-
реход. Следующие команды вызывают непос-
редственный переход к M-й инструкции в L-й
строке, следовательно, действуют значи-
тельно точнее команды GOTO L.
POKE 23618, L-256*(INT(L/256)):
POKE 23619, INT(L/256):
POKE 23620, M
PPC #5C45 (23621) и SUBPPC #5C47
(23623)
Эти переменные содержат соответственно
номер строки и номер выполняемой команды.
Вместе с переменной ERR_NR они могут слу-
жить для завершения программы с ранее за-
данным сообщением без провоцирования фак-
тической ошибки. С этой целью программу
следует завершить инструкцией GOTO 9999, а
в этой строке поместить команды:
9999 POKE 23621, L-256*INT(L/256):
POKE 23622, INT(L/256):
POKE 23610, M-1 : POKE 23623, K
В этом случае программа завершится
сообщением:
M ТЕКСТ L: K .
ERR_NR #5C3A (23610)
В этой ячейке появляется номер-1 ошиб-
ки, которая произошла и будет сигнализиро-
ваться соответствующим сообщением. Содер-
жимое этого байта может быть ценным при
написании собственных процедур обработки
ошибок на ассемблере, т. к. сразу опреде-
ляет причину прерывания программы.
E_PPC #5C49 (23625)
Эта переменная (2 байта) содержит номер
текущей строки и доступна для редактирова-
ния. Ее модификация вызовет тот же эффект,
что и LIST N, но без вывода программы на
экран. Это делает возможным выбор с кла-
виатуры строки программы для модификации,
а затем копирования ее в нижнюю часть эк-
рана и корректировку без уничтожения со-
держимого экрана.
MODE #5C41 (23617)
Эта переменная информирует редактор ка-
кой курсор должен использоваться в данный
момент. Система использует следующие зна-
чения: 0-L, C или K, 1-E, 2-G. Эти числа
затем используются в различных выражениях
для назначения кода символу, который дол-
жен высвечиваться как курсор. Программируя
на Бейсике можно только склонить SPECTRUM,
чтобы в ближайшей инструкции INPUT вместо
стандартного курсора L или C использовался
курсор G или E. Причем режим E будет
действовать только для первого вводимого
символа. Режим E включится POKE 23617, 1.
Интересные эффекты дает размещение в этой
переменной других значений (отличных от 1,
1, 2). POKE 23617, K для K=3,..., 127 вы-
зывает курсор G, хотя на экране вообще не
будет печататься литера G, а нечто другое.
POKE 23617, K для K=0, 128,..., 255 уста-
навливается режим L или C, но с выводом на
экран другого мерцающего курсора.
FLAGS #5C6A (23658)
Эта переменная определяет, какой необ-
ходим режим L или C. За это отвечает 3-й
бит FLAGS2. POKE 23658, 0 устанавливает
режим L, а POKE 23658, 8 - режим C. Подоб-
ные изменения получают с клавиатуры с по-
мощью CS/2.
DF_SZ #5C6B (23659)
Эта переменная содержит число строк
нижней части экрана, зарезервированных для
системных сообщений и данных, вводимых с
помощью INPUT. Инициализируется значением
2. Практически не используемая, хотя иног-
да может быть использована для защиты
программ от прерываний. Помещение в нее 0
вызывает зависание системы, как только
возникает необходимость вывода чего-нибудь
в нижнюю часть экрана (например, сообщения
о нажатии BREAK). Однако это не выгодное
оружие, т. к. одновременно делает невоз-
можным применение инструкций INPUT, CLS, а
также не позволяет задать вопрос
"SCROLL?".
OLDPPC #5C6E (23662) и OCPPC #5C70
(23664)
Они содержат номер строки и команды в
строке, к которым будет осуществлен пере-
ход в случае выдачи команды CONTINUE. Мо-
дификация этих переменных в программе поз-
воляет найти точнейшую альтернативу инст-
рукции GO TO. В некоторых ситуациях это
лучше, чем модификация NEWPPC и NSPPC, т.
к. переход наступает лишь при встрече с
CONTINUE, а не сразу же после модификации
переменных. Эти переменные автоматически
корректируются системой всякий раз, когда
наступает прерывание программы с сообще-
нием, отличным от 0 OK.
SEED #5C76 (23670)
Эта основа генератора псевдослучайных
чисел. Использование SEED рассматривалось
при описании функции RND.
FRAMES #5C78 (23672)
Три байта составляют внутренние часы
ZX-SPECTRUM. Они представляют число PEEK
23672+256*PEEK 23673+65536*PEEK 23674 и
определяют сколько 1/50 сек прошло с мо-
мента инициализации системы. Максимальным
значением является 2^24-1=16777215, что
отвечает 3 суткам 21 часу 12 минутам и 24.
3 секундам. Точность таймера составляет
около 0. 01% или менее 9 сек в сутки. Этот
таймер включается на то время, когда
SPECTRUM обслуживает внешние устройства
(принтер, магнитофон, динамик), а также во
время выполнения программы в машинном ко-
де, которые выключают или обходят контроль
за замаскированными прерываниями.
DATADD #5C57 (23639)
Эта переменная хранит адрес элемента в
списке DATA, который будет считан очеред-
ной инструкцией READ (это близко к правде,
но является хорошим приближением этих двух
ячеек). Запоминая их содержимое и исполь-
зуя его потом, можно получить точнейшую
альтернативу команды RESTORE K.
SCR_CT #5C8C (23692)
Этот байт определяет, после вывода
скольких строк +1, на экране должен поя-
виться вопрос "SCROLL?". Если надо, чтобы
вывод не прерывался, то , по крайней мере,
один раз на 255 выведенных строк необходи-
мо в эту ячейку занести значение 255. Если
нам надо прервать вывод раньше, то нужно
присвоить этой переменной значение меньшее
23.
6. 4 Переменные, обслуживающие экран
телевизора
Эта группа переменных отвечает за пра-
вильные взаимодействия компьютера с теле-
визором. Одна из них управляет цветом,
другие определяют место вывода очередного
знака или графического символа.
BORDCR #5C48 (23624)
Эта переменная содержит атрибуты, опи-
сывающие нижнюю часть экрана, а также
цвет рамки. В обычных условиях ZX-SPECTRUM
не позволяет устанавливать одинаковый цвет
для фона и чернил в нижних строках (поль-
зователь всегда должен видеть вводимые им
символы). Спецификаторы цветов в списке
INPUT будут действенны только для текстов,
печатаемых в нижней части экрана, но цвет
чернил для вводимых данных всегда устанав-
ливается в 9 (белый или черный, в зависи-
мости от цвета фона). Обойти это можно
(например, если компьютер должен считывать
с клавиатуры тайный пароль) используя
команду POKE 23624, 128+F+64*B+8*P+I и
присваивая литерам F, B, P, I значения па-
раметров команд FLASH, BRIGHT, PAPER и
INK, необходимых для получения желаемого
эффекта. Тем, кто не убежден, рекомендуем
получить этот эффект другим способом:
BORDER 3 : POKE 23624, 222 : CLS.
ATTR_P #5C8D (23693) и ATTR_T #5C8F
(23695)
Обе переменные однобайтовые и хранят
значения атрибутов FLASH, BRIGHT, PAPER и
INK. Литера P обозначает величины, уста-
новленные постоянно соответствующими ко-
мандами для всей программы, литера T - те-
кущие значения, устанавливаемые теми же
самыми командами, размещенными в списках
соответствующих пишущих и рисующих команд.
При отсутствии спецификаторов цвета в
списках пишущих инструкций, переменная
ATTR_P копируется в ATTR_T. Способ хране-
ния информации о цветах в одном байте опи-
сан в главе "Использование памяти". Пере-
менная ATTR_P может быть использована в
программе Бейсика для установления всех
атрибутов одной инструкцией POKE. ATTR_T,
в свою очередь, может быть важна для прог-
раммирующих в машинном коде, так как,
обычно, используются процедурами памяти
ROM для установления заданных цветов.
MASK_P #5C8E (23694) и MASK_T #5C90
(23696)
Эти однобайтовые переменные используют-
ся при реализации команд FLASH, BRIGHT,
PAPER, INK с параметром 8. Значение литер
P и T в именах переменных такое же самое,
как для переменных ATTR. Установление ка-
кого-либо бита этих переменных в 1 озна-
чает, что бит с тем же самым номером в
соответствующем байте атрибутов должен ос-
таться неизменным. Обратим внимание, что
команда INK 8 устанавливает в 1 все 3
младших бита переменной MASK_P. Модифици-
руя эту переменную инструкцией POKE можем,
например, установить в 1 только один млад-
ший бит. Тогда будет получен эффект фильт-
ра. Неизменной в цвете чернил останется
только основная синяя компонента, в то
время как остальные могут подвергаться из-
менениям. (Обратим внимание на то, что
нумерация цветов совсем случайна. Цвет си-
ний - 1, красный - 2, зеленый - 3 это ос-
новные цвета, смесь которых позволяет по-
лучить все остальные. В ZX-SPECTRUM роль
смешивания выполняет добавление номеров
соответствующих цветов.
COORDS #5C7D (23677)
Два последовательных байта этой пере-
менной содержат координаты (X, Y) точки
на экране, в которой завершила рисование
последняя инструкция PLOT, DRAW, CIRCLE.
Модификация этой переменной дает тот же
самый эффект, что и PLOT OVER 1, K, N:
PLOT OVER 1, K, N, т. е. смещение указате-
ля экрана без рисования какой-либо точки
или линии.
SPOSN #5C88 (23688)
Эта переменная (2 байта) содержит зна-
чения 33-K, 24-M, где K, M - координаты
последнего выведенного на экран знака.
Непосредственная модификация этих перемен-
ных затруднительна, т. к. необходимо од-
новременно модифицировать DF_CC.
DF_CC #5C84 (23684)
Эта переменная содержит адрес байта на
экране, с которого начинается вывод оче-
редного символа инструкцией PRINT. Модифи-
цируется только вместе с Z_POSN. Значи-
тельно проще применить команду PRINT AT K,
N.
SPONSL #5C8A (23690) и DFCCL #5C86
(23686)
Переменные, аналогичные S_POSN и DF_CC,
описывающие нижнюю часть экрана.
P_FLAG #5C91 (23697)
Переменная, содержащая информацию о ре-
жиме печати и рисования на экране. Описы-
вает режимы, установленные Бейсиком с по-
мощью инструкции INVERSE, OVER, INK 9 и
PAPER 9. Нечетные биты соответствуют пос-
тоянному заданию этих режимов, четные вре-
менному.
__________________________________
| | временно | постоянно |
| | бит | бит |
|-----------|----------|-----------|
| OVER 1 | 0 | 1 |
| INVERSE 1 | 2 | 3 |
| INK 9 | 4 | 5 |
| PAPER 9 | 6 | 7 |
|___________|__________|___________|
Если необходимо установить постоянно
OVER 1: INVERSE 1: INK 9: PAPER 9, то
вместо 4-х команд достаточно одной POKE
23697, 2+8+32+128.
ВНИМАНИЕ: названия системных переменных
не распознаются Бейсиком. Они введены ав-
торами операционной системы и приняты во
всей литературе, относящейся к
ZX-SPECTRUM.
Другие статьи номера:
Похожие статьи:
В этот день... 17 ноября