В одном из номеров "Вычислительной техники" как-то прозвучал призыв к создателям Вильнюсской версии БЕЙСИКа рассказать о возможности использования подпрограмм БЕЙСИКа в программах пользователя, написанных в машинных кодах. Однако до сих пор (а прошёл уже год) никто на этот призыв не откликнулся. По-видимому, исследованием БЕЙСИКа придётся заниматься самим пользователям БК.

Д.Ю. Усенков (Москва)

О МОНИТОРЕ И ВИЛЬНЮССКОЙ ВЕРСИИ БЕЙСИКА

Предлагаю вниманию читателей несколько своих наблюдений.

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

Таблица 1

Номер (адрес) байта-признака

Режим

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 можно получить некоторые интересные эффекты).

Таблица 2

Значение А%

Цвет фона

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, и в книге Осетинского Л.Г. и др. "Фокал для микро- и мини-компьютеров", о которой на страницах журнала говорилось уже неоднократно.

Performed by © gid, 2012-2022.