>
ПРИМЕНЕНИЕ АССЕМБЛЕРА ДЛЯ СОЗДАНИЯ БЫСТРОРАБОТАЮЩИХ ПРОГРАММ
предисловие
Известные книги, справочники и руководства по машинному языку процессора Z-80 используемого в компьютере "ZX-Spectrum" в основном ограничиваются описанием действий всех команд процессора и порядком применения этих команд на простейших примерах программ в машинных кодах. В лучшем случае приводятся программы для сложения чисел или им подобные.
Практика показывает, что конкретному пользователю, желавшему начать освоение машинного кода нужен немного другой подход. Нужна книга, которая поможет ему немедленно, сразу взяться за дело и почувствовать мгновенную отдачу от своих усилий. Одним словом, нужна простейшая практика и живая заинтересованность.
Как нам кажется, в основу этой книги положена весьма плодотворная идея -опереться на знание пользователем БЕЙСИКа и постепенно развивать эти знания в направлении машинного кода, шаг за шагом показывая как алгоритмы БЕЙСИКа переносятся на язык АССЕМБЛЕРа. Эта концепция очень хорошо укладывается в тот стиль работы, который "ИНФОРКОМ" ведет уже третий год на страницах "ZX-РЕВЮ" и в прочих своих книгах.
Нам также показалась очень привлекательной идея книги дать широкое представление конкретному программисту о возможности использования процедур, "зашитых" в ПЗУ для своей повседневной работы. Это может заинтересовать и тех, кто достаточно хорошо знает "АССЕМБЛЕР, но не имеет доступной информации об использовании процедур ПЗУ в своих программах.
Мы горячо благодарим нашего постоянного соавтора из г. Балашова Саратовской обл. В. Пашорина за прекрасный перевод этой нужной книги и, главное, за достойный выбор самой книги для перевода.
К сожалению, мы не могли бы сказать, что оригинал написан простым доступным языком, понятным каждому неспециалисту. Но мы очень хорошо потрудились над ее адаптацией. Оставив по сути без изменения структуру книги и ее фактическое содержание, мы полностью переработали всю методику подачи материала и надеемся, что сделали ее доступной для неподготовленного читателя, впрочем о том, как это удалось, судить будете Вы сами.
Поскольку сама книга фактически не является учебником по машинному кодированию, а служит практическим пособием для тех, кто пошел по этому пути, мы должны напомнить Вам о целесообразности приобретения нашего издания "Программирование в машинных кодах. Первые шаги, практикум. Справочник". По этой книге уже обучились тысячи пользователей и она пока продолжает оставаться лучшим из всего, что было написано на данную тему.
Для тех наших читателей, которые сейчас решают вполне естественный вопрос о целесообразности приобретения всего комплекта "ZX-РEВЮ-93", мы даем содержание книги, которая войдет в "РЕВЮ-93" полностью:
1. Вывод на экран.
2. Команды PLOT, DRAW, CIRCLE.
3. Счет очков в программах.
4. Случайные числа.
5. Опрос клавиатуры.
6. Перемещение объектов.
7. Музыкальные и звуковые эффекты.
8. Команды ATTR, SCREEN$, POINT.
9. Работа с принтером.
10. Разбор конкретного примера перевода игровой программы из БЕЙСИКа в машинный код.
1. ВЫВОД НА ЭКРАН
Создание программ в машинных кодах, выполняющих вывод информации на экран -утомительная задача, требующая значительных затрат рабочего времени. Тем не менее, это одна из наиболее важных задач. Даже очень хорошие программы проиграют многое, если информация, выводимая на экран при их выполнении, не вполне понятна или, хуже того, допускает неоднозначную трактовку. Перед созданием любой программы необходимо подумать о том, чтобы наглядность выводимой на экран информации была обеспечена на должном уровне.
На компьютере "ZX_SPECTRUM" можно создать 21 графический элемент, форма которых полностью определяется пользователем. Это так называемые символы графики пользователя (User Definable Graphics - UDG). Необходимо как можно полнее использовать эти символы в своих программах при выводе информации на экран. Например, при создании игровой программы типа "космических завоевателей" для получения отдельных фрагментов изображения экрана можно использовать те же символы, что используются для создания самих "завоевателей" или других объектов.
Для вывода информации на экран целесообразно использовать контрастные цвета. Не рекомендуется использовать вместе красный и розовый, желтый и белый и т.п. Благоразумно в программах использовать только черный и белый цвета, так как не все пользователи имеют цветные мониторы или цветные телевизоры.
Так как выводить информацию на экран необходимо при работе практически любой программы, то мы начнем нашу книгу с того, что рассмотрим в этой главе способы перевода команды БЕЙСИКа PRINT в машинный код.
Обычно БЕЙСИК-программа начинается с того, что определяются основные цветовые атрибуты, например:
10 PAPER 3: INK 1: BORDER 5
Затем эти атрибуты устанавливаются в системных переменных компьютера и становятся действующими. Делают это командой CLS. 20 CLS
Давайте попробуем сделать то же самое в машинном коде. Самой простой будет операция установления цвета бордюра. Она займет всего лишь 6 байтов в оперативной памяти.
Сначала в регистр A процессора заносится число 5 (оно означает зеленый цвет бордюра), а затем вызывается процедура ПЗУ, которая выполнит изменение этого цвета. Данная процедура называется BORDER и находится она в ПЗУ по адресу 229ВН (8859 DEC).
Процедура не только установит необходимый цвет окантовки экрана, но и передаст значение номера цвета в системную переменную BORDER (23624 DEC - 5С48Н). Для хранения номера цвета бордюра в этой системной переменной отведены 3 бита (с третьего по пятый) и, таким образом, всего могут быть установлены до 8 различных цветов. Оставшиеся биты в этой системной переменной используются для хранения цветовых атрибутов нижней части экрана (системного окна). Системное окно занимает как правило (не всегда) две нижние строки экрана, в которых Вы выполняете INPUT или редактирование программы. Биты 0...3 определяют номер цвета INK в системном окне, бит 6 отвечает за параметр BRIGHT, а бит 7 - за параметр FLASH.
Итак, программа в машинных кодах, эквивалентная команде БЕЙСИКа BORDER 5, будет выглядеть так, как показано на листинге 1.1 (Предполагается, что машинной код начинается с адреса, заданного директивой АССЕМБЛЕРа ORG).
Листинг 1.1
АДРЕС МАШ.КОД АССЕМБЛЕР КОММЕНТАРИЙ ORG 23760
23760 3Е 05 LD А,5 ;Установили в аккумуляторе число
; "5" - код зеленого цвета.
23762 CD 9В 22 CALL 8859 ;Вызов процедуры ПЗУ "BORDER".
23765 С9 RET ;Выход.
Выполнить установку цветов INK и PAPER немного сложнее и соответствующая программа в машинных кодах у нас займет уже не 6, а 13 байтов (она приведена на листинге 1.2).
За установку цветов PAPER и INK в основной части экрана отвечает системная переменная ATTR-P (23693 DEC = 5C8D Н). Поэтому установка этих цветов из машинного кода сводится к переключению битов в данной системной переменной, а раскладка этих битов такова:
7 6 5 4 3 2 1 0
Цвет PAPER Цвет INK
- Параметр BRIGHT
- Параметр FLASH
Если мы хотим из машинного кода дать команду, аналогичную PAPER 3; INK 1, то нам надо включить биты в системной переменной ATTR_P следующим образом:
7 6 5 4 3 2 1 0
0 + 0 + 0 + 16 + 8 + 0 + 0 + 1 = 25
Т.е. фактически нам надо было бы в ячейку памяти с адресом 23693 заслать число 25, например так:
LD (23693),25
Но такой команды, которая позволила бы заслать произвольное число в произвольную ячейку памяти компьютера у процессора Z-80 нет. Приходится немного комбинировать.
Сейчас у нас есть возможность познакомиться с интересным способом адресации в процессоре Z-80, который называется индексной адресацией. Дело в том, что в процессоре есть шестнадцатиразрядная регистровая пара IY, в которой может храниться какое-либо целое число от 0 до 65535. Работа компьютера "ZX-Spectrum" организована таким образом, что после включения его в сеть в этой регистровой паре устанавливается число 23610 (Это адрес системной переменной ERR_NR). И этим активно пользуются на практике. Есть неофициальная договоренность, что для работы с системными переменными используется эта регистровая пара. При этом не надо указывать адрес нужной Вам системной переменной, а достаточно указать "смещение", т.е. величину, на которую отстоит нужный Вам адрес от заранее установленного в регистре IY. Тогда вместо LD (23693),25 можно записать команду: LD (IY+83),25
Эта запись выглядит понятнее уже хотя бы потому, что все, кто программируют на "Спектруме" в машинных кодах, сразу мгновенно понимают: раз используется IY, значит здесь загружают какую-то системную переменную. А какую именно, они быстро определят, ОТКРЫВ таблицу системных переменных.
Вернемся к нашему примеру, см. листинг 1.2. Итак, в первой строчке мы установили необходимые цвета PAPER и INK.
Листинг 1.2
АДРЕС |
МАШ |
.КОД |
АССЕМБЛЕР |
|
|
|
ORG 23760 |
23760 |
FD |
36 53 19 |
LD (IY+83),25 |
23764 |
3E |
02 |
LD A,02 |
23766 |
CD |
01 16 |
CALL 5633 |
23769 |
CD |
6В 0D |
CALL 3435 |
23772 |
C9 |
|
RET |
АДРЕС МАШ.КОД
АССЕМБЛЕР ORG 23760 LD A,2 CALL 5633 LD A,65 RST 16 RET
КОММЕНТАРИЙ
Установили в системной переменной BORDER значения INK и PAPER. Подготовка к открытию канала 2. Открываем канал 2. Вызов процедуры CLS. Выход.
КОММЕНТАРИЙ
Подготовка к открыванию канала.
Открываем канал экрана.
Код символа "А".
Вызов процедуры печати символа.
Выход.
Листинг 1.4
КОММЕНТАРИЙ
Подготовка к открыванию канала.
Открываем канал экрана.
Код символа "H".
Вызов процедуры печати символа.
Код символа "E".
Вызов процедура печати символа.
Выход.
АССЕМБЛЕР ORG 23760 LD A, 2 CALL 5633 LD A,72 RST 16 LD A,69 RST 16 RET
Теперь мы должны дать команду CLS. Это тоже сделает за нас процедура, записанная в машинном коде ПЗУ. Данная процедура так и называется - CLS и находится по адресу 0D6BH = 3435 DEC.
Вместе с тем, Вы по-видимому обратили внимание на то, что перед вызовом этой процедуры вызывается еще одна процедура ПЗУ по адресу 5633 (1601Н). Это весьма важная процедура, она называется CHAN_OPEN, и мы будем еще не раз использовать ее при изучении материалов данной главы. Вызовом этой процедуры открывается канал вывода данных на экран - это канал под номером 2 и потому перед вызовом процедуры в регистр A загружается число 2. Когда Вы работали в БЕЙСИКе, то могли не думать о назначении каналов. Если же Вы выдаете информацию из машинного кода, то никто за Вас этого не сделает, а сделать это необходимо, иначе компьютер не поймет, куда надо подавать информацию.
Теперь Вы, уважаемые читатели, должны уметь устанавливать в машинном коде атрибуты экрана и выполнять очистку экрана. Давайте посмотрим как же нам напечатать на экране что-нибудь содержательное. Проще всего напечатать на экране какой-либо символ. В листинге 1.3 показан пример программы, которая напечатает символ "А" (символ имеет номер 65 DEC) в левом верхнем углу экрана с координатами позиции печати (0,0). Именно такие координаты текущей позиции устанавливаются после того, как отработает процедура CLS.
Если Вы хотите распечатать на экране какой-либо символ, то его код предварительно должен быть заслан в регистр A процессора, после чего должна быть выдана команда RST 16, что Вы и видите на листинге 1.3. По команде RST 16 процессор запустит процедуру ПЗУ PRINT_A_2, находящуюся по адресу 15F2H = 5618 DEC. Символ, код которого находится в аккумуляторе будет напечатан и осуществится переход к следующей позиции печати.
Если с этим Вам все понятно, то Вы без труда поймете работу программы 1.4, которая напечатает целое слово - "НЕ", поочередно засылая символы в аккумулятор и выдавая их командой RST 16.
Хорошо, что слово "НЕ" имеет только два символа, а как быть, если нужно напечатать длинное предложение? Понятно ведь, что кодировать печать длинной фразы по символам дело очень утомительное, к тому же необходим большой расход оперативной памяти - он в два раза больше, чем длина Вашего сообщения, поскольку на каждый символ еще нужна команда RST 16, занимающая байт.
Для решения этой проблемы существуют как минимум три пути.
Главная идея состоит в том, чтобы записать все символы выводимого сообщения в некоторый банк данных и считывать их оттуда по одному до тех пор, пока весь банк не будет исчерпан. Этот прием показан в Листинге 1.5 (версия 1).
В этом листинге Вы знакомитесь с двумя новыми регистровыми парами - ВС и DE. Как правило, пара ВС используется программистами для организации в ней разного рода счетчиков, а пара DE - для указания на какой-либо адрес в памяти компьютера. Регистры B,C,D и Е не обязательно должны использоваться парами, как это было с регистром IY. Они могут использоваться и как одиночные восьмибитные регистры для хранения целых чисел от 0 до 255.
Обратите внимание на пару операций
LD A,B OR C
Это очень быстрый, экономичный и к тому же общепринятый способ проверки ВС на ноль. Поскольку в регистре A у нас загружено содержимое регистра B, то результат операции OR C будет нулевым в том и только в той случае, если и B и C равны нулю.
Листинг 1.5 (Версия 1).
АДРЕС |
МАШ |
].КОД |
АССЕМБЛЕР КОММЕНТАРИЙ |
|
|
|
|
ORG 23760 |
|
23760 |
3E |
02 |
|
LD A,2 |
Подготовка к открыванию канала. |
23762 |
CD |
01 |
16 |
CALL 5633 |
открываем канал экрана. |
23765 |
11 |
E4 |
5С |
LD DE,DATA |
В регистровую пару DE загрузили адрес, в котором хранится наше текстовое сообщение. |
23768 |
01 |
07 |
00 |
LD ВС,7 |
В регистровой паре ВС организовали счетчик на 7 символов. |
LOOP |
|
|
|
|
|
23771 |
78 |
|
|
LD A^ |
Проверка не обнулился ли счет |
23772 |
В1 |
|
|
OR C |
чик символов в ВС? |
23773 |
C8 |
|
|
RET Z |
Выход, если он обнулялся. |
23774 |
1А |
|
|
LD A,(DE) |
Взяли в аккумулятор текущий символ из списка DATA. |
23775 |
D7 |
|
|
RST 16 |
Напечатали его на экране. |
23776 |
13 |
|
|
INC DE |
Перешли к очередному символу. |
23777 |
08 |
|
|
DEC ВС |
Уменьшили счетчик символов на 1. |
23778 |
18 |
F7 |
|
JR LOOP |
Перешли на метку LOOP для очередной проверки не закончился ли список печатаемых символов. |
DATA |
|
|
|
|
|
23779 |
72 |
69 |
76 |
80 32 77 69 |
Начиная с адреса 23779 мы храним |
сообщение "HELP ME".
Листинг 1.5 (Версия 2).
АДРЕС |
МАШ |
.КОД |
АССЕМБЛЕР КОММЕНТАРИЙ |
|
|
|
ORG 23760 |
|
23760 |
3E |
02 |
LD A,2 |
Подготовка к открыванию канала |
23762 |
CD |
01 16 |
CALL 5633 |
Открываем канал экрана. |
23765 |
11 |
DF 5С |
LD DE,DATA |
Адрес сообщения. |
23768 |
01 |
07 00 |
LD ВС,7 |
Длина сообщения - 7 символов. |
23771 |
CD |
3C 20 |
CALL 8252 |
Вызов процедуры ПЗУ PR_STRING. |
23774 |
C9 |
|
RET |
Выход. |
DATA |
|
|
|
|
23775 |
72 |
69 76 |
80 32 77 69 |
Сообщение "HELP ME". |
Обратите также внимание на то, что мы записали наше сообщение, начиная с адреса 23779. Но это совсем не обязательно. Можете хранить свои тексты где хотите, в любых адресах, удобных Вам. Важно только, чтобы в строке LD DE,DATA в регистровую пару DE был заслан истинный адрес начала Вашего сообщения ОТ 0 ДО 65535.
Второй вариант этой программы выглядит немного более простым. Если Вы заранее установили в регистровой паре DE адрес, с которого начинается Ваше сообщение, а в ВС -длину этого сообщения, то больше можно вообще ничего не делать, а вызвать процедуру ПЗУ под названием PR_STRING, которая сама напечатает за Вас это длинное сообщение. Процедура PR_STRING находится по адресу 8252 DEC = 203СН. Пример см. в Листинге 1.5 (версия 2).
Третий способ - самый мощный. Его применяют в тех случаях, когда у Вас заготовлено не одно сообщение, а много, т.е. Вы имеете целую таблицу сообщений, но заранее не знаете, какое когда придется печатать. В этом случае Вам хотелось бы выдавать на экран нужное сообщение указав только его номер. Именно так и поступают в абсолютном большинстве программ, написанных в машинных кодах. Именно так организовано и само ПЗУ, которое, как Вы знаете, хранит в себе много разных сообщений типа "Start tape and press key..." и выдает вам всякий раз именно то, которое надо.
Чтобы программа знала, где кончается одно сообщение и начинается другое, применяют специальный прием - к коду последнего символа сообщения прибавляют число 127, т.е. фактически в последнем символе каждого сообщения принудительно включают старший (7-ой) бит. Таким образом, символ, код которого > 127 является маркером конца сообщения. Теперь нетрудно создать программу для печати 1-го сообщения. Она просмотрит тексты, начиная с адреса, установленного в DE, отсчитает N-1 маркер и начнет печатать то, что найдет после него. Символы будут печататься по одному до тех пор, пока не будет найден N-ый маркер. Для печати последнего придется предварительно отнять от его значения число 127.
В листинге 1.5 приведен пример такой работы, но для простоты там принято, что у Вас есть не таблица, а только одно сообщение, заканчивающееся инвертированным символом (к коду символа прибавлено число 127).
Кстати, обратите внимание на то, что если числа, большие чем 27, являются маркерами конца сообщения, то очевидно нельзя допускать, чтобы в Ваших текстах были символы, код которых больше 27, т.е. символы блочной графики коды от 128 до 143) и символы графики пользователя (коды от 144 до 164) воспроизводить таким методом нельзя.
Похожая на эту, но более сложная процедура вывода на экран значений клавишных слов и сообщений об ошибках используется в ПЗУ компьютера. Стартовый адрес этой процедуры - 3082 -DEC = 0C0AH.
Вы можете и сами выдавать из машинного кода системные сообщения об ошибках, полный перечень которых обычно приводят в руководстве пользователя компьютера.
Так, они могут быть легко выведены на экран с помощью команды RST 8. Байт, следующий за этой командой, определяет какой вид сообщения необходимо вывести, например, если необходимо вывести на экран сообщение "K invalid colour", которое в перечне сообщений об ошибках является двадцать первым по счету, то необходимо записать:
RST 8
DEFB 19 (номер сообщения минус 2)
Причем нет необходимости давать команду RET после этого, так как сразу же после вывода на экран сообщения об ошибке осуществляется возврат в BASIC-систему.
Теперь мы можем приступить к рассмотрению способов вывода на экран символов или даже целых строк в заданную позицию на экране. В BASIC-программах это выполняется с помощью оператора PRINT AT, после которого записывается номер строки, номер столбца и, наконец, само сообщение, которое необходимо вывести на экран.
Для этого используются так называемые управляющие коды. Если Вы посмотрите любую таблицу символов ASCII, то увидите, что печатным символам соответствуют коды, начиная с 32 DEC (это символ "пробел". А коды с 0 до 31 является непечатными (т.е. не имеют закрепленной за ними литеры) и используются в качестве управляющих. Так, например, в "Спектруме" коды с 0 по 5 и с 24 по 31 вообще не используются, а с 6 по 23 -служат в качестве управляющих. (В компьютерах других систем это может быть и не так).
За координаты позиции печати отвечает код 22, он является аналогом БЕЙСИКовского оператора AT. К нашему счастью, команда RST 16 распознает код 22 как PRINT AT и использует следующие 2 байта как "x" и "y" координаты, задающие PRINT-позицию для вывода сообщения на экран. Программа 1.6 демонстрирует использование последовательности байтов DEFB 22 DEFB 3 DEFB 5
как аналог оператора
PRINT AT 3,5.
Совершенно так же можно применять коды 23 и 13 как аналоги операторов TAB и ENTER, соответственно.
Листинг 1.5 (Версия 3).
АДРЕС |
МАШ |
.КОД |
АССЕМБЛЕР КОММЕНТАРИЙ |
|
|
|
|
ORG 23760 |
|
23760 |
3E |
02 |
|
LD A,2 |
Подготовка к открыванию канала. |
23762 |
CD |
01 |
16 |
CALL 5633 |
Открываем канал экрана. |
23765 |
11 |
Е5 |
5С |
LD DE,DATA |
Адрес начала сообщения. |
LOOP |
|
|
|
|
|
23768 |
1A |
|
|
LD A,(DE) |
Взяли текущий символ. |
23769 |
CB |
7F |
|
BIT 7,А |
Проверяем его старший бит. |
23771 |
20 |
04 |
|
JR NZ,END |
Если он не нулевой, то это последний символ и мы переходим на метку END. |
23773 |
D7 |
|
|
RST 16 |
Иначе печатаем его на экране. |
23774 |
13 |
|
|
INC DE |
Перешли к очередному символу. |
23775 |
18 |
F7 |
|
JR LOOP |
Возврат на метку LOOP. |
END |
|
|
|
|
|
23777 |
CB |
BF |
|
RES 7,А |
Выключили старший бит последнего символа. |
23779 |
D7 |
|
|
RST 16 |
Напечатали последний символ. |
23780 |
C9 |
|
|
RET |
Выход DATA |
23781 |
72 |
69 |
76 |
80 32 77 197 |
Сообщение "HELP ME". |
Листинг 1.6
АДРЕС |
МАШ |
.КОД |
|
АССЕМБЛЕР КОММЕНТАРИЙ |
|
|
|
|
ORG 23760 |
|
23760 |
3E |
02 |
|
LD A,2 |
Подготовка к открыванию канала. |
23762 |
CD |
01 16 |
|
CALL 5633 |
Открываем канал экрана. |
23765 |
11 |
DF 5C |
|
LD DE,DATA |
Адрес начала сообщения. |
23768 |
01 |
0С 00 |
|
LD ВС,12 |
Длина сообщения с учетом управляющих |
23771 |
CD |
ЗС 20 |
|
CALL 8252 |
Вызов процедуры ПЗУ PR_STRING |
23774 |
C9 |
RET |
|
|
Выход DATA |
23775 |
22 |
|
|
DEFB 22 |
Код управления позицией печати |
23776 |
03 |
|
|
DEFB 3 |
Координата "Y=3" |
23777 |
05 |
|
|
DEFB 5 |
Координата "Х=5" |
23778 |
84 |
72 65 |
78 |
4В |
Текст сообщения "THANK YOU" |
23783 |
32 |
89 79 |
65 |
|
|
Листинг 1.7
АДРЕС |
МАШ |
.КОД |
АССЕМБЛЕР КОММЕНТАРИЙ |
|
|
|
|
ORG 23760 |
|
23760 |
3E |
02 |
|
LD A,2 |
Подготовка к открыванию канала. |
23762 |
CD |
01 |
16 |
CALL 5633 |
Открываем канал экрана. |
23765 |
11 |
E2 |
5С |
LD DE,DATA |
Адрес начала сообщения. |
23768 |
01 |
24 |
00 |
LD ВС,36 |
Длина сообщения с учетом управляющих |
23771 |
CD |
3C |
20 |
CALL 6252 |
Вызов процедуры ПЗУ PR_STRING |
23774 |
CD |
4D |
0D |
CALL 3405 |
Копирование ATTR-P в ATTR-Т. |
23777 |
C9 |
|
|
RET |
Выход DATA |
23778 |
22 |
04 |
07 |
17 02 |
Сообщение CAN YOU READ THIS с |
инплантированными в нем кодами управления координатой позиции печати и кодами управления цветовыми атрибутами.
С помощью управляющих кодов можно не только задавать координаты позиции печати, но и цвета и прочие атрибуты печатаемых символов. Для этого есть свои управляющие коды.
INK - код 16
PAPER - код 17 FLASH - код 18 BRIGHT - 19 INVERSE - 20 OVER - код 21
Программа 1.7 показывает как используются управляющие коды, соответствующие PAPER, INK, BRIGHT и т.д.
После использования временных цветов для вывода на экран сообщения необходимо вернуться к постоянным цветам для обеспечения дальнейшего вывода. Для режимов OVER и INVERSE это требование легко выполняется, так как команда RST 16 легко распознает их управляющие коды. Для изменения PAPER, INK, BRIGHT и FLASH, необходимо вызвать из ПЗУ процедуру (адрес 3405), которая копирует содержимое системной переменной ATTR-P (23693) в системную переменную ATTR-^23695).
(Продолжение следует)
Михайленко В.С., Турович А.К.