Экономия памяти БК-0010.01

Мизерный размер ОЗУ БК-0010 стал притчей во языцех; к тому же даже в режиме расширения памяти экран из шести строк остаётся графическим и занимает 4К ОЗУ, хотя соответствующую информацию можно было бы разместить в 256 байтах (64 символа x 4 строки).

Однако БК ещё долгое время будет самым распространённым бытовым компьютером, поэтому я предлагаю вниманию читателей "ИНФО" (ни в коей мере не претендуя на единоличное авторство) ряд способов экономии памяти БК-0010.

Итак, что делать, если ваша программа выросла до таких размеров, что перестала запускаться? На практике выглядит это так: программа благополучно записывается в память, но при попытке её запуска выдаётся одно из следующих сообщений:

СТОП
СТОП в строке N
ОШИБКА 7
ОШИБКА 7 в строке N

Самая частая причина первых двух случаев - попытка присвоить значение символьной переменной до распределения памяти операторами CLEAR или DIM (причина этого осталась непонятной). Исправляется эта ситуация просто, хотя опять же непонятно - достаточно описать до строки остановки любой массив (даже если он не нужен в программе), например DIM А%(1). Кстати, все массивы желательно описать в самых первых строках программы, иначе подобные сюрпризы с остановками могут встретиться и в операторах INPUT, INKEY$ и т.д.

Если номера строки в сообщении об ошибке нет, нужно включить режим трассировки директивой TRON. Нужный номер будет последним в списке номеров, выданных на экран. Затем режим трассировки должен быть отключён директивой TROFF, в противном случае при попытке остановить работу программы клавишей СТОП может полностью очиститься память БК.

При появлении "ошибки 7" рекомендуются следующие действия:

Два последних пункта введены из-за склонности БК не только к зависанию, но и к сбросу программ.

Определить характер переполнения можно с помощью директив ?FRE и ?FRE(""). Если сообщение "ОШИБКА 7" будет выдано в обоих случаях, то, вероятнее всего, переполнен стек. Как правило, это происходит при некорректных выводах из подпрограмм и циклов (с помощью GOTO минуя RETURN и NEXT).

"ОШИБКА 7" в символьных переменных (т.е. выдающаяся при вводе директивы ?FRE("")) или сообщение "ОШИБКА 14" могут быть устранены перераспределением памяти, т.е. введением в начале программы строки CLEAR МММ (МММ должно превышать 200; поставьте 250, затем 300 и так - до исчезновения сообщения об ошибке).

Если же это не приводит к желаемому результату, а также при переполнении памяти, выделенной под числовые переменные (?FRE(0)), и малом числе символьных переменных можно также попытаться перераспределить память, но уже в сторону уменьшения. В CLEAR МММ МММ должно быть меньше 200, например 50 или 10, согласно количеству и величине необходимых символьных переменных.

Распределение памяти сохраняется и после исполнения команды NEW, так что вызвать переполнение может и небольшая программа, если до её запуска память была перераспределена директивой CLEAR или предыдущей программой.

Во всех остальных случаях приходится обращаться к специфическим способам экономии памяти БК, изложенным ниже в порядке нарастания трудоёмкости их применения.

  1. Убрать или сократить лишние тексты: комментарии, длинные сообщения, многосимвольные имена переменных. Получаемая экономия памяти - по две ячейки на каждый второй сокращённый символ.
  2. Убрать "хвосты" пробелов в программных строках. Они могут появляться при редактировании текстов (в результате использования курсорных клавиш вместо клавиши ЗАБОЙ), при случайном срабатывании клавиши ТАБ и после номеров строк в GOTO, GOSUB, ON и т.д. при ренумерации (RENUM) программы или её части.

    "Хвосты" обнаруживаются по положению курсора (при выводе на экран данной строки в режимах AUTO и "." - вызов на редактирование) или символа ввода - инверсной буквы J (в LIST при включённом режиме ИСУ).

    Устраняются "сбросом конца строки" или клавишей "ЗАБОЙ". Экономия памяти - по две ячейки на каждый второй символ.

    Для быстрого просмотра удобно применять LIST в режиме инверсии символов (АР2/,) или ИСУ. Приостанавливать просмотр можно нажатием СУ/Ю: эта комбинация приостанавливает любые действия компьютера, возобновляя их по нажатии любой клавиши.

  3. Если несколько циклов можно окончить в одном месте, то это надо делать одной строкой:
    NEXT I%, J%, К%

    Экономия памяти - шесть ячеек на каждый выброшенный NEXT.

    Интересно, что неименованные NEXT занимают на 2-3 ячейки больше (!), чем именованные (NEXT I%).

  4. Правильно использовать типы данных. Все целые числа, кроме номеров строк в GOTO, GOSUB, ON и аргументов оператора DRAW, снабдить символом % (удобно использовать ключ KEY N,CHR$(23%)+"%" - при его применении символы сами раздвигаются при впечатывании %). Экономия памяти - 4-6 ячеек.

    Использовать переменные без чрезмерного запаса точности. Для решения большинства задач достаточна одинарная точность (символ ! после имени).

    При изменении типов переменных нужно быть очень внимательным, ведь X, X!, Х% для компьютера совершенно разные вещи, и менять имена нужно по всей программе, чтоб не пытаться потом "вытащить" из X то, что было присвоено X! или Х%. Грамотнее и надёжнее применять этот приём при написании заведомо большой программы сразу - небольшое увеличение длины текста и времени набора обернётся изрядной экономией памяти.

    Экономия памяти - две ячейки при переходе от X к X! и четыре при переходе от X к Х%.

    У этого способа есть исключение - глобальные переменные, точнее те из них, которые встречаются в тексте программы много раз. В этом случае, экономя на памяти, отведённой под значение переменной, мы расходуем память на многократное повторение длинного имени, ведь % и ! также занимают место.

  5. Необходимо по возможности сокращать количество переменных, у всех локальных циклов, значения параметров которых не употребляется в других частях программы, сократить число параметров до минимума, то же сделать и с локальными переменными; иначе говоря, нужно стремиться использовать одно место в памяти в максимальном числе случаев. Экономия памяти - четыре ячейки при отказе от одной целой переменной (Х%), шесть - при отказе от переменной одинарной точности (X!), десять - при отказе от переменной двойной точности (X или X#).
  6. Немало резервов заключено в использовании значений, задаваемых по умолчанию. Все аргументы, стоящие в списках через запятую и не в скобках (исключение - оператор ON), можно не писать в случаях неизменности их значений. При этом надо не забывать ставить нужное количество запятых, если далее по списку следует хоть одно числовое значение (например, коэффициент сжатия у окружности). Этот приём можно применять и в операторах LOCATE, DATA при считывании данных группами: в этих случаях отсутствие аргумента также оставит неизменным его прежнее значение.

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

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

    При рисовании непрерывных линий оператором LINE нужно знать, что операторы графики "помнят" последнюю обработанную точку даже после работы с текстом и очистки экрана CLS. Этим можно пользоваться, например, при рисовании нескольких прямоугольников или рамок в чередующихся кадрах, если есть возможность использовать старые значения координат:

    CLS
    LINE (0%,0%)-(255%,239%),,В
    ...'текст
    CLS
    LINE -(5%,5%),,В
    ...' текст
    CLS
    LINE -(250%,220%),,В
    ... и т.д.
  7. Имеет смысл "запаковывать" в подпрограммы не только большие фрагменты, но и почти любые строки, повторяющиеся в программе более двух раз, например подготовку печати текстов, стандартные сообщения или задержки.

    Обращение к подпрограмме AAA GOSUB NNN занимает 14 ячеек, оператор возврата ВВВ RETURN - десять, а, например, МММ IF INKEY$ = "" THEN МММ - 42 ячейки, т.е. уже при втором обращении к подпрограмме сэкономим (42*2)-(42+14*2+10)=6 ячеек и по 28 с каждого последующего использования.

  8. Использование "блоков" подпрограмм позволяет выполнить несколько подпрограмм с помощью одного обращения, например:
    100 GOSUB 1000 ’Титр, рулон и задержка - весь блок подпрограмм с одного обращения
    200 GOSUB 3000 ’Только рулон
    300 GOSUB 1010 ’Рулон и задержка
    1000 GOSUB 2000 ’Титр
    1010 GOSUB 3000 ’Рулон
    1020 IF INKEY$="" THEN 1020 ’Задержка
    1030 RETURN
    ...
    2000 ?АТ(8%,22%)CHR$(156%)"НАЖМИТЕ ЛЮБУЮ КЛАВИШУ !"CHR$(156%) ’Титр
    2010 RETURN
    ...
    3000 ?АТ(0%,19%)CHR$(19%); ’Рулонный сдвиг части экрана
    3010 RETURN
  9. Позиция печати может быть установлена операторами LOCATE X,Y,K и ? AT(X,Y)<Текст>. В зависимости от представления данных объём памяти, используемый этими операторами, сильно меняется. Например,

    NN LOCATE X,Y

    - 40 ячеек;

    NN LOCATE X%,Y%

    - 26 ячеек;

    NN LOCATE X%,Y%,C%

    - 34 ячейки;

    NN LOCATE ,Y%,C%

    - 30 ячеек;

    NN LOCATE ,,1%

    - 24 ячейки;

    NN ? AT (X,Y)

    - 46 ячеек;

    NN ? AT (X%,Y%)

    - 32 ячейки;

    NN ? AT (X%,Y%) AT (X%,Y%)

    - 50 ячеек.

     

    Отсюда видно, что использовать LOCATE гораздо выгоднее; кроме того, в этом операторе возможно умолчание. Второй же оператор имеет смысл употреблять только при печати нескольких сообщений одной программой строкой:

    NN ?AT(5%,5%)"МИГАЮЩИЙ ТЕКСТ"AT(5%,5%)"              "

    При необходимости начать печать с новой строки лучше вводить отдельную новую программную строку печати, чем использовать ?АТ или LOCATE. Если же надо при этом стереть или пропустить одну-две строки текста, то экономнее для этого использовать запятые, чем оператор TAB. При этом нужно помнить, что операторы печати, встретив запятую, выводят пробелы до ближайшей позиции с номером, кратным 16.

    10 ?А%

    - 20 ячеек;

    20 ?

    30 ?В%

    10 ?А%,,В%

    - 40 ячеек;

    10 ?А%ТАВ(32%)В%

    - 50 ячеек;

    10 ?А%,,,,В%

    - 48 ячеек;

    10 ?А%ТАВ(64)В%

    - 56 ячеек.

  10. Относительные координаты в графических операторах обычно записываются короче абсолютных. Сравните:
    LINE (220,140)-(225,142)
    LINE @(0,-10)-@(5,2)

    Не забудьте, что операторы графики "помнят" координаты последней обработанной точки даже после работы с текстом и очистки экрана оператором CLS.

  11. Оператор DRAW также допускает сокращения.

    Во-первых, все единицы, кроме последней, можно не писать; у простых рисунков и схем с кратным шагом ради этого даже выгодно изменить масштаб (не забудьте вернуть прежний в этой же строке, иначе велики шансы забыть сделать это и потом удивляться странным размерам рисунка). Отсутствие числового аргумента оператор DRAW воспринимает как 1 у команд направления и как 0 у команды цвета. Не забывайте: во избежание "ОШИБКИ 5" последней в строке DRAW обязательно должна стоять цифра.

    Сравните:

    DRAW "C0R40D40L40U40C1L40D40R40U40"
    DRAW "S10CRDLUC1LDRUS4"

    Во-вторых, использование относительных координат даёт выгоду и в этом операторе, особенно если выбрать направление обхода контура или кривой, при котором большинство смещений по вертикали будет положительным ("плюс" в координате Y в выражении М+-Х,+-Y можно не писать).

    В-третьих, кавычки в DRAW можно не закрывать (как, кстати, и в операторе PRINT).

    В-четвертых, если есть возможность присвоить литерной переменной текст целого фрагмента рисунка, следует пользоваться выражениями типа

    DR X$
    DR X$+"E7"+A$
  12. О возможности сокращения имён операторов уже сообщалось (заметка А. Козлова в "ИНФО", № 3 за 1989 г.), но возможности этого приёма были раскрыты далеко не полностью. Транслятор Бейсика БК опознает операторы (но не функции) по двум-трём буквам не только в начале строки, но и в любом другом месте программы, хотя и не дописывает их до конца, в отличие от первого служебного слова в строке. Приведём дополненный по сравнению с заметкой А. Козлова список допустимых сокращений команд и операторов (в скобках - необязательные части):

    AU(ТО)

    BE(EP)

    BL(OAD)

    BS(AVE)

    CA(LL)

    CI(RCLE)

    CLE(AR)

    CLOA(D)

    CLO(SE)

    COL(OR)

    CON(T)

    CS(AVE)

    DA(TA)

    DEL(ETE)

    DI(M)

    DR(AW)

    EL(SE)

    EN(D)

    FI(ND)

    FO(R)

    GOS(UB)

    GOT(O)

    IN(PUT)

    KE(Y)

    LE(T)

    LIS(T)

    LIN(E)

    LL(IST)

    LOA(D)

    LOC(ATE)

    LP(PINT)

    MO(NIT)

    NEX(T)

    OU(T)

    OP(EN)

    PA(INT)

    PO(KE)

    PRE(SET)

    PRI(NT) /?/

    PS(ET)

    REA(D)

    REN(UM)

    RES(TORE)

    RET(URN)

    RU(N)

    SA(VE)

    ST(EP)

    ST(OP)

    TH(EN)

    TR(OFF)

     

    Ходят слухи, что сокращения ST и EL срабатывают не всегда, но в нашей практике такого не встречалось.

  13. Ещё один резерв экономии памяти - пробелы. Обязательны они в единственном случае - после имён переменных двойной точности, ибо самостоятельно транслятор не может определить конец имени переменной. Однако разделителем, кроме пробела, могут служить и некоторые другие символы (! # $ % ( ) , ;); при наличии любого из них пробел нужен лишь для удобочитаемости.

    Сравните три записи - нормальную, сокращённую и сверхкороткую:

    IF I=0 THEN CIRCLE (100,100),10 ELSE PRINT A$;"=";I%;К
    IF I=0 TH CI @(0,0),10 EL ? A$;"=";I%;K
    IFI=0THCI@(0,0),10EL?A$"="I%K

    Сверхкороткая запись выглядит, конечно, не очень эстетично, но, если нет другого выхода, до эстетики ли...

    Отметим, что транслятор Бейсика БК ставит по одному пробелу до и после первого служебного слова в программной строке, сколько бы пробелов ни было набрано. Этим можно воспользоваться при форматировании программных сообщений: достаточно после знака "?" ввести столько пробелов, чтобы открывающие кавычки оказались в последней позиции экранной строки; тогда в тексте все переносы будут на своих "законных" местах, а введённые пробелы транслятор уберёт.

    Исключение - многооператорные конструкции типа IF...THEN?"..."ELSE?"...", где пробелы надо убирать вручную.

Напомним, что способы экономии памяти заложены в порядке возрастания сложности их применения. Некоторые из них, например 12, 13, создают столько неудобств, делают программу настолько трудночитаемой, что их применение имеет смысл лишь при сокращении свободной памяти до нескольких сотен ячеек. В то же время способы 4-6 при работе над заведомо длинной программой желательно применять с самого начала, так как практически невозможно переименовать все переменные сложной программы без массы ошибок; времени на их исправление потом будет затрачено гораздо больше, чем было сэкономлено при написании текста.

В заключение несколько слов о "сюрпризах" транслятора Бейсика БК-0010.01.

  1. В операторе DRAW иногда происходит "выброс" последней линии - она без видимых причин может стать очень длинной. В этом случае достаточно в конце строки DRAW поставить пробел (кавычки не обязательны).
  2. При включении в оператор DRAW подстрок или переменных иногда вместо символов печатаются какие-то странные нерегулярные точки (даже в ответ на нажатие клавиши СТОП).

    При ближайшем рассмотрении оказывается, что высвечиваются только одна-две "вертикали" символа - машина переходит в "полосатый" цвет. Устранение - "насильное" включение цвета, например АР2/НР/1. Причина - во многих руководствах пропущен символ "точка с запятой", а он в этих случаях обязателен. Корректное включение подстроки выглядит так:

    DRAW"C1XA$;"

    Между X и именем переменной - подстроки не нужен знак равенства, а точка с запятой должна стоять после $ хоть в середине, хоть в конце строки.

  3. Нельзя делать перенумерацию части программы, если в ней используется оператор ON. Его список меняется только при перенумерации всей программы.
  4. Будьте осторожны с режимом трассировки (TRON): если при этом встретится цикл типа
    NN IF INKEY$=""THNN

    то при попытке остановить работу клавишей СТОП иногда происходит полный перезапуск Бейсика с не менее полной очисткой памяти. Выход - попробовать сначала СУ/Ю, а потом уже СТОП; ещё лучше впредь всегда вводить в программу TROFF.

  5. При работе с программами связи БК-ДВК (NET, NET3) также возможны сюрпризы: при загрузке программа читается дважды, причём в БК остаётся только вторая её половина (!). При распечатке же на терминал ДВК или на принтер не обнаруживается ничего подозрительного.

    На диске может обнаружиться файл длиной 0 блоков. Не пытайтесь стереть его - ничего хорошего из этого не выйдет. При детальном исследовании оказывается, что БК этот файл прекрасно читает, правда не то, что там было... А на диске есть ещё один файл, начинающийся с этого же блока. Другими словами, этот файл отзывается и на имя, и на "псевдоним". Но "псевдоним", как и положено, не содержит "анкетных данных" (в данном случае - сведений о длине), хотя попытка уничтожения приводит к успеху, как бы вы к нему не обращались.

    Такое случается при многократной записи на диск программы под одним именем.

    Кроме этого сюрприза NET3 изредка подкидывает и другой - он иногда не читает каталог диска при записи. Кончается это тем, что на диске оказывается записан каталог предыдущего диска и программа вписана на место, которое было свободным на предыдущем диске. Спасти в этом случае программой SOS.SAV можно только текстовые и .ASC файлы. Поэтому не рекомендуется запись на диск директивой CLOAD, a NET3 при смене диска необходимо перезапускать.

    Заканчивая обсуждение сюрпризов NET3, приведём программу, позволяющую читать каталог диска с места ученика.

    1 'Чтение каталога диска,
    2 'созданного так:
    3 'R DIR <ВК>
    4 'САТ=/A/F/C:4 <ВК> СУ/С
    10 OPEN "ТТ:CAT.DIR" FOR INPUT
    20 INPUT #A$
    30 ? A$
    40 IF NOT(EOF)TH20
    50 CLOSE

    Если NET3 будет запущена не командой, а командным файлом CAT.COM

    NET3
    R DIR
    CAT=/A/F/C:4
    ^C

    то по выходу из программы связи каталог для БК будет обновляться автоматически. Файл создаётся в редакторе EDK и запускается командой @CAT.

 

М. ЛАРКИН
при участии И. Левенчука, А. Новикова


 

Ещё раз о плавающей арифметике Фокала

Публикация в журналах текстов программ для ЭВМ сопряжена с техническими трудностями и приводит к увеличению вероятности опечаток. Не явилась исключением и наша статья "Использование плавающей арифметики Фокала в БК-0010" в №5 за 1989 г. (прим.gid: Эта статья не распознавалась, т.к. аналогичная статья в "ВТ и её П" была уже распознана. Но после этой заметки, была произведена вычитка и сравнение статей и исправлены все соответствующие ошибки.) К счастью, имеющаяся опечатка в тексте программы ПИФ не делает её полностью неработоспособной в отличие от аналогичной статьи в научно-популярной серии "Вычислительная техника и её применения", №5, 1989. На с. 67 в тексте программы ПИФ (столбец 5, вторая строчка сверху) вместо числа 014412 должно стоять 104412. Данная ошибка приводит к тому, что на экран не выдаётся сообщение об ошибочных ситуациях при выполнении операций Фокала, например ПОПЫТКА ДЕЛЕНИЯ НА НОЛЬ. В остальном программа ПИФ функционирует нормально.

На с. 65 в таблице 4 в последнем столбце необходимо вставить пустую строку после числа 132552, т.е. фактически сдвинуть все числовые значения вниз от этого числа на одну строку.

По вине авторов при подготовке публикации в примере внизу с. 63 исчезла команда ввода символа с клавиатуры ЕМТ 6. Первоначально данная программа в мнемоническом виде должна была выглядеть следующим образом:

        MOV #A,R1    ; Поместить адрес сим-
                     ; вольной строки в R1
4$:     EMT 6        ; ввести код
                     ; с клавиатуры в R0
        EMT 16       ; вывести эхо на экран

К сожалению, в данном случае, чтобы исправить программу, необходимо вставить команду. Это приведёт к сдвигу чисел во всём примере. Однако если в третьей строке сверху команду ЕМТ 16 заменить на ЕМТ 6 (числовой код 104006), то программа будет работать, правда "вслепую", т.е. без выдачи вводимого числа на экран.

На с. 64 в центре четвертая строка примера должна содержать число 002050 вместо 002052.

В процессе использования плавающей арифметики Фокала выяснились некоторые особенности. Оказалось, что функция FSQT требует для своей работы копию сумматора в рабочих областях Фокала. Поэтому перед использованием FSQT необходимо выполнить копирование сумматора операцией FPUT @#1704.

Использование операции FREAD для перевода чисел из символьного вида в двоичный имеет один нюанс для случая отрицательного числа. В статье на с. 64, второй абзац сверху, сказано, что при переводе отрицательного числа операция FREAD устанавливает разряд условия N. Однако это не так. Разряд N устанавливается автоматически при загрузке в регистр R4 первого байта переводимого числа, который в этом случае является минусом. Чуть ранее в статье объяснялось, что код минуса в Фокале равен 202. С точки зрения архитектуры ЭВМ этот байт является отрицательным числом, что приводит к установке признака N. Поэтому в примере внизу с. 63 необходимо поменять местами две команды:

002064  112737       MOVB #20,@#1723      ; Обязательно заполнить
002066  000020                            ;
002070  001723              
002072  112304       MOVB (R3)+,R4        ; Обязательно поместить
                                          ; первый символ в R4

Правда, разряд N установится также в случае использования знака плюс (код 201) в начале строки с положительным числом, поэтому здесь следует соблюдать осторожность и придерживаться обычной практики кодирования положительного числа без явно заданного знака "плюс".

Некоторые программисты в своей работе часто используют операцию FPRINT. При этом их интересует возможность изменять значение формата выводимых чисел.

Значение формата, как известно, состоит из двух частей: первая указывает общее количество десятичных цифр в записи выводимого числа, а вторая - количество знаков в мантиссе. В нотации Фокала это записывается, например, в виде %8.04. Перед использованием операции FPRINT в регистр R2 помещается требуемый формат, при этом старший байт содержит первую часть формата. В младший байт необходимо поместить удвоенное число позиций мантиссы, включая точку. Для приведённого в статье формата %8.04 регистр R2 содержит (числа восьмеричные):

старший байт = 10

младший байт = (4+1) * 2 = 12

R2 = <10><12> = 4012

Многие пользователи проявили заинтересованность в использовании плавающей арифметики на ЭВМ с Бейсик-интерпретатором. К сожалению, авторы не занимались изучением заложенных в микросхеме Бейсика средств плавающей арифметики. Однако ими разработан пакет подпрограмм, который позволяет использовать механизм псевдокоманд плавающей арифметики Фокала на любом БК, в том числе и на ЭВМ с Бейсиком. В состав пакета входит также библиотека стандартных математических функций.

В заключение авторы хотят выразить благодарность всем пользователям, уже высказавшим свои замечания, а также тем, кто в дальнейшем сообщит об обнаруженных неточностях. Все замечания и предложения просим направлять по адресу: 226063, г. Рига, ул. Кенгарага, 8. НИИ физики твёрдого тела.

 

С. ГВОЗДЕВ, Г. ЭРНЕСТСОНС


 

Универсальный каталогизатор

Широкое распространение БК породило огромное количество программных средств для него. В связи с этим возникла необходимость в программах, облегчающих процесс каталогизации. Такие программы должны обладать следующими функциями: чтение файлов с ленты, вывод на дисплей имени, адреса загрузки в ОЗУ и длины текущего файла, подсчёт количества копий на магнитной ленте (МЛ), регистрация наличия ошибок при чтении с МЛ, чтение имён файлов без занесения в каталог. При этом необходимо предусмотреть возможность записи полученного каталога на МЛ в формате какого- либо редактора и возможность последующей печати каталога на принтере. Существующие программы каталогизации обеспечивают только отдельные из перечисленных функций.

В описываемом каталогизаторе VERIFY реализована вся совокупность перечисленных функций, а также добавлен ряд сервисных возможностей, облегчающих работу пользователя. Имеется шесть основных режимов работы:

В режимах записи и печати каталога для каждого прочитанного файла указываются адрес загрузки, длина, наличие ошибок чтения и число копий на МЛ. В конце каталога подсчитывается и регистрируется общее число файлов.

Программа VERIFY отличается от других каталогизаторов простотой управления: все операции осуществляются в режиме меню, на экране постоянно находится подсказка, объясняющая функции текущего режима. Одно из состояний экрана во время работы с программой представлено на рисунке. Программа написана на ассемблере и занимает примерно 5,5К байт.

На одной из распечаток приведён фрагмент программы, реализующий диалог с пользователем в режиме меню, на другой - пример каталога, созданного программой.

TRA:    CLR CRT         ;УСТАНОВИТЬ ТЕКУЩИЙ
                        ;РЕЖИМ В 0
        JSR PC,MNU      ;ОТОБРАЗИТЬ НА
                        ;ЭКРАНЕ МЕНЮ ДЛЯ
                        ;РАБОТЫ И ВСПОМОГА
                        ;ТЕЛЬНОЕ ОКНО
        JSR PC,CUT      ;НАРИСОВАТЬ СТРЕЛКУ
                        ;ОТ ТЕКУЩЕГО РЕЖИМА
        ADD #7,R1       ;ДО ВСПОМОГАТЕЛЬ-
                        ;НОГО ОКНА
        EMT 24
        MOV #WNW,R1
        CLR R2
        EMT 20
        MOV #ATV,R2     ;ВЫВОД НОМЕРА
                        ;ВЕРСИИ В
        CLR R1          ;СЛУЖЕБНУЮ СТРОКУ
        JSR PC,MEN
TR5:    JSR PC,CUT      ;УСТАНОВИТЬ КУРСОР
                        ;СПРАВА ОТ ТЕКУЩЕГО
                        ;РЕЖИМА
        MOV #SL,R1      ;(ТЕКУЩИЙ РЕЖИМ
                        ;ОТЛИЧАЕТСЯ
                        ;ИНВЕРСНЫМ
        CLR R2          ;ИЗОБРАЖЕНИЕМ)
        EMT 20          ;НАРИСОВАТЬ СТРЕЛКУ
        JSR PC,SEE      ;ВЫВЕСТИ ДОПОЛНИ-
                        ;ТЕЛЬНУЮ ИНФОРМАЦИЮ 
                        ;О РЕЖИМЕ 
        JSR PC,KEY      ;ПРОЧИТАТЬ КОД
                        ;НАЖАТОЙ КЛАВИШИ 
        CMP R0,#12      ;АНАЛИЗ НАЖАТОЙ
                        ;КЛАВИШИ
        BEQ K12 
        CMP R0,#32 
        BEQ T01 
        CMP R0,#33 
        BNE TR6         
        ;НАЖАЛИ СТРЕЛКУ ВНИЗ 
        JSR PC,CUR      ;ВЫВОД В НОРМАЛЬНОМ
                        ;(НЕИНВЕРТИРОВАННОМ) 
                        ;ВИДЕ ТЕК. РЕЖИМА 
        JSR PC,CUT      ;СТЕРЕТЬ И ПРОДЛИТЬ
                        ;СТРЕЛКУ ОТ ВСПОМО- 
        MOV #PPS,R1     ;ГАТЕЛЬНОГО ОКНА 
        CLR R2          ;ДО НОВОГО ТЕКУЩЕГО
                        ;РЕЖИМА
        EMT 20 
        INC CRT         ;СДЕЛАТЬ ТЕКУЩИМ
                        ;СЛЕДУЮЩИЙ РЕЖИМ 
        CMP CRT,#7      ;БЛОКИРОВКА ОТ
                        ;НЕКОРРЕКТНОГО ВВОДА 
        BMI T02 
        DEC CRT
T02:    MOV #234,R0     ;УСТАНОВИТЬ РЕЖИМ
                        ;ИНВЕРСИИ СИМВОЛА 
        EMT 16
        JSR PC,CUR      ;ОТОБРАЗИТЬ В ИНВ.
                        ;ВИДЕ ТЕКУЩИЙ РЕЖИМ 
        MOV #234,R0     ;УСТАНОВИТЬ
                        ;НОРМАЛЬНЫЙ РЕЖИМ
                        ;ВЫВОДА 
        EMT 16
        BR TR5          ;ВОЗВРАТ
        ;НАЖАЛИ СТРЕЛКУ ВВЕРХ 
T01:    JSR PC,CUR      ;ВЫВЕСТИ В
                        ;НОРМАЛЬНОМ ВИДЕ 
                        ;ТЕКУЩИЙ РЕЖИМ
        JSR PC,CUT      ;УКОРОТИТЬ СТРЕЛКУ
        MOV #231,R0     ;ОТ ВСПОМОГАТЕЛЬНОГО
        EMT 16          ;ОКНА ДО НОВОГО
                        ;ТЕКУЩЕГО РЕЖИМА 
        DEC CRT         ;СДЕЛАТЬ ТЕКУЩИМ
                        ;ПРЕДЫДУЩИЙ РЕЖИМ 
        BGE T03         ;БЛОКИРОВКА ОТ
                        ;НЕКОРРЕКТНОГО ВВОДА 
        CLR CRT
T03:    BR T02          ;НАРИСОВАТЬ СТРЕЛКУ
                        ;И ВЕРНУТЬСЯ
        ;НАЖАЛИ <ВВОД> 
K12:    TST CRT         ;ВЫБОР НУЖНОЙ ПОД-
                        ;ПРОГРАММЫ В ЗАВИСИ- 
                        ;МОСТИ ОТ ЗНАЧЕНИЯ 
        BNE KD1         ; ПЕРЕМЕННОЙ CRT
                        ;(НОМЕР ТЕК. РЕЖИМА)
        JSR PC,HLP      ;CRT=0 ИНФОРМАЦИЯ
        BR TR6          ;О ПРОГРАММЕ
KD1:    CMP CRT,#1
        BNE KD2
        JSR PC,RDR      ;CRT=1 ЧТЕНИЕ
        BR TRA          ;ФАЙЛОВ С ЛЕНТЫ
KD2:    CMP CRT,#2
        BNE KD3
        JSR PC,CAT      ;CRT=2 ФИКТИВНОЕ
        BR TR6          ;ЧТЕНИЕ
KD3:    CMP CRT,#3
        BNE KD4
        JSR PC,SAV      ;CRT=3 ЗАПИСЬ
        BR TR6          ;КАТАЛОГА НА МЛ
KD4:    CMP CRT,#4
        BNE KD5 
        JSR PC,PRI      ;CRT=4 ПЕЧАТЬ
        BR TR6          ;КАТАЛОГА
KD5:    CMP CRT,#5
        BNE KD6
        JSR PC,NWT      ;CRT=5 СБРОС
        BR TR6          ;КАТАЛОГА
        ;CRT=6 ВЫХОД В МОНИТОР
KD6:    JSR PC,SUR      ;ЗАПРОС ПОДТВЕРЖДЕ-
                        ;НИЯ У ПОЛЬЗОВАТЕЛЯ
        TST R0 
        BNE Q00 
        JMP TR6
Q00:    EMT 14          ;СБРОС СИСТЕМЫ
        HALT            ;ОСТАНОВ
CRT:    .#0
SL:     .A:<------+
        .B:0
PPS:    .A:|
        .B:34 .A:|
        .B:34 .A: +-----------
        .B:276 .B:0
ATV:    .A:(C) ATV corp. 25-09-89 'VERIFY' V2.0
        .E

 

Имя файла

Адрес

Длина

Ошибки

Число

ОКЕАН

001000

037000

Нет

02

FOKEY

030000

000434

Нет

02

FOKEY 2.0

033000

003310

Да

01

FOKEY 2.0

033000

003310

Нет

01

СНАРЯД

001140

002210

Нет

02

RALLI-A

001140

004126

Нет

02

FANTOM2

001752

016106

Да

01

FANTOM2

001752

016106

Нет

01

TOR

001752

004572

Нет

02

LOOK&PRINT

000732

005434

Нет

02

Общее число файлов 0016

 

А. ТЕРЕХОВСКИЙ


 

Убыстрение поиска файла

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

Между тем существует достаточно простой способ ускорить эту работу.

Первое условие его реализации - уточнение имеющихся на кассете измерительных линеек. На применяемых мною кассетах их заменили этикетки, показанные на рисунке. Шаг разметки равен 1,5 мм.

Второе условие - запись двух копий для каждого файла с разной плотностью записи и со строго установленной их последовательностью для всех записываемых файлов; при этом в списке файлов отмечаются положение диска МЛ, сторона и номер кассеты.

При соблюдении этих условий поиск нужного файла значительно ускоряется за счёт более точного определения его местоположения на МЛ и разной тональности записанных копий.

А. БАРСУКОВ

От редакции. Предлагаемый способ не универсален: его второе условие является одновременно и его ограничением. Действительно, соблюсти его можно только в случае копирования файлов с помощью некоторых копировщиков, позволяющих менять плотность записи. Использование более точных линеек теоретически предпочтительнее для приблизительной ориентации на ленте, но доступность их для обзора в подавляющем большинстве магнитофонов, мягко выражаясь, оставляет желать лучшего.


 

Программа "Музыкальная заставка"

Чтобы разнообразить работу на БК-0010 по озвучиванию программ, написанных учащимися на Бейсике, был разработан метод создания музыкальных подпрограмм (заставок) к этим основным программам. Музыкальные операторы в Бейсике (Вильнюс, 1987) отсутствуют, поэтому пришлось написать подпрограмму в машинных кодах.

В приводимой в качестве примера программе музыку генерирует подпрограмма на машинном языке, определённая как функция пользователя. Её текст записан в операторе DATA. Она обрабатывает символьную строку А$, в которой закодирована мелодия.

Мелодия подбирается и кодируется строками вида

А$="S5D5E5F5G5A5B5@5”
    до  ми соль си 
      ре  фа  ля  до’

Здесь буквами обозначаются соответствующие ноты, а цифрами - длительности нот. Каждая стоящая справа цифра (длительность) соответствует стоящей слева букве (ноте). Длительность может меняться от 1 (максимальная) до 9 (минимальная).

Набрав текст программы и запустив её (обычным RUN), вы услышите несколько известных мелодий.

10 '*** GSB-подпрограмма ***
20 CLS
30 L=PEEK(&O2014)
40 DEF USR=L
50 DATA 7617,60,4928,5599,240,&O177716,32257,4928,5599,144,&O177716,
   32257,32331,6080,&0177716,135,31,350,35,310,37,290,42,260
60 DATA 48,220,24,455,27,405,225,500
70 RESTORE 50
80 FOR L=L TO L+62 STEP 2
90 READ В
100 POKE L,B
110 NEXT
120 POKE L,600
130 INPUT "MELODY (1-5)";N%
140 ON N% GOSUB 220,240,260,280,300
150 K=1
160 H=(ASC(MID$(A$,K,1))-63)*4
170 POKE L,PEEK(L-H+2)*(58-ASC(MID$(A$,K+1,1)))
180 I=USR(PEEK(L-H))
190 K=K+2
200 IF K<LEN(A$) GOTO 160
210 GOTO 130
220 A$="F6E6D6C6G6G6G6F6E6D6C6G6G6F6A6A6F6E6G6G6E6D6F6F6D6C6C6" 'Весёлые гуси
230 RETURN
240 A$="C6C6F3G6A6G6F6C6C6F3G6A6A6G" 'Пусть всегда будет солнце
250 RETURN
260 А$="B8B8A8A8G8G8G8A8B8B8A8A8G4F8F8E8E8D8D8D8E8F8" '
270 RETURN
280 А$="G4E4G4E4D7E7F7D7E5C4G4E4G4E4D7E7F7D7E4A4F4A4F4E7F7G7E7F4D4A4F4A4F4E7E7G7E7F4"
    'Мама, мама, что я буду делать
290 RETURN
300 А$="D6F6A6F6G3F6E6A3G3D2" 'Подмосковные вечера
310 RETURN

Если необходимо изменить темп звучания мелодии, то надо в строке 60 после кода 500 поставить число от 10 до 200, а в строке 80 заменить число 62 на 64.

А. БУНЦЕЛЬМАН


 

Знаете ли вы, что ...

младший байт ячейки ОЗУ с номером 36 управляет режимом подчёркивания на мониторе? Если в нём записан 0, то режим выключен, иначе режим включён. Подача кода ПОДЧ в драйвер монитора меняет содержимое этого байта с 0 на 255 и с 255 на 0; если же в нём содержится число от 1 до 254, то режим подчёркивания будет включён и не будет управляем кодом ПОДЧ. Старший же байт этой ячейки таким же образом управляет режимом инверсии. Аналогично функционируют:

32 (старший байт) - управляет режимом инверсии экрана;

34 (младший байт) - режимом расширения памяти;

38 (младший байт) - режимом ИСУ;

38 (старший байт) - режимом БЛР;

40 (младший байт) - режимом ГРАФ;

40 (старший байт) - режимом ЗАП;

42 (младший байт) - режимом СТИР;

42 (старший байт) - режимом 32/64 символа в служебной строке;

44 (младший байт) - режимом ПОДЧ в служебной строке;

44 (старший байт) - режимом инверсии символа в служебной строке;

46 (младший байт) - включением/выключением курсора.

Младший байт ячейки 32 управляет числом символов в строке (0 - 64, 1 - 32).

В ячейке 88 обычно хранится число 1120. Если сюда занести 0, то блокируется клавиша К1 (первый ключ). Здесь как-то закодированы длина и начальный адрес текста первого ключа. Ключами 2-10 аналогично управляют ячейки 90-106.

Ячейка 112 содержит адрес, с которого будет выводиться на экран следующий символ. Так, если занести сюда 40 000(8), то Ок БК выдаст в левом верхнем углу экрана (предварительно нужно нажать 2 раза клавиши АР2+СБР). Таким образом можно занести любой текст в любое место памяти (не обязательно экранной; можно занести слово и в область с 0(8) до 40 000(8)).

Ячейка 114 (обычное содержимое 2) - это количество пробелов между символами, умноженное на 2. Так, если занести сюда 4, то вся информация будет отображаться на экране с одним пробелом между соседними буквами.

Ячейка 116 (обычное содержимое 1536) - это число строк экрана, доступных пользователю, умноженное на 64. Если сюда занести 128, то можно будет пользоваться лишь двумя строками.

Ячейка 132 (обычное содержимое 1024) задаёт смещение начала строки от левого края экрана. Попробуйте занести сюда 1000(8) и набрать затем несколько символов.

В ячейках 134 и 136 закодировано число строк, стираемых по коду 12 или клавишей СБР; как именно - установить не удалось. Отменяется двукратным нажатием клавиш АР2+СБР.

Каждый символ в режиме 32 символа в строке представляется в матрице 16X10 точек (16 столбцов, 10 строк). Перед тем как вывести на экран очередную строку символа, БК производит операцию логического сложения этой строки и ячейки 138; результат сложения выводится на экран. Если занести сюда, например, &В11001100 11001100, то все символы будут в красную полоску. Отменяется оператором COLOR. Аналогично используется ячейка 140, но производится логическое умножение.

И. КАНИВЕЦ

 

Performed by © gid, 2012-2022.