Операционная система MSDOS


Недостаточно ресурсов: блоков FCB, памяти



Таблица 4



1 Недостаточно ресурсов: блоков FCB, памяти и т.д.
2Временная ситуация
3Нет прав доступа
4Внутренняя ошибка DOS
5Ошибка аппаратуры
6Системная ошибка DOS (нет CONFIG.SYS и т.п.)
7Ошибка в прикладной программе
8Файл или объект не найден
9Неправильный формат файла или объекта
10Файл или объект заблокирован
11Ошибка носителя данных
12Файл или объект уже существует
13Прочие ошибки
Код предполагаемых действий, передаваемый через регистр BL, поможет Вашей программе правильно обработать ошибку и избежать зависания системы. Приведем таблицу кодов предполагаемых действий:


Таблица 4

(0) 2 int20h двоичный код команды int 20h (программы могут использовать эту команду для завершения своей работы)
(+2) 2mem_top нижняя граница доступной памяти в системе в параграфах
(+4) 1reserv1 зарезервировано
(+5) 5call_dsp команда вызова FAR CALL диспетчера MS-DOS
(+10) 4term_adr адрес завершения (Terminate Address)
(+14) 4cbrk_adr адрес обработчика Ctrl-Break
(+18) 4crit_err адрес обработчика критической ошибки
(+22) 2parn_psp сегмент PSP программы, запустившей данную программу (программы-родителя)
(+24) 20file_tab таблица открытых файлов, если здесь находятся байты 0FFH, то таблица не используется
(+44) 2env_seg сегмент блока памяти, содержащего переменные среды
(+46) 4ss_sp адрес стека SS:SP программы
(+50) 2max_open максимальное число открытых файлов
(+52) 4file_tba адрес таблицы открытых файлов
(+56) 24reserv2 зарезервировано
(+80) 3disp диспетчер функций DOS
(+83) 9reserv3 зарезервировано
(+92) 16fcb1 форматируется как стандартный FCB, если первый аргумент командной строки содержит правильное имя файла
(+108) 20fcb2 заполняется для второго аргумента командной строки аналогично fcb1
(+128) 1p_size число значащих символов в неформатированной области параметров, либо буфер обмена с диском DTA, назначенный по умолчанию
(+129) 127 parm неформатированная область параметров, заполняется при запуске программы из командной строки
Для обращения к полям PSP файл sysp.h содержит следующее определение: #pragma pack(1) typedef struct _PSP_ { unsigned char int20h[2]; unsigned mem_top; unsigned char reserv1; unsigned char call_dsp[5]; void far *term_adr; void far *cbrk_adr; void far *crit_err; unsigned parn_psp; unsigned char file_tab[20]; unsigned env_seg; void far *ss_sp; unsigned max_open; void far *file_tba; unsigned char reserv2[24]; unsigned char disp[3]; unsigned char reserv3[9]; unsigned char fcb1[16]; unsigned char fcb2[20]; unsigned char p_size; unsigned char parm[127]; } PSP; #pragma pack()
Приведем программу, определяющую адрес первого блока MCB: /** *.Name get_fmcb * *.Title Получить адрес первого MCB * *.Descr Функция возвращает адрес первого блока MCB * *.Params MCB far *get_fmcb(CVT far *cvt) * * cvt - адрес векторной таблицы связи * *.Return Указатель на первый блок MCB **/ #include "sysp.h" MCB far *get_fmcb(CVT far *cvt) { return((MCB far *)FP_MAKE(cvt->mcb_seg,0)); }
В качестве аргумента функции get_fmcb необходимо передать указатель на векторную таблицу связи, полученный с помощью описанной ранее функции get_mcvt.
Для получения адреса следующего MCB можно использовать функцию get_nmcb: /** *.Name get_nmcb * *.Title Получить адрес следующего MCB * *.Descr Функция возвращает адрес следующего блока MCB * или 0, если это последний блок. В качестве * параметра используется указатель на предыдущий * блок MCB * *.Params MCB far *get_fmcb(MCB far *mcb) * * mcb - адрес предыдущего MCB * *.Return Указатель на следующий блок MCB или 0, если * это последний MCB **/ #include <dos.h> #include "sysp.h" MCB far *get_nmcb(MCB far *mcb) { unsigned seg, off; if(mcb->type == 'M') { seg = FP_SEG(mcb) + mcb->size + 1; off = FP_OFF(mcb); return((MCB far *) FP_MAKE(seg,off)); } else return ((MCB far *)0); }
В завершение описания блоков управления памятью приведем программу, выводящую некоторую информацию об активных MCB. Эта программа определяет адрес векторной таблицы связи, получает из этой таблицы адрес первого MCB и сканирует весь список MCB. #include <dos.h> #include <stdio.h> #include "sysp.h" void main(void); void main(void) { CVT far *cvt; MCB far *mcb; printf("\nБлоки управления памятью (MCB)" "\nCopyright (C)Frolov A., 1990\n" "\nАдрес MCB Тип Владелец Размер" "\n--------- --- -------- ------" "\n"); cvt=get_mcvt(); mcb=get_fmcb(cvt); for(;;) { if(mcb == (MCB far *)0) break; printf("%Fp %c %04X %04X\n", mcb, mcb->type, mcb->owner, mcb->size); mcb=get_nmcb(mcb); } exit(0); }



Таблица 4

0загрузить и выполнить программу;
1загрузить, но не выполнять программу (внутренняя подфункция для DOS 3.х);
2загрузить, но не выполнять программу (внутренняя подфункция для DOS 2.х);
3загрузить программу как оверлей (не создавать PSP).
Для функции 0 регистры DS: DX должны указывать на полный путь запускаемой программы в формате ASCIIZ ( т.е. текстовая строка, закрытая двоичным нулем). Блок параметров EPB (Exec Parameter Block) в этом случае имеет следующий формат:



Таблица 4

(0) 1sizeДлина запроса в байтах ( длина заголовка запроса плюс длина переменной части запроса)
(+1) 1unitНомер устройства (используется для блочных устройств, указывает, с каким именно устройством, обслуживаемым драйвером, будет работать операционная система)
(+2) 1cmdКод команды, которую требуется выполнить (может иметь значение от 0 до 18h)
(+3) 2statusСлово состояния устройства, заполняется драйвером перед возвратом управления операционной системе
(+5) 8reservedЗарезервировано
После вызова программы стратегии DOS передает управление программе прерывания (без параметров). Задача программы прерывания - выполнить команду, код которой находится в поле cmd заголовка запроса. Если драйвер блочного устройства обслуживает несколько логических устройств, то в поле unit находится номер устройства, для которого необходимо выполнить команду.
В зависимости от выполняемой команды запрос может содержать другую информацию, необходимую для выполнения команды.
Как результаты выполнения команды возвращаются DOS?
Данные (или адреса данных), полученные драйвером от физического устройства ввода/вывода, помещаются в область переменной части запроса. Кроме того, драйвер должен установить слово соcтояния устройства status в заголовке запроса в соответствии с результатами выполнения команды.
Приведем формат слова состояния устройства:



Таблица 4

(0) 1sizeДлина запроса в байтах ( длина заголовка запроса плюс длина переменной части запроса)
(+1) 1unitНомер устройства (используется для блочных устройств, указывает, с каким именно устройством, обслуживаемым драйвером, будет работать операционная система)
(+2) 1cmdКод команды, которую требуется выполнить (может иметь значение от 0 до 18h)
(+3) 2statusСлово состояния устройства, заполняется драйвером перед возвратом управления операционной системе
(+5) 8reservedЗарезервировано
После вызова программы стратегии DOS передает управление программе прерывания (без параметров). Задача программы прерывания - выполнить команду, код которой находится в поле cmd заголовка запроса. Если драйвер блочного устройства обслуживает несколько логических устройств, то в поле unit находится номер устройства, для которого необходимо выполнить команду.
В зависимости от выполняемой команды запрос может содержать другую информацию, необходимую для выполнения команды.
Как результаты выполнения команды возвращаются DOS?
Данные (или адреса данных), полученные драйвером от физического устройства ввода/вывода, помещаются в область переменной части запроса. Кроме того, драйвер должен установить слово соcтояния устройства status в заголовке запроса в соответствии с результатами выполнения команды.
Приведем формат слова состояния устройства:

Содержание раздела