Ввод спецификации и открытие файла
Для упрощения программирования работы с файлами DOS выполняет много полезных функций. Их использование возможно только при соблюдении определенных правил манипуляций с файлами. Одно из них заключается в том, что для работы с существующим файлом его надо предварительно открыть и получить идентификатор файла, необходимый для выполнения последующих действий.
Открытие существующего файла
DOS исполняет специальную функцию, предназначенную для открытия существующего файла (open File). Она имеет код 3D0h и вызывается через прерывание int 2ih. Перед вызовом функции в регистрах ds:dx указывается адрес начала строки, содержащей спецификацию файла. В регистр ai помещается код режима открытия: 0 – для чтения, 1 – для записи, 2 – для чтения и записи (для редактирования), а в регистре ah указывается код функции 3Dh.
Если файл существует, то он открывается. При возврате из DOS признак переполнения (разряд carry регистра флагов) очищен, а в регистре ах нахо-дится идентификатор файла (file handle), который надо сохранить в специально выделенной переменной (мы обозначали ее handle). Идентификатор нужен DOS для работы с конкретным файлом. По существу, это порядковый номер файла, открытого задачей.
Если при возврате из DOS флаг переполнения установлен, то файл не был открыт по каким-то причинам. Наиболее вероятно из-за ошибки в тексте спецификации. Поэтому задача должна проверять состояние разряда С и выводить аварийное сообщение, если он установлен.
Запомним, что спецификация должна содержать данные, необходимые для поиска файла на диске, например, C:\Windows\Clouds.bmp. При обработке спецификации DOS преобразует строчные буквы в заглавные, поэтому можно использовать буквы любого размера. Если путь для поиска не указан, то DOS ищет файл в текущем каталоге. Признаком конца спецификации является пустой байт.
Подпрограмма открытия файла
Способ ввода спецификации зависит от установленного видеорежима и от формы диалога, поддерживаемого задачей. Предположим, что задача установила один из видеорежимов VESA, а для диалога с оператором используются информационные строки. То есть нa экран выводится подсказка оператору, и задача переходит в режим ввода данных с клавиатуры. Подпрограммы, необходимые для вывода информационных строк и ввода данных с клавиатуры рассмотрены во второй части главы 5 данной книги. Поэтому мы возьмем за основу описанный там Примep 5.29 и дополним его действиями, необходимыми для открытия файла.
Текст подпрограммы приведен в примере А.1. Перед ее вызовом в регистрах ds:si надо указать адрес подсказки оператору, содержащей текст типа "Введите спецификацию файла >", он должен заканчиваться пустым байтом. После возврата из подпрограммы проверяется состояние С-разряда и содержимое регистра ах. Если С-разряд очищен, а содержимое ах отлично от 0, то оно является идентификатором файла.
Пример А.1. Подпрограмма ввода спецификации и открытия файла.
GetSpec: push Cur win сохранение исходного значения Cur win mov ax, Inflinw ax = номер окна информационной строки mov Cur win, ax Cur win = ax call Savinfo сохранение исходного фона jmp short outstr переход на выборку первого символа BUtl: call outsgn вывод на экран очередного символа outstr: lodsb al = код очередного символа (al = ds: si) or al, al конец выводимого текста? jne outl › нет, переход на метку outl call Inline ввод строки теста с клавиатуры call Delinfo удаление информационной строки с экрана pop Cur win восстановление исходного значения Cur win call setwin восстановление исходного окна mov al, Linbuf al = первый байт строки or al, al спецификация введена? jnz OpenFr › нет, пустая строка xor ah, ah очистка регистра ah ret возврат из подпрограммы OpenFr: lea dx, Linbuf dx = адрес начала спецификации файла mov ax, SDOOh al = 0, ah = 3D – код функции int 21h обращение к DOS для открытия файла ret возврат из подпрограммы
Первые 13 команд подпрограммы повторяют текст примера 5.29. В этой части на экран выводится подсказка оператору, а в буфер Linbuf записываются вводимые с клавиатуры символы. После нажатия оператором на клавишу Enter в Linbuf записывается пустой байт, ввод прекращается, подсказка и ответ оператора удаляются с экрана, а на их месте восстанавливается исходное изображение.
Дополнительные действия начинаются с анализа содержимого первого байта буфера Linbuf. Если он пуст, то просто очищается регистр ах и происходит возврат из подпрограммы. Это предусмотрено на тот случай, если оператор раздумает вводить спецификацию и просто нажмет клавишу Enter.
Если первый байт Linbuf не пустой, то предполагается, что оператор ввел спецификацию. В таком случае в регистр dx загружается адрес Linbuf, в регистр ах записываются код функции 3Dh и признак открытия файла для чтения (оо). После этого происходит обращение к DOS через прерывание int 2ih и возврат из подпрограммы.
Если файл успешно открыт, то после возврата из подпрограммы С-разряд очищен, а содержимое ах отлично от нуля, его надо сохранить в переменной handle и можно читать заголовок файла.