Недостаточно ресурсов: блоков FCB, памяти
Таблица 4
| 1 | Недостаточно ресурсов: блоков FCB, памяти и т.д. | 
| 2 | Временная ситуация | 
| 3 | Нет прав доступа | 
| 4 | Внутренняя ошибка DOS | 
| 5 | Ошибка аппаратуры | 
| 6 | Системная ошибка DOS (нет CONFIG.SYS и т.п.) | 
| 7 | Ошибка в прикладной программе | 
| 8 | Файл или объект не найден | 
| 9 | Неправильный формат файла или объекта | 
| 10 | Файл или объект заблокирован | 
| 11 | Ошибка носителя данных | 
| 12 | Файл или объект уже существует | 
| 13 | Прочие ошибки | 
Таблица 4
| (0) 2 | int20h | двоичный код команды int 20h (программы могут использовать эту команду для завершения своей работы) | 
| (+2) 2 | mem_top | нижняя граница доступной памяти в системе в параграфах | 
| (+4) 1 | reserv1 | зарезервировано | 
| (+5) 5 | call_dsp | команда вызова FAR CALL диспетчера MS-DOS | 
| (+10) 4 | term_adr | адрес завершения (Terminate Address) | 
| (+14) 4 | cbrk_adr | адрес обработчика Ctrl-Break | 
| (+18) 4 | crit_err | адрес обработчика критической ошибки | 
| (+22) 2 | parn_psp | сегмент PSP программы, запустившей данную программу (программы-родителя) | 
| (+24) 20 | file_tab | таблица открытых файлов, если здесь находятся байты 0FFH, то таблица не используется | 
| (+44) 2 | env_seg | сегмент блока памяти, содержащего переменные среды | 
| (+46) 4 | ss_sp | адрес стека SS:SP программы | 
| (+50) 2 | max_open | максимальное число открытых файлов | 
| (+52) 4 | file_tba | адрес таблицы открытых файлов | 
| (+56) 24 | reserv2 | зарезервировано | 
| (+80) 3 | disp | диспетчер функций DOS | 
| (+83) 9 | reserv3 | зарезервировано | 
| (+92) 16 | fcb1 | форматируется как стандартный FCB, если первый аргумент командной строки содержит правильное имя файла | 
| (+108) 20 | fcb2 | заполняется для второго аргумента командной строки аналогично fcb1 | 
| (+128) 1 | p_size | число значащих символов в неформатированной области параметров, либо буфер обмена с диском DTA, назначенный по умолчанию | 
| (+129) 127 | parm | неформатированная область параметров, заполняется при запуске программы из командной строки | 
Приведем программу, определяющую адрес первого блока 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). | 
Таблица 4
| (0) 1 | size | Длина запроса в байтах ( длина заголовка запроса плюс длина переменной части запроса) | 
| (+1) 1 | unit | Номер устройства (используется для блочных устройств, указывает, с каким именно устройством, обслуживаемым драйвером, будет работать операционная система) | 
| (+2) 1 | cmd | Код команды, которую требуется выполнить (может иметь значение от 0 до 18h) | 
| (+3) 2 | status | Слово состояния устройства, заполняется драйвером перед возвратом управления операционной системе | 
| (+5) 8 | reserved | Зарезервировано | 
В зависимости от выполняемой команды запрос может содержать другую информацию, необходимую для выполнения команды.
Как результаты выполнения команды возвращаются DOS?
Данные (или адреса данных), полученные драйвером от физического устройства ввода/вывода, помещаются в область переменной части запроса. Кроме того, драйвер должен установить слово соcтояния устройства status в заголовке запроса в соответствии с результатами выполнения команды.
Приведем формат слова состояния устройства:
Таблица 4
| (0) 1 | size | Длина запроса в байтах ( длина заголовка запроса плюс длина переменной части запроса) | 
| (+1) 1 | unit | Номер устройства (используется для блочных устройств, указывает, с каким именно устройством, обслуживаемым драйвером, будет работать операционная система) | 
| (+2) 1 | cmd | Код команды, которую требуется выполнить (может иметь значение от 0 до 18h) | 
| (+3) 2 | status | Слово состояния устройства, заполняется драйвером перед возвратом управления операционной системе | 
| (+5) 8 | reserved | Зарезервировано | 
В зависимости от выполняемой команды запрос может содержать другую информацию, необходимую для выполнения команды.
Как результаты выполнения команды возвращаются DOS?
Данные (или адреса данных), полученные драйвером от физического устройства ввода/вывода, помещаются в область переменной части запроса. Кроме того, драйвер должен установить слово соcтояния устройства status в заголовке запроса в соответствии с результатами выполнения команды.
Приведем формат слова состояния устройства:
