Система дисковой памяти и ее использование.

02-25-96 10:28am diski_ap.lek
Роберт Журден "Справочник программиста на компьютере фирмы IBM".
А.Г.Шевчик, Т.В.Демьянков "Справочник программиста и пользователя" серия "Карманная энциклопедия" М."Кварта" 1993.
Ю.М.Казаринов "Микропроцессорный комплект К1810. Структура, программирование, применение." Справочная книга. М. "Высшая школа" 1990.
Serge Pachkovsky Новосибирск; Перевел Максим Петров, г. Оренбург

Система дисковой памяти и ее использование.

Физические аспекты записи/чтения данных. Метод MFM

Модифицированный метод частотной модуляции (MFM) для записи на гибкий диск был впервые использован в IBM System 34, часто он называется "запись двойной плотности". Термину "запись одинарной плотности" прямо соответствует метод частотной модуляции (FM) IBM 3740, который использует 4 mс для записи одного бита данных.
Изначальный метод MFM использовал один бит в 2 mс ячейке, но для гибких дисков IBM PC было использовано 4 mс. Таким образом, неформатируемая емкость одной дорожки составляет 6.1 KБайт. Так называемые диски высокой плотности (HD) PC просто соответствуют 2 mс для одного бита, т.е. действительной спецификации метода MFM.
При использовании метода MFM "двойная плотность" обеспечивается путем удаления синхробитов из записываемой последовательности. При таком подходе теряется надежность считавания при изменении характеристик дисковода (колебания скорости вращения) и контроллера (различия частоты тактового питания).

Кодирование информации осуществляется в соответствии со следующими принципами:

  1. Величина битовой ячейки (временная и геометрическая) является постоянной и определяется тактовой частотой контроллера и скоростью вращения диска.

  2. Единица кодируется изменением направления магнитного потока (соответственно наличием импульса при чтении) в середине битовой ячейки.

  3. Ноль кодируется отсутствием изменения направления магнитного потока.

  4. Для уменьшения частотного диапазона сигнала при записи цепочки нулей, начиная со второго нуля, вставляются синхроимпульсы в начало битового интервала (таймерный бит).

  5. Для устранения возможности пересинхронизации системы при наличии длинных нулевых цепочек, после четвертого нуля записывается единичный синхробит.

Рис. Запись данных методом MFM.

 

Декодирование данных зависит от начальной позиции битовой ячейки. Поэтому во избежание двусмысленностей при декодировании бит данных каждое поле данных на дорожке должно снабжаться полем синхронизации.
Поле синхронизации и байт ID
Поле синхронизации по методу MFM состоит из 12 нулевых байтов и следующих за ними 3 байтов A1h (10100001b).
Нулевые байты служат для нормального выравнивания ячеек данных, а байты A1h иденфицируют начало собственно байтов данных (байт A1h является начальной точкой для отсчета контрольной суммы).
За полем синхронизации следует байт-идентификатор (ID), определяющий характер записанных данных:

Общий формат дорожки

Стартовой точкой для всех операций на гибком диске служит физическая индексная метка, которая порождается индексным отверстием в дискетте. Полный формат дорожки флоппи диска, начинающийся от физической индексной метки, может быть описан следующим образом:

Для n от 1 до N-1, где N - количество секторов на дорожке:

Для последнего сектора на дорожке:

Поле заголовка сектора содержит байт FEH, за которым следуют байты со значениями C,H,R,N (значения устанвливаются при форматировании), где:

Эти байты (включая FEH) проверяются посредством 16-ти битового циклического избыточного кода (CRC).
Поле данных содержит байт FBH, за которым следуют 128 * 2^N байтов информации и два байта CRC.

ПРИМЕЧАНИЕ: Во все промежутки при форматировании записывается код 4Eh; размер промежутка 50..80 байт.

 

Контроллер Intel 8272A гибкого диска

Реально в компьютере может отсутствовать микросхема Intel 8272A, но ее регистры полностью присутствуют в любой другой микросхеме котроллера гибких дисков.

Команды 8272A выполняются в три последовательные фазы:

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

Несмотря на то, что во время фазы команды или фазы результата запрошенные FDC данные могут надолго задерживаться (данные могут запоминаться во внутренних регистрах 8272A), все запросы FDC во время выполнения должны удовлетворяться немедленно, иначе FDC выдает ошибку переполнения данных и завершает операцию. Более точно говоря, запрашиваемые данные не могут быть задержаны больше чем на время передачи 8 бит данных.

Хотя сам 8272A может работать как в режиме DMA, так и в режиме неактивного DMA, только относительно быстрый процессор способен выполнять передачу данных на такой скорости. Существующие FDC в не-DMA режиме для дисков двойной плотности требуют по крайней мере 80286 на 6 MHz, а AT-диски высокой плотности могут проглотить и все 10 MHz 80286 процессора.

Регистры 8272A

Чип 8272A взаимодействует с CPU через два регистра:

MSR только читается. DR может быть прочитан или записан, что определяется битом RQM в регистре MSR. Назначение битов в MSR приведено на рис.

Рис. Главный регистр состояния 8272A.

Направление передачи зависит от значения бита DIO.
8272A запоминает текущий номер цилиндра для каждого присоединенного к к нему дисковода. Поскольку дисковод не может отличить один цилиндр от другого (исключая цилиндр 0), это необходимо для выполнения операции поиска, которая переводит FDC в режим пошагового движения. Все эти регистры сбрасываются при сбросе FDC (но дисковод не возвращается на дорожку 0 при сбросе).

Другие важные внутренние регистры содержат время перехода с дорожки на дорожку, время разгрузки головки и время загрузки головки (cм. спецификацию команд).

Сводка команд 8272A

Команды 8272A могут быть разбиты на три группы:

Передача данных включает чтение данных, чтение удаленных данных, запись данных, запись удаленных данных и три команды сканирования: на равно, на меньше или равно, на больше или равно. Контроль дисковода включает команды рекалибровки, поиска, определения состояния дисковода, определения состояния прерывания и форматирования дорожки.
Команды чтения ID и чтения дорожки могут рассматриваться как диагностические. Все команды с неверным первым байтом рассматриваются как неправильные.

Команды 8272A могут быть легко идентифицированы по младшему нибблу первого байта команды согласно таблице:

Последовательность выполнения команды 8272A состоит из следующих шагов:

0. Если в операции используется DMA, необходимо настроить его в режим передачи одиночных байтов.
1. Для каждого байта команды, ожидая пока бит RQM не станет 1, проверяется бит DIO: значение 0 говорит о том, что FDC готов принять команду, 1 сообщает, что случилось одно из двух: либо ваша команда не распознана FDC (и следующее чтение из регистра данных вернет вам 80H), либо что вы уже переслали все данные FDC (и также то, что ваша команда неверна).
Если ваша команда не имеет фазы выполнения и результата (команда Определить), ваши действия на этом прекращаются.
2. Если вы используете FDC в не-DMA режиме и команда передает данные во время фазы выполнения (чтение, запись, форматирование), вы должны на этом шаге ожидать, пока бит NDM не станет = 0. Пока NDM не равен 0, для каждого считанного или записываемого байта вы должны ждать установки бита RQM, после чего только писать в (или читать из) регистра данных следующий байт.
Если вы используете для передачи режим DMA (или не передаете данные вообще), просто переходите на шаг 3.
3. Об окончании фазы выполнения сигнализирует IRQ 6 (INT 0EH). Вы можете либо разрешить прерывания 8272A и отслеживать их в своей программе обработки прерывания, либо непрерывно опрашивать регистр запроса прерываний (IRR) 8259A.
Если команда не имеет фазы выполнения (Получение состояния дисковода), переходите на шаг 4.
4. В фазе результата вы читаете состояние команды из FDC посредством байта RQM (следует при этом быть уверенным, что DIO = 1).

8272A может вернуть вплоть до 3 байтов состояния (которые см. ниже) с другими данными, которые изменяются от команды к команде.

Рис. Байты состояния 8272A 0-3

ST0.

ST1.

ST2.

ST3.

Описание команд 8272A

Здесь приведены все команды 8272A в том порядке, в каком они приводятся в таблице команд 8272A руководства по 8272A фирмы Intel.
Конечно, этого описания недостаточно для создания драйвера гибкого диска. Для получения полной информации см. руководство фирмы Intel или приложение A в качестве простого примера.

Чтение ID сектора

Результат: ST0/ST1/ST2/C/H/R/N

Чтение удаленных данных

Чтение дорожки

Эта команда читает поля данных не считаясь со значениями

C/H/R/N записанными в ID сектора. Поля данных, у которых отсутствует правильный ID могут быть прочитаны с помощью этой команды. Хотя документация фирмы Intel указывает, что команда чтения дорожки прекращается тогда, когда нет вообще не найдены поля данных на дорожке или счетчик секторов превысит значение EOT, эта команда прекращается тогда, когда не найдена адресная метка данных после адресной метки ID сектора с плохим CRC.
Команда чтения дорожки принимает ЛЮБОЕ значение N, таким образом можно читать межсекторный промежуток (или всю дорожку, если N достаточно велико) вместе данными сектора. Сектора будут прочитаны в порядке появления их под головкой чтения/записи, т.е. если дорожка была отформатирована на 8 512-байтных секторов (с чередованием 1:1), и вы начали команду чтения дорожки с R = 1, N = 3, EOT = 4, сектора 1, 3, 5 и 7 будут прочитаны.

Запись данных

Запись удаленных данных

Форматирование дорожки

Кстати: GPL = 0 понимается как 100H.

Сканирование на равно

Сканирование на меньше или равно

Сканирование на больше или равно

Рекалибровка

Все 4 дисковода могут быть рекалиброваны одновременно. 8272A может выполнять операцию чтения или записи на любом другом дисководе.
Так, команда получения состояния прерывания используется для того, чтобы отличить прерывание, вызванное завершением рекалибровки от прерывания, вызванного завершением операции.

FDC не разрешает выполнение какой-либо операции на рекалибруемом дисководе, пока состояние прерывания не укажет на прерывание по завершению поиска.

Получить состояние прерывания

8272A генерирует запрос на прерывание, если происходит какое-либо из следующих событий:

Процедура обслуживания прерывания легко различает эти события:

if NDM = 1 then запрос передачи данных
else
if CB = 1 then началась фаза результата
else
if SE = 0 then изменился сигнал готовности
else конец поиска или рекалибровки

 

Назначить

Все таймеры внутри 8272A фактически синхронизированы с сигналом WR CLK, так что все указанные здесь значения корректны при 500 KHz WR CLK или скорости передачи данных в 500 KBPS. Уменьшение частоты WR CLK влечет удлинение всех внутренних задержек.

Sense Drive Status

Seek

См. рекалибровку.

 

AT-Контроллер гибкого диска

Контроллер гибких дисков оригинального PC и XT был способен работать с четырьмя дисководами. FDC AT, хотя и совместим с ним на уровне регистров, может работать только с двумя, так что возможна установка двух FDC в AT. Большинство клонов BIOS'а не поддерживает второй FDC. Первый FDC использует адреса в промежутке 3F0-3F7, второй FDC в промежутке 370-377.

Вся приводимая здесь информация о первом FDC также может использоваться и ко второму с соответсвующим изменением ссылок на другие адреса. 8272A (или его более интегрированные эквиваленты) использует порты 3F4 (MSR) и 3F5 (DR).

Как вы уже могли видеть, 8272A сам не может управлять двигателем дисковода, этой цели служит регистр 3F2 (регистр цифрового вывода).

Рис. Регистр цифрового вывода (3F2H).

Второй добавочный регистр - это 3F7h (регистр состояния дискетты). (Этого регистра нет в старых XT, но он часто обнаруживается в современных клонах). Только два младших бита имеют значение при записи и один старший бит при чтении.
При записи в 3F7h могут быть заданы скорости передачи:

Три первых значения (от 00 до 10) упоминаются в руководствах IBM.
Хотя последнее значение не документировано, оно работает на любом FDC AT. (Эта скорость передачи предназначена для дисков одинарной плотности в 360 KБ дисководе). Значения от 00 до 10 предназначены для использования для MFM-дискетт, поскольку они используют для длины такта 1/4 длины цикла. 125 KBS использует для такта 1/8 длины цикла.

Поскольку FDC AT не имеет таймера для передачи со скоростью 175 KBS в режиме FM, диски одинарной плотности не могут быть записаны на дисководе высокой плотности (360 RPM). Однако, благодаря высокой сопротивляемости к ошибкам данных, записанных в режиме FM, диски одинарной плотности до сих пор могут быть прочитаны в 360 RPM дисководе. FM-дискетты могут быть прочитаны и записаны на 360KБ (300 RPM) дисководе.

При чтении 3F7h указывает изменении состояния дисковода: установлееный бит 7 ( TEST AL, 80H ) означает, что дискетта была сменена. Индикатор смены носителя сбрасывается после первого поиска цилиндра, отличного от нулевого.

1.2.5 "Нормальный" формат гибкого диска PC

Первые стандартные гибкие диски PC использовались как односторонние или двусторонние с 40 дорожками. Согласно спецификации фирмы Intel, они имели 8 секторов длиной 512 байт на дорожке, таким образом, использовалось 4096 байт (65%) из 6250 байт неформатируемой емкости дорожки. Сектора на дорожке были расположены последовательно (чередование 1:1), как и во всех других стандартных форматах. Более современные дискетты используют 9 и 10 секторов на дорожке или 74% и 82% дискового пространства соответственно. Теоретический предел емкости форматируемой дорожки двойной плотности составляет около 89.2% (5575 байт или 10.89 секторов на дорожке).

Такое приращение емкости гибкого диска стало возможным благодаря высокой стабильности скорости вращения в современных дисководах. Хотя отклонения в 2.5% от номинального разрешены IBM, реально величина нестабильности равна 0.2% от номинала.
Такая стабильность позволяет уменьшить длину межсекторного промежутка и за счет этого разместить больше секторов на дорожке.


Методы защиты от копирования.

Все рассмотренные методы касаются защиты, от несанкционированного копирования информации, поставляемой на гибких дисках. После установки программного продукта на винчестер, изложенный материал может быть применен в рамках требования предъявлять ключевую дискету при каждом запуске защищенного продукта.

ПРИМЕЧАНИЕ: Методы защиты изложены в виде основных идей и не все из них могут быть реализованы на стандартном оборудовании.

Внешний или пропущенный сектор

Ввиду того, что первые гибкие диски MS-DOS имели участок неиспользованного пространства на дорожке, это было использовано как очевидная идея для хранения на дорожке добавочных секторов вместе со стандартными секторами MS-DOS. Даже в хорошо упакованном формате 10 секторов на дорожку находится место для одного 256-байтного сектора.
Другим местом может служить для добавочных секторов может быть дорожка 41, которая не используется DOS, но доступна на большинстве дисководов. На 80 дорожечном устройстве, дополнительные сектора может быть скрыты на нечетных дорожках.

Сейчас этот способ пометки не может рассматриваться как хорошая защита от копирования, поскольку внешние сектора могут быть легко найдены командой чтения ID сектора. Любой из представленных на рынке побитных копировщиков может это сделать. В тоже время сектора на нечетных дорожках не могут быть найдены подобными программами.

Слабая запись данных

Это другой старый добрый метод защиты данных, который проявляется в в кажущемся различии данных во время последовательных операций чтения (слабые данные). Слабые данные могут появится в одном из двух случаев: либо данные попадают в цифровой "район неуверенности", либо посредством длинной серии нулевых данных и пропущенных синхробитов.
В первом случае, на решение FDC может повлиять случайный шум.
Во другом случае, случайные вариации в скорости вращения могут привести к сдвигу битовой ячейки относительно синхронизации. (Такие данные не могут быть записаны без аппаратных изменений в FDC).

Один хороший способ создания слабых данных состоит в помещении их на дефектную поверхность. Тогда слабые данные не могут исчезнуть после команды записи данных сектора. Дефекты на поверхностях создаются вручную, или используются дискеты с технологическим браком.

Слабые биты данных могут быть созданы также и программным путем. Первый подход состоит в манипулировании битами выбора дисковода в регистре цифрового ввода (3F2H). К примеру, если вы желаете создать слабый байт на дисководе A:, начните операцию записи, подождите, пока желаемый байт будет передан на дисковод (но не FDC!) и повторяйте загрузку в цифровой регистр значений 1DH (выбор дисковода 1) и 1CH (выбор дисковода 0) пока байт будет передаваться. Такие действия приводят к тому, что все данные (включая синхробиты), записанные на диск, попадают в район "неуверенности".
Второй подход состоит в выполнении почти техже самых операций с регистром управления дискеттой (3F7H). Переключение скорости передачи приводит к потере бит данных и синхробитов и деформирует их форму, также приводя к помещению их в район "неуверенности".

Обнаружив слабые данные, побитовый копировщик оказывается перед интересной дилеммой: то ли последовательность слабых битов является неопознанным дефектом поверхности и операцию следует повторять пока не будут восстановлены подлинные данные, или же это метка защиты, которая должна быть воспроизведена во всей красе?

Вообщем, слабые данные достаточно простая и дешевая защита.

Данные в промежутке

Можно легко запомнить небольшое количество данных в промежутке после поля данных сектора (в GAP 3). При условии, что сектор не переписывается, метка может находится в промежутке как угодно долго.
Наибольшее количество байт данных, которое может быть размещено в GAP 3 задается значением GPL в команде форматирования дорожки. Проверка такой метки проста (по крайней мере для первого сектора на дорожке) - команда чтения дорожки с N на единицу большим, чем актуальное значение в ID сектора загружает данные из промемутка в память.

Запись данных в промежуток является более тонкой процедурой.
Предположим, некто желает записать 10 байт данных в промежуток после первого 512-байтного сектора на дорожке 0 стороны 0. Во-первых, он должен отформатировать дорожку 0, задав длину первого сектора кодом 3 (1024 байта) в ID сектора. Затем необходимо начать операцию записи в сектор, но остановить ее после передачи 526 байт (512 байт - данные сектора + 2 байта CRC + 10 байт данных в промежутке + 4 байта для сохранения границы). Затем необходимо начать операцию форматирования дорожки с кодом длины 2 в ID сектора) и прекратить ее где-то внутри GAP2 (ID сектора уже записан, но поле данных еще не достигнуто).

Обе операции (форматирования и записи) могут быть остановлены через регистр цифрового вывода, 3F2H (управление двигателем, выбор дисковода).

Секторы без адресной метки данных

Сектора без адресной меткки данных могут порождаться при игнорировании ошибки AM данных (устанавливаются биты MA в ST1 и MD в ST2) во время операции чтения и записи данных. Команда чтения ID сектора завершается нормально на таком секторе.

Сохранение сектора без AM данных требует простой операции форматирования, которая должна быть остановлена после записи AM ID сектора, но раньше записи AM данных.

Секторы без адресной метки ID

Секторы без AM ID сектора могут получены следующим способом:

форматирование дорожки, запись кода длины N+1 для сектора перед интересующим. Потом чтение этого фиктивного сектора и запись его обратно, операция прекращается когда AM ID сектора уже переписана, а AM данных не тронута. Таким образом вы получили сектор без AM ID.
Такой сектор НЕ может быть извлечен какой бы то ни было операцией FDC без всяких исключений.

Трудность использования этого метода заключается в большей сложности чтения данных самой программой защиты.

Секторы с адресной меткой ID плохого сектора

Эта метка отличается от рассмотренной выше только степенью испорченности AM ID. В данном случае FDC все же способен обнаружить AM ID, но при проверке CRC оказывается ошибочным. Метка такого рода не может быть найдена командой чтения ID сектора, но при установленном бите DE в ST1 и сброшенном бите DD в ST2 во время выполнения команды чтения сектора с известными значениями C/H/R/N проверка не представляет проблемы. Сектор с плохой AM ID тем не менее обнаруживается и в команде чтения дорожки. Когда точные значения C/H/R/N не известны, они могут быть получены следующим способом: зная точно положение поля данных из интервалов времени, можно приблизительно рассчитать место AM ID и прочитать ее, используя способ выравнивания битовой ячейки (см. 1.2.4).

Ценной для создателей защит от копирования модификацией этой метки является метка с неверным CRC ID сектора и отсутствующей AM данных. Такой сектор приведет к завершению команды чтения дорожки, тем самым предотвращая обнаружение копировщиком расположенной после метки данного типа "нормальной" метки.

Для получения плохой AM ID, нужно остановить операцию форматирования во время записи CRC AM ID сектора.

Дорожки с разными параметрами

Основная идея состоит в том, чтобы разделить дорожку на части, записанные при разной скорости передачи данных. (Это лучше сделать не переключая скорость передачи данных во время операции форматирования, а посредством двух последовательных форматирований на различных скоростях). К примеру, можно иметь на нулевой дорожке 9 секторов по 512 байт, записанных при скорости 300 KBPS (дисковод HD) и один 512-байтный сектор, записанный при скорости 500 KBPS.

Проверка чередования секторов на дорожке

Измерение времени завершения последовательно выполненных комманд чтения дорожки может указать точную позицию каждого сектора на дорожке. В отношении бит данных Вы можете определить позицию сектора с точностью по меньшей мере в один бит. Поскольку контроллер при выполнении команды форматирования дорожки управляет позицией с разрешением в байт, то при этом невозможно воспроизвести так точно, как нужно, расположение секторов. Таким образом, одно только расположение секторов можно использовать как метку защиты. Однако проверка такой метки очень чувствительна к скорости процессора и стабильности вращения дисковода и часто такая проверка бракует и оригинальный ключевой диск. Таким образом, позиция сектора обычно используется как дополнение к другой (другим) меткам защиты.

Измерение времени передачи данных

Cкорость передачи данных FDC задается регистром управления дискеттой (3F7H) только при инициализации, или, другими словами, задается частота, используемая FDC в процессе декодирования битов.
Специальная аналоговая схема, именуемая фазозапорной петлей (PLL), регулирует скорость так, чтобы поступали неискаженные биты данных.

PLL выдерживает по меньшей мере 4% отклонения от номинальной частоты (разрешенное отклонение скорости вращения составляет ё2%). На практике, PLL будет копировать с 10% отклонениями для MFM дисководов и почти 100% для FM.

Скорость прибытия бит данных определяется угловой плотностью данных и скоростью вращения дисковода, так для определения характеристики диска (угловой плотности данных) нужно измерить скорость передачи содержимого одного сектора для различных дисководов и одной дискете эта скорость бует различной.

Некоторые FDC позволяют сделать такую простую штуку с выводным регистром 3F2H: выдать 0CH в 3F2H (остановить мотор дисковода A:), подождать 10 мс, выдать 1CH в 3F2H (включить мотор дисковода A:) и сразу выполнить операцию записи. Скорость вращения дисковода будет слегка меньше номинальной около 20 мс, что позволяет записать один сектор.

Интересные вариации этого способа могут быть использованы при небольших модификациях аппаратуры PC.

Потерянные дорожки

Некоторые из флоппи контроллеров/дисководов могут более точно управлять положением головки чтения/записи (необходимые для этого аппаратные изменения не слишком велики). Следовательно, ключевой диск для таких машин может иметь нестандартно расположенную дорожку (и программу, способную определить это). Такой диск не может быть проверен на других машинах, так что подобный способ может иметь только ограниченное применение.

В примере приведена полная процедура чтения диска, которая читает один сектор данных с дорожки 12, сектор 1, сторона 0 накопителя A в 512-байтный буфер в сегменте данных. Семь байтов статуса также считываются в отведенный буфер. Эта процедура предназначена для IBM PC и XT. Работа с фиксированным диском осуществляется аналагично.

;---в сегменте данных

BUFFER DB 512 DUP(?)

STATUS_BUFFER DB 7 DUP(?)

SECTOR_READ PROC ;начало процедуры чтения одного сектора

;---включение мотора

STI ;прерывания должны быть разрешены

MOV DX,3F2H ;адрес регистра цифрового вывода

MOV AL,28 ;устанавливаем биты 2, 3 и 4

OUT DX,AL ;посылаем команду

;---ожидаем пока мотор наберет скорость (около 1/2 сек.)

MOV CX,3500 ;счетчик цикла задержки (для IBM PC и XT)

MOTOR_DELAY:

LOOP MOTOR_DELAY ;ожидаем 1/2 секунды

;---выполняем операцию поиска

MOV AH,15 ;номер кода

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,0 ;номер накопителя

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,12 ;номер дорожки

CALL OUT_FDC ;посылаем контроллеру НГМД

CALL WAIT_INTERRUPT ;ожидаем прерывания от НГМД

;---ожидаем установки головки (25 мсек.)

MOV CX,1750 ;счетчик цикла задержки (для IBM PC и XT)

 

WAIT_SETTLE:

LOOP WAIT_SETTLE ;ожидаем 25 мсек.

;---начинаем инициализацию микросхемы DMA

MOV AL,46H ;код чтения данных контроллера НГМД

OUT 12,AL ;посылаем код по двум адресам

OUT 11,AL ;

;---вычисляем адрес буфера

MOV AX,OFFSET BUFFER ;берем смещение буфера в DS

MOV BX,DS ;помещаем DS в BX

MOV CL,4 ;готовим вращение старшего нибла

ROL BX,CL ;вращаем младшие 4 бита

MOV DL,BL ;копируем DL в BL

AND DL,0FH ;чистим старший нибл в DL

AND BL,0F0H ;чистим младший нибл в BX

ADD AX,BX ;складываем

JNC NO_CARRY ;если не было переноса, то # страницы в DL

INC DL ;увеличиваем DL, если был перенос

NO_CARRY:

OUT 4,AL ;посылаем младший байт адреса

MOV AL,AH ;сдвигаем старший байт

OUT 4,AL ;посылаем младший байт адреса

MOV AL,DL ;засылаем номер страницы

OUT 81H,AL ;посылаем номер страницы

;---конец инициализации

MOV AX,511 ;значение счетчика

OUT 5,AL ;посылаем младший байт

MOV AL,AH ;готовим старший байт

OUT 5,AL ;посылаем старший байт

MOV AL,2 ;готовим разрешение канала 2

OUT 10,AL ;DMA ожидает данные

;---получаем указатель на базу диска

MOV AL,1EH ;номер вектора, указывающего на таблицу

MOV AH,35H ;номер функции

INT 21H ;выполняем функцию

;---посылаем параметры чтения

MOV AH,66H ;код чтения одного сектора

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,0 ;номера головки и накопителя

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,12 ;номер дорожки

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,0 ;номер головки

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,1 ;номер записи

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,ES:[BX]+3 ;код размера сектора

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,ES:[BX]+4 ;номер конца дорожки

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,ES:[BX]+5 ;длина сдвига

CALL OUT_FDC ;посылаем контроллеру НГМД

MOV AH,ES:[BX]+6 ;длина данных

CALL OUT_FDC ;посылаем контроллеру НГМД

CALL WAIT_INTERRUPT ;ожидаем прерывание от НГМД

;---читаем результирующие байты

MOV CX,7 ;берем 7 байтов статуса

LEA BX,STATUS_BUFFER ;помещаем в буфер статуса

 

NEXT:

CALL IN_FDC ;получаем байт

MOV [BX],AL ;помещаем в буфер

INC BX ;указываем на следующий байт буфера

LOOP NEXT ;повторяем операцию

;---выключение мотора

MOV DX,3F2H ;адрес регистра цифрового вывода

MOV AL,12 ;оставляем биты 3 и 4

OUT DX,AL ;посылаем новую установку

RET ;конец процедуры

SECTOR_READ ENDP

WAIT_INTERRUPT PROC ;ожидание прерывания от НГМД

;---управление статусом прерывания 6 в байте статуса BIOS

MOV AX,40H ;сегмент области данных BIOS

MOV ES,AX ;помещаем в ES

MOV BX,3EH ;смещение для байта статуса

AGAIN:

MOV DL,ES:[BX] ;получаем байт

TEST DL,80H ;проверяем бит 7

JZ AGAIN ;до тех пор пока не установлен

AND DL,01111111B ;сбрасываем бит 7

MOV ES:[BX],DL ;заменяем байт статуса

RET

WAIT_INTERRUPT ENDP

OUT_FDC PROC ;посылаем байт из AH FDC

MOV DX,3F4H ;адрес порта регистра статуса

KEEP_TRYING:

IN AL,DX ;получаем значение

TEST AL,128 ;бит 7 установлен?

JZ KEEP_TRYING ;если нет, то снова проверяем

INC DX ;указываем на регистр данных

MOV AL,AH ;передаваемое значение в AH

OUT DX,AL ;посылаем значение

RET

OUT_FDC ENDP

IN_FDC PROC ;получаем байт от FDC в AL

MOV DX,3F4H ;адрес порта регистра статуса

ONCE_AGAIN:

IN AL,DX ;получаем значение

TEST AL,128 ;бит 7 установлен?

JZ KEEP_TRYING ;если нет, то проверяем снова

INC DX ;указываем на регистр данных

IN AL,DX ;читаем байт из регистра данных

RET

IN_FDC ENDP


Stay-at-home