|
Echo
#03
31 марта 1997 |
|
Книга - Тайники ZX-Spectrum: Использование Памяти.

Глава 5.
И С П О Л Ь З О В А Н И Е
П А М Я Т И
После включения компьютера в сеть авто-
матически запускается программа, размещен-
ная в ROM по адресу 0. Она проверяет объем
допустимой памяти, разделяет ее на различ-
ные блоки, а также присваивает системным
переменным начальные значения.
Диаграмма, приведенная ниже, описывает
раздел памяти. Объем от 0 до 16383 разме-
щается в ROM, остальные в RAM. Только
часть блоков имеют свое постоянное положе-
ние, другие могут перемещаться в памяти и
их актуальные адреса хранятся в соответст-
вующих системных переменных. Числа в конце
некоторых областей обозначают указатели
конца области и всегда присутствуют там.
______________ _________________________
| | | |
| АДРЕС | ОБЛАСТЬ | КОНЕЦ |
|______________|______________|__________|
| | | |
| #0000 (0) | Системные | |
| | процедуры | |
| #3000 (15616)| Прообразы | |
| | символов в | |
| | кодах 32-127 | |
| #4000 (16384)| Экран | |
| #5800 (22528)| Атрибуты | |
| #5B00 (23296)| Буфер прин- | |
| | тера | |
| #5C00 (23552)| Системные | |
| | переменные | |
| #5C86 (23734)| Карта микро- | |
| | драйва | |
| CHANS | Информация о | #80(128) |
| | каналах | |
|--------------|--------------|----------|
| PROG | Б Е Й С И К | |
|--------------|--------------|----------|
| VARS | Переменные | #80(128) |
| | ZX-Бейсика | |
|--------------|--------------|----------|
| E_LINE | Буфер | #80(128) |
| | редактора | |
|--------------|--------------|----------|
| WORKSP | Буфер инст- | #0D(13) |
| | рукции INPUT | |
|--------------|--------------|----------|
| | Рабочая | |
| | область | |
| | ZX-Бейсика | |
|--------------|--------------|----------|
| STKBOT | Стек кальку- | |
| STKEND | лятора | |
|--------------|--------------|----------|
| SP | Свободная | |
| | область | |
| | памяти | |
| | Бейсика | |
|--------------|--------------|----------|
| ERR_SP | Машинный | |
| | стек | |
|--------------|--------------|----------|
| RAMTOP | Стек адресов | #3E(62) |
| | возврата | |
| | GOSUB | |
|--------------|--------------|----------|
| | Свободная | |
| | область | |
| | памяти | |
|--------------|--------------|----------|
| UDG | Прообразы | |
| | символов, | |
| | определенных | |
| | пользовате- | |
| | лем | |
| P_RAMT | | |
|______________|______________|__________|
5. 1 Прообразы символов
Формы печатных символов с кодами от 32
до 127 (8 байт на каждый знак) заполняют
768 последних ячеек ROM. Они закодированы
в той же форме, что и символы, определяе-
мые пользователем. Знаки мозаичной графики
(коды от 128 до 143) конструируются каждый
раз. Адрес начала этой области 256 хранит-
ся в системной переменной CHARS.
5. 2 Экран
Эта область предназначена для хранения
информации о каждой точке экрана, а точнее
о том, должна ли она быть в цвете чернил
или фона. 6144 байта этого блока позволяют
адресовать 49152 различных точек (1 байт
описывает 8 точек). Они организованы в
таблицу из 192 строк и 256 столбцов. Для
графических конструкций Бейсика доступны
только 176 верхних строк. Каждый графичес-
кий знак выводится в поле 8x8 точек. Это
позволяет выводить тексты в формате 24
строки по 32 позиции. Две нижние текстовые
строки зарезервированы для системных сооб-
щений и для рабочей области редактора.
Интересен способ, которым эта область
переносится на экран. К сожалению, после-
довательные 32 байта не описывают последо-
вательно графическую строку на экране, а
256 последовательных байт не описывают
оператор текста. Размещение графической
строки (линии) абсолютно противоположно, а
с точки зрения ZX-Бейсика похоже на изоб-
ретение сумасшедшего. Лучше всего это мож-
но увидеть во время считывания экрана с
ленты. Здесь мы ограничимся только приме-
рами, позволяющими пересчитывать текстовые
и графические координаты на экранные адре-
са.
Байт, содержащий графическую точку с
координатами (K, M) (точка (0, 0) лежит в
левом верхнем углу экрана выше двух низших
текстовых операторов) на экране имеет
адрес:
16384+32*(INT((175-M)
/8-INT((175-M/64*8+8*(176*M-INT((175-M)
/8) *8+64*INT((175-M) /64) +INT(K/8).
Положение битов в байте рассчитывается
как
8-K+INT(K/8) *8.
В свою очередь, адреса текстовых знаков
рассчитываем по образцу:
16384+2048*INT(K/8) +32*(K-8*INT(K/8))
+256*M+N,
где K обозначает номер оператора (от 0
до 23), N является номером колонки (0...
31), в свою очередь M является номером
графической строки(линии), формирующей
длинный знак (0... 7). За нулевую прини-
мается, лежащая по верху блока знака, ли-
ния. Начало координат для инструкций, пи-
шущих знаками помещено в левом верхнем уг-
лу экрана.
5. 3 Атрибуты (22528... 23295)
В этой области хранится информация о
размещении цветов на экране. Наименьшей
единицей поверхности, цвет которой можно
модифицировать, является поле единичного
знака размером 8x8 точек. Для такого поля
можно определить цвет фона, чернил, мерца-
ния. На выбор имеется 8 цветов:
0 - черный
1 - фиолетовый
2 - красный
3 - синий
4 - зеленый
5 - голубой
6 - желтый
7 - белый
Каждый цвет может выступать в двух от-
тенках: обычном и интенсивном (BRIGHT 0,
1).
Все сведения, касающиеся единичного
знакового поля закодированны в одном бай-
те:
_______________________________
| | |
| Биты | Значение |
|________|______________________|
| | |
| 7 | Мерцание |
|--------|----------------------|
| 6 | Интенсивность фона |
|--------|----------------------|
| 5 | |
| 4 | Цвет фона |
| 3 | |
|--------|----------------------|
| 2 | |
| 1 | Цвет чернил |
| 0 | |
|________|______________________|
Чтобы установить желаемые атрибуты поля
и определить какое значение следует помес-
тить в соответствующий байт, лучше пользо-
ваться образцом:
128*F+64*B+32*P+I,
где F - определяет мерцание (FLASH 0,
1)
B - определяет оттенок фона (BRIGHT 0,
1)
P - является номером цвета фона
I - является цветом чернил
Определение адреса байта, описываемого
атрибутами знакового поля с координатами
K, M , осуществляется по формуле:
22528+32*K+M.
5. 4 Буфер принтера
В этой области собираются данные, кото-
рые будут посланы на принтер. Печать, фак-
тически, следует после заполнения этого
буфера (256 байт или 32 знака), или после
символа "конец строки" (CHR$ 13). Если
принтер не подключен, то область не будет
использоваться системой и может использо-
ваться для других целей.
5. 5 Карта микродрайва
Эта область используется только в слу-
чае подключения к SPECTRUM ZX-ИНТЕРФЕЙ-
СА-1. В "голом" компьютере эта карта не
существует физически и CHANS = 23734.
5. 6 Программа ZX-Бейсик (PROG до
VARS-1)
После инициализации системы, без подк-
люченных внешних устройств, этот блок на-
чинается с адреса #5CC8 (23755). В нем
хранится текст программы Бейсик. Отдельные
строки в памяти компьютера имеют следующую
форму:
___________________________________
| | | | |
|2 байта|2 байта |Длина |1 байт |
| | |текста| |
|-------|--------|------|-----------|
| Номер |Длина | |#0D (13) |
| строки|текста+1|ТЕКСТ |Код <ENTER>|
|_______|________|______|___________|
В случае номера строки сделано отступ-
ление от правил и первым здесь выступает
старший байт, а потом младший. Все ключе-
вые слова, появляющиеся в тексте, коди-
руются единичными символами.
Интересным является способ хранения чи-
сел в тексте программы. За последователь-
ностью знаков, представляющих последова-
тельные цифры, всегда размещается управ-
ляющий символ CHR$ 14, а за ним 5 байтов,
содержащих двоичное представление этого
числа. Во время вывода программы на экран,
эти 6 добавочных байт опускаются. Это об-
ъясняет то, почему некоторые программисты
предпочитают запись VAL "17" вместо просто
17. Первая из них фактически занимaет 5
байтов, а вторая 8. Речь идет об экономии
памяти. Во время выполнения программы, в
свою очередь, пропускаются символы, кото-
рыми записано число и используется 5-ти
байтовое двоичное представление. Это поз-
воляет прятать правильные значения опреде-
ленных чисел (например, стартовых адресов
процедур в машинном коде) от "любопытных".
В этом случае необходимо определить адрес
внутреннего представления данного числа и
инструкцией POKE присвоить ей желаемое
значение. При выводе текста на экран и в
дальнейшем будет фигурировать старое
представление числа, уже не связанное с
записанным за ним двоичным числом! Приме-
няя эту технику необходимо помнить, что
каждое извлечение такой строки в нижнюю
часть экрана и возврат ее на место, даже
без модификации, изменяет внутренне предс-
тавление каждого числа в тексте, присваи-
вая им значения, видимые на экране.
Из других любопытных трюков приведем
еще два. Если в первой строке программы, в
ячейках, содержащих ее номер, поместим
число 0, то такой оператор невозможно бу-
дет скопировать в нижнюю часть экрана в
область редактора, а затем модифицировать.
В другом конце программы возможна другая
штучка. Допишем там строку 9999 REM и пос-
ле установления ее адреса в обоих байтах,
содержащих ее номер, разместим значение
255. Первый результат этого проявится при
выводе программы на экран. Модифицирован-
ная нами строка не появится. Второй эф-
фект, гораздо более ценный, появится при
попытке считывания такой программы с кас-
сеты инструкцией MERGE. SPECTRUM обижается
на пользователя и перестает реагировать на
любые клавиши.
5. 7 Переменные ZX-Бейсика (VARS до
E_LINE-2)
В этой области система хранит все пере-
менные, инициализированные как программой,
так и пользователем с клавиатуры. Появляю-
щиеся переменные последовательно дописы-
ваются в конце этой области (все последую-
щие блоки автоматически сдвигаются) и ос-
таются там, пока область не будет очищена.
Исключением являются простые текстовые пе-
ременные: когда какая-нибудь из них моди-
фицируется, и ее предыдущая версия уби-
рается (что сопровождается необходимым пе-
ремещением других блоков памяти), а новая
дозаписывается в конце этой области. То
же происходит при новом объявлении масси-
вов.
Способ хранения переменных зависит от
их типов. В ZX-Бейсике существует 6 раз-
личных видов переменных, обозначаемых чис-
лами от 2 до 7:
2 (010) - простые текстовые перемен-
ные;
3 (011) - простые числовые переменные
с однолитерными именами;
4 (100) - числовые массивы;
5 (101) - простые числовые переменные
с многолитерными именами;
6 (110) - знаковые массивы;
7 (111) - переменные, управляющие цик-
лами
FOR ... NEXT.
Во всех случаях первый байт описания
переменной содержит ее тип, а также номер
первой литеры имени. Метод размещения
этих сведений в одном слове следующий:
____________________________________
| | | |
| | Тип | Номер литеры |
|----------|--------|----------------|
| Биты | 7 6 5 | 4 3 2 1 0 |
|__________|________|________________|
Обратим внимание, что биты 4... 0 со-
держат порядковый номер литеры в алфавите,
а не ее код. Собственно код мы получаем
складывая с числом #60 (96). Храня имена
переменных SPECTRUM автоматически заменяет
большие литеры малыми и пропускает все
пробелы. Содержимое последующих байт зави-
сит от типа переменной.
Простая текстовая переменная, длина
описания N + 3 байта:
___________________________________
| | | |
| Тип и | N = длина текста | Текст |
| литера | (2 байта) | |
|________|__________________|_______|
Простая числовая переменная с одноли-
терным именем, длина описания 6 байт:
____________________________________
| | |
| Тип и литера | Содержимое (5 байт) |
|______________|_____________________|
Числовой массив, длина описания N + 3
байта:
______________________________________
| | | | | |
| Тип |N=длина|K=число|1-й...K-й|Эл-ты|
| и |описа- |индек- |индексы | по |
|литера|ния-3 |сов |(по 2 б.)|5 б. |
| |(2 б.) | | | |
|______|_______|_______|_________|_____|
Простая числовая переменная, с многоли-
терным именем, длина описания K + 5 байт
________________________________________
| | | |
|Тип и литера|2-ой знак...K-ый знак| Зна-|
| |имени имени|чение|
| | | 5 б.|
|____________|_____________________|_____|
Второй и последующий символы имени хра-
нятся как коды соответствующих знаков.
Последний байт имени имеет самый старший
бит, всегда установленный в 1, что позво-
ляет всегда распознать его.
Знаковый массив, длина описания N + 3
байта:
________________________________________
| | | | | |
|Тип и |N=длина|K=число |1-й...K-й| Эл-ты|
|литера| описа-| индек-| индексы | по |
| | ния-3 |сов | | |
| |(2 б.) | |(по 2 б.)|(1 б.)|
|______|_______|________|_________|______|
Управляющая циклом переменная, длина
описания 19 байт:
________________________________________
| | | | | | |
|Тип и|Значе-|Значе-|Шаг=Z |K= |Номер |
|лите-|ние |ние | |номер |FOR в |
|ра |теку- |конеч-| |строки|стро- |
| |щее=X |ное=Y | | |ке+1 |
| |(5 б.)|(5 б.)|(5 б.)|(2 б.)|(1 б.)|
|_____|______|______|______|______|______|
Последний байт области переменных, как
указатель всегда, содержит значение #80
(128).
5. 8 Буфер редактора (E_LINE до
WORKSP-1)
В этой области размещается строка прог-
раммы или последовательность директив для
непосредственного выполнения во время их
ввода с клавиатуры. Вводимые символы копи-
руются в нижнюю часть экрана. После нажа-
тия <ENTER> компьютер проверяет верность
вводимого текста и предпринимает соот-
ветствующие действия.
5. 9 Буфер инструкции INPUT (WORKSP до
STKBOT-1)
В этот буфер первоначально вводятся
данные, считываемые командой INPUT и толь-
ко после нажатия <ENTER> следует их преоб-
разование. В этой области SPECTRUM также
выполняет некоторые операции, требующие
рабочей памяти (например, сцепление сим-
вольных переменных).
5. 10 Стек калькулятора (STKBOT до
STKEND-1)
Рабочая область системных подпрограмм,
выполняющих большинство арифметических
операций.
5. 11 Свободная область системы Бейсик
(STKEND+1 до SP)
Этот блок памяти свободен, но предназ-
начен для потребностей системы Бейсик. Ра-
бочие области с обоих концов этого блока
пополняются за его счет. Данные, размещен-
ные здесь могут подвергнуться уничтожению
без предупреждения. Пред началом действий,
требующих увеличения какого-нибудь из ра-
бочих блоков, SPECTRUM проверяет, останет-
ся ли в этом блоке хотя бы 80 свободных
байт на возможные потребности машинного
стека. Отрицательный результат проверки
сигнализируется сообщением 4. Адрес конца
этой области хранится в регистре процессо-
ра Z80, называемый указателем стека (SP) и
недоступен из системы Бейсика.
5. 12 Стек машинный (SP до ERR_SP)
Стек, используемый процессором Z80 для
текущего хранения различных данных, адре-
сов и т. п. Эта область абсолютно беспо-
лезна для программирования на Бейсике.
5. 13 Стек адресов возврата GOSUB
(ERR_SP+1 до RAMTOP)
Очередной стек, на этот раз предназна-
ченный для хранения номера строки и поло-
жения в ней инструкции GOSUB. Эти данные
необходимы для команды RETURN при неава-
рийном выходе из подпрограммы. Многоразо-
вое выполнение GOSUB или RETURN вызывает
сдвиг машинного стека, адресуемого через
ERR_SP на 3 байта вниз или вверх. Поэтому
при модификации блока рекомендуется особая
осторожность.
5. 14 Область свободной памяти
(RAMTOP+1 до P_RAMT)
Блок действительно свободной памяти и
безопасный в том смысле, что его содержи-
мое недоступно для системы Бейсик и может
быть модифицировано только по требованию
пользователя с помощью инструкции POKE.
Даже директива NEW не нарушает этой облас-
ти. В принципе она используется для хране-
ния программ в машинном коде или специфич-
ных данных , для которых переменные Бейси-
ка не подходят.
5. 15 Образы символов пользователя (UDG
до UDG+167)
После инициализации системы, этот блок
начинается с ячейки, имеющий адрес
RAMTOP+1=#FF58=65368, и кончается в
P_RAMT=#FFFF=65535. Адрес этого блока в
памяти можно получить, выполняя инструкцию
USR "A". Эта область служит для хранения
очертаний графических символов, определен-
ных пользователем. Определение единичного
символа состоит из восьми байт, описываю-
щих состояние каждой точки в знаковом поле
размером 8*8.
Для примера определим графический сим-
вол и разместим его в области UDG так,
чтобы он высвечивался после нажатия клави-
ши <O> в режиме G. Первым этапом является
проектирование формы нового знака в квад-
рате 8*8. В поле, предназначенном для зак-
рашивания, размещается 1, а в пустом 0.
Каждый, заполненный таким образом опера-
тор, рассматривается как 8-цифровое бинар-
ное число. Полученный набор 8-ми чисел
описывает форму проектируемого символа:
0 0 0 0 0 1 0 0 4
0 0 0 0 1 0 0 0 8
0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 0 0 60
0 1 0 0 0 0 1 0 66
0 1 0 0 0 0 1 0 66
0 0 1 1 1 1 0 0 60
0 0 0 0 0 0 0 0 0
Введем теперь его в компьютер. Проще
всего это сделать с помощью программы:
10 DATA 4, 8, 0, 60, 66, 66, 60, 0
20 FOR I = USR "0" TO USR "0" + 7
30 READ A: POKE T, A
40 NEXT I
После ее выполнения клавиша <O> в режи-
ме G выводит закодированный символ. В це-
почке символов он будет иметь код 158.
Данные в строке 10 можно подать также и в
двоичной форме вместо десятичной, исполь-
зуя функцию BIN. Это требует больше писа-
нины, но значительно облегчает все моди-
фикации, определенного нами образца.
168 байт области UDG позволяют хранить
до 21 различного нового символа. Их коды
размещаются в диапазоне от 144 (A) до 164
(U). После инициализации системы, этот
блок содержит образцы форм больших литер
латинского алфавита.
Другие статьи номера:
Похожие статьи:
В этот день... 19 ноября