800-й, 720-й, ... — Архив WASM.RU

Все статьи

800-й, 720-й, ... — Архив WASM.RU

  Случилось так, что авторам в руки попали машины на которых драйвер 800 потерпел фиаско. Занявшись выяснением причин этого конфуза авторы написали свой драйвер drv720, способный выполнять те же функции, будучи при этом совместимым со своим предшественником.

  Драйвер 800 Альберто Паскуале (Alberto Pasquale) давно популярен у пользователей IBM-совметимых компьютеров типа AT. Этому способствовали, на наш взгляд, относительная дороговизна и недостаточная доступность дискет HD (High Density). Дело в том, что среди многочисленных форматов, реализуемых этим драйвером, есть два 720 и 800 Кбайт, пригодных для дешевых широко распространенных дискет DD (Double Density) и позволяющих радикально повысить объем записываемых данных. При радиальной плотности записи 96 TPI (дорожек на дюйм), по крайней мере первый из них обеспечивает высокую сохранность информации (почти такую же, как на дискетах 360 Кбайт). Использование же других форматов, поддерживаемых драйвером 800, менее надежно и вследствие этого используется существенно реже.

Спустя год (1991), правда, появились вполне надежные дискеты объемом 1200 Кбайт, которые легко форматировались до 1440 Кбайт).

  Драйвер 800 - постоянно резидентная программа, расширяющая возможности подсистемы ввода/вывода BIOS компьютера. Принцип его действия основан на подмене вектора 13h, благодаря чему он перехватывает все обращения к подсистеме ввода/вывода BIOS и иногда вмешивается в выполнение некоторых функций "Прочесть сектор" (AH=02h) и "Установить среду" (AH=18h) [1,3].

  Рассмотрив, к чему сводятся действия драйвера 800 при перехвате запросов посылаемых НГМД DOS. Распознав обращение к функции "Прочесть сектор", драйвер определяет, не является ли оно запросом на считывание первого сектора на нулевом цилиндре и нулевой поверхности (сектор начальной загрузки - НЗ(boot sector). значения регистров CL=0, CH=1, DH=0). Первый сектор всегда запрашивается драйвером НГМД для вновь установленной дискетты по запросу файловой системы DOS "Построить BPB" (BPB - Base Parameter Block).

  Если это так то драйвер считывает сектор с помощью вызова стандартного обработчика прерывания 13h и возвращает управление обратно. Получив управление он определяет количество секторов на дорожках установленной дискеты, прочитав данные из BPB, считанного сектора (смещение 11 [1]). В противном случае управление передается стандартному обработчику без возврата. Определив количество секторов на дорожке, драйвер изменяет таблицу параметров дискеты (указатель на нее он подставляет в вектор 1Eh вместо указателя стандартной таблицы DOS). Модификации подвергаются поле числа секторов и размеры межсекторного промежутка (GAP) для чтения/записи, которая используется системой ввода/вывода (СВВ) для настройки НГМД. Кроме того для форматов 720 и 800 Кбайт, требующих одинарного смещения головок (что обеспечивает на дисководах емкостью 1200 Кбайт работу с 80-дорожечными дискектами), драйвер 800 заносит в байт состояния дисковода по адресу 40h:90h + drv, где drv - дисковод (0 или 1), "магический байт" 54h, означающий, что скорость передачи данных - 300Кбит/с, шаг перемещения - одинарный, признак - "Среда установленна" и что дискета 360 Кбайт помещена в дисковод 1,2 Мбайт [4]. Благодаря этому обеспечивается чтение и запись дискет нестандартных форматов.

  Для работы с дискетами недостаточно, конечно, операций чтения/записи, необходима также возможность их нестандартного форматирования. С этой целью драйвер 800 обрабатывает функцию "Установить среду", которая запрашивается драйвером НГМД DOS перед началом выполнения этой операции. При этом в СВВ (см. выше) передается число цилиндров, поверхностей и секторов на дорожке. СВВ проверяет эти параметры на допустимость и, если они верны, устанавливает требуемую скорость передачи данных (500, 300 или 250 Кбит/с) и шаг перемещения головок (двойной или одинарный). Затем СВВ возвращает в ES:DI указатель на таблицу параметров дискеты, подходящую для этого формата, а в регистр AH - ноль.

  Табл. 1. Межсекторный промежуток (GAP) при различных скоростях передачи данных

Число секторов на дорожке Межсекторный промежуток
чтение/запись форматирование чтение/запись форматирование
300 Кбит/с 500 Кбит/с
9 1Bh (800) 50h (800)    
2Ah (720) 50h (720)    
10 1Bh 2Ah    
11     1Bh (800) 54h (800)
    2Ah (720) 54h (720)

  Обычно СВВ содержит несколько таких таблиц, в которых для конкретного формата дискеты специфичны число секторов на дорожке и GAP для форматирования. Из них обычно только три предназначенны для дискет 5,25 дюйма и соответствуют трем форматам - 320 Кбайт, 360 Кбайт, 1200 Кбайт. Если параметры неверны, СВВ возвращает в регистр AH отличный от нуля код.

  Обрабатывая функцию "Установить среду" без привлечения стандартной СВВ, драйвер 800 возвращает ссылку в ES:DI, дополнительно, при этом, модифицируя собственную таблицу параметров дискеты, в соответствии с запрошенным форматом. Эти изменения затрагивают байт состояния дисковода. Туда заносится 74h (для 40-дорожечных дискет, скорости 300 Кбит/с, формата 360 Кбайт и менее), 54h (для 80-дорожечных дискет, такой же скорости передачи, формата 800 или 720 байт/с) или 15h (для 80-дорожечных дискет, скорости передачи 500 Кбит/с, формата 1200Кбайт/с и более).

  Описанные (упрощенно) действия достаточно просты, что позволило автору (Alberto Pasquale) драйвера 800 уместить код драйвера всего в 864 байта. (Хотя после дизассемблирования и последующей компиляции автору удалось сократить это значение до 400 байт. Интересно как? Да, просто, убрал из исходника торчащий там текст помощи, разметив его во внешнем файле :-). Копирайт конечно сохранил). Основная нагрузка при таком построении драйвера лежит на стандартной СВВ. И все бы было хорошо, если бы не появилось огромное количестко машин, в которых СВВ совместно с 800 несправился с возлагаемой на него задачей. Авторы решили разобраться в проблеме и родился драйвер drv720 (720 для краткости).

  Предлагаемый драйвер радикально отличается от драйвера 800 наличием собственной СВВ, способной самостоятельно выполнять такие функции, как чтение, запись, верификация и форматирование. Она тем не менее не дублирует полностью СВВ компьютера. Некоторые сервисные функции стандартной СВВ (например, определение скорости передачи данных, шага перемещения головок, проверка количества дорожек, распознавание открытия замка дисковода - смены дискеты) не реализуются. Для их выполнения строятся обращения к основной СВВ. Благодаря этому драйвер получился достаточно компактным (2 Кбайта).

  Особенности 720-го, упомянотые выше, исключают ипользование вектора 13h, для взаимодействия с драйвером НГМД DOS (это справедливо по крайней мере для версии DOS 3.30). Дело в том, что первичная обработка прерывания 13h выполняет корректировку указателя на буфер, передаваемого СВВ драйвером НГМД DOS в ES:BX. Без этой коррекции невозможны операции по обмену данными (чтени/запись) большими порциями из-за пересечения буферами границ 64-Кбайтных физических сегментов. Поэтому 720-й использует вектор 40h (обработчик обращения к СВВ машины [1,3], благодаря чему драйвер на входе получает уже скорректированные адреса буферов).

  Теперь мы рассмотрим, как осуществляется распознавание формата дискеты нашим драйвером. Перед выполнением операций чтения/записи DOS вызывает функцию "Проверить среду" (Test Media), для того чтобы гарантировать перенастройку внутренних структур DOS в том случае, если пользователь сменил дискету. На этот запрос драйвер НГМД откликается обращением к СВВ компьютера для выполнения команды "Прочесть статус смены диска" (Read change-of-disk status, AH=16h) [1,3]. В ответ на него СВВ возвращает в регистр AH либо 0 (если замок не открывался), либо 6 (дискета установлена заново).

  В зависимости от полученного сообщения драйвер НГМД DOS отвечает: "Среда изменена" или "Среда не изменена". В первом случае файловая система инициирует считывание сектора начальной загрузки (НЗ), содержащего BPB. Делается это посылкой запроса драйверу НГМД DOS "Построить BPB" (Build BPB). Во втором случае - считается, что дискета не заменялась и никаких действий не производится.

  Функция 16h (Read change-of-disk status) положена в основу механизма узнавания драйвером 720 "своих" форматов 720 и 800 Кбайт. Распознав функцию, обработчик 40h вектора прерывания драйвера 720, передает управление подпрограмме определения формата дискеты, в результате деятельности которой либо взводится, либо сбрасывается флажок, определяющий, кому будут переданы последующие обращения, стандартной или встроенной СВВ.

  Свою работу программа начинает с вызова функции 16h стандартной СВВ, если ответ 0(дискета не менялась), то управление возвращается запросившей данную функцию программе (чаще всего это драйвер НГМД DOS), в противном случае выполнение подпрограммы продолжается. Затем она пыиается определить, не является ли дискета отформатированной на 1200 Кбайт. Для этого стандартная СВВ выполняет операцию "Верифицировать сектор" (Verify sector AH=4) для сектора 1 на нулевой поверхности нулевого цилиндра. Эта функция удобна тем, что не инициирует обмена между контроллером дисковода и оперативной памятью, благодаря чему не требуется буфер. Если при этом будет возвращен не нулевой код, предпринимается еще одна попытка ее выполнения с предварительным сбросом контроллера посредством выполнения команды "Рекалибтовать" (Recalibrate, AH=0). Если она также неудачна, встроенная СВВ 720-го не включается, а дискета считается либо не форматированной, либо поврежденной. Реагирвать на эту ситуацию предоставляется стандартной СВВ.

  Выполнение команды "Верифицировать сектор" означает, что стандартная СВВ уже определила, с какой скоростью передачи данных была записана информация на дискету (500 или 300 Кбит/c), что контроллер настроен на эту скорость, а так же установлен шаг премещения головок.

  Теперь можно выяснить, соответствует ли формат дискеты 1200 Кб. Для этого достаточно проверить, упомянутый ранее, байт состояния дисковода. Наличие в нем 15h говорит о том, что дискета 1200 Кбайт. Наличие в нем 74h означает возможность одного из вариантов - 360, 720 или 800 Кбайт. Подпрограмме распознавания предстоит выяснить какой именно. Для этого сначало определяется не 360-ли Кбайтная это дискета. Для выяснения этого выполняется функция "Верифицировать сектор" для сектора 1 на нулевой поверхности цилиндра 2, однакодля выполнения этой операции используется встроенная СВВ 720-го, работающая только с одинарным шагом перемещения головок. Поэтому, если дискета 360 Кбайт (40 дорожек), головки окажутся неправильно позиционированны. В результате сектор с идентификатором 02000102h (второй цилиндр, нулевая поверхность, первый сектор, размер сектора 512 байт) не будет найден. Возвращаемый при этом код равен 4 (сектор не найден). Управление в этом случае передается вызвавшей программе. Если код возврата 0, то формат либо 720, либо 800. Для разрешения этой ситуации подпрограмма распознавания устанавливает в вектор 1Eh указатель на собственную (drv720) таблицу параметров дискеты, предварительно настроенную на 10 секторов на дорожке (см. Табл. 1). Затем подается команда "Верефицирвать сектор" для 10-го сектора нулевой поверхности нулевого цилиндра. Для ее выполнения используется встроенная СВВ. Если сектор не найден (код 4) - формат 720 Кбайт и подпрограмма перенастраивает таблицу на 9 секторов на дорожке. Если код равен 0 - формат 800 Кбайт и изменять таблицу не надо.

  В случае распознавания команды "Установить среду" (Set Media AH=18h) управление передается подпрограмме эмуляции этой функции. При это проверяются поступившие параметры (число цилиндров, поверхностей, секторов). Если они не соответствуют форматам 720 или 800 Кбайт, управление передается стандартной СВВ. Если параметры оценены, как верные, подпрограмма устанавливает скорость передачи данных 300 Кбит/с, что достигатся непосредственным обращением к порту контроллера дисковода 3F7h:

mov dx,3F7h
mov al,1
out dx,al

  После этого таблица параметров дискеты драйвера 720 настраивается либо на 9, либо на 10 секторов в соответствии с таблицей, а указатель на нее ES:DI возвращается обратившейся программе. Если обработчик 40h-го прерывания распознает функции начиная с AH=0 до AH=5, он отдает управление либо встроенной, либо стандартной СВВ.

  Завершая рассмотрение взаимодействия двух СВВ отметим, что драйвер 720 перехватывает, кроме векторов 40h и 1Eh, вектор 16h. Это сделанно для того, чтобы можно было отключить драйвер. По умолчанию используется сочетание клавиш - SHIFT+F12. Вместе с драйвером поставляется утилика, позволяющая изменять сочетания клавиш (confdrv). Информация об используемых клавишах хранится в файле "drv720.cfg". Драйвер 720 отображает распознаный формат в левом верхнем углу экрана надписями: "720К", "800" или "None".

  Исходники здесь.

  Литература:
  1. Tech Help version 4.02. 1990.
  2. MS-DOS Programmer Reference v.4.0, Microsoft Corporation, publ. in USA - 1988
  3. Brown Ralf. Interrupt List, Release 91.1, Last change 1/5/91.
  4. IBM PC/AT Technical Reference, first edition. - sept. -1985.

2002-2013 (c) wasm.ru