Документ кропотливо восстановлен из фотокопии, которую любезно предоставил ММ. Который превозмог себя и по-быстрому отфотографировал документ из собственной коллекции.
УТВЕРЖДЁН
00008-01.33.01-2-ЛУ
ПЕРСОНАЛЬНАЯ ЭВМ "ЭЛЕКТРОНИКА МС0513"
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
ОПЕРАЦИОННАЯ СИСТЕМА ОС БК11
ПРОГРАММИРОВАНИЕ ВНЕШНИХ УСТРОЙСТВ
РУКОВОДСТВО ПРОГРАММИСТА
00008-01.33.01-2
Документ совпадает с книгой "Руководство системного программиста. Книга 2. Программирование внешних устройств." Из комплекта документации РАФОС-II, но только в части, касающейся SJ-монитора и без расширенной памяти
1988
СОДЕРЖАНИЕ
- 1. ОБРАБОТКА
ПРЕРЫВАНИЙ
- 1.1. ПРОГРАММИРУЕМЫЙ ВВОД/ВЫВОД
- 1.2. ВВОД/ВЫВОД ПО ПРЕРЫВАНИЮ
- 1.3. СРАВНЕНИЕ ВНУТРЕННИХ ПОДПРОГРАММ ОБРАБОТКИ ПРЕРЫВАНИЙ И ДРАЙВЕРОВ УСТРОЙСТВ
- 1.4. РЕКОМЕНДАЦИИ ПО НАПИСАНИЮ ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЙ
-
1.5. СТРУКТУРА
ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЯ
- 1.5.1. ЗАЩИТА ВЕКТОРОВ, МАКРОКОМАНДА .PROTECT
- 1.5.2. УСТАНОВКА ВЕКТОРА ПРЕРЫВАНИЯ
- 1.5.3. МАКРОКОМАНДА .DEVICE
- 1.5.4. МАКРОКОМАНДА .INTEN
- 1.5.5. ИСПОЛЬЗОВАНИЕ МАКРОКОМАНДЫ .SYNCH
- 1.5.6. ВЫПОЛНЕНИЕ НА УРОВНЕ ВЕТВЛЕНИЯ. МАКРОКОМАНДА .FORK
- 1.5.7. КРАТКИЕ СВЕДЕНИЯ О МАКРОКОМАНДАХ .INTEN, .FORK И .SYNCH
- 1.5.8. ВЫХОД ИЗ ПРЕРЫВАНИЯ
- 1.6. ПРИМЕР ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЯ
- 2. СТРУКТУРА И НАСТРОЙКА ДРАЙВЕРА
- 3. ТИПОВАЯ СХЕМА ДРАЙВЕРА УСТРОЙСТВА
- 4. СПЕЦИФИЧНЫЕ СВОЙСТВА ДРАЙВЕРА
- 5. ДРАЙВЕРЫ СИСТЕМНОГО УСТРОЙСТВА И ЗАГРУЗЧИКИ
- 6. АССЕМБЛИРОВАНИЕ,
КОМПОНОВКА И УСТАНОВКА ДРАЙВЕРА
- 6.1. АССЕМБЛИРОВАНИЕ ДРАЙВЕРА
- 6.2. КОМПОНОВКА ДРАЙВЕРА
- 6.3. УСТАНОВКА ДРАЙВЕРА
- 7. ПРОВЕРКА И ОТЛАДКА ДРАЙВЕРА УСТРОЙСТВА
- 8. ОСОБЕННОСТИ УПРАВЛЕНИЯ НЕКОТОРЫМИ УСТРОЙСТВАМИ
1. ОБРАБОТКА ПРЕРЫВАНИЙ
В этом разделе описаны возможные программные способы обмена данными между памятью и периферийным устройством, рассмотрены преимущества и недостатки каждого способа и даны рекомендации по их использованию, далее следует описание структуры подпрограммы обработки прерывания, как одного из способов программирования ввода/вывода, и подробное объяснение её организации и написания.
1.1. ПРОГРАММИРУЕМЫЙ ВВОД/ВЫВОД
Одним из способов обмена данными между памятью и периферийным устройством является использование программируемого ввода/вывода. В соответствии с этим способом, программа пользователя функционирует в условиях запрещения прерываний от устройства и использует бит готовности в регистре состояния соответствующего устройства. При наличии готовности осуществляется передача данных, после чего программа переходит в режим ожидания следующего состояния готовности или выполняет другие действия, периодически опрашивая бит готовности. Программируемый ввод/вывод зависит от конкретного устройства и не использует свойства операционной системы, предназначенные для процессов ввода/вывода. Кроме того, он занимает системные ресурсы до завершения ввода/вывода.
Однако, несмотря на это, программируемый ввод/вывод иногда является наиболее приемлемым способом. Например, резидентный монитор использует программируемый ввод/вывод для печати своего сообщения об ошибке "?MON-F-SYSTEM HALT". Сначала он выполняет операцию RESET, чтобы остановить процесс ввода/вывода. Затем ждёт возможности вывода на терминал сообщения об ошибке (посимвольно). В подобной ситуации, когда может быть запорчен сам монитор, никакое задание или передача данных не может выполняться, кроме того может быть запорчена подпрограмма монитора .PRINT, и она не сможет выполниться. Исходя из этого, в описанной ситуации программируемый ввод/вывод является лучшим способом, использующимся для печати сообщения об ошибке.
В прикладной программе пользователь может использовать программируемый ввод/вывод для устройства, которое должно быть моментально обслужено. Ниже приведён фрагмент RMON, демонстрирующий программируемый ввод/вывод:
; В R1 содержится адрес текста сообщения. ; TTPS является словом, содержащим ; адрес регистра состояния терминала. ; Его бит готовности является старшим битом ; младшего байта регистра состояния. ; TTPB - слово, содержащее ; адрес буфера терминала. ; пересылка символа в буфер печати ; сбрасывает в "0" ; бит готовности в регистре состояния. ; 5¤: TSTB @TTPS ;устройство готово? BPL 5¤ ;нет, вернуться MOVB (R1)+,@TTPB ;да, вывод символа BNE 5¤ ;анализ на конец сообщения
1.2. ВВОД/ВЫВОД ПО ПРЕРЫВАНИЮ
Хотя программируемый ввод/вывод и полезен в некоторых ситуациях, во многих случаях лучшим способом является организация ввода/вывода с помощью прерываний. В соответствии с этим способом программа начинает ввод/вывод и продолжает обработку. Когда передача завершается, устройство выдаёт запрос на прерывание. Затем подпрограмма обработки прерывания определяет, в каком состоянии находится передача: завершена, не завершена или встретилась ошибка. Она выбирает подходящее действие (возвращается к программе, восстанавливает передачу или повторяет передачу). Преимущества использования ввода/вывода по прерывания в том, что он позволяет выполнять две или более обработки одновременно. Не захватывая в монопольное пользование системные ресурсы.
1.2.1. СИСТЕМА ПРЕРЫВАНИЙ
Прерывание вызывает прекращение работы выполняющейся программы и запуск подпрограммы обработки прерывания. Состояние приоритета процессора (PS) и счётчик инструкций (PC) сохраняются в стеке с тем, чтобы обработка беспрепятственно могла продолжаться после возвращения из прерывания.
Затем процессор загружает новое содержимое в PS и PC из двух предварительно назначенных ячеек, названных вектором прерывания. Эти слова содержат адрес подпрограммы обработки прерывания и новое PS, которое указывает уровень приоритета процессора. Когда подпрограмма обработки прерывания завершается, она выполняет инструкцию RTI, которая восстанавливает старые PS и PC из стека, и выполнение исходной программы продолжается с ранее сохранённого адреса.
1.2.2. ПРИОРИТЕТЫ ПРОЦЕССОРА И УСТРОЙСТВА
Наступление прерывания зависит от уровней приоритета процессора и устройства. На рис. 1 дана структура приоритетов системы ОС БК-11. Каждое устройство в системе имеет свой приоритет. Наивысший приоритет имеют те устройства, которые должны обслуживаться первыми. Например, диски обычно имеют приоритет 5; терминалы и другие символьно-ориентированные устройства обычно имеют приоритет 4. Эта приоритетная система тщательно распределяется и устанавливается посредством селектора приоритета на каждом интерфейсе устройства ввода/вывода. Пользователь может контролировать порядок устройств одного и того же приоритета, в этом случае устройство, которое подключено физически ближе к процессору на шине, имеет более высокий приоритет и обслуживается первым, несмотря на то, что прерывания возникли на нескольких устройствах одновременно.
Рис. 1
Процессор функционирует на каждом из восьми уровней приоритета (от 0 до 7). Когда процессор подключён к уровню приоритета 7, ни одно из устройств не может прервать его запросом на обслуживание. Если процессор подключён к более низкому приоритету, то его могут прервать устройства с более высоким приоритетом. Пользователь может установить приоритет процессора из подпрограммы обработки прерывания путём изменения слова состояния процессора. В системе ОС БК-11 для этой цели предусматриваются специальные средства программного обеспечения. Поэтому пользователю не требуется самому непосредственно изменять PS. Для этого можно использовать системные макрокоманды .MTPS, .MFPS, .INTEN и .FORK.
Система прерываний позволяет непрерывно сравнивать приоритет процессора с приоритетом прерывающих устройств и обслуживать устройства с более высоким уровнем приоритета, чем приоритет процессора. Прерывания могут гнездоваться, т.е. обработка одного прерывания может быть прекращена для того, чтобы обслужить прерывание от устройства с более высоким приоритетом. Обслуживание устройства с более низким приоритетом продолжится после окончания обслуживания устройства с более высоким приоритетом.
1.2.3. СЛОВО СОСТОЯНИЯ ПРОЦЕССОРА (PS)
Слово состояния процессора (PS) занимает самый старший адрес страницы ввода/вывода. (Примечание: это относится к старшим системам архитектуры PDP-11, а для микропроцессора 1801ВМ1 это неверно.) В слове состояния процессора содержится информация о текущем уровне приоритета и результатах предыдущих операций (коды условий), а такие разряд слежения (T-бит), вызывающий внутреннее прерывание после исполнения команды (если перед её выполнением этот разряд установлен в ходе отладки программы).
На рис. 2 показана структура PS. Биты с 5 по 7 определяют текущий уровень приоритета процессора. Изменяя эти биты, можно изменить приоритет процессора. Может быть установлен один из восьми уровней приоритета процессора от 0 до 7. (Примечание: это относится к старшим системам архитектуры PDP-11, а для микропроцессора 1801ВМ1 это неверно, значимым является только бит 7 поэтому есть всего два уровня приоритета: есть приоритет и нет приоритета.) Приоритет определяет возможность прерывания работы процессора по запросу от внешнего устройства. Наивысший приоритет 7 означает, что работа процессора прервана быть не может. Приоритет процессора устанавливается или изменяется программно (обслуживаемое устройство не может прерываться). Для изменения приоритета процессора рекомендуется использовать системные макрокоманды .INTEN и .FORK.
Рис. 2. Слово состояния процессора (PS)
1.3. СРАВНЕНИЕ ВНУТРЕННИХ ПОДПРОГРАММ ОБРАБОТКИ ПРЕРЫВАНИЙ И ДРАЙВЕРОВ УСТРОЙСТВ
Как программируемый ввод/вывод, так и ввод/вывод по прерыванию являются допустимыми процессами в системе ОС БК-11. Если требуется связать с системой новое устройство (которое ещё не поддерживается системой ОС БК-11 то необходимо:
- либо написать драйвер для этого устройства;
- либо внутреннюю подпрограмму обработки прерывания.
Как драйверы устройств, так и внутренние подпрограммы обработки прерывания могут иметь секции программируемого ввода/вывода, а также секции ввода/вывода по прерыванию. Обычным интерфейсом ОС БК-11 между монитором и периферийным устройством является драйвер устройства, который может находиться в оперативной памяти только в момент обмена информацией с устройством ввода/вывода. Драйвер устройства обычно включает в себя подпрограмму обработки прерывания.
Для того, чтобы использовать подпрограмму обработки прерывания, необходимо поместить эту подпрограмму в программу пользователя. Программа пользователя должна изменять регистры буфера и состояние для специального устройства. Это означает, что подпрограмма обработки прерывания всегда должна находиться в памяти вместе с программой пользователя.
С другой стороны, если необходимо использовать драйвер устройства, то подпрограмма обработки прерывания находится в драйвере, а не в программе пользователя. Из головной программы выдаются системные макрокоманды .READ и .WRITE. Монитор и драйвер вместе начинают передачу данных, обслуживают прерывания и сообщают программе пользователя, когда выполнился обмен. Драйвер должен быть резидентным, когда программа пользователя требует выполнения ввода/вывода, (т.е. драйвер должен быть резидентным каждый раз, когда открыт файл или канал).
Выбор способа, более подходящего для нового устройства, зависит главным образом от самого устройства и от прикладных программ. Поэтому, необходимо использовать внутреннюю подпрограмму обработки прерывания для устройств датчиков или устройств управления, например, аналого-цифровые преобразователи. Блокозаменяемые устройства, устройства большой памяти файловой структуры (например, диски) рационально обслуживать драйверами. Аппаратуру связи можно обслуживать любым способом - решение зависит от других критериев.
Двумя главными преимуществами внутренних подпрограмм обработки прерывания являются их скорость и объём обрабатываемой информации управления. Т.к. нет дополнительных затрат монитора, связанных с передачей данных, то внутренняя подпрограмма часто может обрабатывать прерывания быстрее, чем драйвер устройства. Если скорость обслуживания прерывания является основным критерием, то необходимо отдать предпочтение написанию внутренней подпрограммы обработки прерывания, даже если устройством является диск.
Внутренняя подпрограмма имеет доступ ко всем регистрам устройства (конечно, драйвер устройства имеет доступ ко всем этим же регистрам, но программа, использующая драйвер - нет). Она может передавать большое количество информации головной программе, что обеспечивает большую гибкость способа, каким головная программа вызывает подпрограмму обработки прерывания, и в объёме информации, который подпрограмма возвращает головной программе.
Три основных преимущества использования драйверов устройств заключаются в том, что они обеспечивают независимость устройства для программ пользователя, они могут разделять время процессора с другими процессами, и они просты в использовании. Драйверы устройств имеют стандартный протокол для интерфейса с монитором ОС БК-11, имеется также стандартный протокол для интерфейса между монитором и программой, так что любая программа, которая соответствует стандартам монитора, может использовать этот драйвер. Он включает прикладные программы, системные стандартные программы и языковые процессоры ОС БК-11, например, Макроассемблер, Паскаль и Бейсик. Итак, драйвер устройства предоставляет новое устройство большому числу программ без какого-либо специального изменения (помимо этого, драйвер для устройства с прямым доступом предоставляет файловую систему ОС БК-11 на устройстве без дополнительных затрат). В противоположность этому, внутренняя подпрограмма обработки прерывания предоставляет новое устройство одной прикладной программе.
Драйверы устройств удобны в использовании. Так как они являются стандартными средствами ОС БК-11 обработки ввода/вывода, то написание и использование их простое. Эта процедура упрощается ещё и тем, что в ОС БК-11 имеются макрокоманды для написания драйвера; имеются также команды монитора, которые устанавливают драйверы в таблицы устройств монитора и загружают их в память. Помимо этого, драйвер устройства позволяет использовать преимущество системных запросов монитора для выполнения передачи данных.
Рис. 3 иллюстрирует некоторые различия между внутренними подпрограммами обработки прерывания и драйверами устройств.
Если выясняется, что новое устройство требует внутреннюю подпрограмму обработки прерывания, то необходимо изучить подраздел 1.4. Если же определится, что более подходит драйвер устройства, то следует изучить этот и последующие разделы.
Рис. 3. Внутренние подпрограммы обработки прерывания и драйверы устройств
1.4. РЕКОМЕНДАЦИИ ПО НАПИСАНИЮ ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЙ
Наиболее важной частью написания внутренней подпрограмм обработки прерывания является тщательное планирование. Необходимо выделить следующие этапы:
- ознакомление с устройством;
- изучение структуры подпрограммы, обслуживающей прерывание;
- изучение схемы подпрограммы обработки прерывания;
- требования к подпрограмме;
- подготовка схемы подпрограммы;
- написание подпрограммы обработки;
- проверка и отладка подпрограммы.
1.4.1. ОЗНАКОМЛЕНИЕ С УСТРОЙСТВОМ
Для правильного написания подпрограммы обработки прерывания необходимо ознакомиться с новым устройством. Для этого следует внимательно изучить документацию о нём, которая должна содержать всю информацию для программирования.
Необходимо разобраться, как работает устройство: что требуется от пользователя, и как оно обрабатывает передачу данных. Не следует начинать писать подпрограмму, пока не рассмотрены следующие вопросы.
Эти вопросы относятся не ко всем типам устройств. Отдельные вопросы касаются устройств с большой памятью, а некоторые более подходят к устройствам датчиков или устройствам связи. Необходимо рассмотреть каждый вопрос, подходит ли он для данного устройства:
- Что представляет собой вектор (или векторы) прерывания
устройства?
Определить, каким должен быть вектор прерывания. Рассмотреть конфликты с существующими устройствами, предоставленными ОС БК-11, и конфликты с устройствами, поддерживаемыми другими операционными системами, если они используются. Если вектор выбран, убедиться, что устройство подключено правильно, и что на шине есть нужные адреса. Операционная система ОС БК-11 требует, чтобы все векторы были ниже ячейки 500, но отдельные ячейки нижней памяти не предоставляются для использования как векторы.
- Что представляют собой регистры команд и состояний?
Необходимо определить, где располагаются эти регистры и что означают биты в каждом из них.
- Какой уровень приоритета устройства?
- Является ли устройство DMA (прямого доступа к памяти) или программным передатчиком (словно- или символьно-ориентированным устройством)?
- Какие регистры буфера данных?
Необходимо определить, где эти регистры располагаются, и что означают биты в каждом из них.
- Какие коды для типичных операций?
Изучить, как задавать различные операции, манипулируя битами в регистрах устройства. Драйверы устройств имеют возможность выполнять операции чтения, записи, поиска.
- Когда устройство выставляет запрос на прерывание?
Некоторые устройства выставляют запрос на прерывание для каждого символа; другие являются словно-ориентированными, блоко-ориентированными или с ориентировкой на пакет. Некоторые устройства выставляют запрос на прерывание дважды для определённых операций, таких как поиск или сброс регистров устройства в начальное состояние. Если данное устройство такое, необходимо это учесть.
- Что является базовой единицей для передачи данных?
Конечно, это относится к предыдущему вопросу, но следует определить, посылать ли запросы ввода/вывода на устройство как байты, слова или блоки. Если, например, программа пользователя имеет дело с термами слов и устройство является символьно-ориентированным, то необходимо в подпрограмме обработки преобразовать число слов в число байтов.
- Требуется ли устройству положительный или отрицательный
счёт байтов?
Некоторые устройства требуют отрицательного счета слов или байтов. Если устройство является одним них, то, возможно, необходимо сделать отрицательным счёт в подпрограмме обработки.
- Какая структура устройства?
Если устройством является диск, то необходимо узнать, как построены цилиндры, дорожки и секторы, определить их размер, узнать, требует ли устройство чередования и, если так, то узнать, как оптимизировать скорость. Чередование описывает процесс записи данных на вращающееся устройство, который требует вмешательства программы между секторами. Диск постоянно движется, данные записываются в один сектор, программа вмешивается при прохождении смежного сектора, затем записываются остальные данные в следующий подходящий сектор.
- Как организована буферизация?
Некоторые устройства передают данные программе пользователя каждый раз по одному символу. Другие буферируют данные внутренне в SILO или посылают их в пакетах. Необходимо установить, как буферизировать данные в программе и проверить, чтобы область буфера, которая отводится, была достаточной.
- Как вычисляется адрес данных на устройстве?
Это относится к структуре устройства. Необходимо изучить устройство и определить, как найти на нём требуемые данные. Обратить внимание, что номера блоков системы ОС БК-11 должны быть преобразованы в адреса на устройстве. Следует иметь в виду что, некоторые процессоры не имеют инструкций умножения или деления.
- Какие "экономические" операции требует
устройство?
Некоторые устройства перед повторением требуют сброса регистров устройства в начальное состояние. Другие требуют, чтобы до выполнения операций на устройстве операционная система поддерживала конкретное число механизмов (дисководов). Например, необходимо выполнить сброс регистров после незавершённого поиска или ошибки передачи.
- Как должны обрабатываться ошибки и условия исключения?
Сначала необходимо решить, какие ошибки являются грубыми и прервут передачу, и какие ошибки являются негрубыми и требуют повторения передачи. Некоторыми типичными негрубыми ошибками являются ошибки контрольной суммы, ошибки временных задержек и ошибки синхронизации. Следует решить, сколько раз необходимо повторять передачу для негрубых ошибок и как обрабатывать условие грубой ошибки.
- Какие обстоятельства аннулирования?
Рассмотреть, является ли устройство относительно быстрым или медленным. Помнить, что не следует сбрасывать регистры контроллера, если только один из носителей двухносительного устройства требует прекращения операции, так как это может мешать операции второго элемента. Подобные обстоятельства могут применяться к двухвходовым носителям.
1.4.2. ТРЕБОВАНИЯ К ПОДПРОГРАММЕ ОБРАБОТКИ
В следующих подразделах описана структура подпрограммы обработки прерывания и содержится план задания с внутренней подпрограммой обработки прерывания. Следует помнить, что подпрограмма обработки прерывания является частью программы пользователя и решить, где поместить её в программе.
Многие опытные программисты готовят блок-схемы после того, как все их программы написаны, или они опускают их совсем. Однако, составление блок-схемы системы со сложным обслуживанием прерывания может помочь составить внутреннюю подпрограмму прерываний и обнаружить ошибки в логике, в случае, когда два или более процессов пытаются изменить одну и ту же структуру данных в одно и то же время, то структура данных разрушается и достоверность результатов непредсказуема. (Например, прерывание устройства произошло во время работы подпрограммы обработки прерывания из-за неправильного приоритета процессора.) После разработки программы пользователя, нужно внимательно проверить каждый шаг, помня, что может случиться при возникновении прерывания в каждой инструкции. Такое планирование поможет избежать возникновения ошибочных ситуаций.
Для проверки подпрограммы обработки прерывания необходимо попытаться выполнить её. Если подпрограмма написана верно, то она будет правильно записывать и считывать данные, обрабатывать условия ошибок. Если при выполнении подпрограммы с подготовленными данными возникнут ошибки, то следует скомпоновать её с ODT и попытаться выполнить шаг за шагом, исправить ошибки в подпрограмме, повторно ассемблировать и снова выполнить.
1.5. СТРУКТУРА ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЯ
В этом подразделе даётся общая структура внутренней подпрограммы обработки прерывания.
1.5.1. ЗАЩИТА ВЕКТОРОВ, МАКРОКОМАНДА .PROTECT
В системах под управлением FB- или ХМ-монитора, где может выполняться более чем одно задание, необходимо использовать макрокоманду .PROTECT для защиты вектора прерывания до того, как в него будет занесено значение. Этот процесс гарантирует, что вектор уже не принадлежит монитору или иному заданию. Он присваивает вектор заданию и защищает его от вмешательства другого задания или монитора, устанавливая биты защиты нижней памяти в мониторе. Задание должно прерваться немедленно, если макрокоманда .PROTECT не срабатывает, задание не будет иметь доступа к вектору, так как он уже используется.
В системе под управлением SJ-монитора макрокоманда .PROTECT не имеет смысла. Она в этом случае не выполняет никакого действия, но желательно её использовать, так как её применение позволит упростить преобразование, если подпрограмма предусматривает выполнение под управлением FB-монитора.
1.5.2. УСТАНОВКА ВЕКТОРА ПРЕРЫВАНИЯ
Программа пользователя должна помещать адрес подпрограммы обработки прерывания в первое слово, а уровень приоритета 7 - во второе слово вектора прерывания. Ниже приведён пример, показывающий типичный способ установки двухсловного вектора прерывания. Следует заметить, что программа не должна устанавливать вектор до тех пор, пока он не будет защищён. Для этого примера предполагается, что именем устройства является XX и вектор прерывания находится в 220 и 222.
XXVEC = 220 ; определение вектора РR7 = 340 ; приоритет 7 = 340 ; ; ISREP - точка входа подпрограммы обработки прерывания .PROTECT #AREA,#XXVEC ; защита вектора BCS NOVEC ; вектор используется MOV #ISREP,@#XXVEC ; установить первое слово MOV #PR7,@#XXVEC+2 ; установить второе слово
1.5.3. МАКРОКОМАНДА .DEVICE
Макрокоманда .DEVICE используется только под управлением FВ- и ХМ-мониторов. Её назначение - отключать устройство, очищая бит разрешения прерывания, если завершается программа или вводится <СУ/C>.
В системе под управлением SJ-монитора использование макрокоманды .DEVICE не имеет смысла, но её всё же рекомендуется включить в программу (это в дальнейшем упростит преобразование, если программа будет выполняться под управлением FB-монитора).
Если программа, выполняющаяся под управлением SJ-монитора, завершается, монитор ожидает окончания всего ввода-вывода, если имеется невыполненный активный элемент очереди. В FB-мониторе, когда программа завершается, монитор не только ожидает выполнения всех элементов очереди, но кроме этого, он передаёт управление драйверу устройства в точке аннулирования запроса. Если задание прерывается по <СУ/C> или если оно выдаёт макрокоманду .HRESET, то SJ-монитор выполняет сброс всех регистров устройств для прекращения ввода/вывода на всех устройствах. При разработке программного обеспечения для данного устройства нужно проверить, останавливается ли оно по очистке при получении сигнала инициализации шины.
1.5.4. МАКРОКОМАНДА .INTEN
При возникновении прерывания управление переходит в точку входа подпрограммы обработки прерываний, адрес которой указан в первом слове вектора прерывания. В этой точке приоритет процессора равен 7, и все другие прерывания запрещены. Если необходимо выполнить что-либо при всех запрещённых прерываниях, то это должно быть сделано программно. Она должна быть как можно более короткой и эффективной и не должна разрушать содержимое регистров. Если подпрограмме необходимо использовать регистры, то она должна хранить и восстанавливать их до вызова макрокоманды .INTEN. Если подпрограмма, выполняемая на уровне приоритета 7 слишком длинна, то будет нарушена реакция системы на прерывания. Рекомендуется, чтобы время выполнения не превышало 50 микросекунд на уровне приоритета 7.
Хорошим подходом является снижение приоритета процессора после прерывания до приоритета устройства. Это позволит устройствам с более высоким приоритетом прерывать работающую подпрограмму обработки прерывания этого устройства. Для снижения уровня приоритета используется макрокоманда .INTEN. Указатель стека и общие регистры с R0 по R5 должны содержать такие же значения при выдаче .INTEN подпрограммой обработки прерывания, как и в точке входа в прерывание. Если подпрограмма обработки прерывания не написана в позиционно-независимом коде (PIC), то используется следующий формат:
.INTEN PRIO
Макрокоманда генерирует следующий код:
JSR R5,@54 .WORD ^C<PRIO*40>&340
Если подпрограмма обработки прерывания пишется в PIC, то макрокоманда .INTEN используется со вторым аргументом - PIC.
.INTEN PRIO,PIC
Второй формат генерирует позиционно-независимый код:
MOV @#54,-(SP) JSR R5,@(SP)+ .WORD ^C<PRIO*40>&340
Оба формата вызывают переход к подпрограмме монитора .INTEN, которая снижает приоритет процессора. затем монитор снова вызывает подпрограмму обработки прерывания, как сопрограмму. R4 и R5 предоставляются для использования после возврата из макрокоманды. Если потребуются R0-R3, то следует сохранить их и восстановить перед выходом из этой макрокоманды. Если необходимо сохранять значения на протяжении работы макрокоманды .INTEN, то необходимо хранить их в памяти до вызова макрокоманды и восстановить их после её выполнения. Подобно этому, если содержимое PS важно (например, значения битов условий), то необходимо сохранить его до выдачи .INTEN. Так как макрокоманда .INTEN вызывает переключение к системному стеку в FB- и XM-мониторах, следует избегать использования стека, и сохранять и восстанавливать регистры и PS, при необходимости, используя ячейки памяти вместо стека. Насчёт SJ-монитора ничего не сказано, но наверное тоже стоит к этому прислушаться.
Примечание. Хранение значений в ячейках памяти не позволяет подпрограмме обработки прерывания быть реентерабельной (повторновходимой). Если предполагается использовать эту подпрограмму для многих устройств, следует быть внимательным относительно реентерабельности при её разработке.
1.5.5. ИСПОЛЬЗОВАНИЕ МАКРОКОМАНДЫ .SYNCH
Макрокоманда .SYNCH используется главным образом в FВ- и ХМ-мониторах. Её назначение - гарантировать, что текущее задание работает, когда подпрограмма обработки прерывания выполняет системную макрокоманду. Использование макрокоманды .SYNCH в SJ-мониторе не имеет смысла, однако её необходимо использовать в любом случае (это в дальнейшем упростит преобразование, если предполагается работа программы под управлением FB-монитора).
Если необходимо выдать одну или более системных макрокоманд из подпрограммы обработки прерывания, нужно сначала вызвать макрокоманду .SYNCH . Следует помнить, что макрокоманда .INTEN переключает выполнение в состояние "система", а системные макрокоманды могут быть выполнены только в состоянии "пользователь". Макрокоманда .SYNCH выполняет обратное переключение в состояние "пользователь". Никогда не следует выдавать системные макрокоманды, требующие USR, из подпрограммы обработки прерывания даже после использования .SYNCH. Можно также выдать .SYNCH после макрокоманды .FORK. При вызове макрокоманды .SYNCH регистры с R0 по R3 и указатель стека должны содержать такие же значения, что и при возвращении из макрокоманды .INTEN.
Табл. 1 иллюстрирует формат блока синхронизации, который действует как элемент очереди. Информация из седьмого слова блока синхронизации помещается в начало очереди завершения соответствующего задания. Вот почему инструкции, следующие за макрокомандой .SYNCH, выполняются как подпрограмма завершения в состоянии пользователя при уровне приоритета 0. Из-за этого программа пользователя должна либо блокировать прерывания перед макрокомандой .SYNCH, либо должна подготовиться к обработке следующего прерывания до выполнения макрокоманды .SYNCH. Блок синхронизации предоставляется для повторного использования, когда Q.COMP (смещение 14 восьмеричное) равна 0. Можно легко проверить блок синхронизации, вызвав ещё раз макрокоманду .SYNCH. Если управление передаётся к обработке ошибки (слово, следующее за .SYNCH), то блок всё ещё используется.
Смещение |
Имя |
Агент |
Содержимое |
---|---|---|---|
0 |
Q.LINK |
- |
Зарезервировано |
2 |
Q.CSW |
Пользователь |
Номер задания |
4 |
Q.BLKN |
- |
Зарезервировано |
6 |
Q.FUNC |
- |
Зарезервировано |
10 |
Q.BUFF |
Пользователь |
Аргумент R0 для передачи |
12 |
Q.WCNT |
Монитор |
-1 |
14 |
Q.COMP |
Пользователь |
После ассемблирования - значение 0; |
Таким образом, между вызовом макрокоманды .SYNCH и возвратом может быть большой интервал времени. Во-первых, переключение в состояние "пользователь" требует времени. Затем, возможно, фоновой подпрограмме завершения придётся ожидать, пока оперативное задание, связанное с вычислением, не заблокируется. Итак, может пройти значительное время, пока инструкция, следующая за .SYNCH, действительно выполнится.
В части программы, следующей за макрокомандой .SYNCH, регистры R0 и R1 свободны для использования как в любой подпрограмме завершения. Регистры с R2 по R5, если они используются, необходимо сохранить, это создаёт проблему для R4 и R5, которые не сохраняются во время выполнения .SYNCH. Если их содержимое важно, то следует сохранить их в памяти до вызова макрокоманды .SYNCH. Можно использовать Q.BUFF в блоке синхронизации для передачи значения в R0 для подпрограммы синхронизации.
Макрокоманда .SYNCH имеет необычный способ возврата управления по ошибке. Первое слово .SYNCH является адресом возврата по ошибке; второе слово - при успешном завершении.
В SJ-мониторе подпрограммы, следующие за вызовами макрокоманды .SYNCH, гнездуются, то есть могут прерывать друг друга. Они упорядочены в FB- и ХМ-мониторах. В SJ-мониторе механизм макрокоманды .SYNCH моделирует схему FB- и ХМ-мониторов, но не дублирует её.
1.5.6. ВЫПОЛНЕНИЕ НА УРОВНЕ ВЕТВЛЕНИЯ. МАКРОКОМАНДА .FORK
Макрокоманда .FORK предоставляет другой способ снижения приоритета процессора. При выдаче её блок ветвления добавляется к очереди ветвления, которая является списком. Принцип действия которого: "первый пришёл - первый обслужился". Подпрограммы ветвления (все инструкции, следующие за макрокомандой .FORK) выполняются в состоянии "системы" при уровне приоритета 0 после того, как обслужены все прерывания, но до того, как монитор переключится в состояние пользователя переключение контекстов запрещается также во время работы подпрограмм ветвления (см. рис. 1).
Регистры R4 и R5 сохраняются во время вызова макрокоманды .FORK. Помимо этого, R0 и R3 свободны для использования после её вызова. Подобно .SYNCH, макрокоманда .FORK предполагает, что регистры с R0 по R3 и стек неизменны, поскольку макрокоманда .INTEN выполнилась. Следует отметить, что выдать .FORK без предшествующего вызова макрокоманды .INTEN нельзя.
Необходимо предоставить четырёхсловный блок памяти для элемента очереди ветвления, три последних слова которого будут содержать R4, R5 и PC. Первое слово является словом связи, которое должно быть равно нулю при выдаче макрокоманды .FORK. Поскольку подпрограмма .FORK не должна быть реентерабельной, следует запретить прерывания на время между моментом выдачи макрокоманды .FORK и временем, когда начнёт выполняться подпрограмма .FORK (инструкции, следующие за макрокомандой).
Нельзя повторно использовать блок ветвления до тех пор, пока работает подпрограмма ветвления. Предполагается, что блок ветвления является свободным, когда макрокоманда, использующая его, выполняется. Иллюстрация блока ветвления приведена в табл. 2.
Смещение |
Имя |
Агент |
Содержимое |
---|---|---|---|
0 |
F.BLNK |
Монитор |
Слово связи |
2 |
F.BADR |
Монитор |
Адрес подпрограммы FORK |
4 |
F.BR5 |
Монитор |
Область хранения R5 |
6 |
F.BR4 |
Монитор |
Область хранения R4 |
Обычно макрокоманда .FORK используется в драйверах устройств. Чтобы использовать её в подпрограмме обработки прерывания, необходимо сначала установить метку ¤FKPTR. Рекомендуется следующая последовательность выполнения головной программы:
MOV @#54,R4 ADD 402(R4),R4 MOV R4,¤FKPTR . . . ¤FKPTR: .WORD 0 XXFBLK: .WORD 0,0,0,0
Затем в подпрограмме обработки прерывания можно использовать обычный формат макрокоманды .FORK:
.FORK XXFBLK
Макрокоманда .FORK генерирует следующий код:
JSR R5,@¤FKPTR .WORD XXFBLK-.
SJ-монитор не поддерживает макрокоманду .FORK, если при генерации системы не будет включено обслуживание таймера. Вместо этого монитор моделирует процесс, сохраняя регистры R0 и R3 до вызова подпрограммы обработки прерывания. Следует запомнить, что в подпрограмме обработки прерывания нет свободных регистров для использования перед вызовом макрокоманды .INTEN. После .INTEN можно свободно использовать R4 и R5.
Применение макрокоманды .FORK полезно в условиях реального времени, т.к. она позволяет откладывать длительную, но не критическую по времени обработку прерывания до тех пор, пока не будут обработаны все другие прерывания.
Макрокоманда .FORK возвращает управление при уровне приоритета 0, но только, когда все другие прерывания обслужены, и до того, как управление возвратится к прерванной программе пользователя.
1.5.7. КРАТКИЕ СВЕДЕНИЯ О МАКРОКОМАНДАХ .INTEN, .FORK И .SYNCH
В табл. 3 кратко изложены сведения об использовании макрокоманд .INTEN, .FORK и .SYNCH.
Имя макрокоманды |
Новый приоритет |
Новый стек |
Регистры, свободные для использования после макрокоманды |
Данные, сохраняющиеся в течение вызова в |
---|---|---|---|---|
.INTEN |
|
Система |
R4, R5 |
Нет |
.FORK |
0 |
Система |
R0-R3 |
R4, R5 |
.SYNCH |
0 |
Пользователь |
R0, R1 |
R0 |
На рис. 4 приводится состояние регистров для каждой макрокоманды в подпрограммах обработки прерываний.
Рис. 4
1.5.8. ВЫХОД ИЗ ПРЕРЫВАНИЯ
Макрокоманда .INTEN заставляет монитор вызывать подпрограмму обработки прерывания как сопрограмму. В конце её используется инструкция RTS PC. Это возвращает управление монитору, который восстанавливает R4 и R5 и затем выполняет инструкцию RTI.
Выход из подпрограмм .FORK и .SYNCH также по инструкции RTS PC. При этом необходимо восстанавливать стек и регистры.
1.6. ПРИМЕР ПОДПРОГРАММЫ ОБРАБОТКИ ПРЕРЫВАНИЯ
Ниже приводится текст оперативной головной программы, содержащей внутреннюю подпрограмму обработки прерывания. Оперативная программа выполняет некоторые задачи инициализации, а затем останавливается. Когда данные поступают из периферийного устройства, то подпрограмма обработки прерывания собирает их. Когда все данные собраны, подпрограмма обработки восстанавливает головную программу, которая может затем обработать новую информацию до очередной остановки.
В этом примере XX представляет имя устройства.
**** ГОЛОВНАЯ ПРОГРАММА **** XXVEC = VVV ;вектор устройства PR7 = 340 ;приоритет 7 DEVPRI= 5 ;приоритет устройства 5 XXCSR = NNNNNN ;регистр команд и состояний IENABL= 100 ;бит разрешения прерывания START: .PROTECT #LIST,#XXVEC ;защита вектора BCS ERROR ;обработать ошибку MOV #ISREP,@#XXVEC ;установить первое слово ;вектора MOV #PR7,@#XXVEC+2 ;установить второе слово ;вектора .DEVICE #LIST,#DEVLST ;блокировать устройство на ;выходе или аннулировании ; ; инициализация входных буферов в подпрограмме обработки ; инициализация других точек и меток ; SPND: BIS #IENABL,@#XXCSR ;разрешить прерывание .SPND ;ожидать данные ; ; сохранение данных ; восстановление меток ; BR SPND ;ожидать ещё данные DEVLST: .WORD XXCSR ;список для .DEVICE .WORD 0 .WORD 0 LIST: .BLKW 3 ;блок аргументов EMT ERROR: . ; подпрограмма обработки . ;ошибок . **** подпрограмма обработки прерывания **** ISREP: . ;точка входа в прерывание . ;приоритет 7 . .INTEN DEVPRI ;внимание: не #DEVPRI ;снизить до приоритета ;устройства, это состояние ;системы с R4 и R5 ; ; если есть ещё данные для сбора ; BR RETURN ; ; если нет больше данных для сбора ; .SYNCH #SYNBLK ; вернуться в головную ;программу для обработки ;данных BR SYNERR ;ошибка SYNCH .RSUM ;продолжить головную ;программу RETURN: RTS PC ;ждать следующего . ;прерывания . . SYNBLK: .WORD 0,2,0,0,0,-1,0 ;замечание: 2 - это номер ;оперативного задания SYNERR: ;обработка ошибок .SYNCH
2. СТРУКТУРА И НАСТРОЙКА ДРАЙВЕРА
Для написания драйвера устройства необходимо на стадии его планирования уточнить некоторые положения. В настоящем документе описаны структура стандартного драйвера и основные его характеристики, а также необязательные свойства, присущие некоторым драйверам, и их применение. Необязательными свойствами являются: установка во внутреннюю очередь (SET-параметры), обеспечение тайм-аута (устройства ввода/вывода), специальные функции.
Чтобы написать программный загрузчик для системного устройства необходимо знать различия между стандартным драйвером и драйвером системного устройства. Эти различия описываются в последующих разделах, где объясняются процедуры ассемблирования, установки, проверки и отладки нового драйвера.
Для правильного написания драйвера в первую очередь необходимо ознакомиться с характеристиками устройства, интерфейсом шины и требованиями, предъявляемыми к подпрограммам обработки прерывания.
Перед созданием драйвера устройства необходимо:
- ознакомиться с устройством;
- изучить структуру стандартного драйвера устройства;
- изучить первичный загрузчик устройства;
- подумать об использовании специальных свойств;
- изучить примеры драйверов;
- подготовить блок-схему драйвера устройства;
- написать программу драйвера;
- установить, проверить и отладить драйвер.
Драйвер устройства системы ОС БК-11 имеет следующие секции:
- введение;
- заголовок;
- инициация ввода/вывода;
- обработка прерывания;
- завершение ввода/вывода;
- завершение драйвера.
Каждая из перечисленных секций представляет собой отдельную логическую единицу, предназначенную для определённой цели. Системная макробиблиотека ОС БК-11 предоставляет специальные макрокоманды для облегчения написания этих секций и драйвера в целом.
2.1. СЕКЦИЯ ВВЕДЕНИЯ
Исходный текст драйвера устройства начинается с секции введения, в которую включается директива .MCALL для указания необходимых макрокоманд (например: .DRDEF и др.). В этой секции устанавливаются символьные определения, которые будут позже использованы.
2.1.1. МАКРОКОМАНДА .DRDEF
Макрокоманда .DRDEF используется в начале секции и позволяет выполнять следующее:
- выдавать директивы .MCALL для всех макрокоманд, связанных с драйвером;
- обеспечивать значения по умолчанию стандартных параметров генерации;
- использовать макрокоманду .QELDF для определения смещений в элементах очереди;
- определять биты характеристик устройства;
- определять размер устройства (DDDSIZ), в блоках;
- определять идентификатор устройства (DD¤COD);
- устанавливать слово состояния устройства из информации, находящейся в DDDSIZ и DD¤COD;
- обеспечивать значения по умолчанию для регистра команд и состояний устройства в DD¤CSR и вектора прерываний в DD¤VEC;
- определять символы DD¤CSR и DD¤VEC глобальными.
Примечание. DD - двухсимвольное имя устройства.
Макрокоманда .DRDEF имеет следующий формат;
.DRDEF NAME,CODE,STAT,SIZE,CSR,VEC |
||||||||
где |
NAME |
- двухсимвольное имя устройства (например, BY для драйвера диска с плавающими головками); |
||||||
CODE |
- восьмеричное числовое значение, которое уникально идентифицирует устройство (байт-идентификатор устройства); |
|||||||
STAT |
- бит слова состояния устройства, в качестве STAT могут быть использованы следующие символы или выражения из них:
|
|||||||
SIZE |
- размер устройства в 256-словных блоках (это значение равно 0, если устройство нефайловой структуры); |
|||||||
CSR |
- значение по умолчанию для регистра команд и состояний устройства; |
|||||||
VEC |
- значение по умолчанию для вектора прерывания устройства. |
2.1.1.1. ДИРЕКТИВА .MCALL
Макрокоманда .DRDEF выдаёт директиву .MCALL для следующих макрокоманд:
.DRAST |
.DRBEG |
.DRFIN |
.DRBOT |
.DREND |
.DRSET |
.DRVTB |
.FORK |
.QELDF |
Помимо этого, при ассемблировании драйвера с условием TIMIT¤=1 макрокоманда .DRDEF выдаёт директиву .MCALL и для макрокоманд:
.TIMIO и .CTIMIO
2.1.1.2. УСЛОВИЯ ГЕНЕРАЦИИ СИСТЕМЫ
Исходные файлы системы ОС БК-11 широко используют директивы условного ассемблирования. Секции драйвера включаются или опускаются во бремя ассемблирования в зависимости от значений стандартных параметров генерации. Например, чтобы указать, должны ли ассемблироваться подпрограммы для регистрации ошибок, система ОС БК-11 использует символьное обозначение ERL¤G.
Если необходимо, чтобы драйвер обеспечивал какую-то функцию, то значение соответствующего стандартного параметра должно быть установлено в 1, в противном случае оно должно быть равно 0.
Макрокоманда .DRDEF устанавливает в 0 стандартные параметры генерации TIMIT¤ (для тайм-аута устройства), MMG¤T (для обеспечения расширенной памяти) и ERL¤G (для регистрации ошибок), если они не определены в файле параметров генерации при ассемблировании. Кроме того, если символы имеют значения, отличные от 0, тo макрокоманда .DRDEF устанавливает их в 1.
2.1.1.3. СМЕЩЕНИЕ В ЭЛЕМЕНТЕ ОЧЕРЕДИ
Макрокоманда .DRDEF вызывает .QELDF для определения символьных смещений в элементах очереди. Следующий пример демонстрирует сгенерированные смещения в элементе очереди.
Q.LINK = 0 (связь со следующим элементом очереди) Q.CSW = 2. (указатель слова состояния канала) Q.BLKN = 4. (номер физического блока) Q.FUNC = 6. (код специальной функции) Q.JNUM = 7. (номер задания) Q.UNIT = 7. (номер устройства) Q.BUFF = ^O10 (адрес буфера пользователя) Q.WCNT = ^O12 (счётчик слов) Q.COMP = ^O14 (код подпрограммы завершения) Q.ELGH = ^O16 (длина элемента очереди)
Поскольку драйвер обычно имеет дело со смещениями в элементах очереди относительно Q.BLKN, то макрокоманда .QELDF такие определяет следующие символьные смещения:
Q¤LINK = -4 Q¤CSW = -2 Q¤BLKN = 0 Q¤FUNC = 2 Q¤JNUM = 3 Q¤UNIT = 3 Q¤BUFF = 4 Q¤WCNT = 6 Q¤COMP = 10
2.1.1.4. ОПРЕДЕЛЕНИЕ СИМВОЛЬНЫХ ОБОЗНАЧЕНИЙ
Для определения символьных обозначений, которые в дальнейшем будут использованы в драйвере, применяются операторы прямого присвоения. Обычно определения включают регистры драйверов и другие величины.
Ниже приводится ряд примеров из драйверов ОС БК-11:
Для символа перевода строки (код в КОИ-7 равен 12) используется следующее определение:
LF = 12 ; перевод строки
Для определения регистров устройства:
RKDS = RK¤CSR ;регистр состояния драйвера RKER = RKDS+2 ;регистр ошибки RKCS = RKDS+4 ;регистр управления состоянием RKWC = RKDS+6 ;регистр счётчика слов
Макрокоманда .DRDEF определяет следующие символы:
HDERR¤ = 1 ; бит грубой ошибки в CSW EOF¤ = 20000 ; бит конца файла в CSW
2.1.2. БАЙТ-ИДЕНТИФИКАТОР УСТРОЙСТВА
Младший байт слова состояния устройства (байт-идентификатор) идентифицирует каждое устройство в системе. Идентификатор устройства определяется как аргумент CODE макрокоманды .DRDEF. В табл. 4 представлены эти знамения в восьмеричном коде:
Байт-идентификатор |
Устройство |
|
---|---|---|
Имя |
Наименование |
|
0 |
RK |
Диск с плавающими головками кассетного типа |
1-2 |
- |
Зарезервировано |
3 |
LP |
Устройство параллельной печати |
4 |
TT/BA |
Системный терминал или драйвер пакетной обработки |
5 |
- |
Зарезервировано |
6 |
BY |
Гибкий диск двойной плотности |
7 |
PC |
Перфоленточное устройство ввода/вывода |
10 |
- |
Зарезервировано |
11 |
MT |
Магнитная лента |
12 |
RP |
Диск с фиксированными головками |
13 |
CT |
Накопитель на кассетной ленте |
14 |
CR |
Устройство ввода с перфокарт |
15-17 |
- |
Зарезервировано |
20 |
MM |
Магнитная лента с высокой плотностью |
21 |
DP |
Пакет сменных дисков |
22 |
DX |
Гибкий диск |
23 |
DM |
Диск 14М байтов |
24 |
- |
Зарезервировано |
25 |
NL |
Нуль-устройство |
26-30 |
- |
Зарезервировано (для системы ТОДа) |
31-40 |
- |
Зарезервировано |
41 |
LS |
Устройство последовательной печати |
42 |
MQ |
Псевдоустройство внутренних сообщений |
44 |
XT |
Драйвер связи для распределённых систем |
60 |
UX,UY,UZ |
Драйверы виртуальных носителей SJ/FB/XM-мониторов |
377 |
VM |
Драйвер расширенной памяти |
Примечание. Для задания кодов байтов-идентификаторов устройств, которые не указаны в этой таблице. Необходимо использовать для первого устройства восьмеричный код 376, для второго - 375 и т.д. не следует использовать коды, которые система отводит для новых аппаратных устройств.
2.1.3. СЛОВО СОСТОЯНИЯ УСТРОЙСТВА
Слово состояния устройства определяет каждое физическое устройство в системе ОС БК-11 и содержит информацию о нём (например, является ли доступ прямым или последовательным). Значение слова состояния хранится в блоке 0 файла драйвера и в таблице монитора ¤STAT после установки устройства. Макрокоманда .DSTATUS посылает это значение выполняющейся программе. A .DRDEF устанавливает слово состояния устройства, используя аргументы CODE и STAT.
В табл. 5 представлены значения битов в слове состояния устройства. Макрокоманда .DRDEF использует символ DDSTS для представления слова состояния устройства.
Бит |
Символ |
Значение |
---|---|---|
0-7 |
- |
Байт-идентификатор устройства |
8-9 |
- |
Зарезервировано |
10 |
SPFUN¤ |
0 = макрокоманда .SPFUN запрещена 1 = драйвер может выполнить макрокоманду .SPFUN |
11 |
HNDLR¤ |
0 = при удалении программы драйвер выполняет завершающие операции с устройством, если элемент очереди активен 1 = при удалении программы драйвер выполняет завершающие операции с устройством |
12 |
SPECL¤ |
1 = устройство с нестандартной файловой структурой (например, CT) |
13 |
WONLY¤ |
1 = устройство только для записи |
14 |
RONLY¤ |
1 = устройство только для чтения |
15 |
FILST¤ |
0 = устройство с последовательным доступом (например, CT, LP) 1 = устройство с прямым доступом (например, BY) |
Примечание. Следует отметить, что 11-й бит в слове состояния должен быть установлен для драйверов устройств, которые при входе в подпрограмму обработки прерывания удаляют элемент очереди и устанавливают его во внутреннюю очередь, и для драйверов устройств, которые имеют внутренние данные, требующие изменения при прерывании (например, CT:).
Все устройства, в драйверах которых установлен бит 15, воспринимаются большинством системных программ как устройства файловой структуры.
Простым способом определения слова состояния является использование мнемоники для битов. Можно задать аргумент STAT, используя следующие символьные обозначения или комбинацию из них.
FILST¤ == 100000 ;структура файла с прямым доступом RONLY¤ == 40000 ;только чтение WONLY¤ == 20000 ;только запись SPECL¤ == 10000 ;нет каталога HNDLR¤ == 4000 ;завершение операции будет выполнять драйвер SPFUN¤ == 2000 ;может выполнять специальные функции
Пример. Указать аргумент STAT макрокоманды .DRDEF для драйверов BY, CT и LP:
для |
BY: |
FILST¤ |
для |
CT: |
SPECL¤!SPFUN¤!HNDLR¤ |
для |
LP: |
WONLY¤ |
2.1.4. СЛОВО РАЗМЕРА УСТРОЙСТВА
Аргумент SIZE макрокоманды .DRDEF определяет размер устройства в 256-словных блоках. Макрокоманда .DRDEF помещает это значение в DDDSIZ. Если устройство не является устройством с прямым доступом, то в SIZE записывается 0.
Макрокоманда .DSTATUS возвращает программе значение слова размера устройства.
2.2. СЕКЦИЯ ЗАГОЛОВКА
Второй секцией драйвера является секция заголовка. В секции заголовка вызывается макрокоманда .DRBEG для установки первых пяти слов драйвера. Эта макрокоманда хранит пять слов информации в блоке 0 файла драйвера в ячейках с 52 по 60 и создаёт некоторые глобальные символы. Данные, устанавливаемые в секции заголовка, используются при загрузке драйвера в память макрокомандой .FETCH или командой монитора LOAD. Содержимое ячейки 176, описанное ниже, используется загрузчиком для проверки наличия устройства во время установки драйвера.
2.2.1. ИНФОРМАЦИЯ В БЛОКЕ 0
В табл. 6 представлено содержание (и мнемоника) восьми слов в блоке 0: из них пять слов устанавливает макрокоманда .DRBEG, используя директиву .ASECT, и три слова, используемые для загружаемых устройств - макрокоманда .DRBOT. (принятые условности: мнемоническое обозначение указано в квадратных скобках, DD - двухсимвольное имя устройства.)
Ячейка |
Содержание |
---|---|
52 |
Размер драйвера в байтах [DDEND-DDSTRT] |
54 |
Размер устройства в 256-словных блоках [DDDSIZ] |
56 |
Слово состояния устройства [DDSTS] |
60 |
Слово состояния для отражения свойств сгенерированной текущей версии системы [ERL¤G+<MMG¤T*2>+<TIMIT¤*4>] |
62 |
Указатель начала основного привода (.DRBOT) |
64 |
Длина основного привода, в байтах (.DRBOT) |
66 |
Смещение от начала основного привода до начала подпрограммы чтения загрузчика (.DRBOT) |
176 |
Адрес регистра команд и состояний [DD¤CSR] |
2.2.2. ПЕРВЫЕ ПЯТЬ СЛОВ ДРАЙВЕРА
В табл. 7 представлены пять слов, которые генерируются с помощью макрокоманды .DRBEG в начале P-секции драйвера (DD - двухсимвольное имя устройства).
Слово |
Символ |
Описание |
---|---|---|
1 |
DDSTRT:: |
Вектор устройства (для одновекторных устройств); смещение к таблице векторов (для многовекторных устройств) |
2 |
- |
Смещение к точке входа подпрограммы обработки прерывания |
3 |
- |
Приоритет (340) |
4 |
DDLQE:: |
Указатель последнего элемента очереди к драйверу |
5 |
DDCQE:: |
Указатель текущего элемента очереди |
2.2.3. МАКРОКОМАНДА .DRBEG
Макрокоманда .DRBEG используется для установки в блок 0 первых пяти слов драйвера. Эта макрокоманда генерирует надлежащие глобальные символы для драйвера. Перед использованием .DRBEG необходимо вызвать макрокоманду .DRDEF для определения DD¤CSR, DD¤VEC, DDDSIZ и DDSTS. Макрокоманда .DRBEG имеет следующий формат:
.DRBEG NAME |
||
где |
NAME |
- двухсимвольное имя устройства. |
Примеры использования .DRBEG приведены в приложении.
2.2.4. МНОГОВЕКТОРНЫЕ ДРАЙВЕРЫ. МАКРОКОМАНДА .DRVTB
Драйвер может обслуживать устройство, имеющее более одного вектора прерывания.
Если устройство имеет более одного вектора прерывания, то для каждого вектора драйвер должен содержать таблицу, состоящую из трёх слов:
- адреса вектора прерывания;
- точки входа в подпрограмму обработки прерывания;
- значения слова состояния процессора (PS).
Чтобы установить заголовок драйвера для многовекторного устройства, необходимо просто вызвать макрокоманду .DRVTB два или более раз. Макрокоманда .DRVTB устанавливает таблицу для каждого вектора. Они помещаются в драйвере между макрокомандой .DRBEG и макрокомандой .DREND (или .DRBOT), но до подпрограммы обработки прерывания. Вызов этой макрокоманды осуществляется один раз для каждого вектора и в определённой последовательности.
Макрокоманда .DRVTB имеет следующий формат:
.DRVTB NAME,VEC,INT[,PS] |
||
где |
NAME |
- двухсимвольное имя устройства (оно должно указываться только в первом вызове макрокоманды .DRVTB); |
VEC |
- ячейка вектора (от 0 до 474). Первым вектором обычно является DD¤VEC. Значение должно быть кратно четырём; |
|
INT |
- символьное имя (метка) подпрограммы обработки прерывания (оно должно быть определено в драйвере, например, макрокомандой .DRAST), принимающее форму DDINT, где DD - двухсимвольное имя устройства; |
|
PS |
- значение (необязательное), которое может использоваться для определения младших четырёх битов нового слова состояния процессора в векторе прерывания. Если этот аргумент опускается, то его значение по умолчанию принимается равным 0. |
Фрагмент драйвера PC, который использует два вектора.
Таблица векторов перфоленточного устройства ввода-вывода:
.IF EQ PR11¤X ; устройство ввода/вывода на ПЛ? .DRVTB PC,PR¤VEC,PRINT ; таблица для устройства ; ввода с ПЛ .DRVTB ,PP¤VEC,PPINT ; таблица для устройства ; вывода на ПЛ .ENDC
Таблица векторов, сгенерированная макрокомандами .DRVTB, имеет следующий вид:
.WORD PR¤VEC,PRINT-.,340|0 ; таблица для устройства ; вводас ПЛ .WORD PP¤VEC,PPINT-.,340|0 ; таблица для устройства ; вывода на ПЛ .WORD 0 ; конец таблицы
Как показано в примере, биты приоритета PS всегда устанавливаются в 7, даже если аргумент PS был опущен.
2.2.5. КОДЫ УСЛОВИЙ PS
В макрокоманде .DRVTB только биты кодов условий аргумента PS являются значащими. Они могут быть полезными, если имеется общая точка входа подпрограммы обработки прерывания в драйвере с двумя и более векторами и необходимо определить, по какому вектору возникло прерывание. Например, драйвер PC имеет отдельные точки входа в прерывания для двух векторов, и он легко может определить источник прерывания. Прерывания по вектору 70 идут к подпрограмме PRINT:, прерывания по 74 - к PPINT:. Если предположить, что драйвер PC имеет только одну точку входа в прерывание, названную PCINT:, то необходимо установить коды условий в PS для каждого вектора. В этом случае драйвер может отличить, по какому вектору произошло прерывание, анализируя новое слово состояния процессора. Например, если в PS бит "C" равен 0, прерывание произошло по вектору 70, а если бит "C" установлен в 1, то - по вектору 74, в соответствии с этим управление может передаваться различным подпрограммам.
Следующий пример демонстрирует вызов макрокоманды .DRVTB и занесение значений в коды условий PS:.
Таблица векторов перфоленточного устройства ввода-вывода
.IF EQ PR11¤X ; ввод и вывод на ПЛ? .DRVTB PC, PR¤VEC,PCINT ; бит "C" сброшен .DRVTB ,PP¤VEC,PCINT,1 ; бит "C" установлен .ENDC
2.3. СЕКЦИЯ ИНИЦИАЦИИ ВВОДА/ВЫВОДА
Секция инициации ввода/вывода содержит первые выполняемые инструкции драйвера. Назначение этой секции - начать передачу данных.
Примечание. Следует помнить, что исходный текст драйвера должен быть написан в позиционно-независимом коде.
Когда в программе встречается системная макрокоманда ввода/вывода (например, .READ или .WRITE), то управление сначала переходит к резидентному монитору, вызывающему драйвер периферийного устройства по инструкции JSR PC. Монитор передаёт управление шестому слову драйвера, т.е. первому слову после заголовка. Он делает вызов каждый раз, когда элемент очереди становится первым элементом в очереди драйвера. Эта ситуация возникает, когда элемент добавляется к пустой очереди или, когда элемент становится первым в очереди, т.к. предыдущий элемент был удалён из очереди. Если какой-либо аргумент в вызове макрокоманды на ввод/вывод является недопустимым для устройства (например, номер блока слишком большой, номер устройства слишком большой и т.д.), драйвер должен немедленно перейти к секции завершения ввода/вывода и сообщить о грубой (неустранимой) ошибке.
Инициация ввода/вывода выполняется в режиме "система" при 0 приоритете процессора. Что означает невозможность переключения в режим "пользователь", подпрограммы завершения не могут выполняться и прерывания по 4 и 10 векторам вызывают останов системы. В этой секции все регистры предоставляются пользователю. Пятое слово заголовка драйвера DDCQE содержит адрес третьего слова (Q.BLKN) текущего элемента очереди.
Постановка в очередь ввода/вывода гарантирует, что запросы на передачу данных будут упорядоченными, т.е. драйверы устройств в ОС БК-11 не должны быть реентерабельными, поэтому размер драйвера можно минимизировать путём смешивания выполняемых инструкций и сегментов данных, а не разделения их.
Для написания секции инициации ввода/вывода, назначение которой начать передачу данных, рекомендуется выполнить следующие шаги:
- Решить, сколько раз драйвер повторит передачу в случае, если возникнет
ошибка. Инициализировать счётчик повторных передач, поместив в него максимальное
число передач. Следующий пример наглядно иллюстрирует это:
MOV #RKCNT,(PC)+ ;в RKCNT макс. число повторений RETRY: .WORD 0 ;счетчик повторений
- Поместить указатель текущего элемента очереди в регистр и получить номер
устройства и номер блока из элемента очереди для передачи. Например:
MOV RKCQE,R5 ;получить указатель MOV @R5,R2 ;в R2 номер блока MOVB Q¤UNIТ(R5),R4 ;в R4 номер устройства BIC #^C<7>,R4
- Вычислить адрес устройства для передачи данных и сохранить его в ячейке
памяти, чтобы при повторной передаче не вычислять его вновь:
. . . MOV R3,(PC)+ ;сохранить адрес в DISKAD DISKAD: .WОРD 0 ;сохранить его здесь
Примечание. Вышеуказанные шаги выполняются один раз для каждого запроса ввода/вывода, изданного в текущей программе. В случае негрубой ошибки эти шаги могут быть повторены.
- Определить вид запроса (запись, чтение или поиск) и записать соответствующую
ему константу в регистр команд и состояний устройства. Этот шаг фактически
начинает ввод/вывод.
CSIE = 100 ;разрешить прерывание FNWRITE = 1*2 ;писать CSGO = 1 . . . AGAIN: MOV RKCQE,R5 ; указать элемент очереди MOV #CSIE!FNWRITE!CSGO,R3 ;запись допустима MOV #RКDА,R4 ; указатель регистра ;адреса диска
После выполнения этих шагов устройство будет готово к обработке прерывания. Как только возникнет прерывание управление перейдёт к драйверу в точке входа секции обработки прерывания.
RTS PC ;ждать прерывание
2.4. СЕКЦИЯ ОБРАБОТКИ ПРЕРЫВАНИЯ
После окончания ввода/вывода или наступления прерывания по запросу от устройства управление передаётся секции обработки прерывания. В данной секции определяется, с ошибкой или без ошибки передались данные.
В начале секции обработки прерывания устанавливается точка входа в подпрограмму обработки прерывания и точка аннулирования запроса. Эти точки устанавливаются макрокомандой .DRAST. Именем (по умолчанию) для точки входа в подпрограмму обработки прерывания является DDINT, где DD - имя устройства. При нормальных условиях управление передаётся драйверу в точку входа подпрограммы обработки прерывания после наступления прерывания. Однако, при некоторых обстоятельствах драйвер вызывается с точки аннулирования запроса. Различные ситуации описаны ниже.
2.4.1. ТОЧКА АННУЛИРОВАНИЯ ЗАПРОСА
Существует ряд ситуаций, которые вызывают аннулирование запроса ввода/вывода:
- двойное нажатие <СУ/C>, прерывающее текущую программу;
- макрокоманда .HRESET;
- прерывание по векторам 4 и 10 или любое другое условие, которое печатает сообщение о неустранимой ошибке типа "?MON-F-".
При указанных ситуациях управление может передаваться или не передаваться драйверу. Это зависит от того, имеется ли активный элемент очереди. В случае, если он есть, управление передаётся драйверу в точку аннулирования запроса. При всех обстоятельствах при входе в драйвер R4 всегда содержит номер аннулированного задания.
При возникновении аннулирования важно остановить ввод/вывод на некоторых устройствах (символьно-ориентированных, например, перфоленточное устройство ввода/вывода). В этом случае при аннулировании драйвер должен остановить устройство, чтобы бесполезно не расходовать перфоленту. Он обеспечивает невозможность продолжения ввода/вывода, поэтому драйверы символьно-ориентированных устройств обычно содержат подпрограмму аннулирования; точка аннулирования запроса является просто инструкцией перехода к этой подпрограмме. Например, драйвер PC имеет подпрограмму аннулирования, которая блокирует прерывания на перфоленточном устройстве ввода/вывода. Затем драйвер (через секцию завершения ввода/вывода) передаёт управление монитору.
Пример. Строка из драйвера PC (PRCSR - это слово в драйвере, которое указывает CSR):
PRDONE: CLR @PRSCR ;выйти из прерывания
Другим устройствам (например, дискам) должно быть разрешено завершать операции ввода/вывода даже при возникновении аннулирования. Попытка аннулирования в середине операции может разрушить данные или формат информации на устройстве. Большинство драйверов для таких устройств игнорируют аннулирование. Инструкция RTS PC находится в точке аннулирования запроса, которая просто возвращает управление монитору.
Если в драйвере устройства используется макрокоманда .FORK, то при возникновении аннулирования выполняется специальная процедура. Необходимо поместить 0 в F.BADR (адрес подпрограммы ветвления со смещением 2) в блоке ветвления. Это препятствует монитору выполнить подпрограмму ветвления, не имевшую смысла после прерывания.
2.4.2. ПОНИЖЕНИЕ ПРИОРИТЕТА ПРОЦЕССОРА ДО ПРИОРИТЕТА УСТРОЙСТВА
При возникновении прерывания драйвер имеет приоритет 7. Поэтому в подпрограммах обработки прерывания драйвер сначала понижает приоритет процессора до приоритета устройства, позволив, таким образом, более приоритетным устройствам прерывать эту сервисную подпрограмму. Как и в подпрограмме обработки прерывания, вместо использования микрокоманды .INTEN, необходимо для снижения приоритета использовать микрокоманду .DRAST.
2.4.3. МАКРОКОМАНДА .DRAST
Макрокоманда .DRAST используется для установки точки входа подпрограммы обработки прерывания и выхода из прерывания, и для снижения приоритета процессора. Это макрокоманда также устанавливает глобальный символ ¤INPTR, который содержит указатель подпрограммы ¤INTEN в резидентном мониторе. Этот указатель заполняется загрузчиком (для системного устройства) или во время выполнения макрокоманды .FETCH (командой монитора LOAD).
Макрокоманда .DRAST имеет следующий формат:
.DRAST NAME,PRI[,ABO] |
||
где |
NAME |
- двухсимвольное имя устройства; |
PRI |
- приоритет устройства, т.е. приоритет, при котором должна выполняться подпрограмма обработки прерывания; |
|
ABO |
- аргумент (необязательный), который представляет собой метку точки аннулирования запроса. Если аргумент опущен, то эта макрокоманда генерирует инструкцию RTS PC в точке аннулирования запроса, которая является словом, непосредственно предшествующим точке входа в прерывание. |
Следующий пример из драйвера PC демонстрирует вызов макрокоманды .DRAST код, который она генерирует:
.DRAST PP,4,PRDONE .GLOBL ¤INPTR ;определить глобальный символ BR PRDONE ;отвергнуть точку входа PRINT:: JSR R5,@¤INPTR ;вызов п/п обработки прерывания .WORD ^C<4*^O40>&^O340 ; новый приоритет
Ниже приводится пример из драйвера BY, не имеющего подпрограммы аннулирования:
.DRAST BY,5 .GLOBL ¤INPTR ;определить глобальный символ RTS PC ;возврат при аннулировании BYINT:: JSR R5,@¤INPTR ;вызов п/п обработки прерывания WORD ^C<5*^O40>&^O340 ;новый приоритет
2.4.4. РЕКОМЕНДАЦИИ ПО ПРОГРАММИРОВАНИЮ СЕКЦИИ
Поскольку назначением этой секции является вычисление результатов действия активного устройства, то для этого необходимо воспользоваться рекомендациями по написанию секции обработки прерывания. Но прежде требуется определить, была ли передача завершена, была ли она не завершена, или при передаче возникла ошибка.
Если во время передачи возникла ошибка, то драйвер должен установить, была ли эта ошибка грубой или нет.
Если ошибка грубая, то драйвер должен немедленно передать управление монитору через секцию завершения ввода/вывода.
Если ошибка негрубая, то драйвер может выполнить повторную передачу. Он должен уменьшить счётчик повторных передач. Затем вернуться в секцию инициации ввода/вывода для возобновления передачи. Если попытка передачи повторилась заданное число раз (т.е. счётчик равен 0), то ошибка рассматривается как грубая, и драйвер должен перейти в секцию завершения ввода/вывода.
Следует отметить, что переход к уровню ветвления не обязателен для обработки ошибки. Использовать или нет макрокоманду .FORK зависит от длительности времени, требуемого для проведения повторных передач, применение макрокоманды .FORK предоставляет возможность использования регистров R0-R3, позволяя, таким образом, использовать общие подпрограммы для повторных передач. Если не используется макрокоманда .FORK, то в наличии будут только регистры R4 и R5.
Макрокоманда .FORK вызывает передачу управления резидентному монитору. Инструкции, следующие за .FORK, выполняются на нулевом приоритете (а не на приоритете устройства) после того, как будут обслужены все другие прерывания, но до того, как могут выполняться другие задания или их подпрограммы завершения. Инструкции, следующие за макрокомандой .FORK, представляют собой основное тело секции обработки прерывания драйвера в состоянии "система". (это такое же состояние, в которой выполняется секция инициации ввода/вывода.) Поэтому, любой переход по векторам 4 и 10 вызывает останов системы.
Следующий пример из драйвера BY иллюстрирует, как приоритет драйвера снижается до уровня ветвления для повторной передачи данных после возникновения негрубой ошибки. Так как этот процесс может быть длительным, то уровень ветвления идеально подходит для выполнения повторных передач.
Макрокоманда .FORK и её расширение:
.FORK BYFBLK ;вызов .FORK JSR R5,@¤FKPTR ;перейти в монитор с кодом FORK .WORD BYFBLK-. ;смещение в элементе очереди FORK BYRETR: CLRB RETRY+1 ;сбросить флаг BR AGAIN ;перейти в секцию инициации В/В
Передача считается незавершённой, если символы или блоки данных остались непереданными. Драйвер должен повторно инициировать устройство и выйти по инструкции RTS PC для ожидания следующего прерывания.
Когда передача завершена, то драйвер может просто передать управление монитору через секцию завершения ввода/вывода.
2.5. СЕКЦИЯ ЗАВЕРШЕНИЯ ВВОДА/ВЫВОДА
Секция завершения ввода/вывода драйвера обеспечивает передачу управления монитору. При этом монитору сообщается, что драйвер выполнил текущий запрос, и монитор может освободить текущий элемент очереди. Если другие секции драйвера являются отдельными его частями, то секция завершения ввода/вывода фактически является расширением секции обработки прерывания, и разделение этих двух секций является искусственным. Управление передаётся в секцию завершений через секцию обработки прерывания. Выполнение переходит к секции завершения ввода/вывода в случаях:
- завершения передачи данных;
- когда повторения негрубой ошибки достигли максимально заданного числа;
- обнаружения грубой ошибки, (следует отметить, что можно немедленно выполнить условный переход непосредственно в эту секцию из секции инициации ввода/вывода при обнаружении грубой ошибки.)
Существует два вида ошибок, которые вызывают передачу управления в секцию завершения ввода/вывода:
- Грубые (неустранимые) ошибки
-
ошибки, которые немедленно вызывают условный переход в эту секцию;
- Негрубые (устранимые) ошибки
-
ошибки, которые исчерпали отведённое им число повторений, что вызывает условный переход в эту секцию после последнего неудачного повторения.
При выходе из драйвера в обоих случаях произойдёт передача управления от драйвера к монитору.
Во-первых, необходимо установить бит грубой ошибки (бит 0) в слове состояния канала (CSW), второе слово элемента очереди ввода/вывода (Q.CSW) указывает на слово состояния канала. Затем перейти к подпрограмме завершения ввода/вывода в резидентном мониторе, используя для этого перехода макрокоманду .DRFIN, описанную ниже.
Следующий пример приведён из драйвера BY. Он иллюстрирует установку бита грубой ошибки драйвером и переход к монитору:
BIS #HDERR¤,@-(R5) ; установить бит грубой ; ошибки (R5 указывает ; на третье слово элемента ; очереди ; указатель CSW ; находится во втором слове) .DRFIN BY ; перейти к монитору
Для устройства, ориентированного на блоки (например, диск) драйвер просто блокирует прерывание и выполняет переход к монитору. Как показано во втором примере, макрокоманда .DRFIN генерирует код для выполнения перехода.
Для устройства, ориентированного на слова или символы (например, УВВЛ), процедура будет более сложной. В этом случае драйвер должен сообщить о достижении конца файла заданию, которое выставило запрос на ввод-вывод. Примерами условий, требующих подобного рода сообщение, являются: отсутствие ленты в УВВЛ или обнаружение <СУ/Z>, введённого с терминала. Когда драйвер действительно обнаруживает условие EOF (конец файла) при операции чтения, то он должен установить внутренний флажок EOF, поместить последний символ в буфер пользователя и затем заполнить нулями остаток буфера. Затем драйвер
должен, передать управление монитору, как если бы метка EOF не была обнаружена, а просто был бы заполнен буфер. Драйвер снова ожидает вызова, чтобы сообщить пользователю о достижении конца файла.
Драйвер PC использует бит готовности УВВЛ в регистре состояния устройства как внутренний флажок EOF, Следующий пример демонстрирует, как драйвер PC заполняет нулями буфер пользователя при обнаружении конца файла, устанавливает внутренний флажок EOF и возвращает управление монитору:
PREO1: CLRB @(R4)+ ; очистить остаток буфера ;(R4 указывает на адрес буфера) INC -(R4) ; увеличить адрес буфера DEC BYTCNT-BUFF(R4) ; проверить BNE PREO1 ; возвратиться, если больше PRDONE: CLR @PRCSR ; запретить прерывание PRFIN: .DRFIN PR ; перейти к монитору
Когда драйвер снова вызывается с новым элементом очереди для другой операции чтения, то он сначала проверяет внутренний флажок EOF . Обнаружив, что он установлен, драйвер устанавливает бит EOF слова состояния канала (бит 13), и возвращает управление монитору. Резидентный монитор может, в конечном счёте, очищать этот бит при выполнении следующего запроса на ввод-вывод для этого канала.
Следующий пример демонстрирует, как драйвер PC проверяет бит готовности устройства, который он использует как внутренний флажок EOF , устанавливает бит EOF для программы пользователя и возвращает управленце монитору:
TST @#РR¤CSR ; устройство ввода с ПЛ готово? BPL PRGORD ; да, начать передачу BIS #EOF¤,@-(R4) ; нет, установить бит EOF BR PRDONE ; переход на завершение ... PRDONE: CLR @PRCSR ; запретить прерывание PRFIN: .DRFIN PR ; перейти к монитору
Это соглашение об указании конца файла означает, что символьно-ориентированные устройства воспринимаются программой как устройства с прямым доступом, что соответствует независимости устройств в ОС БК-11.
2.5.1. МАКРОКОМАНДА .DRFIN
Макрокоманда .DRUM предназначена для генерации инструкций, которые возвращают управление монитору. И используется в конце секции завершения ввода/вывода драйвера. Макрокоманда объявляет указатель текущего элемента очереди глобальным символом и генерирует позиционно-независимый код для перехода к монитору. Когда управление переходит к монитору, то монитор освобождает текущий элемент очереди.
Макрокоманда .DRFIN имеет следующий формат:
.DRFIN NAME |
||
где |
NAME |
- двухсимвольное имя устройства. |
Примеры макрокоманды .DRFIN приведены в приложении.
2.6. СЕКЦИЯ ЗАВЕРШЕНИЯ ДРАЙВЕРА
Назначение секции завершения драйвера - объявить некоторые глобальные символы и установить таблицу указателей смещений в резидентном мониторе. Указатели заполняются загрузчиком, если это драйвер системного устройства. Они заполняются иначе, если драйвер загружается макрокомандой .FETCH или командой монитора LOAD. Секция завершения также определяет символ для размера драйвера. Макрокоманда .DREND используется для генерации инструкций завершения драйвера
2.6.1. Макрокоманда .DREND
Формат макрокоманды .DREND следующий:
.DREND NAME |
||
где |
NAME |
- двухсимвольное имя устройства. |
Примеры макрокоманды .DREND см. в приложении.
2.6.2. ПСЕВДОУСТРОЙСТВА
Можно написать драйвер для псевдоустройства (которое не прерывается и не является устройством с большой памятью) для использования преимуществ постановки в системную очередь ввода/вывода и, при этом, драйверы могут оставаться резидентными в памяти. Примерами драйверов для псевдоустройств являются: NL (нуль-драйвер) и MQ (драйвер очереди сообщений).
Все выполняемые инструкции такого драйвера должны быть в секции инициации ввода/вывода. Поскольку псевдоустройства не прерываются, то драйверу не требуется секция обработки прерывания и вызов макрокоманды .DRAST. Затем в драйвере необходимо вызвать макрокоманду .DRFIN для завершения операции и возврата элемента очереди.
3. ТИПОВАЯ СХЕМА ДРАЙВЕРА УСТРОЙСТВА
Ниже представлена структура драйвера устройства, здесь имя XX является именем устройства.
.TITLE XX V02.01 ; драйвер устройства XX .IDENT /V02.01/ .SBTTL секция введения .MCALL .DRDEF .DRDEF XX,377,WONLY¤,0,177514,200 XXBR = XX¤CSR+2 ; регистр буфера XX XXIE = 100 ; бит разрешения прерывания .SBTTL секция заголовка .DRBEG XX .SBTTL секция инициации ввода/вывода MOV XXCQE,R4 ; R4 указывает на текущий ; элемент очереди ASL Q¤WCNT(R4) ; сделать словный счетчик - ; байтным BEQ XXDONE ; немедленно завершить BCC XXERR ; устройство только для ; записи, запрос на чтение ; неверный RET: BIS #XXIE,@#XX¤CSR ; разрешить прерывание RTS PC ; ждать его .SBTTL секция обработки прерывания .DRAST XX,4,XXDONE MOV XXCQE,R4 ; R4 указывает на текущий ; элемент очереди BIT #100200,@#XX¤CSR ;ошибка или готовность? BMI RET ; ошибка - вернуться назад BEQ RET ; нет -готовности - выйти и ; ждать BIC #XXIE,@#XX¤CSR ; запретить прерывание .FORK XXFBLK ; перейти к ф-обработке ADD #Q¤WCNT,R4 ; адрес счетчика в R4 XXNEXT: TSTB @#XX¤CSR ; готово для след. Символа? BPL RET ; нет, вернуться назад TST @R4 ; печатать? BEQ XXDONE ; уже все - завершить MOVB @-(R4),R5 ; получить символ INC (R4)+ ; увеличить адрес буфера INC (R4) ; увеличить счетчик символов BIC #^C<177>,R5 ; перевод в код КОИ-7 MOVB R5,@#XXBR ; переслать символ на устр-в BR XXNEXT ; идти за следующим символом .SBTTL секция завершения ввода/вывода XXERR: BIS #HDERR¤,@-(R4) ; установить бит ошибки XXDONE: BIC #XXIE,@#XX¤CSR ; запретить прерывания .DRFIN XX ; перейти к монитору XXFBLK: .WORD 0,0,0,0 ; элемент очереди fork .SBTTL секция завершения драйвера .DREND XX .END
4. СПЕЦИФИЧНЫЕ СВОЙСТВА ДРАЙВЕРА
4.1. ВНУТРЕННЯЯ ОЧЕРЕДЬ ДРАЙВЕРОВ
Драйвер устройства, вместо использования обычной очереди ввода/вывода монитора/драйвера, может обслужить одну или более из своих собственных внутренних очередей из невыполненных запросов ввода/вывода. Цель обслуживания внутренней очереди заключается в том, что она позволяет выполняться нескольким операциям на устройстве одновременно, драйвер может обслужить сразу несколько запросов к устройству.
Примером является очередь сообщений системы, использующая драйвер MQ для связи системных заданий. Если одно задание посылает сообщение другому заданию, а второе задание не принимает это сообщение, то драйвер MQ переходит в состояние ожидания. Однако, если запрос на приём для задания является очередным, то драйвер MQ обрабатывает запрос. Чтобы выполнить это, он принимает исходный запрос от задания из очереди монитора/драйвера. Устанавливает его во внутреннюю очередь и затем обслуживает запрос приёма.
В общем, драйвер выполняет простую процедуру для установления внутренней очереди. Когда для драйвера выполняется запрос ввода/вывода, то он всегда является первым и единственным в очереди монитора/драйвера. Как только поступает запрос, драйвер устанавливает его во внутреннюю очередь, очищает DDCQE и DDLQE для "удаления" запроса из очереди монитора/драйвера. Следует запомнить, что элемент очереди занят, он ещё используется драйвером.
4.1.1. УСТАНОВКА ВО ВНУТРЕННЮЮ ОЧЕРЕДЬ
Когда драйвер впервые вызывается для выполнения запроса (с шестого слова), то он должен проверить элемент очереди на допустимость. Недопустимый запрос вызывает неустранимую ошибку.
Если запрошенная процедура не требует длительных вычислений и завершается быстро, то драйвер выполняет её, а затем вызывает макрокоманду .DRFIN для освобождения элемента очереди и сообщает вызывающей программе, что операция завершена. Если запрошена та процедура, которая требует вычислений и времени для завершения, то драйвер помещает запрос во внутреннюю очередь, используя слово связи элемента очереди. Слово связи равно 0, т.к. в этом случае элемент является первым и единственным в очереди.
Драйвер устанавливает запрос во внутреннюю очередь, если он требует каких-либо вычислений и времени, и должен обслуживаться асинхронно. Если запрос является первым во внутренней очереди, то драйвер начинает операцию, ожидает её завершения и затем выходит по инструкции RTS PC. Если запрос не является первым во внутренней очереди, то драйвер не начинает операцию, а просто выходит по инструкции RTS PC.
4.1.2. ОБСЛУЖИВАНИЕ ПРЕРЫВАНИЯ ДЛЯ ДРАЙВЕРОВ С ВНУТРЕННЕЙ ОЧЕРЕДЬЮ
После завершения операции драйвер переходит на точку обработки прерывания DDINT:. После этого, в зависимости от обстоятельств, выполняются различные действия. Если имеется больше одной внутренней очереди, то драйвер определяет, какой запрос вызывает это прерывание. Если операция не завершена, то драйвер повторно начинает её и возвращает управление монитору. Если передача завершена, то драйвер должен поместить запрос из внутренней очереди обратно в очередь ввода/вывода монитора/драйвера, устанавливая DDCQE и DDLQE. В этой ситуации драйверу необходимо возвратить запрос в главную очередь ввода/вывода, но ему также необходимо продолжать выполнение (а не возвращать немедленно управление монитору) для проверки внутренней очереди на наличие невыполненного запроса.
Чтобы вернуть запрос монитору, не передавая ему управление, драйвер должен вместо .DRFIN выполнить инструкции, приведённые в примере.
Регистр R4 указывает на третье слово элемента внутренней очереди.
MOV DDCQE,-(SP) ;в случае, если есть элемент ;очереди к монитору/драйверу. ;тогда возможно прерывание MOV R4,DDCQE ;загрузить элемент внутренней MOV R4,DDLQE ;очереди в очередь монитора/ ;драйвера CLR Q¤LINK(R4) MOV PC,R4 ;переход ADD #DDCQE-.,R4 ;на MOV @#L4,R5 ; JSR PC,@270(R5) ; .DRFIN MOV @SP,DDCQE ;восстановить следующий MOV (SP)+,DDLQE ;элемент очереди . . (проверка внутренней очереди и запуск другой операции, если необходимо) . . RTS PC ;возврат
4.1.3. ПРОЦЕДУРЫ АННУЛИРОВАНИЯ ДЛЯ ДРАЙВЕРОВ С ВНУТРЕННЕЙ ОЧЕРЕДЬЮ
Независимо от того, имеет ли драйвер запросы ввода/вывода во внутренней очереди, система подсчитывает число невыполненных запросов ввода/вывода для каждого канала. В каждом канале имеется один счётчик; сумма невыполненных запросов ввода/вывода находится в резидентном мониторе, когда задание аннулируется, счётчики сбрасываются. Это происходит автоматически, если драйвер строго полагается на очередь ввода/вывода монитора/драйвера.
Однако, если драйвер использует внутреннюю очередь ввода/вывода, то он должен выполнять процедуру уменьшения числа невыполненных запросов ввода/вывода. Эта процедура гарантирует, что драйвер начнёт выполняться при аннулировании задания (независимо, будет ли драйвер иметь активный элемент очереди), если в драйвере установлен бит 11 (HNDLR¤) в слове состояния устройства DDSTS при вызове макрокоманды .DRDEF.
Если вход в драйвер осуществляется в точке аннулирования запроса, то он должен проверить свою внутреннюю очередь, принадлежат ли элементы аннулированному заданию (следует помнить, что R4 всегда содержит номер аннулированного задания). Драйвер должен очищать свою внутреннюю очередь от этих элементов, а также выполнить процедуру сброса счётчиков невыполненных запросов ввода/вывода монитора. Для этого драйвер помещает значения в DDCQE и DDLQE, чем возвращает запрос обратно в очередь монитора/драйвера. Затем он выполняет изменённую макрокоманду .DRFIN, и повторяет эту процедуру для каждого элемента внутренней очереди, принадлежащей заданию. Монитор сам уменьшает число невыполненных запросов ввода/вывода.
4.2. SET-ПАРАМЕТРЫ
Команда клавишного монитора SET позволяет изменять определённые характеристики драйвера устройства. Драйвер должен находиться на системном устройстве с именем DD.SYS где DD - двухсимвольное имя устройства, например, эта команда изменяет для устройства печати длину распечатываемой строки:
SET LP WIDTH=80 (по умолчанию - 132 символа)
Другой тип команды SET может разрешить или запретить какую-либо функцию. Следующий пример показывает, как команда SET может заставить систему включать (или нет) в текст комбинации символов конца строки.
SET LP CR (передаёт знаки <ВК>; по умолчанию) SET LP NOCR (препятствует передаче знаков <ВК>)
Для отмены какой-либо функции необходимо добавить "NO" к параметру. Драйвер устройства, который программирует пользователь, может иметь возможность применения различных SET-параметров. Добавление SET-параметра влияет только на файл драйвера. Пользователю нет необходимости делать какие-нибудь изменения для монитора. Следует отметить, что SET-параметры допустимы как для системных устройств, так и для устройств данных.
4.2.1. ВЫПОЛНЕНИЕ КОМАНДЫ SET
Команда SET полностью управляется таблицей в блоке 0 файла драйвера и набором подпрограмм (также в блоке 0), которые изменяют инструкции и данные в блоках 0 и 1 драйвера. Следует помнить, что блок 0 обращается к адресам с 0 по 776-й и что заголовок драйвера начинается в блоке 1 с ячейки 1000.
При вводе команды SET с терминала монитор анализирует командную строку и ищет файл драйвера DD.SYS на системном устройстве. Этот драйвер не должен быть загружен в системе. Затем монитор считывает блоки 0 и 1 драйвера в область буфера USR в память. Он сканирует таблицу в блоке 0 до тех пор, пока не найдёт в таблице запись для указанного SET-параметра. Из записи в таблице он может определить требуемую подпрограмму, предназначенную для использования этого параметра и модификатора, допускаемых этой подпрограммой (например, "NO" или числовые значения). Затем монитор выполняет подпрограмму, изменяющую код в блоках 0 или 1 драйвера. Код в блоке 1 является частью тела драйвера и содержит инструкции для установки по умолчанию всех SET-параметров. После изменения кода монитор записывает блоки 0 и 1 обратно на системное устройство. Итак, в результате выполнения команды SET изменяются некоторые инструкции или данные в драйвере.
4.2.2. ФОРМАТ ТАБЛИЦЫ SET-ПАРАМЕТРОВ
Таблица SET-параметров состоит из серии четырёхсловных записей для каждого параметра, таблица начинается с ячейки 400 в блоке 0 драйвера и заканчивается нулевым словом. Для генерации таблицы используется макрокоманда .DRSET.
Первое слово таблицы - это значение, которое передаётся через R3 в подпрограмму, обслуживающую данный SET-параметр. Это слово может быть числовым значением (например, количество символов в строке для устройства печати) или инструкцией для замены другой инструкции в блоке 1 драйвера. Оно не должно быть равно 0.
Второе и третье слова таблицы являются именем параметра (например, WIDTH или CR) в коде RADIX-50. В таблице символы выровнены по левому краю и дополнены пробелами.
Младший байт четвёртого слова является указателем подпрограммы, которая выполняет модификацию файла. Старший байт указывает тип допустимого SET-параметра. Установка в байт значений 100 указывает, что требуется десятичный аргумент. Значение 140 показывает, что требуется восьмеричный аргумент. Установка в байт значения 200 означает, что для этого параметра допустим префикс "NO".
Структура таблицы SET-параметров представлена на рисунке 8.
Значение передаётся в R3 подпрограммы |
|
Имя параметра в RADIX-50 (два слова) |
|
Код допустимых типов команды SET |
Указатель для подпрограммы SET |
Рис. 8
4.2.3. Макрокоманда .DRSET
Для установки таблицы параметра используется макрокоманда .DRSET. Она вызывается для каждого параметра отдельно, так что вызовы макрокоманд по тексту драйвера следуют один за другим. Необходимо использовать макрокоманду .DRSET после макрокоманды .DRDEF, но перед макрокомандой .DRBEG.
Формат макрокоманды .DRSET следующий:
.DRSET OPTION,VAL,RTN[,MODE] |
||
где |
OPTION |
- имя SET-параметра (например, WIDTH или CR). Имя может быть длиной до шести буквенно-цифровых символов и не должно содержать встроенных пробелов или табуляций; |
VAL |
- параметр, который будет передан подпрограмме в регистр R3. Это может быть числовая константа, например, минимальная длина строки, или вся инструкция, заключённая в угловые скобки, для замены существующей в блоке 0 или 1 драйвера. Он не должен быть равен нулю; |
|
RTN |
- имя подпрограммы, которая изменяет код в блоке 0 или 1 драйвера. Подпрограмма должна располагаться за таблицей параметра в блоке 0 и не должна переходить за адрес 776; |
|
MODE |
- аргумент (необязательный), применяемый для указания типа SET-параметра, можно использовать "NO". Для десятичных значений используется аргумент NUM, для восьмеричных - OCT. Пропуск аргумента MODE означает, что параметр не принимает ни "NO", ни числового значения. Можно объединить "NO" и числовые аргументы. Конструкция <NO,NUM> указывает, что требуется либо "NO", либо десятичное значение, но не оба вместе. Конструкция <NO,OCT> указывает, что требуется либо "NO", либо восьмеричное значение. Пропуск аргумента MODE означает, что 0 записывается в старший байт последнего слова таблицы. |
Первая макрокоманда .DRSET выдаёт директиву .ASECT и устанавливает счётчик ячеек в 400 для начала таблицы. Макрокоманда такие записывает нуль в конце таблицы так как макрокоманда располагает счётчик ячеек в конце таблицы, то необходимо в драйвере поместить подпрограммы для изменения кода непосредственно после вызовов макрокоманды .DRSET. Это гарантирует, что они будут находиться в нулевом блоке драйвера.
4.2.4. ПОДПРОГРАММЫ ДЛЯ ИЗМЕНЕНИЯ ДРАЙВЕРА
Для каждого SET-параметра драйвер требует свою подпрограмму. Она является единой как для установки SET-параметра, так и для отказа от этой функции (использование "NO" с этим параметром). Назначение подпрограммы - изменять код в теле драйвера, в зависимости от команды монитора SET, набранной на системном терминале.
Подпрограммы должны следовать непосредственно за таблицей параметра и находиться в блоке 0 (после таблицы и ниже адреса 1000). Код в теле драйвера, который изменяет подпрограммы, должен быть в блоке 1 драйвера в пределах первых 256 (десятичных) слов.
Имя подпрограммы - это её точка входа (по умолчанию), она является точкой входа для параметров, принимающих числовое значение, не принимающих ни числового значения, ни "NO", и которые могут принимать префикс "NO", но не имеют его. Точкой входа для параметров, которые могут принимать и имеют "NO", является точка входа по умолчанию плюс 4.
На входе в подпрограмму, для всех параметров R3 содержит "VAL" таблицы параметра и очищенный бит переноса. Помимо этого, если числовые значения допустимы для этого параметра, то R0 содержит числовые значения из строки команды SET.
Подпрограмма может указать, что команда монитора является недопустимой, и при этом установить бит "C". Например, команда "SET WIDTH" не позволяет устанавливать длину строки устройства печати меньше 30 символов. Если подпрограмма SET-параметра выполнилась с ошибкой, то монитор печатает сообщение об ошибке и не записывает блоки 0 и 1. Итак, проверка может быть сделана после изменения кода блока 1.
Если пользователь добавил подпрограммы для каждого SET-параметра драйвера, то можно использовать следующую строку, чтобы убедиться, находится ли подпрограмма в требуемых границах:
.IIF GT,<.-1000>, .ERROR .-1000 ;код для SET-параметра ;слишком большой
Эта секция завершается директивой .ASECT, после которой пользователь устанавливает счётчик ячеек в 1000. Затем можно продолжать писать драйвер, начиная с макрокоманды .DRBEG которая устанавливает заголовок драйвера.
4.2.5. ПРИМЕРЫ SET-ПАРАМЕТРОВ
Следующие примеры, взятые из драйвера устройства печати, показывают применение SET-параметров.
.SET LP WIDTH = 80 .SET LP CR .SET LP NOCR
Драйвер вызывает макрокоманду .DRSET для установки таблицы параметров для двух параметров "WIDTH" и "CR".
Первая команда означает, что устанавливается параметр устройства печати "WIDTH", что 30 (десятичное) является значением по умолчанию, что "O.WIDTH" является подпрограммой, которая изменяет код для параметра "WIDTH", и что "WIDTH" принимает числовой аргумент:
.DRSET WIDTH,30.,O.WIDTH,NUM
Следующая команда означает, что устанавливается параметр "CR" устройства печати, что инструкция "NOP" должна быть передана подпрограмме, что "O.CR" является именем подпрограммы, которая изменяет код для этого параметра, и что параметр "CR" может быть указан с "NO":
.DRSET CR,NOP,O.CR,NO
Два вызова макрокоманды генерируют следующую таблицу:
.ASECT . = 400 .WORD 30. ;минимальная длина строки .RAD50 \WIDTH \ ;имя параметра .BYTE <O.WIDTH-400>/2 .BYTE 100 NOP ;инструкция для передачи .RAD50 \CR \ ;имя параметра .BYTE <O.CR-400>/2 .BYTE 200 .WORD 0 ;конец таблицы
Подпрограммы для обработки этих SET-параметров следуют непосредственно за таблицей. Ниже приведены возможные тексты подпрограмм O.WIDTH и O.CR.
O.WIDTH: MOV R0,COLCNT ;передвинуть значение MOV R0,RSTC+2 ;в две константы CMP R0,R3 ;сравнить новое значение ;с минимальной длиной 30. RTS PC ;вернуться, установить бит "C"
Следует отметить, что инструкции в подпрограмме O.WIDTH изменяют данные в двух ячейках в блоке 1 драйвера.
O.CR: MOV (PC)+,R3 ;ввести указатель для "CR", ;передвинуть адрес следующей ;строки в R3 BEQ RSTC-CROPT+. ;новая инструкция MOV R3,CROPT ;ввести указатель для "NOCR" ;(O.CR+4); передвинуть "NOP" ;или предыд. Строку на CROPT RTS PC ;возврат
Подпрограмма O.CR имеет две точки входа: для параметра CR подпрограмма вводится в точке O.CR; для параметра NOCR она вводится в O.CR+4. Следует отметить следующее:
- подпрограмма выполняет замену инструкции в блоке 1 одной из двух инструкций:
- инструкция NOP пересылается к CROPT, если выбран параметр NOCR;
- если выбран CR, то инструкция "BEQ RSTC-CROPT+." пересылается к CROPT.
Такая конструкция инструкции BEQ необходима, поскольку условный переход ассемблируется в другой ячейке, а не в той, в которой она выполняется. Во всех подпрограммах инструкция перехода должна использовать следующую конструкцию для генерации правильного адреса:
BR A-B+. |
||
где |
A |
- назначение инструкции перехода; |
B |
- адрес инструкции перехода; |
|
. |
- текущий счётчик ячеек. |
Обычно, только подпрограммы для параметров, которые принимают "NO", используют эти инструкции перехода.
И, наконец, следует обратить внимание:
- на текст секции обработки прерывания, которая изменяется только что рассмотренными подпрограммами;
- что код, подлежащий изменению, должен быть расположен в первом блоке драйвера в первых 256 (десятичных) словах.
. . . COLCNT: .WORD COLSIZ ;печатать оставшиеся строки . . . CHRTST: CMPB R5,#HT ;это <ТАБ>? BEQ TABSET ;да, сбросить <ТАБ> CMPB R5,#LF ;это <LF>? BEQ RSTC ;да, восстановить счетчик строк CMPB R5,#CR ;это <CR>? CROPT: NOP ;"NOP", еcли "NOCR", иначе (если ;<CR>) использовать ;"BEQ RSTC-CROPT+." из ;подпрограммы SET в блоке 0 CMPB R5,#FF ;это <FF>? BNE IGNORE ;нет, это не печатать RSTC: MOV #COLSIZ,COLCNT ;повторно инициализировать ;счетчик строк
4.3. ТАЙМ-АУТ ВВОДА/ВЫВОДА УСТРОЙСТВА
Драйвер может передать управление подпрограмме завершения, используя необязательное свойство тайм-аута устройства, если прерывание не возникло в указанный временной интервал. Драйвер может выполнять подпрограмму завершения по истечении указанного интервала времени без использования макрокоманды .SYNCH и сопровождающей её потенциальной задержки.
В системе имеется две макрокоманды, с помощью которых обеспечивается использование в драйвере тайм-аута устройства. Это макрокоманды - .TIMIO и .CTIMIO. Их можно использовать только в драйверах устройств. При ассемблировании файла драйвера с TIMIT¤=1 макрокоманда .DRDEF выдаёт директиву .MCALL для макрокоманд .TIMIO и .CTIMIO.
4.3.1. МАКРОКОМАНДА .TIMIO
Макрокоманда .TIMIO используется в секции инициации ввода/вывода драйвера для запуска подпрограммы завершения через заданный интервал времени. Макрокоманду .TIMIO можно использовать в любом месте драйвера за исключением уровня обработки прерывания. Однако, если необходимо применить eё в секции обработки прерывания, то предварительно нужно использовать макрокоманду .FORK.
Макрокоманда .TIMIO планирует выполнение подпрограммы завершения после истечения указанного интервала времени. Подпрограмма завершения выполняется в контексте задания, указанного в блоке таймера. Завершения регистры R0 и R1 предоставляются для использования. При передаче управления подпрограмме завершения R0 содержит последовательный номер запроса в тайм-ауте.
Поскольку пользователь может перейти к уровню ветвления (F-обработке) для выдачи макрокоманды .TIMIO или .CTIMIO, то драйвер должен блокировать прерывания устройства перед выдачей макрокоманды .FORK или должен быть правильно запрограммирован во избежание проблем реентерабельности. Следует помнить, что пользователь не может повторно использовать блок таймера, пока не истекло назначенное время и не введена подпрограмма завершения, или не будет аннулирован элемент таймера при успешном завершении макрокоманды.
Формат макрокоманды следующий:
.TIMIO TBK,HI,LO |
||
где |
TBK |
- адрес блока таймера, семисловного элемента очереди. Необходимо заметить, что не следует использовать символ "#" перед TBK; |
HI |
- константа, указывающая старшее слово двухсловного интервала времени; |
|
LO |
- константа, указывающая младшее слово двухсловного интервала времени. |
Формат блока таймера показан в табл. 8.
Смещение |
Имя |
Агент |
Содержание |
---|---|---|---|
0 |
C.HOT |
.TIMIO |
Старшее слово времени |
2 |
C.LOT |
.TIMIO |
Младшее слово времени |
4 |
C.LINK |
Монитор |
Связь со следующим элементом очереди; 0 указывает, что очереди нет |
6 |
C.JNUM |
Пользователь |
Номер задания пользователя; получить его из элемента очереди |
10 |
C.SEQ |
Пользователь |
Последовательный номер запрос таймера. Допустимый диапазон для последовательных номеров от 177400 до 177477 |
12 |
C.SYS |
Монитор |
-1 |
14 |
C.COMP |
Пользователь |
Адрес подпрограммы завершения для выполнения при возникновении тайм-аута. Монитор обнуляет это слово при вызове подпрограммы завершения, указывая, что блок таймера предоставляется для повторного использования |
Хотя макрокоманда .TIMIO пересылает старшее и младшее слова времени в блок таймера для пользователя, он должен правильно указать их в вызове макрокоманды. Интервал времени выражается в тиках. Если система функционирует с 50-цикловой частотой, то он соответствует 50 (десятичное) тикам в секунду. Существует и 60 тик/с при 60-цикловой частоте. Значения времени для 60-цикловой частоты показаны в квадратных скобках "[...]" непосредственно после значения частоты 50 Гц.
Младшее слово времени принимает значения включительно до 65535 тиков, что почти равно 1310 [1092] сек. или 21,8 [18,2] мин. Если требуется в макрокоманде .TIMIO указать интервал времени 21,8 [18,2] мин. или меньше, необходимо поместить 0 в аргумент HI и число тиков в аргумент LO.
Если требуется определить интервал времени больше 21,8 [18,2] мин, то необходимо помнить о старшем слове как о слове переноса. Каждый интервал длительностью 21,8 [18,2] мин вызывает перенос единицы в старшее слово. Итак, чтобы указать интервал немного больше, чем 21,8 [18,2] мин необходимо, чтобы аргумент HI был равен 2, а аргумент LO - 0.
Для задания 43,6 [36,4] мин задать 2 в аргументе HI и 0 в аргументе LO и т.д. поскольку двухсловное время позволяет указывать до 65535 единиц по 21,8 [18,2] минут каждая, то самый большой интервал, который может указать пользователь, равен приблизительно 2,7 [2,3] годам.
Единственные слова информации, которые пользователь должен установить сам в блоке таймера - это номер задания, последовательный номер и адрес подпрограммы завершения. Номер задания можно получить из текущего элемента очереди и переслать его в блок таймера. Пользователь должен присвоить последовательный номер в пределах от 177400 до 177477. Номер задания и последовательный номер передаются подпрограмме завершения при её вызове адрес подпрограммы завершения необходимо переслать в седьмое слово блока таймера позиционно-независимым способом.
Макрокоманда .TIMIO расширяется следующим способом:
.TIMIO TBK,HI,LO JSR R5,@¤TIMIT ;указатель конца драйвера .WORD TBK-. .WORD 0 ;код для .TIMIO .WORD HI ;старшая часть интервала времени .WORD LO ;младшая часть интервала времени
4.3.2. МАКРОКОМАНДА .CTIMIO
При возникновении условия, которое предусмотрено драйвером, необходимо выдать запрос на отмену тайм-аута, блокирующий подпрограмму завершения. Для отмены запроса таймаута в драйвере используется макрокоманда .CTIMIO. Выполнение её должно происходить в режиме системы. Следует помнить, что перед использованием макрокоманды .CTIMIO на уровне обработки прерывания необходимо использовать макрокоманду .FORK.
Например, драйвер LP предоставляет возможность проверить, находится ли устройство печати в автономном режиме. Когда программа запрашивает операцию ввода/вывода, то секция инициации ввода/вывода немедленно разрешает прерывание. Затем секция обработки прерывания проверяет бит ошибки устройства. При установленном бите устройство печати неработоспособно, и драйвер печатает сообщение, организуя двухминутный тайм-аут с помощью макрокоманды .TIMIO, и передаёт управление монитору по инструкции RTS PC для ожидания другого прерывания. Если прерывание не возникает в пределах двух минут, то подпрограмма завершения таймера печатает второе сообщение об ошибке, устанавливает другой двухминутный тайм-аут. И передаёт управление монитору по инструкции RTS PC для ожидания следующего прерывания.
Если очищен бит ошибки, драйвер выдаёт макрокоманду .CTIMIO для отмены временного ожидания.
Если интервал времени уже истёк (устройство находится не в тайм-ауте), то макрокоманда .CTIMIO не выполнится. Будет установлен бит C.
Формат вызова макрокоманды .CTIMIO следующий:
.CTIMIO TBK |
||
где |
TBK |
- адрес семисловного блока таймера. Это тот же временной блок использованный в макрокоманде .TIMIO. |
Макрокоманда .CTIMIO расширяется следующим образом:
.CTIMIO JSR R5,@¤TIMIT ;указатель конца драйвера .WORD TBK-. .WORD 1 ;код для .CTIMIO
Следует отметить, если задание аннулируется, и драйвер вводится в точке аннулирования запроса, то необходимо немедленно отменить невыполненные запросы таймера. Если подпрограмма завершения драйвера уже введена, то необходимо подождать, пока она выполнится.
4.3.3. ПРИМЕНЕНИЕ ТАЙМ-АУТА УСТРОЙСТВ
Обеспечение тайм-аута устройства поддерживается системой ОС БК-11 только в некоторых случаях. Существует ряд условий, для которых допускается использование макрокоманд, работающих с таймером. При написании пользователем драйвера устройства следует определить, необходимо ли использование таких макрокоманд.
4.3.3.1. ТИПИЧНАЯ ПРОЦЕДУРА ТАЙМЕРА ДЛЯ ДРАЙВЕРА ДИСКА
Драйвер диска может применить тайм-аут для любой операции с диском. Назначение подпрограммы таймера - отменить операцию, которая протекает слишком долго или повторно запустить её. Если операция не завершается в пределах указанного отрезка времени, это означает, что произошла ошибка чтения диска.
Секция инициации ввода/вывода устанавливает таймер, используя макрокоманду .TIMIO. Затем драйвер начинает операцию, которую запросило задание: чтение, запись или поиск. Драйвер передаёт управление монитору по инструкции RTS PC и ожидает прерывания от устройства.
Если возникает прерывание до истечения указанного интервала времени, то драйвер отменяет .TIMIO и выполняет обычную проверку результатов передачи, обычно, драйвер либо переходит на уровень ветвления для повторного начала неправильной операции, либо передаёт управление монитору с помощью макрокоманды .DRFIN для удаления текущего элемента очереди.
Если прерывание не возникает в пределах заданного интервала времени, то начинает выполняться подпрограмма завершения таймера. Её первым действием должно быть воспроизведение прерывания. Это дублирует обстановку драйвера после истинного прерывания и гарантирует, что стек имеет необходимую информацию. Затем подпрограмма завершения таймера действует так, как если бы устройство было прервано, но при передаче была ошибка. Подпрограмма завершения таймера для окончания обработки просто переходит в секцию обработки прерывания драйвера устройства.
Подпрограмма завершения таймера должна использовать следующие инструкции для моделирования прерываний и входа в режим системы:
MOV @SP,-(SP) ;организовать стек CLR 2(SP) ;имитировать прерывание PS=0 .MTPS #340 ;установить приоритет 7 .INTEN 0,PIC ;ввести режим системы
После входа драйвера в режим системы он предпринимает соответствующее действие как результат тайм-аута. Драйвер может снова попытаться выполнить операцию. Чтобы сделать это, он уменьшает счёт повторных попыток, переходит к уровню ветвлений и передаёт управление секции инициации ввода/вывода. В секции инициации устанавливает другой таймер, начинается повторная передача и управление передаётся монитору по инструкции RTS PC для ожидания следующего прерывания.
Если драйвер определяет, что произошла неустранимая ошибка, то он выполняет такую же процедуру, как если бы число повторений передачи выло исчерпано. В этом случае драйвер устанавливает бит неустранимой ошибки в слове состояния канала и с помощью макрокоманды .DRFIN передаёт управление монитору с удалением текущего элемента очереди.
Примечание. До того, как драйвер выполнит макрокоманду .DRFIN для удаления текущего элемента очереди, он должен отменить все макрокоманды таймера, которые ещё не выполнились.
4.3.3.2. ПРИМЕР ДРАЙВЕРА УСТРОЙСТВА ПЕЧАТИ
Ниже приводится пример, который состоит из фрагментов драйвера устройства печати ОС БК-11, изменённый для использования обеспечения таймера, чтобы проверить работу устройства в автономном режиме.
Секция инициации ввода/вывода драйвера начинает передачу (разрешает прерывания), секция обработки прерывания драйвера проверяет бит ошибки в CSR. При наличии ошибки управление переходит к подпрограмме OFFLIN, которая вызывает макрокоманду .SYNCH для входа в режим пользователя, печатает сообщение об ошибке на системном терминале и организует двухминутный тайм-аут. Затем драйвер возвращает управление монитору по инструкции RTS PC и ожидает прерывание устройства.
Если наступает прерывание от устройства, то это значит, что неисправность устройства ликвидирована. Драйвер отменяет тайм-аут и ещё раз проверяет бит ошибки. Если нет ошибки, то драйвер продолжает обычное выполнение. При наличии ошибки драйвер передаёт управление подпрограмме OFFLIN. Если прерывание не возникает в пределах двух минут, то начинает выполняться подпрограмма завершения таймера. Она печатает сообщение об ошибке, устанавливает другой двухминутный тайм-аут и возвращает управление монитору по инструкции RTS PC для ожидания прерывания.
Пример драйвера устройства печати
; секция инициации ввода/вывода .DRBEG LP MOV LPCQE,R4 ;R4 указывает на текущий элемент ;очереди ASL 6(R4) ;преобразовать словный счетчик в ;байтный BCC LPERR ;запрос на чтение недопустим BEQ LPDONE ;немедленно завершить поиск RET: BIS #100,@LPS ;установить прерывание. Начать ; передачу RTS PC ; секция обработки прерывания .ENABL LSB .DRAST LP,4,LPDONE TST TICMPL ;элемент таймера активный ? BEQ 1¤ ;нет .CTIMIO TIMBLK ;да, удалить его BCS 1¤ ;ошибка CLR TICMPL ;очистить элемент таймера 1¤: MOV LPCQE,R4 ;R4 указывает на текущий элемент ;очереди TST @(PC)+ ;ошибка ? LPS: .WORD LP¤CSR ;регистр состояния LP ERROPT: BMI OFFLIN ;да, идти на корректировку . . . ; секция завершения ввода/вывода LPDONE: CLR @LPS ;сбросить бит прерывания .DRFIN LP . . . ; устройство печати в автономном режиме: ; печатать предупреждение каждые 2 мин OFFLIN: MOV LPCQE,R5 ;указать элемент очереди MOVB Q¤JNUM(R5),R5 ;получить номер текущего ;задания ASR R5 ;сдвинуть его ASR R5 ; вправо на ASR R5 ;три бита BIC #^C<16>,R5 ;выделить номер задания MOV R5,SYJNUM ;сохранить его для .SYNCH MOV R5,TIJNUM ;сохранить его для .TIMIO .SYNCH SYNBLK,PIC ;установить режим пользователя RTS PC ;сбой синхронизации 1¤: CLR TICMPL TST @LPS ;еще есть ошибки ? BPL 2¤ ;нет, выйти MOV PC,R0 ;печать сообщения подобно ;подпрограмме завершения ADD #MESSAG-.,R0 ;пересылка сообщения .PRINT ;печатать его MOV PC,R0 ; способом PIC ADD #1¤-.,R0 ;указать для .TIMIO ;подпрограмму завершения MOV R0,TICMPL ;сохранить указатель .TIMIO TLMBLK,0,2*60.*50. ;установить двухминутный ;тайм-аут 2¤: RTS PC ;вернуться TIMBLK: .WORD 0 ;блок таймера, старшее слово времени .WORD 0 ; младшее слово времени .WORD 0 ;связь со следующим элементом очереди TIJNUM: .WORD 0 ;номер задания .WORD 177400 ;последовательный номер .WORD 0 ;монитор помещает сюда -1 TICMPL: .WORD 0 ;адрес подпрограммы завершения SYMBLK: .WORD 0 ;блок синхронизации SYJNUM: .WORD 0 ;номер задания .WORD 0,0,0,-1,0 ;и т.д. MESSAG: .ASCIZ "?LP-W-LP устройство в автономном режиме" .EVEN .DREND LP
4.4. СПЕЦИАЛЬНЫЕ ФУНКЦИИ
Иногда драйверам устройств необходимо выполнить специфичные действия, которые невозможно выполнить из-за отсутствия соответствующих системных макрокоманд ОС БК-11. Например, перемотка кассетных лент, чтение/запись абсолютных секторов на гибких дисках и т.д. системная макрокоманда .SPFUN является средством для выполнения таких специфичных действий. Когда программа выдаёт макрокоманду .SPFUN, то для её выполнения в качестве одного из аргументов необходимо задать код конкретной функции. Этот код указывает драйверу, какую специальную функцию необходимо выполнить. Например, для обратной перемотки магнитной ленты в автономном режиме нужно указать драйверу MT код 372.
4.4.1. СИСТЕМНАЯ МАКРОКОМАНДА .SPFUN
Формат системной макрокоманды .SPFUN следующий:
.SPFUN AREA,CHAN,FUNC,BUF,WCNT,BLK[,CRTN]
Полное описание аргументов системной макрокоманды .SPFUN системы ОС БК-11 приводится в документе "Системные таблицы и библиотеки" 00008-01.33.01-1.
Если вызов специальной функции предназначен для возврата одного значения, то BUF должен быть областью однословного буфера. Пользователь может свободно интерпретировать WCNT и BLK. Они могут быть любыми словами спецификации, указателями дополнительных буферов и т.д. до тех пор, пока драйвер будет интерпретировать их согласно коду специальной функции. Следует помнить, что монитор не изменяет эти значения при передаче их драйверу. Например, он не изменяет счёта слов из положительного в отрицательное.
4.4.2. ОБЕСПЕЧЕНИЕ СПЕЦИАЛЬНЫХ ФУНКЦИЙ В ДРАЙВЕРЕ
Для разрешения задания специальных функций в драйвере для аргумента STAT макрокоманды .DRDEF нужно задать бит SPFUN¤. Это будет означать, что драйвер может принимать специальные функции.
Затем следует определить символику в драйвере для определения типов специальных функций, которые может выполнить драйвер. Например, драйвер гибкого диска BY принимает следующие коды специальных функций:
SIZ¤FN = 373 ;получить размер устройства WOD¤FN = 375 ;писать с удалением отмеченных ;данных WRT¤FN = 376 ;писать абсолютный сектор RED¤FN = 377 ;читать абсолютный сектор
Следует заметить, что все коды специальных функций должны быть отрицательными значениями байтов (т.е. в диапазоне с 200 по 377 восьмеричных).
При инициации драйвера для ввода/вывода он должен проверить четвёртое слово элемента очереди и узнать, есть ли запрос специальной функции. Символьное обозначение Q.FUNC, которое является младшим байтом 4-го слова элемента очереди ввода/вывода, содержит код специальной функции. В системных макрокомандах ввода/вывода для операций чтения, записи и поиска этот байт = 0. Для макрокоманд специальных функций это значение является отрицательным кодом специальных функций, следует проверить, является ли код для этого устройства допустимым и, если нет, то предусмотреть немедленную посылку сообщения о грубой ошибке.
Для макрокоманды специальной функции драйвер должен начать эту функцию и возвратиться по инструкции RTS PC. В секции обработки прерывания драйвер должен проверить наличие ошибки и определить, завершена ли операция. Драйвер возвращает вызывающей программе данные или слова состояния в буфер пользователя.
Поскольку пользователь применяет специальные функции для определённого устройства, то он может установить условия вызова для этой функции в системной макрокоманде .SPFUN и условия возврата из драйвера. Точно так же драйвер рассматривает аргументы для каждой другой макрокоманды специальной функции.
4.4.3. ТОМА РАЗНЫХ РАЗМЕРОВ
Драйвер может управлять устройством, которое допускает использование томов с различными размерами.
Драйвер устройства, которое поддерживает тома разных размеров, должен передавать размер наименьшего тома (в блоках) в параметре SIZE макрокоманды .DRDEF. Это то значение, которое возвращается выполняемой программе при выдаче ею системной макрокоманды .DSTATUS.
Если необходимо, чтобы выполняемая программа знала размер установленного тома, то в ней нужно сделать вызов макрокоманды .SPFUN. Драйвер должен быть в состоянии ответить на запрос возвратом фактического размера тома в область однословного буфера. Стандартный код специальной функции для определения фактического размера тома равен 373.
Программа DUP требует изменения для правильной инициализации и операции "сборка мусора" устройства, которое допускает использование томов различного размера.
4.4.4. ЗАМЕНА ПЛОХОГО БЛОКА
Если для драйвера нужна поддержка замены плохого блока, то пользователь должен использовать коды специальной функции 377, 376, 374. Примером может служить драйвер DL.
Программа DUP требует изменения для правильной инициализации и операции "сборка мусора" устройства, которое допускает замену плохого блока.
4.4.5. УСТРОЙСТВА СО СПЕЦИАЛЬНЫМИ КАТАЛОГАМИ
Монитор ОС БК-11 может связываться с устройствами файловой структуры, имеющими нестандартные каталоги (т.е. не ОС БК-11). Примером специального устройства является кассета. Её драйвер устанавливают бит 12 (SPECL¤) слова состояния устройства. USR выполняет операции с каталогом для устройств со структурой каталога ОС БК-11; для специальных устройств сам драйвер должен выполнить операции с каталогом, например, .LOOKUP, .ENTER, .CLOSE, и .DELETE, а также передачу данных.
Монитор запрашивает специальную операцию с каталогом, помещая положительное нулевое значение в байт кода функции в элементе очереди. Положительные коды функции являются стандартными для всех устройств. Они следующие:
Код: |
1 |
2 |
3 |
4 |
Функция: |
CLOSE |
DELETE |
LOOKUP |
ENTER |
Эти функции соответствуют системным макрокомандам .CLOSE, .DELETE, .LOOKUP, и .ENTER. Макрокоманда .RENAME для специальных устройств игнорируется пятое слово элемента очереди специальной функции, работающей с каталогом, содержит указатель блока описателя файла, содержащее имя устройства, имя файла и тип файла в коде RADIX-50.
При ошибках программного обеспечения (например, файл не найден или каталог заполнен), обнаруженных драйвером специального устройства во время операций с каталогом, управление передаётся в монитор. Для каждого типа ошибки выбирается уникальный код. Код ошибки заносится в SPUSR, расположенного на фиксированном смещении 272 от начала резидентного монитора. Аппаратные ошибки возвращаются обычным способом, установкой бита 0 в слове состояния канала, указанного вторым словом элемента очереди.
Программные запросы для операций с каталогами специальных устройств обрабатываются системными макрокомандами, например, при выдаче макрокоманды .LOOKUP монитор проверяет слово состояния устройства на бит специального устройства, если устройство имеет специальную структуру каталога, то соответствующий код функции вводится в элемент очереди, который прямо устанавливается в очередь к драйверу, проходя и обрабатываясь USR. Поддерживается независимость устройства, поскольку операции, выполняемые макрокомандами .LOOKUP, .ENTER, .CLOSE и .DELETE, являются "прозрачными" для пользователя.
5. ДРАЙВЕРЫ СИСТЕМНОГО УСТРОЙСТВА И ЗАГРУЗЧИКИ
В этом разделе продолжается описание драйверов, даётся информация, как создать драйвер системного устройства или изменить существующий для использования его в качестве системного. Здесь приводятся сведения о первичном драйвере системного устройства и различных подпрограммах начальной загрузки (загрузчиках). В конце раздела даётся информация о процедурах подпрограммы DUP для начальной загрузки нового системного устройства.
5.1. ФАЙЛ МОНИТОРА
Файл монитора должен находиться на системном устройстве; имя файла: B11SJ.SYS.
Блоки с 0 по 4 каждого файла монитора содержат вторичный загрузчик. Вторичный загрузчик загружает драйвер системного устройства и монитор в память. Он также изменяет таблицы монитора для соединения монитора с драйвером устройства и присваивает имена (по умолчанию) DK и SY.
Сам файл монитора не содержит код специального устройства, и не имеет связей с драйвером специального устройства до начальной загрузки. Вместо этого, каждый драйвер устройства, который может быть использован как драйвер системного устройства, имеет специальный блок с программой для системного устройства, названный первичным драйвером, который используется вторичным загрузчиком для чтения файла драйвера системного устройства и файла монитора из системного устройства. Вторичный загрузчик имеет место в своём блоке 0 для хранения первичного драйвера.
5.2. СОЗДАНИЕ ДРАЙВЕРА СИСТЕМНОГО УСТРОЙСТВА
Для создания драйвера системного устройства необходимо добавить первичный драйвер к стандартному драйверу устройства данных.
Драйвер системного устройства может содержать SET-параметры. Если SET-параметры являются частью драйвера, то нет необходимости удалять их при создании драйвера системного устройства.
5.2.1. ПЕРВИЧНЫЙ ДРАЙВЕР
Первичный драйвер, который добавляется к стандартному драйверу устройства данных, состоит из четырёх частей:
- подпрограмма входа;
- программный загрузчик;
- подпрограмма чтения загрузчика;
- подпрограмма обработки ошибки загрузчика.
Первичный драйвер выполняется вместе с начальным загрузчиком системы (BSTRAP) для загрузки нового системного устройства. Первичный драйвер полностью находится в P-секции DDBOOT, где DD - это двухсимвольное имя устройства. Код выполняется в физической памяти c ячейки 0.
5.2.2. ПОДПРОГРАММА ВХОДА
Точкой входа для первичного драйвера является DDBOOT:. Подпрограмма входа может содержать только две инструкции. Этими инструкциями являются "NOP" и безусловный переход к началу программного загрузчика. Если начало программного загрузчика находится слишком далеко для безусловного перехода, то можно перейти по инструкции JMP, которая начинает загрузку программного обеспечения. Ниже приводится подпрограмма входа для драйвера RK (BOOT1 определяется в первичном драйвере):
RKBOOT:: NOP BR BOOT1
Любой аппаратный загрузчик вызывает загрузку в память кода P-секции DDBOOT с ячейки 0. Он также начинает выполнение с DDBOOT::.
5.2.3. ПРОГРАММНЫЙ ЗАГРУЗЧИК
Программный загрузчик (подпрограмма начальной загрузки программного обеспечения) выполняется в результате перехода из подпрограммы входа. Когда начинает выполняться программный загрузчик, для использования предоставляются все регистры. Программный загрузчик должен выполнять следующие функции в указанном порядке:
- Установить стек с ячейки 10000.
- Сохранить номер устройства, с которого была загружена система (это - значение в диапазоне от 0 до 7). Метод, используемый для нахождения номера, изменяется в зависимости от устройства; некоторые номера передаются в регистр R0, другие должны извлекаться из CSR. Следует хранить номер устройства в стеке и, если необходимо, где-нибудь ещё в памяти.
- Вызвать подпрограмму чтения загрузчика для считывания оставшейся части загрузчика.
- поместить указатель в B¤READ подпрограммы чтения загрузчика.
- поместить значение в коде RADIX-50 для "B¤DNAM" в B¤DEVN.
- сохранить номер устройства в B¤DEVU.
- выполнить переход к B¤BOOT в загрузчике ОС БК-11 для продолжения.
Программный загрузчик должен находиться в основном приводе непосредственно ниже ячейки DDBOOT+64 (ячейки с 667 по 776 содержат подпрограмму обработки ошибки, созданную макрокомандой .DREND).
5.2.4. ПОДПРОГРАММА ЧТЕНИЯ ЗАГРУЗЧИКА
Назначение подпрограммы чтения загрузчика заключается в считывании тома с устройства, с которого была загружена система. Она вызывается как загрузчиком системы, так и программным загрузчиком.
Интерфейс, через который другие подпрограммы передают информацию подпрограмме чтения загрузчика, следующий:
- R0 содержит номер блока для считывания;
- R1 содержит число слов для считывания;
- R2 содержит адрес буфера памяти, в котором хранятся данные.
В подпрограмме чтения загрузчика предоставляются для использования все регистры и стек.
Подпрограмма чтения загрузчика не должна прерываться во время считывания тома согласно параметрам, передаваемым в регистры R0 - R2. В случае ошибки подпрограмма должна переходить к BIOERR. При отсутствии ошибок она должна возвращаться по инструкции RTS PC с очищенным битом переноса.
Подпрограмма чтения загрузчика должна находиться в первичном драйвере у ячейки DDBOOT+210 (ячейка 210 - это наименьший адрес, с которого может располагаться подпрограмма чтения).
5.2.5. ПОДПРОГРАММА ОБРАБОТКИ ОШИБКИ ЗАГРУЗЧИКА
Подпрограмма обработки ошибки загрузчика начинается с ячейки BIOERR::. Код в этой подпрограмме полностью обеспечивается макрокомандой .DREND, которая помещается в конце основного привода.
5.2.6. МАКРОКОМАНДА .DRBOT
Макрокоманда .DRBOT помогает при установке первичного драйвера. Она также вызывает макрокоманду .DREND для обозначения конца драйвера. Так что первичный драйвер не будет загружаться в память во время обычных операций. Код в первичном драйвере может быть позиционно-зависимым. Однако, любая позиционно-зависимая ссылка должна выражаться относительно DDBOOT::. Следует отметить, что ячейки с 60 по 206 пользователю не предоставляются.
Формат макрокоманды .DRBOT следующий:
.DRBOT NAME,ENTRY,READ |
||
где |
NAME |
- двухсимвольное имя устройства; |
ENTRY |
- точка входа подпрограммы начальной загрузки программного обеспечения; |
|
READ |
- точка входа подпрограммы чтения загрузчика. |
Макрокоманда .DRBOT помещает указатель начала первичного драйвера в ячейку 62 файла драйвера, длину первичного драйвера (в байтах) - в ячейку 64. Первичный драйвер, включая подпрограмму обработки ошибки, снабжённую макрокомандой .DREND, не должен превышать 1000 (восьмеричных) байтов. Ячейка 66 содержит смещение от начала первичного драйвера к началу подпрограммы чтения загрузчика.
Макрокоманда .DRBOT вызывается до макрокоманды .DREND. Код основного привода помещается между макрокомандами .DRBOT и .DREND. (следует помнить, что размер первичного драйвера должен быть меньше или равен одному блоку, т.е. 1000 (восьмеричным) байтам, включая подпрограмму обработки ошибки и ячейки с 60 по 206). Следует заметить, что макрокоманда .DREND вызывается дважды в драйвере системного устройства: один раз макрокомандой .DRBOT и один раз, когда используется в самом конце первичного драйвера. Первое появление .DREND закрывает несистемную секцию драйвера устройства и, кроме того, устанавливает таблицу указателей в мониторе. Второй вызов .DREND создаёт подпрограмму обработки ошибки загрузчика BIOERR вместо повторения таблицы указателей.
При использовании команды BOOT для начальной загрузки нового устройства программа DUP передаёт номер системного устройства в первичный драйвер, в ячейку 4722, и в регистр R0. При начальной загрузке устройства аппаратным загрузчиком или любой системной программой (не системы ОС БК-11) первичный драйвер должен определить номер устройства, которое было загружено, и сохранить его в ячейке 4722 и регистре R0.
5.3. ПРОГРАММА DUP И ПРОЦЕСС НАЧАЛЬНОЙ ЗАГРУЗКИ
В этом подразделе показано, как программа DUP выполняет три команды, относящиеся к начальной загрузке, эти команды следующие:
.BOOT DDN:FILNAM .COPY/BOOT XXN:FILNAM DDM: .BOOT DDN:
5.3.1. КОМАНДА "BOOT DDN:FILNAM"
Команда "BOOT DDN:FILNAM" используется для начальной загрузки программного обеспечения указанного файла монитора с указанного устройства. В командной строке DD представляет двухсимвольное имя устройства; N - номер устройства; FILNAM - имя файла монитора. Оба файла, файл монитора и файл драйвера устройства, должны быть на устройстве DD.
Сразу же после выдачи этой команды программа DUP проверяет, является ли устройство DD устройством с прямым доступом. Затем находит файл монитора FILNAM.SYS на устройстве. DUP считывает пять первых блоков (с 0 по 4) в буфер памяти. Эти блоки содержат вторичный загрузчик монитора.
Предпоследнее слово в блоке 4 содержит суффикс для имени драйверов, связанных с этим монитором. Программа DUP использует это для построения имени файла драйвера устройства (имена DD.SYS или DDX.SYS). DUP считывает блок 0 файла драйвера устройства в буфер памяти, используя содержимое ячеек 62 и 64 для нахождения первичного драйвера, и считывает его в буфер памяти.
Затем программа DUP копирует первичный драйвер в буфер в начало вторичного загрузчика, который также находится в буфере памяти. Она загружает информацию, показанную в табл. 9 для первичного драйвера и вторичного загрузчика.
Смещение от начала |
Содержание |
---|---|
4722 |
Номер загружаемого устройства |
4724-4726 |
Имя загружаемого файла в RADIX-50 |
5000 |
Дата загрузки |
5002-5004 |
Время загрузки |
Затем, программа DUP копирует основной привод и вторичный загрузчик из буфера памяти в ячейки памяти с 0 по 5004. Затем DUP переходит к ячейке 1000, чтобы начать вторичную загрузку с точки входа DUP. После этого вторичный загрузчик может загрузить в память монитор и драйвер системного устройства.
На рис. 11 представлена процедура выполнения этой команды.
Процедура команды "BOOT DDN:FILNAM"
Рис. 11
5.3.2. КОМАНДА "COPY/BOOT XXN:FILNAM DDM:"
Команда "COPY/BOOT XXN:FILNAM DDM:" используется для копирования вторичного загрузчика из файла монитора на устройстве XX в блоки 2, 3, 4 и 5 устройства DD. В командной строке XX указывает устройство, на котором хранится файл монитора; N - номер устройства; DD представляет двухсимвольное имя устройства, предназначенное для получения загрузчика; M - номер устройства.
После выдачи этой команды программа DUP проверяет, являются ли XX и DD устройствами с прямым доступом. Затем DUP находит файл монитора FILNAM.SYS на устройстве XXN: и считывает первые пять блоков файла монитора (с 0 по 4) в буфер памяти. Эти блоки содержат вторичный загрузчик для монитора.
Программа DUP находит файл соответствующего драйвера на устройстве DD, считывает блок 0 файла драйвера устройства в буфер памяти, используя содержимое ячеек 62 и 64 для нахождения первичного драйвера, и считывает его в буфер памяти.
Прежде чем копировать загрузчик на устройство драйвер системного устройства DD должен уже быть найден на DD. DUP загружает два слова в коде RADIX-50 для FILNAM в ячейки 4724 и 4726 буфера памяти. Затем копирует первичный драйвер в блок 0 устройства DD. И, наконец, DUP записывает вторичный загрузчик в блоки со второго по пятый устройства DD.
На рис. 12 показана процедура выполнения этой команды.
Процедура команды "COPY/BOOT XXN:FILNAM DDM:"
Рис. 12
5.3.3. КОМАНДА "BOOT DDN:"
Команда "BOOT DDN:" выполняет загрузку программного обеспечения с указанного устройства, на котором монитор уже имеет вторичный загрузчик в блоках 2, 3, 4 и 5 (помещённый туда командой COPY/BOOT). В командной строке DD представляет двухсимвольное имя устройства, подлежащее загрузке; N - номер устройства. Оба файла (файл монитора и файл драйвера устройства) должны находиться на устройстве DD.
После выдачи этой команды программа DUP сначала проверяет, является ли устройство DD устройством с прямым доступом. Затем она считывает блоки 2, 3, 4 и 5 в буфер памяти. Эти блоки содержат вторичный загрузчик монитора. Основной привод уже находится в ячейках с 0 по 776.
Программа DUP находит файл драйвера на устройстве DD. Эта процедура проверяет, имеет ли том драйвер системного устройства и загружен ли он.
Затем DUP извлекает имя файла монитора из ячеек 724 и 726 блока 4 и ищет файл монитора на устройстве.
Далее программа DUP загружает информацию, приведённую в табл. 10 для первичного драйвера и вторичного загрузчика.
Смещение от начала |
Содержание |
---|---|
4722 |
Номер загружаемого устройства |
5000 |
Дата загрузки |
5002-5004 |
Время загрузки |
Затем, программа DUP копирует первичный драйвер и вторичный загрузчик из устройства в ячейки памяти с 0 по 4777 и переходит к ячейке 1000, чтобы начать вторичную загрузку с точки входа DUP. После этого вторичный загрузчик может загрузить монитор и драйвер системного устройства в память.
Рис. 13 иллюстрирует процедуру выполнения этой команды.
Процедура команды "BOOT DDN:"
Рис. 13
6. АССЕМБЛИРОВАНИЕ, КОМПОНОВКА И УСТАНОВКА ДРАЙВЕРА
Ассемблирование, компоновка и установка нового драйвера устройства являются простыми процедурами. Их описание подробно изложено ниже.
6.1. АССЕМБЛИРОВАНИЕ ДРАЙВЕРА
Исходный файл драйвера на макроассемблере должен иметь имя DD.MAC, где DD - это двухсимвольное имя устройства. Для удобства чтения листинга и распечатки расширения макрокоманд, таких как .DRBEG и .DRAST, используется ключ макроассемблера /SHOW:MEB.
При ассемблировании драйвера используется следующая команда:
.MACRO/CROSSREFERENCE/SHOW:MEB/LIST SYCND+DD/OBJECT
SYCND - файл параметров системы, созданный в процессе генерации рабочей версии ОС БК-11, он должен использоваться при ассемблировании этого драйвера, чтобы избежать конфликта с системой.
6.2. КОМПОНОВКА ДРАЙВЕРА
Если исходный файл ассемблируется без ошибок, то он готов к компоновке. При компоновке драйвера DD используется следующая команда:
.LINK/MAP/EXECUTE:DD.SYS DD
6.3. УСТАНОВКА ДРАЙВЕРА
Прежде чем использовать новый драйвер необходимо добавить информацию о нём в таблицы устройств монитора. Процесс добавления нового устройства называется установкой. В системе ОС БК-11 это можно осуществить при загрузке системы или с помощью команды монитора INSTALL. При этом необходимо чтобы перед установкой драйвера устройства аппаратура его присутствовала и была включена. Ниже описан способ, как обойти это ограничение, если необходимо установить драйвер для неподключенного устройства.
Ниже описываются различные способы установки драйверов устройств в системе ОС БК-11.
6.3.1. АВТОМАТИЧЕСКАЯ УСТАНОВКА ЗАГРУЗЧИКОМ
Подпрограмма начальной загрузки (загрузчик) определяет местонахождение драйвера системного устройства на устройстве, с которого загружена система, и устанавливает его. Затем она сканирует остальные файлы драйверов на системном устройстве и пытается установить соответствующий драйвер для каждого устройства, которое она находит в системе. Если устройство не подключено, то загрузчик не устанавливает его драйвер.
Единственная трудность в этой процедуре возникает в случае, если файлов драйверов больше, чем слотов устройств. Дистрибутивный монитор резервирует один слот для каждого устройства, которое поддерживается ОС БК-11. Монитор, создаваемый в результате генерации системы, резервирует один слот для каждого устройства, запрашиваемого пользователем. Помимо этого, он обеспечивает ряд пустых слотов, указанных пользователем. Считается, что слот резервируется для определённого устройства. Если таблица монитора ¤PNAME имеет вход для этого устройства. Слот является пустым, если таблица имеет нулевое слово в ¤PNAME.
Подпрограмма автоматической установки устройства при загрузке имеет ряд приоритетов для определения, какие драйверы устанавливать, если драйверов больше, чем слотов. Если все слоты пустые, то загрузчик устанавливает драйвер системного устройства плюс первые драйверы подключённых устройств, которые он встречает на системном устройстве. Например, если система имеет 8 пустых слотов, то загрузчик устанавливает драйвер системного устройства и первые семь драйверов, которые она находит на системном устройстве.
Если один или более слотов резервируются для определённых устройств (т.е. устройства имеют входы в таблице ¤PNAME), то загрузчик резервирует эти слоты для соответствующих драйверов до тех пор, пока он не проверит, отключена ли надлежащая аппаратура. Если аппаратура подключена, то загрузчик устанавливает драйвер устройства. Если аппаратура не подключена, то загрузчик очищает вход ¤PNAME, создавая, таким образом, пустой слот.
На рис. 14 приведён алгоритм, который использует загрузчик для установки драйверов устройств.
Алгоритм загрузчика для установки драйвера устройства
Рис. 14
Как видно, драйверы с входами в таблице ¤PNAME имеют наивысший приоритет во время загрузки. Если файл драйвера находится на системном устройстве и аппаратура устройства подключена, то загрузчик всегда устанавливает этот драйвер.
Если драйвер устройства написан пользователем, то при установке его в системе ОС БК-11 проблем не возникнет, т.к. загрузчик сам установит его, если этот драйвер находится на системном устройстве и в таблицах монитора имеется пустой слот. Если система не имеет свободного слота, то можно создать один или более слотов, сохранив (например, переименовав) несколько файлов драйверов устройства на системном устройстве, и повторно загрузить систему. Можно также использовать команду монитора INSTALL для установки нового драйвера, не выполняя новой загрузки системы (этот новый драйвер может быть тем драйвером, который загрузчик не смог установить из-за недостатка свободных слотов, или это может быть новый драйвер, который создан пользователем и скопирован на системное устройство). Если сгенерирована новая система, можно использовать макрокоманду .DEV, чтобы зарезервировать слот для нового драйвера устройства и указать ему приоритет для установки во время начальной загрузки. На рис. 15 кратко изложены способы, которыми можно установить новый драйвер устройства.
Установка нового драйвера устройства
Рис. 15
6.3.2. РУЧНАЯ УСТАНОВКА КОМАНДОЙ INSTALL
Перед использованием команды INSTALL для установки драйвера вручную необходимо использовать команду SHOW, чтобы увидеть, имеются ли пустые слоты для устройств в системе. Если их нет, то нужно использовать команду REMOVE для удаления ненужного устройства и предоставить место для нового, которое добавляется командой INSTALL.
Если слот для устройства уже имеется, то устройство автоматически установится при начальной загрузке системы. Следует помнить, что команды REMOVE или INSTALL необходимо использовать для добавления нового устройства каждый раз, если осуществлена начальная загрузка системы. Эта задача значительно упростится, если ввести указанные команды монитора в стартовый командный файл. При этом создастся видимость постоянной установки устройства.
6.3.3. АВТОМАТИЧЕСКАЯ УСТАНОВКА МАКРОКОМАНДОЙ .DEV
Имеется ещё одна возможность автоматической установки драйвера. Её можно осуществить во время генерации системы. Для этого нужно отредактировать файл SYSTBL.MAC, указав в нём макрокоманду .DEV для установки необходимого драйвера.
Макрокоманда .DEV в файле SYSTBL.MAC используется для постоянного введения нового устройства в систему.
Формат макрокоманды .DEV следующий:
.DEV NAME,S |
||
где |
NAME |
- двухсимвольное имя устройства; |
S |
- слово состояния устройства (необязательный аргумент). |
Следующие примеры взяты из файла SYSTBL:
.DEV BY ;установить диск BY .DEV LP ;установить устройство LP .DEV CT ;установить ленту CT
После введения в файл SYSTBL.MAC макрокоманды .DEV необходимо повторно ассемблировать его. Для этого использовать следующую команду:
.MACRO/OBJECT:TBXX XX+SYCND+SYSTBL
В этой командной строке XX представляет имя SJ, FB или ХМ. SJ.MAC, FB.MAC и ХМ.MAC - это дистрибутивные файлы РАФОС, определяющие разрешается ли фоновая (оперативная) обработка. Файл XM.MAC, кроме того, указывает, имеется ли обеспечение расширенной памяти. Если ассемблирование уже завершено, необходимо просто перекомпоновать объектные файлы для создания нового монитора. Эти команды находятся в командном файле, полученном в результате генерации системы. К ОС БК-11 этот абзац не относится.
6.3.4. УСТАНОВКА ДРАЙВЕРА ПОДКЛЮЧЁННОГО УСТРОЙСТВА
При обычной установке драйвера могут быть установлены драйверы только тех устройств, аппаратура которых в текущей конфигурации системы подключена. Программы проверяют ячейку 176 в блоке 0 драйвера и адрес, содержащийся в этой ячейке, который обычно является CSR для устройства. Если аппаратура устройства не подключена в системе, то на шине возникает тайм-аут, вызывающий прерывание по ячейке 4. В результате ни подпрограмма начальной загрузки, ни команда INSTALL не установят драйвер устройства. Помимо этого, при попытке установки по команде INSTALL будет напечатано сообщение "?KMON-F-ILLEGAL DEVICE INSTALLATION".
Считается, что аппаратура устройства подключена, если CSR находится на шине. Однако, в некоторых случаях, этого теста недостаточно, чтобы определить, какое аппаратное устройство подключено. Например, некоторым устройствам на странице ввода/вывода для одного или более регистров состояния присваиваются одинаковые адреса. Если система проверила разделяемый адрес на странице ввода/вывода, то она ещё не знает, какое из двух устройств действительно подключено и какой драйвер устанавливать. Например, устройства гибких дисков DX и DY имеют один и тот же адрес на шине, и одно и то же число регистров состояния на странице ввода-вывода. При попытке установить драйвер DX система должна определить, подключена ли аппаратура и является ли она устройством DX. Естественно, что система не должна устанавливать драйвер DX, если аппаратурой является устройство гибкого диска DY.
Всегда имеются некоторые различия между двумя или более устройствами, которые можно определить по регистрам на странице ввода/вывода. Каждый драйвер одного из устройств, близких по идентификации, может проверять это различие и сообщать подпрограмме установки ОС БК-11, устанавливать или нет драйвер устройства, который рассматривает система.
6.3.5. ПОДПРОГРАММА ПРОВЕРКИ УСТАНОВКИ УСТРОЙСТВА
Все драйверы устройств системы ОС БК-11, которые разделяют адреса страницы ввода/вывода, содержат подпрограмму проверки установки для определения, какое аппаратное устройство фактически подключено, и разрешения (или запрещения) установки рассматриваемого драйвера. Если драйвер устройства написан пользователем, он может иметь собственную подпрограмму проверки установки.
В общем, подпрограммы проверки установки различают, какая аппаратура подключена, в зависимости от трёх следующих условий:
- из двух устройств, которые разделяют некоторые регистры, одно имеет больше регистров, чем другое;
- если два устройства разделяют адреса для всех регистров, и они имеют одно и то же число регистров, то одно устройство может иметь бит чтения/записи, тогда как другое - только бит чтения;
- иногда устройство имеет уникальный бит или байт идентификации.
Подпрограммы проверки установки определяют, какое устройство подключено, руководствуясь результатами проверки одного из этих различий. Если различие найдено, то подпрограмма проверки сигнализирует подпрограмме установки ОС БК-11, устанавливать ли рассматриваемый драйвер и передавать управление монитору. При этом бит "C" устанавливается для предотвращения установки драйвера и очищается - для разрешения.
Следует отметить, что подпрограмма проверки установки может использовать все общие регистры.
6.3.5.1. ТОЧКИ ВХОДА ПОДПРОГРАММЫ ПРОВЕРКИ
Подпрограмма проверки установки, которую пишет пользователь в собственном драйвере, начинается с ячейки 200 в блоке 0 драйвера. Она не должна выходить за ячейку 356.
Ячейка 200 является точкой входа, которую загрузчик и команда монитора INSTALL используют для установки устройства данных.
Ячейка 202 является точкой входа, которую загрузчик использует для установки системного устройства. Команда монитора INSTALL никогда не использует её.
Если пользователя не интересует, устанавливается ли драйвер как системное устройство или как устройство данных, необходимо поместить инструкцию NOP в ячейку 200. Если драйвер должен быть установлен как системный, то используются следующие инструкции для предотвращения установки его любыми другими способами:
.=200 ;не системная точка входа BR ERROR ;переход на ошибку . . . ERROR: SEC ;установить бит "C" RTS PC ;и возвратиться
6.3.5.2. НАЛИЧИЕ ДОПОЛНИТЕЛЬНОГО РЕГИСТРА
Если этот драйвер предназначается для устройства, которое разделяет адрес страницы ввода/вывода с другим устройством, то можно определить, какое устройство подключено, если они имеют разное число регистров, когда устройство для рассматриваемого драйвера имеет на один регистр больше, чем другое устройство, то используются следующие инструкции для проверки дополнительного регистра.
MOV 176,R0 ;получить адрес CSR TST N(R0) ;есть дополнительный регистр ;на смещении N ? RTS PC ;вернуться (бит переноса ;устанавливается, если нет ;устройства)
Эта подпрограмма проверяет наличие дополнительного регистра. Если его нет, то на шине происходит тайм-аут, что вызывает прерывание по вектору 4, и устанавливается бит переноса. Подпрограмма проверки установки передаёт управление монитору с установленным битом переноса, указывая, что аппаратура для рассматриваемого драйвера не подключена, и этот драйвер не может быть установлен.
С другой стороны, если тест обнаружил дополнительный регистр, то инструкция TST возвращается с очищенным битом переноса. Это означает, что имеется аппаратура для этого драйвера, и система ОС БК-11 установит этот драйвер.
6.3.5.3. ОТСУТСТВИЕ ДОПОЛНИТЕЛЬНОГО РЕГИСТРА
Если рассматриваемое устройство имеет меньше регистров, чем устройство, с которым оно разделяет адреса на странице ввода/вывода, то драйвер этого устройства может проверить отсутствие дополнительного регистра. Если дополнительный регистр не найден, то система ОС БК-11 должна установить рассматриваемый драйвер.
Ниже приведён пример, иллюстрирующий эту ситуацию:
MOV 176,R0 ;получить адрес CSR TST N(R0) ;есть дополнительный регистр ;на смещении N ? BCC 1¤ ;да, здесь другое устройство CLC ;нет, очистить бит "C" RTS PC ;установить драйвер 1¤: SEC ;установить бит "C" RTS PC ;не устанавливать драйвер
Эта подпрограмма проверяет наличие дополнительного регистра другого устройства. Если он отсутствует, то подпрограмма даёт системе ОС БК-11 команду установить рассматриваемый драйвер.
6.3.5.4. БИТ ИЛИ БАЙТ ИДЕНТИФИКАЦИИ
Если устройства, которые разделяют адреса страницы ввода/вывода, отличаются битом или байтом идентификации, то подпрограмма проверки установки может проверить бит или байт и определить, какая аппаратура подключена. Затем, в зависимости от этой информации, она может разрешить (или запретить) установку рассматриваемого драйвера.
6.3.5.5. БИТ ЧТЕНИЯ/ЗАПИСИ УСТРОЙСТВА
Если одно из устройств, которые разделяют адреса страницы ввода/вывода, имеет бит чтения/записи в CSR, тогда другое устройство имеет только бит чтения. В этом случае подпрограмма проверки может установить, какая аппаратура подключена, выполняя обычную процедуру проверки бита, и разрешить (или запретить) установку рассматриваемого драйвера. Подпрограмма должна считать бит, изменить его и записать обратно в CSR. Затем подпрограмма должна снова считать бит, если значение бита изменилось, то устройство с регистром чтения/записи подключено. Если значение бита осталось прежним, то имеется устройство с регистром только чтения.
Подпрограмма может установить бит переноса надлежащим образом и передать управление монитору. Если бит переноса установлен, то ОС БК-11 не устанавливает этот драйвер. Если бит переноса очищен, то драйвер устанавливается.
6.3.6. УСТАНОВКА ДРАЙВЕРА НЕПОДКЛЮЧЕННОГО УСТРОЙСТВА
Если по какой-либо причине необходимо установить драйвер устройства, аппаратура которого не подключена в рассматриваемой конфигурации системы, то подпрограмму начальной загрузки и команду INSTALL можно обойти системной программой SIPP. Ячейки 176 и 200 в блоке 0 файла драйвера следует очистить. Затем использовать команду INSTALL или повторно загрузить систему для установки драйвера устройства.
7. ПРОВЕРКА И ОТЛАДКА ДРАЙВЕРА УСТРОЙСТВА
Если новый драйвер ассемблирован, скомпонован и установлен, то можно начать его проверку. Во время отладки следует, помнить, что необходимо каждый раз удалять прежний файл и устанавливать новый при создании новой версии драйвера DD(X).SYS.
Проверка драйвера осуществляется в три этапа:
- Использовать системную программу ODT для проверки передачи данных драйвером.
- Проверить драйвер командами клавишного монитора, системными программами и программами на языке Паскаль или Бейсик. Проверить команду COPY или программу PIP, копируя данные с устройства на устройство. Использовать драйвер с операторами INPUT или PRINT языка Бейсик. Если драйвер устанавливает бит в слове состояния устройства, который указывает, что драйвер для устройства файловой структуры ОС БК-11, то программа DUP будет функционировать правильно на устройстве без дальнейших модификаций, т.е. можно использовать DUP для инициализации устройства (командой INITIALIZE) и для объединения свободной области (командой SQUEEZE). Программа RESORC не требует модификаций для распознавания нового устройства и включает его в протокол команды SHOW DEVICES.
- Поработать с прикладной программой, которая использует программы ввода/вывода в режиме ожидания, асинхронного ввода/вывода и подпрограммы завершения.
Если драйвер прошёл успешно через все тесты, то можно начать его использование в системе ОС БК-11.
7.1. ИСПОЛЬЗОВАНИЕ ODT ДЛЯ ПРОВЕРКИ ДРАЙВЕРА
Чтобы использовать программу ODT для проверки драйвера, необходимо выполнить ODT как задание.
Необходимо загрузить систему аппаратным загрузчиком, но не запускать никаких системных задач и не загружать драйверы.
Далее, скомпоновать программу ODT для задания по следующей команде:
.LINK/MAP/FOREGROUND ODT
Затем загрузить драйвер устройства, подлежащий отладке:
.LOAD DD(X)
По карте загрузки для ODT определить длину ODT, вычитая тысячу из верхнего предела, если, к примеру, верхней границей был адрес 7100. Тогда длина ODT будет равна 6100 (восьмеричным) словам.
Запустить ODT. Для определения адреса загрузки программы ODT использовать ключ /P:
.FRUN ODT/P Загружено с 123532
Затем выдать команду RESUME для запуска ODT:
.RESUME ODT v01.00
Примечание. Поскольку последним загруженным драйвером является драйвер, подлежащий отладке, то он располагается в памяти над программой ODT.
Поместить адрес загрузки ODT в регистр перемещения 0:
123532;0R
Открыть ячейку, следующую за ODT в памяти, используя размер смещения ODT от регистра перемещения 0:
0,6100/ 704
В этой ячейке находится размер драйвера устройства. Длина драйвера фактически равна 702 (восьмеричным) словам. Значение 704 включает слово размера, которое не является частью драйвера. Итак, ячейка сразу после слова размера является началом драйвера устройства. Повторно установить регистр перемещения 0 к началу драйвера:
0,6102;0R
Рис. 16 иллюстрирует организацию компонентов в памяти в этот момент.
ODT и драйвер устройства в памяти
Рис. 16
Если имеется листинг ассемблирования, то можно проследить работу драйвера по шагам. Первые пять слов являются заголовком; первая выполняемая инструкция является шестым словом. Установить первую точку останова у шестого слова.
0,12;0B
Установить дополнительные точки останова в других местах драйвера, которые необходимо отладить. Ещё одним критическим местом является точка входа в прерывание, её можно найти, просмотрев листинг драйвера. Следует помнить, что точка входа в прерывание называется DDINT:: её легко найти и установить там точку останова.
После окончания установки точек останова в драйвере из программы ODT выходят по команде:
0;G
Теперь рекомендуется поработать с драйвером. Для этого можно попробовать использовать DUP для инициализации устройства или программу PIP для копирования данных на устройство или выполнить тестовую программу, специально разработанную для этой цели. Когда выполнение достигает первой точки останова в драйвере, то ODT принимает управление. Можно, как обычно, использовать ODT для проверки ячеек и их содержимого или для изменения инструкций. Следует помнить, что приоритет ODT по умолчанию равен 7; это препятствует другим прерываниям "вмешиваться" во время отладки.
Если драйвер работает без ошибок, то точки останова можно удалить и продолжить выполнение остальной части драйвера:
;B ;P
Требуется осторожность, чтобы не выгрузить задание (ODT), если в драйвере ещё имеются установленные точки останова.
8. ОСОБЕННОСТИ УПРАВЛЕНИЯ НЕКОТОРЫМИ УСТРОЙСТВАМИ
В этом разделе описываются драйверы устройств, имеющие специальные, зависимые от устройства, характеристики, к этой категории относятся следующие устройства:
- системный терминал (TT);
- нуль-устройство (NL).
8.1. ДРАЙВЕР СИСТЕМНОГО ТЕРМИНАЛА (TT)
Системный терминал используется как обычное устройство при обращении к драйверу TT. Необходимо отметить следующее:
- Символ (^) печатается, когда драйвер готов для ввода;
- <СУ/Z> может быть использован для указания конца ввода с TT. После <СУ/Z> не требуется возврат каретки. Если <СУ/Z> не печатается, драйвер TT принимает символы до тех пор, пока не будет исчерпан счётчик слов, заданный в запросе ввода;
- <СУ/О> при вводе с TT вызывает игнорирование всего буфера вывода;
- При вводе информации с TT нажатие одного <СУ/C> приводит к завершению операции ввода и передаче управления монитору;
- Пользователь может выводить на TT. Вывод символов из кольцевого буфера ввода производится перед обращением к KMON. Завершающий <СУ/Z> может быть также выведен на TT;
- Если задание использует TT для ввода, и подпрограмма завершения выполняет макрокоманду .TTYIN, то вводимые символы будут передаваться с ошибкой и в .TTYIN, и на TT;
- Если задание передаёт данные для вывода на TT, а затем выполняет макрокоманды .TTYOUT или .PRINT, то вывод на TT задерживается до тех пор пока драйвер не завершит свою передачу. Если операция вывода на TT начата, когда кольцевой буфер монитора вывода с терминала содержит данные (т.е. до завершения печати), то драйвер завершает операцию передачи до распечатки содержимого буфера.
8.2. НУЛЬ-ДРАЙВЕР (NL)
Нуль-драйвер выполняет все макрокоманды считывания/записи. При операциях вывода он игнорирует данные, при вызове NL:, он немедленно возвращает управление монитору, указывая, что вывод завершён. NL-драйвер не возвращает ошибок и не вызывает прерываний. При операциях ввода NL: передаёт сообщение о EOF для всех запросов, и данные не передаются, поэтому содержимое входного буфера не изменяется.