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). После инициализации системы, этот блок содержит образцы форм больших литер латинского алфавита.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября