В одном из номеров "Вычислительной техники" как-то прозвучал призыв к создателям Вильнюсской версии БЕЙСИКа рассказать о возможности использования подпрограмм БЕЙСИКа в программах пользователя, написанных в машинных кодах. Однако до сих пор (а прошёл уже год) никто на этот призыв не откликнулся. По-видимому, исследованием БЕЙСИКа придётся заниматься самим пользователям БК.
Д.Ю. Усенков (Москва)
О МОНИТОРЕ И ВИЛЬНЮССКОЙ ВЕРСИИ БЕЙСИКА
Предлагаю вниманию читателей несколько своих наблюдений.
1. При нажатии клавиши на клавиатуре БК код, посылаемый этой клавишей в компьютер, зависит только от положения клавиши на клавиатуре. Все преобразования, приводящие к получению кодов символов (русские-латинские; заглавные-строчные, буквы-полуграфика и т.д.), происходят в программе-драйвере клавиатуры. Так, АР2 - переключатель, указывающий БК какой из двух векторов прерывания выбрать: @#60 или @#274. Клавиши РУС и ЛАТ обрабатываются драйвером по прерыванию @#60, управляя записью кода-маски в ячейку ОЗУ @#438 (ЛАТ - 0; РУС - 2008). Клавиши ЗАГЛ и СТР работают без участия программы-драйвера, но, по сути, выполняют те же самые действия. После записи числа в ячейку @#438 все другие коды символов-букв устанавливаются по этому числу, как по маске, таким образом преобразуюсь в символы русских или латинских букв в зависимости от режима клавиатуры. Основываясь на этом свойстве БК, я написал небольшую программу для БЕЙСИКа. Привожу здесь её текст в восьмеричных кодах:
010737 |
002100 |
062737 |
000012 |
002100 |
000000 |
105703 |
002026 |
010046 |
010146 |
011501 |
005701 |
001407 |
002403 |
012701 |
000240 |
000404 |
012701 |
000200 |
000401 |
005001 |
110137 |
000043 |
005000 |
005037 |
000222 |
004737 |
110572 |
012601 |
012600 |
000207 |
000000 |
Адрес программы может быть любым. Обращение к ней производится через USR-функции. Программа написана так, что после её загрузки с м/ф командой BLOAD "<имя>" R (обязательно с R!) оператор DEF USR не требуется. Используется функция USR0. Если же вы хотите задействовать USR-функцию с другим номером, измените выделенные подчёркиванием коды с 2100 на 2102 (для USR1), 2104 (для USR2) и т.д. При обращении аргумент функции обязательно должен быть целым числом (типа %). Исходный режим до запуска программы должен быть ЛАТ ЗАГЛ, тогда аргумент функции, равный 1, даёт переключение в режим РУС ЗАГЛ; -1 - в режим РУС СТР; 0 - в исходный режим ЛАТ ЗАГЛ. Чтобы не происходило путаницы, переход в режимы РУС ЗАГЛ и РУС СТР лучше делать из исходного режима (не сразу из РУС СТР в РУС ЗАГЛ или наоборот, а сначала выполнив USR0). Эта программа - один из немногих, видимо, способов управлять режимом работы клавиатуры непосредственно из программы на БЕЙСИКе или в кодах, так как БЕЙСИК не позволяет записывать числа непосредственно в старший байт ячейки ОЗУ. Думаю, что эта программа будет очень полезна для Бейсик-программ, связанных с вводом и обработкой текстов или просто при вводе ответа на запрос машины типа "Да" или "Нет". При этом уменьшается вероятность ошибки пользователя-новичка при работе с этой программой, упрощается сама программа (становятся ненужными различные "ухищрения" для выявления возможных ошибок такого типа и "многобуквенные" инструкции с AND или OR в операторах для отработки и русских и латинских букв в ответе пользователя) и не надо "возиться" с переключением регистров.
2. При написании программ в кодах для выяснения режима работы клавиатуры и дисплея БК (РУС/ЛАТ, инверсия экрана, инверсия или подчёркивание символов и т.п.) обычно пользуются функцией ЕМТ 34, которая записывает в R0 слово состояния дисплея БК. После этого производя тестирование того или иного бита R0, можно определить включён или выключен тот или иной режим. (Кстати, выяснять значение первого и последнего бита проще и короче не обычной командой BIT #<маска>, R0 с последующим BEQ или BNE, а парой команд: (ROR или ROL) + (BCS или ВСС)). Еще одно неудобство такого метода (кроме "громоздкости" и потери машинного времени на выполнение функции ЕМТ 34) в том, что узнать режим работы БК из программы на БЕЙСИКе можно, но для этого следует написать USR-программу. Более простой и быстрый способ, доступный и непосредственно в Бейсик-программе оператором РЕЕК или OUT, - обращение к байтам-признакам режимов в ОЗУ БК. Кстати, именно к этим байтам обращается ЕМТ 34, формируя слово состояния в R0. Далее приводится таблица с указанием адресов байтов-признаков, а также их значений для включённого режима.
Все адреса байтов - восьмеричные. При выключенном значении режима во всех случаях значение байта-признака равно 0 Значение при включённом режиме всюду -1(3778), кроме номера 43, где - 2008
Номер (адрес) байта-признака |
Режим |
---|---|
40 |
32 символа в строке |
41 |
Инверсия фона |
42 |
Режим РП |
43 |
РУС |
44 |
Подчёркивание символов |
45 |
Инверсия символов |
46 |
ИНД СУ |
47 |
БЛОК РЕД |
50 |
ГРАФ |
51 |
ЗАП |
52 |
СТИР |
53 |
32 символа в служебной строке |
54 |
Подчёркивание в служебной строке |
55 |
Инверсия символов в служебной строке |
56 |
Гашение курсора |
3. Интересна ячейка ОЗУ @#1628: записанная в ней константа зависит от режима "32/64 символа в строке" и определяет, на сколько байтов экранной памяти произвести сдвиг очередного знакоместа (курсора) при печати символов (ширина символа в режиме 64 символа в строке равна 1 байту, а в режиме 32 символа в строке - 2 байта). При изменении содержимого этой ячейки операторами MOVB в Ассемблере (кодах) и РОКЕ в БЕЙСИКе можно при выводе текста получить интересные эффекты. В обычном состоянии значение байта @#1628 равно 1 для 64 символов в строке и 2 - для 32 символов. Если она будет равна 2 или 4 (соответственно), то текст будет выведен на экран как бы вразрядку. Обычно этого добиваются, просто задавая текст в операторе PRINT уже с пробелами. Работая с ячейкой @#1628, можно вывести текст в таком виде с экономией памяти вдвое. Другие значения этой константы приводят к тому, что-либо печатаются два символа в одно место, либо они группируются в разделённые пробелом пары, либо просто при печати вразрядку расстояние между символами становится больше - это каждый из читателей сможет выяснить сам, проведя простой эксперимент: POKE &O162,<конст.>. Установленный таким образом режим вывода действует всегда и в кодах, и в БЕЙСИКе, причём в БЕЙСИКе - и в операторе PRINT, и в INPUT, и при листинге программы, и в любом другом способе. Те из читателей, у кого есть принтер, могут поэкспериментировать: действует ли этот режим на вывод текста на принтер.
4. Фон экрана в БК-0010 при выполнении операций очистки экрана и печати символов определяется содержимым ячейки памяти @#2128. При выполнении операции очистки экрана число из этой ячейки копируется во все ячейки ОЗУ экрана. При печати символа БК, готовя место для него, переписывает содержимое этой ячейки в ячейки ОЗУ экрана, соответствующие прямоугольнику в 1 символ. Затем в уже подготовленном знакоместе высвечиваются "текущим" цветом точки, соответствующие графической прорисовке данного символа.
Как легко заметить, получить при выводе текста в БЕЙСИКе на экране три цвета (например, весь экран синий, а символы красные на зелёном фоне) невозможно: оператор COLOR, как и "ИНВ.Э.", который используется оператором. COLOR, меняет цвет фона на всем экране. Правда, есть способ вынести символы на экран цветом, отличным от цвета всего экрана и как бы в "окошке" черного цвета: перед печатью такого текста нужно дважды вывести код 15510 (или дважды нажав "АР2 + ;"), но после этого вернуться к обычному способу печати невозможно. Для примера: попробуйте поэкспериментировать с этой программкой на Бейсике с разными значениями С1 и С2, обозначающими номер цвета; программу просчитайте после вывода текста "СТОП в строке..." пошаговым методом с помощью клавиши ШАГ:
5 STOP 10 COLOR С1,С2 20 CLS 30 ? "AAA" 32 COLOR С1,4 ' черный фон 35 COLOR C1,С2 40 ? CHR$(155);CHR$(155); 50 ? "БББ" 60 CLS 70 ? "ССС" 80 END
С помощью же ячейки 2128 можно добиться любых эффектов такого рода: получать как общий фон экрана, так и фон знакоместа под символы любых цветов и расцветок хоть даже в вертикальную полоску! Этого мало! Экспериментируя, можно получить и другие эффекты, например эффект "утолщения" символов Сделать это можно, используя оператор РОКЕ или, что надёжнее для БЕЙСИКа, подпрограмму в кодах. Вот текст программы для смены цвета фона:
120327 |
377 |
1012 |
10546 |
11505 |
42705 |
177760 |
6305 |
62705 |
37734 |
11567 |
140262 |
12605 |
207 |
0 |
177777 |
125252 |
52525 |
167356 |
156735 |
63146 |
154330 |
146314 |
104210 |
42104 |
0 |
|
|
|
|
|
|
Начальный адрес: 377008. После ввода с м/ф введите DEF USR = &O37700. Чтобы сменить цвет фона, вызовите функцию USR оператором типа А% = USR(A%), где А% - число целого типа, обозначающее цвет (см. таблицу 2). После этого все символы будут печататься в "окошке" заданного цвета. Если же вы после этого выполните команду CLS, то весь экран окрасится в заданный цвет, и если захотите, вы можете опять вызвать функцию USR и задать для знакоместа символа другой цвет.
Применять цвета 4-10 нужно осторожно: иногда символы на таком фоне видны плохо. Лучше использовать такие цвета для окраски всего экрана, а для знакомест символов выбирать все-таки обычные для БК цвета (а с другой стороны, при печати символов на фоне 4-10 можно получить некоторые интересные эффекты).
Значение А% |
Цвет фона |
---|---|
0 |
Чёрный |
1 |
Красный |
2 |
Зелёный |
3 |
Синий |
4 |
Жёлтый |
5 |
Фиолетовый |
6 |
Голубой |
7 |
Белый |
8 |
Темно-красный |
9 |
Темно-зелёный |
10 |
Темно-синий |
11 и более |
Чёрный |
Для желающих поэкспериментировать (а также увидеть на экране обещанный фон "в разноцветную полосочку)" привожу вторую программу:
120327 |
000377 |
001005 |
010546 |
011505 |
010537 |
000212 |
012605 |
000207 |
000000 |
|
|
|
|
|
|
Начальный адрес любой; аргумент USR-функции - числа типов: %, &О или &В. Задавая разные значения аргумента, можно получать на экране все, что угодно. Введите в программу на БЕЙСИКе (пример, рассмотренный выше) дополнительную строку 25 В% = USR(B%) и попробуйте поэкспериментировать, подставляя различные значения В%.
5. В составе программного обеспечения БК, записанного в ПЗУ, есть полезные подпрограммы, которые можно вызывать из программ пользователя в кодах с помощью оператора JSR R7, @#<адрес>. Приведу данные о четырёх из них:
а) Подпрограмма @#100460 - печать строки символов. При этом длина строки текста должна быть записана в первом байте строки, а затем должен идти сам текст (как для программирования ключей). Перед вызовом в регистр R3 нужно поместить адрес байта с длиной строки.
б) Подпрограмма @#100472 - ввод с клавиатуры восьмеричного числа. В обычных условиях её использует монитор для ввода адреса запуска программы командой "С". После возврата введённое значение записано в R5. Если вводится "8", "9" или нецифровой символ, то в R5 тут же записывается 0 (Внимание! На экране внешне всё нормально!) и вводить число придётся заново. Если введено более шести цифр, то ввод каждой последующей цифры приводит к потере первой, второй и т.д. введённой цифры, а от цифры, записанной в самое левое "место" регистра, остаётся только её младший бит:
(стрелкой показан ввод стоящей рядом с ней цифры). На последнем шаге приведённой диаграммы видно, что при вводе седьмой по счету цифры 7 цифра 1 потеряна, а от цифры 2 остался только её младший бит: 0 (210=102) Завершается ввод числа клавишей <ВВОД>
в) Подпрограммы @#110346 и @#110362 (вызов оператором JSR R4, @#<адрес>) сохраняют в стеке и извлекают из стека (соответственно) регистры R0-R3. При этом значение R4 не сохраняется - он используется как вспомогательная ячейка памяти. (Первая из подпрограмм - сохранение; вторая - восстановление).
И в заключение небольшой совет тем, кто тоже будет исследовать монитор и БЕЙСИК: лучше всего воспользоваться программой PATCH, входящей в прилагаемый к БК-0010.01 пакет программ на БЕЙСИКе. Нужно переписать коды и начальный адрес на бумагу (если есть принтер - великолепно! Поменяйте в программе команды PRINT на LPRINT и включите принтер). Затем коды нужно перевести в команды Ассемблера по таблицам, имеющимся в одной из брошюр серии "Микропроцессоры" (Издательство "Высшая школа"), посвящённой микропроцессору К1801, и в книге Осетинского Л.Г. и др. "Фокал для микро- и мини-компьютеров", о которой на страницах журнала говорилось уже неоднократно.