04/16/95 12:50pm
diski_ap.lek
Роберт Журден "Справочник
программиста на компьютере фирмы
IBM".
А.Г.Шевчик, Т.В.Демьянков
"Справочник программиста и
пользователя" серия
"Карманная энциклопедия"
М."Кварта" 1993.
Ю.М.Казаринов "Микропроцессорный
комплект К1810. Структура,
программирование, применение."
Справочная книга. М. "Высшая
школа" 1990.
Работа с НГМД на уровне БИС КНГМД и КПДП.
Работа с НГМД сводится в программировании БИС контроллеров НГМД и ПДП.
После программирования обмен данными ведется без участия центрального процессора. Об окончании обмена процессор узнает через соответствующее прерывание. Во время обмена процессор может выполнять другую программу (при работе в многозадачном режиме) или выполнять специальное прерывание ожидания. В некоторых системах контроллер ПДП не используется, в этом случае центральный процессор сам выполняет его роль, анализируя соответствующие сигналы от КНГМД.
Программирование БИС контроллера ПДП.
IBM PC и XT используют 4-хканальную микросхему DMA 8237.
Канал 0 предназначен для "освежения" памяти (memory refresh); он постоянно восстанавливает заряд ячеек оперативной памяти. Использование этого канала в других целях приведет к нарушению работоспособности машины.
Канал 2 предназначен для дисковых операций, а два другие канала, с номерами 1 и 3, доступны (через разъемы расширения) для дополнительного оборудования.
Компьютер AT имеет 7 каналов прямого доступа к памяти (две микросхемы) с возможностью выполнения операции MOVS, существенно увеличивая производительность.
Каждый канал микросхемы 8237 использует три основных регистра:
Один 16-битный регистр, регистр счетчика, содержит число передаваемых байтов данных. Его величина должна быть на единицу меньше, чем требуемое число байтов. Загрузка значения осуществляется побайтно, младший байт - первый.
Остальные два регистра содержат адрес буфера в памяти, с которым будет происходить обмен данными.
Один из регистров является частью БИС КПДП и хранит базовый адрес буфера; другой находится вне микросхемы и содержит старшие биты адреса - номер 64Кбайтной страницы.
Существует еще несколько регистров, управляющих работой БИС КПДП:
Регистр режима - определяет операцию, выполняемую конкретным каналом:
7..6 Режим обслуживания:
00 - по требованию (обмен ведется пока не достигнут конец или не снят запрос ПДП),
01 - одиночная передача (по одному появлению запроса ПДП передается один байт),
10 - блочная передача (начатый обмен ведется пока не достигнут конец);
11 - каскадирование (указывают, что к данному каналу подключена дополнительная БИС КПДП);
5 Направление счета (0+, 1-);
4 Автоинициализация (=1) при достижении конца регистры автоматически перезагружаются (при регенерации памяти);
3..2 Тип цикла:
00 - проверка (обмен не выполняется),
01 - загрузка (в память),
10 - выгрузка (из памяти),
11 - комбинация запрещена;
1..0 Номер канала режим которого загружается.
Регистр команды - определяет основные параметры работы каналов:
7 Активный уровень сигнала DACKi - подтверждение ПДП (=0 - низкий);
6 Активный уровень сигнала DREQi - запрос ПДП (=0 - высокий);
5 Длительность цикла записи (=1 - удлиненный);
4 Приоритеты каналов (=1 - циклический);
3 Сжатие циклов ПДП (=1 цикл ПДП выполняется за меньшее число тактов);
2 =0 работа контроллера разрешена;
1..0 Режим память-память для каналов 0,1:
X0 - нормальная работа,
01 - изменяются оба адреса,
11 - изменяется только адрес приемника - канала 1 (заполнение области константой, расположенной по адресу в 0-ом канале.
Регистр слова-состояния:
7..4 В унитарном коде разрешение работы каналов (=1);
3..0 В унитарном коде конец ПДП по счетчику (=1).
Регистр запросов используется при необходимости выполнить ПДП но инициативе программы:
7..3 Не используются;
2 Сброс/установка запроса (=0 - сброс);
1..0 Номер канала.
Регист маски запрешает/разрешает работу каналов (маскирует сигналы DREQi), доступ возможен как ко всем битам одновременно, так и поразрядно. одновременно:
7..4 Не используются;
3..0 Установка/сброс разрешения в унитарном коде (=0 работа разрешена). поразрядно:
7..3 Не используются;
2 установить/сбросить маску (=1 установить)
1..0 номер канала.
Инициализация контроллера ПДП:
- Возможно только в пассивном состоянии.
- Начальную инициализацию необходимо произвести сразу после включения питания, в том числе и неиспользуемых каналов.
- Перед обменом (например с КНГМД):
Послать команду чтения или записи.
Вычислить физический адрес памяти буфера, в который будут посланы данные, и заслать его в регистры базового адреса и страницы канала.
Поместить значение числа передаваемых байтов (минус 1) в регистр счетчика канала.
Разрешить канал, сбросив соответствующий бит в регистре маски.
Программирование БИС контроллера НГМД
Микросхема контроллера НГМД 765 фирмы NEC управляет мотором и головками накопителя на дискетах и обрабатывает потоки данных, направляемые в или из дисковых секторов. Один контроллер, установленный на плате адаптора дисков, может обслуживать до четырех НГМД. Программированием микросхемы КНГМД обычно занимаются при решении задач защиты информации.
Микросхема КНГМД 8272A фирмы Intel аналогична микросхеме фирмы NEC.
Контроллер НГМД может выполнять 15 операций:
1. Чтение данных;
2. Чтение удаленных данных;
3. Запись данных;
4. Запись удаленных данных; - маркер.
5. Чтение данных с дорожки - используется в диагностических и специальныхцелях;
6. Сканирование до "равно";
7. Сканирование до "меньше или равно";
8. Сканирование до "больше или равно";
9. Форматирование - выполняет разметку трека;
10. Считать ID - читает первый обнаруженний индексный маркер;
11. Инициализация - переход на дорожку 0 для указанных накопителей;
12. Чтение состояния прерывания - используется для получения ST0;
13. Определить - указывает КНГМД временные параметры НГМД;
14. Чтение состояние накопителя - используется для получения ST3;
15. Поиск - установка головки на заданный цилиндр.
Работа микросхемы контроллера НГМД разделяется на три фазы: командная фаза, фаза выполнения и фаза результата.
В командной фазе один или более байтов инициируемой команды посылаются в регистр данных. Последовательность байтов строго фиксирована и она меняется от команды к команде.
Затем контроллер НГМД выполняет команду и в это время он находится в фазе выполнения. При этом можно читать слово-состояния при программном обмене между ОП и КНГМД.
Наконец, во время фазы результата, ряд байтов статуса считываются из регистра данных. При этом обязательно, чтобы не было ошибки в числе передаваемых или считываемых данных в регистр данных в фазах командной и результата.
Первый байт команды является кодом, определяющим требуемую операцию. Номер кода содержится в младших 5-ти битах байта и в некоторых случаях встарших трех битах закодирована добавочная информация. В большинстве случае второй байт команды содержит номер накопителя (0-3) в младших двух битах и номер головки (0 или 1) в бите 2, все остальные биты игнорируются контроллером
НГМД. Остальные байты содержат атрибуты комады (например логические номер а секторов, головок, треков...).
В следующей таблице показана командная последовательность для трех операций. В цепочках битов черех X обозначены биты, значение которых несущественно, через H - номер головки, а через DD - номер накопителя.
Операция # байта Функция Установка для головки 0
дорожки 15, сектора 1
Поиск 1 номер кода 00001111 1FH
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 те же, что и для чтения сектора
Вы должны быть уверены, что контроллер НГМД готов прежде чем Вы пошлете или прочитаете байт из регистра данных. Биты 7 и 6 регистра статуса предоставляют эту информацию. Вот значение битов этого регистра:
биты 3-0 1 = накопитель D-A в режиме поиска
4 1 = контроллер НГМД выполняет команду чтения/записи
5 1 = контроллер НГМД не в режиме ПДП (выдает байты статуса)
6 1 = регистр данных контроллер НГМД готов к приему данных
0 = готов к посылке данных
7 1 = контроллер НГМД готов к посылке или приему данных
Перед началом дисковых операций необходимо проверить, что бит 6 равен единице, индицируя что контроллер НГМД ожидает команду. Когда байт данных посылается в регистр данных, то бит 7 регистра статуса становится равным нулю; продолжайте чтение регистра до тех пор, пока бит не изменится обратно на 1, а затем посылайте следующий байт команды. Аналогично, проверяйте этот бит статуса перед чтением байта статуса в фазе результата.
После посылки командных байтов (а при необходимости и байтов данных), необходимо дождаться готовности выходных данных (бит 6=0, 7=1) и прочитать выходные данные (при необходимости) и байты статуса.
Форматы байтов статуса (STi) таковы:
Операция # байта Функция
Поиск нет
Чтение 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 = отсутствует адресная метка
Байт статуса 3:
бит 7 1 = ошибка накопителя
6 1 = диск защищен от записи
5 1 = накопитель готов
4 1 = дорожка 0
3 1 = дискета двухсторонняя
2 номер выбранной головки
1-0 номер выбранного накопителя
В примере приведена полная процедура чтения диска, которая читает один сектор данных с дорожки 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