В последнее время наряду с компьютерами БК-0010, работающими на ФОКАЛе, получили распространение компьютеры БК-0010-01, в ПЗУ которых «зашит» язык программирования БЕЙСИК.
ВКЛЮЧЕНИЕ ПОДПРОГРАММ В МАШИННЫХ КОДАХ В ПРОГРАММЫ НА БЕЙСИКе ДЛЯ БК-0010-01
По сравнению с ФОКАЛом БЕЙСИК работает значительно быстрее, программисту представляются более широкие возможности, за которые, правда, приходится расплачиваться двукратным уменьшением объёма памяти для программ Тем не менее имеющейся памяти вполне достаточно для создания сложных вычислительных программ и логических игр, а популярность БЕЙСИКА столь велика, что при наличии выбора ему отдаётся явное предпочтение перед ФОКАЛом.
Многих владельцев БК привлекает имеющаяся в БЕЙСИКе возможность использования подпрограмм в машинных кодах, однако далеко не все знают, как к этому подступиться, тем более что по необъяснимому капризу разработчиков операторы BLOAD и BSAVE для чтения и записи на магнитную ленту двоичных файлов действуют только в директивном режиме, то есть включить их в программу нельзя. Кроме того, для выделения памяти подпрограммам в машинных кодах приходится устанавливать границы Бейсик-системы оператором CLEAR, что тоже возможно лишь в директивном режиме. При использовании «штатных» возможностей БЕЙСИКа, загрузка и запуск таких программ требуют множества предварительных манипуляций с клавиатурой и магнитофоном, что отнимает много времени, увеличивает вероятность ошибок и в конечном итоге приводит пользователей к решению обойтись без использования кодовых подпрограмм.
Между тем существуют сравнительно несложные способы преодоления указанных трудностей. Во-первых, если подпрограмма в кодах занимает в памяти не более 20-30 машинных слов, её можно не записывать на магнитофон, а включать прямо в текст программы на БЕЙСИКе при помощи оператора Data и затем переслать в нужный участок ОЗУ, используя оператор непосредственного доступа к памяти РОКЕ
Во-вторых, достаточно длинные подпрограммы в кодах можно «спрятать» в стековой области БЕЙСИКа, которая занимает адреса с 400 до 2000 (здесь и далее адреса восьмеричные). Такой объем стека, судя по всему, связан с предполагаемым использованием данной версии БЕЙСИКа в новой модели БК-0011 с оперативной памятью до 128 кбайт. В самых длинных программах на БК-0010 обычно используется не более трети выделенной под стек памяти. Это означает, что есть возможность без особого риска располагать подпрограммы в кодах длиной до 500 байт в младших адресах стека, не затрагивая программную память, т.е. не используя оператор CLEAR.
Эти два приёма помогут реализовать некоторые несуществующие в БЕЙСИКе операции. К примеру, часто владельцев БК огорчает недоступность служебной строки экрана, которую БЕЙСИК использует для вывода первых символов программируемых ключей. Короткая подпрограмма в машинных кодах позволит нам использовать служебную строку для вывода любой символьной информации. Вот её текст в мнемонике АССЕМБЛЕРА и в машинных кодах
АССЕМБЛЕР |
Код |
||
---|---|---|---|
Восьмеричный |
Десятичный |
||
CLR |
R1 |
5001 |
2561 |
MOV |
(R5)+,R3 |
12503 |
5443 |
MOV |
(R5), R2 |
11502 |
4930 |
MET: MOVB |
(R2)+, R0 |
112200 |
-27520 |
EMT |
22 |
104022 |
-30702 |
INC |
R1 |
5201 |
2689 |
SOB |
R3, MET |
77304 |
32452 |
RTS |
R7 |
207 |
135 |
Нам остаётся разместить эту подпрограмму в памяти, начиная с адреса 400, и определить её при помощи оператора БЕЙСИКа DEF USR. Участок программы на БЕЙСИКе, реализующий вывод в служебную строку текста «Электроника-БК-0010», будет выглядеть так:
10 DATA 2561,5443,4930,-27520,-30702,2689,32452,135 20 FOR I% = 0 TO 7 30 READ J% 40 POKE &O400+2*I%,J% 50 NEXT I% 60 DEF USR0=&O400 70 A$="ЭЛЕКТРОНИКА БК-0010" 80 A$=USR0(A$)
Аргументом функции USR0 может быть символьная константа, переменная или выражение. Не допускается только использование символьных функций.
Теперь нам ничто не мешает составить подпрограмму для автоматической загрузки с магнитной ленты более длинных подпрограмм, которые нерационально размещать в операторе DATA. Собственно говоря, её даже не надо составлять, такая подпрограмма есть в ПЗУ монитора и имеет стартовый адрес 100602. К ней можно обращаться из БЕЙСИК-программы, предварительно определив DEF USR1 = &O100602. Следует помнить, что в основе всех операций с магнитофоном в БК-0010 лежит макрокоманда монитора ЕМТ 36, которая использует блок параметров драйвера магнитофона, располагаемый по умолчанию в ячейках с адресами 320-371. В младший байт ячейки 320 записывается число 3 - код команды чтения файла с магнитной ленты. В старший байт монитор помещает результат операции: 0 - ошибок нет, 2 - при чтении не совпала контрольная сумма, 4 - операция прервана нажатием клавиши «СТОП». Далее, в ячейке 322 должен находиться начальный адрес памяти, куда считывается файл. Область с адресами 326-344 предназначена для хранения имени считываемого файла. Перед обращением к подпрограмме нам необходимо поместить в блок параметров все необходимые значения. Код команды и адрес загрузки отправим по нужным адресам оператором РОКЕ. Имя загружаемого файла также можно переслать на место операторами БЕЙСИКа, однако программа пересылки получается громоздкой, да и соответствующая функция БЕЙСИКа MID$ ведёт себя внутри цикла порой совершенно непредсказуемо. Для этой цели удобнее определить ещё одну подпрограмму в машинных кодах, которая почти не отличается от предыдущей (см. таблицу).
В качестве примера рассмотрим программу на БЕЙСИКе, которая после старта автоматически переходит в режим загрузки с магнитофона подпрограммы в машинных кодах с именем FILENAME, после успешной загрузки выполняет подпрограмму, а в случае ошибки при чтении загружает её повторно.
10 DATA 5443,4930,5569,214,-27503,32450,135 20 FOR I%=0 ТО 6 30 READ J% 40 РОКЕ &O400+2*I%,J% 50 NEXT I% 60 DEF USR1=&O400 70 DEF USR2=&O100602 80 POKE &O320,3 90 POKE &O322,&O420 100 A$=USR1("FILENAME ") 110 I%=USR2(I%) 120 IF PEEK(&O320)\256 > 0 THEN 110 130 DEF USR3=&O420 140 I%=USR3(I%)
Имя файла в качестве параметра в строке 100 рекомендуется дополнять справа пробелами до 16 знаков.
Стоит указать ещё одну область ОЗУ, куда можно загружать подпрограммы в кодах длиной до 256 байт, не изменяя границу БЕЙСИК-системы оператором CLEAR. Это так называемый буфер ввода-вывода, расположенный в ячейках с адресами 37400-37776. Здесь, однако, есть два ограничения: в программе не должно быть операторов чтения и записи данных на магнитную ленту INPUT# и PRINT#, а саму программу нельзя записывать на ленту директивой SAVE, поскольку буфер ввода-вывода предназначен именно для этих команд. К слову говоря, записывать БЕЙСИК-программы на ленту во всех отношениях удобней директивой CSAVE: экономятся время, лента и меньше вероятность ошибок.
АССЕМБЛЕР |
Код |
||
---|---|---|---|
Восьмеричный |
Десятичный |
||
MOV |
(R5)+,R3 |
12503 |
5443 |
MOV |
(R5),R2 |
11502 |
4930 |
MOV |
#326,R1 |
12701 |
5569 |
|
|
326 |
214 |
MET: MOVB |
R2+,(R1)+ |
112221 |
-27503 |
SOB |
R3,MET |
77302 |
32450 |
RTS |
R7 |
207 |
135 |
Д. БАРОНОВ,
член Московского клуба
пользователей бытовых компьютеров