Д.Ю. Усенков
РЕАЛИЗАЦИЯ МНОГОЦВЕТНОЙ ЗАКРАСКИ НА БЕЙСИКЕ
(по следам одной старой ошибки)
В журнале «Информатика и образование» №2 за 1989 г. была опубликована программа для реализации 16-цветной закраски с помощью оператора Бейсика PAINT (автор - С. Зильберштейн). Кратко напомню, о чём шёл разговор. Предлагалось с помощью опубликованной программы в кодах модифицировать Бейсик таким образом, чтобы иметь возможность закрашивать замкнутые области (с помощью PAINT) произвольно выбранным цветом из 16 возможных (из них четыре стандартных), где добавочные цвета задаются пользователем с помощью оператора описания DEF С<номер цвета>=(хххх, хххх, хххх, хххх), где "хххх” - числа, кодирующие цвет.
К сожалению, в опубликованной программе оказались ошибки. Их поиск и устранение сильно усложнились из-за того, что коды были приведены в десятичном формате и отсутствовала контрольная сумма.
Сегодня среди пользователей БК уже имеется аналогичная программа в составе комплекта FBASIC, но она менее удобна - цвет приходится задавать байтами с помощью операторов РОКЕ перед каждым вызовом PAINT, что более сложно и удлиняет программу.
Всё вышесказанное побудило произвести подробный анализ, исправление ошибок и доработку старого варианта программы. И теперь вашему вниманию предлагается программа, позволяющая выполнять всё, что было обещано в упомянутом втором номере «Информатики и образования».
Ниже приводится листинг в кодах (с указанием контрольной суммы) и исходный текст на ассемблере в формате М18. Ассемблерный листинг не только поможет снизить вероятность ошибок при наборе на БК, но и даст возможность при желании легко перекомпилировать программу с другого начального адреса, задать другое количество цветов в палитре и т.д. Кроме того, весьма полезно рассмотреть ассемблер-текст поподробнее «в обучающих целях», так как он является хорошей иллюстрацией некоторых приёмов работы Бейсик-транслятора и способов вмешательства в процесс компиляции.
«Постановка задачи программисту» или «немного о возможностях программы»
Прежде чем писать программу, программист чётко формулирует для себя «техническое задание» - определяет все необходимые операции, которые должна обеспечивать программа. В нашем случае эта задача была поставлена в журнале «Информатика и образование» №2 за 1989 г., но не решена.
Итак, наша программа должна обеспечивать:
- Заливку с помощью PAINT неким дополнительным цветом (грамотнее было бы говорить о цвете и фактуре закраски), заданным пользователем. При этом пользователь задаёт вид элементарного «макро-пиксела», состоящего из 4*4 точек.
- Возможность указания номера, выбранного для закраски дополнительного цвета непосредственно в операторе PAINT, как обычно указывается стандартный цвет заливки. При этом программа должна обеспечивать распознавание номеров стандартных цветов (от 0 до 4) и нестандартных (от 5 до 15). Если задан стандартный цвет, заливка должна производиться как обычно.
- Возможность задания цвета и фактуры для любого нестандартного «цвета» палитры с помощью оператора DEF С<номер>=(хххх, хххх, хххх, хххх), где «хххх» - числа из 4 цифр, определяющие четыре строки «макро-пиксела»:
макро-пиксел запись оператора DEF C<n> = (1111, 1212, 3322, 4344) ┌─────┬─────┬─────┬─────┐ │ │ │ │ │1 │1 │1 │1 │ │ │ │ │ │ │ │ │ ├───┘ │ │ │ ├─────┼─────┼─────┼─────┤ │ │ │ │1 │2 │1 │2 │ │ │ │ │ │ │ │ ├─────────┘ │ │ ├─────┼─────┼─────┼─────┤ │ │ │3 │3 │2 │2 │ │ │ │ │ │ │ ├───────────────┘ │ ├─────┼─────┼─────┼─────┤ │ │4 │3 │4 │4 │ │ │ │ │ │ ├─────────────────────┘ └─────┴─────┴─────┴─────┘
(цифры 1...4 обозначают общепринятые номера цветов точек, т.е. 1-красный, 2-зелёный, 3-синий, 4-чёрный)
Исходя из этого видно, что алгоритм нашей программы должен включать в себя как минимум три части: алгоритм закраски, алгоритм перехвата и обработки ошибки при задании нестандартного номера цвета в PAINT и алгоритм перехвата синтаксической ошибки при трансляции не предусмотренного в Бейсике оператора DEF С...
Отдельно рассмотрим одну из этих частей - алгоритм многоцветной закраски. Остальные части достаточно хорошо просматриваются при анализе листинга программы на Ассемблере.
Алгоритм многоцветной закраски
Проще всего получить новый цвет, загружая в служебные ячейки Монитора (@#212 - фон, @#214 - передний план) вместо стандартных байтов, кодирующих цвета (177777 - красный, 125252 - зелёный, 52525 - синий, 0 - чёрный), свои значения, кодирующие нужный цвет. Подробно об этом было рассказано в журнале «Вычислительная техника и её применение» № 12 за 1990 г., с. 31. Однако простая подстановка имеет существенный недостаток: получаемый при заливке цвет оказывается всегда «в вертикальную полоску».
В программе GRAF3 применён более совершенный алгоритм: для первой телевизионной строки используется «основной» байт, для второй - тот же байт предварительно проворачивается влево и только затем заносится в ячейку @#214, для третьей строки - ещё раз влево и т.д. Но и у этого алгоритма свой недостаток: он хорошо реализует простые «смесевые» цвета (темно-красный, тёмно-зелёный, тёмно-синий, жёлтый, фиолетовый и голубой, то есть состоящие из «сетки» точек двух каких-нибудь стандартных цветов), а также «гладкие» стандартные цвета. Но вот попытка задать «белый» цвет (смесь трёх цветов) или задать более редкое расположение точек одного цвета по отношению к другому (например, на три черные точки одна зелёная) оканчивается неудачей: проступает явная «полосатость» получаемой закраски либо производится простая «заштриховка» наклонными линиями.
Мы же применим алгоритм ещё более совершенный, и в то же самое время простой. Пусть пользователь сам задаёт четыре отдельных байта для закраски. Тогда можно будет при желании сделать и «сетку», и «штриховку», и сложную фактуру. А наша программа будет всего лишь подставлять в ячейку @#214 один из этих байтов в соответствии с координатой Y требуемой точки, то есть для нулевой строки - первый байт из четырёх, для первой строки - второй, для второй - третий, для третьей - четвёртый, для четвертой - снова первый и т.д.
Итак, новая программа должна перехватывать ЕМТ 30 и ЕМТ 32, определять, относятся ли эти функции к реализации оператора PAINT (ведь нам не нужно менять цвета для LINE, PSET и т.д.), вычислять по значению хранящейся в R2 координаты Y адрес байта в палитре, где записаны по 4 байта на каждый цвет, заносить выбранный байт в ячейку @#214 и после установки точки или линии не забывать восстановить старый цвет рисования. Проще всего это реализовать так: сохраним в стеке значение R2, выделим из него три младших бита - останется число от 0 до 3, прибавим это число к хранящемуся в ячейке @#300 (она используется только при операциях обмена с магнитофоном и мы можем использовать её как буфер) адресу первого байта палитры, соответствующего указанному ранее номеру цвета, занесём байт в ячейку @#214, сохранив предварительно в стеке старое значение из этой ячейки, восстановим истинное значение R2 и отработаем ЕМТ 30 или ЕМТ 32, а затем восстановим из стека старое значение ячейки цвета.
Именно так и сделано в программе. Мы можем увидеть это в первой части листинга, «посвящённой» ЕМТ-перехвату.
Программа начинается с ЕМТ-драйвера. Мы перехватываем на него ЕМТ-прерывание и по сохранённому в стеке адресу возврата определяем точное место, откуда был вызван ЕМТ (из PAINTa, из LINE или откуда-нибудь ещё). Для такой работы полезно иметь ассемблеровский листинг Бейсик-транслятора. (Этот листинг, а также листинг Монитора БК-0010 редакция планирует опубликовать в одном из выпусков приложения к ИНФО - «Персональный компьютер БК-0010 - БК-0011М».)
Если «пойманный» ЕМТ не тот, который нам нужен, производим переход на стандартный драйвер обработки ЕМТов по адресу 100112.
Кстати, нет нужды делать отдельные реализации замены цвета для ЕМТ 30 и ЕМТ 32. В нашей программе производится определение (опять-таки по адресу, с которого был вызван ЕМТ) типа функции (ЕМТ30 или ЕМТ32) и нужный машинный код заносится непосредственно «в тело» самой программы, а затем, после замены цвета, выполняется.
Далее, нам нужно производить перехват ошибок Бейсика. Для этого мы пишем свой драйвер TRAP-прерываний. И первая же строка нашей программы, первое же действие, производимое при любом ЕМТ-прерывании - занесение нового значения адреса обработки прерываний TRAP. Ну а в самом драйвере TRAP мы производим аналогичным способом (по адресам вызова) анализ TRAP-функций, чтобы выделить среди всех возможных вызовов сообщений об ошибках, а также (не следует об этом забывать) вызовов TRAP-подпрограмм самого Бейсика нужные нам ошибку цвета в PAINT и ошибку синтаксиса в DEF. Остальные TRAPы перенаправляем на стандартную обработку.
Если посмотрим на ассемблеровский листинг, то увидим три анализируемых случая TRAP. Во-первых, мы перехватываем первый же служебный TRAP при компиляции оператора PAINT. Это не ошибка, а признак «для нас»: пора вставить в шитый код адрес маленькой самодельной подпрограммки, которая при работе уже откомпилированной Бейсик-программы будет производить исходное обнуление буферной ячейки @#300 перед каждым оператором PAINT (зачем - обсудим позже).
Во-вторых, отлавливается сообщение об ошибке, когда при работе откомпилированной Бейсик-программы БК «замечает», что PAINT задан номер цвета более 4. Теперь нам нужно «сделать вид», что ошибки не было. Мы прежде всего определяем «оставшийся» в R0 после компиляции заданный нами нестандартный номер цвета и вычисляем по нему адрес первого байта из четырёх отведённых для этого цвета в палитре. Записываем адрес в ячейку @#300. Заменяем «условно» цвет закраски на текущий (О), чтобы Бейсик «больше не ругался», и «как ни в чём не бывало» продолжаем работу, переходя к следующему шитому коду. (Разумеется, уже произведена «нормализация» стека, то есть с помощью команды CMP (R6)+,(R6)+ удалены занесённые туда при вызове TRAP четыре байта.)
Затем, уже при постановке точек и линий, ЕМТ-перехватчик заменит «условный» цвет заливки на заданный нами через значение ячейки @#300. Заметим, что если мы задали в PAINT стандартный номер цвета от 0 до 4, то этой ошибки не возникнет, ячейка @#300 останется обнуленной, как это сделала подпрограммка, рассмотренная нами «во-первых», а при отработке ЕМТ наша программа не будет заменять цвет закраски, а просто выведет точку или линию заданным стандартным цветом. Таким образом реализовано одно из дополнительных условий задачи - если цвет стандартный закраска производится как обычно.
И в-третьих, отлавливаем ошибку при компиляции DEF. Точно так же нормализуем стек, а затем выполняем вместо вильнюсского транслятора его работу, то есть сами компилируем наш оператор DEF С<n>=... .
Для этого вначале убираем лишние пробелы между «DEF» и «С» с помощью служебной функции TRAP112. Проверяем, совпадает ли текущий символ исходного текста на Бейсике с символом «С» (латинское заглавное). При компиляции регистр R3 содержит адрес текущего байта исходного текста и мы это используем Если текущий символ не «С», значит, мы действительно ошиблись в Бейсик-программе, и мы генерируем запоздалое TRAP2. Если не ошиблись, продолжаем. Снова убираем незначащие пробелы (если они есть) между «С» и номером цвета с помощью TRAP112. Вызываем подпрограмму, считывающую записанное в десятичной форме в исходном тексте число - номер цвета в палитре и заносим номер в R5 Подпрограмма чтения номера (NUM) сама следит и за синтаксисом (чтобы номер не содержал нецифровых символов), и за значением номера (не менее 5 и не более 15), выдавая в некорректном случае «ОШИБКУ 2». Вновь вызываем TRAP112 для ликвидации пробелов перед знаком равенства и проверяем, действительно ли это знак равенства.
Теперь с помощью другой служебной функции TRAP127 производим поиск открывающей скобки (TRAP127 пропускает пробелы в исходном тексте и возвращает в R3 адрес первого непробельного байта после найденной открывающей скобки). И с помощью подпрограммы PPR анализируем четыре записанных через запятую числа. Сначала первое, мы «на нём стоим». Потом вызываем спецфункцию TRAP126, которая выводит нас аналогично TRAP127 на первый непробельный байт после запятой, и снова вызываем подпрограмму PPR для второго числа. Сделав так четыре раза для четырёх чисел, вызываем TRAP130, которая, аналогично двум предыдущим спецфункциям, возвращает адрес после закрывающей скобки и, наконец, с помощью TRAP106, отсекающей попутно комментарии, переходим на следующую строку исходного Бейсик-текста. И вот теперь возвращаемся в стандартный компилятор.
Как работает подпрограмма PPR, думаю, не стоит разбирать подробно. Это можно сделать и самостоятельно по ассемблер-тексту.
И в качестве своеобразного «резюме» повторим ещё раз сведения об используемых при компиляции регистрах процессора и служебных TRAP-подпрограммах.
ПРИ КОМПИЛЯЦИИ ИСПОЛЬЗУЮТСЯ:
- Регистры:
R3 - адрес текущего байта исходного текста Бейсик-программы (указатель на текущий байт);
R1 - адрес текущей ячейки для записи шитого кода.
- Служебные TRAP-функции:
TRAP 112 - тестирует текущий байт исходного текста и, если это пробел, смещает указатель «вправо», пока не встретит непробельный символ. Таким образом, при компиляции реализуется пропуск незначащих пробелов;
TRAP 127 - аналогичным образом пропускает пробелы, а затем проверяет: если очередной, непробельный символ - открывающая скобка ("("), снова пропускает пробелы после скобки и возвращает в R3 адрес первого непробельного символа в скобках. Если не скобка, генерируется ОШИБКА 2;
TRAP 126 - аналог предыдущей функции, «натасканный» на запятую (",");
TRAP 130 - аналог двух предыдущих по отношению к закрывающей скобке (")");
TRAP 106 - пропускает все байты исходного текста, пока не встретится код 12 - код конца строки. Возвращает в R3 адрес первого байта следующей строки и используется как «завершающий аккорд» при компиляции каждой из строк Бейсик- программы. Кстати, отсекает дополнительные комментарии;
TRAP с номерами менее 100 генерируют текст «ОШИБКА n», где n - номер ошибки, равный номеру TRAP-функции. В Бейсик-трансляторе задействованы не все номера ошибок из возможных, так что при желании вы можете предусмотреть в своих программах свои номера сообщений об ошибках. Нужно только подать TRAP<номер>, а остальное Бейсик сделает сам.
Правила работы с программой
Программа в машинных кодах 16PAIN.BIN должна быть считана в Бейсик с адреса &037300 с помощью оператора BLOAD. Предварительно нужно выполнить оператор CLEAR ,&О37300. Перед компиляцией (то есть ДО ввода команды RUN!) нужно занести адрес начала программы (в нашем случае 37300) в ячейку @#30 оператором POKE &О30,&О<нач.адрес>, набранным в непосредственном режиме. После этого Бейсик-программа запускается на выполнение как обычно.
В Бейсик-программе допустимы операторы:
DEF С<номер> = (хххх, хххх, хххх, хххх) - задание цвета, <номер> - от 5 до 15;
PAINT (X, Y),<номер>,<цвет границы> - закраска внутри контура, <номер> - от 0 до 15, <цвет границы> - от 0 до 4.
Желающие могут перекомпилировать ассемблерный текст в системе типа М18, заменив начальный адрес программы на требуемый (программа неперемещаема). При этом можно также расширить размер палитры, для чего в помеченных звёздочками строках нужно изменить значения констант:
#460 заменить на большее, увеличивая на 4 для каждого добавляемого цвета (при этом уменьшается «действующий» объём стека, и вы тем самым уменьшаете возможности Бейсик-программы);
#17 заменить на новый максимально допустимый номер цвета в палитре.
; ; Драйвер многоцветной графики для оператора PAINT Вильнюсского ;Бейсика (исправленный вариант программы из «ИНФО» №2 за 1989г) ; -------------------------- SCREW(c) ------------------------- ; ; Усенков ДЮ. МОСКВА 1992 ; ;============================================================== ; Новый EMT-драйвер: %EMT: MOV #%TRAP,@#34 ; Новый вектор TRAP ; Проверка: откуда вызван ЕМТ? CMP @R6,#126264 ; ЕМТ30 реализации PAINT? BNE I1 ; I2: MOV #104030,KOMMD ; ДА! BR I3 ; I1: CMP @R6,#126310 ; ЕМТ30 также из PAINT? BEQ I2 ; ДА-переход, нет- проверка: CMP @R6,#126320 ; ЕМТ32 из реализации PAINT? BNE A1 ; MOV #104032,KOMMD ; I3: MOV @#214,-(R6) ; Старый цвет закраски - в стек TST @#300 ; Цвет закраски-стандартный? BEQ KOMMD ; ДА-сразу на вывод точки/линии MOV R2,-(R6) ; НЕТ-формируем цвет закраски: CMP R6,#460 ; * ; Не затер ли стек палитру цветов? BHI I4 ; НЕТ-формируем цвет MOV 2(R6),@#214 ; ДА-восстановим старый цвет за- TRAP 7 ; краски и выводим "ОШИБКУ 7" I4: BIC #177774,R2 ; Формируем цвет заливки по коор- ADD @#300,R2 ; динате Y и номеру цвета из ячейки MOVB @R2,@#214 ; @#300 MOV (R6)+,R2 ; Восстанавливаем значение Y KOMMD: EMT 30 ; Рисуем точку/линию MOV (R6)+,@#214 ; Восстанавливаем цвет закраски. RTI ; Выход из ЕМТ A1: JMP @#100112 ; Для других ЕМТ-на стандартный ; драйвер ERR: JMP @#146404 ; Стандартный драйвер TRAP ; Новый драйвер TRAP: %TRAP: CMP 4(R6),#145230 ; Компиляция PAINT? BNE A2 ; MOV #X1V,(R1)+ ; ДА-заносим в шитый код свой код BR ERR ; и продолжаем трансляцию X1V: CLR @#300 ; Подпрограмма предварительного JMP @(R4)+ ; обнуления номера цвета A2: CMP @R6,#125172 ; Ошибка при отработке PAINT: не- ; стандартный номер цвета? BNE A3 ; CMP (R6)+,(R6)+ ; ДА-нормализуем стек, SUB #5,R0 ; вычисляем по номеру заданного в ASL R0 ; PAINT цвета номер в палитре, по- ASL R0 ; мещаем его в ячейку @#300, для ADD #400,R0 ; ’’маскировки” ошибки назначаем MOV R0,@#300 ; цвет, равный 0, и возвращаемся CLR @R6 ; в программу отработки PAINT JMP @(R4)+ ; A3: CMP @R6,#145566 ; Ошибка при компиляции DEF Сп=..? BNE ERR ; НЕТ - на стандартный драйвер CMP (R6)+,(R6)+ ; ДА-нормализуем стек, TRAP 112 ; убираем лишние пробелы, CMPB (R3)+,'C' ; это наш DEF С? BNE SYERR ; Нет-ошибка 2 TRAP 112 ; убираем лишние пробелы после "С", JSR R7,NUM ; считываем номер цвета BR B ; SYERR: TRAP 2 ; выход на сообщение об ошибке B: TRAP 112 ; убираем лишние пробелы перед CMPB (R3)+,'=' ; дальше идет код "="? BNE SYERR ; НЕТ-ошибка 2 TRAP 127 ; ищем открывающую скобку SUB #5,R5 ; формируем адрес ячеек палитры ASL R5 ; для данного цвета ASL R5 ; ADD #400,R5 ; MOV #3,-(R6) ; Формируем составляющие байты A: JSR R7,PPR ; п/пр чтения очередного числа TRAP 126 ; ищем запятую DEC @R6 ; BGT A ; TST (R6)+ ; JSR R7,PPR ; последнее число TRAP 130 ; поиск закрывающей скобки TRAP 106 ; выход на следующую строку Бейсик ; программы RTS R7 ; выход на продолжение компиляции ; PPR: CLR -(R6) ; Подпрограмма формирования байтов: MOV #4,R2 ; AA: ASR @R6 ; загружает очередное 4-цифровое ASR @R6 ; число из списка и формирует по MOVB (R3)+,R4 ; нему байт для палитры SUB #64,R4 ; NEG R4 ; CMP R4,#3 ; BHI SYERR ; SWAB R4 ; ASR R4 ; ASR R4 ; BIS R4,@R6 ; SOB R2,AA ; MOV (R6)+,R4 ; MOVB R4,(R5)+ ; Готовый байт заносим в палитру RTS R7 ; ; ; Подпрограмма чтения цвета: NUM: MOV R0,-(R6) ; CLR R5 ; 1: CMPB @R3,'0' ; заносит в R5 номер цвета, за- BLO 2 ; данного в описании DEF С<номер> CMPB @R3,'9' ; BHI 2 ; ASL R5 ; MOV R5,R0 ; ASL R5 ; ASL R5 ; ADD R0,R5 ; MOVB (R3)+,R0 ; SUB '0',R0 ; BIC #177400,R0 ; ADD R0,R5 ; BR 1 ; 2: CMP R5,#5 ; BLO 3 ; CMP R5,#17 ; * ; Ограничение кол-ва цветов BHI 3 ; MOV (R6)+,R0 ; RTS R7 ; ; ; 3: TRAP 2 ; Ошибочный номер цвета ; ;--------------------------------------------------------------
Кодовый листинг программы 16PAIN.BIN
НАЧ. АДРЕС : 037300 ДЛИНА : 000500
012737 |
037436 |
000034 |
021627 |
126264 |
001004 |
012767 |
104030 |
000074 |
000411 |
021627 |
126310 |
001771 |
021627 |
26320 |
001033 |
012767 |
104032 |
000050 |
013746 |
000214 |
005737 |
000300 |
001417 |
010246 |
020627 |
000460 |
101004 |
016637 |
000002 |
000214 |
104407 |
042702 |
177774 |
063702 |
000300 |
111237 |
000214 |
012602 |
104030 |
012637 |
000214 |
000002 |
000137 |
100112 |
000137 |
146404 |
026627 |
000004 |
145230 |
001006 |
012721 |
037454 |
000767 |
005037 |
000300 |
000134 |
021627 |
125172 |
001013 |
022626 |
162700 |
000005 |
006300 |
006300 |
062700 |
000400 |
010037 |
000300 |
005016 |
000134 |
021627 |
145566 |
001343 |
022626 |
104512 |
122327 |
000103 |
001004 |
104512 |
004767 |
000134 |
000401 |
104402 |
104512 |
122327 |
000075 |
001373 |
104527 |
162705 |
000005 |
006305 |
006305 |
062705 |
000400 |
012746 |
000003 |
004767 |
000022 |
104526 |
005316 |
003373 |
005726 |
004767 |
000006 |
104530 |
104506 |
000207 |
005046 |
012702 |
000004 |
006216 |
006216 |
112304 |
162704 |
000064 |
005404 |
020427 |
000003 |
101333 |
000304 |
006204 |
006204 |
050416 |
077216 |
012604 |
110425 |
000207 |
010046 |
005005 |
121327 |
000060 |
103417 |
121327 |
000071 |
101014 |
006305 |
010500 |
006305 |
006305 |
060005 |
112300 |
162700 |
000060 |
042700 |
177400 |
060005 |
000756 |
020527 |
000005 |
103405 |
020527 |
000017 |
101002 |
012600 |
000207 |
104402 |
000000 |
000000 |
000000 |
КОНТРОЛЬНАЯ СУММА: 011047
И.А. Сапегин
О ПРИРУЧЕНИИ КЛАВИШИ "СТОП"...
В ИНФО №2 за 1992 г. была напечатана статья Д. Якошвили "Обработка прерываний по клавише СТОП средствами Бейсика". Способ определения адреса начала "шитого кода" строки, предложенный автором, имеет несколько недостатков. Во-первых, он очень трудоёмкий. Во-вторых, даже при небольшом изменении программы приходится проводить всю работу заново.
Я предлагаю программу, свободную от этих недостатков:
1 FOR I=РЕЕК(1044)+4 ТО 16384 STEP 6 2 IF ABS(65536*(SGN(PEEK(I))-1))/2+PEEK(I)=<A> THEN POKE 514,PEEK(I-4) ELSE 7 3 POKE 512,5572 4 POKE 516,92 5 POKE 4,512 6 GOTO 10 7 NEXT I 10 REM ...ВАША ПРОГРАММА...
Во второй строке <А> - это номер строки в вашей программе, куда нужно перейти при нажатии клавиши СТОП.
При запуске программа сама определит адрес начала "шитого кода” нужной строки. Для этого используется таблица номеров строк, адрес начала которой записан в ячейке 1044 (здесь и далее все адреса десятичные). В этой таблице для каждой строки записано три параметра: адрес начала "шитого кода” строки, адрес начала её исходного текста и номер.
Моя программа последовательно просматривает все номера строк в этой таблице и, найдя требуемый, записывает адрес начала ’’шитого кода", соответствующего нужной строке, в ячейку 514.
Подпрограмма в машинных кодах, расположенная в памяти с адреса 512 и заносимая туда строками 3 и 4, работает так, как написано в статье Д. Якошвили.
ОТ РЕДАКЦИИ
Письмо И.А. Сапегина продолжает начатую в прежних публикациях тему о "приручении" клавиши СТОП в Бейсике. Предлагаемая им программа позволяет "подвешивать" клавишу СТОП на нужную строку полностью автоматически, не производя при этом длительных и запутанных ручных расчётов и поисков, описанных в статье Д. Якошвили.
Хотелось бы добавить к сказанному автором следующее. Во-первых, в программе не предусмотрен контроль за существованием строк, и, если в качестве <А> вы зададите номер несуществующей строки, реакция БК будет, мягко говоря, непредсказуемой. Во-вторых, если ваша программа не изменяет искусственно при своей работе шитый код и содержимое ячейки @#4, то после выхода из программы в диалоговый режим по оператору STOP или END нажатие на клавишу СТОП по-прежнему вызывает переход на заданную Бейсик-строку. Таким образом данный эффект даёт возможность повторного запуска Бейсик-программы, заменяя собой команду RUN <номер строки> или GOTO <номер строки>.
Р. Аскеров
ЕСЛИ НЕТ ПРИНТЕРА...
... и вам нужна копия с экрана БК, и не одна - как быть? Если у вас есть фотоаппарат и вы можете подключить свой компьютер к телевизору с размером экрана по диагонали 50-60 см, то нет проблем!
После длительных экспериментов в Брянском клубе пользователей БК разработана методика съёмок с экрана ТВ. Использовался дальномерный фотоаппарат ФЭД5В и черно-белый телевизор КАСКАД-230 с диагональю 59 см. Аппарат устанавливается на штативе (впрочем, снимать можно и «с рук», жертвуя при этом чёткостью) на расстоянии 1 м от экрана, видоискатель наводится на точку, отстоящую на 13 см от верхней кромки экрана и на 23 см от левой. На шкалах фотоаппарата устанавливаются значения выдержки 1/30, диафрагмы 2.8, дальности 1 м. Спуск затвора можно производить как через фототросик, так и непосредственным нажатием на кнопку.
На негативах изображение получается чётким, во весь кадр, и в дальнейшем может быть увеличено в любое количество раз и переведено на фотобумагу. К сожалению, при использовании некоторых видов плёнки изображение может оказаться слегка неравномерным по яркости из-за особенностей телевизионного экрана.
ПРИМЕЧАНИЕ РЕДАКТОРА
Данный совет полезен не только пользователям БК, но и всем, кто работает с домашними ПЭВМ, тем более что многие «самодельные» компьютеры вообще не рассчитаны на подключение принтера. Практическая ценность предложенного Брянским клубом пользователей БК совета значительно повышается и за счёт того, что в нём приведены готовые рекомендации при пересъёмке изображения на экране с помощью фотоаппарата с видоискателем, а работать таким фотоаппаратом в подобных случаях намного сложнее, чем зеркальной фотокамерой.
Следует также сказать, что и на профессиональных персональных компьютерах в составе графических станций, оснащённых принтерами и графопостроителями, также используется фотографическая пересъёмка изображения на экране с помощью специализированных фотокамер. Подробнее об этом можно узнать из книги «Компьютер обретает разум» (М.: Мир, 1990, с. 138).
Однако справедливости ради следует заметить, что предлагаемая идея использования фотоаппарата для получения копии экрана на БК не нова. О ней, в частности, говорилось на страницах журнала «Наука и жизнь» (1986, №10, с. 113, заметка читателя И. Львова из Москвы). В «Науке и жизни» предлагалось производить пересъёмку с экрана зеркальной фотокамерой «Зенит» со штатива в затемнённой комнате (для устранения бликов на экране) Объектив «Волна-9», плёнка 32 или 65 ед. ГОСТ. Диафрагма 5.6 - 8 с выдержкой 3 - 4 с для 32 ед или 1 - 2 с для 65 ед. (выдержка отрабатывается вручную). Проявитель стандартный, время проявления - указанное на коробочке с плёнкой.