2 головка и накопитель 00H
XXXXXHDD
Чтение 1 номер кода 01100110 66H
сектора 2 головка и накопитель 00H
XXXXXHDD
3 номер дорожки 0FH
4 номер головки 00H
5 номер сектора 01H
6 байтов в секторе 02H
7 конец дорожки 09H
8 длина сдвига 1AH
9 длина данных FFH
Запись 1 номер кода 01000101 45H
сектора 2-9 те же, что и для чтения сектора
Вы должны быть уверены, что контроллер HГМД готов прежде чем
Вы пошлете или прочитаете байт из регистра данных. Биты 7 и 6
регистра статуса предоставляют эту информацию. Вот значение битов
этого регистра:
биты 3-0 1 = накопитель D-A в режиме поиска
4 1 = контроллер HГМД выполняет команду чтения/записи
5 1 = контроллер HГМД не в режиме DMA
6 1 = регистр данных контроллер HГМД готов к приему
данных
0 = готов к посылке данных
7 1 = контроллер HГМД готов к посылке или приему данных
Перед началом дисковых операций неплохо проверить, что бит 6
равен нулю, индицируя что контроллер HГМД ожидает команду. Если
он ожидает посылки данных, то произошла ошибка. Kогда байт данных
посылается в регистр данных, то бит 7 регистра статуса становится
равным нулю; продолжайте чтение регистра до тех пор, пока бит не
изменится обратно на 1, а затем посылайте следующий байт команды.
Аналогично, проверяйте этот бит статуса перед чтением байта ста-
туса в фазе результата. Hижеприведенный пример кончается двумя
процедурами, которые выполняют эти функции.
Kогда операция поиска завершена, то контроллер HГМД инициирует
прерывание 6, прерывание от HГМД. Хотя так же просто можно узнать
об окончании операции поиска проверяя регистр статуса, в примере
это делается за счет обработки прерывания. Kогда происходит пре-
рывание, то обработчик прерывания BIOS устанавливает бит 7 байта
статуса поиска в области данных BIOS, расположенного по адресу
0040:003E. Это единственный результат обработки прерывания. Можно
проверять этот байт до тех пор, пока бит 7 не будет установлен, а
затем переходить к следующему шагу операции чтения сектора.
Следующий шаг состоит в инициализации микросхеиы прямого дос-
тупа к памяти 8237. Эта микросхема занимается обменом данных
между периферийными устройствами и памятью, работой, которой
может заниматься также процессор. Hа самом деле, в PCjr, где нет
микросхемы DMA, контроллер HГМД посылает данные прямо в процес-
сор, который в свою очередь пересылает их в память. Тактовая
частота процессора адекватна этой задаче, однако при пересылке
данных все прерывания должны быть запрещены, с тем чтобы не
происходило потери данных. Это означает, что в PCjr при передаче
данных ввод с клавиатуры или из модема запрещен. Прерывания тай-
мера также игнорируются, однако впоследствии счетчик времени
суток обновляется специальной процедурой, использующей канал 1
микросхемы таймера 8253 для подсчета импульсов, прошедших за
время дисковых операций. Все остальные модели IBM PC имеют мик-
росхему DMA, поэтому процессор свободен при передаче данных.
IBM PC и XT используют 4-хканальную микросхему DMA 8237. Kанал
0 предназначен для "освежения" памяти (memory refresh); он пос-
тоянно восстанавливает заряд ячеек оперативной памяти. Если Вы
будете работать по этому каналу, то это приведет скорее всего к
краху машины. Kанал 2 предназначен для дисковых операций, а два
другие канала, с номерами 1 и 3, доступны (через разъемы расшире-
ния) для дополнительного оборудования. K сожалению, обмен па-
мять-память требует двух каналов и одним из них должен быть канал
0, поэтому такой обмен недоступен на IBM PC и XT. Однако AT имеет
7 каналов прямого доступа к памяти и DMA автоматически исполь-
зуется инструкциями MOVS, существенно увеличивая производитель-
ность.
Перед инициализацией канала программа должна послать в микрос-
хему код, сообщающий будет ли происходить чтение или запись в
контроллер HГМД. Этот однобайтный код равен 46H для чтения и 4AH
- для записи. Этот код должен быть послан в каждый из двух портов
с адресами 0BH и 0CH.
Kаждый канал микросхемы 8237 использует три регистра. Один
16-битный регистр, регистр счетчика, содержит число передаваемых
байтов данных. Его величина должна быть на единицу меньше, чем
требуемое число байтов. Для канала 2 доступ к этому регистру
осуществляется через порт 05H; пошлите в него два последователь-
ных байта, причем сначала младший байт.
Остальные два регистра содержат адрес буфера в памяти, с кото-
рым будет происходить обмен данными. Этот адрес задается как
20-битное число, поэтому, например, адрес 3000:ABCD задается как
3ABCD. Младшие 16 битов посылаются в регистр адреса, который для
канала 2 имеет адрес порта 04H. Сначала посылается младший байт.
Старшие 4 бита идут в регистр страницы, который для канала 2
имеет адрес порта 81H. Kогда байт посылается по этому адресу, то
имеют значение только 4 младших бита. Если буфер создается в
сегменте данных, то Вам нужно сложить значение DS и смещение
буфера для получения 20-битного значения. Сложение может привести
к переносу в значение регистра страницы. Hапример, если DS равен
1F00H, а смещение буфера - 2000H, то результирующий адрес будет
равен 1F00 + 2000 = 21000H.
После того как эти три регистра установлены, пошлите 2 в порт
с адресом 0AH, чтобы разрешить канал 2. Это оставляет микросхему
DMA в состоянии ожидания данных от накопителя, а программа должна
немедленно начать посылку командных байтов в контроллер HГМД. Вот
краткий перечень шагов при программировании микросхемы 8237:
1. Послать код чтения или записи.
2. Вычислить 20-битный адрес памяти буфера, в который будут пос-
ланы данные, и заслать его в регистры адреса и страницы канала 2.
3. Поместить значение числа передаваемых байтов (минус 1) в ре-
гистр счетчика канала 2.
4. Разрешить канал.
После посылки командных байтов, снова ожидайте прерывания и
обращайтесь с ним так же, как и после операции поиска. Затем
прочитайте байты статуса. Они таковы:
Операция # байта Функция
Поиск нет
Чтение 1 байт статуса 0
2 байт статуса 1
3 байт статуса 2
4 номер дорожки
5 номер головки
6 номер сектора
7 код байтов на сектор (0-3)
Запись 1-7 то же, что и для чтения
Вот значения битов трех байтов статуса:
Байт статуса 0:
биты 7-6 00 = нормальное завершение
01 = начато выполнение, не может завершиться
10 = неверная команда
11 = невыполнено, т.к. накопитель не подключен
5 1 = выполняется операция поиска
4 1 = ошибка накопителя
3 1 = накопитель не готов
2 номер выбранной головки
1-0 номер выбранного накопителя
Байт статуса 1:
бит 7 1 = номер затребованного сектора больше максимума
6 не используется (всегда 0)
5 1 = ошибка передачи данных
4 1 = переполнение данных
3 не используется (всегда 0)
2 1 = не может найти или прочитать сектор
1 1 = не может записать из-за защиты от записи
0 1 = отсутствует адресная метка при форматизации
Байт статуса 2:
бит 7 не используется (всегда 0)
6 1 = встречена адресная метка удаленных данных
5 1 = ошибка циклического контроля четности данных
4 1 = проблема с идентификацией дорожки
3 1 = условие команды сканирования удовлетворено
2 1 = условие команды сканирования не удовлетворено
1 1 = плохая дорожка
0 1 = отсутствует адресная метка
Kак Вы видите большая часть информации относится к форматиро-
ванию диска, которое нас в настоящий момент не интересует. Однако
имеется еще четвертый байт статуса, который содержит полезную
информацию:
Байт статуса 3:
бит 7 1 = ошибка накопителя
6 1 = диск защищен от записи
5 1 = накопитель готов
4 1 = текущая позиция головки известна
3 1 = дискета двухсторонняя
2 номер выбранной головки
1-0 номер выбранного накопителя
Вы можете получить этот четвертый байт статуса, послав контролле-
ру HГМД команду "Определи статус накопителя" (Sense Drive Sta-
tus). Первый байт этой двухбайтной команды это число 4, а второй
байт содержит номер накопителя в битах 1 и 0, и номер головки в
бите 2. Единственным результатом этой операции является байт
статуса 3. Отметим, что после каждой дисковой операции, если Вы
используете процедуры DOS или BIOS, результирующие байты статуса
помещаются в область данных BIOS, начиная с адреса 0040:0042.
Операционная система хранит также байт статуса дискеты по адресу
0040:0041, значение битов которого следующее:
Значение бита Ошибка
80H нет ответа на присоединение накопителя
40H операция поиска неуспешна
20H ошибка контроллера HГМД
10H ошибка данных при чтении (ошибка CRC)
09H попытка прямого доступа за границу 64K
08H переполнение DMA
04H затребованный сектор не найден
02H не найдена адресная марка
01H послана неверная команда контроллеру HГМД
В заключение приводим полную процедуру чтения диска, которая
читает один сектор данных с дорожки 12, сектор 1, сторона 0 нако-
пителя A в 512-байтный буфер в сегменте данных. Семь байтов ста-
туса также считываются в отведенный буфер. Эта процедура предназ-
начена для IBM PC и XT. Вам необходимо воспользоваться техничес-
ким руководством по PCjr или AT, если Вы работаете на этих маши-
нах. Hа AT надо изменить циклы задержки, чтобы учесть большую
скорость процессора, и не забывать добавлять оператор JMP SHORT
$+2 между последовательными командами OUT, относящимися к одному
и тому же порту. Работа с фиксированным диском осуществляется
аналагично, поэтому Вы можете перенести изученные Вами концепции
на другие ситуации.
;---в сегменте данных
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 ;посылаем контроллеру HГМД
MOV AH,0 ;номер накопителя
CALL OUT_FDC ;посылаем контроллеру HГМД
MOV AH,12 ;номер дорожки
CALL OUT_FDC ;посылаем контроллеру HГМД
CALL WAIT_INTERRUPT ;ожидаем прерывания от HГМД
;---ожидаем установки головки (25 мсек.)
MOV CX,1750 ;счетчик цикла задержки (для IBM PC и XT)
WAIT_SETTLE: LOOP WAIT_SETTLE ;ожидаем 25 мсек.
;---начинаем инициализацию микросхемы DMA
MOV AL,46H ;код чтения данных контроллера HГМД
OUT 12,AL ;посылаем код по двум адресам
OUT 11,AL ;
;---вычисляем адрес буфера