ПРОГРАММИРОВАНИЕ ПЕРИФЕРИЙНЫХ УСТРОЙСТВ
РУКОВОДСТВО СИСТЕМНОГО ПРОГРАММИСТА

1. ОБЩИЕ СВЕДЕНИЯ О ПРОГРАММЕ

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

2. СТРУКТУРА ПРОГРАММЫ

Драйвер устройства системы ФОДОС-2 состоит из шести следующих секций:

Каждая секция - это отдельный логический блок, содержащий код для определённой цели. Так как макробиблиотека системы ФОДОС-2 предусматривает специальные запросы для генерации требуемого кода для каждой части, то написание их несложно, необходимо лишь внимательнее изучить примеры драйверов устройств.

2.1. Секция определений

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

2.1.1. Запрос .DRDEF.

 Запрос .DRDEF используется вначале драйвера устройства и выполняет следующие функции:

Здесь и далее DD - двухсимвольное имя устройства.

Формат запроса .DRDEF следующий:

.DRDEF NAME, CODE, STAT, SIZE, CSR, VEC

где

NAME

- двухсимвольное имя устройства (например, MT для магнитной ленты);

 

CODE

- восьмеричное число, определяющее устройство (см. табл. 1);

 

STAT

- комбинация разрядов состояния устройства (см. табл. 2);

 

SIZE

- размер устройства в блоках (по 256 слов); если устройство нефайловой структуры, то SIZE = 0;

 

CSR

- адрес регистра состояния устройства по умолчанию;

 

VEC

- адрес вектора прерывания устройства по умолчанию.

Запрос .DRDEF выдаёт директиву .MCALL для следующих запросов:

.DRAST

.DRBEG

.DRFIN

.DRBOT

.DREND

.DRSET

.DRVTB

.FORK

.QELDF

Кроме того, если в драйвере при генерации системы выбрана поддержка таймера (ТIМ¤IТ=1), то .DRDEF выдаёт директиву .MCALL для запросов .TIMIO и .CTIMIO.

2.1.1.1. Условия генерации системы

В системе ФОДОС-2 широко используются условные директивы при транслировании. Секции программы на исходном языке участвуют в транслировании или нет, в зависимости от значения условных символов. Например, ФОДОС-2 использует условный символ ERL¤G для показа - должна ли транслироваться подпрограмма регистрации ошибок или нет. Если в драйвере устройства используются условные символы, то они должны согласовываться со стандартными, использующимися в ФОДОС-2. При равенстве нулю условного символа данная особенность не включается при транслировании программы, в случае, когда условный символ равен 1, эта особенность присутствует; ФОДОС-2 использует только значения 0 и 1; если условные символы имеют значения иные, чем 0, то .DRDEF приравнивает их 1.

Запрос .DRDEF приравнивает нулю, при генерации системы, ТIМ¤IТ (для тайм-аута устройства), MMG¤T (для поддержки расширенной памяти) и ERL¤G (для регистрации ошибок), если не определить их в начале файла при транслировании.

2.1.1.2. Смещение элементов очереди

Запрос .DRDEF вызывает запрос .QELDF для символического определения смещений элементов очереди. Ниже приведены сгенерированные смещения элементов очереди:

Q.LINK=0

(связь со следующим элементом очереди)

Q.CSW=2.

(указатель для слова состояния канала)

Q.BLKN=4.

(номер физического блока)

Q.FUNK=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¤FTUNC=2
Q¤JNUM=3
Q¤UNIT=3
Q¤BUFF=4
Q¤WCNT=6
Q¤COMP=10
2.1.1.3. Определение символов

Для определения символов используются операторы прямого присваивания. Обычно таким образом определяются регистры устройств и другие необходимые внутренние символы. Ниже приведены примеры из драйверов устройств системы ФОДОС-2.

Например, для определения внутреннего символа для перевода строки (код 12 в КОИ-7):

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. Восьмеричные значения кода приведены в табл. 1.

Для создания кода идентификации устройств, которые не поддерживаются системой ФОДОС-2, можно пользоваться значением кода 374 для первого непредусмотренного устройства, 373 - для второго и т.д. Главное, чтобы эти коды не противоречили кодам, которые будут использоваться в будущем.

Таблица 1

Имя

Код

Устройство

0

Кассетный магнитный диск

 

1

зарезервирован

EL

2

Логическое устройство регистрации ошибок

LP

3

Построчно-печатающее устройство

ТТ, ВА

4

Системный терминал типа 15ИЭ-00-013 или драйвер управления пакетной обработкой

 

5

зарезервирован

DY

6

Гибкий диск с двойной плотностью записи (диаметр 203 мм)

PC

7

Перфоленточное устройство ввода (FS 1501) и вывода (ПЛ-150)

 

10

зарезервирован

MT

11

Магнитная лента типа СМ 5300.01

 

12-20

зарезервированы

DP

21

Пакет магнитных дисков (29 Мбайт)

DX

22

Гибкий диск с одинарной плотностью записи (диаметр 203 мм)

 

23-24

зарезервированы

NL

25

Фиктивное устройство

 

26-33

зарезервированы

DD

34

Магнитная лента кассетного типа

 

35-40

зарезервированы

LS

41

Построчно-печатающее устройство последовательного типа

MQ

42

Драйвер обмена между заданиями

 

43-45

зарезервированы

LD

46

Драйвер логического диска

VM

47

Драйвер расширенной памяти

DU

50

Диски винчестерского типа и гибкие мини-диски

DW

53

Винчестерский диск

SL

51

Редактор командной строки

MX

376

Гибкий диск с одинарной плотностью записи, двухсторонний (диаметр 133 мм)

MY

375

Гибкий диск с двойной плотностью записи, двухсторонний (диаметр 133 мм)

2.1.3. Слово состояния устройства

Слово состояния устройства определяет каждое физическое устройство в системе ФОДОС-2 и содержит информацию о том, какое это устройство: произвольного или последовательного доступа к данным. Слово состояния устройства записывается в нулевой блок файла драйвера устройства и в таблицу ¤STAT, когда устройство установлено; программный запрос .DSTATUS возвращает значение слова состояния устройства в выполняющуюся программу. Запрос .DRDEF устанавливает слово состояния устройства на основании аргументов CODE и STAT.

В табл. 2 показаны значения разрядов в слове состояния устройства. Запрос .DRDEF использует символ DDSTS для определения слова состояния устройства.

Таблица 2

Разряд

Символ

Значение

0-7

-

Байт идентификации устройства

8

VARSZ¤

0 = запрос .SPFUN 373 недопустим для этого драйвера

1 = драйвер допускает использование запроса .SPFUN 373 (возвращает размер тома)

9

ABTIO¤

0  = вход в драйвер осуществляется не в точке преждевременного прерывания по нормальному выходу из программы

1  = вход в драйвер осуществляется в точке преждевременного прерывания всякий раз по окончании программы

10

SPFUN¤

0 = запрос .SPFUN недопустим

1 = драйвер допускает использование .SPFUN

11

HNDLR¤

0 = вводит драйвер в точку входа преждевременного прерывания, если в прерванном задании есть активный элемент очереди

1  = вводит драйвер в точку входа преждевременного прерывания во всех случаях преждевременных прерываний. Этот разряд игнорируется в системе SJ

12

SPECL¤

1 = устройство специальной справочной структуры (например, MT)

13

WONLY¤

1 = устройство только для записи

14

RONLY¤

1 = устройство только для чтения

15

FILST¤

0  = устройство последовательного доступа к данным (например, MT)

1 = устройство произвольного доступа к данным (например, RK, DX, MX)

Разряд 11 в слове состояния устройства устанавливается для драйверов устройств, которые перемещают элемент очереди при вводе и организуют внутреннюю очередь, и для устройств, таких, как магнитная лента, которые имеют внутренние данные, которые могут измениться при преждевременном прерывании. Предполагается, что все драйверы устройств, у которых установлен разряд 15, являются устройствами файловой структуры в системе ФОДОС-2 для большинства программ, обслуживающих систему. Самым простым способом определения слова состояния устройства является использование мнемоники для комбинации двоичных разрядов, которые определяют запрос .DRDEF. Таким образом, можно создать аргумент STAT посредством объединения (с помощью операции "ИЛИ") соответствующих символов из вышеприведённого перечня:

FILST¤ == 100000   ; файловая структура произвольного
                   ; доступа к данным
RONLY¤ == 40000    ; только чтение
WONLY¤ == 20000    ; только запись
SPECL¤ == 10000    ; несправочная структура
HNDLR¤ == 4000     ; ввод драйвера при преждевременном
                   ; прерывании
SPFUN¤ == 2000     ; использование специальных функций
ABTIO¤ == 1000     ; всегда выполняет преждевременное
                   ; прекращение входа
VARSZ¤ == 400      ; поддержка драйвером томов
                   ; переменного размера

Пример:

Для RK:

FILST¤

Для MT:

SPECL¤!SPFUN¤

Для LP:

WONLY¤

В этом примере приведён аргумент STAT для драйверов устройств RK, MT, LP.

2.1.4. Слово размера устройства

Аргумент SIZE в запросе .DRDEF определяет размер устройства в блоках. Запрос .DRDEF помещает значение размера устройства в DDDSIZ. Если устройство не является устройством произвольного доступа к данным, необходимо поместить значение 0 в SIZE. Например, размер устройства DX: равен 486 блокам (746 восьмеричных); размер устройства PC: равен 0, т.к. оно не является устройством произвольного доступа к данным.

Программный запрос .DSTATUS возвращает значение слова размера устройства в выполняющуюся программу.

2.2. Секция заголовка

В заголовке драйвера вызывается запрос .DRBEG для установки первых пяти слов драйвера. Кроме того, этот запрос записывает 5 слов информации в блок 0 файла драйвера, в ячейки с 52 по 60, и создаёт несколько глобальных символов. Данные, которые устанавливаются в секции заголовка, используются при загрузке драйвера в память посредством программного запроса .FETCH или команды монитора LOAD. Содержимое ячейки 176 используется начальным загрузчиком для проверки наличия аппаратуры устройства во время установки драйвера.

2.2.1. Информация в блоке 0

В табл. 3 приведены 5 слов в блоке 0, которые запрос .DRBEG устанавливает посредством директивы .ASECT, и три слова, которые .DRBOT устанавливает для загружаемых устройств. В таблице соответствующая мнемоника показана в квадратных скобках, двухсимвольное имя устройства представлено посредством DD.

Код сравнения установки, являющийся параметром, описан в п. 6.2.3.

Таблица 3

Ячейка

Содержимое (и мнемоника)

52

Размер драйвера в байтах [DDEND-DDSTRT]

54

Размер устройства в блоках [DDDSIZ]

56

Слово состояния устройства [DDSTS]

60

Слово состояния для отражения текущих дополнительных средств генерации системы

[ERL¤G+<MMG¤Т*2>+<ТIМ¤IТ*4>]

62

Указатель начала первичного драйвера (из .DRBOT)

64

Размер первичного драйвера в байтах (из .DRBOT)

66

Смещение от начала первичного драйвера к началу подпрограммы считывания начального загрузчика (из .DRBOT)

176

Адрес регистра команд и состояния CSR [DD¤CSR]

200

Начало кода сравнения установки

2.2.2. Первые пять слов драйвера

В табл. 4 приведены 5 слов, которые запрос .DRBEG генерирует в начале секции определений драйвера.

Таблица 4

Слово

Символ

Устройство

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 - двухсимвольное имя устройства.

2.2.4. Многовекторные драйверы: запрос .DRVTB

 Драйверы устройств системы ФОДОС-2 могут обслуживать устройства, имеющие более одного вектора. Например, драйвер PC обрабатывает прерывание посредством вектора 70 для считывателя с перфоленты и посредством вектора 74 для перфоратора. Если данное устройство имеет один вектор прерывания, то его драйвер должен иметь таблицу трёхсловных элементов для каждого вектора. Элемент для каждого вектора состоит из ячейки вектора, точки входа по прерыванию, значения слова состояния процессора (или PS). Для установки заголовка драйвера необходимо вызвать запрос .DRVTB два или большее число раз. Запрос .DRVTB устанавливает таблицу трёхсловных элементов для каждого вектора многовекторного устройства. Ее необходимо поместить в драйвере между запросами .DRBEG и .DREND (.DRBOT) до подпрограммы обработки прерываний. Запрос .DRVTB необходимо вызывать один раз для каждого вектора, программные запросы должны появляться в драйвере один за другим. Формат запроса следующий:

.DRVTB NAME,VEC,INT[,PS]

где

NAME

- двухсимвольное имя устройства; его необходимо указать в первом вызове .DRVTB; во всех последующих вызовах его можно опустить;

 

VEC

- ячейка вектора; она должна находиться между 0 и 474; первым вектором обычно является DD¤VEC, значение которого должно быть кратно четырем;

 

INT

- символическое имя подпрограммы обработки прерываний; оно должно быть определено в драйвере и обычно принимает форму DDINT;

 

PS

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

Пример:

; Таблица векторов перфоленточного устройства ввода-вывода
.IF PR114¤               ; если перфоленточное
                         ; устройство ввода-вывода
.DRVTB PC,PC¤VEC,PCINT   ; таблица ввода с перфо-
                         ; ленты
.DRVTB ,PP¤VEC,PPINT     ; таблица вывода на пер-
                         ; фоленту
.ENDC

В этом примере показаны строки и коды, которые генерирует запрос .DRVTB.

Пример:

.WORD <PC¤VEC>&<^C3>,PCINT-.,340!0   ; таблица
                                 ; ввода
                                 ; с перфо-
                                 ; ленты
.WORD <PP¤VEC>&<^C3>,PPINT-.,340!0   ; таблица
                                 ; вывода на 
                                 ; перфоленту
.WORD 0                          ; для окон-
                                 ; чания таб-
                                 ; лицы

В этом примере приведена таблица вектора, сгенерированная запросом .DRVTB. Из примера видно, что разряды приоритета PS всегда установлены семёркой, даже если аргумент PS опущен.

2.2.5. Коды условий PS

В запросе .DRVTB существенны только разряды кодов условий аргумента PS. Они могут быть полезны, если имеется общая точка входа в подпрограмму обработки прерывания для двух или большего числа векторов и необходимо определить, через какой вектор возникло прерывание. Например, драйвер PC имеет раздельные точки входа прерывания для двух его векторов, поэтому он может легко определить источник прерывания. Прерывания посредством вектора 70 идут к подпрограмме PCINT:; прерывания посредством вектора 74 идут к PPINT:.

Если бы драйвер PC имел только одну точку входа прерывания, названную PCINT:, то в этом случае, драйвер мог определить, какой вектор использовал прерывание посредством установки кодов условий в PS для векторов. Для вектора, считывающего устройства 70 он мог оставить С-разряд чистым, а для вектора 74 он мог установить С-разряд. Затем PCINT: управление может переходить к различным подпрограммам, основанным на значении С-разряда в новом PS.

Пример

; Таблица векторов перфоленточного устройства ввода-вывода
.IF EQ PR11¤X                 ; если перфоленточное
                              ; устройство ввода-
                              ; вывода
        .DRVTB PC,PR¤VEC,PCINT ; С-разряд чист
        .DRVTB ,PP¤VEC,PCINT,1 ; С-разряд установлен
.ENDC

В этом примере показано как вызывается запрос .DRVTB, и определяется значение кодов условий в PS.

2.3. Секция инициирования ввода-вывода содержит пять выполняемых команд драйвера

 Цель этой секции - начать передачу данных. Необходимо написать позиционно-независимый код (PIC) для драйвера.

Когда выдаётся программный запрос .READ или .WRITE, требующий устройства ввода-вывода, управление сначала передаётся клавиатурному монитору. Затем клавиатурный монитор вызывает драйвер первого слова после пятисловного заголовка самого драйвера. Он делает вызов каждый раз, когда новый элемент очереди становится первым элементом очереди драйвера. Такая ситуация возникает, когда элемент добавляется в пустую очередь драйвера или когда элемент становится первым в очереди, потому что предыдущий элемент был освобождён. Если любой из параметров в запросе ввода-вывода недопустим для устройства (например, слишком большой номер блока, слишком высокий номер привода и т.д.), драйвер сразу же должен завершить секцию ввода-вывода и сигнализировать о невосстановимой (фатальной) ошибке.

Код инициирования ввода-вывода выполняется при нулевом приоритете процессора в системном режиме. Это означает, что не может произойти переключение контекста, невозможно вызвать подпрограмму завершения, и прерывание по вектору 4 и 10 вызывает фатальный останов системы. В этой секции можно использовать все регистры. Пятое слово заголовка драйвера, DDCQE, содержит указатель текущего элемента очереди в его третьем слове, Q.BLKN.

Организованная в очередь система ввода-вывода гарантирует, что запросы передачи данных преобразуются в последовательную форму таким образом, что драйверам устройств системы ФОДОС-2 нет необходимости вводиться повторно. Поэтому, можно уменьшить размер драйвера посредством объединения, а не разделения чистого кода и сегментов данных.

2.3.1. Указания для начала передачи данных

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

  1. Необходимо решить, сколько раз драйвер будет повторно выполнять передачу данных в случае, если произойдёт ошибка. Необходимо инициализировать счётчик повторных передач посредством перемещения в него максимального числа повторных передач. Следующие две строки иллюстрируют этот этап:
    MOV    #RKCNT,(PC)+           ; RKCNT = максимум #
                                  ; повторных передач
    RETRY: .WORD 0                ; счётчик повторных передач
  2. Указатель текущего элемента очереди необходимо поместить в регистр и получить число приводов для устройства и число блоков для передачи из элемента очереди. Это иллюстрируют следующие строки кода:
    MOV    RKCQE,R5               ; засылает указатель текущего
                                  ; элемента очереди
    MOV    @R5,R2                 ; R2 = номер блока
    MOV    Q¤UNIT-1 (R5),R4       ; R4 = номер запрашиваемого
                                  ; привода
    ASR    R4                     ; сдвигает номер привода на
    ASR    R4                     ; три разряда вправо
    ASR    R4                     ; в младший байт
    SWAB   R4                     ; размещает номер привода в
                                  ; трех разрядах старшего байта
    BIS    #^C<DAUNIT>,R4         ; изолирует привод в разрядах
                                  ; выборки привода
  3. Затем вычисляется адрес для начала передачи данных в устройство. Используемые при этом команды зависят от структуры устройства. После того, как адрес вычислен, его необходимо записать в ячейку памяти. Если будет необходимо повторно выполнить передачу, то адрес не придётся вычислять повторно.
            .
            .
            .
            MOV     R3,(PC)+      ; сохраняется адрес в DISKAD
    DISKAD: .WORD   0             ; ячейка памяти для сохранения
                                  ; вычисленного адреса
  4. Описанные выше этапы 1-3 выполняются только один раз для каждого запроса ввода-вывода данных из выполняющейся программы. Однако в случае восстановимой ошибки можно начать повторно передачу как часть операции повторения. Поэтому, если поместить метку, чтобы использовать её как точку входа повторной передачи, то можно избежать повторения этапов 1-3. Следующие этапы могут быть выполнены более одного раза: они выполняются один раз для первого пуска ввода-вывода, и они могут быть выполнены вновь, если ошибка ввода-вывода вызывает повторную передачу. В этой точке драйвер должен определить, является ли запрос ввода-вывода считыванием, записью или установкой. Затем он должен генерировать соответствующий код операции и засылать его в регистр состояния устройства. Этот этап фактически инициирует передачу ввода-вывода.
            CSIE    = 100          ; разрешение прерывания
            FNWRITE = 12          ; запись
            CSGO    = 1           ; разряд GO
    AGAIN:  MOV     RKCQE,R5      ; указатель элемента
                                  ; очереди
            MOV     #CSIE!FNWRITE!CSGO,R3  ; устанавливает запись
            MOV     #RKDA,R4      ; указатель регистра
                                  ; адреса диска
  5. И последнее, возврат к прерванной программе необходимо осуществлять через монитор. Затем, когда передача ввода-вывода заканчивается, устройство будет прервано, и управление перейдёт к драйверу в точке входа прерывания в секции обработки прерывания драйвера.
            RTS PC                 ; ожидание прерывания

2.4. Секция обработки прерываний

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

Первым шагом в кодировании секции обработки прерываний является установка точки входа преждевременного прерывания посредством использования запроса .DRAST (эти точки входа иногда рассматриваются как точки входа асинхронного прерывания). Именем точки входа по умолчанию является DDINT. Обычно драйвер устройства вызывается у точки входа прерывания, когда прерывание возникло. Однако, при некоторых обстоятельствах драйвер вызывается у точки входа преждевременного прерывания.

2.4.1. Точка входа преждевременного прерывания

Существует ряд ситуаций, которые вызывают преждевременное прерывание в организованной в очередь системе ввода-вывода:

Преждевременное прерывание, независимо от того, введён драйвер или нет, зависит от двух факторов. Драйвер всегда вводится в точке входа преждевременного прерывания (слово сразу же перед обычной точкой входа прерывания), если выполнялся активный элемент очереди, который принадлежит преждевременно прерванному заданию. В мониторах FB и ХМ драйвер вводится всегда независимо от наличия элемента очереди, если HNDLR¤ (разряд И) установлен в слове состояния устройства. Если HNDLR¤ установлен, прекращение выполнения программы рассматривается в двух случаях: (1) - преждевременное прерывание во время операции ввода-вывода; (2) - преждевременное прерывание во время выполнения другой операции.

Монитор SJ игнорирует этот разряд. К тому же, драйвер не может выйти, когда прекращается работа в системе SJ, монитор SJ автоматически выполняет запрос .RESET.

Во всех условиях, при входе в драйвер, регистр R4 всегда содержит номер преждевременно прерванного задания. Регистры R0-R3 должны быть сохранены и восстановлены. Когда возникает преждевременное прерывание, в некоторых устройствах важно остановить ввод-вывод. Символьно-ориентированные устройства, как, например, PC:, попадают под эту категорию. При преждевременном прерывании драйвер должен остановить устройство, чтобы, например, предотвратить выход из-под контроля (отклонение) ленты. Он также должен убедиться, что устройство не может прерваться вновь. Поэтому символьно-ориентированные устройства обычно содержат подпрограмму преждевременных прерываний; точка входа преждевременного прерывания - это просто команда перехода к этой подпрограмме. Например, драйвер PC имеет подпрограмму преждевременного прерывания, которая запрещает прерывание в перфоленточном устройстве ввода-вывода. Затем драйвер вводится в монитор в секцию завершения ввода-вывода. Следующие строки взяты из драйвера PC:

PCDONE:  CLR    @#PC¤CSR      ; отменяет прерывание
                              ; перфоленточного
                              ; устройства ввода
         CLR    @#PP¤CSR      ; отменяет прерывание
                              ; перфоленточного 
                              ; устройства вывода

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

Если в драйвере используется запрос .FORK, то существует специальная процедура, которая имеет место, если возникает преждевременное прерывание. Необходимо поместить 0 в F.BADR (адрес подпрограммы .FORK, смещённый на 2) в FORK-блоке. Это предотвращает монитор от попытки выполнения бессмысленной после преждевременного прерывания подпрограммы .FORK.

2.4.2. Понижение приоритета до приоритета устройства

Когда возникает прерывание, драйвер вводится с приоритетом 7. Так же, как и в подпрограмме обработки прерываний, первой задачей драйвера является понижение приоритета процессора до приоритета устройства, позволяя таким образом устройствам с большим приоритетом прервать эту подпрограмму обработки прерываний. Вместо использования вызова .INTEN, как и в подпрограмме обработки прерываний, для понижения приоритета используется запрос .DRAST.

2.4.3. Запрос .DRAST

Запрос .DRAST используется для установки точки входа прерывания, точки входа преждевременного прерывания и для снижения приоритета процессора. Этот запрос устанавливает также глобальный символ ¤INPTR, который содержит указатель подпрограммы ¤INTEN в резидентном мониторе. Этот указатель заполняется начальным загрузчиком (для системного устройства) или во время запроса .FETCH (для устройства данных).

Формат запроса .DRAST следующий:

.DRAST NAME,PRI[,ABO]

где

NAME

-двухсимвольное имя устройства;

 

PRI

- приоритет устройства, т.е. приоритет, при котором должна выполняться подпрограмма обработки прерываний;

 

АВО

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

Пример:

         .DRAST PP,4,PCDONE
         .GLOBL ¤INPTR         ; делает этот символ
                               ; глобальным
         BR     PCDONE         ; точка входа
                               ; преждевременного 
                               ; прерывания
PPINT::  JSR    R5,@¤INPTR     ; переход в монитор
                               ; по коду .INTEN
         .WORD  ^C<4*^O40>&^O340 ;новый приоритет

В этом примере показаны запрос .DRAST из драйвера PC и код, который он генерирует.

Пример:

         .DRAST RK,5
         .GLOBL ¤INPTR         ; делает этот символ
                               ; глобальным
         RTS    PC             ; осуществляет возврат
                               ; из преждевременного
                               ; прерывания
RKINT::  JSR    R5,@¤INPTR     ; переход в монитор
                               ; по коду .INTEN
         .WORD  ^C<5*^O40>&^O340 ; новый приоритет
 

В этом примере приведена часть драйвера RK, который не имеет подпрограммы преждевременного прерывания.

2.4.4. Основные правила для программирования секции обработки прерываний

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

1. Если возникла ошибка

Если во время передачи возникла ошибка, драйвер должен определить, была ли эта ошибка восстановимой или невосстановимой, после того, как операция повторится.

Если ошибка невосстановимая, драйвер должен немедленно выводиться через секцию завершения ввода-вывода.

Если ошибка восстановимая, драйвер должен подготовиться к повторной передаче. Он должен уменьшить счётчик допустимых повторных операций. Затем, на FORK-уровне, он должен снова перейти к секции инициирования ввода-вывода для возобновления передачи. Если число повторных передач достигло допустимого (счётчик повторений равен нулю), то необходимо рассматривать эту неисправность как невосстановимую ошибку. В этом случае драйвер должен переходить в секцию завершения ввода-вывода.

Снижение до FORK-уровня необязательно для обработки ошибки. Использовать запрос .FORK или нет, зависит от промежутка времени, необходимого для установки повторной передачи. Вызов .FORK полезен тем, что позволяет использовать регистры R0-R3, давая возможность использовать общие подпрограммы для повторных передач. Если запрос .FORK не используется, то для использования допустимы только регистры R4 и R5.

2. Выполнение повторных передач на FORK-уровне

Запрос .FORK вызывает возврат к резидентному монитору, который отвергает текущее прерывание. Код, следующий за .FORK, выполняется при нулевом приоритете, а не при приоритете устройства, после того, как все другие прерывания были обработаны, но до того, как любое задание или его подпрограммы завершения смогут выполниться. Код, следующий за .FORK, выполняется так же, как и основная часть секции обработки прерываний драйвера, в системном режиме (это тот же режим, в котором выполняется секция инициирования ввода-вывода). Таким образом, переключение контекста защищено во время выполнения кода на FORK-уровне, и любое прерывание по 4 или 10 вектору является причиной фатального останова системы.

Пример:

         .FORK  RKFBLK        ; вызов .FORK
         JSR    R5,@¤FKPTR    ; переход в монитор по
                              ; коду .FORK
         .WORD  RKFBLK-.      ; смещение к элементу
                              ; FORK-очереди
RKRETR:  CLRB   RETRY+1       ; переустановка признака
         BR     AGAIN         ; переход в секцию
                              ; инициирования 
                              ; ввода-вывода

В этом примере приведена часть драйвера RK, где драйвер понижает приоритет до FORK-уровня для выполнения повторных передач данных после возникновения восстановимой ошибки. FORK-уровень идеален для выполнения повторных передач, так как это может быть длительный процесс. Здесь же показан вызов .FORK и его расширение.

3. Если передача не была завершена

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

4. Если передача была завершена

Когда передача завершена, драйвер может просто выйти через секцию завершения ввода-вывода.

2.5. Секция завершения ввода-вывода

Секция завершения ввода-вывода обеспечивает общий путь выхода, чтобы информировать монитор о том, что драйвер выполнил текущий запрос, и, поэтому, монитор может освободить текущий элемент очереди. Хотя другие секции драйвера являются различными отдельными частями, секция завершения ввода-вывода - это фактически расширение секции обработки прерываний, и граница между этими двумя секциями - искусственная. Управление не переходит к секции завершения ввода-вывода в результате вызова монитора, вызова подпрограммы или перехода, а переходит лишь в результате обычного хода выполнения через секцию обработки прерывания. Выполнение передаётся в секцию завершения ввода-вывода, когда обнаружена невосстановимая ошибка, когда число повторных передач в случае восстановимой ошибки достигло допустимого или когда передача данных закончена. (Если сразу же будет обнаружена невосстановимая ошибка, то можно непосредственно переходить из этой секции в секцию инициирования ввода-вывода.)

1. Если произошла ошибка

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

Сначала необходимо установить разряд невосстановимой ошибки для канала, разряд 0 в слове состояния канала (CSW). Второе слово элемента очереди ввода-вывода, Q.CSW, указывает слово состояния канала. Затем необходимо переходить к подпрограмме завершения ввода-вывода в резидентном мониторе. Для генерации кода этого перехода используется запрос .DRFIN.

Пример:

BIS     #HDERR¤,@-(R5)     ; устанавливается разряд
                           ; невосстановимой
                           ; ошибки
                           ; (R5 указывается третье
                           ; слово элемента очереди
                           ; указателем CSW
                           ; является второе слово)
.DRFIN  RK                 ; переход в монитор

В этом примере приведены строки кода из драйвера RK. Они показывают, как драйвер устанавливает разряд невосстановимой ошибки и осуществляет возврат в монитор.

2. Если передача была завершена

Для блочно-ориентированных устройств, как, например, диск, драйвер просто запрещает прерывание и выполняет переход в монитор. Запрос .DRFIN генерирует код для выполнения перехода.

Для символьно-ориентированных (или словно-ориентированных) устройств, как, например, перфоленточное устройство ввода-вывода, эта процедура сложнее, потому что драйвер должен сообщить об окончании файла заданию, которое запросило передачу ввода-вывода. Примерами условий, которые вызывают конец файла, являются: отсутствие перфоленты в перфоленточном устройстве ввода и обнаружение СУ/Z, напечатанного на системном терминале. Когда драйвер фактически обнаруживает условие EOF в операции READ, он должен установить внутренний признак EOF, поместить последний символ в буфер пользователя, а затем заполнить нулями остальной буфер. Затем драйвер должен переходить обратно в монитор, как если бы EOF не был обнаружен, и буфер просто бы заполнился. Драйвер ожидает, пока не будет вызван вновь признак EOF пользователю.

Драйвер PC использует разряд готовности в слове состояния перфоленточного устройства ввода-вывода как внутренний признак EOF.

Пример:

:      CLRB   @-(R4)        ; очищает байт (R4 ука-
                              ; зывает адрес буфера)
         INC    (R4)+         ; изменяет адрес буфера
         DEC    @R4           ; уменьшает счётчик ос-
                              ; тавшихся байтов
         BNE                ; цикл до готовности
PCDONE:  CLR    @#PC¤CSR      ; запрещает прерывание
                              ; перфоленточного уст-
                              ; ройства ввода
         CLR    @#PP¤CSR      ; запрещает прерывание
                              ; перфоленточного уст-
                              ; ройства вывода
         CLR    PCFBLK+2      ; очищает FORK-блок для
                              ; недопущения диспетче-
                              ; ризации
PCFIN:   .DRFIN PC            ; переход к окончанию
                              ; ввода-вывода

В этом примере показано, как драйвер PC заполняет нулями буфер пользователя, когда он обнаруживает конец файла, устанавливает внутренний признак EOF и переходит обратно в монитор.

Когда драйвер вызывается вновь с новым элементом очереди для другой операции READ, он сначала проверяет внутренний признак EOF. Найдя его установленным, драйвер устанавливает разряд EOF слова состояния канала, разряд 13, и переходит обратно в монитор. Резидентный монитор, в конце концов, очищает этот разряд, когда осуществляется следующий запрос ввода-вывода для этого канала.

Пример:

MOV     #PC¤CSR,R5     ; запрашивает перфолен-
                       ; точное устройство вво-
                       ; да-вывода, засылает CSR
TST     (R5) +         ; устройство готово?
BPL     PCGORD         ; да, начало передачи
BIS     #EOF¤,@-(R4)   ; не готов вход,
                       ; устанавливает EOF
BR      PCFIN          ; и операция завершения

В этом примере показано, как драйвер PC проверяет разряд готовности устройства, который он использует как признак своего EOF, устанавливает разряд EOF для программы пользователя и возвращается обратно в монитор. Благодаря этому соглашению для обозначения конца файла (EOF) программа воспринимает символьно-ориентированные устройства как устройства произвольного доступа к данным, что не противоречит идее системы ФОДОС-2 о независимости устройств.

2.5.1. Запрос .DRFIN

Запрос .DRFIN используется для генерации команд для перехода обратно в монитор в конце секции завершения ввода-вывода. Он делает указатель текущего элемента очереди глобальным символом и генерирует позиционно-независимый код для возврата в монитор. Когда после возврата управление переходит к монитору, он освобождает текущий элемент очереди.

Формат запроса .DRFIN следующий:

.DRFIN NAME

где

NAME

- двухсимвольное имя устройства.

2.6. Секция окончания драйвера

Целью секции окончания драйвера является объявление некоторых глобальных символов и установка таблицы указателей для смещений в резидентном мониторе. Указатели заполняются во время загрузки, если это драйвер системного устройства. В противном случае, они заполняются, когда драйвер делается резидентным посредством запроса .FETCH или команды монитора LOAD. Секция окончания драйвера предусматривает также символ для определения размера драйвера. Для генерации окончания драйвера используется запрос .DREND.

2.6.1. Запрос .DREND

Формат запроса .DREND следующий:

.DREND NAME

где

NAME

- двухсимвольное имя устройства.

2.6.2. Фиктивные устройства

В системе ФОДОС-2 предусмотрена возможность написания драйвера для фиктивного устройства (устройство, которое не прерывается и не является большим запоминающим устройством), чтобы использовать преимущества организованной в очередь системы ввода-вывода и того факта, что драйверы могут оставаться резидентными в памяти. Примерами драйверов для фиктивных устройств являются драйверы NL (драйвер фиктивного устройства) и MQ (драйвер обмена между заданиями).

Все выполняемые коды таких драйверов должны содержаться в секции инициирования ввода-вывода. Затем драйвер должен вызвать запрос .DRFIN для окончания операции и возврата элемента очереди. Так как фиктивные устройства не прерываются, то драйверам не нужна секция обработки прерываний и запрос .DRAST.

3. НАСТРОЙКА И ПРОВЕРКА ПРОГРАММЫ

3.1. Общее описание драйвера устройства

Ниже приведён пример, в котором показана структура для простого драйвера устройства SK.

Пример:

TITLE    SK     V05.01
;Драйвер устройства SK
.IDENT   /V05.01/
.SBTTL   секция определений
.MCALL   .DRDEF
.DRDEF   SK,377,WONLY¤,0,177514,200
SKBR = SK¤CSR + 2             ; регистр буфера SK
SKIE=100                      ; разряд разрешения
                              ; прерывания
.SBTTL   секция заголовка
         .DRBEG SK
.SBTTL   секция инициирования
         MOV    SKCQE,R4      ; R4 указывает текущий
                              ; элемент очереди
         ASL    Q¤WCNT(R4)    ; делает из счётчика слов
                              ; счётчик байтов
         BEQ    SKDONE        ; переход к непосредствен-
                              ; ному окончанию
         BCC    SKERR         ; устройство только запи-
                              ; си - запрос считывания
                              ; запрещён
RET:     BIS    #SKIE,@#SK¤CSR ; разрешение прерывания
         RTS    PC            ; ожидание прерывания
.SBTTL   секция обработки прерывания
         .DRAST SK,4,SKDONE
         MOV    SKCQE,R4      ; R4 указывает текущий
                              ; элемент очереди
         BIT    #100200,@#SK¤CSR ; ошибка или готовность?
         BMI    RET           ; ошибка, необходимо ис-
                              ; правление
         BEQ    RET           ; нет готовности - выход
                              ; и ожидание
         BIC    #SKIE,@#SK¤CSR ; запрещение прерываний
         .FORK  SKFBLK        ; код, переводящий про-
                              ; цесс на FORK – уровень
         ADD    #Q¤WCNT,R4    ; переместить указатель
                              ; элемент очереди
SKNEXT:  TSTB   @#SK¤CSR      ; готовность для следую-
                              ; щего символа?
         BPL    IRET          ; нет - переход назад
         TST    @R4           ; печатать немного левее?
         BEQ    SKDONE        ; нет - передача законче-
                              ; на
         MOVB   @-(R4) ,R5    ; принять символ
         INC    (R4)+         ; увеличить указатель бу-
                              ; фера
         INC    @R4           ; увеличить счётчик сим-
                              ; волов
         BIC    #^C<177>,R5   ; 7-разрядный ASCII
         MOVB   R5,@#SKBR     ; переслать символ в уст-
                              ; ройство
         BR     SKNEXT        ; то же самое для других
                              ; символов
.SBTTL секция завершения ввода-вывода
SKERR:   BIS    #HDEIRR¤,@-(R4)   ; установить разряд ошиб-
                              ; ки в CSW
SKDONE:  BIC    #SKIE,@#SK¤CSR ; запретить прерывания
         .DRFIN SK            ; возврат в монитор
SKFBLK:  .WORD  0,0,0,0       ; элементы FORK-очереди
.SBTTL секция окончания драйвера
         .DREND SK
.END

3.2. Драйверы, которые формируют внутреннюю очередь

Драйвер устройства может использовать одну или больше своих собственных очередей, необходимых для запросов ввода-вывода, вместо использования обычной очереди ввода-вывода монитор-драйвер. Внутренняя очередь предназначена для одновременного выполнения нескольких операций, т.е. драйвер может обслужить несколько запросов с одним обращением к устройству. Внутренняя очерёдность возможна в этом случае, но многое зависит от конкретной ситуации. Для драйвера и устройств, для которых внутренняя очерёдность невозможна или нецелесообразна, её не рекомендуется использовать.

Другим примером является очередь сообщений системы ФОДОС-2, выполненная посредством драйвера MQ для связи системных заданий. Если одно задание посылает сообщение второму заданию, и второе задание не принимает сообщение, драйвер MQ ожидает. Если процесс приёма сообщения осуществляется через очередь, то драйвер MQ обрабатывает его.

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

Вообще, драйвер следует простой процедуре для осуществления формирования в очередь. Когда запрос ввода-вывода делается для драйвера, он является первым и единственным запросом в очереди монитор - драйвер. Как только запрос будет принят, драйвер ставит его во внутреннюю очередь и очищает DDCQE и DDLQE для "удаления" запроса из очереди монитор - драйвер. Важно, что элемент очереди всё ещё занят - он ещё используется драйвером.

3.2.1. Формирование внутренней очереди

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

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

Если запрос сделан для процедуры, требующей вычислений и времени, драйвер ставит запрос во внутреннюю очередь посредством использования слова связи элементов очереди. Слово связи равно 0, так как этот элемент является первым и единственным в очереди.

В общем, драйвер устанавливает запрос во внутреннюю очередь, если этот запрос требует работы и времени и должен выполняться асинхронно. Если во внутренней очереди этот запрос является первым, драйвер начинает операцию, ожидает её завершения и выводится командой RTS PC. Если этот запрос не является первым во внутренней очереди, драйвер не начинает операцию и выводится командой RTS PC.

3.2.2. Обработка прерываний для драйверов, формирующих внутреннюю очередь

Когда операция завершается, драйвер переходит в точке входа прерывания DDINT:. Если внутренних очередей больше, чем одна, драйвер определяет, какой запрос включает это прерывание. Если операция не завершена, драйвер начинает её вновь и возвращается в монитор. Если передача завершена, драйвер должен поставить запрос, находящийся во внутренней очереди, снова в очередь ввода-вывода монитор - драйвер посредством установки DDCQE и DDLQE. В этой ситуации драйверу нужно вернуть запрос в основную очередь ввода-вывода, но ему нужно также продолжать выполнение (а не сразу возвращаться в монитор), чтобы проверить внутреннюю очередь на случай другого невыполненного запроса.

Чтобы вернуть запрос в монитор без вывода, драйвер должен выполнить подпрограмму .DRFIN.

Пример:

MOV    DDCQE,- (SP)  ; в случае, когда в очереди мо-
                     ; нитор - драйвер есть эле-
                     ; мент, тогда возможно преры-
                     ; вание
MOV    R4,DDCQE      ; элемент внутренней очереди
MOV    R4,DDLQE      ; помещается в очередь мони-
                     ; тор - драйвер
CLR    Q¤LINK(R4)
MOV    PC,R4         ; выход на запрос
ADD    #DDCQE-.,R4   ; .DRFIN
MOV    @#54,R5       ; через
JSR    PC,@270(R5)   ; подпрограмму JSR
MOV    @SP,DDCQE     ; восстановление возможных
MOV    (SP)+,DDLQE   ; других элементов очереди
.
.
.
(Проверка новой внутренней очереди и начало другой операции, если необходимо)
.
.
RTS    PC            ; возврат

В этом примере показано, как драйвер использует внутреннюю очередь. (R4 указывает элемент внутренней очереди, его третье слово.)

3.2.3. Процедуры преждевременного прерывания для драйверов, формирующих внутреннюю очередь

Несмотря на то, устанавливает ли драйвер запросы во внутреннюю очередь или нет, ФОДОС-2 использует счётчик невыполненных запросов ввода-вывода для каждого канала. Общее число невыполненных запросов ввода-вывода находится в резидентном мониторе. Когда задание преждевременно прерывается, некоторые невыполненные запросы ввода-вывода должны устраняться из счётчиков. Это происходит автоматически, если драйвер полагается на очередь ввода-вывода монитор - драйвер.

Если же драйвер осуществляет внутреннюю очередь ввода-вывода, он должен следовать процедуре понижения счётчика невыполненных запросов ввода-вывода. Эта процедура должна гарантировать, что драйвер будет вводиться, когда задание преждевременно прерывается, несмотря на то, имеет драйвер активные элементы очереди или нет, он устанавливает разряд 11, HNDLR¤, в слове состояния устройства DDSTS, когда драйвер вызывает запрос .DRDEF. В системах FB и ХМ это приводит к тому, что драйвер будет вводиться при всех преждевременных прерываниях, даже если в очереди монитор-драйвер ничего нет. (Монитор SJ игнорирует этот разряд, так как в системе одного задания такой проблемы нет.)

Если драйвер вводится в точке входа преждевременного прерывания, то он должен проверять внутреннюю очередь на элементы, принадлежащие преждевременно прерванному заданию. (R4 всегда содержит номер преждевременно прерванного задания.) Драйвер должен очищать внутреннюю очередь от этих элементов, и должна следовать остановка процедуры для снижения счётчика монитора невыполненных запросов ввода-вывода. Регистры R0-R3 должны быть сохранены и если DDCQE имеет ненулевое значение, то драйвер:

Если DDCQE имеет нулевое значение, то драйвер:

3.3. Параметры SET

Команда клавиатурного монитора SET позволяет изменить определённые характеристики драйвера устройства. Драйвер должен находиться на системном устройстве файлом с именем DD.SYS (DDX.SYS для ХМ монитора), где DD - двухсимвольное имя устройства.

Пример:

SET LP WIDTH=80

В этом примере устанавливается восьмидесятиколоночная ширина печати для устройства LP: (по умолчанию - 132 колонки).

Другой тип команды SET может разрешать или запрещать функцию.

Пример:

SET LP CR     (устанавливает возврат каретки;
              то же - по умолчанию)
SET LP NOCR   (не делает возврат каретки)

В этом примере показано, как с помощью префикса NO отрицается параметр CR (префикс NO всегда стоит перед параметром).

Драйвер устройства может содержать код для осуществления различных параметров. Ниже описано, как добавлять параметр SET к драйверу. Это добавление влияет только на файл драйвера, нет необходимости делать изменения в мониторе. (Параметры SET действительны и для устройств данных, и для системных устройств.)

3.3.1. Как выполняется команда SET

Команда SET целиком и полностью приводится в действие таблицей в блоке 0 файла драйвера и посредством установки подпрограмм, также в блоке 0, которые изменяют команды и данные в блоках 0 и 1 драйвера. (Блок 0 относится к адресам с 0 до 776, заголовок драйвера начинается в блоке 1, в ячейке 1000 файла драйвера.)

После печати команды SET на пульте терминала, монитор производит анализ командной строки и ищет файл драйвера системного устройства DD.SYS (DDX.SYS в ХМ мониторе). Нет необходимости в том, чтобы этот драйвер был установлен в выполняющейся системе. Затем монитор считывает блоки 0 и 1 драйвера в область буфера USR в памяти. Он просматривает таблицу в блоке 0, пока не найдёт элементы таблицы для указанного параметра SET. По элементу таблицы он может найти определённую подпрограмму, предназначенную для выполнения этого параметра и изменений, допускаемых этой подпрограммой, таких как NO или числовые значения. Затем монитор выполняет подпрограмму, которая содержит команды, изменяющие код в блоках 0 и 1 драйвера. Код в блоке 1 является частью основания драйвера и содержит команды для установок по умолчанию для всех параметров SET. После изменения кода, монитор записывает блоки 0 и 1 обратно на системное устройство. Поэтому, в результате команды SET, некоторые команды или данные в драйвере изменяются. Однако другие копии драйвера, находящиеся в памяти, недействительны.

3.3.2. Формат таблицы SET

Таблица для параметров SET состоит из серии четырёхсловных элементов для параметра. Таблица начинается с ячейки 400 блока 0 драйвера и оканчивается нулевым словом. Для генерации таблицы используется запрос .DRSET (см. п. 3.3.3).

Первое слово таблицы является значением, которое будет передано в R3 для подпрограммы SET, связанной с параметром, когда монитор обрабатывает этот параметр. Это слово может быть числовым значением - таким, как число колонок по умолчанию для построчно-печатающего устройства - или командой для замены на другую команду в блоке 1 драйвера. Это слово не должно быть нулевым.

Второе и третье слова таблицы являются наименованием параметра в кодах RADIX-50 (например, CR или WIDTH). В таблице символы выровнены влево и заполнены пробелами.

Младший байт четвёртого слова является указателем подпрограммы, которая изменяет код. Старший байт показывает тип допустимого параметра SET. Установка кода 100 показывает, что требуется восьмеричный аргумент. Установка кода 200 показывает, что префикс NO действителен для этого параметра. На рис. 1 показана таблица параметров SET.

Значение, находящееся в R3,
для подпрограммы SET

Имя параметра в кодах
RADIX-50 (два слова)

Коды для допустимого типа команд SET

Указатель подпрограммы SET

Рис. 1

3.3.3. Запрос .DRSET

Запрос .DRSET используется для установки таблицы параметров посредством вызова запроса один раз для каждого параметра таким образом, чтобы вызовы запроса следовали один за другим. Необходимо использовать запрос .DRSET после .DRDEF и перед запросом .DRBEG.

Формат вызова запроса .DRSET следующий:

.DRSET OPTION,VAL,RTN[,MODE]

где

OPTION

- имя параметра SET (например, CR или WIDTH); оно может содержать не более шести буквенно-цифровых знаков и не должно содержать пробелы или табуляцию;

 

VAL

- параметр, который будет передан в R3 для подпрограммы; он может быть числовой константой, такой, как минимальная ширина колонки, или целой командой, заключённой в угловые скобки, для замены содержимого блоков 0 или 1 драйвера; он не должен быть нулевым;

 

RTN

- имя подпрограммы, которая изменяет код в блоках 0 или 1 драйвера; подпрограмма должна следовать за таблицей параметров в блоке 0, но не выше адреса 776;

 

MODE

- произвольный аргумент для показа типа параметра SET; необходимо ввести префикс NO для показа, что он действителен для параметра; необходимо ввести NUM, если требуется десятичное значение, ОСТ - если восьмеричное; пропуск аргумента MODE показывает, что OPTION не принимает ни префикс NO, ни числовые аргументы; конструкция <NO,NUM> показывает, что требуется и префикс NO, и десятичное значение; конструкция <NO,OCT> показывает, что требуется и префикс NO, и восьмеричное значение; пропуск аргумента MODE вызывает появление нуля в старшем байте последнего слова элементов таблицы.

Сначала запрос .DRSET выдаёт директиву .ASECT и устанавливает счётчик адреса 400, в начале таблицы. Он генерирует также нулевое слово для окончания таблицы. Так как запрос .DRSET оставляет счётчик адреса в конце таблицы, то необходимо поместить подпрограмму для изменения кода сразу же после того, как запрос .DRSET вызовет драйвер. Это гарантирует, что они расположатся в блоке 0 драйвера.

3.3.4. Подпрограмма изменения драйвера

Драйверу нужна одна подпрограмма для каждого допустимого параметра SET. Для версии NO для каждого параметра используется та же подпрограмма. Целью подпрограммы является изменение кода в основной части драйвера, основанное на команде SET, напечатанной на пульте терминала.

Подпрограммы должны следовать сразу после таблицы параметров, и они должны находиться в блоке 0 после таблицы и ниже адреса 1000. Код в основной части драйвера, которую изменяет подпрограмма, должен находиться в блоке 1 драйвера, в пределах первых 256-ти слов.

Имя подпрограммы является точкой входа по умолчанию. Эта точка входа для параметров, которые не принимают ни числовые значения, ни префикс NO, и для параметров, которые принимают префикс NO, но в данный момент его не имеют. Точкой входа для параметров, которые позволяют использовать префикс NO и имеют его, является точка входа по умолчанию +4.

При входе в подпрограмму для всех параметров разряд переноса чист, и регистры R0, R1 и R3 содержат информацию по использованию подпрограммы. Если для этого параметра допустимы числовые значения, то регистр R0 содержит числовое значение, содержащееся в командной строке с SET; R1 содержит указанный номер канала как часть имени устройства (если номер канала не указан, то разряд признака установлен); R3 содержит слово VAL таблицы параметров SET.

Подпрограмма может показать, что команда недопустима, посредством возврата с установленным разрядом переноса. Например, для построчно-печатающего устройства SET WIDTH не допускает ширину менее 30. Если параметры подпрограммы показывают неисправность, монитор печатает сообщение об ошибке и не записывает блоки 0 и 1. Таким образом можно сделать проверку после изменения кодов в блоке 1.

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

.IIF GT,<.1000>, .ERROR .-1000 ;код SET слишком велик!

Эта секция завершается директивой .ASECT, после которой необходимо установить счётчик адресов 1000. Затем можно продолжать обработку остального кода драйвера, начинающегося с запроса .DRBEG, который устанавливает заголовок драйвера.

3.3.5. Примеры параметров SET

Следующие далее примеры взяты из драйвера построчно- печатающего устройства и демонстрируют параметры SET, описанные ранее:

SET LP WIDTH=80
SET LP CR
SET LP NOCR

Сначала драйвер вызывает запрос .DRSET для установки таблицы параметров для двух параметров: WIDTH и CR.

Первый вызов показывает, что установлен параметр WIDTH построчно-печатающего устройства, что десятичное 30 - это значение по умолчанию, что O.WIDTH - это имя подпрограммы, которая изменяет код этого параметра, и что WIDTH - цифровой аргумент: .DRSET WIDTH,30.,O.WIDTH,NUM.

Следующий вызов показывает, что установлен параметр CR построчно-печатающего устройства, что "NOP" должен переходить к подпрограмме, что O.CR - это имя подпрограммы, которая изменяет код этого параметра, и что этот параметр CR может использоваться с приставкой NO: .DRSET CR,NOP,O.CR,NO.

Эти два вызова генерируют следующую таблицу:

.ASECT
.=400
.WORD   30.            ; минимальное значение
                       ; WIDTH
.RAD50  \WIDTH\        ; имя параметра
.BYTE   <O.WIDTH-400>/2
.BYTE   100
NOP                    ; невыполняемая команда
.RAD50  \CR \          ; имя параметра
.BYTE   <O.CR-400>/2
.BYTE   200
.WORD   0              ; конец таблицы

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

Пример:

O.WIDTH: MOV     R0,COLCNT     ; перемещает значение от
                               ; пользователя
         MOV     R0,RSTC+2     ; в две постоянные ячейки
         CMP     R0,R3         ; сравнивает новое значе-
                               ; ние с минимальным зна-
                               ; чением WIDTH, 30
         RTS     PC            ; возврат, С-разряд
                               ; установлен на ошибку

В этом примере показана подпрограмма изменения параметра WIDTH. Команды в подпрограмме 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. Подпрограмме удаётся заменить одну из двух команд, расположенных в блоке 1;
  2. Команда NOP перемещается в CROPT, если выбран параметр "NOCR";
  3. Команда BEQ RSTC-CROPT+. Перемещается в CROPT, если выбран "CR";
  4. Во время выполнения подпрограмм при обработке параметров SET регистры R4 и R5 недоступны для использования.

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

BR А-В+.

где

А

- место назначения команды перехода;

 

В

- адрес команды перехода;

 

.

- текущее значение счётчика ячеек.

Обычно только подпрограммы для параметров, допускающих префикс NO, используют эти команды перехода.

И, наконец, приведён код секции обработки прерываний драйвера, который изменяется вышеприведёнными подпрограммами, Код для изменения должен быть расположен в, блоке 1 драйвера, в первых 256-ти словах.

Пример:

COLCNT: .WORD   COLSIZ         ; печать оставшихся
                               ; символов строки
CHRTST: CMPB    R5,#HT         ; это символ табуляции?
        BEQ     TABSET         ; да, сбросить табуляцию
        CMPB    R5,#LF         ; это перевод строки?
        BEQ     RSTC           ; да, восстановить счётчик
                               ; колонок
        CMPB    R5,#CR         ; это возврат каретки?
CROPT:  NOP                    ; "NOP", если нет;
                               ; иначе "BEQ RSTC-
                               ; CROPT + ."
                               ; посредством подпро-
                               ; граммы SET в блоке 0
                               ; (если параметр "CR")
        CMPB    R5,#FF         ; это перевод формата?
        BNE     IGNORE         ; нет, это не печать
RSTC:   MOV     #COLSIZ,COLCNT ; переустановка счётчика
                               ; колонок

Из этого примера видно, как подпрограммы из блока 0 могут изменять данные и команды в блоке 1 драйвера.

3.4. Как проверить и отладить драйвер устройства

Как только новый драйвер будет оттранслирован, отредактирован и включён в систему (установлен), можно начинать его проверку. Во время отладки необходимо не забывать о том, что каждый раз необходимо устранять старый драйвер и устанавливать новый после создания его новой версии DD(X).SYS.

Проверка драйвера заключается в следующих трех стадиях.

  1. Использование ODT для наблюдения за драйверами в процессе передачи ими данных (см. п.п. 3.4.1 и 3.4.2).
  2. Проверка драйвера командами клавиатурного монитора, программами работы с файлами и программами ФОРТРАН или БЕЙСИК. Например, команду COPY (см. [2]) можно использовать для копирования данных на или с устройства или использовать для копирования PIP (см. [3]). Хорошо использовать драйвер с операторами BASIC INPUT или PRINT, или с операторами FORTRAN READ, или WRITE. Если драйвер устанавливает разряд в слове состояния устройства, который показывает, что драйвер предназначен для устройства системы ФОДОС-2 справочной структуры, DUP будет работать правильно в устройстве, без дальнейших изменений, т.е., можно использовать DUP для инициализации устройства (по переключателю /Z) и объединения неиспользуемой области (по переключателю /S). Программе RESORC не требуется изменения для признания нового устройства и включения его в сообщение SHOW DEVICES.
  3. Дать драйверу расширенную разработку с прикладной программой, которая использует режим ожидания ввода-вывода, асинхронный ввод-вывод и подпрограмму завершения.

Когда драйвер пройдёт всю проверку успешно, можно использовать его как часть системы ФОДОС-2.

3.4.1. Использование ODT для проверки драйвера

Лучший способ использования ODT для проверки драйвера - это выполнение ODT как основного задания. Если используется монитор SJ, то имеет смысл переключить его на FB на время отладки. Во время отладки рекомендуется быть основным пользователем.

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

Ниже приведена команда, по которой ODT связывается с основным заданием: LINK/MAP/FOREGROUND ODT.

Затем необходимо загрузить драйвер устройства, который необходимо отладить: LOAD DD[X].

Теперь необходимо выполнить команду SHOW D. Запомним адрес, определённый для драйвера устройства, например, 131634. Вычитаем 6 (восьмеричное) и получаем базу адреса драйвера:

 131634
-     6
 131626

Запускается ODT как основное задание:

FRUN ODT
ODT V01.04
*

Засылается в регистр смещения 0 значение, вычисленное из адреса по команде SHOW D: 131626;0R

Можно перемещаться по драйверу в памяти по мере следования инструкций листинга трансляции. Пять первых слов являются заголовком; первая исполняемая команда является шестым словом. Поэтому лучше всего установить первую точку разрыва у шестого слова: 0,12; 0В

Другие точки разрыва можно поставить в тех частях драйвера, которые необходимо проверить во время отладки. Другим критическим местом является точка входа прерывания. Соответствующую ячейку можно найти проверкой листинга драйвера (точка входа прерывания называется DDINT:).

После установки точек разрыва можно выходить из ODT:

0;G

Теперь можно пытаться использовать драйвер. Например, использовать DUP для инициализации устройства или PIP для копирования на устройство данных, или выполнить тест-программу, предназначенную специально для этой цели. Когда выполнение достигает первой точки разрыва, ODT принимает управление. ODT используется как обычно для проверки ячеек и их значений или изменения команд. Приоритет ODT по умолчанию равен 7; это предотвращает от вмешательства других прерываний во время сеанса отладки.

Если работа драйвера устраивает, то необходимо устранить из него точки разрыва и приступить к дальнейшему выполнению посредством драйвера:

;В
;Р

Недопустима разгрузка основного задания (ODT), если точки разрыва ещё установлены в драйвере.

3.4.2. Использование ODT в ХМ

Необходимо тщательно выбрать место для ODT в памяти. Можно связать его с прикладной программой или так, чтобы он размещался в памяти там, где он не будет разрушен. Если точка разрыва должна быть выбрана во внутреннем режиме, ODT не должен размещаться в области РАС1 (ячейки с 20000 по 37776). Самое безопасное место для ODT - это секция основного задания (см. п. 3.4.1).

При отладке с использованием ODT страница ввода-вывода должна быть отображена.

Установка точек разрыва требует осторожности. После введения ODT необходимо проверить вектор прерывания по точке разрыва (BPT) в ячейках 14 и 16 нижней памяти. После установки точек разрыва необходимо вручную установить разряды текущего режима, разряды 14 и 15, PS в ячейке 16. Затем ожидается точка разрыва. Значение 11 предназначено для режима пользователя, 00 для системного режима. Программы работы с файлами системы ФОДОС-2, такие как PIP и DUP, выполняются в режиме пользователя и предполагают, что разряды режима будут установлены 11.

После установки точек разрыва необходимо напечатать 0;G для выхода из ODT. Это заставляет ODT выполнить запрос .EXIT, который разрушает вектор BPT. Поэтому после выхода из ODT необходимо вручную реконструировать содержимое вектора посредством использования команды DEPOSIT следующим образом:

D 14 = (истинное содержимое ячейки 14), (истинное содержимое ячейки 16)

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

4. ПОДПРОГРАММА ОБРАБОТКИ ПРЕРЫВАНИЙ

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

4.1. Программируемый ввод-вывод

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

Однако программируемый ввод-вывод в то же время является лучшим практически методом. Например, резидентный монитор использует программируемый ввод-вывод для печати своего сообщения об ошибке: ?MON-F-SYSTEM-HALT. Сначала он выполняет операцию RESET для остановки всех активных процессов ввода-вывода. Потом он ждёт в сжатом цикле для системного терминала, чтобы напечатать сообщение об ошибке по одному символу за раз. Очевидно, в такой ситуации, где монитор может быть испорчен, ни одно другое задание или передача данных не могут выполняться, и системный терминал разрешён только как устройство вывода.

Подпрограмма монитора .PRINT также может быть испорчена и не может быть использована. Учитывая эти требования, программируемый ввод-вывод является лучшим способом для печати сообщения об ошибке.

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

Пример:

; R1 указывает текст сообщения.
: TTPS - слово в памяти, содержащее адрес регистра состоя-
; ния печатающего терминала; его признак готовности уста-
; навливается в последнем по счёту разряде младшего байта
; (разр. 7).
; TTPB - слово в памяти, содержащее адрес буфера термина-
; ла.
; Пересылка символов в буфер восстанавливает признак заня-
; тости в регистре состояния
;
:     TSTB    QTTPS          ; проверить, ТТ - исполь-
                               ; зуется?
        BPL                  ; если да, проверить снова
        MOVB    (R1)+,@ТТРВ    ; если нет, печатать сим-
                               ; вол
        BNE                  ; переход назад, если пе-
                               ; чатать дальше

В этом примере из RMON демонстрируется программируемый ввод-вывод.

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

Пример:

;
; R4 указывает регистр состояния гибкого диска;
; R5 указывает внутренний буфер;
; R2 указывает буфер данных в памяти.
;
TRBYT:  TSTB    @TTPS          ; ожидает окончания пе-
                               ; редачи
        BPL     TRBYT          ; ветвление, если переда-
                               ; ча не закончена
EFBUF:  MOVB    @R5,(R2) +     ; передача символа
        DEC     @SP            ; проверка на окончание
                               ; счётчика
        BGT     TRBYT          ; дальнейшая передача

4.2. Ввод-вывод, обрабатываемый по прерываниям

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

4.2.1. Как работают прерывания

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

Затем процессор загружает новое содержимое PS и PC из двух предварительно назначенных ячеек нижней памяти, называемых вектором прерывания. Эти слова содержат адрес подпрограммы обработки прерывания и новое слово состояния процессора (PS), которое указывает новый приоритет процессора. Когда подпрограмма обработки прерывания завершается, она выполняет команду RTI, которая восстанавливает старые PC и PS из стека, и возобновляется выполнение в прерванной программе.

4.2.2. Приоритеты устройств и процессора

Обработка прерывания тесно связана с приоритетом процессора и устройств. Рис. 2 иллюстрирует структуру приоритетов ФОДОС-2.

Рис. 2

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

Центральный процессор (ЦП) оперирует с любым одним из восьми уровней приоритета, от 0 до 7. Когда ЦП работает с приоритетом 7, ни одно устройство не может его прервать. Когда ЦП оперирует с более низким приоритетом, причиной прерывания может стать лишь устройство с более высоким приоритетом. Можно устанавливать приоритеты процессора внутри подпрограммы обработки прерывания, изменяя слово состояния процессора. В системе ФОДОС-2 программное обеспечение предусматривает это, и можно напрямую изменять PS самостоятельно. Оно включает программные запросы .MTPS и .MFPS и запросы .INTEN и .FORK.

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

4.2.3. Слово состояния процессора (PS) занимает верхний адрес страницы ввода-вывода

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

Рис. 3 показывает разряды PS. Разряды с 5 по 7 определяют текущий приоритет.

При изменении разрядов, необходимо изменять приоритет ЦП. Можно изменить приоритет до 7, например, для предотвращения возникновения любого другого прерывания. Когда необходима обработка особого прерывания, можно изменить приоритет процессора до приоритета устройства так, что только устройства с высшим приоритетом будут прерывать эту подпрограмму обработки. (Обслуживаемое устройство прервать нельзя.) Вообще, нет необходимости в самостоятельном доступе к PS, можно использовать запросы системы ФОДОС-2, такие, как .INTEN и .FORK, для изменения приоритета процессора.

Рис. 3

4.3. Внутренние подпрограммы обработки прерываний в сравнении с драйверами устройств

Т.к. в системе ФОДОС-2 используются как программируемый (непрерывный), так и драйверный (прерывный) ввод-вывод, когда необходимо включить новое устройство в систему, которое уже не поддерживается системой, сначала необходимо решить, использовать внутреннюю подпрограмму обработки прерываний или написать драйвер. Каково бы ни было решение, и подпрограмма обработки прерываний, и драйвер могут включать как программируемую секцию ввода-вывода, так и драйверный код. Обычный интерфейс системы ФОДОС-2 между монитором и периферийным устройством есть драйвер устройства, который выполнен как файл образа памяти на устройстве массового хранения и находится в памяти, если он необходим для выполнения ввода-вывода устройства (см. разд. 2). Драйвер устройства обычно включает в себя подпрограмму обработки прерываний.

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

Если решено использовать драйвер, коды подпрограммы обработки прерываний должны находиться в драйвере, а не в программе. Выходить из основной программы необходимо посредством запросов .READ и .WRITE, и монитор, и драйвер вместе инициируют передачу данных, обрабатывают прерывания и сообщают программе, когда передача завершается. В системе SJ или для фонового задания в FB драйвер должен быть резидентом, только когда программа непосредственно нуждается в нем для выполнения ввода-вывода (т.е. драйвер должен быть всякий раз резидентным, когда файл или канал открыт). Для основного и системного задания для FB и ХМ необходимо загружать драйвер, используя команду монитора LOAD) перед выполнением программы, так что драйвер всегда резидентен.

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

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

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

Тремя большими преимуществами использования драйверов является обеспечение независимости устройства от программы пользователя, они могут разделять время процессора с другими процессами и просты в использовании. Драйверы имеют стандартный протокол для присоединения к монитору системы ФОДОС-2. Есть также стандартный протокол для интерфейса между монитором и программой, так что любая программа, которая согласована со стандартами монитора, может использовать драйверы. Это программы пользователя, вспомогательные программы системы и языковые процессоры ФОДОС-2: АССЕМБЛЕР, ФОРТРАН и БЕЙСИК. Таким образом, драйвер делает новое устройство доступным большому количеству программ без специальной модификации, кроме того, драйвер для устройств произвольного доступа, к данным делает файловую систему ФОДОС-2 применимой на устройстве без дополнительных затрат. Напротив, внутренняя подпрограмма обработки прерываний делает новое устройство доступным одной прикладной программе.

Драйверы устройств удобны для использования. Они стандартны для обслуживания устройств ввода-вывода, процедура для их написания и использования ясна и доступна, поскольку ФОДОС-2 предусматривает использование запросов при написании драйверов; имеются также команды клавиатурного монитора для установки драйвера в таблицу устройств монитора и загрузки в память. Кроме того, драйверы позволяют извлекать выгоду из программных запросов монитора для выполнения передачи данных. Наконец, драйвер это лишь способ соединения устройства с виртуальным заданием в системе ХМ.

Рис. 4 иллюстрирует различия между внутренней подпрограммой обработки прерываний и драйверами.

Рис. 4

4.4. Как планировать подпрограммы обработки прерываний

Наиболее важной частью написания подпрограммы обработки прерываний является момент её планирования. Ниже приведено руководство.

  1. Изучить устройство.
  2. Изучить структуру подпрограммы обработки прерываний.
  3. Изучить схему подпрограммы обработки прерываний.
  4. Продумать требования к программе.
  5. Подготовить блок-схему программы.
  6. Написать коды.
  7. Проверить и отладить программу.

4.4.1. Изучить устройство

Этот пункт является решающим для написания правильно работающей подпрограммы обработки прерываний. Необходимо внимательно изучить документацию к нему. Невзирая на формат документации (будь то руководство или брошюра), она должна содержать существенную информацию, которая необходима для поддержки его системой ФОДОС-2. Необходимо получить эту информацию.

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

  1. Что такое вектор прерывания устройства?

    Необходимо решить, что сделать вектором прерываний, приняв во внимание как конфликт с существующими устройствами, поддерживаемыми системой ФОДОС-2, так и конфликт с устройствами, поддерживаемыми другими операционными системами, если они используются. Если вектор выбран, необходимо убедиться, что устройство установлено правильно, и аппаратура скачет по этому адресу. В системе ФОДОС-2 используются все вектора по адресам ниже 500, и их нельзя использовать как вектора прерываний. В разд. 2 приводится список векторов периферийных устройств.

  2. Что такое регистры состояния?

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

  3. Какой у устройства приоритет?
  4. Устройство произвольного доступа к памяти или программируемой передачи (словно- или символьно-ориентированное).
  5. Где находятся регистры буферов данных?

    Необходимо изучить, где расположены регистры и что означают разряды в каждом случае.

  6. Каковы коды для типичных операций?

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

  7. Когда происходит прерывание устройства?

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

  8. Какой привод является основным для передачи данных?

    Это, конечно, относится к предыдущему вопросу, но необходимо определить, как посылаются запросы ввода-вывода в устройство: байтами, словами или блоками. Если, например, программа оперирует словами, а устройство ориентировано на символы, необходимо преобразовать слова в байты в подпрограмме обработки.

  9. Устройство нуждается в положительном или отрицательном счётчике байтов?

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

  10. Какова структура устройства, его геометрия?

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

  11. Каков механизм буферизации?

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

  12. Как выполнять вычисление адреса данных на устройстве?

    Это относится к структуре устройства. Необходимо изучить устройство и определить, как искать нужные данные. Номера блоков должны быть преобразованы в специальные адреса устройства. (Некоторые процессоры не имеют инструкций умножения и деления.)

  13. Какие собственные операции требуются устройству?

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

  14. Как обслуживать ошибки и условия исключения?

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

  15. На что обратить внимание при преждевременном прерывании?

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

4.4.2. Подготовка блок-схемы программы

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

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

Необходимо потратить достаточное количество времени для очистки и прямого обслуживания условия ошибки; если программа хорошо обслуживает условия ошибки, то в нормальном состоянии программа работает так же хорошо.

4.4.3. Написание кодов

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

4.4.4. Проверка и отладка

Проверка подпрограммы с внутренней обработкой прерываний - попытка выполнить её. Если подпрограмма составлена правильно, она будет способна считывать и записывать данные точно, без потери некоторых данных и будет правильно обслуживать условия ошибки. Если обнаружились ошибки, необходимо связать подпрограмму с ODT (не VDT) и попробовать выполнить её шаг за шагом. Сделать корректировку подпрограммы, снова оттранслировать и снова выполнить её, если необходимо.

4.5. Структура подпрограммы обработки прерываний

Этот подраздел даёт набросок общей структуры внутренней подпрограммы обработки прерываний. Пользователь должен выбрать из нее лишь то, что применимо к его случаю.

4.5.1. Защита векторов: запрос .PROTECT

В системах FB и ХМ, где выполняется более одного задания, следует использовать программный запрос .PROTECT для защиты векторов прерывания перед засылкой в них значений. Это гарантирует, что вектор уже не будет относиться к мониторному или другому заданию, обеспечивает пользовательскому заданию собственность вектора и защищает его от вмешательства другого задания или монитора путём установки разрядов в карте защиты памяти (разд. 3 детально описывает карту защиты нижней памяти). Пользовательскому заданию необходимо немедленно выходить в случае ошибки запроса .PROTECT. Задание не должно иметь доступа к векторам, которые всегда используются. Пример использования запроса .PROTECT приведён в подразделе 4.6. см. в [1] формат программного запроса .PROTECT.

Несмотря на то, что запрос .PROTECT не работает в системе SJ, его целесообразно использовать в программе. Запрос не оказывает действия, немедленно возвращающего в программу, тем не менее использование его упрощает позже переход, если программа будет выполняться в среде FB.

4.5.2. Установка вектора прерывания

Программа пользователя должна позаботиться о пересылке адреса подпрограммы обработки прерываний в первое слово вектора прерывания. Система ФОДОС-2 требует, чтобы все прерывания поднимали приоритет процессора до 7, поэтому программа пользователя должна заполнить второе слово вектора прерывания новым приоритетом, равным 7.

Пример:

        XXVEC=220              ; определяется вектор
        PR7=340                ; приоритет 7 равен 340
;
; точкой входа для подпрограммы
; обработки прерываний является
; ISREP:
        .PROTECT #AREA,#XXVEC  ; защита вектора
        BCS     NOVEC          ; вектор используется
        MOV     #HSREP,@#XXVEC ; установка первого слова
        MOV     #PR7,@#XXVEC+2 ; установка второго слова

В этом примере показан типичный случай установки двухсловного вектора прерывания. Программе не следует устанавливать вектор, пока он защищён. Здесь XX - имя устройства и 220 и 222 - адреса векторов прерывания.

4.5.3. Чистая остановка: запрос .DEVICE

Программный запрос .DEVICE является многозначительным лишь в системах FB и ХМ. Его предназначение - замена устройства (посредством очистки его разряда разрешения прерывания), если выполняющаяся программа преждевременно прервана по СУ/C или если программа выполнена. (Формат программного запроса .DEVICE см. в [1], а в подразделе 4.6 - пример использования запроса .DEVICE.)

Этот запрос необязателен в области SJ. Однако, целесообразно его использовать в пользовательской программе. Запрос не предпринимает действий возвращения непосредственно в программу пользователя, однако использование его упрощает позже переход, если программа будет выполняться в области FB.

Если программа выполняется в среде SJ, монитор ожидает окончания любого ввода-вывода, если имеется активная очередь невыполненных элементов. В среде FB, когда программа выполняется, монитор не только ожидает, если имеется активная очередь невыполненных элементов, но и входит в точку входа драйвера устройства в том месте, где он был преждевременно прерван. Если задание было преждевременно прервано по СУ/C или если оно вышло на запрос .HRESET, монитор SJ выполняет аппаратную очистку для прекращения ввода-вывода на любом устройстве. Если для данного устройства назначена аппаратура, необходимо убедиться, что произошёл чистый останов, когда получен сигнал инициализации канала.

4.5.4. Понижение приоритета процессора: запрос .INTEN

Когда возникает прерывание, управление передаётся подпрограмме обработки прерываний, адрес которой находится в первом слове вектора прерывания. В этой точке приоритет процессора равен 7, и все остальные прерывания запрещаются. Если требуется запретить некоторые прерывания, это относится к этому коду. Он должен быть краток и эффективен и не должен разрушать содержимое регистров. Если подпрограмма нуждается в использовании регистров, она должна сохранять их содержимое и восстанавливать их перед выходом из запроса .INTEN. Если код выполняется на приоритете 7 слишком долго, произойдёт прерывание системы в скрытом виде (мера, которой система быстро отвечает на прерывание). Хорошей будет обработка не более 50 микросекунд на приоритете 7.

Следует понижать приоритет процессора для устройства как только возможно. Это значит, что только устройства с высоким приоритетом будут способны прервать подпрограмму обработки прерываний данного устройства. Для понижения приоритета необходимо использовать запрос .INTEN. Указатель стека и общие регистры R0-R5 должны содержать те же значения, которые уже содержались там до вызова запроса .INTEN, когда подпрограмма обработки прерываний покидает запрос .INTEN. Если подпрограмма обработки прерываний записана не в позиционно-независимом коде (PIC), необходимо использовать следующий формат: .INTEN PRIO

Запрос .INTEN генерируется в следующий код:

       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, которая понижает приоритет процессора и в системах FB и ХМ переключает режим в системный. Затем монитор вызывает подпрограмму обработки прерываний как соподпрограмму. R4 и R5 можно использовать после выхода из запроса. Недопустимо разрушение содержимого любого другого регистра. Если требуются регистры R0-R3, необходимо сохранить их в стеке или памяти и восстановить перед окончанием. Если требуется сохранить значения в процессе работы запроса .INTEN, необходимо сохранить их в памяти перед вызовом и восстановить после выхода из него. Таким образом, если содержимое PS важное, такое как значения разрядов условий, следует сохранить их перед использованием вызова .INTEN, т.к. .INTEN вызывает переключение системного стека в FB и ХМ, следует избегать чрезмерного использования стека в подпрограмме обработки прерываний.

Можно хранить и восстанавливать регистры и PS, используя ячейки памяти вместо стека.

Хранение в ячейках памяти должно предохранить подпрограмму прерываний от повторного входа. Если подпрограмма будет использоваться для многих устройств, необходимо позаботиться при планировании о повторном входе.

4.5.5. Использование программного запроса .SYNCH

Запрос .SYNCH полезен в системах FB и ХМ. Его цель - убедиться, что задание выполнено правильно, когда подпрограмма обработки прерываний выполняет программный запрос. (В системе SJ не работает.)

Если необходимо выдать один или несколько запросов из подпрограммы обработки прерываний, первым должен следовать запрос .SYNCH. Запрос .INTEN передаёт управление в системный режим, а программный запрос .SYNCH может выполняться только в состоянии пользователя. Запрос .SYNCH сам обслуживает переход назад пользователя. Никогда не следует выдавать из подпрограммы обработки прерываний запросы, требующие USR, даже после использования .SYNCH. Можно также использовать .SYNCH после .FORK. При использовании запроса .SYNCH, R0-R3, SP должны содержать те же значения, какие были после использования запроса .INTEN.

В табл. 5 показан формат SYNCH-блока, который работает подобно элементу очереди завершения. Информация в 7-словном SYNCH-блоке размещена во главе соответствующей очереди завершения заданий. Следовательно, коды, следующие за .SYNCH выполняются как подпрограмма завершения в режиме пользователя с приоритетом 0. Поэтому программа пользователя должна запрещать прерывания перед запросом .SYNCH или она должна быть подготовлена для устройства, чтобы прерывание опять выполнялось перед выполнением. .SYNCH. SYNCH-блок доступен для повторного использования, если Q.COMP равно 0. Можно проверить SYNCH-блок путём подачи следующего запроса .SYNCH. Если управление передаётся к возврату по ошибке (слово, следующее за вызовом .SYNCH), значит, блок по-прежнему используется.

Таблица 5

Смещение

Имя

Владелец

Содержимое

0

Q.LINK

--

Зарезервировано

2

Q.CSW

Пользователь

Номер задания

4

Q.BLKN

--

Зарезервировано

6

Q.FUNK

--

Зарезервировано

10

Q.BUFF

Пользователь

R0 - аргумент для перехода

12

Q.WCNT

Монитор

-1

14

Q.COMP

Пользователь

0 при транслировании; монитор затем сохраняет содержимое этого слова

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

В коде следующего вызова .SYNCH R0 и R1 свободны для использования, т.к. они имеются в любой подпрограмме завершения. Однако необходимо сохранить R2-R5, если подпрограмма .SYNCH использует их. R4 и R5 не сохраняются при вызове. Поэтому, если их содержимое важно, необходимо сохранить их в памяти перед вызовом .SYNCH. Можно использовать Q.BUFF в SYNCH-блоке для пересылки значения в R0 для подпрограммы.

Запрос .SYNCH имеет необычный возврат по ошибке. Первое слово после .SYNCH - адрес возврата по ошибке, второе слово после .SYNCH - возврат при успешном завершении.

В среде SJ подпрограммы, следующие за вызовом .SYNCH (фактически подпрограммы завершения), будут вмонтированы (т.е. они могут прерывать друг друга). Они выдаются сериями в FB и ХМ. В SJ механизм запроса похож на схему FB и ХМ, но не делает его дважды.

4.5.6. Выполнение на FORK-уровне: запрос .FORK

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

R4 и R5 сохраняются во время вызова .FORK. Кроме того, R0-R3 можно использовать после запроса .FORK. Подобно .SYNCH, запрос .FORK предполагает, что R0-R3 и SP не изменяются после возвращения из запроса .INTEN. Недопустимо использование запроса .FORK без предварительного запроса .INTEN.

Необходимо предоставить 4-словный блок памяти для элемента FORK-очереди, нижние три слова содержат R4,R5 и адрес возврата PC. Первое слово - слово связи, которое должно быть 0, когда выдаётся запрос .FORK. т.к. подпрограмму .FORK не следует перезапускать, необходимо убедиться, что устройство не может быть прервано между моментом выдачи .FORK и моментом начала выполнения подпрограммы (коды, следующие за вызовом).

Недопустимо повторное использование FORK-блока, пока работает подпрограмма .FORK. Предполагается, что FORK- блок является свободным, когда вызов, который использовал его, возвращается. Табл. 6 иллюстрирует содержимое FORK- блока.

Таблица 6

Смещение

Имя

Владелец

Содержимое

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 перед вызовом подпрограммы обработки прерываний. Затем он не пытается выдавать серии FORK-подпрограмм. В подпрограмме обработки прерываний нет свободных для использования регистров перед вызовом .INTEN. После вызова .INTEN можно использовать регистры R4 и R5.

Запрос .FORK имеет различные применения в системах реального времени, т.к. он допускает откладывать обработку растянутых, но не критических по времени прерываний, пока не будут обработаны все другие прерывания.

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

Запрос .FORK решает проблему. Он возвращается на приоритет 0, только когда все другие прерывания уже обработаны, но перед передачей управления в прерванную программу пользователя.

4.5.7. Итог по .INTEN, .FORK и .SYNCH

Табл. 7 обобщает действия вызовов .INTEN, .FORK и .SYNCH. Рис. 5 показывает состояние регистров для каждого вызова.

Таблица 7

Макровызов

Новый приоритет

Новый стек

Регистры, доступные для использования после вызова

Данные, сохраняющиеся при вызове

.INTEN

Устройства

Системный

R4, R5

Нет

.FORK

0

Системный

R0-R5

R4, R5

.SYNCH

0

Пользователя

R0, R1

R0

4.5.8. Выход из обработки прерывания: RTS PC

Запрос .INTEN заставляет монитор вызывать подпрограмму обработки прерываний как соподпрограмму. В конце этой подпрограммы, для выхода из нее необходимо использовать инструкцию RTS PC, по которой управление возвращается в монитор, который восстанавливает R4, R5 и выполняет команду RTI.

Аналогично осуществляется выход из подпрограмм .FORK и .SYNCH с помощью команды RTS PC. Стек должен быть таким же, что и перед входом, и регистры должны иметь начальные значения.

4.6. Схематическая конструкция подпрограммы обработки прерываний

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

Рис. 5

В примере XX - двухсимвольное имя устройства.

Пример:

**Основная программа**
        XXVEC=VVV              ; вектор устройства
        PR7=340                ; приоритет 7
        DEVPRI=5               ; приоритет устройства
                               ; равен 5
                               ; (0-7, но не 000-340)
        XXCSR=NNNNNN           ; регистр состояния уст-
                               ; ройства
        IENABLE = 100          ; разряд разрешения пре-
                               ; рывания
START: .PROTECT #LIST,#XXVEC   ;  защита вектора
        BCS     ERROR          ; обработка ошибки
                               ; .PROTECT
        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              ; блок аргументов ЕMT
ERROR:  .                      ; подпрограммы для об-
        .                      ; работки ошибок
        .
** Подпрограмма обработки прерываний **
ISPEP:  .                      ; точка входа прерыва-
        .                      ; ния;
        .                      ; приоритет равен 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

5. ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ

5.1. Тайм-аут устройства ввода-вывода

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

Выбор средства тайм-аута производится во время генерации системы. Тайм-аут используется частично в мультитерминальном мониторе системы ФОДОС-2. Параметр автоматически включён в систему, если выбрана мультитерминальная поддержка. В противном случае, если это средство используется в драйвере, необходимо включить его во время генерации системы.

Для обеспечения тайм-аута устройства в системе ФОДОС-2 предусмотрены два запроса: .TIMIO и .CTIMIO. Они доступны только драйверам устройств. Если при трансляции файла драйвера в условии ТIМ¤IТ равен 1, то запрос .DRDEF выдаёт директиву .MCALL для запросов .TIMIO и .CTIMIO.

5.1.1. Запрос .TIMIO.

Запрос .TIMIO используется в секции инициирования ввода-вывода для формирования вызова тайм-аута. Этот запрос может располагаться в любом месте драйвера, кроме уровня прерывания. Если необходимо выдать запрос на уровне прерывания, то сначала должен следовать запрос .FORK.

Запрос .TIMIO планирует выполнение подпрограммы завершения после истечения указанного интервала времени. Подпрограмма завершения выполняется в контексте задания, указанного в блоке таймера. В ХМ-системе подпрограмма завершения выполняется с внутренним отображением, так как она является частью подпрограммы обработки прерываний. Как обычно, R0 и R1 используются в подпрограммах завершения. Когда вводится подпрограмма завершения, R0 содержит последовательное число запросов тайм-аута.

Так как для выдачи запроса .TIMIO или .CTIMIO необходимо переходить к FORK-уровню (нулевому приоритету процессора), драйвер должен запретить прерывание устройства перед использованием .FORK, или должен быть тщательно закодирован во избежание проблемы повторного ввода. Запрещено повторно использовать блок таймера, пока не исчезнет элемент таймера и не будет введена подпрограмма завершения, или пока элемент таймера не будет успешно устранён.

Формат запроса .TIMIO следующий:

.TIMIO TBK,HI,LO

где

ТВК

- адрес блока таймера, семисловного псевдоэлемента очереди таймера; нельзя использовать номерной знак (#) перед ТВК;

 

HI

-константа, обозначающая старшее слово двухсловного интервала времени;

 

LO

-константа, обозначающая младшее слово двухсловного интервала времени.

Формат блока таймера показан в табл. 8.

Хотя запрос .TIMIO перемещает старшее и младшее слова времени в блок таймера, необходимо обозначать их правильно при макровызове. Интервал времени выражается в тиках. Имеется 50 десятичных тиков.

Младшее слово времени вмещает значение до 65535 тиков. Это эквивалентно приблизительно 1310 с или приблизительно 21,8 мин. Если необходимо указать интервал времени в 21,8 минутах и менее, то аргумент HI должен содержать 0, и аргумент LO в запросе .TIMIO должен содержать число тиков.

Таблица 8

Смещение

Имя

Владелец

Значение

0

C.HOT

.TIMIO

Старшее слово времени

2

С.LOT

.TIMIO

Младшее слово времени

4

С.LINK

Монитор

Связь со следующим элементом очереди; 0 показывает отсутствие элемента

6

C.JNUM

Пользов.

Номер задания владельца; передаётся из элемента очереди

10

C.SEQ

Пользов.

Номер запроса таймера.

Допустимый диапазон использования номеров от 177000 до 177377

12

С.SYS

Монитор

- 1

14

С.СОМР

Пользов.

Адрес подпрограммы завершения, которая будет выполняться, если возникнет тайм-аут. Монитор обнуляет это слово, когда вызывает подпрограмму завершения, показывая, что блок таймера имеется в наличии для повторного использования

Если необходимо указать интервал времени продолжительнее, чем 21,8 мин, то старшее слово должно быть представлено в виде слова переноса. Каждый интервал, продолжительностью 21,8 мин, вызывает перенос 1 в старшее слово. Поэтому, для обозначения интервала, чуть большего, чем 21,8 мин, необходимо определять 1 для аргумента HI и 0 для аргумента LO. Для обозначения 43,6 мин в аргумент HI перемещается 2, 0 - в аргумент LO и т.д. так как двухсловное время позволяет показать до 65565 единиц, каждая длиной в 21,8 мин, то самый большой интервал, который можно указать, равен 2,7 года.

Единственными информационными словами, которые необходимо установить в блоке таймера, являются номер задания, последовательный номер и адрес подпрограммы завершения. Номер задания получается из текущего элемента очереди и, затем, помещается в блок таймера. Необходимо назначить последовательный номер, начиная с 177000, и можно работать до самого высшего номера последовательности, 177377. Номер задания и последовательный номер передаются подпрограммой завершения, когда она вводится. Адрес подпрограммы завершения необходимо переместить к седьмому слову блока таймера.

Ниже приведено макрорасширение запроса .TIMIO:

        .TIMIO  TBK,HI,LO
        JSR     R5,@¤TIMIT     ; указатель конца драйвера
        .WORD   ТВК-.
        .WORD   0              ; код для .TIMIO
        .WORD   HI             ; старшее слово интервала вре-
                               ; мени
        .WORD   LO             ; младшее слово интервала
                               ; времени

5.1.2. Запрос .CTIMIO

После возникновения условия, которое ожидал драйвер, необходимо выдать вызов устранения тайм-аута, который запрещает подпрограмму завершения. Вызов .CTIMIO используется в драйвере для устранения запроса тайм-аута. Выполнение должно происходить в системном режиме, когда выдаётся вызов. Если .CTIMIO используется на уровне прерывания, то сначала выдаётся вызов .FORK.

Например, драйвер построчно-печатающего устройства может проверять на условие автономности. Когда программа запрашивает передачу ввода-вывода, секция инициирования ввода-вывода драйвера вызывает немедленное прерывание. Затем секция обработки прерываний драйвера проверяет разряд ошибки устройства. Если разряд установлен, построчно-печатающее устройство неавтономно, то драйвер печатает сообщение, устанавливает посредством .TIMIO двухминутный таймер и возвращается в монитор по команде RTS PC для ожидания другого прерывания. Устройство не должно прерываться снова, пока условие ошибки не будет зафиксировано оператором. Если за две минуты не возникло прерывание, подпрограмма завершения таймера печатает другое сообщение об ошибке, устанавливает другой двухминутный таймер и возвращается опять в монитор по RTS PC для ожидания прерывания (пример драйвера построчно-печатающего устройства см. п. 5.1.3.3).

В этом примере, когда возникает прерывание и разряд ошибки чист, драйвер выдаёт вызов .CTIMIO для устранения временного ожидания.

В виде другого примера, драйвер диска может установить таймер до того, как начнёт операцию поиска. Т.к. прерывания ищутся дважды, драйвер не должен устранять таймер после первого прерывания. Когда возникает второе прерывание, хотя поиск уже завершён, драйвер должен устранить таймер.

Если интервал времени в каком-то применении уже истёк, и устройство поэтому находится в тайм-ауте, выполнение запроса .CTIMIO не удаётся. Так как подпрограмма завершения была помещена в очередь, вызов .CTIMIO возвращается с установленным разрядом переноса. Обычно можно игнорировать это условие.

Формат вызова .CTIMIO следующий:

 .CTIMIO ТВК

 где ТВК - адрес семисловного блока таймера; блок, указанный в вызове .CTIMIO, должен быть таким же, как уже использованный соответствующим запросом .TIMIO.

Запрос .CTIMIO расширяется следующим образом:

        .CTIMIO  ТВК
        JSR     R5,@¤TIMIT     ; указатель конца драйвера
        .WORD   ТВК-.
        .WORD   1              ; код для .CTIMIO

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

5.1.3. Применение тайм-аута устройства

Поддержка тайм-аута устройства используется в системе ФОДОС-2 лишь в нескольких случаях. Однако в ряде условий применяются запросы таймера.

5.1.3.1. Мультитерминальная обработка в системе ФОДОС-2

Мультитерминальная обработка в системе ФОДОС-2 использует тайм-аут устройства для проверки состояния удалённых терминалов. Эта проверка осуществляется с помощью специальной подпрограммы, которая проверяет готовность каждого удалённого терминала и использует запрос .TIMIO.

5.1.3.2. Обычная процедура таймера для драйвера диска

Драйвер диска может выполнить любую процедуру таймера для любой операции диска. Целью подпрограммы таймера является аннулирование или восстановление любой операции, которая длится слишком долго. Если операция не заканчивается за отведённый промежуток времени, то, скорее всего, на диске ошибочно разрушены некоторые операции.

Секция инициирования ввода-вывода устанавливает таймер, используя запрос .TIMIO. Затем драйвер начинает операции, запрошенные заданием: операции считывания, записи или установки. Драйвер возвращается в монитор по команде RTS PC и ожидает прерывания устройства. Если прерывание возникает до истечения интервала времени, драйвер аннулирует таймер и выполняет обычную последовательность проверки ошибок в результате передачи. Вообще, драйвер или снижается до FORK-уровня для восстановления неправильной операции, или выводится в монитор посредством .DRFIN для удаления текущего элемента очереди.

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

Подпрограмма завершения таймера должна использовать следующие команды для моделирования прерывания и ввода системного режима:

        MOV     @SP,-(SP)      ; отводит место для стека
        CLR     2(SP)          ; имитировать прерывание
                               ; PS = 0
        .MTPS   #340           ; переход на приоритет 7
        .INTEN  0,РIС          ; ввод системного режима

После входа драйвера в системный режим, он предпринимает соответствующее действие как результат тайм-аута. Драйвер снова может пытаться выполнить операцию. Для этого он уменьшает счётчик повторений, снижается до FORK-уровня и переходит в секцию инициирования ввода-вывода. Код в секции инициирования ввода-вывода устанавливает другой таймер, повторяет передачу и возвращается в монитор по команде RTS PC для ожидания следующего прерывания.

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

5.1.3.3. Пример драйвера построчно-печатающего устройства

Ниже приведён пример, состоящий из выдержек, взятых из драйвера построчно-печатающего устройства системы ФОДОС-2, модифицированного для использования поддержки таймера для проверки условия автономности устройства.

Когда секция инициирования ввода-вывода драйвера начинает передачу, это приводит к немедленному прерыванию и заставляет секцию обработки прерываний выполнять проверку разряда ошибки в CSR. Если есть ошибка, управление переходит к подпрограмме OFFLIN, которая выдаёт вызов .SYNCH для входа в режим пользователя, печатает сообщение об ошибке, затем устанавливает двухминутный таймер, после чего драйвер возвращается в монитор по команде RTS PC и ожидает прерывание устройства.

Если устройство было прервано, это означает, что условие ошибки было исправлено оператором. Драйвер аннулирует таймер и проверяет снова разряд ошибки, чтобы убедиться, что проблемы отсутствуют. Если ошибок нет, то драйвер обрабатывается как обычно. Если ошибка есть, драйвер циклится в подпрограмме OFFLIN. Если прерывание не возникнет за 2 минуты, то начинает выполняться подпрограмма завершения таймера. Она печатает сообщение об ошибке, устанавливает другой двухминутный таймер и возвращается в монитор по команде 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
        CLR     @LPS           ; запрещение прерываний
        .FORK   FRKBLK
        TST     TICMPL         ; активный элемент таймера?
        BEQ                  ; нет
        .CTIMIO TIMBLK         ; да, удалить его
        BCS                  ; ошибка
        CLR     TICMPL         ; и не устанавливать его снова
:     MOV     LPCQE,R4       ; R4 указывает текущий эле-
                               ; мент очереди
        TST     @(PC)+         ; ошибочное условие?
LPS:    .WORD   LP¤CSR         ; регистр состояния построч-
                               ; но-печатающего устройства
ERROPT: BMI     OFFLIN         ; да, идти на исправление
        .
        .
        .
; секция завершения ввода-вывода
LPDONE: CLR     @LPS           ; возврат из прерывания
        .DRFIN  LP
        .
        .
        .
; построчно-печатающее устройство автономно, предупрежде-
; ние печатать каждые две минуты
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             ; синхронизация законче-
                               ; на, продвинуться
:     CLR     TICMPL         ; показывает, что мы по-
                               ; пали сюда
        TST     @LPS           ; ошибка всё ещё есть?
        BPL                  ; нет, закончить
        MOV     PC,R0          ; в случае подпрограммы
                               ; завершения печатает со-
                               ; общение
        ADD     #MESSAG-.,R0   ; указатель сообщения
                               ; как PIC
        .PRINT                 ; печатать его
        MOV     PC,R0          ; в PIC-кодах, указывая
                               ; для
        ADD     #1¤-.,R0       ; .TIMIO подпрограмму
                               ; завершения,
        MOV     R0,TICMPL      ; запоминает его
        .TIMIO  TIMBLK,0,2*60.*60.     ; устанавливает двухминутный
                               ; таймер
:     RTS     PC             ; возврат назад
FRKBLK: .WORD   0,0,0,0        ; FORK-блок
TIMBLK: .WORD   0              ; блок таймера: старшее
                               ; слово времени
        .WORD   0              ; младшее слово времени
        .WORD   0              ; связь со следующим эле-
                               ; ментом очереди
TIJNUM: .WORD   0              ; номер задания
        .WORD   177000 + 3     ; последовательный номер
        .WORD   0              ; монитор устанавливает
                               ; здесь - 1
TICMPL: .WORD   0              ; адрес подпрограммы за-
                               ; вершения
SYNBLK: .WORD   0              ; SYNCH-блок
SYJNUM: .WORD   0              ; номер задания
        .WORD   0,0,0,-1,0     ; остальные
MESSAG: .ASCIZ  "?LP-W-LP OFF LINE-PLEASE CORRECT"
        .EVEN
        .DREND  LP

В этом примере приведён драйвер построчно-печатающего устройства.

5.2. Регистрация ошибок

Регистрация ошибок - это дополнительное средство системы ФОДОС-2, предназначенное для обеспечения надёжности системы. Драйверы устройств, которые поддерживают регистрацию ошибок, вызывают регистратор ошибок после каждой передачи ввода-вывода. Регистратор ошибок собирает статистику о деятельности устройств ввода-вывода, которую можно использовать для проверки их надёжности.

Поддержка регистрации ошибок выбирается в процессе генерации системы. Регистрация ошибок может выполняться под управлением мониторов ХМ или FB. Если система способна выполнять системное задание, регистратор ошибок выполняется как системное задание; в противном случае, он выполняется как обычное основное задание. Содержимое файла параметров генерации системы для регистрации ошибок следующее:

ERL¤G

-

если это значение равно 1, то регистрация ошибок разрешена для этой системы;

ERL¤S

-

это условие определяет число 256-словных блоков, используемых под внутренний буфер регистрации в мониторе SJ;

ERL¤U

-

максимальное количество индивидуальных приводов устройств, для которых регистратор ошибок собирает статистику; значение по умолчанию равно 10, максимальное число приводов равно 30; каждый привод добавляет семь слов в регистратор ошибок; для каждого блока требуется одна позиция (например, для системы с кассетными дисками требуется две позиции); значение этой переменной устанавливается при ответе на вопрос во время генерации системы.

Необходимо пересмотреть требования, предъявляемые к памяти и времени, до использования регистратора ошибок, так как регистратор ошибок создаёт определённое минимальное количество дополнительных глав для каждой передачи ввода-вывода, и сам регистратор ошибок использует почти 2К слов памяти. Однако регистратор ошибок может выполняться не каждый раз, чтобы требующаяся ему память была доступна программам пользователя и вызовы драйвером регистратора ошибок возвращались бы немедленно. Самый удобный способ использования регистрации ошибок системы - это использование её в виде проверки, когда есть сомнения в надёжности системы.

Все коды драйвера, которые предназначены только для регистрации ошибок, должны быть размещены среди команд условной трансляции. Эти команды включают код регистрации ошибок, если символ ERL¤G = 1, и опускают его в противном случае. Таким образом, коды регистрации ошибок или включаются в драйвер при его транслировании, или нет.

5.2.1. Когда и как вызывать регистратор ошибок

Драйвер устройства вызывает регистратор ошибок после каждой передачи ввода-вывода, независимо от того, была передача успешной или нет. Если передача была ошибочной, драйвер вызывает регистратор ошибок один раз для каждой повторной попытки передачи и ещё раз, когда разрешённое количество повторных попыток уже исчерпано. Так как вызовы регистратора ошибок должны быть упорядочены, драйвер может вызывать его только во время инициирования ввода-вывода или следом за вызовом запроса .FORK.

Драйвер должен установить регистры вызова регистратора ошибок.

5.2.1.1. Регистрация успешной передачи

Регистры R4 и R5 устанавливаются перед вызовом регистратора ошибок после каждой успешной передачи следующим образом:

R5

-

должен указывать на третье слово текущего элемента очереди;

R4

-

содержит два байта информации: старший байт является байтом идентификации устройства, DD¤COD, младший байт равен -1.

5.2.1.2. Регистрация невосстановимой ошибки

Перед вызовом регистратора ошибок необходимо установить регистры с R2 по R5 после возникновения невосстановимой ошибки. Примерами невосстановимых ошибок являются: неавтономность устройства, блокировка устройства записи, отсутствие ленты в перфоленточном устройстве ввода и т.д. Восстановимая ошибка, которая исчерпала число повторных передач, рассматривается как невосстановимая ошибка.

R5

-

должен указывать на третье слово текущего элемента очереди;

R4

-

содержит два байта информации: старший байт является байтом идентификации устройства, DD¤COD; младший байт является 0;

R3

-

содержит два байта информации: старший байт содержит общее число повторных попыток, разрешённых для этой передачи; младший байт содержит число регистров устройства, содержимое которых должно появляться в протоколе ошибок;

R2

-

указывает на буфер в драйвере, который содержит регистры устройства для регистрации.

5.2.1.3. Регистрация восстановимой ошибки

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

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

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

R5

-

должен указывать на третье слово текущего элемента очереди;

R4

-

содержит два байта информации: старший байт является байтом идентификации устройства, DD¤COD; младший байт является текущим значением счётчика повторных передач;

R3

-

содержит два байта информации: старший байт содержит общее число повторных попыток, разрешённых для этой передачи; младший байт содержит число регистров устройства, содержимое которых должно появляться в сообщении об ошибке;

R2

-

указывает буфер в драйвере, который содержит регистры устройства для регистрации.

5.2.1.4. Различия между восстановимой (SOFT) и невосстановимой (HARD) ошибками

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

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

5.2.1.5. Вызов регистратора ошибок

После того, как необходимые регистры будут установлены, можно вызвать регистратор ошибок:

JSR PC,@¤ELPTR 

где ¤ELPTR - его указатель в резидентном мониторе.

Запрос .DREND отводит место в драйвере для этого указателя. Указатель заполняется во время загрузки (для системного устройства) или по запросу .FETCH или по команде монитора LOAD (для устройства данных). Если регистратор ошибок не работает, то монитор возвращается непосредственно к драйверу. Если регистратор ошибок работает, то слово связи в RMON содержит его точку входа.

Пример:

¤ERLOG: MOV    (PC)+,-(SP)    ; входит здесь из драйвера, по-
                              ; мещая следующее слово в стек
¤ELHND::.WORD  0              ; 0, если регистратор ошибок
                              ; не работает; иначе, содержит
                              ; точку входа регистратора
                              ; ошибок
        BNE                 ; переход, если загружен
        TST    (SP) +         ; очистка стека
:     RTS    PC             ; вызов регистратора ошибок
                              ; или возврат к драйверу

Приведённые выше строки кода из RMON показывают, как выполняется вызов регистратора ошибок.

Команды монитора SRUN или FRUN устанавливают точку входа регистратора ошибок; команда UNLOAD EL обнуляет ¤ELHND.

При возвращении из вызова регистратора ошибок, регистры R0-R3 восстанавливаются в драйвере, R4 и R5 - разрушены.

5.3. Специальные функции

Иногда драйверам необходимо выполнять действия указанных устройств, для которых нет соответствующих программных запросов ФОДОС-2. Примеры таких действий: перемотка магнитных лент и считывание или запись абсолютных секторов на гибких дисках. Программный запрос .SPFUN обеспечивает средства программам для инициации таких специальных функций. Когда программа выдаёт запрос .SPFUN, должен присутствовать и код специальной функции в виде одного из аргументов. Этот код сообщает драйверу, какие специальные функции он должен выполнить. Например, кодом, который приказывает драйверу MT выполнять автономную перемотку магнитной ленты, является 372.

5.3.1. Программный запрос .SPFUN

Формат программного запроса .SPFUN следующий:

.SPFUN AREA,CHAN,FUNC,BUF,WCNT,BLK[,CRTN]

Полное описание аргументов для .SPFUN см. в [1].

Для использования вызова специальных функций в драйвере устройства необходимо определить интерфейс между программным запросом и драйвером устройства. Таким образом, значения аргументов BUF, WCNT и BLK зависят от конкретных специальных функций, которые вызывают запрос. Если запрос вызывает передачу данных, аргументы имеют свои обычные значения. Однако, хотя монитор осуществляет проверку, чтобы BUF являлся действительным адресом в области задания, он не гарантирует, что BUF + WCNT ещё находится в области задания. Поэтому необходимо указывать допустимые значения, если используется запрос .SPFUN для передачи данных.

Если вызов специальной функции заключается в возврате одного значения, то BUF должен быть однословной буферной областью. Можно изменять WCNT и BLK по своему усмотрению. Они могут быть спецификациями одного слова, указателями больших буферов и т.д., так как драйвер интерпретирует их в соответствии с кодом специальной функции. Монитор не изменяет их, когда передаёт в драйвер. Например, он не изменяет счётчик слов из положительного в отрицательный.

5.3.2. Поддержка специальных функций в драйвере устройства

Для осуществления поддержки вызова специальных функций в драйвере устройства необходимо задать SPFUN¤, один из разрядов значения STAT, которое предусмотрено для запроса .DRDEF. Это значит, что драйвер допускает использование специальных функций.

Затем определяется символика в драйвере для представления типов специальных функций, которые может выполнить драйвер. Например, драйвер устройства гибких дисков с двойной плотностью записи DY определяет следующие коды специальных функций:

SIZ¤FN =373   ; устанавливает размер устройства
WDD¤FN =375   ; записывает метку удалённых данных
WRT¤FN =376   ; записывает указанный сектор
RED¤FN =377   ; считывает указанный сектор

Все коды специальных функций должны быть отрицательными значениями байта (т.е. в диапазоне восьмеричных чисел от 200 до 377); рекомендуется, чтобы определённый код специальной функции представлял одну и ту же операцию на всех устройствах. Поэтому необходимо ознакомиться со всеми уже существующими кодами специальных функций (см. [1]), чтобы убедиться, есть ли соответствующий данной специальной функции код или он отсутствует. Если код уже существует, то его смело можно использовать, если же таковой отсутствует, то необходимо присвоить этой функции любой свободный код, начиная с 200 в сторону кода 377. Это поможет избежать в будущем конфликтов ввиду появления новых кодов следующих версий системы.

Когда драйвер вводится для передачи ввода-вывода, он должен проверить четвёртое слово элемента очереди, чтобы убедиться, является ли оно запросом специальной функции. Q.FUNC, являющийся младшим байтом четвёртого слова элемента очереди ввода-вывода, содержит код специальной функции. В стандартных запросах ввода-вывода для операции считывания, записи или установки этот байт равен 0. Для вызовов специальной функции этот байт равен отрицательному значению кода специальной функции. Необходимо проверять, чтобы этот код был допустимым для данного устройства, в противном случае, необходимо уходить на невосстановимую ошибку.

Если это запрос специальной функции, драйвер должен инициировать эту функцию и возвратиться по команде RTS PC. В секции обработки прерываний драйвер должен проверить, как обычно, наличие ошибок и определить завершение операции. Драйвер возвращает или данные, или слово, информирующие о состоянии, в буфер пользователя вызванной программы.

Так осуществляется выполнение специальных функций для определённого устройства, можно установить правило вызова для этой функции в программном запросе .SPFUN, а также правило возврата из драйвера. Драйвер должен рассматривать аргументы соответственно для каждого различного вызова специальной функции.

5.3.3. Тома переменного размера

Драйвер может управлять устройством, которое допускает использование томов двух (или больше) различных размеров. Примером такого драйвера является драйвер DY, который может обслуживать гибкие диски с одинарной или с двойной плотностью записи на одном приводе устройства.

Драйвер устройства, которое поддерживает тома различных размеров, должен передавать размер в блоках самого маленького тома в параметр SIZE запроса .DRDEF. Это значение возвращается в выполняющуюся программу, когда она выдаёт программный запрос .DSTATUS.

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

5.3.4. Устройства со специальными справочниками

Монитор ФОДОС-2 может сопрягаться с устройствами файловой структуры, имеющими нестандартные (т.е. не системы ФОДОС-2) справочники. Примером такого устройства является магнитная лента. Ее драйвер устанавливает разряд 12 (SPECL¤) слова состояния устройства. USR обрабатывает операции справочника для устройств справочной структуры ФОДОС-2; для специальных устройств драйвер должен обрабатывать операции справочника, как .LOOKUP, .ENTER, .CLOSE и .DELETE, так же, как и передачу данных.

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

Код:

1

2

3

4

функция:

закрытие

удаление

просмотр

ввод

 

CLOSE

DELETE

LOOKUP

ENTER

Эти функции соответствуют программным запросам .CLOSE, .DELETE, .LOOKUP и .ENTER (см. [1]). Запрос .RENAME не поддерживается для специальных устройств.

Пятое слово в элементе очереди для специальной функции справочника содержит указатель блока определителя файла, содержащего имя устройства, имя и тип файла в RADIX-50.

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

Программные запросы для операций справочника специальных устройств обрабатываются стандартными программными запросами. Когда, например, выдаётся запрос .LOOKUP, монитор проверяет разряд специального устройства в слове состояния устройства. Если устройство имеет специальную справочную структуру, то соответствующий код функции вводится в элемент очереди, и элемент непосредственно устанавливается в очередь драйвера, обходя обработку посредством USR. Независимость устройства сохраняется, так как операции .LOOKUP, .ENTER, .CLOSE и .DELETE очевидны для пользователя.

Для специальных устройств запрос .LOOKUP возвращает размер файла в шестое слово элемента очереди (Q.WCNT). Для запроса .ENTER шестое слово возвращает размер нового файла.

5.4. Драйверы устройств в ХМ-системе

Драйверы устройств в системах SJ и FB требуют нескольких изменений для правильной работы в системе ХМ. Предварительно необходимо ознакомиться с условными обозначениями в системе ХМ.

5.4.1. Условные обозначения наименований и условные обозначения системы

При написании драйвера устройства пишется общий исходный файл с именем DD.MAC, где DD - это двухсимвольное имя устройства, включающее код, который обеспечивает поддержку расширенной памяти в директивах условной трансляции. Обозначением условия, которое обеспечивает поддержку расширенной памяти при генерации системы, является MMG¤T, которое имеет значение 0, если поддержка расширенной памяти не выбрана, или 1, если выбрана поддержка расширенной памяти.

Это означает, что код расширенной памяти транслируется только тогда, когда значение, условно обозначенное MMG¤T, равно 1. Далее необходимо протранслировать исходный файл DD.MAC с условным файлом системы, SYCND, и с ХМ.МАС, создавая DDX.OBJ для ХМ-системы или DD.OBJ для систем SJ или FB. Эта процедура гарантирует, что дополнительные средства системы, которые поддерживают драйвер, согласуются с дополнительными средствами данного монитора.

5.4.2. ХМ-среда

В системе ХМ драйверы должны размещаться в пределах младших 28К слов физической памяти. Может быть ещё одно ограничение, в зависимости от наличия или отсутствия поддержки .FETCH в ХМ-мониторе.

Если ХМ-монитор осуществляет поддержку .FETCH, драйвер не может размещаться в пределах области физической памяти, отображённой посредством РАС1 (регистр адреса страницы 1), областью, которая включает ячейки памяти от 20000 до 37776. Перед вызовом программ, использующих драйверы необходимо сделать их резидентными по команде монитора LOAD, которая приводит к ограничению адреса.

Если ХМ-монитор поддерживает .FETCH (определяется во время генерации системы), ограничение распространяется только на размещение драйвера в памяти, он не должен превышать 28К слов. При поддержке .FETCH нет надобности в загрузке драйверов ХМ перед вызовом программ. Однако, даже при поддержке .FETCH, тот же самый драйвер может быть загружен по команде монитора LOAD.

Когда драйверы введены, они выполняются с внутренним отображением, которое разрешает доступ к младшим 28К словам памяти плюс страница устройства ввода-вывода (см. раздел 6). Однако программе, запрашивающей передачу ввода-вывода, нет необходимости иметь такое же отображение, что и внутреннее. Фактически программа может попадать в одну из трех возможных категорий:

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

Дело в том, что в системе ХМ ячейки физической памяти выражены в виде 18- или 22-разрядных адресов, это важно, когда необходимо обозначить адрес в пределах самого драйвера в виде адреса буфера. Если, например, драйвер содержит строку нулей, которую он записывает в устройство как часть инициализации, драйвер устанавливает операцию записи устройства, обозначая адрес строки в драйвере как адрес буфера. Так как драйвер размещается в пределах младших 28К слов физической памяти, его физический адрес может быть выражен как его виртуальный 16-разрядный адрес плюс дополнительные разряды для ХМ (разряды 16 и 17 для 18-разрядного адреса или разряды с 16 по 21 для 22-разрядного адреса), которые должны быть нулевыми.

На рис. 6 показана ХМ-система. Программа, которая запрашивает передачу ввода-вывода, отобразила область буфера данных в физическую память выше границы 28К слов.

Рис. 6

Монитор ФОДОС-2 предоставляет подпрограммы для драйверов для доступа к буферу данных пользователя в физической памяти. Далее описаны эти подпрограммы и ситуации, в которых они используются.

5.4.3. Элемент очереди в ХМ

Для того, чтобы найти фактический буфер пользователя в физической памяти, драйверу требуется дополнительное информационное слово в элементе очереди. Это слово является значением для РАС1, которое, будучи объединено с адресом виртуального буфера пользователя, обеспечивает физический адрес буфера. Хотя для драйверов в ХМ-системе используется только одно дополнительное слово, элемент очереди предоставляет место для двух слов. Эти два слова, со смещениями 20 и 22, сохраняются для будущего использования в системе и не должны использоваться пользователем. Когда условно обозначенный системой MMG¤T установлен 1, запрос .QELDF, вызванный посредством .DRDEF в начале драйвера, расширяется при генерации допустимых смещений для элемента очереди ХМ. Ниже приведено это макрорасширение:

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¤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 = ^O10

 

Q.PAR = ^O16

(значение PAC1)

Q¤PAR = ^O12

 

Q.ELGN = ^O24

(размер элемента очереди)

5.4. 4. Устройства произвольного доступа к данным: подпрограмма ¤MPPHY

Устройства произвольного доступа к данным, например, большинство дисков, работают, обычно, с 18-разрядными или 22-разрядными адресами, поэтому их драйверам нет необходимости отображаться в буфер пользователя. Эти драйверы используют подпрограмму монитора ¤MPPHY для поиска буфера пользователя в физической памяти. ¤MPPHY использует значение Q.PAR элемента очереди и адрес виртуального буфера Q.BUFF для создания истинного 18- или 22-разрядного адреса буфера пользователя.

Формат вызова подпрограммы ¤MPPHY следующий:

JSR PC,@¤MPPTR

где

¤MPPTR

- содержит указатель подпрограммы ¤MPPHY в резидентном мониторе; запрос .DREND размещает этот указатель в конце драйвера; указатель заполняется во время начальной загрузки (для системного устройства) или во время LOAD (для устройства данных).

Перед вызовом: R5 должен указывать на Q.BUFF, пятое слово элемента очереди.

После вызова: (SP), первое слово в стеке, содержит шестнадцать младших разрядов физического адреса буфера; 2(SP), второе слово в стеке, содержит 2 старших разряда физического адреса буфера в разрядах 4 и 5 (для 18-разрядного адреса) или в разрядах с 4 по 9 (для 22-разрядного адреса);

R5 указывает на Q.WCNT, шестое слово элемента очереди; значение не изменяется.

Пример:

        CMP     (R5)+,(R5)     ; переходит к адресу бу-
                               ; фера в элементе очереди
        JSR     PC,@¤MPPTR     ; переводит виртуальный
                               ; адрес пользователя в
                               ; физический
        MOV     (SP)+,-(R4)    ; засылает 16 младших
                               ; разрядов в RKBA, стар-
                               ; шие разряды - в стек
        MOV     (R5)+,-(R4)    ; засылает счётчик слов в
                               ; RKWC
        BEQ                  ; счётчик равен 0=поиск
        BMI                  ; счётчик отрицательный
                               ; =запись всех до по-
                               ; следнего
        NEG     @R4            ; счётчик положительный
                               ; = считывать, фиксируя
                               ; счётчик для контроллера
        MOV     #CSIE!FNREAD!CSGO,R3 ;функция считывания
:     BIS     (SP)+,R3       ; присоединение старших
                               ; разрядов адреса в функ-
                               ; цию
        MOV     R3, -(R4)      ; начало операции
:     RTS     PC             ; выход из прерывания

Этот пример взят из драйвера RK.

5.4.5. Символьно-ориентированные устройства: подпрограммы ¤GETBYT и ¤PUTBYT

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

5.4.5.1. Подпрограмма ¤GETBYT

Драйвер может использовать подпрограмму монитора ¤GETBYT для перемещения байта из области буфера физической памяти в стек. Затем драйвер может перемещать символы в регистр буфера данных устройства страницы ввода-вывода и инициировать передачу ввода-вывода.

Формат вызова подпрограммы ¤GETBYT:

JSR PC,@¤GTBYT

где

¤GTBYT

- содержит указатель подпрограммы ¤GETBYT в резидентном мониторе; запрос .DREND размещает этот указатель в конце драйвера; указатель заполняется во время начальной загрузки (для системного устройства) или во время LOAD (для устройства данных).

Перед вызовом:

После вызова:

Адрес буфера (Q.BUFF) в элементе очереди устанавливается 1. Если возникает переполнение отображения, подпрограмма вычитает 20000 из значения в Q.BUFF и добавляет 200 к значению в Q.PAR. Более подробно переполнение отображения описано в п. 5.4.7.

Пример:

        MOV     PCCQE,R4       ; указатель текущего элемента
                               ; очереди
        MOV     #PP¤CSR,R5     ; указатель регистра состоя-
                               ; ния перфоленточного устрой-
                               ; ства ввода-вывода
        TST     (R5)+          ; ошибка?
        BMI     PPERR          ; да, в устройстве нет ленты
        TST     Q¤WCNT(R4)     ; есть ещё символы для вывода?
        BEQ     PCDONE         ; нет, готовность к передаче
        INC     Q¤WCNT(R4)     ; уменьшается счётчик байтов
                               ; (он отрицательный)
        JSR     PC,@¤GTBYT     ; изымается байт из буфера
                               ; пользователя
        MOVB    (SP)+,@R5      ; выводит его на перфоленту

Этот пример из драйвера PC показывает как драйвер получает байт из буфера пользователя и выводит его на перфоленту.

5.4.5.2. Подпрограмма ¤PUTBYT

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

Формат вызова подпрограммы ¤PUTBYT следующий:

JSR PC,@¤PTBYT

где

¤PTBYT

- содержит указатель подпрограммы ¤PUTBYT в резидентном мониторе; запрос .DREND размещает этот указатель в конце драйвера; указатель заполняется во время начальной загрузки (для системного устройства) или во время LOAD (для устройства данных).

Перед вызовом:

После вызова:

Адрес буфера (Q.BUFF) в элементе очереди устанавливается 1. Если возникает переполнение отображения, подпрограмма вычитает 20000 из значения в Q.BUFF и добавляет 200 к значению в Q.PAR. Более подробно переполнение отображения описано в п. 5.4.7.

Пример:

        MOV     PRCQE,R4       ; R4 указывает на Q.BLKN
        MOVB    @#PRB,-(SP)    ; засылает символ
        JSR     PC,@¤PTBYT     ; перемещает его в буфер поль-
                               ; зователя
        DEC     Q¤WCNT(R4)     ; уменьшает счётчик байтов

Этот пример из драйвера PC показывает, как драйвер получает символ из перфоленточного устройства ввода-вывода и перемещает его в буфер пользователя.

5.4.6. Другие устройства: подпрограмма ¤PUTWRD

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

Формат вызова подпрограммы ¤PUTWRD следующий:

JSR PC,@¤PTWRD

где

¤PTWRD

- содержит указатель подпрограммы PUTWRD в резидентном мониторе; запрос .DREND размещает этот указатель в конце драйвера; указатель заполняется во время начальной загрузки (для системного устройства) или во время LOAD (для устройства данных).

Перед вызовом:

После вызова:

Адрес буфера (Q.BUFF) в элементе очереди устанавливается 1. Если возникает переполнение отображения, подпрограмма вычитает 20000 из значения в Q.BUFF и добавляет 200 к значению в Q.PAR. Более подробно переполнение отображения описано в п. 5.4.7.

Пример:

        MOV     #DDNBLK,-(SP)  ; помещает размер в блоках в
                               ; стек
        MOV     DYCQE,R4       ; R4 указывает на Q.BLKN
        JSR     PC,@¤PTWRD     ; вызов подпрограммы

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

5.4.7. Драйверы, которые имеют непосредственный доступ к буферу пользователя

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

Процедура драйвера для отображения в буфер пользователя следующая.

Устройства, такие как гибкий диск, передают данные по сектору за раз между самим диском и внутренним буфером данных диска. Однако гибкий диск не является устройством произвольного доступа к данным, поэтому драйвер DX не может использовать подпрограмму монитора ¤MPPHY. Кроме того, другие подпрограммы монитора для символьно-ориентированных устройств, имеющих в наличии внутренний буфер данных устройства, слишком медленны для практического использования. Поэтому, драйвер DX отображается в буфер пользователя физической памяти, а затем выполняет операцию ввода-вывода так, как если бы она была простой передачей между памятью и устройством. Драйвер осуществляет это отображение, заимствуя область РАС1.

¤Р1ЕХТ копирует из драйвера в стек монитора необходимые инструкции по передаче данных, таким образом, перемещение инструкций происходит из возможной области РАС1. Затем ¤Р1ЕХТ устанавливает необходимое значение РАС1 и выполняет команды, скопированные в стек. После окончания ¤Р1ЕХТ восстанавливает РАС1, очищает стек монитора и засылает в драйвер по словам следующий список команд.

Вызов подпрограммы ¤Р1ЕХТ осуществляется по команде JSR R0, следующей после числа байтов для копирования в стек монитора плюс 2, списка команд для осуществления передачи данных и значения РАС1 (Q.PAR) из элемента очереди.

Пример:

        MOV     @#SYSPTR,R4    ; R4 содержит указатель
                               ; базы монитора
        MOV     Р1ЕХТ(R4),(PC)+   ; засылает адрес подпрограммы ¤Р1ЕХТ
¤Р1ЕХТ: .WORD   Р1ЕХТ          ; указатель подпрограмм-
        .                      ; мы ¤Р1ЕХТ
        .
        .
; --- удаляет две следующие ниже строки, если диспетчер
; --- памяти не используется
        JSR     R0,@¤Р1ЕХТ     ; разрешает монитору вы-
                               ; полнять следующие коды
        .WORD   PARVAL-.       ; число байтов для копи-
                               ; рования+2
:     TSTB    @R4            ; проверяет признак го-
                               ; товности передачи
        BPL                  ; ожидает готовность
:     MOVB    (R2)+,@R5      ; перемещает символ из
                               ; буфера пользователя на
                               ; гибкий диск
        TSTB    @R4            ; устанавливает CSR для
                               ; следующего раза
        DECB    R1             ; уменьшает счётчик передач
        BNE                  ; если не 0, передавать
                               ; остальные символы
; --- если используется диспетчер памяти, ограничиться
; --- списком значений РАС1
PARVAL: .WORD   0              ; удаляется, если исполь-
                               ; зуется диспетчер памяти
	; ---
; далее продолжается обычный процесс

В этом примере приведена команда из драйвера DX, которая иллюстрирует описанную выше технику. R1 - счётчик переданных байтов, R2 - указатель буфера пользователя, R4 - указатель регистра состояния устройства гибких дисков и R5 - указатель регистра данных устройства гибких дисков. Р1ЕХТ - указатель значения фиксированного смещения подпрограммы ¤Р1ЕХТ относительно монитора.

К списку команд, переходящему в ¤Р1ЕХТ, накладываются следующие ограничения:

Чтобы драйвер имел доступ непосредственно к буферу пользователя, необходимо понять, как область РАС1 отображается в область пользователя. Рис. 7 поможет разобраться в этом вопросе. Он показывает виртуальное задание в обычной ХМ-системе с буфером пользователя, размещённым в физической памяти свыше 28К слов. Программа пользователя отображается в буфер через РАС6. Драйвер использует РАС1, помещая туда значение Q.PAR из элемента очереди, а затем использует значение Q.BUFF из элемента очереди для доступа к буферу пользователя. РАС1 отображается в физическую память секциями 32-словных блоков (десятичное) и, в лучшем случае может отображать область размером 4К слов. (Размер страницы РПС1 (регистр признака страницы) установлен всегда так, что отображается вся страница.) Если буфер пользователя начинается с ячейки, физической памяти, которая не кратна 32-м словам, РАС1 отображается в первую же область выше начала буфера, кратную 32-м словам. Область отображения РАС1 может начинаться в физической памяти с любого адреса, две младшие восьмеричные цифры которого являются нулями. Таким образом, при отображении РАС1 в буфер пользователя будет отображено 4К или (4К-31) слов (десятичное).

Рис. 7

Ниже приведён рис. 8, на котором показана работа отображения.

Рис. 8

На рис. 8 показана область буфера, размещённая у ячейки 331724 физической памяти с прикладной программой, отображённой в буфер посредством РАС6. Буфер на 24 (восьмеричное) байта выше 331700, которое является 32-словной границей. ¤Р1ЕХТ помещает значение Q.PAR, 3317, в РАС1, заменяя значение РАС1 по умолчанию (0200). Это вызывает отображение РАС1 в 4К-словную область физической памяти, начиная с адреса 331700. В результате, когда драйвер обращается к внутренним виртуальным адресам в диапазоне от 20000 до 37776, он выбирает ячейки физической памяти с 331700 по 351676. Так как значением в Q.BUFF является 20024, то используя это значение, драйвер может иметь доступ к области буфера пользователя в ячейке 331724.

Если количество данных для передачи слишком большое, то может потребоваться перемещение указателя буфера и регулирование отображения для его учёта. Существует два способа перемещения указателя буфера. Самый лёгкий способ - это модификация РАС1. Например, каждым 32-м словам, перемещённым через буфер, добавляется 1 к значению РАС1. Драйвер DX, например, передаёт 64 слова за раз, добавляя 2 к значению РАС1 после каждой передачи, чтобы избежать переполнения отображения.

Другим способом перемещения указателя буфера является модификация значения Q.BUFF посредством изменения значения в самом элементе очереди. Сначала необходимо после модификации значения Q.BUFF сравнить новое значение с 40000. Если значение больше или равно 40000, из него надо вычесть 20000 и прибавить затем 200 к Q.PAR. Это позволит не только следить за регулированием отображения, но и поможет избежать переполнение отображения.

И, наконец, необходимо выбрать любую ячейку в буфере пользователя, если дано смещение байта от начала буфера. По существу, необходимо определить число 32-словных секций в 16-разрядном смещении байта делением на 100 (восьмеричное) и прибавлением частного к РАС1, а остатка к Q.BUFF. Тогда можно правильно выбрать ячейку в буфере пользователя.

Например, предположим, что нужен байт со смещением 12345 от начала буфера, показанного на рис. 8. Частное от деления 12345 на 100 равно 123, остаток - 45. Прибавление 123 к текущему значению Q.PAR, которое равно 3317, даёт 3442 для нового значения РАС1. Прибавление 45 к значению Q.BUFF, которое равно 020024, даёт 020071 - новый адрес буфера (в данном случае получен адрес байта).

5.5. Подпрограмма обработки прерываний в системе ХМ

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

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

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

Рис. 9 содержит схему внутреннего отображения по умолчанию, которое предусматривает доступ к нижним 28К словам памяти и к странице ввода-вывода. Это также схема отображения для привилегированного задания, если оно начало выполняться. Эта схема отображения эффективна всегда, когда прерывание обрабатывается. (Заштрихованная область на рисунке представляет собой память, которая недоступна пользовательскому заданию.) На рис. 9 векторы прерывания 200 и 202 содержат точку входа подпрограммы обработки прерываний, называемую ISREP:, и значение 340, которое является новым приоритетом PS. Если произошло прерывание, система использует внутреннее отображение для поиска подпрограммы обработки прерываний. В этом примере она начинается с адреса 120000. После этого привилегированное отображение и внутреннее отображение одинаковы на этой диаграмме, подпрограмма обработки прерываний находится в физической памяти точно в месте точки внутреннего отображения, тогда она может быть выполнена правильно.

Рис. 9

Рис. 10 содержит привилегированное задание, которое изменяет отображение виртуального адреса пользователя. (Заштрихованная на рис. 10 область представляет память, которая не доступна пользователю.) Например, подпрограмма обработки прерываний не может быть выполнена правильно, если прерывание произошло потому, что подпрограмма обработки прерываний не была расположена в физической памяти в должном месте. Указанная область памяти до внутреннего отображения содержит произвольные данные или команды.

Рис. 10

Второе ограничение для подпрограммы обработки прерываний в ХМ относится к области монитора, использующей регистр адреса страницы 1 (РАС1) при внутреннем отображении. РАС1 контролирует отображения виртуальных адресов с 20000 до 37776. Если ХМ-монитор загружается при внутреннем отображении, то виртуальный адрес отображается в тот же самый физический адрес. Однако монитор сам использует РАС1 для отображения блоков области ЕMT и буфера данных пользователя. Когда же система выполняется, внутренние виртуальные адреса, расположенные в РАС1, могут быть отображены в любое место физической памяти, и у пользователя нет возможности проконтролировать это. Недопустимо, чтобы подпрограмма обработки прерываний и все данные, которые ей необходимы, располагались в виртуальном адресе области, отображённой в РАС1. Рис. 11 иллюстрирует это ограничение. Допустимое нахождение подпрограммы обработки прерываний предполагается тогда, когда привилегированное отображение совпадает с внутренним отображением во время прерывания (на диаграмме отмечено "*").

Рис. 11

Если подпрограмма обработки прерываний нуждается в окне в памяти, она может заимствовать РАС1 так же, как эта делает монитор. Она должна сохранить содержимое, значения которого ей необходимы, и восстановить истинное содержимое сразу же после выхода. Это можно сделать с помощью запросов .INTEN или .FORK, но не .SYNCH.

Если система использует драйвер MQ для связи с системным заданием, и параметр условной трансляции MQH¤P2=1 определён во время генерации системы, все ограничения для РАС1 также относятся к РАС2 - области адресов с 40000 до 57777 включительно.

Если в подпрограмме обработки прерываний используется запрос .SYNCH, то строки кодов, следующих за .SYNCH, выполняются почти как подпрограмма завершения. Подпрограмма завершения выполняется в ХМ с регистром пользователя, стеком пользователя и пользовательским отображением. Однако после кодов, следующих за .SYNCH, ослабевает роль подпрограммы обработки прерываний, она выполняется с регистром пользователя, исключая внутреннее отображение. Таким образом, коды, следующие за запросом .SYNCH, вызванным в ХМ-мониторе, должны соблюдать те же ограничения, что и для главного тела подпрограммы обработки прерываний: её отображение должно совпадать с внутренним отображением в то время, когда произошло прерывание или когда выполняется подпрограмма завершения. И последнее, она должна полностью соблюдать ограничения, налагаемые на РАС1 и РАС2.

6. УСТАНОВКА ДРАЙВЕРА УСТРОЙСТВА

6.1. Драйверы системного устройства и начальный загрузчик

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

6.1.1. Файлы монитора

Файл монитора должен находиться на системном устройстве и может иметь любое имя, но требуемым типом, файла всегда является .SYS. В ФОДОС-2 они имеют определённое название: FMONBL.SYS, FMONSJ.SYS и FMONFB.SYS. Если монитор создаётся в процессе генерации системы, именем монитора всегда является FMONXX.SYG, где XX - одно из четырёх: BL, SJ, FB или ХМ. Перед использованием монитор необходимо переименовать, чтобы его тип был .SYS.

Блоки с 0 по 4 каждого файла монитора содержат вторичный загрузчик. Вторичный загрузчик загружает драйвер системного устройства и монитор в память. Он также модифицирует таблицы монитора для соединения монитора с драйвером устройства и присваивает имена устройствам по умолчанию DK. и SY.

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

6.1.2. Создание драйвера системного устройства

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

6.1.2.1. Первичный драйвер

Первичный драйвер, который прибавляется к стандартному драйверу устройства данных, состоит из четырёх частей:

Первичный драйвер работает вместе с начальным загрузчиком системы ФОДОС-2 для загрузки нового системного устройства. Первичный драйвер целиком содержится в программной секции (Р-SECT) DDBOOT, где DD - это двухсимвольное имя устройства. Код выполняется в ячейке 0 физической памяти.

6.1.2.2. Подпрограмма входа

Точкой входа для первичного драйвера является DDBOOT::. Эта ячейка должна содержать только две команды, и они должны следовать за последовательностью начальных загрузчиков. Этими командами являются NOP и переход к началу начального загрузчика программного обеспечения. Если начало начального загрузчика программного обеспечения дальше пределов действия команды BR, то можно использовать команду JMP, которая начинает загрузку программного обеспечения.

Пример:

RKBOOT::   NOP
           BR     BOOT1

В этом примере приведена подпрограмма входа для драйвера RK (BOOT1 определяется в первичном драйвере).

Любой аппаратный загрузчик вызывает коды в П-секции DDBOOT для загрузки с ячейки 0 памяти. Он начинает также выполнение с DDBOOT::.

6.1.2.3. Начальный загрузчик программного обеспечения

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

  1. Установить стек с ячейки 10000.
  2. Сохранить номер привода устройства, с которого была загружена система (значение в диапазоне от 0 до 7). Метод, который используется для нахождения номера привода, меняется в зависимости от устройства; некоторые номера приводов передаются в R0, другие должны извлекаться из CSR. Номер привода можно сохранить в стеке или, если это необходимо, где-либо в памяти.
  3. Вызвать подпрограмму считывания начального загрузчика для считывания всего начального загрузчика.
  4. Поместить указатель подпрограммы считывания начального загрузчика в B¤READ.
  5. Поместить значение "B¤DNAM" в RADIX-50 в B¤DEVN.
  6. Записать номер привода устройства в B¤DEVU.
  7. Перейти к В¤BOOT в начальном загрузчике системы ФОДОС-2 для продолжения.

Начальный загрузчик программного обеспечения должен находиться в первичном драйвере сразу же ниже ячейки DDBOOT+664. (Ячейки с 664 по 776 содержат подпрограмму ошибок, созданную посредством запроса .DREND).

6.1.2.4. Подпрограмма считывания начального загрузчика

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

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

R0 содержит номер считываемого блока;

R1 содержит счётчик считываемых слов;

R2 содержит адрес буфера памяти, в котором будут записываться данные.

Подпрограмма считывания начального загрузчика может использовать все имеющиеся регистры и стек.

Подпрограмма считывания начального загрузчика должна быть непрерываемой подпрограммой при считывании тома в соответствии с параметрами, передаваемыми в R0-R2. При ошибке подпрограмма должна переходить к BIOERR. Если ошибок нет, она должна возвращаться по команде RTS PC с очищенным разрядом переноса.

Подпрограмма считывания начального загрузчика должна находиться в первичном драйвере с ячейки DDBOOT+210. (Ячейка 210 - самый младший адрес, с которого может начинаться подпрограмма считывания.)

6.1.2.5. Подпрограмма ошибок начального загрузчика

Эта подпрограмма начинается с ячейки BIOERR::. Код в этой подпрограмме полностью поставляется посредством запроса .DREND, который находится в конце первичного драйвера.

6.1.2.6. Запрос .DRBOT

Запрос .DRBOT используется для установки первичного драйвера. Он выдаёт также запрос .DREND для пометки конца драйвера, поэтому первичный драйвер не будет загружаться в память во время обычных операций. Вообще, код в первичном драйвере не должен быть позиционно независимым (PIC). Однако любое обращение не в PIC-кодах должно быть выражено относительно 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. Если устройство загружено аппаратным загрузчиком или вспомогательной программой не системы ФОДОС-2, первичный драйвер должен определить номер привода загруженного устройства и сохранить его в ячейке 4722 и в регистре R0.

6.1.3. DUP и процесс начальной загрузки

В этом пункте показано, как DUP выполняет три команды, относящиеся к начальной загрузке. Это следующие команды:

BOOT DDN:FILNAM
COPY/BOOT XXN:FILNAM DDM:
BOOT DDN:
6.1.3.1. Команда BOOT DDN:FILNAM.

Эта команда используется для загрузки программного обеспечения указанного файла монитора с указанного устройства. В командной строке DD - двухсимвольное имя устройства; N - номер привода этого устройства. И файл нового монитора, и файл нового драйвера устройства должны находиться на системном устройстве DD.

После подачи этой команды DUP проверяет, чтобы устройство было устройством произвольного доступа к данным. Затем она размещает файл монитора FILNAM.SYS на устройстве (тип файла .SYS является и обязательным, и типом файла по умолчанию). DUP считывает пять первых блоков, блоки с 0 по 4, в буфер памяти. Эти блоки содержат вторичный загрузчик монитора.

Предпоследнее слово в блоке 4 содержит префикс драйверов, связанных с этим монитором. DUP использует его для построения имени файла драйвера устройства, обычно - DD.SYS или DDX.SYS. DUP считывает блок 0 файла драйвера устройства в буфер памяти, используя содержимое ячеек 62 и 64 для поиска первичного драйвера и считывания его в буфер памяти.

Затем она копирует первичный драйвер в буфер у начала вторичного загрузчика, который также находится в буфере памяти. Она загружает информацию, показанную в табл. 9 для первичного драйвера и вторичного загрузчика.

Таблица 9

Смещение от начала буфера памяти

Содержимое

4722

Номер загружаемого привода

4724 4726

Имя загружаемого файла в RADIX-50

5000

Дата загрузки

5002-5004

Время загрузки

После этого DUP копирует первичный драйвер и вторичный загрузчик из буфера памяти в ячейки памяти с 0 по 5004. Затем она переходит к ячейке 1000, в начало вторичного загрузчика, чтобы он мог загрузить монитор и драйвер системного устройства в память.

Рис. 12 иллюстрирует эту процедуру.

Рис. 12

6.1.3.2. Команда COPY/BOOT XXN:FILNAMDDM:

Эта команда используется для копирования вторичного загрузчика из файла монитора на устройстве XX в блоки 2, 3, 4 и 5 устройства DD. В командной строке XX - двухсимвольное имя устройства, на котором находится файл монитора; N - номер его привода; DD - двухсимвольное имя устройства, которое должно получить начальный загрузчик; М номер его привода.

После подачи этой команды DUP проверяет, чтобы устройство было устройством произвольного доступа к данным. Затем она осуществляет поиск файла монитора FILNAM.SYS на устройстве XXN:. Она считывает пять первых блоков файла монитора, блоки с 0 по 4, в буфер памяти. Эти блоки содержат вторичный загрузчик монитора.

DUP далее размещает соответствующий файл драйвера на устройстве DD:. Затем она считывает блок 0 файла драйвера устройства в буфер памяти, используя содержимое ячеек 62 и 64 для поиска первичного драйвера и считывания его в буфер памяти.

Драйвер системного устройства DD должен находиться на устройстве DD: перед тем, как будет производиться копирование начального загрузчика на устройство. DUP загружает два слова в RADIX-50 для имени файла в ячейки 4724 и 4726 буфера памяти. Затем DUP копирует первичный драйвер в блок 0 устройства DD:. И, наконец, она записывает вторичный загрузчик в блоки со 2-го по 5-ый устройства DD:.

Рис. 13 иллюстрирует эту процедуру.

Рис. 13

6.1.3.3. Команда BOOT DDN:

Эта команда используется для загрузки программного обеспечения указанного устройства, которое уже содержит вторичный загрузчик указанного монитора в блоках со 2-го по 5-ый (помещённый туда по команде монитора COPY/ BOOT). В командной строке DD - двухсимвольное имя загружаемого устройства; N - номер его привода. Файл нового монитора и драйвер нового устройства должны находиться на устройстве DDN:.

После подачи команды DUP проверяет, чтобы устройство DD: было устройством произвольного доступа к данным. Затем она считывает блоки 2, 3, 4, 5 в буфер памяти. Эти блока содержат вторичный загрузчик монитора. Первичный драйвер уже находится в ячейках с 0 по 776.

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

Затем DUP извлекает имя файла монитора из ячеек 724 и 726 блока 4 и производит поиск файла монитора на устройстве, чтобы убедиться в том, что он действительно там существует.

Далее DUP загружает информацию, приведённую в табл. 10 для первичного драйвера и вторичного загрузчика.

Таблица 10

Смещение от начала буфера памяти

Содержимое

4722

Номер загружаемого привода

5000

Дата загрузки

5002-5004

Время загрузки

DUP копирует первичный драйвер и вторичный загрузчик из устройства в ячейки памяти с 0 по 4777. Затем она переходит к ячейке 1000, в начало вторичного загрузчика, точку входа которого указывает DUP, чтобы вторичный загрузчик мог загрузить монитор и драйвер системного устройства в память.

Рис. 14 иллюстрирует эту процедуру.

Рис. 14

6.2. Как транслировать, связывать и устанавливать драйвер устройства

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

6.2.1. Транслирование драйвера устройства

Исходный файл драйвера может быть назван DD.MAC, где DD - двухсимвольное имя устройства. Для наглядности можно использовать переключатель АССЕМБЛЕРа /SHOW:MEB, который позволяет напечатать макрорасширение запросов .DRBEG и .DRAST.

Для транслирования драйвера в системах SJ и FB используется следующая команда:

MACRO/CROSSREFERENCE/SHOW:MEB/LIST SYCND+DD/OBJECT

Для транслирования драйвера в ХМ-системе используется следующая команда:

 MACRO/CROSSREFERENCE/SHOW:MEB/LIST ХМ+SYCND+DD/OBJECT:DDX

где

ХМ

- исходный файл в системе ФОДОС-2, который показывает наличие в системе средства расширенной памяти, поддерживающего среду FB;

 

SYCND

- условный файл системы; если система создана в процессе генерации, необходимо использовать этот файл, чтобы при транслировании драйвера условия драйвера и условия монитора соответствовали друг другу, и драйвер мог работать в этой среде; можно опустить этот файл, если транслируется драйвер устройства, которое будет выполняться с дистрибутивным монитором ФОДОС-2, или использовать файл SYCND.DIS, который является частью дистрибутивного пакета.

6.2.2. Связывание драйвера устройства

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

LINK/MAP/EXECUTE: DD SYS DD

Для связывания драйвера в ХМ-системе используется следующая команда:

LINK/MAP/EXECUTE:DDX.SYS DDX

6.2.3. Установка драйвера устройства

Перед использованием нового драйвера необходимо добавить информацию о нем в таблицу устройств монитора. Процедура добавления нового устройства называется установкой. В системе ФОДОС-2 имеются две отдельные подпрограммы, которые могут установить драйвер устройства: начальный загрузчик и команда монитора INSTALL. Обе подпрограммы требуют, чтобы в системе имелась аппаратура устройства до начала установки драйвера этого устройства. (В п. 6.2.3.6 описывается способ обхода этого ограничения, если необходимо установить драйвер для несуществующего устройства.)

6.2.3.1. Использование начального загрузчика для автоматической установки драйверов

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

Затруднения в этой процедуре возникают тогда, когда имеется больше файлов драйверов, чем позиций устройства. Дистрибутивный монитор сохраняет одну позицию для каждого устройства, поддерживаемого в системе ФОДОС-2. Монитор, созданный в процессе генерации системы, сохраняет одну позицию для каждого запрашиваемого пользователем устройства. Кроме того, он гарантирует ряд запрошенных пользователем пустых позиций. Считается, что позиция сохраняется для определённого устройства, если таблица монитора ¤PNAME имеет вход для этого устройства. Позиция пуста, если таблица ¤PNAME имеет нулевое слово.

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

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

Рис. 15 показывает алгоритм, который использует начальный загрузчик для установки драйвера устройства.

Рис. 15

Как видно из рис. 15, драйверы с входами в таблице ¤PNAME имеют высший приоритет во время загрузки. Если файл драйвера находится на системном устройстве, и аппаратура имеется в наличии, начальный загрузчик всегда устанавливает драйвер. При самостоятельном написании драйвера у пользователя не должно возникать затруднений при его установке в системе ФОДОС-2, так как можно рассчитывать при установке драйвера на Начальный загрузчик, в случае, если драйвер находится несистемном устройстве, и имеется пустая позиция в таблицах монитора. Если в системе нет свободной позиции, то можно просто создать их (одну или более) путём записи файла Драйвера устройства на системное устройство и перезагрузки системы. Можно также использовать команду монитора INSTALL (см. п. 6.2.3.2) для установки нового драйвера без перезагрузки системы. (Этот драйвер может быть одним из таких, которые начальный загрузчик не может установить из-за отсутствия свободных позиций, или это вновь созданный и скопированный на системное устройство.) Или, если система создана в процессе генерации, можно использовать запрос DEV (см. п. 6.2.3.3) для резервирования позиции для драйвера нового устройства и указать ему приоритет для установки во время загрузки.

Рис. 16 кратко излагает способы, которыми можно установить драйвер нового устройства

Рис. 16

6.2.3.2. Использование команды INSTALL для установки драйверов вручную

Перед использованием команды INSTALL необходимо использовать команду SHOW для определения наличия пустых позиций устройств в системе. Если их нет, необходимо использовать команду REMOVE для удаления ненужного устройства и освобождения места для нового устройства, которое добавляется по команде INSTALL. (Форматы этих команд см. в [2].)

Если позиция устройства уже имеется, устройство будет установлено автоматически во время следующей загрузки системы. Если использовать команды REMOVE и INSTALL для добавления нового устройства к системе, то необходимо подавать эти команды каждый раз после каждой загрузки. Для автоматической установки нового устройства во время каждой загрузки, необходимо поместить команды REMOVE и INSTALL в косвенный файл запуска системы. Это избавляет пользователя от печати этих команд и даёт видимость, что устройство постоянно установлено

6.2.3.3. Использование запроса DEV для помощи автоматической установки

Если система создана в процессе генераций, можно связать исходный файл для добавления нового устройства к таблице ¤PNAME, отдавая этим самым предпочтение автоматической установке драйвера. Редактируемый файл - это файл SYSTBL.MAC - один из файлов, которые транслируются при создании файла монитора.

Необходимо использовать запрос DEV в файле SYSTBL.MAC, чтобы устройство было постоянно добавлено к системе.

Формат запроса DEV следующий:

DEV NAME,S

где

NАМЕ

- двухсимвольное имя устройства;

 

S

- слово состояния устройства (можно не указывать этот аргумент).

Пример:

DEV     RK      ; устанавливает диск
DEV     LP      ; устанавливает построчно-печатающее
                ; устройство
DEV     MT      ; устанавливает магнитную ленту

В этом примере показаны случаи использования запроса DEV в файле SYSTBL.MAC.

После редактирования файла SYSTBL.MAC и добавления запроса DEV для нового устройства, необходимо оттранслировать его, используя следующую команду:

MACRO/OBJECT:ТВХХ XX+SYCND+SYSTBL

где

XX

- это SJ, FB или ХМ;

 

SJ.MAC, FB.MAC и ХМ.МАС

- файлы ФОДОС-2, которые определяют параметры условной трансляции; эти параметры показывают, разрешена или нет, основная/фоновая обработка; ХМ.МАС показывает также, что имеется поддержка расширенной памяти.

Как только трансляция закончится, необходимо отредактировать объектные файлы для создания нового монитора.

6.2.3.4. Установка устройств, аппаратура которых имеется в наличии

Обе подпрограммы ФОДОС-2, и начальный загрузчик, и команда монитора INSTALL, могут устанавливать драйверы только тех устройств, аппаратура которых имеется в наличии в данной конфигурации системы. Подпрограммы находят ячейку 176 в блоке 0 драйвера устройства и проверяют её содержимое (обычно это регистр состояния устройства, CSR). Если аппаратура устройства отсутствует, происходит таймаут канала, вызывая прерывание по вектору 4, из поля подпрограммы установки. В результате, ни команда INSTALL, ни подпрограмма начального загрузчика не будут устанавливать драйвер устройства. К тому же, команда INSTALL печатает сообщение:

?KMON-F-ILLEGAL DEVICE INSTALLATION

Подпрограммы установки предполагают, что аппаратура устройства имеется в наличии, если CSR отвечает на запрос канала. Однако этой простой проверки недостаточно в отдельных случаях для определения, аппаратура какого устройства имеется в наличии. Например, некоторым устройствам назначаются одинаковые адреса в странице ввода-вывода для одного или большего числа их регистров состояния. Если система ФОДОС-2 проверила адрес совместно используемой страницы ввода-вывода, то ещё неизвестно, какое из двух устройств имеется в наличии и какой драйвер необходимо устанавливать. Устройства гибких дисков обеих плотностей записи данных, например, имеют одинаковый адрес канала и одинаковый номер регистров состояний в странице ввода-вывода. Когда система пытается установить драйвер DX, она должна, определить наличие аппаратуры и выяснить, является ли это устройство устройством гибких дисков или нет. Ясно, что система не должна устанавливать драйвер DX, если имеется Аппаратура устройства гибких дисков с двойной плотностью записи.

Существует несколько отличий между двумя или большим числом устройств, которые следуют из регистров страницы ввода-вывода. Каждый драйвер одного из трудноопределимых устройств может проверить это различие и информировать подпрограмму установки ФОДОС-2, устанавливать рассматриваемый в данный момент драйвер устройства или нет.

6.2.3.5. Подпрограмма сравнения установки

Все драйверы ФОДОС-2 для устройств с совместно используемыми адресами страницы ввода-вывода содержат подпрограмму сравнения установки, чтобы различать, аппаратура какого устройства имеется в наличии, и чтобы разрешить или запретить установку данного драйвера. При написании драйвера устройства можно включить в него свою подпрограмму сравнения установки.

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

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

Затем подпрограммы сравнения установки определяют, какое устройство имеется в наличии, основываясь на результатах проверки одного из вышеуказанных условий. Как только определение будет сделано, подпрограмма сравнения установки сигнализирует подпрограмме установки ФОДОС-2, нужно устанавливать данный драйвер или нет, а потом возвращается в монитор с установленным разрядом переноса для предотвращения установки и с очищенным разрядом переноса для разрешения установки.

Подпрограмма сравнения установки может использовать регистры R0 и R1; остальные регистры должны быть сохранены и восстановлены.

6.2.3.5.1. Точка входа подпрограммы сравнения установки

Подпрограмма сравнения установки должна начинаться с ячейки 200 блока 0 драйвера и не должна размещаться выше ячейки 356. Ячейка 200 - это точка входа, которую начальный загрузчик и команда монитора INSTALL используют для установки устройства данных. Ячейка 202 - это точка входа, которую начальный загрузчик использует для установки системного устройства. Команда монитора INSTALL никогда не использует эту ячейку. Если всё равно, как устанавливается драйвер, как устройство данных или как системное устройство, необходимо поместить команду NOP в ячейку 200. Если драйвер должен быть установлен как драйвер системного устройства, необходимо использовать следующие команды для предотвращения его установки любыми другими способами:

        .=200                  ; несистемная точка входа
        BR    ERROR            ; переход к подпрограмме оши-
        .                      ; бок
        .
        .
ERROR:  SEC                    ; установка С-разряда для за-
                               ; прещения установки
        RTS     PC             ; возврат
6.2.3.5.2. Если аппаратура данного драйвера имеет дополнительный регистр

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

        MOV     176,R0       ; устанавливает совместно исполь-
                             ; зуемый CSR
        TST     N(R0)        ; проверяет дополнительный регистр
                             ; со смещением N от совместно ис-
                             ; пользуемого CSR
        RTS     PC           ; возврат (с установленным C-разря-
                             ; дом в случае недопустимого уст-
                             ; ройства)

Эта подпрограмма проверяет дополнительный регистр. Если это не описанное устройство, канал прерывается, вызывается прерывание по вектору 4, и устанавливается разряд переноса. Подпрограмма сравнения установки возвращается в монитор с установленным разрядом переноса, показывая, что аппаратуры соответствующего устройства нет в наличии, и драйвер не будет установлен.

С другой стороны, если дополнительный регистр реагирует на проверку, команда TST возвращается с очищенным разрядом переноса, означая, что аппаратура соответствующего устройства имеется в наличии и что ФОДОС-2 должен установить данный драйвер.

6.2.3.5.3. Если аппаратура для этого драйвера имеет несколько регистров

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

Пример:

        MOV     176,R0         ; устанавливает совместно ис-
                               ; пользуемый CSR
        TST     N(R0)          ; проверяет дополнительные
                               ; регистры со смещением N от
                               ; 176. Есть устройство?
        BCC                  ; да, другое устройство
        CLC                    ; нет, очищает С-разряд
        RTS     PC             ; устанавливает данный драй-
                               ; вер
:     SEC                    ; устанавливает С-разряд
        RTS     PC             ; не устанавливает данный
                               ; драйвер

В этом примере подпрограмма сравнения установки проверяет наличие дополнительного регистра для другого устройства. Если его нет, система ФОДОС-2 устанавливает данный драйвер.

6.2.3.5.4. Если имеется разряд или байт идентификации

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

В ФОДОС-2, например, устройства DX: и DY: совместно используют CSR. Разряд 11, названный CSRX02, очищается, если имеется аппаратура устройства DX:, и устанавливается - если DY:.

Пример:

        .ASECT
        .=200                  ; начало подпрограммы срав-
                               ; нения
        NOP                    ; производит проверку для сис-
                               ; темного или несистемного ;устройства
        BIT     #CSRX02,@176   ; это устройство DY:?
        BEQ                  ; нет, это DX:. Не устанавли-
                               ; вать драйвер DY
        TST     (PC)+          ; очищает С-разряд, переходит
                               ; к команде SEC. Имеется DY:,
                               ; устанавливать драйвер DY
:     SEC                    ; устанавливает С-разряд, не
                               ; устанавливает драйвер DY
        RTS     PC             ; возврат в монитор

В приведённом примере драйвер DY должен устанавливаться только в том случае, если имеется в наличии аппаратура устройства DY:.

6.2.3.5.5. Если одно устройство имеет разряд считывания/записи

Если одно из устройств, совместно использующих адрес страницы ввода-вывода, имеет разряд считывания/записи в CSR, где другое устройство имеет только разряд считывания, подпрограмма сравнения может определить аппаратуру, имеющуюся в наличии, посредством использования процедуры проверки разряда и разрешения или запрета установки данного драйвера на основании результатов проверки. Подпрограмма должна считывать разряд, изменять его и записывать обратно в CSR. Затем подпрограмма должна снова считывать разряд. Если значение разряда изменилось, имеется в наличии устройство с регистром считывания/записи. Если значение осталось неизменным, имеется в наличии устройство с регистром только считывания. Подпрограмма может установить соответственно разряд переноса и вернуться в монитор. Если разряд переноса установлен, ФОДОС-2 не устанавливает этот драйвер. Если разряд переноса очищен, ФОДОС-2 устанавливает данный драйвер.

6.2.3.5.6. Игнорирование аппаратных ограничений

Если по какой-то причине необходимо установить драйвер устройства, аппаратуры которого нет в наличии в конфигурации данной системы, можно обойти начальный загрузчик и подпрограмму INSTALL посредством выполнения SIPP. Необходимо очистить ячейки 176 и 200 в блоке 0 файла драйвера, затем можно использовать команду INSTALL или перезагрузить систему для установки драйвера устройства.

6.3. Содержимое системного драйвера

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

Таблица 11

Ячейка

Содержимое

0

 

52:

Размер драйвера в байтах (DDEND-DDSTRT)

54:

Размер устройства в блоках (DDSIZE)

56:

Слово состояния устройства (DDSTS)

60:

Слово параметров SYSGEN

62:

Начальный адрес первичного драйвера (из .DRBOT)

64:

Размер первичного драйвера в байтах (из .DRBOT)

66:

Смещение от начала первичного драйвера до начала подпрограммы считывания начального загрузчика (из .DRBOT)

70:

Смещение к области данных драйвера

110:

Новое имя в RADIX-50

112:

Номер версии; -1 для завершения списка

176:

Адрес CSR (DD¤CSR)

200:

Начало кода установки устройства данных, если другое (или 0)

202:

Начало кода установки системного устройства, если другое

356:

Верхняя граница кода установки

360:

Резервируется для памяти, использующей разрядовые комбинации (360-377)

400:

Начало кода параметров SET (из .DRSET)

776:

Верхняя граница кода параметров SET

1000:

Адрес вектора (DD¤VEC) (из .DRBEG)

1002:

DDINT-. (Из .DRBEG)

1004:

Новое слово состояния процессора (PSW) (из .DRBEG)

1006:

DDLQE (из DRBEG)

1010:

DDCQE (из .DRBEG)

1012:

Точка входа драйвера

N

Точка входа по преждевременному прерыванию (из .DRAST; может быть более 1777)

N+2

Точка входа по прерыванию (из .DRAST; может быть более 1777)

1776:

Верхняя граница области, изменяемой кодом SET DD¤END = . (Из .DREND; конец драйвера устройства)

DD¤END:

¤RLPTR: (из .DREND)

¤MPPTR: (из .DREND)

¤GTBYT: (из .DREND)

¤PTBYT: (из .DREND)

¤PTWRD: (из .DREND)

¤ELPTR: (из .DREND)

¤TIMIT: (из .DREND)

¤INPTR: (из .DREND)

¤FKPTR: (из .DREND)

DDEND = . (из .DREND)

DDEND:

 

DDBOOT:

NOP начало первичного загрузчика (из .DRBOT)

BR вход метки ENTRY из .DRBOT

ENTRY-14

020                                 (из .DRBOT)1)

ENTRY-12

Тип контроллера          (из .DRBOT)

ENTRY-10

020                                 (из .DRBOT)2)

ENTRY-6

Контрольная сумма     (из .DRBOT)3)

ENTRY-4

0                                     (из .DRBOT)

ENTRY-2

Тип гибкого диска       (из .DRBOT)4)

ENTRY:

BR .+2 или BMI .+2     (из .DRBOT)5)

Начало подпрограммы считывания первичного загрузчика

662:

Верхняя граница первичного загрузчика

664:

Начало кода ошибок начального загрузчика

776:

Конец кода ошибок начального загрузчика

ПРИМЕЧАНИЯ:

1) Этот байт показывает тип ЦП. Значение 20 определяет процессор мини-ЭВМ.

2) Этот байт показывает тип файловой структуры диска. Значение 20 определяет файловую структуру ФОДОС-2.

3) Байт контрольной суммы - контрольная сумма предшествующих трех байтов. Она вычисляется как дополнение к сумме байтов.

4) Этот байт содержит номер идентификации загрузчика в разрядах 0-6 и признак одинарной или двойной плотности записи на гибких дисках в разряде 7. Значение может быть:

разряд 7=0 гибкий диск с одинарной плотностью записи

разряд 7=1 гибкий диск с двойной плотностью записи

5) Рекомендуется, чтобы адрес подпрограммы считывания первичного загрузчика ENTRY был расположен выше ячейки 120 в блоке начального загрузчика. Это поможет избежать конфликта с вектором и системной областью монитора при загрузке монитора.

7. ПРОГРАММИРОВАНИЕ СПЕЦИАЛЬНЫХ УСТРОЙСТВ

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

  1. Драйвер магнитной ленты: MT.
  2. Драйверы гибких дисков: DX и DY.
  3. Драйвер перфоленточного устройства ввода-вывода: PC.
  4. Драйвер системного терминала: ТТ.
  5. Драйвер фиктивного устройства: NL.
  6. Драйвер расширенной памяти: VM.
  7. Драйвер логического диска: LD.

7.1. Драйвер магнитной ленты (MT)

Магнитная лента - это устройство файловой структуры с последовательным доступом к данным. Драйвер магнитной ленты системы ФОДОС-2 поддерживает файловую структуру, совместимую с метками магнитной ленты и форматом ленты. Формат ленты предоставляет пользователю возможности доступа к контроллеру ленты, не принимая во внимание специфику устройства.

В системе ФОДОС-2 имеется два типа драйверов магнитной ленты: аппаратный драйвер (MTHD.SYS) и драйвер файловой структуры (MT.SYS). Команда SET изменяет характеристики драйверов: количество дорожек, плотность записи и соответствие привода ленты. Эти команды применимы ко всем приводам определённого контроллера.

Драйвер MT поддерживает до 8 приводов ленты на одном контроллере. Рекомендуется использовать драйвер файловой структуры (если специальные обстоятельства не заставят использовать аппаратный драйвер), таким образом, только драйверы файловой структуры могут взаимодействовать с вспомогательными программами системы ФОДОС-2. В последующих пунктах описываются эти драйверы.

В этом разделе используется несколько присущих магнитной ленте сокращений: ВОТ - для начала ленты; EOT - для физического конца ленты; LEOT - для логического конца ленты и EOF - для конца файла. LEOT состоит из метки, EOF1, которая включает один маркер ленты, за которым следуют два маркера ленты.

7.1.1. Драйвер магнитной ленты файловой структуры

Драйвер магнитной ленты файловой структуры содержит аппаратный драйвер, описанный в п. 7.1.2, и модули файловой структуры. Модуль файловой структуры, который предназначен для работы с любым драйвером магнитной ленты, позволяет драйверу принимать запросы с файловой структурой. В драйвере магнитной ленты файловой структуры можно использовать аппаратные команды. Драйвер магнитной ленты файловой структуры называется MT.SYS. Поставляемые версии этого драйвера поддерживают приводы ленты 0 и 1. Во время генерации системы можно добавить поддержку для большего числа приводов (2-7).

Лента, содержащая два файла, имеет следующий формат:

VOL1 HDR1*дaнные*EOF1*HDR1*данные*EOF1***

VOL1, HDR1, EOF являются метками ленты. Конструкция "*"  является маркером ленты.

7.1.1.1. Поиск номера файла

Драйвер файловой структуры осуществляет поиск файлов на ленте, взяв за основу последовательный номер файла на ленте.

  1. Когда последовательный номер указанного файла больше номера файла, на котором позиционирована лента, драйвер перематывает ленту вперёд. Например, если лента в данный момент позиционирована у файла номер 1, а желаемый номер - 2, лента перематывается вперёд от маркера ленты после файла номер 1 к маркеру ленты в начале файла номер 2.
  2. Когда последовательный номер указанного файла меньше, чем номер файла, на котором позиционирована лента, драйвер оптимизирует время поиска посредством продвижения ленты вперёд или назад, в зависимости от местонахождения файла. Практически, драйвер почти всегда перематывает ленту в начало, а затем осуществляет поиск. Например, пусть номер файла, на котором позиционирована лента, -2, а нужный файл имеет последовательный номер - 1. Лента перематывается к началу тома. Затем она перематывается вперёд к маркеру ленты у начала файла номер 1. Для другого примера допустим, что номер файла, на котором позиционирована лента, равен 9 и последовательный номер указанного файла равен 6. Лента перематывается к началу тома и производит поиск в прямом направлении.

Если удалить драйвер посредством команды UNLOAD или программного запроса .RELEAZE, позиция файла теряется. В этой ситуации лента перематывается назад до тех пор, пока аппаратный драйвер не найдёт ВОТ или метку, от которой он может установить позицию ленты.

7.1.1.2. Поиск по имени файла

Драйвер файловой структуры может отыскивать файлы на ленте, взяв за основу имя файла. Подпрограмма для поиска имён файлов использует алгоритм, который позволяет драйверу узнавать имена и типы файлов из других операционных систем. Драйвер использует поле идентификации файла, транслируя содержимое в узнаваемое имя файла. Это имя файла согласуется с именем файла, записанным в формате RADIX-50. Формат следующий:

FILNAM.TYP

где

FILNAM

- допустимое в системе ФОДОС-2 имя файла, состоящее из шести символов (недостающее число символов в имени файла справа заполняется пробелами, если необходимо);

 

TYP

- тип файла, состоящий из трех символов (недостающее число символов в типе файла справа заполняется пробелами, если необходимо).

Алгоритм, который использует драйвер, позволяет системе ФОДОС-2 считывать и использовать ленты, записанные под управлением ранних версий системы.

7.1.1.3. Программные запросы

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

7.1.1.3.1. Программный запрос .ENTER

Программный запрос .ENTER записывает метку заголовка файла HDR1 и маркер ленты на ленту, после чего лента позиционируется после маркера ленты. Запрос инициализирует несколько внутренних таблиц, включая элементы для последнего записанного блока и текущего номера блока. (Последний блок или файл на ленте всегда считается только что записанным). Информация для внутренних таблиц и элементов для последнего записанного блока верна, если запрос .SPFUN выполняется по этому каналу. Файлы, открытые запросом .ENTER, не имеют выполняемых в них специальных функций, кроме того случая, когда должен записываться блок нестандартного размера (который не равен 256 словам). Для записи нестандартного блока необходимо открыть файл запросом .ENTER; затем выдать запрос записи .SPFUN. После завершения операции необходимо закрыть файл запросом .CLOSE. Если должен выполняться просмотр файла, необходимо открыть ленту запросом .LOOKUP нефайловой структуры. Табл. 12 показывает возможные значения аргумента SEQNUM для запросов .ENTER.

Программный запрос .ENTER имеет следующий формат:

.ENTER AREA,CHAN,DBLK,SEQNUM
Таблица 12

Аргумент SEQNUM

Имя файла

Предпринятое действие

Положение ленты

Больше 0

Задано

Устанавливается последовательный номер файла и выполняется запрос .ENTER

Файл найден: готова к записи.

Файл не найден: у логического конца ленты LEOT (LEOT отличается от физического конца ленты)

0

Задано

Лента перематывается, на ней ищется имя указанного файла. Если файл найден, выдаётся сообщение об ошибке, если нет, указанный файл записывается

Файл найден: перед файлом. Файл не найден: готова к записи

-1

Задано

Лента позиционируется у LEOT, и файл записывается

Готова к записи

-2

Задано

Лента перематывается, на ней ищется указанное имя файла. Указанный файл записывается на место найденного файла или на место LEOT (что встретится раньше)

Готова к записи

0

Не задано

Выполняется запрос .LOOKUP нефайловой структуры

Лента перемотана

Запрос .ENTER возвращает ошибки, показанные в табл. 13.

Таблица 13

Код байта 52

Значение

0

Канал используется

1

Устройство заполнено. Во время записи HDR1 был обнаружен EOT. Лента позиционируется у первого маркера ленты, который следует за последней меткой EOF1 на ленте

2

Устройство уже используется. Магнитная лента имеет открытый файл на указанном приводе

3

Файл существует, его удаление невозможно

4

Файл с указанным номером не найден. Лента позиционируется так же, как и в случае, когда устройство заполнено

5

Ошибка недопустимого аргумента. Аргумент SEQNUM не должен принимать значения в диапазоне от -3 до -32767 или не указано имя файла для .ENTER

Запрос .ENTER выдаёт невосстановимую ошибку справочника во время записи файла.

7.1.1.3.2. Программный запрос .LOOKUP

Программный запрос .LOOKUP вызывает поиск и считывание указанной метки HDR1. После этого запроса лента позиционируется перед первым блоком данных файла. Табл. 14 показывает значение последовательного номера файла для запроса .LOOKUP, который имеет следующий формат:

.LOOKUP AREA,CHAN,DBLK,SEQNUM

Описание аргументов см. в [1].

Таблица 14

Аргумент SEQNUM

Имя файла

Предпринятое действие

Положение ленты

0

Не задано

Выполняется .LOOKUP нефайловой структуры

Перематывается

-1

Не задано

Выполняется .LOOKUP нефайловой структуры

Не перематывается

Больше 0

Не задано

Выполняется .LOOKUP файловой структуры для файла с указанным номером

Файл найден: готова считывать первый блок данных.

Файл не найден: на месте LEOT

0

Задано

Лента перематывается в начало, затем имя файла используется для выполнения .LOOKUP файловой структуры

Файл найден: готова считывать первый блок данных. Файл не найден: на месте LEOT

-1

Задано

Выполняется .LOOKUP файловой структуры для файла с указанным именем. Лента не перематывается

Файл найден: готова считывать первый блок данных. Файл не найден: на месте LEOT

Больше 0

Задано

Лента позиционируется у файла с указанным номером, выполняется запрос .LOOKUP файловой структуры. Если файл не найден, то выдаётся сообщение об ошибке

Файл найден: готова считывать первый блок данных. Файл не найден: на месте LEOT

Если канал открыт посредством запросов .LOOKUP нефайловой структуры (имя файла не задано, последовательный номер файла 0 или -1), .READ, .READC, .READW, необходимо использовать счётчик слов, равный размеру физического блока на ленте; запросы .WRITE, .WRITC и .WRITW используют счётчик слов для определения размера блока на ленте. Это условное обозначение используется вместо использования в виде размера блока по умолчанию (512 байт) и выполнения блокировки и деблокировки. Этот запрос почти идентичен считыванию или записи по запросу .SPFUN, который не сообщает об ошибках (BLK=0). Блок ошибки и блок состояния не должны попадать в область свопинга USR.

Запрос .LOOKUP возвращает ошибки, показанные в табл. 15.

Таблица 15

Код байта 52

Значение

0

Канал используется

1

Файл не найден. Лента позиционируется после первого маркера ленты, следующего за последним EOF1 на ленте

2

Устройство используется. Магнитная лента уже имеет открытый файл

5

Ошибка недопустимого аргумента. Аргумент SEQNUM принимает значения в диапазоне от -2 до -32767. Запрос .LOOKUP для аппаратного драйвера должен иметь положительное значение аргумента SEQNUM

Запрос .LOOKUP выдаёт невосстановимую ошибку справочника таким же образом, как и запрос .ENTER.

7.1.1.3.3. Программные запросы .READX

Термин .READX/.WRITX относится к следующей группе программных запросов: .READ, .READC, .READW, .WRITE, .WRITC, .WRITW.

Запросы .READX считывают данные с магнитной ленты блоками по 512 байтов каждый. Эта группа запросов описывается здесь для файлов, открытых запросами .ENTER и .LOOKUP файловой структуры. В дополнение к этому описанию имеются описания .READX и .WRITX, соответствующие запросам .LOOKUP нефайловой структуры (см. п.п. 7.1.2.11 и 7.1.2.12).

Если запрос выдаётся менее чем для 512 байтов, драйвер считывает указанное число байтов. Если запрос выдан более чем для 512 байтов, драйвер выполняет запрос с многочисленными 512-байтовыми запросами (последний запрос может быть менее, чем для 512 байтов). Запросы .READX действительны в файле, открытом посредством запроса .LOOKUP. Они также действительны в файле, открытом посредством запроса .ENTER, предусмотренного для того, чтобы запрошенный номер блока не превышал номер последнего записанного блока (возвращается код 0). Если считывается маркер ленты, подпрограмма повторно позиционирует ленту так, что следующий запрос опять вызывает считывание маркера ленты. Когда запрос .CLOSE выдаётся для файла, открытого запросом .ENTER, лента не позиционируется после последнего записанного блока. Это приводит к потере информации, когда программа выдаёт запрос считывания для блока, записанного последним, и не может повторно сосчитать последний блок, тем самым позиционируя ленту в конце данных.

Основные требования для номеров блока:

  1. .READX: когда .LOOKUP используется (для поиска файла) с этим запросом, драйвер пытается позиционировать ленту у блока с указанным номером. Когда это невозможно, выдаётся код ошибки 0 (код EOF), и лента позиционируется после последнего блока в файле.
  2. .WRITEX и .READX: во введённом файле выполняется проверка для определения, является ли запрошенный блок последним блоком в файле. Если является, лента не перематывается, и выдаётся код ошибки 0.

Формат запроса .READX следующий:

.READX AREA,CHAN,BUF,WCNT,BLK[,CRTN]

В табл. 16 приведены ошибки, которые возвращают запросы .READX.

Таблица 16

Код байта 52

Значение

0

Попытка считывания после маркера ленты или образован блок, который слишком велик

1

В канале возникла невосстановимая ошибка

2

Канал не открыт

7.1.1.3.4. Программные запросы .WRITX

Программные запросы .WRITX записывают данные на магнитную ленту в блоки по 512 байтов. Если запрос выдан для менее, чем 512 байтов, драйвер осуществляет запись 512-ти байтов, начиная с адреса буфера. Если запрос выдан для более, чем 512 байтов, драйвер выполняет многочисленные 512-байтовые передачи.

Запросы .WRITX действительны в файле, открытом посредством .ENTER или .LOOKUP нефайловой структуры.

Запросы .WRITX имеют следующий формат:

.WRITX AREA,CHAN,BUF,WCNT,BLKT[,CRTN]

В табл. 17 приведены ошибки, которые возвращают запросы .WRITX.

Таблица 17

Код байта 52

Значение

0

Конец ленты. Это значит, что данные не были записаны, но предыдущий блок действителен. Или же, если номер блока слишком велик

1

В канале возникла аппаратная ошибка

2

Канал не открыт

После операции записи остальная лента может оставаться неопределённой (см. рис. 17).

В примере 1 на рис. 17 блоки А, В и С записаны на ленту считывающей головкой, позиционированной в межзонном промежутке (МП) сразу же после блока С. Любая операция в прямом направлении на приводе ленты, исключая команды записи (т.е. запись, удаление или запись межзонного промежутка или запись маркера ленты), приводит к неопределённым результатам вследствие аппаратных ограничений.

В примере 2 на рис. 17 считывающая головка позиционирована у ВОТ после операции перемотки так, что операций считывания могут считывать блоки А, В и С. Считывающая головка позиционирована как показано в примере 3. Выполняется условие, и действуют все ограничения, рассмотренные в примере 1.

Рис. 17

7.1.1.3.5. Программные запросы .DELETE и .RENAME

Программные запросы .DELETE и .RENAME недопустимы в операциях с магнитной лентой, и любая попытка их выполнения приводит к коду недопустимой операции (код 2) , который возвращается в байт 52.

7.1.1.3.6. Программный запрос .CLOSE

Программный запрос .CLOSE действует тремя различными способами в зависимости от того, как был открыт файл.

  1. Когда файл открыт запросом .ENTER, файл закрывается записью маркера ленты, метки EOF1 и ещё более чем трех маркеров ленты. В этой операции лента позиционируется в левом положении, как раз перед вторым маркером ленты, у LEOT. Остаток ленты уже не считывается.
  2. Когда файл открыт запросом .LOOKUP файловой структуры, лента позиционируется после маркера ленты, за которым следует метка EOF1 для этого файла.
  3. Когда файл открыт запросом .LOOKUP нефайловой структуры, никакое действие не предпринимается, и канал освобождается.

Запрос .CLOSE имеет следующий формат:

.CLOSE CHAN

Этот запрос выдаёт невосстановимую ошибку справочника, если обнаружена неисправность. Ошибка может быть исправлена запросом .SERR.

7.1.1.3.7. Программный запрос .SPFUN .SPFUN

Программный запрос .SPFUN .SPFUN может выполнять асинхронные операции справочника без USR, что делает его полезным при длительных поисках на ленте. Особенно он полезен для программистов в системе мультизаданий, не имеющих возможности ожидать длительных поисков на ленте, которые могут возникнуть во время запросов .ENTER и .LOOKUP. Он также очень полезен для пользователей в мониторах FB и ХМ, которые не хотят блокировать USR. Этот запрос позволяет запрашивать .ENTER и .LOOKUP после того, как .LOOKUP нефайловой структуры присваивает канал драйверу магнитной ленты. Если этот запрос выдаётся для канала, который не был открыт запросом .LOOKUP нефайловой структуры, возникают непредсказуемые результаты. Запрос .SPFUN имеет следующий формат:

.SPFUN AREA,CHAN,#-20.,BUF, ,BLK

где

-20.

- код для асинхронного запроса справочника;

 

BUF

- адрес 7-словного блока с форматом, приведённым в табл. 18.

 

BLK

- адрес 4-словного блока состояния и ошибки, используемого для возвращения ошибок .LOOKUP и .ENTER, которые обычно передаются в байт 52; этим запросом используется только первое слово BLK; другие три слова сохраняются для дальнейшего использования и должны быть 0; когда первое слово BLK 0, информация об ошибке не возвращается; этот блок всегда должен отображаться, когда программа выполняется в среде расширенной памяти.

Таблица 18

Слово

Значение

0-2

Имя файла в RADIX-50

3

Один из следующих кодов:

3 - для .LOOKUP

4 - для .ENTER

4

Значение последовательного номера файла.

См. соответствующие разделы для .LOOKUP или .ENTER для завершения информации по интерпретации этого значения

5-6

Зарезервированы

Ниже приведён пример программирования.

.TITLE пример работы асинхронного справочника
        .ENABLE LC             ; печатать строчными бук-
                               ; вами
        .NLIST  ВЕХ            ; не запоминать текст
                               ;строки
.MCALL .LOOKUP,.SPFUN,.CLOSE,.PRINT,.EXIT
;определения
        ASYREQ = -20.          ; асинхронный запрос
        LOOKUP = 3             ; код LOOKUP для асин-
                               ; хронного запроса
        ENTER=  4              ; код ENTER для асин-
                               ; хронного запроса
        CHAN =  0              ; используется канал 0
        FNF =   1              ; 1=ошибка "Файл не
                               ; найден"
        FSN=    0              ; использовать 0 как по-
                               ; следовательный номер
                               ; файла
; пример допускает, что драйвер магнитной ленты загружен
START: .LOOKUP #AREA,#CHAN,#NFSBLK,#0
                               ; открыть канал для сле-
                               ; дующего запроса
        BCS     LOOKER         ; ветвление, если обнару-
                               ; жена ошибка
        .SPFUN  #AREA,#CHAN,#ASYREQ,#COMBLK,#ERRBLK
                               ; выполнять LOOKUP
        BCC     FILFND         ; ветвление, если файл
                               ; найден
        CMP     #FNF,ERRBLK    ; ошибка "Файл не най-
                               ; ден"?
        BEQ     NOTFND         ; ветвление, если да
        MOV     #ASYERR,R0     ; нет, другая ошибка
        BR      CLOSE
 
LOOKER: MOV     #LOOERR,R0     ; ошибка "NFS LOOKUP
                               ; FAILED"
        BR      CLOSE
FILFND: MOV     #OK,R0         ; сообщение об успешном
                               ; исходе
        BR      CLOSE
NOTFND: MOV     #FNFERR,R0     ; сообщение о том, что
                               ; файл не найден
CLOSE:  .PRINT                 ; печать ошибки, указы-
                               ; ваемой R0
        .CLOSE  #CHAN          ; очистка ...
        .EXIT                  ; возврат в монитор
; область данных
AREA:   .BLKW   5              ; блок аргументов ЕMT
NFSBLK: .RAD50  /MT/           ; использ-ся для открытия
        .WORD   0              ; магнитной ленты в слу-
        .WORD   0              ; чае нефайловой струк-
                               ; туры
        .WORD   0
COMBLK: .RAD50  /FILNAMTYP/    ; имя файла, который не-
                               ; обходимо найти
        .WORD   LOOKUP         ; код асинхронной опера-
                               ; ции для LOOKUP
        .WORD   FSN            ; последовательный но-
                               ; мер файла для LOOKUP
        .WORD   0,0            ; зарезервировано (долж-
                               ; но быть 0)
ERRBLK: .WORD   1              ; установка первого слова
        .WORD   0,0,0          ; не 0, так здесь возвра-
                               ; щаются ошибки
; сообщения
LOOERR: .ASCIZ  /NON-FILE-STRUCTURED LOOKUP FAILED/
OK:     .ASCIZ  /FILE FOUND, LOOKUP SUCCESSFUL/
FNFERR: .ASCIZ  /FILE NOT FOUND/
ASYERR: .ASCIZ  /ERROR IN ASYNCHRONOUS REQUEST/
        .EVEN
        .END START
SYMBOL TABLE
AREA      000130R ERRBLK    000170R LOOKUP    = 000003
ASYERR    000317R FILFND    000104R NFSBLK     000142R
ASYREQ    177754  FNF       000001  NOTFND     000112R
CHAN    = 000000  FNFERR    000300R OK         000242R
CLOSE     00011GR FSN     = 000000  START      000000R
COMBLK    000152R LOOERR    000200R ...V1     = 000003
ENTER   = 000004  LOOKER  = 00007GR ...V2     = 000027
 .ABS.    000000  000
          000354  001
ERRORS DETECTED: 0
VIRTUAL MEMORY USED: 9472 WORDS (37 PAGES)
DINAMIC MEMORY AVAILABLE FOR 72 PAGES
.SSM012/L:TTM=SSM102
7.1.1.4. Выдача вызовов аппаратного драйвера с модулем файловой структуры

Драйвер магнитной ленты предназначен для выполнения двух различных типов доступа: файлово-ориентированный доступ (в этом случае магнитная лента подобна диску; такой доступ делает магнитную ленту малозависимым устройством) и доступ к аппаратным командам, таким, как считывание, запись, пропуск и т.д.

Когда драйвер произвольной магнитной ленты использует файлово-ориентированные команды, он следит за последовательным номером файла, на котором позиционирована лента, т.е. он может оптимизировать движение ленты во время поиска файла. Когда драйвер выбирает данные из файла на магнитной ленте, используя запросы .READX/.WRITX, он фиксирует как номер текущего блока, так и номер последнего считанного блока. Аргумент номера блока может быть использован для моделирования устройства произвольного доступа к данным даже в файлах, открытых посредством .ENTER.

Два метода, описанные выше, могут быть объединены: т.е. можно использовать команды аппаратного драйвера в файле магнитной ленты. Из этого вытекают следующие выводы.

  1. Когда принимается первая команда аппаратного драйвера, информация о последовательном номере хранящегося файла и о его номере блока, описанная выше, удаляется и не восстанавливается до тех пор, пока не будет выполнена команда .CLOSE и другая команда открытия файла. .CLOSE перематывает ленту и, в случае, если файл был открыт посредством запроса .ENTER, записывает файл на ленту независимо от команд, выданных с момента открытия файла. Данная лента больше не удовлетворяет стандарту. Когда файл закрыт, драйвер магнитной ленты не может записать размер файла, потому что размер файла потерян для драйвера. На месте размера он записывает 0. Поле последовательного номера файла будет правильным.
  2. Исключение из правила, приведённого выше, возникает, когда необходимо открыть ленту с файловой структурой и записывать блоки данных, размер которых отличается от стандартного размера блока (512 байт), который используют запросы .WRITX. Драйвер магнитной ленты фиксирует число записанных блоков, метка EOF1 действительна до тех пор, пока не будут использованы другие команды, отличные от команды записи .SPFUN. Если используются другие команды, размер файла потерян.

Рекомендуется выдавать команды .SPFUN для файла магнитной ленты только в случае, описанном выше в пункте 2.

7.1.2. Аппаратные драйверы магнитной ленты

Аппаратные драйверы магнитной ленты принимают только аппаратные запросы. Они применимы в операциях ввода-вывода, где не существует файловой структуры. Любой запрос файловой структуры, который выдаётся для аппаратного драйвера, приводит к возникновению ошибки ввода-вывода в справочнике монитора. Аппаратный драйвер - это поднабор драйвера магнитной ленты файловой структуры. Аппаратные драйверы используются, если не нужна дополнительная поддержка файловой структуры. Хотя аппаратные драйверы являются частью дистрибутивного пакета, перед использованием их нужно переименовать. Можно использовать ряд команд монитора (см. табл. 19), которые заменяют драйвер файловой структуры MT на аппаратный драйвер MT.

Таблица 19

Команда

Действие

REMOVE MT

Удаляет драйвер файловой структуры

RENAME/SYS MT.SYS MTFS.SYS

Сохраняет драйвер файловой структуры

RENAME/SYS MTHD.SYS MT.SYS

Создаёт новый аппаратный драйвер

INSTALL MT

Устанавливает новый драйвер

Аппаратный драйвер выбирается посредством программных запросов .LOOKUP нефайловой структуры, запросов специальной функции .SPFUN и запросов .READ, .READC, .READW, .WRITE, .WRTIC, .WRITW и .CLOSE. Аппаратный драйвер может выполнять операции ввода-вывода в физических блоках, позиционировать ленту и освобождаться от ошибок.

7.1.2.1. Сообщения об исключениях

Те запросы .SPFUN, которые принимаются аппаратным драйвером, сообщают об окончании файла и условиях невосстановимой ошибки посредством байта 52 в области коммуникации системы. Кроме того, они используют аргумент, обычно используемый для номера блока в виде указателя 4-словного блока состояния и ошибки в порядке поступления указательной информации об исключительных условиях. Когда аргумент номера блока равен 0, эта указательная информация не возвращается. Содержимое этих слов является неопределённым, если нет исключительных условий и если разряд переноса не установлен. Блок определяется следующим образом: слова 1 и 2 содержат указательную информацию; слова 3 и 4 сохраняются для дальнейшего использования и должны быть 0. Поэтому в программе необходимо инициализировать слова 3 и 4 только один раз. Система модифицирует слова 1 и 2 только тогда, когда появляются сообщения об исключениях.

Указательная информация, возвращённая в первом слове для условия "Конец файла" (EOF), показана в табл. 20. (Разряд переноса установлен, байт 52 равен 0.)

Таблица 20

Первое слово восьмеричный код

Значение

1

Лента только перед EOF (маркер ленты обнаружен)

2

Лента только перед EOT (маркер ленты не обнаружен)

3

Лента перед EOT и EOF (маркер ленты обнаружен)

4

Лента перед ВОТ (маркер ленты не обнаружен)

Когда маркер ленты встречается во время операции пропуска, количество непропущенных блоков возвращается в слове 2. EOT, маркер ленты и ВОТ возвращаются аппаратным драйвером как EOF.

Указательная информация, возвращённая в первом слове и случае невосстановимой ошибки, показана в табл. 21. (Разряд переноса установлен, а байт 52 равен 1.)

Аппаратный драйвер выдаёт невосстановимую ошибку, если он получает запрос иной, чем .LOOKUP нефайловой структуры, .CLOSE или любой запрос .SPFUN, неопределённый для аппаратного драйвера.

Когда программа выполняется в ХМ-среде, блок состояния для сообщения об ошибках должен каждый раз отображаться.

Таблица 21

Первое слово восьмеричный код

Значение

0

Нет дополнительной информации (включает ошибку чётности и все другие ошибки, которые не перечислены ниже)

1

Нет привода ленты

2

Контроллер потерял позицию ленты.

Когда, происходит эта ошибка, необходимо перемотать или вернуть ленту к известной позиции

3

Была выбрана несуществующая память

4

Лента блокирована для записи

5

Последний считанный блок имел больше информации

6

Был считан короткий блок. Второе слово состояния содержит разность между числом запрошенных слов и числом считанных слов

7.1.2.2. Считывание и запись физических блоков

Аппаратный драйвер считывает и записывает блоки любого размера. Запросы для считывания и записи переменного количества слов осуществляются посредством двух кодов .SPFUN.

Запрос .SPFUN имеет следующий формат:

.SPFUN AREA,CHAN,#370,BUF,WCNT,BLK[,CRTN]

где

370

- код функции для операции считывания;

 

BLK

- адрес 4-словного блока состояния и ошибки, используемого для возврата исключительных условий;

 

CRTN

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

Этот запрос возвращает ошибки, показанные в табл. 22. Дополнительная указательная информация для этих ошибок возвращается в первых двух словах блока состояния аргумента BLK.

Таблица 22

Код байта 52

Код первого слова

Указательная информация

EOF

значение=0

1

Лента только перед EOF (маркер ленты обнаружен)

2

Лента только перед EOT (маркер ленты не обнаружен)

3

Лента перед EOF и EOT (маркер ленты обнаружен)

Невосстановимая ошибка

значение=2

0

Нет дополнительной информации (справочная документация для конкретного привода ленты для всевозможных ошибочных состояний)

1

Нет привода ленты

2

Контроллер потерял позицию ленты

3

Выбрана несуществующая память

4

Лента блокирована для записи

5

Последний считанный блок имел больше информации

6

Был считан короткий блок. Второе слово состояния содержит разность между числом запрошенных и числом считанных слов

Запрос .SPFUN для записи переменного количества слов в блок имеет формат:

.SPFUN AREA,CHAN,#371,BUF,WCNT,BLK[,CRTN]

где

371

- код функции для операции записи.

Этот запрос возвращает ошибки, показанные в табл. 23. Дополнительная указательная информация для этих ошибок возвращается в первых двух словах блока состояния.

Таблица 23

Код байта 52

Код первого слова

Указательная информация

EOF

значение=0

1

Лента только перед EOF (маркер ленты обнаружен)

2

Лента только перед EOT (маркер ленты не обнаружен)

3

Лента перед EOF и EOT (маркер ленты обнаружен)

Невосстановимая ошибка значение=1

0

Нет дополнительной информации (справочная документация для конкретного привода ленты для всевозможных ошибочных состояний)

1

Нет привода ленты

2

Контроллер потерял позицию ленты

3

Выбрана несуществующая память

4

Лента блокирована для записи

7.1.2.3. Перемотка ленты вперёд и назад

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

Команда для перемотки вперёд на блок имеет следующий формат:

.SPFUN AREA,CHAN,#376, ,WCNT,BLK[,CRTN]

где

376

- функциональный код для операции перемотки вперёд;

 

WCNT

- число блоков для последующей перемотки (не должно превышать 65534);

 

CRTN

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

Этот запрос возвращает ошибки, показанные в табл. 24. Дополнительная указательная информация для этих ошибок возвращается в двух первых словах блока состояния.

Таблица 24

Код байта 52

Код первого слова

Указательная информация

EOF

значение=0

1

Лента только перед EOF (маркер ленты обнаружен)

2

Лента только перед EOT (маркер ленты не обнаружен)

3

Лента перед EOF и EOT (маркер ленты обнаружен).

Второе слово в блоке состояния содержит число запрошенных для перемотки блоков (WCNT) минус число пропущенных блоков, если обнаружен маркер ленты или ВОТ. Иначе его значение не определено

Невосстановимая ошибка значение=1

0

Нет дополнительной информации (справочная документация для конкретного привода ленты для всевозможных ошибочных состояний)

1

Нет привода ленты

2

Контроллер потерял позицию ленты

Вследствие аппаратных ограничений рекомендуется, чтобы команды перемотки вперёд не подавались, если бобина ленты установлена после маркера EOT.

Формат команды перемотки назад на блок следующий:

.SPFUN AREA,CHAN,#375, ,WCNT,BLK[,CRTN]

где

375

- функциональный код для операции перемотки назад.

Этот запрос возвращает ошибки, показанные в табл. 25. Дополнительная указательная информация для этих ошибок возвращается в первых двух словах блока состояния.

Таблица 25

Код байта 52

Код первого слова

Указательная информация

EOF

значение=0

1

Лента только перед EOF (маркер ленты обнаружен)

2

Лента только перед EOT (маркер ленты не обнаружен)

3

Лента перед EOF и EOT (маркер ленты обнаружен)

4

Лента перед ВОТ (маркер ленты не обнаружен).

Второе слово в блоке состояния содержит число запрошенных для перемещения блоков (WCNT) минус число пропущенных блоков, если обнаружен маркер ленты или ВОТ. В противном случае, его значение не определено

Невосстановимая ошибка

значение=1

0

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

1

Нет привода ленты

2

Контроллер потерял позицию ленты

7.1.2.4. Перемотка

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

Запрос перемотки имеет следующий формат:

.SPFUN AREA,CHAN,#373,,,BLK[,CRTN]

где

373

- функциональный код для операции перемотки;

 

CRTN

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

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

Таблица 26

Код байта 52

Код первого слова

Указательная информация

Невосстановимая ошибка значение=1

0

Нет дополнительной информации (справочная документация для конкретного привода ленты для всевозможных ошибочных состояний)

1

Нет привода ленты

7.1.2.5. Перемотка и переход к автономности

Этот запрос такой же, как и перемотка, с тем исключением, что привод ленты берётся автономным, а затем перематывается к ВОТ. Драйвер может принимать команды после начала перемотки.

Запрос перемотки и перехода к автономности имеет следующий формат:

.SPFUN AREA,CHAN,#372,,,BLK[,CRTN]

где

372

- функциональный код для операции перемотки и перехода к автономности;

 

CRTN

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

Этот запрос возвращает тот же самый код ошибки, и указательную информацию, что и запрос перемотки (см. табл. 26).

7.1.2.6. Запись с расширенным межзонным промежутком

Этот запрос позволяет производить запись на лентах, имеющих дефектные участки. Он идентичен запросу записи, функциональный код которого равен 374. Ошибки аналогичны ошибкам для запроса записи (см. п. 7.1.2.2).

7.1.2.7. Запись маркера ленты

Аппаратный драйвер принимает запрос для записи маркера ленты. Этот запрос имеет следующий формат:

.SPFUN AREA,CHAN,#377,,,BLK[,CRTN]

где

377

- функциональный код для записи маркера ленты.

Этот запрос возвращает ошибки, показанные в табл. 27. Дополнительная указательная информация для этих ошибок возвращается в первых двух словах блока состояния (аргумента BLK).

Таблица 27

Код байта 52

Код первого слова

Указательная информация

EOF

значение=0

1

Лента только перед EOF (маркер ленты обнаружен)

Невосстановимая ошибка значение=1

0

Нет дополнительной информации (справочная документация для конкретного привода ленты для всевозможных ошибочных состояний)

1

Нет привода ленты

2

Контроллер потерял позицию ленты

4

Лента блокирована для записи

7.1.2.8. Восстановление ошибок

Любые ошибки, обнаруженные во время операций перемотки, вызывают преждевременное прерывание, и выдаётся сообщение о невосстановимой (позиционной) ошибке. Если обнаружена ошибка паритета считывания, то драйвер файловой структуры и аппаратный драйвер выполняют следующие операции.

  1. Перемотка назад на блок и повторное считывание. Если безуспешно, процедура повторяется до пяти неудачных попыток.
  2. Перемотка назад на 5 блоков, перемотка вперёд на четыре блока, затем считывание записи.
  3. Повторяет вышеуказанные пункты 1 и 2 восемь раз или пока блок не будет успешно считан.

Драйвер выполняет следующие операции при обнаружении ошибок паритета при считывании после записи.

  1. Перематывает ленту назад на один блок.
  2. Удаляет данные на 76.2 мм ленты и повторно записывает блок. Никогда не делает попыток повторно записать блок на дефектные участки, так как этот блок может быть ненадёжен и позднее может вызвать проблемы.
  3. Повторяет вышеуказанные пункты 1, 2, если считывание после записи по-прежнему отсутствует. Если таким образом пропускается 7620 мм ленты, выдаётся сообщение о невосстановимой ошибке.
7.1.2.9. Программный запрос .LOOKUP нефайловой структуры

Аппаратный драйвер принимает запрос .LOOKUP нефайловой структуры, который необходим для открытия канала в устройстве перед тем, как любые операции ввода-вывода будут выполнены. Он заставляет аппаратный драйвер пометить привод как занятый, и никакой другой канал не может быть открыт для этого привода, пока не будет выдан запрос .CLOSE. Этот запрос имеет следующий формат:

.LOOKUP AREA,CHAN,DBLK,SEQNUM

где

SEQNUM

- аргумент, который указывает, должна ли перематываться лента; когда этот аргумент равен 0, лента перематывается, когда он равен -1, лента не перематывается.

В табл. 28 показаны ошибки, возвращаемые этим запросом.

Таблица 28

Код байта 52

Значение

0-1

Запрос не имеет смысла

2

Устройство используется. Выбранный привод уже присоединён к другому каналу

3

Нет привода ленты

4

Обнаружен недопустимый аргумент: обнаружено имя файла или аргумент SEQNUM отличен от 0 или -1

7.1.2.10. Программный запрос .CLOSE

Аппаратный драйвер принимает запрос .CLOSE и заставляет драйвер отмечать привод как свободный для использования. Этот запрос имеет следующий формат:

.CLOSE CHAN
7.1.2.11. Программные запросы .WRITX нефайловой структуры

Аппаратный драйвер принимает запросы .WRITX, которые записывают различное количество слов в блок на ленте. Поле номера блока игнорируется. Эти запросы имеют следующий формат:

.WRITX AREA,CHAN,BUF,WCNT[,,CRTN]

Эти запросы возвращают ошибки, показанные в табл. 29. Дополнительная указательная информация отсутствует.

Таблица 29

Код байта 52

Значение

0

Маркер ленты EOT не был обнаружен

1

В канале возникла невосстановимая ошибка

2

Канал не открыт

7.1.2.12. Программные запросы .READX нефайловой структуры

Эти запросы считывают различное количество слов из блока на ленте. Они игнорируют маркер EOT и сообщают о конце файла, когда считан маркер ленты. Поле номера блока игнорируется. Запросы имеют следующий формат:

.READX AREA,CHAN,BUF,WCNT[, ,CRTN]

Эти запросы возвращают ошибки, показанные в табл. 30. Дополнительная указательная информация отсутствует.

Таблица 30

Код байта 52

Значение

0

Попытка считывания после маркера ленты или при создании блока, который слишком велик

1

В канале возникла невосстановимая ошибка

2

Канал не открыт

7.2. Драйверы гибких дисков (DX и DY)

Запросы .SPFUN позволяют считывать и записывать абсолютные секторы на гибких дисках. (В дальнейшем гибкие диски с одинарной плотностью записи будем называть просто гибкими дисками, в отличие от гибких дисков с двойной плотностью записи данных.) Драйвер DY принимает дополнительный запрос .SPFUN для определения размера (в 256-словных блоках) тома, установленного на указанном приводе. В гибких дисках с двойной плотностью записи секторы имеют размер 128 слов. Система ФОДОС-2 обычно считывает и записывает их группами из двух секторов. В гибких дисках секторы имеют размер 64 слова. Система ФОДОС-2 считывает и (вписывает их группами по четыре сектора. Секторы могут выбираться индивидуально посредством запроса. .SPFUN. Формат запроса следующий:

.SPFUN AREA,CHAN,FUNC,BUF,WCNT,BLK,CRTN

где

FUNC

- код функции, которая будет выполняться; коды и функции приведены в табл. 31.

 

BUF

- для функциональных кодов 377, 376, 375 является ячейкой 129-словного буфера (для гибких дисков с двойной плотностью записи) или 65-словного буфера (для гибких дисков); первое слово буфера, слово признака, обычно, установлено 0;

если первое слово установлено 1, осуществляется считывание физического сектора, содержащего метку удалённых данных; фактическая область данных буфера расширяется от второго слова к концу буфера;

 

BUF

- для функционального кода 373 является ячейкой однословного буфера, в котором возвращается размер тома, установленного на указанном приводе; (для гибких дисков возвращается 494; для гибких дисков с двойной плотностью записи возвращается 988)

 

WCNT

- для функций 377, 376, 375 является абсолютным числом дорожек для считывания или записи от 0 до 76;

 

WCNT

- для функции 373 резервируется и должен быть установлен 1;

 

BLK

- для функций 377, 376, 375 является абсолютным числом секторов для считывания или записи с 1 по 26;

 

BLK

- для функции 373 резервируется и должен быть установлен 0.

Таблица 31

Код

Функция

377

Считывание физического сектора

376

Запись физического сектора

375

Запись физического сектора с меткой удалённых данных

374

Зарезервировано

373

Определяет размер тома устройства в 256-словных блоках (только DY)

Гибкие диски должны открываться запросом .LOOKUP нефайловой структуры. Аргументы BUF, WCNT, BLK имеют разные значения, когда они используются гибкими дисками. Ниже приведён запрос, выполняющий синхронное считывание сектора с дорожки 0, сектора 7 в 65-словную область, названную BUFF:

.SPFUN #RDLIST,#377,#BUFF,#0,#7,#0

Каждый из драйверов, и DX, и DY, может поддерживать два контроллера, и каждый контроллер обслуживает два привода. Например, если драйвер DX создаётся в процессе генерации системы с поддержкой двух контроллеров, он будет поддерживать 4 устройства: DX0, DX1, DX2, DX3. DX0 и DX1 - это приводы 0 и 1 стандартного гибкого диска с вектором 264 и регистром состояния канала (CSR) 177170. DX2 и DX3 - это приводы 0 и 1 другого контроллера. Процесс ввода-вывода может действовать всего один раз, даже если имеется два контроллера. Совмещение ввода-вывода в драйвере недопустимо.

7.3. Драйвер перфоленточного устройства ввода-вывода (PC)

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

Драйвер PC во время операции ввода заполняет нулями буфер, если кончилась лента во время считывания. При следующем запросе считывания драйверу PC устанавливается разряд EOF и разряд переноса при возврате по окончании ввода-вывода.

7.4. Драйвер системного терминала (ТТ)

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

  1.  Управляющий символ "^" печатается, когда драйвер готов для ввода.
  2. СУ/Z используется для обозначения конца ввода в TT:. После СУ/Z не требуется нажатия <ВК>. Если СУ/Z не печатается, драйвер ТТ принимает символы, пока счётчик слов запроса ввода не будет исчерпан.
  3. СУ/O, напечатанное, когда осуществляется вывод на TT:, вызывает игнорирование всего буфера вывода. (Все символы образуют текущую очередь.)
  4. Однократная печать СУ/C во время ввода на TT: вызывает возврат в монитор. Если осуществляется вывод на TT:, для возврата в монитор требуется двукратная печать СУ/C, если выполняется FB-монитор. Если выполняется SJ-монитор, требуется только однократная печать СУ/C для завершения вывода на TT:.
  5. Драйвер ТТ может использоваться в определённый момент только одним заданием (основным или фоновым) и только для одной функции (ввода или вывода). Коммуникация терминала для задания, не использующего TT:, вообще, не затрагивается.
  6. Можно печатать сначала на TT:; символы изымаются из кольцевого буфера ввода перед обращением к клавиатуре. Завершающее СУ/Z может быть также напечатано заранее.
  7. Если основной код задания использует TT: для ввода, а подпрограмма завершения выдаёт запрос .TTYIN, то напечатанные символы будут пропущены по .TTYIN и на TT: непредсказуемо.
  8. Если задание посылает данные в TT: для вывода и затем выдаёт запрос .TTYOUT или запрос .PRINT, вывод из последнего задерживается до завершения драйвером своей передачи. Если операция вывода на TT: начата, когда выходной кольцевой буфер мониторного терминала не пуст (перед окончанием прямой печати), драйвер завершает операцию передачи до того, как содержимое буфера напечатается.

7.5. Драйвер фиктивного устройства NL

Драйвер фиктивного устройства NL принимает все запросы считывания и записи. В операциях вывода этот драйвер действует как приёмник данных. Когда программа вызывает NL, драйвер сразу же возвращается в монитор, показывая, что вывод завершён. Драйвер не возвращает ошибок и не вызывает прерываний. При операциях ввода NL возвращает немедленную индикацию EOF для всех запросов; данные не передаются. Следовательно, содержимое буфера ввода остаётся неизменным.

7.6. Драйвер расширенной памяти VM

Драйвер расширенной памяти VM имеет произвольный доступ к расширенной памяти, подобно диску. Команда INITIALIZE используется для инициализации расширенной памяти, зарезервированной для области VM: перед копированием файлов в область, и можно получить справочник файлов в области VM: используя команду DIR. Можно даже копировать мониторы SJ или FB и начальный загрузчик в VM: и работать в системе SJ или FB. Особенности драйвера содержат:

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

Если необходимо изменить размеры памяти, имеющейся в распоряжении драйвера VM, посредством изменения адреса базы, необходимо переместить и переустановить драйвер. Большинство других драйверов необходимо только перезагрузить после команды SET без переустановки. Необходимо также повторно инициализировать VM: после изменения адреса базы, используя команду INIT VM:. Система ФОДОС-2 печатает предупреждающее Сообщение: VM-W-REMOVE AND REINSTALL всякий раз, когда требуется изменить адрес базы, по команде: SET VM BASE = N.

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

Адрес базы (N), использованный в команде SET VM BASE = N, - это затребованный адрес базы в восьмеричном представлении, делённый на 100 (восьмеричное). Например, используем значение 1600 для установки адреса базы на границе адреса 28К слов или 10000 для установки адреса базы на границе адреса 128К слов; любое другое значение между 1600 и верхней границей физической памяти также допустимо.

В табл. 32 приведены соответствия между размерами памяти К слов и соответствующими значениями N.

Таблица 32

К-слова

N

28

1600

32

2000

64

4000

96

6000

128

10000

256

20000

512

40000

1024

100000

Рис. 18 показывает 22-разрядную систему с адресом базы, равным 10000 (128Кслов).

Рис. 18

Если используется монитор ХМ, и аппаратура не имеет 22-разрядную адресацию, драйвер по умолчанию устанавливаться не будет; необходимо заменить адрес базы на более низкое значение перед использованием VM: с системой ХМ. Можно ещё использовать расширенную память и для программы ХМ, и для тома VM:, но область, указанная для одной будет урезаться областью, занятой другой. Рис. 19 показывает 18-разрядную систему с базовым адресом, установленным VM на 3600 (60К слов).

Рис. 19

Большинство устройств произвольного доступа к данным, например, диски, не могут обрабатывать более, чем 18-разрядный адрес (128К слов). Если имеется одно из таких устройств и более 128К слов памяти в системе, то установка базы VM: на границе 128К слов гарантирует, что ни одна из программ пользователя не будет создавать буфер данных, который данный диск не сможет считывать или записывать, позволяя в то же время эффективное использование памяти свыше 128К слов драйвером VM.

7.7. Программа установки логического диска

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

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

7.7.1. Выполнение программы установки логического диска

Для вызова LD с системного устройства следует убедиться, что LD установлен и подать с терминала команду после того, как монитор напечатает точку: R LD.SYS<ВК>.

В ХМ-системе команда будет выглядеть следующим образом:

R LDX.SYS<ВК>

После вызова LD печатает звёздочку (*) и ожидает ввода командной строки. Если в это время нажать клавишу <ВК>, то LD печатает номер своей версии. Для выхода из программы LD и передачи управления монитору следует подать команду СУ/C, если LD ожидает ввода командной строки, или дважды СУ/C, если LD выполняет операцию.

Режим работы программы LD задаётся введением с терминала командной строки.

Формат командной строки следующий:

Входспф/прк

где

входспф

- спецификация файла, определяемого как логический диск;

 

прк

- переключатель (см. табл. 33).

В командной строке можно указать до шести спецификаций входных файлов. Тип файла по умолчанию - .DSK.

7.7.2. Переключатели LD

В табл. 33 приведены переключатели программы LD.

Таблица 33

Переключатель

Функция

/A:DDD

Назначает имя логическому диску. Используется с переключателем /L

/C

Сравнивает все логические диски, назначенные файлам на установленном в данный момент томе

/L:N

Устанавливает логический диск и связывает его с файлом на диске или удаляет логический диск и отменяет связь его с файлом на диске

/R:N

Запрещает запись на логический диск. Когда используется переключатель /R:N, имеется только доступ к чтению

/W:N

Разрешает запись на логический диск. Когда используется переключатель /W:N, имеется доступ к чтению/записи

7.7.2.1. Переключатель /A:DDD

Переключатель /A:DDD следует использовать с переключателем /L для назначения логического имени логическому диску. Аргумент DDD - логическое имя (от одного до трех символов). Первый символ должен быть буквой, двоеточие после логического имени включается по умолчанию. После назначения логического имени логическому диску, можно обращаться к логическому диску, используя форму LDN: или логическое имя устройства.

Следующая команда назначает логическое имя VOL логическому диску с номером 2 (LD2:), когда он определяется файлом DK:LOGFIL.DSK: *LOGFIL.DSK/L:2/A:VOL

7.7.2.2. Переключатель /C

Переключатель /C проверяет все назначения логических дисков. При использовании переключателя /C, LD проверяет текущее назначение логическим дискам файлов на томах, которые установлены. Этот переключатель наиболее полезен после перемещения или удаления файлов на томе или удаления тома с устройства. Если файл логического диска перемещён, LD определяет новое расположение так, что можно продолжать использование этого логического диска. Если удалён файл логического диска или том, содержащий файл логического диска, не установлен, LD отменяет назначения логического диска. В случае, если том удаляется, отмена назначения - временная.

После операции сжатия по команде монитора SQUEEZE (или с использованием переключателя /S программы DUP, см. [2], [3]) или начальной загрузки система автоматически выполняет операцию по переключателю /C для модификации назначений логических дисков.

Переключатель /C не должен повторяться в командной строке (должен встречаться не более одного раза).

7.7.2.3. Переключатель /L:N

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

спф/L:N

где

спф

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

 

N

- номер логического диска, связанного с файлом; после его установки, к логическому диску можно обращаться как к LDN:; аргумент N должен принимать целые значения в диапазоне от 0 до 7.

Для освобождения логического диска от связи с файлом следует подать следующую команду: /L:N

Можно установить и удалить в одной командной строке несколько логических дисков. Например, следующая команда связывает логический диск с номером 0 с файлом MYFILE. DSK на DK0:, логический диск с номером 4 с файлом DATFIL.DSK на DY0: и удаляет логический диск с номером 2:

*DK0:MYFILE/L:0,DY0:DATFIL.DSK/L:4,/L:2

Можно также переназначить логический диск с номером N, указав /L:N и другое имя файла.

7.7.2.4. Переключатель /R:N

Переключатель /R:N используется для запрещения записи на логический диск. После команды с этим переключателем доступ к логическому диску будет осуществляться только по чтению. Аргумент N - номер логического диска (N - целое, от 0 до 7). Следующая команда устанавливает LD3: для файла JMS.TXT на DY1: и устанавливает запрещение записи:

*JMS.TXT/L:3/R:3

Следующая далее команда устанавливает запрещение записи на LD4:: */R:4

7.7.2.5. Переключатель /W:N

Переключатель /W:N используется для разрешения записи на логический диск. После этой команды к логическому диску имеется доступ по чтению/записи. Аргумент N - номер логического диска (N - целое, от 0 до 7). Этот режим выполняется по умолчанию.

Следующая команда устанавливает логический диск LD5:, связывает его с файлом JMS.DSK на DK0: и разрешает запись на этом логическом диске: *DK0:JMS/L:5/W:5

7.8. Драйвер логического диска (LD)

Драйвер логического диска (LD) осуществляет поддержку логического диска в системе ФОДОС-2. Драйвер LD принимает запросы ввода-вывода так же, как это делает любой другой драйвер диска. Посредством вставленных таблиц трансляции драйвер LD определяет, какой физический диск и какое смещение начального блока должно использоваться для каждого запроса ввода-вывода LD. Когда соответствующий физический диск и номер блока определены, драйвер LD заносит номер блока и номер привода в элемент очереди ввода-вывода так, что они соответствуют значениям для назначенного физического диска. Затем драйвер LD помещает элемент очереди в очередь ввода-вывода для физического диска так, чтобы мог произойти фактический ввод-вывод.

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

7.8.1. Таблицы трансляции LD

В драйвере LD находятся четыре таблицы трансляции. Первая таблица трансляции начинается с метки HANDLR и содержит одно слово для каждого номера привода LD:, максимум 8. Эта таблица имеет порядковый номер, равный номеру привода LD:, умноженному на 2.

Разряды с 0 по 5 каждого слова в таблице HANDLR содержат порядковый номер в таблице драйвера в RMON для физического устройства, соответствующего номеру привода LD:.

Разряд 6 является признаком, который сигнализирует, что элемент таблицы OFFSET для привода LD: может быть неправильным. Этот разряд устанавливается каждый раз при сжатии тома. Драйвер LD, когда он использует привод LD:, проверяет этот разряд; если разряд установлен, драйвер проверяет элемент таблицы блока OFFSET перед обработкой.

Разряд 7 является признаком, который сигнализирует, что содержимое поля порядкового номера, разряды с 0 по 5, может быть неправильным и будет проверено и исправлено. Драйвер LD устанавливает разряд 7 для всех приводов, если у элемента разряд LDREL¤ установлен в CONFG2.

Разряды с 8 по 10 содержат номер привода физического диска, назначенный для привода логического диска.

Разряды 11, 12, и 14 не используются.

Разряд 13 является разрядом блокировки записи. Если он установлен, то привод LD: предназначен только для считывания.

Разряд 15 является разрядом назначения. Если он установлен, то привод LD: является назначенным, если он очищен, то привод не назначен.

Вторая таблица трансляции начинается с метки OFFSET и содержит одно слово для каждого номера привода LD:, максимум 8. Эта таблица имеет порядковый номер, равный номеру привода LD:, умноженному на 2. Каждое слово содержит смещение в блоках от начала назначенного физического диска до начала области на физическом диске, назначенный для номера привода LD:.

Третья таблица трансляции начинается с метки SIZE и содержит одно слово для каждого номера привода LD:, максимум 8. Эта таблица имеет порядковый номер, равный номеру привода LD:, умноженному на 2. Каждое слово содержит размер области в блоках на физическом диске, назначенной для привода логического диска.

Четвёртая таблица трансляции начинается с метки NAME и содержит 4 слова для каждого номера привода LD:. Эта таблица имеет порядковый номер, равный номеру привода LD:, умноженному на 8. Первое слово каждого 4-словного элемента содержит двухсимвольное имя физического диска в RADIX-50, назначенное приводу логического диска. Это слово должно быть фактически именем устройства, а не логически присвоенным именем, и не должно иметь номер привода как часть имени. Второе, третье и четвёртое слова каждого 4-словного элемента содержат имя и тип файла в RADIX-50, назначенные как логический диск.

7.8.2. Другие разряды, используемые драйвером LD

Драйвер LD использует разряд 4 (LDREL¤) в CONFG2, фиксированное смещение монитора 370. Этот разряд устанавливается всякий раз, когда драйвер разгружается или освобождается. Драйвер LD проверяет этот разряд, чтобы убедиться, назначен ли драйвер приводу LD, удалённый из памяти после того, как он был последний раз использован. Если разряд установлен, драйвер LD устанавливает разряд 7 во всех элементах таблицы HANDLR, затем очищает разряд LDREL¤. Когда драйвер LD начинает обработку запроса ввода-вывода, он проверяет разряд 7 для запрошенного привода LD:. Если разряд 7 установлен, драйвер LD проверяет, чтобы драйвер для диска, назначенного этому номеру привода LD: находился в памяти, затем очищает разряд. Драйвер LD проверяет и очищает разряд 7 для привода, только когда запрос ввода-вывода посылается для этого привода. Проверка только при абсолютной необходимости гарантирует, что драйвер LD не будет тратить время на сравнение приводов, которые никогда не могут быть использованы в индивидуальной программе пользователя.

7.8.3. Специальный переключатель LD ()

Когда подаётся команда клавиатурного монитора MOUNT для назначения привода логического диска, MOUNT строит командную строку для назначения привода логического диска, размещает команду в цепной области и сцепляется с LD.SYS. MOUNT включает в командную строку переключатель /L, который определяет назначение логического привода. MOUNT включает также дополнительно переключатель .

LD.SYS принимает командную строку и использует код переключателя /L для назначения привода логического диска. Затем, если переключатель /¤ был включён в командную строку, LD проверяет, находится ли в памяти драйвер устройства, затребованный этим логическим приводом. Если драйвер устройства не загружен, LD вызывает команду LOAD для этого драйвера, помещает команду в цепную область и передаёт команду обратно в KMON для выполнения. Таким образом, любые запрошенные драйверы для логических приводов, назначенных по команде MOUNT, являются автоматически загруженными. Хотя переключатель первоначально предназначен для использования в MOUNT, можно использовать с /L, если необходимо самостоятельно выполнить LD.SYS для назначения логических приводов.

8. СООБЩЕНИЯ СИСТЕМНОМУ ПРОГРАММИСТУ

Все сообщения системы ФОДОС-2 приведены в книге 6 глава "Сообщения системы".

ПЕРЕЧЕНЬ ССЫЛОЧНЫХ ДОКУМЕНТОВ

  1. Операционная система ФОДОС-2
    Системная макробиблиотека.
    Руководство программиста.
  2. Операционная система ФОДОС-2
    Командный язык системы.
  3. Операционная система ФОДОС-2
    Программы работы с файлами.
    Руководство оператора.