|
|
|
|
Программа ПРЕРЫВАНИЙ
После того, как программа СТРАТЕГИЙ сохраняет указатель на
блок запроса и возвращает управление, MS-DOS вызывает программу
ПРЕРЫВАНИЙ (называемую также точкой входа запроса в документации
фирмы IBM по PC DOS). Собственно запрос к драйверу обрабатывается
именно этой программой.
Самое первое действие, которое должна выполнить программа ПРЕРЫВАНИЙ - это сохранить все регистры. На момент обращения к драйверу устройства стек имеет
емкость примерно в 20 слов. Сохранение всех регистров, включая флаги, требует 14 слов. Если программе
ПРЕРЫВАНИЙ требуется для работы более чем 6 слов стека, она должна установить свой собственный локальный стек.
После сохранения текущего состояния процессора, программа ПРЕРЫВАНИЙ должна получить блок запроса, сохраненный программой
СТРАТЕГИЙ. Если адрес этого блока был сохранен с помощью приведенных выше команд, то получить адрес блока параметров можно командой LDS
lds bx,cs:[req_ptr] ; получить адрес блока запроса
|
Теперь, получив доступ к заголовку блока запроса, можно начинать его обработку. Первый шаг заключается в анализе запроса.
Доступ к нужным полям блока запроса будет значительно облегчен,
если описана структура заголовка. Структура, которую мы используем в драйвере RDISK и которая определяет формат заголовка запроса, показана в
листинге 6-2.
Если драйвер должен обслуживать блоковое устройство, то первый элемент заголовка запроса, который должен быть проверен, это поле
количества устройств (request.unit). После проверки корректности
поля request.unit, программа ПРЕРЫВАНИЙ должна получить из блока
запроса код команды (request.command), которую требуется выполнить. Символьные драйверы могут обращаться сразу к коду команды,
т.к. каждый символьный драйвер поддерживает только одно устройство.
Определив код команды, программа ПРЕРЫВАНИЙ должна передать
управление соответствующему обработчику. В листинге 6-3, содержащем пример программы ПРЕРЫВАНИЙ, показан один из способов передачи управления
требуемому обработчику, основанный на использовании
таблицы переходов. Таблица переходов представляет собой последовательность смещений программ-обработчиков команд. Для передачи
управления определенному обработчику необходимо указать индекс
требуемой подпрограммы, заданной своим смещением в таблице переходов. Этот индекс (в нашем случае это код команды) преобразуется
в смещение в таблице, после чего выполняется косвенный вызов подпрограммы или переход на нее через таблицу переходов
call word ptr cs:jumptab[bx] ; обработать команду
|
В связи с тем, что индекс (т.е. код команды) может быть больше, чем максимальный из используемых кодов команд, программа ПРЕРЫВАНИЙ должна выполнять
проверку индекса для того, чтобы убедиться в его правильности. При этом, вместо сравнения индекса с
каким-либо заранее фиксированным значением, программа ПРЕРЫВАНИЙ
сравнивает код команды с максимально допустимым значением, хранящимся в поле max_cmd :
cmp bl,[max_cmd] ; команда допустима ?
|
Для того, чтобы понять пользу хранения максимально допустимого
значения в памяти, взгляните на таблицу 6-2. В этой таблице
представлены команды, поддерживаемые различными версиями MS-DOS.
Максимальный код команды, обеспечиваемый MS-DOS версий до 3.0,
имеет значение 0CH. Однако, учитывая тот факт, что max_cmd располагается в памяти, драйвер может модифицировать это значение во
время инициализации, позволяя, таким образом, использовать новые
команды, если драйвер загружен под управлением новой версии
MS-DOS.
Таблица 6-2
Команды для драйверов устройств
ДДДДДДДДВДДДДДДДВДДДДДДДДДВДДДДДДДДДВДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДД
Команда і Версияі Блоковыеі Симв-ныеі Атрибут і Название команды
і DOS і устр-ваі устр-ваі і
ДДДДДДДДЕДДДДДДДЕДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДД
0: і 2.0 і + і + і і INIT
1: і 2.0 і + і - і і MEDIA CHECK
2: і 2.0 і + і - і і BUILD BPB
3: і 2.0 і + і + і 14:IOCTLі INPUT IOCTL
4: і 2.0 і + і + і і INPUT
5: і 2.0 і - і + і і Nondestructive INPUT
6: і 2.0 і - і + і і INPUT STATUS
7: і 2.0 і - і + і і INPUT FLUSH
8: і 2.0 і + і + і і OUTPUT
9: і 2.0 і + і + і і OUTPUT with VERIFY
10: і 2.0 і - і + і і OUTPUT STATUS
11: і 2.0 і - і + і і OUTPUT FLUSH
12: і 2.0 і + і + і 14:IOCTLі OUTPUT IOCTL
13: і 3.0 і + і + і 11:OCRM і DEVICE OPEN
14: і 3.0 і + і + і 11:OCRM і DEVICE CLOSE
15: і 3.0 і + і - і 11:OCRM і REMOVABLE MEDIA
16: і 3.1 і - і + і 13:OTB і OUTPUT until busy
19: і 3.2 і + і + і 6:GIOCTLі Generic IOCTL Request
23: і 3.2 і + і - і 6:GIOCTLі Get Logical Device
24: і 3.2 і + і - і 6:GIOCTLі Set Logical Device
ДДДДДДДБДДДДДДДБДДДДДДДДДБДДДДДДДДДБДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДД
Примечание 1. В колонке "Версия DOS" указана самая ранняя версия
MS-DOS, начиная с которой поддерживается эта команда.
Примечание 2. В колонке "Атрибут" указаны бит слова атрибутов
драйвера, разрешающий использование данной команды.
ННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН
|
Последняя задача программы ПРЕРЫВАНИЙ после обработки требуемой команды заключается в установке статуса возврата в блоке запроса. В листинге 6-3
ожидается, что обработчик каждой команды возвращает статус завершения в регистре AX. После возврата управления от обработчика, программа ПРЕРЫВАНИЙ
записывает статус в поле слова состояния заголовка запроса (поле request.status). Затем программа ПРЕРЫВАНИЙ устанавливает бит DONE ("выполнено") в
слове состояния и возвращает управление MS-DOS. Так как возврат
управления должен быть выполнен командой RETF, программа ПРЕРЫВАНИЙ определяется как процедура типа FAR.
Листинг 6-3. Пример программы ПРЕРЫВАНИЙ.
-----------------------------------------------------------------
;
; Определение битов слова состояния драйвера устройства
;
ST_ERROR equ 1000000000000000b ; была ошибка
ST_BUSY equ 0000001000000000b ; устройство занято
ST_DONE equ 0000000100000000b ; команда выполнена
;
; Определение кодов ошибки при обработке команд
;
WRITE_PROTECT equ 0 ; защита от записи
UNKNOWN_UNIT equ 1 ; неопознано устройство
NOT_READY equ 2 ; устройство не готово
UNKNOWN_COMMAND equ 3 ; команда не опознана
.
.
;
;********** Точка входа в программу ПРЕРЫВАНИЙ ************************
;
INTERRUPT proc far
pusha ; сохраним все рабочие
push ds ; регистры
push es
push cs ; установим локальный
pop ds ; сегмент данных
les di,[req_ptr] ; получим адрес блока
mov bl,es:[di].command ; запроса и код
; команды
;
; Установим заранее флаг ошибки (на случай, если команда будет
; неопознана)
;
mov ax,(ST_ERROR or UNKNOWN_COMMAND)
cmp bl,[max_cmd] ; эта команда
ja exit ; поддерживается ?
;
; Передадим управление соответствующему обработчику. На входе каждый
; обработчик получает регистры CS и DS установленными на сегмент
; DRIVER и регистры ES:DI указывающими на блок запроса. Свой статус
; обработчик должен вернуть в регистре AX.
;
xor bh,bh ; превратим команду
shl bx,1 ; в индекс
call word ptr cs:jumptab[bx] ; обработаем команду
;
; Запишем статус в слово состояния блока запроса
;
exit: push cs
pop ds
les di,[req_ptr] ; получим адрес блока
or ax,ST_DONE ; запроса, установим
mov es:[di].status,ax ; бит DONE и сохраним
pop es ; статус
pop ds ; восстановим контекст
popa
ret ; RETF
INTERRUPT endp
.
.
.
;
;********** Таблица переходов на обработку команд *******************
;
JUMPTAB label word
dw offset INIT ; 0 - Инициализация
dw offset MEDIA_CHECK ; 1 - Проверка носителя
dw offset BUILD_BPB ; 2 - Построить BPB
.
.
.
dw offset NO_COMMAND ; 16
dw offset GET_LOGICAL ; 17 - Получить имя ЛУ
dw offset SET_LOGICAL ; 18 - Установить ЛУ
.
.
.
---------------------------------------------------------------------
|
Слово состояния, показанное на рис.6-5, используется для индикации ошибок, случившихся при выполнении какой-либо команды (бит
ERROR -- ошибка) и для отображения состояния устройства по командам опроса статуса и проверки смены носителя (бит BUSY -- занято).
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
ЪДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДД·
і E і і і і і і B і D і і і і і і і і є
і R і і і і і і U і O і і і КОД ОШИБКИ і і є
і R і ЗАРЕЗЕРВИРОВАНО і S і N і і ЕСЛИ БИТ 15 РАВЕН 1 і є
і O і і і і і і Y і E і і і і і і і і є
і R і і і і і і і і і і і і і і і є
ФНННПНННПНННПНННПНННПНННПНННПНННПНННПНННПНННПНННПНННПНННПНННПНННј
Значение битов :
ERROR = 1 : При обработке команды случилась ошибка.
Код ошибки находится в битах с 0 по 7.
BUSY = 1 : Устанавливается командами опроса состояния
и проверки смены носителя.
DONE = 1 : Команда выполнена. Устанавливается на выходе.
Рисунок 6-5. Слово состояния драйвера устройства
|
Бит ERROR устанавливается, если возникла ошибка при выполнении
какой-либо команды или если команда является недопустимой для
данного драйвера. При установленном бите ошибки драйвер обязан
поместить соответствующий код ошибки в биты с 0 по 7 слова состояния. Возможные ошибки и их коды перечислены в таблице 6-3. Бит
DONE должен всегда устанавливаться драйвером перед возвратом управления к MS-DOS.
Таблица 6-3
Коды ошибок драйверов устройств
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Код Ошибка іКод Ошибка
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДД
0 Запись на устройство запрещена і 8 Сектор не обнаружен
1 Неопознанное устройство і 9 Нет бумаги в принтере
2 Устройство не готово і A Ошибка при записи
3 Команда не опознана і B Ошибка при чтении
4 Неверно переданы данные і C Общая ошибка
5 Неверна длина заголовка запросаі D Зарезервировано
6 Ошибка при установке головки і E Зарезервировано
7 Неопознанный носитель данных і F Недопустимая смена диска
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Примечание 1. Все коды ошибок представлены в виде шестнадцати-
ричных значений.
Примечание 2. Код ошибки 0FH поддерживается только в MS-DOS вер-
сии 3.0 и более поздних.
|
|
|