5.4.1 Программирование контроллера НГМД 765 и микросхемы прямого доступа к памяти 8237.

Error message

Notice: Undefined index: add term path in hansel_get_breadcrumbs() (line 524 of /data/sites/msdosworld.ru/www/sites/all/modules/hansel/hansel.module).

  Микросхема контроллера НГМД 765  фирмы NEC управляет мотором и
головками  накопителя на дискетах и обрабатывает  потоки  данных,
направляемые в или из дисковых секторов.   Один контроллер, уста-
новленный на плате адаптора дисков, может обслуживать до  четырех


НГМД. За исключением случаев, связанных с защитой от копирования,
программистам не приходится программировать микросхему контролле-
ра НГМД прямо. Процедуры работы  с дисками, предоставляемые DOS и
BIOS эффективны и удобны, кроме того, очень рисковано писать свои
собственные  процедуры,  поскольку  ошибки  в них могут разрушить
дисковый каталог или таблицу размещения файлов, что вызовет  пол-
ное разрушение информации на диске.
   Нижеследующее  обсуждение  служит  цели  дать Вам только общее
представление.   Листинг  ROM-BIOS, приведенный в  конце  каждого
технического руководства по MS DOS, содержит код тщательно разра-
ботанных  процедур  для  форматирования дискет,  чтения и  записи
секторов, а также сброса и  получения  статуса накопителей. После
того, как Вы усвоите приведенный здесь материал, изучите процеду-
ры ROM-BIOS для продолжения Вашего образования в области операций
с дисками на низком уровне. Вам потребуется также документация по
микросхеме контроллера НГМД 8272A фирмы Intel, которая аналогична
микросхеме фирмы NEC.  В данной документации перечислены прерыва-
ния, генерируемые контроллером НГМД,  в то время как в документа-
ции  по  IBM PC этого списка нет.  Информация о микросхеме  8272A
может быть найдена во  втором  томе  Справочника  по  компонентам
микросистем (Microsystem Components Handbook).
   Контроллер НГМД может выполнять 15 операций, из которых  здесь
будут обсуждаться только три: операции поиска и чтения или записи
одного  сектора.   Понимание того как они работают  позволит  Вам
выполнить любую из оставшихся двенадцати,  при условии, что у Вас
будет  вышеупомянутая информация.  Чтение файла состоит в  поиске
его в  каталоге  [5.2.1],  определении  его  положения на диске с
помощью таблицы размещения файлов [5.1.1] и затем наборе операций
чтения одного сектора. Эта процедура включает 6 шагов:

1. Включение мотора и короткое ожидание, пока он наберет обороты.
2. Выполнение операции поиска и ожидание прерывания, указывающего
на завершение этой операции.
3. Инициализация микросхемы DMA для пересылки данных в память.
4. Посылка команды чтения контроллеру НГМД и ожидание прерывания,
указывающего, что пересылка данных завершена.
5. Получение информации о статусе контроллера НГМД.
6. Выключение мотора.

   Контроллер  НГМД  работает через три порта  ввода/вывода.   На
самом деле микросхема имеет  больше,  чем три регистра, но доступ
к  большинству  из них осуществляется через один порт.   Эти  три
порта такие:

   3F2H          регистр цифрового вывода
   3F4H          регистр статуса
   3F5H          регистр данных

   Первый шаг состоит в  доступе  к  регистру  цифрового  вывода.


Значение его битов следующее:

   биты 1-0     выбор накопителя, где 00 = A
                                      01 = B
                                      10 = C
                                      11 = D
          2     0 = сброс контроллера НГМД
          3     1 = разрешение прерывания FDC и доступа DMA
        7-4     1 = включение мотора накопителя D-A (бит 4 = A)

Это регистр только для записи, поэтому необходимо заботиться  обо
всех его битах. В нижеприведенном примере используется накопитель
A, поэтому цепочка битов должна выглядеть 00011100.  Такая  уста-
новка битов выбирает накопитель A, сохраняет установленным бит 2,
разрешающий работу с НГМД и включает мотор накопителя A. Не сбра-
сывайте бит 2 в ноль, так как в этом случае Вам придется произво-
дить  перекалибровку  накопителя,  действие,  которое  необходимо
очень редко.
   "Перекалибровка" накопителя подразумевает  возврат его головки
на нулевую дорожку.  Эта операция осуществляется посылкой простой
последовательности команд контроллеру  НГМД.  Контроллер НГМД уп-
равляет текущей позицией головки, за счет запоминания всех  изме-
нений позиции головки после  ее  начальной  установки  на нулевую
дорожку.   Когда контроллер НГМД сбрасывается, за счет  изменения
бита 2 регистра  цифрового  вывода,  то  значение текущей позиции
головки  устанавливается  в ноль, независимо от  того,  на  какой
дорожке находится головка на  самом  деле, что делает необходимым
перекалибровку. Обычно сброс контроллера НГМД производится только
в случае такой серьезной ошибки  накопителя,  после которой неиз-
вестно текущее состояние контроллера НГМД и накопителя.
   Отметим,  что  выбор накопителя и включение его  мотора -  это
отдельные действия. Контроллер  НГМД  может иметь доступ только к
одному  накопителю в данный момент времени, но мотры  могут  быть
включены у нескольких.  Моторы  могут  оставаться включенными еще
несколько  секунд  после  завершения обмена  данными, в  ожидании
следующего доступа к накопителю.  Такая стратегия позволяет избе-
жать  потери  времени  на повторное ожидание пока  мотор  наберет
скорость.  Напротив, мотор нельзя оставлять постоянно включенным,
так как это приведет к преждевременному износу дискет.
   Работа  микросхемы  контроллера НГМД разделяется на три  фазы:
командная фаза, фаза выполнения  и  фаза  результата. В командной
фазе один или более байтов посылаются в регистр данных.  Последо-
вательность байтов строго фиксирована и она меняется от команды к
команде. Затем контроллер НГМД выполняет команду и в это время он
находится в фазе выполнения.  Наконец,  во время фазы результата,
ряд байтов статуса считываются из регистра данных.  При этом обя-
зательно, чтобы не было ошибки в числе передаваемых или считывае-
мых данных в регистр данных в фазах командной и результата.
   Число  байтов  команды и результата меняется в зависимости  от
выполняемой контроллером  дисковой  операции. В техническом руко-
водстве по IBM PC приведены данные для всех 15 операций.   Первый
байт команды является  кодом,  определяющим  требуемую  операцию.
Номер  кода содержится в младших 5-ти битах байта  и в  некоторых


случаях в старших трех битах  закодирована добавочная информация.
В  большинстве случаев второй байт команды содержит номер накопи-
теля (0-3) в младших двух битах и  номер головки (0 или 1) в бите
2, все остальные биты игнорируются контроллером НГМД.  При опера-
ции поиска требуется  дополнительно еще только один байт, в кото-
ром  должен содержаться номер новой дорожки.  Чтение  или  запись
сектора требует  семи  дополнительных  командных  байтов, которые
идентичны в этих двух случаях. Байты с третьего по пятый содержат
текущий номер дорожки,  номер  головки  и  номер сектора. За ними
следуют  четыре байта, содержащие техническую информацию, необхо-
димую для контроллера НГМД.
   Первый байт этой  технической  информации  относится  к  числу
байтов в секторе, которое кодируется как 0 для 128, 1 для 256,  2
для 512 и 3 для 1024. Конечно  дискеты,  созданные в MS DOS имеют
сектора размером 512 байт. Затем идут данные конца дорожки (EOT),
которые дают максимальный номер сектора  для цилиндра; это значе-
ние  равно 9 для дискет емкостью 360K.  Наконец, идет байт дающий
длину сдвига (GPL, равный 2AH) и длину  данных (DTL, равный FFH).
Техническое  руководство  по IBM PC содержит  таблицу, в  которой
объясняются другие вхожные  параметры,  например  те, которые ис-
пользуются при форматировании диска.  MS DOS хранит четыре техни-
ческих параметра в  памяти,  в  специальной  таблице  параметров,
называемой базой диска (disk base).  Вектор прерывания 1EH указы-
вает на эту таблицу.  Четыре  значения  хранятся в том порядке, в
котором  они  должны быть переданы контроллеру НГМД,  начиная  со
смещения 3. В следующей таблице показана командная последователь-
ность для трех операций, используемых в нижеприведенном  примере.
В цепочках битов черех 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 = контроллер НГМД не в режиме DMA
       6    1 = регистр данных контроллер НГМД готов к приему
                данных
            0 = готов к посылке данных
       7    1 = контроллер НГМД готов к посылке или приему данных

Перед началом  дисковых  операций  неплохо  проверить,  что бит 6
равен  нулю, индицируя что контроллер НГМД ожидает команду.  Если
он ожидает посылки данных, то произошла ошибка. Когда байт данных
посылается в регистр данных, то бит 7 регистра статуса становится
равным нулю; продолжайте чтение регистра  до тех пор, пока бит не
изменится обратно на 1, а затем посылайте следующий байт команды.
Аналогично, проверяйте этот бит статуса  перед чтением байта ста-
туса  в фазе результата.  Нижеприведенный пример кончается  двумя
процедурами, которые выполняют эти функции.
   Когда операция поиска завершена, то контроллер НГМД инициирует
прерывание 6, прерывание от НГМД. Хотя так же просто можно узнать
об окончании операции поиска  проверяя регистр статуса, в примере
это делается за счет обработки прерывания.  Когда происходит пре-
рывание, то обработчик прерывания  BIOS устанавливает бит 7 байта
статуса  поиска в области данных BIOS, расположенного  по  адресу
0040:003E. Это единственный результат обработки прерывания. Можно
проверять этот байт до тех пор, пока бит 7 не будет установлен, а
затем переходить к следующему шагу операции чтения сектора.
   Следующий шаг состоит в  инициализации микросхеиы прямого дос-
тупа  к  памяти 8237.  Эта микросхема занимается  обменом  данных
между  периферийными  устройствами  и  памятью,  работой, которой
может заниматься также процессор.  На самом деле, в PCjr, где нет
микросхемы DMA, контроллер НГМД  посылает  данные прямо в процес-
сор,  который  в свою очередь пересылает их в  память.   Тактовая
частота процессора  адекватна  этой  задаче, однако при пересылке
данных  все  прерывания  должны быть запрещены, с  тем  чтобы  не
происходило потери данных. Это  означает, что в PCjr при передаче
данных ввод с клавиатуры или из модема запрещен.  Прерывания тай-
мера также  игнорируются,  однако  впоследствии  счетчик  времени
суток  обновляется специальной процедурой, использующей  канал  1
микросхемы таймера  8253  для  подсчета  импульсов,  прошедших за
время дисковых операций.  Все остальные модели IBM PC имеют  мик-
росхему DMA, поэтому процессор свободен при передаче данных.
   IBM PC и XT используют 4-хканальную микросхему DMA 8237. Канал
0  предназначен для "освежения" памяти (memory refresh); он  пос-
тоянно восстанавливает заряд  ячеек  оперативной памяти.  Если Вы
будете  работать по этому каналу, то это приведет скорее всего  к
краху машины. Канал 2  предназначен  для дисковых операций, а два
другие канала, с номерами 1 и 3, доступны (через разъемы расшире-
ния) для  дополнительного  оборудования.  К  сожалению, обмен па-


мять-память требует двух каналов и одним из них должен быть канал
0, поэтому такой обмен недоступен на IBM PC и XT. Однако AT имеет
7  каналов  прямого доступа к памяти и DMA автоматически  исполь-
зуется инструкциями MOVS,  существенно  увеличивая производитель-
ность.
   Перед инициализацией канала программа должна послать в микрос-
хему код, сообщающий будет  ли  происходить  чтение  или запись в
контроллер НГМД.  Этот однобайтный код равен 46H для чтения и 4AH
- для записи. Этот код должен быть послан в каждый из двух портов
с адресами 0BH и 0CH.
   Каждый  канал микросхемы 8237 использует три  регистра.   Один
16-битный регистр, регистр  счетчика, содержит число передаваемых
байтов  данных.  Его величина должна быть на единицу меньше,  чем
требуемое число байтов.   Для  канала  2  доступ к этому регистру
осуществляется через порт 05H; пошлите в него два  последователь-
ных байта, причем сначала младший байт.

   Остальные два регистра содержат адрес буфера в памяти, с кото-
рым  будет  происходить обмен данными.  Этот адрес  задается  как
20-битное число, поэтому, например,  адрес 3000:ABCD задается как
3ABCD.  Младшие 16 битов посылаются в регистр адреса, который для
канала 2 имеет адрес порта 04H.  Сначала посылается младший байт.
Старшие  4  бита  идут в регистр страницы, который для  канала  2
имеет адрес порта 81H.  Когда байт посылается по этому адресу, то
имеют  значение  только 4 младших бита.  Если буфер  создается  в
сегменте данных, то Вам  нужно  сложить  значение  DS  и смещение
буфера для получения 20-битного значения. Сложение может привести
к переносу в значение регистра страницы.  Например, если DS равен
1F00H,  а смещение буфера - 2000H, то результирующий адрес  будет
равен 1F00 + 2000 = 21000H.
   После того как эти три регистра  установлены, пошлите 2 в порт
с адресом 0AH, чтобы разрешить канал 2.  Это оставляет микросхему
DMA в состоянии ожидания данных от накопителя, а программа должна
немедленно начать посылку командных байтов в контроллер НГМД. Вот
краткий перечень шагов при программировании микросхемы 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 = отсутствует адресная метка

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

Байт статуса 3:
   бит 7   1 = ошибка накопителя
       6   1 = диск защищен от записи
       5   1 = накопитель готов
       4   1 = текущая позиция головки известна
       3   1 = дискета двухсторонняя
       2   номер выбранной головки
     1-0   номер выбранного накопителя


Вы можете получить этот четвертый байт статуса, послав контролле-
ру НГМД команду  "Определи  статус  накопителя" (Sense Drive Sta-
tus).  Первый байт этой двухбайтной команды это число 4, а второй
байт содержит номер накопителя  в  битах 1 и 0, и номер головки в
бите  2.   Единственным результатом этой операции  является  байт
статуса 3.  Отметим, что после  каждой дисковой операции, если Вы
используете  процедуры DOS или BIOS, результирующие байты статуса
помещаются в область  данных  BIOS,  начиная  с адреса 0040:0042.
Операционная  система хранит также байт статуса дискеты по адресу
0040:0041, значение битов которого следующее:

   Значение бита             Ошибка

        80H           нет ответа на присоединение накопителя
        40H           операция поиска неуспешна
        20H           ошибка контроллера НГМД
        10H           ошибка данных при чтении (ошибка CRC)
        09H           попытка прямого доступа за границу 64K
        08H           переполнение DMA
        04H           затребованный сектор не найден
        02H           не найдена адресная марка
        01H           послана неверная команда контроллеру НГМД

   В заключение приводим полную  процедуру  чтения диска, которая
читает один сектор данных с дорожки 12, сектор 1, сторона 0 нако-
пителя A в 512-байтный буфер в сегменте данных.  Семь байтов ста-
туса также считываются в отведенный буфер. Эта процедура предназ-
начена для IBM PC и XT.  Вам необходимо воспользоваться техничес-
ким  руководством по PCjr или AT, если Вы работаете на этих маши-
нах.  На 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     ;посылаем контроллеру НГМД
   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

 

Вы находитесь в разделе: 

Добавить коментарий