Повторить операцию позже. Можно спросить
Таблица 5
1 | Повторить операцию позже. Можно спросить пользователя, желает он повторить операцию или завершить работу программы. |
2 | Повторить предыдущую операцию после небольшой паузы. Если ошибка не исчезла, следует спросить пользователя, будет он ждать и дальше, или следует завершить работу программы. |
3 | Если пользователь вводил какие-то данные для DOS, следует попросить его ввести эти данные еще раз (например, пользователь мог указать неправильный идентификатор диска или путь доступа к файлу). |
4 | Аварийно завершить работу прикладной программы с выполнением всех обычных завершающих действий (закрытие файлов, сброс буферов на диск, освобождение блоков памяти и т.д.) |
5 | Немедленный выход из программы без выполнения завершающих действий. Система находится в непредсказуемом состоянии. |
6 | Следует игнорировать ошибку. |
7 | Повторить операцию после того, как пользователь выполнит требуемые действия (установит дискету и т.п.). |
Таблица 5
(0) 1 | drv_num | номер устройства (0 соответствует устройству А:, 1 - В: и т.д.) |
(+1) 1 | drv_numd | дополнительный номер устройства внутри драйвера |
(+2) 2 | sec_size | размер сектора в байтах |
(+4) 1 | clu_size | число, на единицу меньшее количества секторов в кластере |
(+5) 1 | clu_base | если содержимое этого поля не равно нулю, то для получения общего числа секторов в кластере надо возвести 2 в степень clu_base и получившееся число прибавить к clu_size |
(+6) 2 | boot_siz | количество зарезервированных секторов (boot-сектора, начало корневого каталога) |
(+8) 1 | fat_num | количество копий FAT |
(+9) 2 | max_dir | максимальное число дескрипторов файлов в корневом каталоге (т.е. максимальное число файлов, которое может содержать корневой каталог на этом устройстве) |
(+11) 2 | data_sec | номер первого сектора данных на диске (номер сектора, соответствующего кластеру номер 2) |
(+13) 2 | hi_clust | максимальное количество кластеров (равно увеличенному на 1 количеству кластеров данных) |
(+15) 1 | fat_size | количество секторов, занимаемых одной копией FAT |
(+16) 2 | root_sec | номер первого сектора корневого каталога |
(+18) 4 | drv_addr | FAR-адрес заголовка драйвера, обслуживающего данное устройство |
(+22) 1 | media | байт описания среды носителя данных |
(+23) 1 | acc_flag | флаг доступа, 0 означает, что к устройству был доступ |
(+24) 4 | next | адрес следующего блока DDCB, для последнего блока в поле смещения находится число FFFF |
--------------- только для DOS 2.x ----------------- | ||
(+28) 2 | dir_clu | номер начального кластера текущего каталога (0 для корневого каталога) |
(+30) 64 | dir_path | строка в формате ASCIIZ, содержащая путь к текущему каталогу |
----- DOS 3.х ------ | ||
(+28) 2 | reserv1 | зарезервировано, обычно равно 0 |
(+30) 2 | built | число FFFF в этом поле означает, что блок DDCB был построен |
Таблица 5
(0) 2 | seg_env | сегментный адрес среды, которая создается родительской программой для запускаемой программы. Если в этом поле находится 0, то для запускаемой программы копируется среда родительской программы |
(+2) 4 | cmd | FAR-адрес строки параметров для запускаемой программы. Эта строка должна иметь такой же формат, как и в PSP, т.е. вначале идет байт со значением, равным количеству символов в строке параметров, а затем - сама строка параметров |
(+6) 4 | fcb1 | адрес блока FCB, который будет помещен в PSP со смещением 5Ch (в PSP помещается блок, а не адрес!) |
(+10) 4 | fcb2 | адрес блока FCB, который будет помещен в PSP со смещением 6Ch. |
Если родительская программа сама формирует среду для дочерней программы, она должна подготовить новую среду на границе параграфа и поместить значение сегментного адреса в поле seg_env блока EPB.
Приведем простую программу, которая запускает программу с именем PARM.COM из текущего каталога. Программу PARM.COM мы только что рассматривали, эта программа выводит на экран полученные ей в командной строке параметры. .MODEL small DOSSEG .STACK 100h .DATA path db "PARM.COM",0 command_line db 8,"Parm Str" epb dw 0 cmd_off dw ? cmd_seg dw ? fcb1 dd ? fcb2 dd ? .CODE .STARTUP mov bx,OFFSET command_line ; адрес командной mov cmd_off,bx ; строки для блока EPB mov cmd_seg,ds mov ax,ds mov es,ax mov bx,OFFSET epb ; ES:BX указывают на EPB mov dx,OFFSET path ; DS:DX указывают на путь ; запускаемой программы mov ax, 4B00h ; AH = 4Bh ; AL = 0 загрузить и выполнить int 21h .EXIT 0 END
Эта программа использует модель памяти SMALL, и ее загрузочный модуль имеет формат EXE. При редактировании был указан стандартный для Quick C 2.01 размер памяти, требуемый для программы. Если попытаться использовать формат COM в модели TINY, то окажется, что вся память распределена COM-программе и для дочерней программы не осталось места.
Следующая программа освобождает всю неиспользуемую ей память, после чего на освободившееся место загружает программу PARM.COM: .MODEL tiny DOSSEG .STACK 100h .DATA path db "PARM.COM",0 command_line db 8,"Parm Str" epb dw 0 cmd_off dw ? cmd_seg dw ? fcb1 dd ? fcb2 dd ? .CODE .STARTUP ; ; Освобождаем лишнюю память за концом программы ; mov bx,OFFSET last ; смещение конца ; программы mov cl,4 ; вычисляем длину в ; параграфах shr bx,cl add bx,17 ; добавляем 1 параграф для ; выравнивания и 256 байт ; для стека mov ah, 4Ah ; изменяем размер выделенного int 21h ; блока памяти mov ax,bx ; установка нового значения shl ax,cl ; указателя стека dec ax mov sp,ax mov bx,OFFSET command_line ; адрес командной mov cmd_off,bx ; строки для ; блока EPB mov cmd_seg,ds mov ax,ds mov es,ax mov bx,OFFSET epb ; ES:BX указывают на EPB mov dx,OFFSET path ; DS:DX указывают на путь ; запускаемой программы mov ax, 4B00h ; AH = 4Bh ; AL = 0 загрузить и ; выполнить int 21h .EXIT 0 last: db ? END
Для изменения размера выделенного программе блока памяти мы использовали функцию 4Ah прерывания 21h.
Подфункции 1 и 2 прерывания 4Bh используются DOS (это внутренние подфункции DOS). Мы приведем недокументированный формат блока EBP для этих функций.
Для подфункнкции 1:
Таблица 5
Бит | Назначение |
0-7 | Код ошибки устройства (если команда выполнена с ошибкой и драйвер установил признак ошибки (бит 15) в единицу, в это поле он должен записать код ошибки). |
8 | Команда выполнена. Этот бит всегда устанавливается драйвером перед тем, как он возвращает управление операционной системе. |
9 | Занято. Этот бит устанавливается обработчиком команды, когда физическое устройство занято выполнением предыдущей операции и поэтому не может выполнить требуемую команду. Этот бит используется также для передачи такой информации, как "буфер клавиатуры не пуст", "среда носителя данных заменяемая" (в команде проверки возможности замены среды носителя данных). |
10-14 | Зарезервировано. |
15 | Признак ошибки. Устанавливается драйвером, когда он не может обработать запрос или произошла физическая либо логическая ошибка при обработке правильного запроса. Биты 0-7 при этом должны содержать код ошибки. |
Таблица 5
Бит | Назначение |
0-7 | Код ошибки устройства (если команда выполнена с ошибкой и драйвер установил признак ошибки (бит 15) в единицу, в это поле он должен записать код ошибки). |
8 | Команда выполнена. Этот бит всегда устанавливается драйвером перед тем, как он возвращает управление операционной системе. |
9 | Занято. Этот бит устанавливается обработчиком команды, когда физическое устройство занято выполнением предыдущей операции и поэтому не может выполнить требуемую команду. Этот бит используется также для передачи такой информации, как "буфер клавиатуры не пуст", "среда носителя данных заменяемая" (в команде проверки возможности замены среды носителя данных). |
10-14 | Зарезервировано. |
15 | Признак ошибки. Устанавливается драйвером, когда он не может обработать запрос или произошла физическая либо логическая ошибка при обработке правильного запроса. Биты 0-7 при этом должны содержать код ошибки. |