Глава 4. Программирование контроллера НГМД.
Большинство дисковых операций можно выполнить на уровне функций BIOS. Это самый простой и надежный способ работы с диском на физическом уровне. Однако в отдельных случаях вам может потребоваться непосредственный доступ к контроллеру НГМД - например, если вы разрабатываете систему защиты данных от несанкционированного копирования.
Информация, приведенная в этой главе, ориентирована прежде всего не на выполнение операций чтения или записи (которые лучше выполнять с помощью функций BIOS), а на управление контроллером и получение состояния контроллера. Именно эти операции требуются для организации защиты данных от несанкционированного копирования.
4.1 Порты контроллера НГМД.
Программа обращается к контроллеру для выполнения различных операций с помощью команд ввода/вывода. Для IBM PC и IBM PC/XT используются три порта с адресами 3F2h, 3F4h и 3F5h. В компьютерах IBM PC/AT дополнительно используются два порта с адресами 3F6h и 3F7h.
Порт 3F2h работает только на запись, это порт вывода. С его помощью можно выбирать для работы один из НГМД (одновременно можно работать только с одним НГМД), сбрасывать контроллер в исходное состояние, разрешать или запрещать прерывания от контроллера и работу схем прямого доступа к памяти, включать или выключать двигатели НГМД.
Приведем назначение отдельных бит этого порта:
| Биты | Назначение | 
| 0-1 | Выбор НГМД. Компьютеры IBM PC/AT не используют бит 1, так как в них установлены только два НГМД | 
| 2 | 0 - сброс контроллера; 1 - разрешение работы контроллера | 
| 3 | 1 - разрешение прерываний и прямого доступа к памяти | 
| 4-7 | Значение 1 в каждом разряде вызывает включение соответствующего двигателя НГМД. Для компьютеров IBM PC/AT биты 6-7 не используются | 
Порт 3F4h предназначен только для чтения. С его помощью можно получить байт основного состояния контроллера. Назначение отдельных бит приведено ниже:
| Биты | Назначение | 
| 0-3 | Значение 1 говорит о том, что соответствующий НГМД занят, он выполняет операцию поиска. Для IBM PC/AT биты 2-3 не используются | 
| 4 | Контроллер занят выполнением команды чтения или записи | 
| 5 | 0 - используется режим прямого доступа к памяти; 1 - режим прямого доступа к памяти не используется | 
| 6 | Направление передачи данных: 0 - от процессора к контроллеру; 1 - от контроллера к процессору | 
| 7 | Запрос на передачу данных - контроллер готов к записи или чтению данных | 
Порт 3F5h предназначен для записи или чтения данных. Он используется для всех операций.
Выполнение любой операции начинается с того, что программа посылает в этот порт байт кода операции, за которым следует один или несколько байт параметров. Количество байт параметров и их назначение зависит от кода операции (т. е. от первого байта). После выполнения операции программа считывает несколько байт результата для анализа результата выполнения операции.
Порт 3F7h работает на запись и чтение, он используется только в IBM PC/AT.
При записи в этот порт биты 0-1 определяют скорость передачи данных:
| Биты | Скорость передачи данных, Кбайт/с | 
| 00 | 500 (высокая плотность HD) | 
| 01 | 300 (двойная плотность DD) | 
| 10 | 250 (одинарная плотность SD) | 
| 11 | Зарезервировано | 
Приведем назначение отдельных бит порта 3F7h при чтении из него:
| Биты | Назначение | 
| 0 | 1 - выбран НГМД 0 | 
| 1 | 1 - выбран НГМД 1 | 
| 2-5 | Выбраны головки : бит 2 соответствует головке 0, бит 3 - головке 1 и т. д. | 
| 6 | Переключатель записи | 
| 7 | 1 - признак замены дискеты | 
4.2 Команды для контроллера НГМД.
Контроллер НГМД может выполнять 15 операций, или команд. Команда разделяется на три фазы - командная фаза, фаза выполнения, фаза результата. В командной фазе программа должна передать контроллеру всю информацию, необходимую для команды. В фазе выполнения команда выполняется, и в фазе результата программа получает от контроллера информацию о состоянии контроллера.
Информация, необходимая для команды, передается контроллеру через порт данных 3F5h. В соответствии с форматом команды программа должна последовательно вывести в этот порт код команды и все параметры.
Прежде чем программа начнет командную фазу, она должна убедиться в том, что контроллер завершил выполнение предыдущей операции и готов к приему команды. Для этого программа должна прочитать байт основного состояния контроллера из порта с адресом 3F4h и проверить биты 6 и 7. Бит 6 должен быть установлен в 0. Это означает, что данные будут передаваться от процессора к контроллеру. Бит 7 должен быть установлен в 1 - это готовность контроллера к приему команды.
Фаза выполнения начинается после установки битов 6 и 7 байта основного состояния в 1. После завершения команды контроллер формирует сигнал запроса прерывания.
В фазе результата процессор считывает состояние контроллера. Это состояние хранится в нескольких внутренних регистрах контроллера:
• RS - регистр основного состояния;
• ST0, ST1, ST2, ST3 - регистры дополнительного состояния.
Регистр основного состояния доступен через порт 3F4h, содержимое остальных регистров процессор считывает после выполнения контроллером команды через порт данных 3F5h.
В форматах команд и таблицах, приведенных ниже, используются следующие обозначения:
| Обозначение | Описание | 
| MT | Двухсторонняя операция | 
| MFM | Двойная/одинарная плотность записи | 
| SK | Пропуск удаленных данных | 
| HDS | Номер головки для двухстороннего НГМД | 
| DS1, DS0 | Номер выбираемого НГМД | 
| C | Номер цилиндра | 
| H | Номер головки для двухстороннего НГМД | 
| R | Номер сектора | 
| N | Число байт в секторе | 
| EOT | Номер последнего сектора на дорожке | 
| GPL | Размер промежутка | 
| DTL | Количество считываемых или записываемых байт | 
| SC | Количество секторов в цилиндре | 
| D | Данные | 
| PCN | Номер цилиндра после выполнения команды чтения состояния прерывания | 
| SRT | Время шага, мс | 
| HUT | Время разгрузки головки | 
| HLT | Время загрузки головки | 
| ND | Режим прерывания | 
| NCN | Номер цилиндра после поиска | 
Приведем форматы всех команд контроллера НГМД.
| MT | MFM | SK | 0 | 0 | 1 | 1 | 0 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| MT | MFM | SK | 0 | 1 | 1 | 0 | 0 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| MT | MFM | 0 | 0 | 0 | 1 | 0 | 0 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| MT | MFM | 0 | 0 | 1 | 0 | 0 | 1 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| MT | MFM | SK | 0 | 0 | 0 | 1 | 0 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| MT | MFM | SK | 1 | 0 | 0 | 0 | 1 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| MT | MFM | SK | 1 | 1 | 0 | 0 | 1 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| MT | MFM | SK | 1 | 1 | 1 | 0 | 1 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| 0 | MFM | 0 | 0 | 1 | 1 | 0 | 1 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| 0 | MFM | 0 | 0 | 1 | 0 | 1 | 1 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 
| 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
| 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 
| 0 | 0 | 0 | 0 | 0 | HDS | DS1 | DS0 | 
Первые несколько команд имеют одинаковый формат параметров и одинаковые байты результата.