Недостаточно ресурсов: блоков 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 в заголовке запроса в соответствии с результатами выполнения команды.
Приведем формат слова состояния устройства: