6.1. Использование подпрограмм в кодах при работе на Бейсике
Одним из приемов увеличения возможностей программы на Бейсике
является использование подпрограмм в кодах. Правда, этот путь
несколько половинчатый - почему бы сразу не писать всю программу на
ассемблере ? Поскольку Бейсик по-прежнему занимает много памяти, то и
эффективность этого способа сомнительна. Использовать подпрограммы в
кодах в Бейсике, пожалуй, целесообразно только при отсутствии
описанных в гл.5 инструментальных средств, а также в тех случаях,
когда Вы не хотите или не умеете писать программы в кодах, а улучшить
свою программу на Бейсике хочется. В последнем случае можно
использовать чьи-либо готовые подпрограммы в кодах.
Для подготовки подпрограммы в кодах с помощью Бейсика часто
используется такой прием: коды команд записываются в операторе DATA,
из которого затем в цикле читаются оператором READ и заносятся в
память оператором POKE.
Для того, чтобы зарезервировать достаточно места в памяти для
размещения подпрограмм, необходимо перед началом работы дать команду
CLEAR в непосредственном режиме Бейсика:
CLEAR B,A
где
B - количество байт, отводимых под символьные переменные;
A - адрес верхней границы памяти, отведенной для программы на
Бейсике.
Например, если начальный адрес подпрограммы в кодах равен 30000, то
можно ввести оператор CLEAR 250,&O30000 . После исполнения этого
оператора транслятор с языка Бейсик использует только область ОЗУ,
расположенную до адреса 30000. А с адреса 30000 могут быть расположены
подпрограммы в машинных кодах.
Две команды Бейсика позволяют записывать и читать с магнитофона
участки ОЗУ, в которых могут размещаться подпрограммы в кодах или
таблицы изображений (спрайтов).
BSAVE"имя",начало,конец
По этой команде область ОЗУ с указанным начальным и конечным
адресом записывается на магнитофон в виде файла.
Программа с МЛ может быть загружена в ОЗУ и запущена на выполнение
командой Бейсика:
BLOAD"имя",R,адрес
Если в данной команде отсутствует первая запятая с буквой "R", то
произойдет только загрузка программы в ОЗУ с указанного адреса.
Обычно, чтобы не возиться с загрузкой множества файлов,
подпрограмму в кодах не записывают отдельно, а так и хранят в
программе на Бейсике в операторе DATA. При выполнении программы коды
переписываются в ОЗУ, потом задается адрес запуска подпрограммы и она
вызывается в любом нужном месте программы на Бейсике.
Здесь будут рассмотрены два примера использования в программах на
языке Бейсик подпрограмм в машинных кодах.
Пример 1. Вывод спрайта и управление его движением.
Этот пример аналогичен второму примеру из п.5.3.3. Для вывода и
стирания спрайта используются подпрограммы в кодах, а управление
движением спрайта осуществляется программой на Бейсике.
Подпрограммы вывода и стирания спрайта аналогичны приведенным в
п.5.3.3:
; вывод спрайта на экран
035000 012700 MOV #MEN,R0
035002 035070
035004 011501 MOV (R5),R1 ;адрес вывода спрайта
035006 012002 MOV (R0)+,R2
035010 012003 MOV (R0)+,R3
035012 010204 A: MOV R2,R4
035014 010146 MOV R1,-(SP)
035016 112021 B: MOVB (R0)+,(R1)+
035020 077402 SOB R4,B
035022 012601 MOV (SP)+,R1
035024 062701 ADD #100,R1
035026 000100
035030 077310 SOB R3,A
035032 000207 RTS PC ;выход из подпрограммы
; чистка спрайта на экране
035034 012700 MOV #MEN,R0
035036 035070
035040 011501 MOV (R5),R1 ;адрес стирания спрайта
035042 012002 MOV (R0)+,R2
035044 012003 MOV (R0)+,R3
035046 010204 C: MOV R2,R4
035050 010146 MOV R1,-(SP)
035052 105021 D: CLRB (R1)+
035054 077402 SOB R4,D
035056 012601 MOV (SP)+,R1
035060 062701 ADD #100,R1
035062 000100
035064 077310 SOB R3,C
035066 000207 RTS PC ;выход из подпрограммы
; спрайт, закодированный в формате ГРЕД
035070 MEN: .#2.#12.#1640.#1700.#140300.#37774.#1703
.#1700.#1700.#6060.#6060
035116 .#36074
В отличие от примера п.5.3.3, где операции вывода и стирания
спрайта были встроены в программу, здесь они оформлены в виде
подпрограмм, которые можно вызывать функцией Бейсика USR. Выход из
подпрограммы осуществляется, как обычно, командой RTS PC.
Одновременно в программе могут быть определены 10 различных функций
USR0..USR9. В данном примере мы используем только две подпрограммы
(соответственно, функции USR0 и USR1).
Функция USR позволяет передать подпрограмме в кодах один параметр и
вернуть одно значение того же типа. Функция USR помещает в R5 адрес
передаваемого параметра, а в R3 - его тип (единица в 15-м разряде
означает символьную строку, информация о других типах хранится в
младшем байте R3: -1 - целый, 0 - вещественный двойной точности, 1 -
вещественный одинарной точности; если аргумент - символьная строка, то
в качестве аргумента передаются два слова - длина и адрес строки). В
данном примере мы передаем подпрограммам адрес ОЗУ экрана, куда нужно
вывести (или где стереть) спрайт. Поскольку адрес будет размещаться в
переменной целого типа, анализировать R3 нет нужды.
Отметим также, что в п.5.3.3 "по ходу действия" в R5 сохранялось
значение R1, здесь же мы R1 сохраним в стеке, чтобы не испортить адрес
аргумента.
Подпрограммы и закодированный спрайт мы разместим с адреса 35000.
Тогда перед набором программы (или загрузкой ее с магнитной ленты)
необходимо выполнение оператора CLEAR ,&О35000. Этот оператор можно
вставить первой строкой в программу, чтобы он выполнялся
автоматически, но вот беда - не все экземпляры БК-0010-01 отработают
его правильно. Это связано с различиями версий Бейсика в ПЗУ БК разных
лет выпуска.
Для того, чтобы автоматизировать ввод подпрограмм, их коды мы
разместим в операторе DATA, откуда потом в цикле будем читать и
переписывать по адресам ОЗУ, начиная с 35000.
10 DATA &O012700,&O035070,&O011501,&O012002,&O012003,&O010204,&O010146
15 DATA &O112021,&O077402,&O012601,&O062701,&O100,&O077310,&O207
20 DATA &O012700,&O035070,&O011501,&O012002,&O012003,&O010204,&O010146
25 DATA &O105021,&O077402,&O012601,&O062701,&O100,&O077310,&O207
30 DATA 2,&O12,&O1640,&O1700,&O140300,&O37774,&O1703
35 DATA &O1700,&O1700,&O6060,&O6060,&O36074
40 ?CHR$(140);CHR$(140) 'инициализируем экран
50 FOR A%=&O35000 TO &O35116 STEP 2% 'записываем подпрограммы в ОЗУ
60 READ D%
70 POKE A%,D%
80 NEXT A%
90 DEF USR0=&O35000 'задаем адрес подпрограммы вывода спрайта
95 DEF USR1=&O35034 'задаем адрес подпрограммы стирания спрайта
100 S%=&O56036 'начальный адрес ОЗУ, где располагается спрайт
110 L%=USR0(S%) 'выводим спрайт
115 FOR L%=0% TO 150% 'задержка
116 NEXT
117 L%=USR1(S%) 'стираем спрайт
120 I%=PEEK(&O177662) 'смотрим, какая клавиша была нажата
130 IF I%=&O10 THEN IF S% MOD 64% <> 0% THEN S%=S%-1% 'влево
140 IF I%=&O31 THEN IF S% MOD 64% < &O76 THEN S%=S%+1% 'вправо
150 IF I%=&O32 THEN IF S%>&O43000 THEN S%=S%-&O200 'вверх
160 IF I%=&O33 THEN IF S%<&O76000 THEN S%=S%+&O200 'вниз
170 GOTO 110
Строки 50 - 80 производят загрузку команд и данных в область памяти
с адреса 35000 по 35116.
Оператор DEF (строки 90-95) определяет подпрограммы в машинных
кодах под именем USR0 и USR1 и задает их начальный адрес.
Текущее значение адреса спрайта в ОЗУ экрана хранится в целой
переменной S%.
В строке 120 переменной I% присваивается код нажатой клавиши, в
зависимости от которого в строках 130 - 160 изменяется адрес спрайта
S%.
Начальная установка экрана (строка 40) необходима для того, чтобы
привести экран в исходное состояние, когда верхний левый угол экрана
соответствует адресу 40000.
Пример 2:
10 DATA &O13701,&O35102,&O12737,&O100,&O177716,&O13700,&O35100
12 DATA &O77001,&O12737,0,&O177716,&O13700,&O35100,&O77001,&O77115
14 DATA &O12702,&O400,&O77201,&O207
20 FOR A%=&O35000 TO &O35044 STEP 2
30 READ B%
40 POKE A%,B%
50 NEXT A%
60 DEF USR0=&O35000
70 DATA 128,128,112,128,99,640,128,128,112,128,99,128,128,128
75 DATA 94,128,99,128,128,256,112,128,99,128,112,640
80 FOR C%=1 TO 13
90 READ T%,D%
100 POKE &O35100,T%
110 POKE &O35102,D%
120 I%=USR0(I%)
130 NEXT C%
Программа на Бейсике, приведенная в этом примере, использует
подпрограмму в машинных кодах для получения мелодии.
Строки 10-60 подготавливают в памяти, начиная с адреса 35000,
подпрограмму в машинных кодах.
Вся мелодия состоит из звуков. Количество звуков равно количеству
пар чисел, перечисленных в строках 70-75. В каждой паре чисел первое
число задает тональность, а второе - длительность звука.
Строки 80-130 "исполняют" мелодию.
6.2. Использование вещественной арифметики Бейсика
при программировании в кодах
Вы уже знаете, что в системе команд процессора БК нет команд работы
с вещественными (действительными) числами. Как в Бейсике, так и в
Фокале работа с вещественными числами организуется чисто программно. В
таком случае, почему бы не использовать записанные в ПЗУ БК
подпрограммы, если надо производить какие-либо вычисления ?
Использование подпрограмм вещественной арифметики Фокала описано в
[15]. Здесь мы опишем использование арифметики Бейсика [8]. Сразу же
заметим, что формат вещественного числа в Бейсике и Фокале различен.
Учтите также, что применение описываемого здесь метода сделает
программу непереносимой - она уже не сможет работать на БК-0010 с
Фокалом или на БК-0010-01 при включенном блоке МСТД (равно как и
программы, использующие Фокал, не будут работать с Бейсиком). Хорошим
выходом было бы использование стандартных подпрограмм (из программного
обеспечения Электроники-60) или эмуляторов вещественной арифметики, но
это доступно, пожалуй, только профессиональным программстам,
использующим ЭВМ более высокого класса в качестве инструментальной.
Что же касается использования подпрограмм Бейсика, то платой за это
будет 2К памяти, так как область ОЗУ ниже адреса 4000 используется
Бейсиком для своих рабочих переменных и стека.
Все расчеты в Бейсике производятся с вещественными числами двойной
точности. Если в программе на Бейсике используются числа одинарной
точности, то перед вычислениями они все равно преобразуются к двойной.
Каков же формат вещественного числа в Бейсике ?
Числа двойной точности занимают в памяти 4 слова (8 байт). При этом
старший разряд 1-го слова (63-ий разряд числа) - знак числа, разряды
7-14 (разряды 55-62 числа) - порядок (p), а остальные 6 разрядов 1-го
слова и 2-ое, 3-е, 4-е слова (разряды 0-54 числа) - мантисса (М)
(рис.26).
Тогда значение числа N определяется по формуле:
p-201 -1 -2 -3 -54 -55 p-201
N=(M+1) 2 =(1+2 a +2 a +2 a + ... +2 a +2 а ) 2 ,
54 53 52 1 0
где a - значение i - го бита числа (0 или 1).
i
Число 201 -восьмеричное, остальные - десятичные.
│ X (адрес числа) │ X+2 │ X+10
│ │ │
│63 р а з р я д ы │ ч и с л а 0│
├─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┼─┬─┬─┬─┬─┬─ - - - ───┬─┬─┬─┬─┬─┤
│ порядок (p) │ м а н т и с с а (M) │
├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┼─┴─┴─┴─┴─┴─ - - - ───┴─┴─┴─┴─┴─┤
│15 разряды слова 2 1 0│ │
│ 1-ое слово (2 байта) │ 2-ое, 3-е и 4-ое слова(6 байт)│
Рис.26. Представление числа двойной точности
Как же перевести число из привычного для нас десятичного вида в
двоичное представление числа двойной точности ?
Для этого берется исходное число и делится на 2 до тех пор, пока
его целая часть не будет равна 1.
Если исходное число меньше 1, то вместо деления производится
умножение на 2 до тех пор, пока целая часть не станет равна 1. Затем
дробная часть числа переводится в двоичный код - мантисса готова. 201
(восьмеричное) плюс (или минус, если производилось умножение)
количество делений или умножений на 2 - получим порядок числа.
Осталось "скомпоновать" число: последовательно слева направо
записываются знак (0 - для знака "+", 1 - для знака "-"), порядок,
мантисса. Остальные биты мантиссы заполняются нулями или мантисса
укорачивается справа так, чтобы общая длина числа равнялась 64 битам.
Рассмотрим несколько примеров перевода десятичных чисел в двоичные
числа двойной точности:
Пример 1: Исходное число: 9.5 . Делим на 2:
9.5
4.75 - результат после 1-го деления:
2.375 - после 2-го деления;
1.1875 - после 3-го деления.
Дробная часть числа, равная 0.1875 переводится в двоичный код
посредством последовательного умножения на 2. При этом если после
умножения число стало больше 1, то целая 1 отбрасывается.
0.1875 - умножается на 2;
0.375 - умножается на 2;
0.75 - умножается на 2:
1.5 - отбрасывается 1 и умножается на 2:
1 - все.
Тогда двоичный код мантиссы - 0011 (последовательно сверху вниз
переписывается первый столбец цифр, кроме первого 0). Было произведено
3 деления на 2, поэтому порядок числа равен 201 + 3 = 204 (числа
восмеричные) или 10000100 (двоичное). Осталось "скомпоновать" число:
так как число положительное, то 63-ий бит равен 0, тогда число имеет
следующий вид в двоичном коде:
0 10000100 0011 000000000000000000000000000000000000000000000000000.
Если X - адрес числа, то код этого числа сохраняется по словам памяти
следующим образом:
Адреса: Содержимое:
X 41030 (восьмеричное)
X+2 0
X+4 0
X+6 0
Пример 2: Исходное число: -13.25. Отмечаем, что оно отрицательное,
и все остальные операции проделываем с его абсолютным значением. Делим
на 2:
13.25
6.625
3.3125
1.65625
Берем дробную часть числа 0.65625 и переводим в двоичный код:
0.65625
1.3125
0.625
1.25
0.5
1
Получаем 10101. Порядок равен 201+3=204 (10000100).
Тогда число в двоичном коде будет равно:
1100001001010100000000000000000000000000000000000000000000000000
или четыре слова: 141124,0,0,0 в восьмеричном виде.
Пример 3: Исходное число: 0.0234375. Умножаем на 2:
0.0234375
0.046875
0.09375
0.1875
0.375
0.75
1.5
Переводим дробную часть числа 1.5 равную 0.5 в двоичный код: это будет
1. Порядок равен 201-6=173 (числа восьмеричные). Знак - 0 ("+"). Вид
числа в двоичном коде:
0011110111000000000000000000000000000000000000000000000000000000
или четыре слова: 36700,0,0,0 в восьмеричном виде.
Как же теперь использовать наши умения ? Сначала надо поближе
познакомиться с тем, как Бейсик транслирует свою программу.
Исходная программа на Бейсике после ее запуска командой RUN
преобразуется в последовтельность адресов подпрограмм, реализующих
соответствующие операторы Бейсика, и исходных данных: констант,
адресов переменных и так далее [8]. Эти подпрограммы, как и сам
транслятор, делающий такое преобразование, зашиты (записаны) в ПЗУ.
После того, как указанная последовтельность (ее называют "шитым
кодом") получена в ОЗУ, в регистр R4 помещается адрес начала
последовательности, и командой "JMP @(R4)+" начинается обращение к
подпрограмме, адрес начала которой записан в указанной
последовательности первым. Передача управления от одной подпрограммы к
другой осуществляется также по команде "JMP @(R4)+" , содержащейся в
конце каждой подпрограммы.
Если в программе на языке ассемблера программисту необходимо
получить значение какой-либо функции (или арифметической операции), то
он может организовать обращение к готовым подпрограммам, зашитым в
ПЗУ. Далее под словом "операция" подразумевается арифметическая
операция или функция, а под словом "операнд" - операнд арифметической
операции или аргумент функции.
В таблице 19 приводится список адресов подпрограмм, при обращении к
которым вычисляется результат соответствующей функции (или
арифметической операции).
Операнды и результаты операций - числа двойной точности.
Таблица 19. Адреса подпрограмм Бейсика
┌─────────────────────────┬───────────────┬───────────────┐
│ Арифметические операции │ Адреса │ Количество │
│ и функции │ подпрограмм │ операндов │
├─────────────────────────┼───────────────┼───────────────┤
│ + (сложение) │ 167144 │ 2 │
│ - (вычитание) │ 167124 │ 2 │
│ / (деление) │ 170776 │ 2 │
│ * (умножение) │ 170210 │ 2 │
│ SQR │ 171350 │ 1 │
│ SIN │ 173614 │ 1 │
│ COS │ 173566 │ 1 │
│ TAN │ 174306 │ 1 │
│ ATN │ 174434 │ 1 │
│ EXP │ 171762 │ 1 │
│ LOG │ 173052 │ 1 │
│ FIX │ 176212 │ 1 │
│ INT │ 176340 │ 1 │
│ RND │ 175176 │ 1 │
│ подпрограмма преобразо- │ 166760 │ 1 │
│ вания результата в │ │ │
│ целый тип │ │ │
└─────────────────────────┴───────────────┴───────────────┘
Необходимо помнить, что для нормальной работы подпрограмм,
указанных в таблице 19, область памяти с адресами от 2000 до 4000
должна быть свободной (эта область - область системных переменных
Бейсика).
Предлагаем Вашему вниманию небольшую подпрограмму, которая может
облегчить Вам вызов нужных подпрограмм Бейсика.
Для вызова нужной подпрограммы в регистрах должны быть подготовлены
следующие данные:
R0 - число операндов (1 или 2);
R1 - адрес первого операнда;
R2 - адрес второго операнда (для операций с двумя операндами.
При операциях с одним операндом значение несущественно);
R3 - адрес подпрограммы операции (из табл.19);
R5 - адрес результата.
Эта вспомогательная подпрограмма работает аналогично транслятору с
Бейсика после команды RUN - формирует требуемый для вызова нужной
подпрограммы шитый код и передает ему управление.
Последовательность адресов подпрогрмм и данных (шитый код)
начинается с адреса A.
FUN: MOV R0,-(SP) ; сохранение
MOV R1,-(SP) ; содержимого
MOV R2,-(SP) ; регистров
MOV R3,-(SP) ; в стеке;
MOV R4,-(SP) ;
MOV R5,-(SP) ;
MOV #A,R4 ; последовательность адресов
; начинается с адреса А;
MOV #156170,(R4)+ ; адрес подпрограммы пересылки в стек;
MOV R1,(R4)+ ; адрес первого операнда;
CMP R0,#1 ; если операция с одним операндом,
BEQ C ; то идти на метку C;
MOV #156170,(R4)+ ; засылка в стек второго операнда;
MOV R2,(R4)+ ; адрес второго операнда;
C: MOV R3,(R4)+ ; адрес нужной подпрогрммы записы-
; вается в последовательность адресов;
CMP R3,#166760 ; если это не подпрограмма перевода
BNE G ; вещественного в целое, идти на G;
MOV #156350,(R4)+ ; подпрограмма пересылки слова из стека
BR D ; (результат целого типа);
G: MOV #156334,(R4)+ ; либо пересылка вещественного числа
D: MOV R5,(R4)+ ; из стека по адресу, указанному в R5;
MOV #B,(R4)+ ; организовать выход из шитого кода;
MOV #A,R4 ; запустить шитый код на выполнение;
JMP @(R4)+ ;
B: MOV (SP)+,R5 ; восстановление
MOV (SP)+,R4 ; содержимого
MOV (SP)+,R3 ; регистров
MOV (SP)+,R2 ; из стека
MOV (SP)+,R1 ;
MOV (SP)+,R0 ;
RTS PC ; возврат из подпрограммы
A: .+22
По команде "MOV #156170,(R4)+" в эту последовательность
записывается адрес подпрограммы, производящей пересылку значения
переменной в стек, а по команде "MOV R1,(R4)+" - адрес самой
переменной, указанный в R1.
Аналогично засылается в стек второй операнд, если нужен.
После выполнения любой арифметической подпрограммы результат
получается в стеке. Его необходимо оттуда извлечь и переслать по
адресу, заданному в R5. Для этого используется подпрограмма 156334,
пересылающая вещественное число (4 слова), либо 156350, пересылающая
одно слово, если результат целый.
Пример цепочечных вычислений:
; Вычисляем выражение (4+7)*3.0625-1.25
MOV #2,R0 ;двухоперандная команда
MOV #AR1,R1 ;первое слагаемое
MOV #AR2,R2 ;второе слагаемое
MOV #167144,R3 ;адрес подпрограммы сложения
MOV #REZ,R5 ;адрес результата
JSR PC,FUN ; складываем
MOV R5,R1 ;результат используем
;как первый сомножитель
MOV #AR3,R2 ;второй сомножитель
MOV #170210,R3 ;адрес подпрограммы умножения
JSR PC,FUN ; умножаем (результат там же - в REZ)
MOV R5,R1 ;результат используем как уменьшаемое
MOV #AR4,R2 ;вычитаемое
MOV #167124,R3 ;адрес подпрограммы вычитания
JSR PC,FUN ; вычитаем
; Печатаем полученный результат на дисплей
ADD #10,R5 ;засылаем результат в стек;
MOV -(R5),-(SP)
MOV -(R5),-(SP)
MOV -(R5),-(SP)
MOV -(R5),-(SP)
JSR PC,@#164710 ;вызываем подпрограмму перевода
;числа в символьную строку;
ADD #4,SP ;восстанавливаем стек;
MOV #3027,R1 ;адрес символьной строки
MOV #20000,R2 ;ограничитель строки - пробел
EMT 20 ;печатаем сформированную строку
; Аргументы:
AR1: .#40600.#0.#0.#0 ;4.0
AR2: .#40740.#0.#0.#0 ;7.0
AR3: .#40504.#0.#0.#0 ;3.0625
AR4: .#40240.#0.#0.#0 ;1.25
REZ: .#0.#0.#0.#0 ;результат
6.3. Использование системных переменных МОНИТОРа БК
Область ОЗУ в диапазоне адресов от 0 до 377 МОНИТОР БК использует
для хранения своих рабочих переменных (используются те адреса, которые
не заняты векторами прерывания, см.п.4.4.3). В этих переменных
указываются текущие режимы работы устройств, например, режимы работы
дисплея. Зная о назначении тех или иных переменных, можно добиться
таких эффектов, которые невозможны при "штатном" использовании
системного программного обеспечения.
Рассмотрим несколько примеров использования системных ячеек.
Примеры даны на Бейсике и на языке ассемблера.
Таблица 20. Системные переменные
┌─────┬─────┬─────────────────────────────────────────────────┐
│Адрес│Длина│ Назначение │
│ │байт │ │
├─────┼─────┼─────────────────────────────────────────────────┤
│ 040 │ 1 │ Режим 32/64 (0 - режим "64", 377 - режим "32") │
│ 041 │ 1 │ Инверсия экрана (0 - выкл., 377 - вкл.) │
│ 042 │ 1 │ Режим расширенной памяти (0 - выкл., 377 - вкл.)│
│ 043 │ 1 │ Регистр (0 - LAT, 200 - РУС ) │
│ 044 │ 1 │ Подчеркивание (0 - выкл., 377 - вкл.) │
│ 045 │ 1 │ Инверсия символа (0 - выкл., 377 - вкл.) │
│ 046 │ 1 │ Режим ИСУ (0 - выкл., 377 - вкл.) │
│ 047 │ 1 │ Режим БЛР (0 - выкл., 377 - вкл.) │
│ 050 │ 1 │ Режим ГРАФ (0 - выкл., 377 - вкл.) │
│ 051 │ 1 │ Режим ЗАП (0 - выкл., 377 - вкл.) │
│ 052 │ 1 │ Режим СТИР (0 - выкл., 377 - вкл.) │
│ 053 │ 1 │ Режим 32/64 в служебной строке (0-"64",377-"32")│
│ 054 │ 1 │ Подчеркивание в служ. строке (0-выкл., 377-вкл.)│
│ 055 │ 1 │ Инверсия служ. строки (0 - выкл., 377 - вкл.) │
│ 056 │ 1 │ Гашение курсора (0 - выкл., 377 - вкл.) │
│ 104 │ 1 │ Код последнего введенного символа │
│ 112 │ 10 │ Положения табуляторов (побитно при режиме "64") │
│ 126 │ 2 │ Адрес буфера программируемого ключа К10 │
│ 130 │ 2 │ Адрес буфера программируемого ключа К1 │
│ 132 │ 2 │ Адрес буфера программируемого ключа К2 │
│ 134 │ 2 │ Адрес буфера программируемого ключа К3 │
│ 136 │ 2 │ Адрес буфера программируемого ключа К4 │
│ 140 │ 2 │ Адрес буфера программируемого ключа К5 │
│ 142 │ 2 │ Адрес буфера программируемого ключа К6 │
│ 144 │ 2 │ Адрес буфера программируемого ключа К7 │
│ 146 │ 2 │ Адрес буфера программируемого ключа К8 │
│ 150 │ 2 │ Адрес буфера программируемого ключа К9 │
│ 153 │ 1 │ Тип операции в режиме ГРАФ (0 - СТИР, 1 - ЗАП) │
│ 154 │ 2 │ Унитарный код положения графического курсора │
│ 160 │ 2 │ Абсолютный адрес курсора в ОЗУ экрана │
│ 162 │ 2 │ Константа смещения одного алфавитно-цифрового │
│ │ │ символа относительно другого │
│ 164 │ 2 │ Длина ОЗУ экрана в символах │
│ 176 │ 2 │ Координата Х последней графической точки │
│ 200 │ 2 │ Координата Y последней графической точки │
│ 202 │ 2 │ Начальный адрес ОЗУ экрана │
│ 204 │ 2 │ Адрес начала информационной части экрана │
│ │ │ минус 40000 │
│ 206 │ 2 │ Длина ОЗУ экрана в байтах │
│ 210 │ 2 │ Длина информационной части экрана │
│ 212 │ 2 │ Код цвета фона на экране │
│ 214 │ 2 │ Код цвета символа на экране │
│ 216 │ 2 │ Код цвета фона в служебной строке │
│ 220 │ 2 │ Код цвета символа в служебной строке │
│ 260 │ 2 │ Адрес подпрограммы, выполняемой при прерывании │
│ │ │ по вектору 60. Если 0, то ничего не выполняется │
│ 262 │ 2 │ Если 0, то код клавиши "ВК" равен 12, иначе 15 │
│ 264 │ 2 │ Начальный адрес загруженной программы │
│ 266 │ 2 │ Длина загруженной программы │
└─────┴─────┴─────────────────────────────────────────────────┘
Примечание: В буфере программируемого ключа записана длина
соответствующего ключа (в символах), далее - сами символы.
Пример 1. Печать красными буквами на синем фоне:
10 POKE &O214,-1 MOV #177777,@#214 ;красный цвет;
20 POKE &O212,&O52525 MOV #52525,@#212 ;синий фон;
30 ?"Приветик!" MOV #TXT,R1 ;печатаем
CLR R2 ;текст
EMT 20 ;
HALT
TXT: .A:Приветик!
Пример 2. Запись символов в служебную строку:
10 POKE &O160,PEEK(&O204)+&O36100 MOV @#204,@#160
ADD #36100,@#160
20 ? "текст" MOV #TXT,R1
CLR R2
EMT 20
HALT
TXT: .A:текст
Примечание: эта последовательность проходит только в программе;
если попытаться проделать ее в непосредственном режиме, то после
оператора POKE ... Бейсик напишет "Ок" в служебной строке и курсор
вернется на свое прежнее место.
Пример 3. Печать "в столбик":
10 X=PEEK(&O162) MOV @#162,R3 ;запомнить старый режим
20 POKE &O162,&O100 MOV #100,@#162
30 ?"текст" MOV #TXT,R1
CLR R2
EMT 20
40 POKE &O162,X MOV R3,@#162 ;восстановить режим
HALT
TXT: .A:текст