My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
SVK1_Floppy  
Из "Секретов Вектора и Кристы" (С) Шашков Вячеслав Александрович
Phase-Design
Updated Feb 4, 2010 by svof...@gmail.com
              КОНТРОЛЛЕР НАКОПИТЕЛЯ НА ГИБКИХ МАГНИТНЫХ ДИСКАХ

    Дисковод является наиболее сложным из внешних устройств ПК.  Достаточно
сказать, что не существует единого способа подключения контроллера дисково-
да. Автору известны по крайней мере 4 варианта  интерфейса  контроллера  (в
дальнейшем - КД). Большинство изготовителей  придерживаются  "Кишиневского"
стандарта, рекомендованного разработчиками ПК. Незначительно отличается  от
него вариант Sphere+, распространяемый одноименной фирмой (возможно  созда-
ние универсальных программ). Контроллер дисковода,  выпускаемый  московской
фирмой Coman, отличается от обоих указанных выше вариантов. Существует  еще
вариант Омского центра программирования, способный работать на "Кристе-2" и
совместимый снизу вверх с "Кишиневским" вариантом.
    Все упомянутые контроллеры построены на основе БИС КР1818ВГ93.
    Микросхема КР1818ВГ93 представляет собой однокристальное  программируе-
мое устройство, предназначенное для управления  обменом  информацией  между
ЭВМ и накопителями на гибких магнитных дисках. БИС обеспечивает  программи-
рование номера дорожки, сектора и стороны диска, а также длины сектора, ре-
жимов поиска дорожки и установки магнитной головки  в  исходное  состояние,
режимов записи/чтения, скорости перемещения МГ.  Обмен  информацией  с  ЭВМ
происходит по восьмиразрядной двунаправленной шине данных.  Запись  осущес-
твляется с одинарной (английская аббревиатура - FM) или двойной (MFM) плот-
ностью. Поддерживаются дисководы 5.25" и 8". БИС не содержит схем  управле-
ния двигателем и выбора накопителя. Этим должно заниматься специальное  ус-
тройство управления.
    БИС содержит, как говорилось, 5  внутренних  регистров.  Их  назначение
следующее:
 - Data    (запись, чтение) - служит для обмена данными между ЭВМ и БИС.
 - Track   (запись, чтение) - содержит номер текущей дорожки.
 - Sector  (запись, чтение) - содержит номер сектора.
 - Status  (чтение)         - содержит результат выполнения команды.
 - Command (запись)         - служит для задания команды БИС.
Примечание. Чтение  Status возможно не ранее чем через 30мс после записи ко-
манды.

    Микросхема обеспечивает прием и выполнение 11 команд. Все  команды  ус-
ловно разделены на 4 типа: вспомогательные,  записи  и  чтения  информации,
поиска и чтения индексного поля и принудительного прерывания.

1. Вспомогательные команды.

    Команды этого типа выполняются вне зависимости  от  сигнала  готовности
накопителя.



    Команда RESTORE обеспечивает переход МГ на нулевую дорожку. Если  нуле-
вая дорожка не достигнута после 256 шагов, выполнение команды прекращается.
    Команда SEEK предполагает, что регистр Data  содержит  номер  требуемой
дорожки, а Track - текущей. Перемещение МГ выполняется до тех пор, пока  не
будет достигнута требуемая дорожка. По окончании регистр Track содержит но-
вый номер текущей дорожки.
    Команда STEP обеспечивает перемещение головки на 1 шаг. Направление пе-
ремещения совпадает с направлением предыдущего движения головки.
    Команды STEPF и STEPB обеспечивают перемещение головки на 1  шаг  соот-
ветственно вперед или назад.

Состояние битов регистра Status в процессе и после выполнения этих команд:

R7: 1=накопитель не готов.
R6: 1=дискета защищена от записи.
R5: 1=головка прижата.
R4: 1=ошибка поиска.
R3: 1=ошибка в контрольном коде заголовка сектора
R2: 1=МГ на нулевой дорожке.
R1: 1=индексный импульс.
R0: 1=идет выполнение команды.


2. Команды чтения и записи данных.

    Перед выполнением этих команд необходимо в регистры Track и Sector  за-
писать номер требуемой дорожки и сектора соответственно. Длина сектора  за-
дается кодом в индексной области (заголовке):

00 = 128  байт на сектор;
01 = 256  байт на сектор;
02 = 512  байт на сектор;
03 = 1024 байт на сектор.

    Команда READSCT выполняется, когда прочитан заголовок сектора  с  пара-
метрами, совпадающими с запрошенными в Track и Sector. Если за 10  оборотов
диска запрошенный сектор не найден, вырабатывается признак СЕКТОР НЕ НАЙДЕН
и прекращается выполнение команды. Если сектор найден, он  байт  за  байтом
считывается и передается в регистр Data. В момент передачи  устанавливается
сигнал DRQ и признак ЗАПРОС ДАННЫХ в Status. Регистр Data должен быть  счи-
тан в течение 20мкс после установки признака. Если это не произойдет, то  в
Data записывается следующий байт и вырабатывается признак ПОТЕРЯ ДАННЫХ.  В
конце считывания проверяется контрольная сумма. В случае несовпадения  выс-
тавляется признак ОШИБКА КОНТРОЛЬНОГО КОДА и выполнение команды прекращает-
ся, даже в случае многосекторного режима (m=1).
    Команда WRITESCT выполняется аналогично. Если регистр Data не будет за-
писан в течение 20мс после установки признака ЗАПРОС ДАННЫХ,  то  вырабаты-
вается признак ПОТЕРЯ ДАННЫХ, а на диск записывается байт нулей.

Значение битов регистра Status:

    READSCT                         WRITESECT

R7: 1=Накопитель не готов.          Накопитель не готов.
R6: всегда 0                        Защита записи
R5: 1=стертые данные                Ошибка записи
R4: 1=сектор не найден              Сектор не найден
R3: 1=ошибка в контрольном коде     Ошибка в контрольном коде
R2: 1=потеря данных                 Потеря данных
R1: 1=запрос данных                 Запрос данных
R0: 1=идет выполнение команды.      Идет выполнение команды.

3. Команды поиска и чтения индексного поля.
    Эти команды  предназначены для поиска информации на диске и для формати-
рования.
    Команда READADR предназначена для  определения  положения  головки.  По
этой команде последовательно считываются с диска и передаются в ЭВМ 6  байт
индексной области первого обнаруженного на диске  сектора:  номер  дорожки,
номер стороны, номер сектора, код длины  сектора,  двухбайтная  контрольная
сумма. В процессе выполнения этой  команды  содержимое  Sector  разрушается
(туда копируется содержимое Track). Если за 10 оборотов диска ни один  сек-
тор не будет найден, устанавливается признак СЕКТОР НЕ НАЙДЕН.
    Команда READTRK предназначена для отладочных целей. По этой команде до-
рожка считывается целиком (начало дорожки определяется  по  индексному  им-
пульсу) и передается в ЭВМ. Проверка контрольного кода не производится.
    Команда WRITETRK предназначена для форматирования дорожки. Информация в
ЭВМ для этой процедуры должно содержать все пробелы, индексные метки и т.д.
Байты F5H-FEH - служебные и предназначены для записи контрольных кодов, ме-
ток и т.п. Запись дорожки начинается в момент прихода индексного импульса.

Содержимое регистра Status:

    READADDR              READTRK               WRITETRK
R7: 1=накопитель не готов 1=накопитель не готов 1=накопитель не готов
R6: всегда 0              всегда 0              1=защита записи
R5: всегда 0              всегда 0              1=ошибка записи
R4: 1=сектор не найден    всегда 0              всегда 0
R3: 1=ошибка контроля     всегда 0              всегда 0
R2: 1=потеря данных       1=потеря данных       1=потеря данных
R1: 1=запрос данных       1=запрос данных       1=запрос данных
R0: 1=идет выполнение     1=идет выполнение     1=идет выполнение

4. Команды прерывания.

    По этим командам выполнение текущей команды прекращается и  генерирует-
ся сигнал INTRQ. В зависимости от кода команды, возможны различные  условия
генерации этого сигнала.

Коды команд:

        ┌──────────┬─────────────────────────────────┐
        │ Команда  │             Биты                │
        │          │ 7   6   5   4   3   2   1   0   │
        ├──────────┼─────────────────────────────────┤
        │ RESTORE  │ 0   0   0   0   h   V   Ч1  Ч0  │
        │ SEEK     │ 0   0   0   1   h   V   Ч1  Ч0  │
        │ STEP     │ 0   0   1   И   h   V   Ч1  Ч0  │
        │ STEPF    │ 0   1   0   И   h   V   Ч1  Ч0  │
        │ STEPB    │ 0   1   1   И   h   V   Ч1  Ч0  │
        ├──────────┼─────────────────────────────────┤
        │ READSCT  │ 1   0   0   m   S   E   C   0   │
        │ WRITESCT │ 1   0   1   m   S   E   C   а0  │
        ├──────────┼─────────────────────────────────┤
        │ READADR  │ 1   1   0   0   0   E   0   0   │
        │ READTRK  │ 1   1   1   0   0   E   0   0   │
        │ WRITETRK │ 1   1   1   1   0   E   0   0   │
        ├──────────┼─────────────────────────────────┤
        │ INTERRUPT│ 1   1   0   1   j3  j2  j1  j0  │
        └──────────┴─────────────────────────────────┘

  h=1 - прижимать головку, h=0 - нет.
  V=0 - не проверять положение МГ, V=1 - проверять.
  И=0 - не изменять Track во время выполнения команды; И=1 - изменять.
  m=0 - работать с одним сектором, m=1 - работать до конца дорожки.
  S=0 - нижняя сторона, S=1 - верхняя сторона.
  C=0 - не проверять совпадение стороны, C=1 - проверять.
  Е=1 - задержка 15мс после приема команды (подвод головки), Е=0-без задерж.
  Ч1=0,  Ч0=0 - время на шаг 6 мс
  Ч1=0,  Ч0=1 - время на шаг 12 мс
  Ч1=1,  Ч0=0 - время на шаг 20 мс
  Ч1=1,  Ч0=1 - время на шаг 30 мс.
  а0=0 - обычнаязапись,  а0=1 - запись стертых данных.
  j0=1 - прерывание по готовности накопителя.
  j1=1 - прерывание по неготовности накопителя.
  j2=1 - прерывание по индексному импульсу.
  j3=1 - немедленное прерывание.
      Структура информации для форматирования дорожки (MFM):

         ┌────────┬──────┬───────────────────────────────────────┐
         │ Число  │ Байт │          Назначение                   │
         │ байтов │      │                                       │
         │ десят. │      │                                       │
         ├────────┼──────┼───────────────────────────────────────┤
         │  80    │  4Е  │ Пробел от начала индексного импульса  │
         │  12    │  00  │                                       │
         │   3    │  F6  │ Запись байтов C2                      │
         │   1    │  FC  │ Индексная метка начала дорожки        │
         │  50 ─┐ │  4Е  │ Пробел перед сектором                 │
         │  12  │ │  00  │                                       │
         │   3  │ │  F5  │ Запись байтов A1                      │
         │   1  │ │  FE  │ Метка заголовка сектора               │
         │   1  │ │  ХХ  │ Номер дорожки                         │
         │   1  │ │  ХХ  │ Номер стороны                         │
         │   1  │ │  ХХ  │ Номер сектора                         │
         │   1  │ │  ХХ  │ Код длины сектора                     │
         │   1  │ │  F7  │ Запись контрольной суммы              │
         │  22  │ │  4Е  │ Пробел перед данными                  │
         │  12  │ │  00  │                                       │
         │   3  │ │  F5  │ Запись байтов A1                      │
         │   1  │ │  FB  │ Метка данных                          │
         │ ХХХ  │ │  E5  │ Сектор                                │
         │   1 ─┘ │  F7  │ Запись контрольной суммы              │
         │  ###   │      │ Запись остальных секторов             │
         │  &&&   │  4Е  │ Продолжение записи до конца дорожки.  │
         └────────┴──────┴───────────────────────────────────────┘

Назначение служебных байтов (MFM):

F5: запись байта A1, запуск вычисления контрольного кода (суммы);
F6: запись байта C2;
F7: запись контрольного кода (контрольной суммы).

    В режиме MFM на одну дорожку можно записать:

 - пять секторов размером 1024 байта;
 - девять (на некоторых накопителях - 10) секторов размером 512 байт;
 - шестнадцать секторов размером 256 байт;
 - двадцать шесть секторов размером 128 байт.

    Подробная информация о БИС КР1818ВГ93 опубликована в журнале "Микропро-
цессорные средства и системы", 3-1986, стр. 3-8.

      В ПК "Вектор" адреса регистров БИС (номера портов) следующие:

      ┌──────────┬────────────┬───────────┐
      │ Регистр  │ Порт Coman │ Остальные │
      ├──────────┼────────────┼───────────│
      │ Data     │ 9EH        │ 18H       │
      │ Sector   │ BEH        │ 19H       │
      │ Track    │ DEH        │ 1AH       │
      │ Command  │ FEH        │ 1BH       │
      │ Status   │ FEH        │ 1BH       │
      └──────────┴────────────┴───────────┘

      Кроме того, каждый контроллер содержит еще регистр управления; Sphera
  и Coman имеют второй регистр статуса.
      Контроллеры Кишиневского варианта, Омского варианта и  Кристы-2.  Но-
  мер порта управления - 1CН. Доступен только по записи.
   ┌─────┬────────────────┬──────────────────┬──────────────────────┐
   │     │ Кишиневский    │        Омский    │      Криста-2        │
   ├─────┼────────────────┴──────────────────┴──────────────────────┤
   │ R0: │          выбор накопителя (0=A/C, 1=B/D)                 │
   │ R1: │ Выбор 0=AB,1=CD│       Не задействован; всегда АВ        │
   │ R2: │    1=нижняя сторона, 0=верхняя сторона                   │
   │ R3: │           Не задействован                                │
   │ R4: │ 0=8", 1=5"     │       Не задействован; всегда 5"        │
   │ R5: │ 0=FM, 1=MFM    │       Не задействован; всегда MFM       │
   │ R6: │           Не задействован                                │
   │ R7: │ Не задействован│ Не задействован  │ 0=стандартный,       │
   │     │                │                  │ 1=совмещенный режим  │
   └─────┴────────────────┴──────────────────┴──────────────────────┘

      Для запуска двигателя необходимо записать байт в регистр  управления.
  После этого двигатель работает в течение 2.5 сек. Перезапись регистра во-
  зобновляет отсчет времени с момента последней записи.

      Контроллер фирмы Coman. Номер порта управления - 1ЕН. Доступен только по
  записи.

  R0,R1: выбор накопителя (A-D)
  R2:    сброс БИС ВГ93 (для сброса записать 0; нормально - 1)
  R3:    сигнал готовности головки (записать 1 перед выполнением команд)
  R4:    0=верхняя сторона, 1=нижняя
  R5:    не задействован
  R6:    0=MFM, 1=FM
  R7:    не задействован.
  Второй регистр статуса. Номер порта - 1ЕН. Доступен только по чтению.

  R0-R5: не задействованы
  R6:    сигнал DRQ
  R7:    сигнал INTRQ.

      Для запуска двигателя необходимо выполнить любую вспомогательную  ко-
манду с модификатором прижима головки, а затем  установить  бит  готовности
головки в регистре управления. Время выбега двигателя - 2 сек.  (10  оборо-
тов диска).


    Контроллер фирмы Sphere+.  Номер порта управления - 1СН. Доступен только
по записи.

R0,R1: выбор накопителя (A-D)
R2:    0=верхняя сторона, 1=нижняя сторона
R3:    0=выбор накопителя запрещен, 1=разрешен.
R4-R7: не задействованы.

Второй регистр статуса. Номер порта - 1СН. Доступен только по чтению.

R0,R1: не задействованы
R2:    инверсный DRQ
R3:    INTRQ
R4-R7  не задействованы

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

    Для  того,  чтобы  что-то  сделать  с  дисководом   (прочитать/записать
сектор), нужно уметь включать мотор, выбирать  накопитель,  позиционировать
головку и обмениваться данными. Однако, как правило, человек, имеющий  дис-
ковод и контроллер, использует его не просто так, а под операционной систе-
мой (напр. CP/M). И система обычно не любит, чтобы  пользовательская  прог-
рамма сама работала с регистрами контроллера - такие действия часто  закан-
чиваются "повисанием". Поэтому рекомендуется в таких  программах  сохранять
состояние всей используемой дисковой аппаратуры - регистров Sector и Track,
положение головок всех используемых накопителей.
    Вот пример программы, определяющей текущую дорожку, на которой находит-
ся головка накопителя, вне зависимости от того, какая  дискета  установлена
(даже неформатированная).

SAFE:   IN TRACK          ; Сохраняем регистр Track
        STA TRKBUF        ; в ячейке TRKBUF,
        IN SECTOR         ; а регистр Sector -
        STA SCTBUF        ; в SCTBUF.
WAIT:   CALL MOTOR        ; Запустим мотор, выберем накопитель.
                          ; Реализация этой процедуры зависит
                          ; от типа контроллера
        IN STATUS         ; Накопитель готов (дверь закрыта)?
        RLC               ; Бит готовности -> флаг переноса
        JC WAIT           ; Нет, еще не готов.
        MVI A,STEPF       ; Делаем шаг вперед
        CALL DO
        MVI B,255         ; B - счетчик шагов
LOOP:   MVI A,STEPB       ; Делаем шаг назад
        CALL DO
        INR B             ; Инкрементируем счетчик шагов.
        IN STATUS         ; Читаем результат.
        ANI 4             ; Нулевая дорожка?
        JZ LOOP           ; Нет еще.
        MOV A,B           ; Иначе B содержит номер дорожки, на которой
        STA TRK0          ; стояла головка
        CALL STOP         ; Остановим мотор (для контроллера Sphera+)
        RET               ; Закончим.
;
DO      PROC              ; Процедура выполнения вспомогательной команды
        OUT COMMAND       ; Пошлем команду в ВГ93
DO_1:   IN STATUS         ; Команда уже выполняется?
        RRC               ; Бит выполнения -> флаг переноса
        JNC DO_1          ; Еще не выполняется.
DO_2:   IN STATUS
        RRC               ; Команда еще выполняется?
        JC DO_2           ; Да.
        RET               ; Команда выполнена.
DO      ENDP

    Для восстановления положения головки можно пользоваться, например,  та-
кой программой:








REST:   CALL MOTOR        ; Запустим мотор
        MVI A,RESTORE     ; Головку - на нулевую дорожку
        CALL DO
        LDA TRK0          ; Номер требуемой дорожки ->
        OUT DATA          ; -> в регистр данных
        MVI A,SEEK
        CALL DO           ; Позиционирование на сохраненную дорожку.
        LDA TRKBUF        ; Восстанавливаем регистры
        OUT TRACK
        LDA SCTBUF
        OUT SECTOR
        RET               ; Вот и все.

    Как было сказано выше, перед началом чтения нужно установить головку на
нужную дорожку. Для этой цели можно использовать программу, аналогичную вы-
шеприведенной. Но необходимо помнить, что в дисковод может быть  установле-
на дискета не того типа,  на  который  рассчитан  накопитель,  например,  в
80-дорожечный накопитель может быть вставлена 40-дорожечная дискета. В этом
случае для перемещения головки на соседнюю дорожку необходимо перемещать ее
на 2 шага, а значение в регистре Track изменять на 1. Чтобы определить, ка-
кая дискета установлена, можно воспользоваться информацией, содержащейся  в
системной области диска. Однако этот способ не универсальный.  Гораздо  на-
дежнее, например, позиционировать головку на дорожку 2  и  прочитать  адрес
(команда READADR). Если на самом деле головка стоит на 1 дорожке -  то  это
ситуация 40дор. диск в 80дор. накопителе.
    Предположим, что Вы установили головку  на  нужную  дорожку  и  регистр
Sector содержит номер требуемого сектора. Процесс  чтения  происходит  так.
Запускается мотор дисковода. Когда накопитель будет готов,  посылается  ко-
манда READSCT. В подтверждение выполнения контроллер устанавливает бит  вы-
полнения. Теперь нужно следить за состоянием бита ЗАПРОС ДАННЫХ. Когда этот
бит равен 1, необходимо прочитать содержимое регистра Data и записать его в
память. Так продолжать до тех пор, пока бит выполнения не очистится  (можно
для проверки окончания процесса чтения проверять состояние сигнала INTRQ (в
контроллерах Coman и Sphere+), который равен 1 в момент завершения выполне-
ния команды.
    Из-за довольно низкой тактовой частоты процессора процесс чтения крити-
чен ко времени(особенно на "Кристе-2"). Во время чтения  прерывания  должны
быть запрещены. Более того, без применения программных ухищрений  невозмож-
но одновременно следить за битами ЗАНЯТО и ЗАПРОС ДАННЫХ. Как эта  ситуация
обходится - читайте ниже.
    При чтении возможно  возникновение  ошибок.  Наиболее  часто  возникают
ошибки "Сектор не найден" и "Ошибка контрольного кода". Разберемся,  почему
они возникают.
    Ошибка "Сектор не найден" возникает, если по каким-то причинам не прои-
зойдет идентификация сектора.  Это  случится,  например,  если  в  дисковод
вставлена неформатированная дискета, неверно  позиционирована  головка  или
заголовок сектора поврежден. При чтении контроллер пытается прочитать заго-
ловок сектора с требуемыми параметрами -  номером  дорожки,  стороны  (если
затребована такая проверка) и сектора. Если он не будет найден за 10 оборо-
тов диска, устанавливается признак СЕКТОР НЕ НАЙДЕН.  Поскольку  диск  вра-
щается со скоростью 5 оборотов в секунду, то для того, чтобы эта ошибка  не
приводила к повисанию, время выбега двигателя должно быть не менее 2.5  сек
(это относится только к контроллеру МикроДОС).
    ОШИБКА КОНТРОЛЬНОГО КОДА происходит, если, например, загрязнена  голов-
ка дисковода, неверная юстировка, некачественная запись, наводки, помехи  и
т.п. Иногда для ее устранения полезно делать несколько попыток чтения  сек-
тора.
    Приведем здесь два варианта программ чтения сектора. Первая из них при-
меняется в почти всех программах, работающих с диском (по-видимому,  она  -
ровесница ДОС). Вторая была разработана в Омском центре программирования  и
применяется в Универсальном загрузчике Spase.
    Будем считать, что мотор запущен и регистры  Track  и  Sector  содержат
верные параметры.

RSECT:  DI              ; Запретим прерывания - критично по времени
        LXI H,BUF       ; HL - адрес буфера, кратный 256
        MVI A,READSCT   ; Команду READSCT
        OUT COMMAND     ; пошлем в регистр команд
RRDY:   IN STATUS       ; Ожидаем начала выполнения:
        RRC             ; Выделим бит выполнения
        JNC RRDY        ; Он сброшен  - ждем.
        MVI B,2         ; Маска бита ЗАПРОС ДАННЫХ
        LDA SCTSIZE     ; Читаем код размера сектора
                        ; (должен быть записан сюда заранее)
        DCR A           ; =1 ?
        JZ R256         ; Да, сектор в 256 байт
        DCR A           ; =2 ?
        JZ R512         ; Да, сектор в 512 байт
                        ; Иначе - 1024 байта
R1024:  IN STATUS       ; Читаем статус
        ANA B           ; Выделяем бит запроса данных.
        JZ R1024        ; Он сброшен - запроса нет.
        IN DATA         ; Читаем порт данных
        MOV M,A         ; Записываем в ОЗУ
        INR L           ; Инкрементируем смещение
        JNZ R1024       ; 256 байт еще не прочитаны
        INR H           ; Читаем следующие 256 байт
R768:   IN STATUS       ; Читаем статус
        ANA B           ; Выделяем бит запроса данных.
        JZ R768         ; Он сброшен - запроса нет.
        IN DATA         ; Читаем порт данных
        MOV M,A         ; Записываем в ОЗУ
        INR L           ; Инкрементируем смещение
        JNZ R768        ; 256 байт еще не прочитаны
        INR H           ; Читаем следующие 256 байт
R512:   IN STATUS       ; Читаем статус
        ANA B           ; Выделяем бит запроса данных.
        JZ R512         ; Он сброшен - запроса нет.
        IN DATA         ; Читаем порт данных
        MOV M,A         ; Записываем в ОЗУ
        INR L           ; Инкрементируем смещение
        JNZ R512        ; 256 байт еще не прочитаны
        INR H           ; Читаем следующие 256 байт
R256:   IN STATUS       ; Читаем статус
        ANA B           ; Выделяем бит запроса данных.
        JZ R256         ; Он сброшен - запроса нет.
        IN DATA         ; Читаем порт данных
        MOV M,A         ; Записываем в ОЗУ
        INR L           ; Инкрементируем смещение
        JNZ R256        ; 256 байт еще не прочитаны
REND:   IN STATUS       ; Ждем завершения
        RRC             ; Завершено?
        JC REND         ; Нет еще. Ждем.
        IN STATUS       ; В аккумуляторе - код завершения.

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

RSECT:  LXI H,BUF       ; HL - адрес буфера
        DI
        MVI A,READSCT
        OUT COMMAND
RRDY:   IN STATUS
        RRC
        JNC RRDY        ; до этого момента - аналогично предыдущему
        MVI B,3         ; Маска ВЫПОЛНЕНИЕ & ЗАПРОС ДАННЫХ
        JMP LOOP2       ; Обходим участок...
LOOP1:  MOV M,A         ; Заносим байт в ОЗУ
        INX H           ; Инкремент адреса
LOOP2:  IN STATUS       ; Читаем статус
        ANA B           ; Выделим нужные биты
; Флаг паритета процессора = 0,  если только один из двух выделенных битов -
; единичный. Поскольку ситуация, при которой ЗАПРОС ДАННЫХ = 1, а ВЫПОЛНЕНИЕ
; =0 - невозможна,  то (PF=0) обозначает, что команда еще выполняется и зап-
; роса данных нет.
        JPO LOOP2
        IN DATA         ; Читаем порт данных
; Флаг паритета будет равен 1,  если либо оба выделенных бита  =1,  и  тогда
; нужно обработать запрос данных,  либо оба равны 0,  и тогда выполнение ко-
; манды закончено. Но в последнем случае дополнительно флаг Z=1. Поэтому
        JNZ LOOP1
        IN STATUS       ; На выходе в аккумуляторе - код завершения.

    Поскольку выполнение команды рано или поздно кончается,  эта  программа
не "зависает", если не найден сектор, как предыдущая. Кроме того, она  зна-
чительно короче.

    Операция записи выполняется на  всех  контроллерах,  кроме  "Криста-2",
аналогично. Приведем здесь паритетный вариант программы записи сектора.

WSECT:  LXI H,BUF
        DI
        MVI A,WRITESCT
        OUT COMMAND
        IN STATUS
        RRC
        JNC $-3
        MVI B,3
LOOP:   IN STATUS
        ANA B
        JPO LOOP
        MOV A,M         ; Эти команды
        OUT DATA        ; на флаги процессора
        INX H           ; не влияют.
        JNZ LOOP
        DCX H           ; Был лишний инкремент
        IN STATUS

See also


Sign in to add a comment
Powered by Google Project Hosting