Диалекты бейсика для ZX Spectrum 1992 г.

Beta Basic - Обработка ошибок, трассировка, часы.


ОБРАБОТКА ОШИБОК, ТРАССИРОВКА, ЧАСЫ

ON ERROR, TRACE, CLOCK, TIME$ ()

ON ERROR < номер строки >

Этот оператор не производит явных действий в момент выполнения. Он лишь указывает интерпретатору номер строки, с которой начинается подпрограмма обработки ошибок. Если во время выполнения программы возникнет ситуация, приводящая к выдаче сообщения об ошибке, управление будет немедленно передано подпрограмме, начинающейся с указанной строки. Операторы ON ERROR 0, RUN и CLEAR восстанавливают обычный режим обработки ошибок.

Задать подпрограмму обработки ошибок можно и непосредственно сразу после оператора ON ERROR, используя следующий формат:

ON ERROR: <оператор>:<оператор>:...<оператор>: RETURN

Для наглядности вместо набора операторов можно просто указать имя процедуры обработки ошибок, а саму процедуру оформить отдельным программным модулем.

Проанализировать причины, приведшие к ошибке, и определить место в программе, где она произошла, помогут специальные системные переменные Beta Basic. К ним, в отличие от обычных системных переменных ZX Spectrum, имеется доступ по именам, как к обычным числовым переменным: переменная с именем ERROR содержит код возникшей ошибки (информация о кодах ошибок приводится в Приложении 3). Переменные LINO и STAT указывают, соответственно, номер строки и номер оператора в строке, где была прервана работа программы. Эта информация позволяет предусмотреть подходящую реакцию на ошибку в зависимости от вызвавшей ее причины:

10 ON ERROR 1000: LET J=1 30 FOR K=1 TO 10000 40 PLOT INT (25794RND),INT (178*RND) 50 NEXT K: STOP 1000 REM Начало подпрограммы обработки ошибок 1010 ВЕЕР 1,69

1020 IF ERROR=11 AND LINO=40 THEN PRINT AT 0,0;J: J=J+1:

ELSE BEEP 0.5,12 1030 RETURN

Фрагмент программы (строки 30...50) выводит на экран точки со случайными значениями координат, которые могут выходить за допустимые пределы (Х>255, Y>175). Обычно попытка поставить точку за пределами экрана приводит к ошибке с выдачей сообщения Integer out of range. Но в данном примере строка 10 предписывает в случае ошибки обращаться к подпрограмме, начинающейся со строки 1000. В ней анализируется, вызвано ли прерывание ошибкой выхода за пределы экрана, и если «да», то на экран выводится номер J такого «выхода», после чего управление возвращается в основную программу. Если попытаться сгенерировать ошибку с другим кодом, например, нажать Break, то программа, подав звуковой сигнал (оператор ВЕЕР в строке 1020), продолжит свою работу.

На время выполнения подпрограммы обработки ошибок «антиошибочный иммунитет» отключается. Поэтому, если не предусмотреть необходимой защиты, то при нажатии клавиши Break программа остановится, поскольку переход к подпрограмме обработки ошибок произойдет еще до того, как будет отпущена клавиша. Во избежание такой ситуации в начале подпрограммы обработки ошибок нужно всегда организовывать задержку, достаточную для того, чтобы успеть освободить клавишу Break. В нашем примере это сделано в строке 1010с помощью оператора ВЕЕР, звучащего в неслышимом диапазоне частот (ВЕЕР не реагирует на нажатие Break).

Вернуться из подпрограммы обработки ошибок можно двумя способами. Первый способ — по RETURN (как в приведенном примере), когда управление передается оператору, следующему за тем, который вызвал ошибку*, a ON ERROR опять активен — готов к охоте за ошибками. Второй способ — по CONTINUE, после которого действие оператора ON ERROR отключается, а управление (за редкими исключениями) вновь возвращается оператору, вызвавшему ошибку. Повторное выполнение этого оператора приведет к привычному останову программы с выдачей сообщения об ошибке. Пользуясь этими двумя способами, в подпрограмме обработки ошибок можно предусмотреть выбор: в зависимости от места возникновения ошибки или ее типа работа программы продолжается либо прекращается.

Следует помнить, что, возвращаясь из подпрограммы по CONTINUE, необходимо предварительно снять со стека GO SUB адрес возврата из подпрограммы, так как оператор CONTINUE сам этого не делает. Операцию по очистке вершины стека GO SUB производит оператор POP (его работа описана далее). Поэтому возврат по CONTINUE в приведенном выше примере должен выглядеть так:

1030 POP: CONTINUE

После того как в программе встретится оператор трассировки

TRACE <номер строки)

или

TRACE: <оператор>:<оператор):...<оператор>: RETURN

- интерпретатор, после каждого выполненного оператора, будет делать переход к подпрограмме, расположенной с указанного < номера строки) или размещенной непосредственно за оператором TRACE после двоеточия. Это будет происходить до тех пор, пока в программе не встретится оператор TRACE 0 или CLEAR. Пользуясь этим свойством, можно замедлять выполнение программы, отслеживать по ее ходу изменения значений переменных, следить за состоянием клавиатуры (не нажималась ли какая-либо клавиша) и т. д. Поместим в начало предыдущего примера строку

1 TRACE 2000

- а также добавим следующий фрагмент:

2000 REM Подпрограмма трассировки 2005 WINDOW 1;140г175,115,64 2010 WINDOW 1: CLS: CSIZE 4,8: DEFAULT K=0 2020 LIST LINO TO LINO: PRINT AT 7,0;"K=";K 2030 PRINT #0; AT 0,0; "String ";LINO;":";STAT; 2040 PAUSE 0: CLS: WINDOW 0: CSIZE 4,8 2050 RETURN

Теперь можно ^выполнить программу в пошаговом режиме. В правом верхнем углу экрана (строки 2005, 2010) будут выводиться исполняемая в настоящий момент строка программы и текущее значение переменной К (строка 2020). В нижней части эк^на будет выводиться цомер строки и номер выполняемого оператора в ней (строка 2030). Для осуществления следующего шага необходимо нажимать клавишу Enter (строка 2040). Заменив в 2040-й строке оператор PAUSE 0 на IF INKEY$="1" THEN POP: STOP, можно сделать так, чтобы программа работала без пауз и останавливалась при нажатии клавиши 1.

257

9 Зак. № 192

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

CLOCK <чиспо|строка символов)

Этот оператор управляет часами с «боем», встроенными в Beta Basic: устанавливает текущее время, высвечивает его в верхнем правом углу экрана, задает контрольный час, минуту и секунду, когда необходимо подать звуковой сигнал и/или передать управление подпрограмме.

При загрузке Beta Basic устанавливается время 00:00:00. Для переустановки времени нужно выполнить оператор CLOCK в следующем формате:

CLOCK <"HH[:]MM[:]SS">

- где НН — часы, ММ — минуты, SS — секунды. Разделители (двоеточия) между цифрами можно опускать, достаточно ввести 6 цифр. В случае, если количество цифр окажется меньшим, вместо недостающих будут подставлены нули. Так, например, CLOCK "173" установит время 17:30:00.

Для настройки будильника, который в назначенное время подаст звуковой сигнал и/или передаст управление подпрограмме, к строке символов, задающей время, в первую позицию добавляется символ А:

CLOCK "А09:45"

Режим работы часов задается оператором

CLOCK <код режима)

Всего имеется 8 режимов работы, они перечислены в табл. 18.

Таблица 18. Режимы работы оператора CLOCK.

Кой

режима

Индикация аремени

Подача заукоаого сигнала

Переход к подпрограмм*

0

-

-

-

1

+

-

-

2

-

+

-

3

+

+

-

4

-

-

+

5

+

-

+

6

-

+

+

7

+

+

+

Так, к примеру, CLOCK 7 установит режим, в котором текущее время будет высвечиваться на экране, а в заданный момент прозвенит будильник и произойдет обращение к подпрограмме. Номер строки, с которой начинается подпрограмма, задается оператором вида:

CLOCK <номер строки)

- где <номер строки) — число от 8 до 9999 (числа от 0 до 7 зарезервированы под номера режимов). Возможно также размещение подпрограммы непосредственно за оператором CLOCK через двоеточие:

CLOCK: <оператор>:<оператор>:...<оператор>: RETURN

Следует учитывать, что часы, прежде чем «зазвенеть» при достижении контрольного времени, ждут окончания выполнения теку-щей строки программы, что иногда может длиться долго (например, ввод с клавиатуры' выполнение оператора PAUSE).

Часы Beta Basic поддерживают также символьную функцию

Т1МЕ$ ()

— возвращающую значение текущего времени в виде строки символов, в которой часы, минуты и секунды разделены знаком двоеточия.

Нужно иметь в виду, что часы приостанавливают отсчет времени при генерации звукового сигнала оператором ВЕЕР и one-рациях с внешними устройствами (в частности, магнитофоном).

Описанные свойства оператора CLOCK позволяют создавать программы, которые через заданные интервалы времени приостанавливают работу, проделывают некие запрограммированные действия, а затем снова продолжают свое дело. Предположим, что к компьютеру подключен цифровой прибор, с которого необходимо снимать данные каждые 10 секунд. Основная программа производит обработку данных (к примеру, выводит на экран диаграмму показаний прибора, делает статистический анализ и т. д.). А подпрограмма, к которой происходит обращение в заданное время, считывает очередное показание прибора (например, из порта 104) и помещает его в специальный массив. Последний служит кольцевым буфером для согласования времени обработки данных в основной программе с частотой их поступления подпрограммы. Подпрограмма также устанавливает новое значение контрольного времени для снятия очередного показания прибора. Программа обслуживания прибора может выглядеть так:

10 CLOCK 6: REM Установка режима работы часов 20 CLOCK:PortRead: RETURN: REM задание имени процедуры 30 LET Мах=3000: REM Задание размера массива-буфера 40 DIM А(Мах): REM Инициализация массива 50 LET Mldx=0, Sldx=0: REM Инициализация указателей массива 60 PROC PortRead: REM Вызов процедуры считывания 100 LET Mldx=Mldx+1: IF Mldx>Max THEN LET Mldx=!

120 IF A(Mldx)=0 THEN GO TO 120: REM Ожидание новых данных 130 LET Value=A(Mldx): LET A(Mldx)=0

... (обработка показаний прибора) 7000 GO TO 100: REM Возврат к началу цикла

9000 DEF PROC PortRead: REM Процедура считывания показаний прибора

9010 LET Sldx=Sldx+1: IF Sldx>Max THEN LET Sldx=1

9030 LET A(Sldx)=IN 104: REM Считывание данных из порта

9040 CLOCK "00:00:00": REM Сброс часов

9060 CLOCK "А00:00:10": REM Время следующего «звонка»

9070 END PROC

В данном примере первые показания снимаются при принудительном обращении к подпрограмме считывания данных (строка 60), а все остальные — при вызове этой подпрограммы по прерыванию от таймера. Если основная программа опережает поступление данных, она ожидает их в бесконечном цикле (строка 120).

Другой пример использования оператора CLOCK и функции Т1МЕ$ можно найти в разделе, описывающем циклы типа DO...LOOP (стр. 266).




СОДЕРЖАНИЕ:
  1. Laser Basic - Вывод спрайтов на экран; Вывод на экран части спрайта; Перенос атрибутов; Преобразование окна экрана; Наборы переменных; Перемещение спрайтов; Наложение спрайтов; Копирование изображения с экрана в спрайт; Преобразование спрайтов; Скроллинг пейзажа; Изменение размеров области спрайт-файла; Вспомогательные графические операторы и функции; Определение столкновений спрайтов; Сервисные операторы и функции; Процедуры; Загрузка и запись программ.


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Part 10 - A-Z Of Spectrum games reviews (part 2).
Печатается с продолж. - ДООМЕР.
Реклама - реклама и объявления.
Застрял ? - Описание игры Sacred Sword (La Espada Sagrada).
Amiga+PC - И еще одна греза...

В этот день...   21 ноября