А.В. Алексеев (г. Ленинград)

О ТЕКСТАХ ПОДПРОГРАММ В КОДАХ

Меня заинтересовала статья А.П. Гармашова "О текстах подпрограмм в кодах для БЕЙСИКа БК 0010.01". Однако, как подметил автор статьи, программа имеет ряд недостатков: длина исходной подпрограммы в машинных кодах должна быть не более &O212, а также программа генерации теряется. Все эти недостатки можно устранить, применив другой принцип для построения программы, как мне кажется, более простой и очевидный. Применив этот принцип, я разработал две программы, отличающиеся друг от друга лишь степенью сервиса (вторая программа имеет более удобный интерфейс к пользователю). Из программы автора статьи я позаимствовал лишь подпрограмму USR2 - вызова процедуры монитора чтения файла с магнитной ленты и идею буферизации подпрограммы в кодах в экранной области ОЗУ.

Теперь более подробно о принципе, который положен в основу моей программы. Как известно из руководства по языку БЕЙСИК (1986.07.24), файлы данных записываются на магнитную ленту в формате кодов ASCII, так же, как и текстовые файлы программ, записанные командой SAVE. Из этого можно сделать следующий вывод: Бейсик-программы можно создавать средствами символьных функций Бейсик-программы, накапливая строки создаваемой программы в символьном массиве (каждый элемент массива - строка создаваемой программы). Затем можно с помощью операторов работы с файлами данных записать этот массив на магнитную ленту. Соответствующий фрагмент программы будет выглядеть следующим образом:

OPEN R$+'.ASC' FOR OUTPUT
FOR I%=1% TO V%
? # A$(I%) NEXT I%
CLOSE

где R$ - символьная переменная, содержащая имя файла; V% - размер символьного массива; A$(N) - символьный массив, содержащий строки создаваемой программы.

Далее записанную программы можно считать с магнитной ленты командой LOAD, дополнить её необходимыми операторами и скомпилировать подпрограмму в кодах, как в программе автора статьи.

Мною были написаны две программы: одна максимально минимизированная и позволяющая генерировать большие программы, другая - предоставляющая пользователю ряд удобств в работе с ней и занимающая больше места в памяти, хотя я предпринял все меры по сокращению памяти, занимаемой программой генерации.

Теперь рассмотрим более подробно каждую из программ. Разбор начнём с первой, короткой программы. Операторы в строках 10 и 20 устанавливают размер памяти, выделяемой под хранение строк генерируемой программы. В строках 30 - 70 загружается и определяется программа в машинных кодах, вызывающая процедуру чтения файла с магнитной ленты. Затем производится очистка экранной памяти, загрузка упаковываемой подпрограммы в машинных кодах в экранное ОЗУ с адреса &O42000. Далее в строках 130 - 230 происходит формирование очередной строки генерируемой программы. Причём каждая строка содержит: номер, оператор DATA и восемь чисел. Оператор в строке 240 удаляет последнюю запятую в последней неполной строке. Если строка полная, то после последнего числа нет запятой (см. строку 200). Потом полученный символьный массив записывается на магнитную ленту в файле с расширением .ASC'. В конце программа запрашивает пользователя о дальнейших действиях. Вторая программа содержит первую в качестве одной из подпрограмм. Выбор требуемой функции осуществляется с помощью меню. Курсор перемещается вверх и вниз с помощью двух клавиш 'курсор вверх' и 'курсор вниз' и устанавливается на необходимую строку. По нажатии клавиши 'ВВОД'(ВК) осуществляется переход на необходимую подпрограмму. С помощью второй программы можно кроме упаковки подпрограмм в кодах распечатать сгенерированную программу на экран или принтер записать программу на магнитную ленту.

Обе программы были мною проверены на подпрограмме, реализующей команду MERGE (ВТ и её применение. - № 4. - 1990.), которой я пользовался до создания моих программ. Я решил добиться аналогичного результата с помощью программы генерации. Последовательность действий при проверке была такая:

  1. С помощью отладочного монитора я записал в память подпрограмму с адреса &O1000 и директивой М3 вывел её на магнитную ленту.
  2. Отключив блок МСТД, запустил БЕЙСИК и загрузил свою программу генерации.
  3. Загрузил подпрограмму в кодах, которая моей программой была упакована в операторы DATA.
  4. Вывел сгенерированную программу на магнитную ленту.
  5. Считал сгенерированную программу командой LOAD, дополнил её необходимыми операторами и скомпилировал.

Подпрограмма оказалась полностью работоспособной. Я думаю, что эти две программы генерации окажутся полезными пользователям БК, использующим подпрограммы в машинных кодах.

 

Программа 1

10 CLEAR 2000                           'Выделение памяти под массив
20 DIM А$(30)                           'Объявление массива
30 РОКЕ &O400,&O11505                   'Загрузка
40 РОКЕ &O402,&O4737                    'подпрограммы
50 РОКЕ &O404,&O100536                  'вызова п/п
60 РОКЕ &O406,&O207                     'загрузки файла
70 DEF USR=&O400                        'её определение
80 ? CHR$(140)+CHR$(140);               'Очистка ОЗУ экрана
90 А%=USR(&O42000)                      'Вызов п/п загрузки
100 DL%=&O42000+PEEK(&O266)             'Нач.адр. считывания+длина файла
110 С%=&O42000                          'Адрес первого упаковываемого маш. слова
120 I%=10%                              'Номер первой строки генерир.программы
130 V%=I%\10%                           'Индекс элемента символьного массива
140 A$(V%)=""                           'Очистка очередного элемента массива
150 A$(V%)=""+MID$(STR$(I%),2%,LEN(STR$(I%)))+"DATA "
160 FOR J% =1% TO 8%                    'Цикл формирования очередной строки
170 A$(V%)=""A$(V%)+"&O"+OCT$(PEEK(C%)) 'генерируемой
180 IF J%<8% THEN A$(V%)=""+A$(V%)+"'"  'программы
190 C%=C%+&O2                           'Адрес следующего машинного слова
200 IF С%>DL% THEN 240                  'Если все слова прочитаны то на выход
210 NEXT J%
220 I%=I%+10%"                          'Номер следующей строки
230 GOTO 130                            'Идти на формирование новой строки
240 IF J%<8 THEN A$(V%)=""+MID$(A$(V%),1%,LEN(A$(V%))-1)
250 CLS
260 R$=""
270 INPUT "ИМЯ ФАЙЛА";R$
280 ? "ВКЛЮЧИ МАГНИТОФОН."
290 IF INKEY$="" THEN 290
300 OPEN R$+".ASC" FOR OUTPUT           'Запись
310 FOR J%=1 TO V%                      'Массива
320 PRINT # A$(J%)                      'на
330 NEXT J%                             'магнитную ленту
340 CLOSE
350 INPUT "БУДЕТЕ ПРОДОЛЖАТЬ",U$        'Запрос о дальнейших действиях
360 IF U$="D" OR U$="Д" THEN 80
370 CLS
380 END

 

Программа 2

10 REM ПРОГРАММА УПАКОВКИ П/П В КОДАХ В ОПЕРАТОРЫ 'DATA'
20 REM АЛЕКСЕЕВ А.В. 1.10.1990. БЕЙСИК-БК
30 CLEAR 2000
40 DIM А$(30)
50 РОКЕ &O400,&O11505
60 РОКЕ &O402,&O4737
70 РОКЕ &O404,&O100536
80 РОКЕ &O406,&O207
90 DEF USR=&O400
100 CLS
110 ? АТ(0,6)"ЗАГРУЗКА И УПАКОВКА П/П <=/*" 'Печать меню
120 ? АТ(0,8)"РАСПЕЧАТКА НА ЭКРАН <=/*"
130 ? АТ(0,10)"РАСПЕЧАТКА НА ПРИНТЕР <=/*"
140 ? АТ(0,12)"ЗАПИСЬ НА МАГНИТОФОН <=/*"
150 ? АТ(0,14)"ВЫХОД   <=/ *"
160 LINE (0,50)-(245,157),3,B           'Рамка меню
170 Y%=6%
180 LOCATE 29%,Y%,1%                    'Высвечивание курсора
190 Т$=INKEY$                           'Считывание символа с клавиатуры
200 IF Т$="" THEN 190
210 Т%=ASC(T$)                          'Определение кода символа
220 LOCATE 29%,Y%,0%                    'Гашение курсора
230 IF Т%=26% THEN 270                  'Переход на
240 IF Т%=27% THEN 310                  'соответствующую программу в
250 IF Т%=10% THEN 350                  'зависимости от нажатой клавиши
260 GOTO 180
270 Y%=Y%-2%                            'П/п движения курсора вверх
280 IF Y%=4% THEN BEEP ELSE 300
290 Y%=6%
300 GOTO 180
310 Y%=Y%+2%                            'П/п движения курсора вниз
320 IF Y%=16% THEN BEEP ELSE 340
330 Y%=14%
340 GOTO 180
350 ON Y%\2%-2% GOTO 360,660,750,800,920 'П/п перехода на требуемую функцию
360 CLS                                 'П/п упаковки п/п в машинных кодах
370 ? АТ(8,0)"ФОРМАТ УПАКОВКИ"
380 ? АТ(13,2)"1-ОСТ"
390 ? АТ(13,3)"2-НЕХ"
400 ? AT(13,4)"3-DEC"
410 В$=INKEY $
420 IF В$=""THEN 410
430 IF B$<"1" OR B$>"3" THEN 360
440 ? CHR$(140)+CHR$(140);
450 LOCATE 0%,10%
460 A%=USR(&O42000)
470 DL%=&O42000+PEEK(&O266)
480 C% = &O42000
490 I%=10%
500 V%=I%\10%
510 A$(V%)=""
520 A$(V%)=""+MID$(STR$(I%),2%,LEN(STR$(I%)))+"DATA "
530 FOR J%=1% TO 8%
540 D%=PEEK(C%)
550 IF B$="1" THEN A$(V%)=""+A$(V%)+"&O"+OST$(D%)
560 IF B$="2" THEN A$(V%)=""+A$(V%)+"&H"+HEX$(D%)
570 IF B$="3" THEN IF D% <0% THEN A$(V%)=""+A$(V%)+MID$(STR$(D%),1%,LEN(STR$(D%))-1)+"%"
    ELSE A$(V%)=""+A$(V%)+MID$(STR$(D%),2%,LEN(STR$(D%))-2)+"%"
580 IF J%<8% THEN A$(V%)=""+A$(V%)+","
590 C%=C%+&O2
600 IF C%>DL% THEN 640
610 NEXT J%
620 I%=I%+10%
630 GOTO 500
640 IF J%<8% THEN A$(V%)=""+MID$(A$(V%),1%,LEN(A$(V%))-1)
650 GOTO 100
660 CLS                                 ' П/п печати сгенерированной программы на экран
670 FOR J%=1% ТО V%
680 ? A$(J%)
690 IF CSRLIN<22 THEN 720
700 IF INKEY$="" THEN 690
710 CLS
720 NEXT J%
730 IF INKEY$="" THEN 730
740 GOTO 100
750 CLS                                 'П/n печати сгенерированной программы на принтер
760 FOR J%=1% ТО V%
770 LPRINT A$(J%)
780 NEXT J%
790 GOTO 100
800 CLS                                 'Запись сгенерированной программы на магнитную ленту
810 R$=""
820 LOCATE 0%,10%
830 INPUT "ВВЕДИТЕ ИМЯ ФАЙЛА";R$
840 ? "ВКЛЮЧИТЕ МАГНИТОФОН И НАЖМИТЕ ЛЮБУЮ КЛАВИШУ"
850 IF INKEY$="" THEN 850
860 OPEN R$+".ASC" FOR OUTPUT
870 FOR J%=1% TO V%
880 PRINT # A$(J%)
890 NEXT J%
900 CLOSE
910 GOTO 100
920 CLS                                 'Очистка экрана
930 END                                 'и выход из программы

 

Performed by © gid, 2012-2022.