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

Низкий уровень.

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

;---инициализация обработчика прерывания устройства
DEV_INTERRUPT: PUSH ES ;сохраняем регистры
PUSH DS
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
MOV AX,CS:KEEP_ES ;ES:BX указывают на заголовок запроса
MOV ES,AX ;
MOV BX,CS:KEEP_BX ;
MOV AL,ES:[BX]+2 ;получаем код команды из заголовка
SHL AL,1 ;умножаем на 2 (т.к. таблица словная)
SUB AH,AH ;обнуляем AH
LEA DI,FUNCTIONS ;DI указывает на смещение до таблицы
ADD DI,AX ;добавляем смещение в таблице
JMP WORD PTR [DI] ;переходим на адрес из таблицы

FUNCTIONS LABEL WORD ;это таблица функций
DW INITIALIZE
DW CHECK_MEDIA
DW MAKE_BPB
DW IOCTL_IN
DW INPUT_DATA
DW NONDESTRUCT_IN
DW INPUT_STATUS
DW CLEAR_INPUT
DW OUTPUT_DATA
DW OUTPUT_VERIFY


DW OUTPUT_STATUS
DW CLEAR_OUTPUT
DW IOCTL_OUT

;---выход из драйвера, если функция не поддерживается
CHECK_MEDIA:
MAKE_BPB:
IOCTL_IN:
INPUT_DATA:
NONDESTRUCT_IN:
INPUT_STATUS:
CLEAR_INPUT:
OUTPUT_VERIFY:
OUTPUT_STATUS:
CLEAR_OUTPUT:
IOCTL_OUT:
OR ES:WORD PTR [BX]+3,8103H ;модифицируем статус
JMP QUIT

;---процедуры для двух поддерживаемых кодов
INITIALIZE: LEA AX,E_O_P ;смещение конца программы в AX
MOV ES:WORD PTR [BX]+14,AX ;помещаем его в заголовок
MOV ES:WORD PTR [BX]+16,CS ;
.
(здесь идет инициализация устройства)
.
JMP QUIT

OUTPUT_DATA: MOV CL,ES:[BX]+18 ;получаем число символов
CBW CX ;CX используем как счетчик
MOV AX,ES:[BX]+16 ;получаем адрес буфера данных
MOV DS,AX ;
MOV DX,ES:[BX]+14 ;
.
(здесь идут операции по выводу)
.
JMP QUIT

;---выходим, модифицируя байт статуса в заголовке запроса
QUIT: OR ES:WORD PTR [BX]+3,100H ;устанавливаем бит 8
POP BP ;восстанавливаем регистры
POP DI ;
POP SI ;
POP DX ;
POP CX ;
POP BX ;
POP AX ;
POP DS ;
POP ES ;
RET
E_O_P: ;метка конца программы
DEVICE12 ENDP
CSEG ENDS
END DEVICE12


Перед возвратом драйвер устанавливает слово статуса в заголов-
ке запроса. В данном примере это делается в двух местах, в зави-
симости от того вызывалась функция обеспечиваемая драйвером или
нет. Эти строки выглядят так: OR ES:WORD PTR [BX]+3,XXXXH. Значе-
ние битов XXXX следующее:

биты 0-7 код ошибки (если бит 15 = 1)
бит 8 устанавливается в 1, когда функция завершена
бит 9 устанавливается в 1, когда драйвер занят
биты 10-14 зарезервированы MS DOS
бит 15 устанавливается при возникновении ошибки

Младший байт этого слова содержит следующие коды ошибок, если
установлен бит 15, индицирующий ошибку:

0 попытка записи на защищенное от записи устройство
1 неизвестное устройство
2 устройство не готово
3 неизвестная команда
4 ошибка проверки по контрольной сумме
5 неверная длина запроса к устройству
6 ошибка поиска
7 неизвестный носитель
8 сектор не найден
9 нет бумаги в принтере
A ошибка записи
B ошибка чтения
C общая ошибка


    7.2.4 Доступ к драйверу устройства.



Драйвер устройства устанавливается путем включения имени гото-
вой программы в файл конфигурации системы. Для установки пробной
программы поместите в файл CONFIG.SYS строку DEVICE = DEVI-
CE12.COM. Затем перезагрузите систему для установки драйвера.
Если машина не будет загружаться, то скорее всего имеется ошибка
в коде инициализации драйвера.
После того как драйвер установлен, для доступа к нему пользуй-
тесь обычными функциями MS DOS прерывания 21H. Какие функции
можно использовать зависит от того, заменяет ли устройство стан-
дартное устройство DOS (как в приведенном примере) или оно добав-
ляется как совершенно новое устройство. Для замены стандартного
последовательного устройства, назовите драйвер AUX, после чего
функции 3 [7.1.7] и 4 [7.1.6] прерывания 21H будут осуществлять
соответственно ввод и вывод. Если устройство параллельное, то
назовите его PRN, после чего функция 5 [6.3.1] будет выводить
данные на принтер. Другой возможностью является использование
функции 3FH [5.4.4] для ввода и [5.4.3] для вывода. В этом случае
используйте номер файла 3 - для последовательного устройства и 4
- для параллельного. Напоминаем, что при использовании предопре-
деленных номеров файла нет необходимости открывать устройство.
Если устройство не заменяет одно из стандартных устройств MS
DOS (т.е. если оно не названо одним из резервных слов, таким как
PRN, AUX и т.д.), то Вы можете открыть устройство с помощью одной


из функций для открытия файла. Вы можете использовать как метод
доступа с помощью управляющего блока файла, так и метод дескрип-
тора файла, хотя последний предпочтительнее. Чтобы быть уверен-
ным, что Вы по ошибке не откроете дисковый файл, поместите номер
файла в BX, 0 - в AL, посде чего выполните функцию 44H прерывания
21H. Это функция IOCTL и если бит 7 значения, возвращаемого в DL
установлен, то драйвер устройства загружен.
IOCTL требует, чтобы в байте атрибутов драйвера была соот-
ветствующая установка битов и чтобы по крайней мере основы проце-
дуры обработки IOCTL имелись в процедуре обработчика прерывания
драйвера. Функция IOCTL имеет 8 подфункций, пронумерованных от 0
до 7, при этом соответствующий кодовый номер помещается в AL при
вызове функции:

0 Возвратить информацию об устройстве в DX
1 Установить информацию об устройстве, используя DL (DH=0)
2 Считать CX байтов от драйвера устройства через управля-
щий канал и поместить их начиная с DS:DX
3 Записать CX байтов в драйвер устройства через управляющий
канал, взяв их начиная с DS:DX
4 То же, что и 2, но использовать номер накопителя в BL,
где 0 = накопитель по умолчанию, 1 = A и т.д.
5 То же, что и 3, но использовать номер накопителя как в 5
6 Получить статус ввода
7 Получить статус вывода

В ответ возвращается различная информация, в зависимости от
того, какая функция вызвана. Для подфункций 0 и 1 значение битов
регистра DX следующее (при условии, что бит 7 = 1, что означает,
что доступ получен к устройству, а не к файлу):

0 1 = устройство консольного ввода
1 1 = устройство консольного вывода
2 1 = нулевое устройство
3 1 = устройство часы
4 резерв
5 1 = нет проверки на Ctrl-Z, 0 = есть проверка на Ctrl-Z
6 1 = не конец файла, 0 = конец файла
7 1 = устройство, 0 = дисковый файл
8-13 резерв
14 1 = если можно использовать подфункции 2 и 3, 0 = нельзя
15 резерв

Подфункции 2-5 позволяют программе и устройству обмениваться
произвольными управляющими строками. Это позволяет передавать
управляющие сообщения отдельно от основного потока данных, что
существенно упрощает дело. При возврате AX будет содержать число
переданных байтов. Подфункции 6-7 позволяют программе проверить,
готово ли устройство для ввода или вывода. Для устройств в AL
возвращается FF, если устройство готово и 0, если нет. При ис-
пользовании с открытым файлом (бит 7 = 0) в AL возвращается FF до
тех пор, пока не будет доститгнут конец файла.
Отметим, что в Бейсике 3.0 добавлены операторы IOCTL и IOCTL$.
Они позволяют бейсиковской программе, соответственно, посылать и


принимать управляющие строки от драйвера устройства, которое было
предварительно открыто оператором OPEN. Выходная строка должна
быть заключена в кавычки, как в IOCTL #3,"...". Подобным образом,
A$ = IOCTL$(3) принимает информацию о статусе через IOCTL.


    7.2.5 Обнаружение и анализ ошибок устройства.



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

Высокий уровень.

Интерпретатор Бейсика обнаруживает многие ошибки, включая
ошибки драйверов устройств. При обнаружении ошибки возвращается
код ошибки и если не предусмотрена программа восстановления при
ошибках, то программа останавливается. Однако можно установить
обработку ошибок, с тем чтобы когда происходит критическая ошибка
Бейсик автоматически переходил на процедуру восстановления при
сбоях, которую Вы создали. Процедура может проанализировать код и
определить в какой строке программы произошла ошибка. После того
как это сделано, программа может принять меры по устранению ошиб-
ки, либо с помощью пользователя, либо выполняя другую часть прог-
раммы. После того, как эта процедура завершена, программа может
продолжить выполнение с любого места, с которого Вы захотите (с
некоторыми ограничениями). Код для тщательного анализа ошибочных
ситуаций может существенно увеличить размер программы. Отметим,
что компилятора Бейсика даже минимальные проверки на ошибки пот-
ребуют дополнительно по не менее чем 4 байта на каждую строку
программы.
Чтобы разрешить обработку ошибок в Бейсике поместите в начале
программы строку ON ERROR GOSUB n, где n это номер строки прог-
раммы, в которой начинается процедура обработки ошибок. При воз-
никновении критической ошибки управление будет передано на эту
строку. В начале процедуры поместите ряд строк вида IF ERR = n
THEN номерстроки, где n - номер ошибки, взятый из приложения к
руководству по Бейсику, содержащему сообщения об ошибках. Номера
строк в этих операторах соответствуют началу кода, обрабатывающе-
го данную конкретную ошибку. Эти части могут быть в свою очередь
разбиты на куски рядом операторов IF ERL = n THEN номерстроки.
ERL возвращает номер строки, в которой произошла ошибка, позволяя
процедуре восстановления точно определить ошибочное место.
После того как процедура восстановления завершила свою работу
надо использовать оператор RESUME для возврата управления в ту
строку, где произошла ошибка. За этим оператором может следовать
номер, в этом случае управление будет передано на строку с ука-
занным номером. Однако, имейте ввиду, что нельзя использовать
RESUME для перехода в точку программы, которая находится за пре-
делами процедуры, в которой произошла ошибка. Если восстановление


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

100 ON ERROR GOSUB 5000 'разрешаем обработку ошибок
.
.
5000 IF ERR = 61 THEN 5100 'диск полон
5010 IF ERR = 71 THEN 5200 'диск не готов
.
.
5100 IF ERL = 2080 THEN 5120 'где произошла ошибка?
5110 BEEP: PRINT "Disk in drive B: is full": RESUME
5120 BEEP: PRINT "Disk in drive A: is full": RESUME
.
5200 BEEP: PRINT "A disk drive is not ready"
5210 PRINT "Strike any key when corrected"
5220 IF INKEY$ = "" THEN 5220 'ожидаем нажатия клавиши
5230 RESUME ERL - 10 'пытаемся повторить операцию

В Бейсике 3.0 введены инструкции ERDEV и ERDEV$. Обе они поз-
воляют получить переменные только для чтения от прерывания 24H,
обрабатывающего критичекие ошибки. Z% = ERDEV возвращает в Z%
слово статуса, в котором старший байт содержит 13-15 биты атрибу-
та заголовка устройства, а младший байт - код ошибки прерывания
24H. Z$ = ERDEV$ помещает в Z$ 8-байтное имя устройства для сим-
вольных устройств и 2-байтный указатель накопителя для блочных
устройств.

Низкий уровень.

Иногда драйверы устройств содержат такие серьезные ошибки, что
программа просто не может продолжаться, пока они не будут исправ-
лены. Когда такие ошибки происходят, то система вызывает обработ-
чик критических ошибок. Он может вступать в действие как для
стандартных устройств, так и для установленных драйверов. Пользо-
ватель наиболее часто сталкивается с ним, когда пытается произ-
вести дисковую операцию с дисководом, у которого открыта дверца.
В этом случае появляется сообщение: "Not ready error reading
drive A - Abort, Retry, Ignore?"
Обработчик критических ошибок может быть переписан, чтобы он
лучше обрабатывал устройства, для которых Вы создали устанавли-
ваемые драйверы. Вектор прерывания 24H указывает на стандартную
процедуру MS DOS, но Вы можете перенаправить вектор на свою про-
цедуру. При вызове этой процедуры старший бит AH содержит 0 если
ошибка произошла на блочном устройстве и 1, если на символьном.
BP:SI указывают на заголовок драйвера виновного устройства, кото-
рый может дать дополнительную информацию. Восемь байтов, начиная
со смещения AH в заголовке содержат имя устройства, а обработчик
критичеких ошибок помещает код ошибки длиной в слово в DI. Вот
кодовые номера (они не представляют битовых позиций):


Код Проблема

0 попытка писать на диск, защищенный от записи
1 неизвестное устройство
2 накопитель не готов
3 неизвестная команда
4 ошибка обмена данными
5 неверная длина запроса
6 ошибка поиска

7 неизвестный тип носителя
8 сектор не найден
9 нет бумаги в принтере
A ошибка при записи
B ошибка при чтении
C общая ошибка

В случае дисковой ошибки AL содержит номер накопителя, на котором
произошла ошибка (0 = A, 1 = B и т.д.), а биты 2-0 AH индицируют
тип ошибки. Бит 0 устанавливается, если ошибка произошла во время
операции записи, и сбрасывается - если при чтении. Биты 2-1 со-
держат информацию о том, в каком месте диска произошла ошибка,
давая 00 - для начальных секторов DOS, 01 - для FAT, 10 - для
каталога и 11 - для всего остального диска.
Имеется три способа, которыми программа может восстановиться
после критической ошибки:

1. Можно попросить пользователя устранить причину ошибки (напри-
мер, закрыть дверцу накопителя), после чего система предоставит
устройству возможность повторить операцию.
2. Управление может быть возвращено инструкции, следующей за INT
21H, которая сделала попытку обратиться к драйверу.
3. Программа может завершиться и вернуть управление системе.

Ваша процедура обработки ошибок может восстановить ситуацию,
выдав инструкцию IRET, после того, как она поместила 0 в AL,
чтобы игнорировать ошибку, 1 - чтобы повторить операцию и 2 -
чтобы завершить программу. Если Вы хотите, чтобы Ваша процедура
провела восстановление сама, то она должна восстановить регистры
выполняемой программы из стека, а затем удалить со стека все,
кроме последних трех слов. После этого инструкция IRET возвратит
управление программе, хотя сама система останется в нестабильном
состоянии до тех пор, пока она не сделает вызов функции с номером
большим, чем 12. Вот конфигурация стека (начиная сверху до низа)
когда вызывается обработчик критических ошибок:

Адрес возврата обработчика ошибок: IP, CS, флаги

Пользовательские регистры задачи, AX, BX, CX, DX, SI, DI, BP,
из которой был вызван драйвер: DS, ES, IP, CS, флаги

MS DOS обрабатывает также многие некритические ошибки. Сюда
включаются коды ошибок, которые могут возвращаться в регистрах,
когда вызывалась функция DOS. Эти коды обсуждаются в данной книге


в тех местах, в которых описываются соответствующие функции.
Однако имейте ввиду, что начиная с версии 3.0 MS DOS возвращает
расширенные коды ошибок для функций, использующих FCB или деск-
рипторы файлов. Когда при выполнении одной из этих функций уста-
навливается флаг переноса, то в AX возвращается обычный код ошиб-
ки. Дополнительный расширенный код доступен через прерывание 59H,
если в BX поместить 0. Эта функция сообщает также о критических
ошибках и она может быть использована из обработчика критических
ошибок, вызываемого через прерывание 24H.
Функция помещает в AX код ошибки, взятый из обычного списка
знакомых кодов ошибок (например, "недостаточно памяти") или один
из новых кодов (например, "ограничение доступа" для многопользо-
вательской системы). BH возвращает код класса ошибки, указывая
какого типа ошибка произошла. Например, код 1 указывает, что
исчерпаны ресурсы, т.е. что память, файловые буфера или что-то
еще израсходовано. Другие классы могут указывать на программные
ошибки, проблемы с носителями, форматированием и т.д. BL содержит
код, предполагающий действие для восстановления, такое как "пов-
торить", "прекратить" или "запросить у пользователя". Наконец, CH
возвращает число, определяющее место где возникли проблемы: на
блочном устройстве, на символьном, в памяти?
Данные для этих кодов ошибок весьма обширны. Полную информацию
о них см. в Техническом руководстве по MS DOS 3.0. Поскольку
предполагается, что MS DOS 3.0 не будет использоваться на маши-
нах, более ранних, чем AT, то использование этих кодов ограничи-
вает совместимость Ваших программ. Тем не менее, набор процедур,
предназначенный только для MS DOS 3.0 может дополняться поверх
обычных процедур обработки ошибок. В [1.1.3] показано как прог-
рамма может определить версию MS DOS, в которой она работает.
Наконец, имейте ввиду, что процесс может передавать код завер-
шения вызвавшему его процессу. Термин процесс относится к взаимо-
действующим программам. Например, когда одна программа загружает
и запускает другую с помощью функции EXEC, то запускаемая прог-
рамма называется потомком, а запускающая программа - родителем.
Родителю может потребоваться информация о том, как завершился
потомок. Чтобы использовать эту возможность, поместите желаемый
код завершения в AL и выполните функцию 4CH прерывания 21H для
завершения программы. Когда управление будет возвращено родителю,
то он выполнит функцию 4DH прерывания 21H (без входных регистров)
и в AL будет получен код завершения, который может затем быть
проанализирован. Кроме того, AH будет содержать информацию о том,
как завершился потомок: 0 - для нормального завершения, 1 - по
Ctrl-Break, 2 - по критической ошибке устройства и 3 - с помощью
функции 31H, оставляющей задачу резидентной.
Если программа завершилась с помощью этой функции (а не 20H -
см. обсуждение в [1.3.4]), то MS DOS получает код выхода и он
может быть включен в обработку командным файлом с помощью подко-
манды IF. Эта подкоманда позволяет условное исключение других
команд из командного файла. Код выхода рассматривается как номер
ERRORLEVEL и условные операции выполняются в зависимости от того,
больше он или нет определенного числа. С помощью этой возможности
командные файлы могут прекращать обработку и выводить сообющение
о возникновении ошибки в одной из запущенных программ. Более
подробная информация приведена в разделе "Команды пакетной обра-
ботки" руководства по операционной системе.


    Раздел 3. Использование специальных устройств ввода/вывода.



Имеется огромное количество устройств ввода/вывода, которые
могут быть присоединены к IBM PC, включая мышь, джойстик, графо-
построители и т.д. В данном разделе обсуждаются только те уст-
ройства, которые специально поддерживаются оборудованием IBM PC.
Сюда относятся кассетные магнитофоны, световое перо и другие
устройства, которые могут быть присоединены через игровой порт.
Адреса портов, относящиеся к другим устройствам, обсуждаются в
других разделах этой книги, относящихся именно к данным устройст-
вам. Распределение адресов портов в основном одно и то же для
всех типов IBM PC:

Адрес порта Функция

00-0F микросхема DMA 8237 (не для PCjr)
20-2F микросхема прерываний 8259 (AT контроллер #1: 20-3F)
40-4F микросхема таймера 8253/8254
60-6F микросхема PPI 8255 (AT использует только адреса
клавиатуры
70-7F часы реального времени (только AT)
80-83 регистры страниц DMA (не для PCjr)
A0-BF микросхема прерываний #2 (только AT)
C0-C7 микросхема звука SN76496 (только PCjr)
F0-FF PCjr - контроллер НГМД, AT - управление математиче-
ским сопроцессором
1F0-1F8 фиксированный диск AT
200-20F игровой адаптер
278-27F AT коммуникационный порт #2
2F8-2FF коммуникационный порт COM2 (COM1 для PCjr)
320-32F фиксированный диск XT
378-37F адаптер параллельного принтера для PC, XT, AT
3B0-3BF монохромный/параллельный адаптеры (не для PCjr)
3D0-3DF цветной графический адаптер
3F0-3F7 контроллер НГМД
3F8-3FF коммуникационный адаптер COM1 (модем PCjr)


    7.3.1 Чтение/запись с кассетного магнитофона.



Только очень немногие IBM PC и PCjr используют кассетный маг-
нитофон, а XT и AT не поддерживают его вообще. Помимо того, что
он очень ненадежен, обмен с кассетным магнитофоном возможен толь-
ко последовательный, но не с прямым доступом. Тем не менее, могут
быть причины для программирования кассетного магнитофона на PCjr.
Имейте ввиду, что кассетные операции используют канал 2 микросхе-
мы таймера 8253 [2.1.1], поэтому не пытайтесь одновременно ис-
пользовать этот канал для других целей. Отметим также, что при
операции чтения с кассеты, запрещено прерывание времени суток,
поэтому счетчик времени суток BIOS будет давать неверное значе-
ние.

Высокий уровень.

Хотя кассетные файлы обрабатываются совершенно по-другому чем
дисковые файлы, однако команды доступа к ним совершенно аналогич-


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

.B программа на Бейсике
.P защищенная программа на Бейсике
.A программа на Бейсике в формате ASCII
.M файл изображения памяти
.D последовательный файл данных

Для сохранения файла на кассете напишите SAVE "CAS1:имяфайла".
Для загрузки программы - LOAD "CAS1:имяфайла". В последнем случае
лента прогоняется до тех пор, пока нужный файл не будет найден,
при этом имя каждого встреченного файла будет выводиться на экран
(кассеты не используют каталоги). Если запросить несуществующий
файл, то будет выведен полный список файлов на кассете.

Средний уровень.

BIOS работает с кассетной лентой порциями в 256-байтные блоки.
Набору блоков предшествует "лидер", который состоит из 256 байтов
ASCII 1. Лидер завершается нулевым битом синхронизации. Затем
следует байт синхронизации со значением 16H, а затем 256 байтов
данных. После этого идут 2 байта контроля ошибок, а затем новый
блок данных, сопровождающийся парой байт проверки ошибок и т.д.
Вся последовательность завершается четырехбайтным "хвостом",
содержащим коды ASCII 1.
Для чтения данных с кассеты на до использовать функцию 2 пре-
рывания 15H. Нет необходимости открывать файл, как это делается
при дисковых операциях. ES:BX указывают на буфер в памяти, куда
будут посылаться данные, а CX - число байтов, которые надо счи-
тать. При возврате DX сообщит сколько байтов прочитано на самом
деле, а ES:BX будут указывать на последний считанный байт плюс 1.
Флаг переноса будет равен 0, если чтение прошло успешно, а в
противном случае AH будет содержать 1, если проблема с контролем
ошибки, 2 - при ошибке чтения данных и 3 - при отсутствии данных
на ленте.
Функция 3 прерывания 15H записывает данные на кассету. ES:BX
указывают на первый байт данных, а CX содержит число байтов,
которое надо записать. При возврате ES:BX указывают на байт,
следующий за последним записанным. Мотор управляется функциями 0
(включение) и 1 (выключение) прерывания 15H. Для этих функций нет
выходных регистров.


    7.3.2 Чтение позиции светового пера.



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


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

Высокий уровень.

Бейсик может определять позицию светового пера двумя способа-
ми. При первом программа непрерывно определяет статус пера. При
втором, когда перо используется, то управление временно передает-
ся процедуре, обеспечиваемой Вашей программой. Для непрерывного
контроля за пером надо использовать оператор PEN как функцию в
форме X = PEN(n), где n - кодовый номер, определяющий какую ин-
формацию Вы хотите получить о пере и его позиции. Возможные зна-
чения n такие:

0 возвращает -1, если перо было выключено со времени послед-
него запроса, 0 - если нет
1 возвращает последнюю координату x (0-319 или 0-639), в ко-
торой перо было включено (оно могло быть впоследствии
передвинуто, если оставалось включенным)
2 возвращает последнюю координату y (0-199), в которой перо
было включено.
3 возвращает -1, если перо включено и 0 - если нет
4 возвращает текущую x координату (0-319 или 0-639) пера
5 возвращает текущую y координату (0-199) пера
6 возвращает позицию - номер строки (1-24), в которой перо
было последний раз активизировано
7 возвращает позицию - номер столбца (1-40 или 1-80), в ко-
торой перо было последний раз активизировано
8 возвращает текущую позицию - номер строки (1-24)
9 возвращает текущую позицию - номер столбца (1-40 или 1-80)

В данном примере определяется включено ли перо, и если это
так, то берется текущее его положение:

100 IF NOT PEN(3) THEN 130 'проверяем включено ли перо
110 X = PEN(4) 'получаем координату точки по оси x
120 Y = PEN(5) 'получаем координату точки по оси y
130 ... 'продолжаем программу

Более гибкие возможности использования светового пера предос-
тавляются оператором ON PEN GOSUB. Этот оператор указывает номер
строки, в которой начинается процедура, активизируемая при вклю-
чении пера. Бейсик достигает этого проверкой состояния пера после
выполнения каждой его инструкции. Процедура может получить пози-
цию пера и предпринять требуемые действия. Когда процедура закан-
чивается, то программа продолжается с того места, где она была
при включении пера.
ON PEN GOSUB не работает до тех пор, пока она не активизирова-
на оператором PEN ON. PEN OFF отменяет ее работу. Смысл этого