IPB

Здравствуйте, гость ( Вход | Регистрация )

> Исходники ПЗУ: КНГМД 326ая прошивка ПЗУ
SuperMax
сообщение 20.6.2022, 17:53
Сообщение #1


Администратор
*****

Группа: Root Admin
Сообщений: 6 286
Регистрация: 7.1.2006
Из: Красноярск
Пользователь №: 1



Код

                                  - 1 -
                                         В каждой глупости есть
                                      своя доля логики, особен-
                                      но, если там ее найти.


   Уважаемые  читатели! Вы держите в руках текст 326 прошивки в
блоке КНГМД. Он получен дизассемблированием  программы, зашитой
в микросхеме  КР1801РЕ2-326. Этот текст появился на свет благо-
даря дизассемблеру  DIZAKS4 v4 17.04.88 (KSA corp.), текстовому
редактору EDALT3E (фирма ALTEC), моему  желанию, ну, и конечно,
дисководу.
   На сегодня все больше  и  больше людей приобретают дисководы
и подключают их к БК. Но очень мало тех, кто знает, как работа-
ет их любимый дисковод. У нас на БК стало дурной традицией сде-
лать что-нибудь  хорошее, а всю информацию, как  и  с  чем  это
едят, припрятать или раздать  очень  узкому  кругу лиц. Кстати,
это повелось  с  выпуска самой БК. Ее пустили  в  продажу, а ни
схем, ни описания  принципов работы не опубликовали. Думаю, что
если бы это сделали, то в 1989 году мы  бы уже имели на БК дис-
ковод, расширение памяти, и, следовательно, много хороших прог-
рамм. Точно так же произошло с контроллером дисковода. Господин
Саяпин написал драйвер для работы с НГМД, а информацию по этому
драйверу никому  не  дал. Кстати, я его  в  этом не виню, может
быть, эту информацию у него  никто и не просил. Имеются, конеч-
но, какие-то обрывки, но полной  информации все же нет. Вот по-
чему я принялся за эту каторжную  работу. Понять и прокомменти-
ровать эту программу было довольно сложно, так как в своем рас-
поряжении я имел всего лишь распределение ячеек  в  рабочей об-
ласти драйвера, известное по руководству системного программис-
та для БК0011.
   Конечно, это не исходник, но я думаю, что с помощью  данного
текста Вы сможете кое-что узнать об этой прошивке и составить о
ней собственное мнение. Думаю, что Вы поймете, что эта програм-
ма далека от совершенства, что многие  операции можно было сде-
лать лучше, и что в некоторых случаях  применялись не самые хо-
рошие алгоритмы.
   Самое главное, что теперь это положение не изменить, так как
эта прошивка стала стандартной для БК, и ее изменение  приведет
к несовместимости некоторых  программ  с  новой зашивкой. Хотя,
конечно, это относится только  к  таким программам, которые ис-
пользуют подпрограммы зашивки не через стандартные точки входа.
   Вот вроде и все что я хотел сказать по этому поводу. Сидите,
разбирайтесь. Огромная просьба  к  тем, кто заметит  допущенные
неточности, ошибки  или  имеет сказать что-нибудь интересное по
этому поводу - позвоните мне, и мы с Вами поговорим об этом.

   Москва 1993 г.                 Гаршенин К.В. (095)4675093

   Дополнения и исправления внесли:

                           Войлуков А.А, Рузаков А.С. - 1992
                           "Black beards"             - 1992
                           Dale Publishing co.        - 1992-94








                              - 2 -


  Регистр состояния КНГМД (177130).

  Формат регистра по записи.
┌──────┬─────────────────────────────────────────┐
│разряд│               назначение                │
├──────┼─────────────────────────────────────────┤
│  00  │Выбор накопителя с номером 0             │
│  01  │Выбор накопителя с номером 1             │
│  02  │Выбор накопителя с номером 2             │
│  03  │Выбор накопителя с номером 3             │
│  04  │Включение электродвигателя               │
│  05  │Выбор головки накопителя: 0=верх. 1=нижн.│
│  06  │Направление шага                         │
│  07  │Шаг                                      │
│  08  │Признак "НАЧАЛО ЧТЕНИЯ"                  │
│  09  │Признак "ЗАПИСЬ МАРКЕРА"                 │
│  10  │Переключение схемы прекоррекции          │
│11-15 │Не используются                          │
└──────┴─────────────────────────────────────────┘

  Формат регистра по чтению.
┌────────┬──────────────────────────────────────┐
│ разряд │             назначение               │
├────────┼──────────────────────────────────────┤
│   00   │Признак "дорожка 00"                  │
│   01   │Признак готовности накопителя         │
│   02   │Запрет записи                         │
│   07   │Требование съема информации с регистра│
│        │данных или записи в него нового кода  │
│   14   │В режиме чтения признак  записи цикли-│
│        │ческого контрольного кода на диск     │
│   15   │Индекс                                │
│3-6 8-13│Не используются                       │
└────────┴──────────────────────────────────────┘

   Регистр данных КНГМД (177132).
   Все разряды регистра доступны по чтению и записи.


   Драйвер НГМД размещен в ПЗУ, находящемся в контроллере НГМД,
и доступен при подключении контроллера к микро-ЭВМ.
   Для работы драйвера необходима  область ОЗУ размером 66 байт
для размещения параметров и рабочих ячеек.

















                              - 3 -


   Формат рабочей оласти драйвера:
┌───────┬────┬──────┬────────┬────────────────────────────────┐
│Смеще- │Дли-│Симво-│Началь- │        Назначение ячейки       │
│ние от │на, │личес-│ное зна-│                                │
│начала │байт│кое   │чение   │                                │
│области│    │имя   │        │                                │
├───────┼────┼──────┼────────┼────────────────────────────────┤
│   0   │ 2  │CSRW  │ 000000 │Копия по записи РС КНГМД        │
│   2   │ 2  │CURTRK│    -   │Адрес текущей дорожки           │
│   4   │ 4  │TRKTAB│ 177777 │Таблица текущих дорожек (*)     │
│  10   │ 2  │TDOWN │ 020000 │Задержка опускания головки      │
│  12   │ 2  │TSTEP │    -   │Задержка перехода дорожки       │
│  14   │ 1  │TRKCOR│ 000036 │Дорожка начала предкомпенсации  │
│  15   │ 1  │BRETRY│ 000030 │Число попыток повтора при ошибке│
│  16   │ 1  │FLAGS │ 000000 │Рабочая ячейка драйвера (**)    │
│  17   │ 1  │FILLB │    -   │Код заполнения при форматиров.  │
│  20   │ 2  │FLGPTR│    -   │Указатель на байт признаков     │
│  22   │ 4  │FLGTAB│ 000000 │Таблица признаков (***)         │
│  26   │ 2  │ADDR  │    -   │Адрес буфера ОЗУ                │
│  30   │ 2  │WCNT  │    -   │Число слов для пересылки        │
│  32   │ 1  │SIDE  │    -   │Номер стороны диска             │
│  33   │ 1  │TRK   │    -   │Номер дорожки                   │
│  34   │ 1  │UNIT  │    -   │Номер привода                   │
│  35   │ 1  │SECTOR│    -   │Номер сектора                   │
│  36   │ 2  │WRTVAR│ (****) │Записываемое значение при форм. │
│  40   │ 2  │MARKER│ (****) │Буфер маркера при записи        │
│  42   │ 2  │FREE  │ (****) │Размер пустого остатка сектора  │
│  44   │ 2  │INTIME│ (****) │Время от перепада индекса       │
│  46   │ 2  │BUF4  │ (****) │Буфер @#4                       │
│  50   │ 2  │BUFSP │ (****) │Буфер SP                        │
│  52   │ 2  │BUFPSW│ (*+**) │Буфер PSW                       │
│  54   │ 1  │CRETRY│ (****) │Счетчик повторов по BRETRY      │
│  55   │ 1  │TURNS │ (****) │Число оборотов диска на операцию│
│  56   │ 1  │SECRET│ (****) │Число повторных поисков сектора │
│  57   │ 1  │ERRNUM│ (****) │Буфер для номера ошибки         │
│  60   │ 2  │MAXSEC│ 000012 │Число секторов на дорожке       │
│  62   │ 2  │HOLTIN│    -   │Время задержки после индекса    │
│  64   │ 2  │SECLEN│ 000400 │Длина сектора в словах (*****)  │
└───────┴────┴──────┴────────┴────────────────────────────────┘

   (*) Старший бит каждого  байта при установке в 1 задает воз-
врат соответствующего дисковода  к  дорожке 00 перед  операцией
позиционирования (для случая, когда положение  головки  заранее
неизвестно).

   (**) Флаги имеют следующие значения:

   Бит 0 (001) - разрешение читать/записывать скрытые данные
   Бит 2 (004) - двигатель уже был включен перед операцией
   Бит 4 (020) - признак записи информации на диск
   Бит 5 (040) - текущее состояние индекса
   Бит 6 (100) - отмена двойного шага при возврате на 00.








                              - 4 -


   (***) Таблица признаков содержит по одному байту на привод и
используется для обработки нестандартных дисков. В каждом байте
используется четыре бита для указания параметров операции.
   Бит 0 - при установке драйвер производит пропуск дорожек при
поиске, т.е. фактически обрабатываются лишь четные дорожки. Эта
возможность используется для обработки на 80-дорожечном  диско-
воде 40-дорожечных дисков;
   Бит 1 - при установке драйвер  производит  обращение  только
к нижней стороне диска. Эта возможность используется  при  под-
ключении  одностороннего  дисковода, а также  при  обработке на
двустороннем дисководе односторонних дисков;
   Бит 2 - при  установке  обрабатываются  сектора  длиной 2000
байт, иначе - 1000 байт (Внимание! Работа  с  секторами  длиной
2000 байт организована неверно!);
   Бит 3 - при установке начало первого сектора задается задер-
жкой HOLTIN от индекса, в противном случае - своим заголовком.

   (****) Значения заносятся в процессе работы драйвера.

   (*****) Внимание! Следите, чтобы  при  записи  ячейка SECLEN
содержала соответствующее значение, в противном случае портится
разметка диска!


   Перед самым первым вызовом драйвера  нужно  инициализировать
рабочую область. Это делает специальная  подпрограмма инициали-
зацми.
   После завершения операций обмена с диском драйвер  оставляет
двигатель дисковода включенным. Для  остановки  двигателя  про-
грамма  пользователя  должна  обнулить  ячейки @#177130 и CSRW.
Просьба не выключать двигатель командой RESET, думайте  о  тех,
кто имеет БК0010+ДОЗУ32Кб.


   Диагностика ошибок в драйвере НГМД.

   При возникновении ошибки бит С в слове состояния  процессора
устанавливается в 1 и в байт @#52 помещается код ошибки:

    1  При чтении - ошибка CRC в зоне данных
       При записи - установлена защита записи
    2  Ошибка CRC в зоне заголовка сектора
    3  Нет позиционирования на нулевую дорожку
    4  Ошибка позиционирования
    5  Не найден сектор
    6  Нет диска или диск не вращается
    7  Прерывание по вектору 4 во время операции
   10  Не найден адресный маркер
   11  Не найден маркер данных
   12  Недопустимые  параметры команды или нестандартный формат
       диска
   13  Попытка считывания скрытых данных  без  соответствующего
       разрешения





ъ                              - 5 -


   Драйвер имеет несколько точек входа:

   160000   Автоматическая загрузка
   160002   Загрузка с выбранного привода
   160004   Чтение-запись по номеру блока
   160006   Чтение-запись по номеру сектора
   160010   Инициализация рабочей области драйвера
   160012   Форматирование дорожки


   Автоматическая загрузка

   Вызов:
          JSR PC,@#160000

   Можно также произвести загрузку непосредственно из пускового
монитора:
   <СТОП>С160000<ВВОД>
   Входные параметры отсутствуют.
   Действие: производится попытка загрузить операционную систе-
му с привода 0. Если попытка загрузки  была неудачной, то драй-
вер пытается  загрузить систему с 1 привода. Если  все  попытки
оказались неудачными, драйвер возвращает  управление с установ-
ленным битом "C" процессора.
   Алгоритм загрузки:
   1. Инициализируется  рабочая область драйвера в ОЗУ (базовый
адрес 2000) с параметрами для НГМД 6022;
   2. В ОЗУ, начиная с адреса 1000, считывается сектор 1 дорож-
ки 0 выбранного дисковода;
   3. В следующих случаях:

      - в приводе нет диска;
      - привод не защелкнут;
      - привод неисправен;
      - диск не отформатирован;
      - ошибка чтения;
      - отсутствует начальный загрузчик,

   попытка загрузки  считается неудачной. При успешной загрузке
драйвер передает управление по адресу 1000, при этом в R0 поме-
щается номер привода, с которого производилась загрузка.
   Драйвер прошивки 253 пытается  загрузиться с приводов 0...3.
Поскольку он использует EMT 0,16,122, их необходимо  перехваты-
вать. EMT 112 заменяется на NOP, ЕМТ 0 восстанавливает стек.


   Загрузка с выбранного привода

   Вызов:
          MOV #N,R0
          JSR PC,@#160002

   ИЗ ВСТРОЕННЫХ МОНИТОРОВ БК ВЫБОРОЧНАЯ ЗАГРУЗКА НЕВОЗМОЖНА.
   Действие аналогично предыдущему пункту, но загрузка  начина-
ется сразу с выбранного привода, и при неудачной загрузке попы-
ток загрузиться с других приводов не предпринимается.




                              - 6 -


   Чтение-запись логического блока

   Вызов:
          JSR PC,@#160004   ;BCC WORK или BCS ERROR
   Входные параметры:

          R0 - номер блока на диске;
          R1 - длина пересылаемого массива в словах;
          R2 - начальный адрес массива данных;
          R3 - базовый адрес рабочей области драйвера;
          в рабочей области: UNIT - номер привода.

   Блок  является логической единицей информации на внешних но-
сителях и равен 1000 байт. В используемом формате записи размер
блока совпадает  с  размером сектора. Первый сектор нулевой до-
рожки нижней  стороны  соответствует блоку 0. Вычисление номера
сектора и дорожки по номеру блока производится  с  учетом уста-
новленных признаков в таблице FLGTAB. Алговитм этого вычисления
совпадает с алгоритмом драйвера MY для микроЭВМ ДВК.
   Длина  массива данных задает число слов, подлежащих пересыл-
ке, а также тип операции: положительное - чтение, отрицательное
- запись. При записи пересылаемое число слов равно  абсолютному
значению длины. Если заданное число слов превышает размер  сек-
тора, осуществляется автоматический переход к следующему секто-
ру, а если необходимо, то и на другую сторону  и  дорожку. Если
при записи число  слов  не  кратно  размеру сектора, то остаток
последнего сектора заполняется нулями.
   Перед самым первым вызовом драйвера поля CSRW, TRKTAB, FLAGS
в рабочей области  должны быть заполнены значениями, указанными
в таблице, и не должны изменяться программой пользователя. Поля
TDOWN, TSTEP, TRKCOR, BRETRY, FLGTAB   рекомендуется  заполнять
значениями, указанными в таблице, однако они могут быть измене-
ны в зависимости от конкретных условий.
   Возврат из драйвера осуществляется командой RTS PC, содержи-
мое регистров (кроме R3) не сохраняется.
   Возникновение прерывания  по  вектору 4 при записи  на  диск
приводит к появлению  сбоя  в  секторе, в который производилась
запись. Сбой может быть устранен повторной записью этого секто-
ра.


   Чтение-запись по номеру сектора и дорожки

   Вызов:
          JSR PC,@#160006
   Входные параметры:

          R3     - адрес рабочей области;
          ADDR   - начальный адрес массива данных;
          WCNT   - длина массива данных;
          SIDE   - номер стороны (0 - нижняя, 1 - верхняя);
          TRK    - номер дорожки;
          UNIT   - номер привода (0...3);
          SECTOR - номер сектора (1...12).

   Действие аналогично предыдущему пункту.




                              - 7 -


   Инициализация рабочей области

   Эта точка входа является вспомогательной и служит для облег-
чения написания программ, использующих драйвер НГМД.
   Вызов:
          JSR PC,@#160010
   Входной параметр:

          R3 - базовый адрес рабочей области.

   Действие: заполняются следующие поля рабочей области:

          CSRW   - 0
          TRKTAB - 177777,177777
          TDOWN  - 10000
          TSTEP  - 10000
          TRKCOR - 30. (253); 32. (326)
          BRETRY - 30. (253); 20. (326)
          FLAGS  - 0
          FLGTAB - 0,0
          MAXSEC - 12 (только 326)


   Форматирование дорожки

   Вызов:
          JSR PC,@#160012
   Входные параметры:

          R3    - базовый адрес рабочей области;
          FILLB - код заполнения секторов при форматировании;
          SIDE  - номер стороны;
          TRK   - номер дорожки;
          UNIT  - номер привода.

   Действие: форматируется указанная дорожка с указанной сторо-
ны, поле данных всех секторов заполняется кодом FILLB.


   Команды расширенной арифметики

   В 326 прошивке помимо драйвера дисковода зашит эмулятор  ко-
манд расширенной арифметики процессора К1801ВМ2, т.е. на данной
машине  возможно  использование программного обеспечения, напи-
санного для этого процессора.
   Для организации работы с блоком расширенной арифметики необ-
ходимо перед  ее  использованием  в  программе инициализировать
эмулятор. Инициализация производится занесением  в  ячейку @#10
числа 160016. При поступлении кода команды расширенной  арифме-
тики происходит прерывание  по  вектору 10 и обработка соответ-
ствующей команды.









                              - 8 -


   Мнемоника команд расширенной арифметики реализована в ассем-
блерах MICRO Коренкова В.С., TURBO Надежина А.М:

1. MUL   S,Rn  Деление
2. DIV   S,Rn  Умножение
3. FMUL  Rn    Умножение с плавающей запятой
4. FDIV  Rn    Деление с плавающей запятой
5. FADD  Rn    Сложение чисел с плавающей запятой
6. FSUB  Rn    Вычитание чисел с плавающей запятой
7. ASH   S,Rn  Арифметический сдвиг на заданное число бит
8. ASHC  S,Rn  Арифметический сдвиг двойного слова на заданное
               число бит

   Автор  не  стал  комментировать блок расширенной арифметики,
т.к. его основной  целью  было  комментирование работы драйвера
дисковода.


   Описание команд расширенной арифметики.

   DIV S,D

   Деление 32-разрядного слова RnRn+1 на число или регистр. Ре-
гистр результата (D) в команде должен быть четным.

      MOV #75.,R1
      CLR R0
      DIV #10.,R0  ;Деление числа 75. на 10.
                   ;R0 - результат, R1 - остаток.


   MUL S,D

   Умножение регистра  на  число. Если номер регистра нечетный,
сохраняется младшая часть результата. Регистр результата (D)
должен быть нечетным.

      MOV #7,R1
      MUL #10.,R1  ;умножение 7*10.=70. в регистре R1.


   ASH S,D

   Арифметический  сдвиг  регистра  вправо/влево на (-32...+32)
позиции  в  зависимости от значения 5-го бита аргумента сдвига.
При 1 в 5 бите - сдвиг вправо, при 0 - влево.

      ASH #5,R1    ;сдвиг регистра R1 на 5 позиций влево.


   ASHC S,D

   Арифметический сдвиг двойного слова, причем регистр с нечет-
ным номером содержит младшую часть слова, а с четным - старшую,
остальное аналогично команде ASH.





                              - 9 -


   FADD Rn

   Сложение чисел с плавающей запятой. Регистр указывает на ад-
рес нахождения аргументов. A←A+B - результат помещается на мес-
то аргумента A.


   FSUB Rn

   Вычитание чисел с плавающей запятой. A←A-B - результат в A.

      FSUB R5      ;R5 указывает на адрес MET
      HALT
MET: A            ;два слова аргумента A
      B            ;два слова аргумента B


   Формат чисел с плавающей запятой:

Первое слово :  15  14        07  06                 00
                 ├───┼─────────┼───┼──────────────────┤
                 S   Порядок        ст. часть мантиссы

Второе слово :  15                                   00
                 ├────────────────────────────────────┤
                          младшая часть мантиссы


   FMUL Rn

   Умножение  чисел  с  плавающей запятой. A←A*B - результат на
месте аргумента A.


   FDIV Rn

   Деление чисел с плавающей запятой. A←A/B - результат на мес-
те  аргумента A. Если  делитель (B) равен  нулю, то результат в
стек не записывается.
   Подробнее  об  использовании  команд  расширенной арифметики
можно узнать в документациях к программам MICRO или TURBO.

Коренков Василий Семенович                 тел. (095) 4359514
Надежин Алексей                            тел. (095) 1803002
ъ                              - 10 -


        BR   BOOT0    ;Aвтоматическая загрузка         160000
        BR   BOOT1    ;Загрузка с выбранного привода   160002
        BR   RWBLK    ;Чтение-запись по номеру блока   160004
        BR   RWSEC    ;Чтение-запись по номеру сектора 160006
        BR   INIT     ;Инициализация рабочей области   160010
        JMP  FORMAT   ;Форматирование дорожки          160012
        JMP  EXT      ;Расширенная арифметика          160016

            *** 160022 П/п автоматической загрузки ***

BOOT0:  CLR  R0       ;Начнем с нулевого привода
        CALL BOOT     ;Пробуем загрузиться
        MOV  #1,R0    ;Там не получилось, попробуем с первого
        CALL BOOT     ;Загружаем...
        BR   STOP     ;Загрузчика нигде нет, выходим

           *** 160042 Загрузка с выбранного привода ***

BOOT1:  MOV  #1000,SP ;Установим стек
        CALL BOOT     ;Попробуем загрузиться

     *** 160052 Остановка двигателя НГМД и выход из п/п ***

STOP:   CLR  (R3)
        CLR  @#177130
        CLR  @#177760
        RET

        *** 160066 П/п загрузки и запуска загрузчика ***

BOOT:   MOV  #2000,R3     ;Установим адрес рабочей области
        CALL INIT         ;   и инициализируем ее
        MOVB R0,34(R3)    ;Занесем номер привода
        CLR  R0           ;Читаем нулевой блок
        MOV  #400,R1      ;   длиной 400 слов (1000 байт)
        MOV  #1000,R2     ;   с адреса 1000
        CALL RWBLK        ;Прочитаем...
        BCS  1$           ;   не получилось - выход
        CMP  @#1000,#240  ;Загрузчик начинается с NOP?
        BNE  1$           ;Нет - выход
        CMP  @#1002,#5    ;Вторая команда - RESET?
        BEQ  1$           ;Да - диск не системный, выход
        MOVB 34(R3),R0    ;Вспомним, откуда это мы загрузились
        CALL @#1000       ;Запускаем загрузчик...
1$:     RET               ;Вот и все

          *** 160154 Чтение-запись по номеру сектора ***

RWSEC:  BR   SUBRW

        *** 160156 П/п инициализации рабочей области ***

INIT:   CLR  (R3)         ;Очистим копию РС КНГМД
        MOV  #177777,4(R3);Заполним таблицу текущих дорожек
        MOV  #177777,6(R3)
        MOV  #23420,10(R3);Время опускания головки
        MOV  #23420,12(R3);Время перехода дорожки
        MOVB #40,14(R3)   ;Дорожка начала предкомпенсации


                              - 11 -


        MOVB #24,15(R3)   ;Число повторов при ошибке
        CLRB 16(R3)       ;Очистим флаги
        CLR  22(R3)       ;   и таблицу признаков
        CLR  24(R3)
        MOV  #12,60(R3)   ;Занесем число секторов на дорожке
        RET

        *** 160250 П/п чтения-записи по номеру блока ***

   Входные параметры:
      R0 - номер блока
      R1 - длина массива в словах (отрицательная - запись)
      R2 - адрес начала массива
      R3 - адрес рабочей области

RWBLK:  MOV  #10,R4
        MOVB 60(R3),R5;число секторов на дорожке
        SWAB R5       ;делим ст. байт R0 на ст. байт R5
1$:     CMP  R5,R0
        BHI  2$
        SUB  R5,R0
        SEC
2$:     ROL  R0       ;Частное накапливается в мл. байте R0
        SOB  R4,1$
        MOVB R0,R4    ;В мл. байте номер дорожки, сохраним его
        CLRB R0
        SWAB R0       ;Получили остаток от деления
        INC  R0       ;Номер сектора на единичку больше
        CLRB 32(R3)   ;Пока мы на нижней стороне
        CMP  R0,60(R3);Этот сектор за пределами дорожки?
        BLE  3$       ;Нет - полный порядок
        INCB 32(R3)   ;Да - значит, он на другой стороне
        SUB  60(R3),R0;   и номер у него другой
3$:     CALL SETPTR   ;Установим указатель на байт признаков
        BITB #2,@20(R3);Диск односторонний?
        BEQ  4$       ;Нет - оставим все как есть
        ASRB 32(R3)   ;Да - сторона всегда 0,
        ROLB R4       ;   а дорожка уже другая
4$:     MOVB R4,33(R3);Запишем результаты: дорожка,
        MOVB R0,35(R3);   сектор,
        MOV  R1,30(R3);   число слов,
        MOV  R2,26(R3);   адрес буфера

       *** 160372 П/п чтения-записи по номеру сектора ***

   Входные параметры:
      R3 - базовый адрес рабочей области
      ADDR, WCNT, SIDE, TRK, UNIT, SECTOR - соответственно

SUBRW:  MOV  SP,50(R3)    ;Сохраняем SP,
        MFPS 52(R3)       ;   PSW,
        MOV  #4,R0
        MOV  (R0),46(R3)  ;   @#4 в соответствующих буферах
        MOV  PC,(R0)      ;Переназначаем вектор @#4 на себя,
        ADD  #1076,(R0)   ;   теперь он равен 161512
        TSTB 35(R3)       ;Какой сектор нужен?
        BEQ  ERR12        ;Нулевых у нас нет, ошибка 12
        CMPB 35(R3),60(R3);Сектор больше максимального?
        BGT  ERR12        ;Таких тоже нет, ошибка 12

                              - 12 -


        CLRB @#52         ;Пока ошибок нет
        BICB #30,16(R3)   ;Пока не записываем
        TST  30(R3)       ;Сколько слов будем пересылать?
        BEQ  QUIT         ;0 - ничего делать не надо, выход
        BPL  READ         ;больше 0 - будем читать

              *** 160460 П/п записи массива ***

        NEG  30(R3)       ;Нормализуем длину
        BISB #20,16(R3)   ;Установим признак записи
        MOV  #175641,40(R3);Запомним маркер данных
        BITB #1,16(R3)    ;Записываем скрытно?
        BEQ  1$           ;Нет - идем дальше
        MOV  #174241,40(R3);Да - запомним специальный маркер
1$:     CALL ENGINE       ;Включим двигатель, запомним привод
        BIT  #4,(R4)      ;Защита записи есть?
        BEQ  MAIN         ;Нет - продолжить работу
        MOV  #1,R0        ;Есть - ошибка 1
        BR   ERR

               *** 160536 П/п чтения массива ***

READ:   CALL ENGINE       ;Включим двигатель, запомним привод
        MOV  #400,64(R3)  ;Сектора стандартной длины
        BITB #4,@20(R3)   ;А они ли нам нужны?
        BEQ  MAIN         ;Да - продолжить работу
        MOV  #1000,64(R3) ;Нет - секторы удвоенной длины

         *** Основная часть п/п чтения/записи массива ***

MAIN:   CALL GOTRK        ;Спозиционируем на нужную дорожку
        CALL CORR         ;Включим схему прекоррекции
        MOVB 15(R3),54(R3);Число попыток - в буфер

               *** Получение заголовка сектора ***

        MOVB #10,57(R3)   ;Предполагаем ошибку 10
        MOVB #24,55(R3)   ;На операцию отводим 20. оборотов
1$:     CALL FINDH        ;Найдем маркер заголовка
        BCC  3$           ;Нашли - идем дальше
2$:     MOVB 57(R3),R0    ;Не нашли - выходим с ошибкой
        BR   ERR
3$:     TSTB (R4)         ;Информация получена?
        BPL  3$           ;Нет - подождем
        MOV  (R5),R0      ;Теперь прочитаем ее
4$:     TSTB (R4)         ;Хотим еще информации!
        BPL  4$           ;Дождемся ее появления
        MOV  (R5),R1      ;   и заберем ее
        CALL TSTCRC       ;Проверим CRC
        BNE  5$           ;Ошибки нет - идем дальше
        MOVB #2,57(R3)    ;Ошибка 2!
        DECB 54(R3)       ;Остались еще попытки?
        BNE  1$           ;Да - повторим чтение
        BR   2$           ;Видно, не судьба! Выходим с ошибкой
5$:     BIC  #177774,R1   ;Выделяем код длины сектора
        BITB #4,@20(R3)   ;Какие сектора нам были нужны?
        BNE  LONG         ;Длинные - посмотрим...
        CMPB R1,#2        ;Короткие. А на диске какие?
        BEQ  WORK         ;Тоже короткие. Порядок, идем дальше
ъ                              - 13 -


        DECB 54(R3)       ;Как там дела с попытками?
        BNE  1$           ;Есть еще - повторим все сначала

               *** 160724 Выход с ошибкой ***

ERR12:  MOV  #12,R0   ;Выходим с ошибкой 12
ERR:    JMP  ERROR    ;Идем на обработку и выход
QUIT:   JMP  EXIT     ;Идем на нормальный выход

LONG:   CMPB R1,#2    ;Нужны длинные сектора, а какие здесь?
                      ;   ОШИБКА: На самом деле код длинных
                      ;            секторов - 3, а не 2
        BNE  ERR12    ;Длинные - выходим с ошибкой 12

                *** Собственно п/п чтения ***

WORK:   MOVB 15(R3),54(R3);Восстановим счетчик по BRETRY
        MOVB #6,56(R3)    ;На поиск сектора - 6 попыток
        CLR  42(R3)       ;Остаток сектора отсутствует
        CMP  30(R3),64(R3);Читать надо больше одного сектора?
        BHI  1$           ;Да - идем читать
        MOV  64(R3),42(R3)
        SUB  30(R3),42(R3);Вычислим длину остатка
1$:     MOVB #5,57(R3)    ;Прогнозируем ошибку 5
2$:     MOVB #24,55(R3)   ;На операцию отводим 20. оборотов
3$:     CALL FINDH        ;Ищем маркер заголовка
        BCC  4$           ;Нашли - идем дальше
        MOVB 57(R3),R0    ;Кончились обороты - выходим
        BR   ERR          ;   с ошибкой
4$:     TSTB (R4)         ;Готовность данных есть?
        BPL  4$           ;Нет - подождем
        CMP  32(R3),(R5)  ;Нужная дорожка и сторона?
        BEQ  5$           ;Да - идем дальше
        DECB 56(R3)       ;Минус одна попытка
        BEQ  6$           ;Кончились - выход с ошибкой
        CALL GOTO00       ;Спозиционируем на дорожку 00,
        CALL GOTRK        ;   вернемся на нужную
        BR   3$           ;   и попытаемся еще раз
6$:     MOV  #4,R0        ;Выходим с ошибкой 4
        BR   ERR
5$:     TSTB (R4)         ;Ждем готовности данных
        BPL  5$           ;Не готовы - повторять...
        MOV  (R5),R1      ;Получим номер сектора,
        SWAB R1           ;   поместим его в младший байт
        CMPB 35(R3),R1    ;Этот сектор ищем?
        BEQ  7$           ;Да - будем его читать
        MOV  64(R3),R0    ;Нет - возьмем длину данных,
        ADD  #27,R0       ;   прибавим длину заголовка
        CALL FICT         ;   и пропустим их
        BR   3$           ;Повторим процедуру еще раз
7$:     CALL TSTCRC       ;Проверим CRC
        BNE  8$           ;Совпала - идем дальше
        MOVB #2,57(R3)    ;Если что, это будет ошибка 2
        DECB 54(R3)       ;Одной попыткой меньше
        BNE  2$           ;Еще остались - поищем снова
        MOVB 57(R3),R0    ;Нет - выходим с ошибкой
        BR   ERROR
8$:     MOV  64(R3),R1    ;Получим длину сектора
        SUB  42(R3),R1    ;Вычислим длину используемой части

                              - 14 -


               *** 161176 Чтение сектора ***

        BITB #20,16(R3);Будем записывать?
        BEQ  9$       ;Нет - значит, читать
        JMP  WRSEC    ;Да - идем на запись сектора
9$:     CALL FINDS    ;Ищем зону синхронизации
        TSTB 56(R3)   ;Нашли?
        BEQ  11$      ;Нет - пробуем снова
        CALL STREAD   ;Начинаем чтение!
        MOV  #1130,R0 ;
10$:    TSTB (R4)     ;Данные готовы?
        BMI  12$      ;Да - посмотрим их
        SOB  R0,10$   ;Больше ждать нельзя?
11$:    MOVB #11,57(R3);Да - прогнозируем ошибку 11
        DECB 54(R3)   ;Одной попыткой меньше
        BNE  2$       ;Попытки есть - повторим операцию
        MOVB 57(R3),R0;Кончились - выйдем с ошибкой
        BR   ERROR
12$:    TST  (R5)     ;Пропустим маркер A1A1
13$:    TSTB (R4)     ;Готовность данных есть?
        BPL  13$      ;Нет - ждем
        MOV  (R5),R0  ;Прочитаем данные
        CMP  #120773,R0;Обычный сектор?
        BEQ  14$      ;Да - идем дальше
        CMP  #120770,R0;Скрытый сектор?
        BNE  11$      ;Что-то иное - ошибка
        BITB #1,16(R3);Можно читать скрытые данные?
        BNE  14$      ;Да - будем читать
        MOV  #13,R0   ;Нельзя - выходим с ошибкой 13
        BR   ERROR
14$:    CALL RDSEC    ;Прочитаем сектор
        CALL TSTCRC   ;Проверим CRC
        BNE  NEXT     ;Совпала - посмотрим следующий сектор
        MOVB #1,57(R3);Не совпала - ошибка 1
        DECB 54(R3)   ;Попытки кончились?
        BNE  2$       ;Нет - попробуем еще раз
        MOVB 57(R3),R0;Кончились - выходим с ошибкой
        BR   ERROR

           *** 161362 Мультисекторные операции **+

NEXT:   SUB  64(R3),30(R3);Сектор обработали, вычтем из длины
        BLE  EXIT         ;Массив кончился - выход
        INCB 35(R3)       ;Нет - следующий сектор
        CMPB 35(R3),60(R3);Конец дорожки?
        BLOS 3$           ;Нет - продолжим обработку
        BIT  #40,(R3)     ;Верхняя сторона?
        BNE  1$           ;Да - следующая дорожка
        BITB #2,@20(R3)   ;Диск односторонний?
        BNE  1$           ;Да - продолжим обработку
        MOVB #1,32(R3)    ;Нет - установим верхнюю сторону
        BIS  #40,(R3)
        BR   2$           ;Перейдем к обработке
1$:     INCB 33(R3)       ;Следующая дорожка
        CALL GOTRK        ;Спозиционируем на нее
        CLRB 32(R3)       ;Установим нижнюю сторону
        BIC  #40,(R3)
2$:     MOVB #1,35(R3)    ;Теперь сектор будет первым
        CALL CORR         ;Переключить прекоррекцию

                              - 15 -


3$:     ADD  64(R3),26(R3);Получим новый начальный адрес
        ADD  64(R3),26(R3)
        JMP  WORK         ;Идем на чтение очередного сектора

      *** 161512 Обработка прерывания по вектору 4 ***

        TST  (R5)     ;Сбросить данные
        MOV  #7,R0    ;Заносим код ошибки 7

                 *** Выход с ошибкой ***

ERROR:  MOVB R0,@#52  ;Код ошибки - на место!
        MOVB #1,56(R3);Установим бит C в буфере
        BR   EXIT1    ;Идем на выход

                 *** Выход без ошибки ***

EXIT:   CLRB 56(R3)   ;Сбросим бит C в буфере
EXIT1:  MOV  46(R3),@#4;Восстановить вектор 4
        MTPS 52(R3)   ;Восстановить PSW
        CCC           ;Сбросить все признаки
        RORB 56(R3)   ;Бит C - из буфера в PSW
        MOV  50(R3),SP;Восстановить SP
        RET           ;Возврат

              *** 161566 П/п проверки CRC ***

TSTCRC: TSTB (R4)         ;Ждем готовности данных
        BPL  TSTCRC
        MOV  #17,R2       ;CRC появится не позже 15. циклов
1$:     BIT  #40000,(R4)  ;CRC сошлась?
        BNE  2$           ;Да - выход
        SOB  R2,1$        ;Нет - очередной цикл
2$:     RET               ;Если бит Z=1, то произошла ошибка

          *** 161610 П/п чтения сектора в буфер ***

   Входные параметры: R1 - число слов для пересылки

RDSEC:  MTPS #340     ;Маскируем прерывания
        MOV  26(R3),R2;Получим адрес буфера
1$:     TSTB (R4)     ;Ожидаем данные
        BPL  1$
        MOV  (R5),R0  ;Читаем два байта,
        SWAB R0       ;   делаем из них нормальное слово,
        MOV  R0,(R2)+ ;   которое суем в буфер
        SOB  R1,1$    ;Читаем заказанное число слов
        MOV  42(R3),R1;Получаем длину остатка
        BEQ  3$       ;Остатка нет - сразу выходим
2$:     TSTB (R4)     ;Ждем данные
        BPL  2$
        TST  (R5)     ;Вхолостую читаем остаток
        SOB  R1,2$    ;   требуемой длины
        MTPS 52(R3)   ;Восстанавливаем PSW
3$:     RET




ъ                              - 16 -


      *** 161660 П/п поиска синхропоследовательности ***

FINDS:  TST  (R5)         ;Сбрасываем прочитанное значение
        MOVB #144,56(R3)  ;Будем искать 100. циклов
1$:     TSTB (R4)         ;Ждем готовности
        BPL  1$
        MOV  (R5),R0      ;Получим прочитанные данные
        BEQ  2$           ;Это 0 - на выход
        INC  R0           ;Это 177777?
        BEQ  2$           ;Да - на выход
        DECB 56(R3)       ;Циклы кончились?
        BNE  1$           ;Нет - повторяем поиск
2$:     RET

     *** 161714 П/п чтения двух слов (не используется) ***

01$:    TSTB (R4)     ;Ждем готовности
        BPL  01$
        MOV  (R5),R0  ;Получаем первое слово
02$:    TSTB (R4)     ;Ждем готовности
        BPL  02$
        MOV  (R5),R1  ;Получаем второе слово
        RET

              *** 161732 П/п запуска чтения ***

STREAD: BIS  #400,(R3);Установим признак "начало чтения"
        MOV  (R3),(R4);   и запишем в регистр
        BIC  #400,(R3);Снимем признак
        MOV  #10,R0
1$:     SOB  R0,1$    ;Небольшая задержка...
        MOV  (R3),(R4);   и снова запишем в регистр
        RET

   *** 161756 П/п поиска начала индекса (не используется) ***

01$:    TST  (R4)     ;Индекс есть?
        BMI  01$      ;Да - ждем исчезновения
        BIS  #400,(R3);Установим признак "начало чтения"
        MOV  (R3),(R4);   и запишем в регистр
02$:    TST  (R4)     ;Индекса еще нет?
        BPL  02$      ;Да - ждать появления
        MOV  62(R3),R0
03$:    SOB  R0,03$   ;Задержимся...
        BIC  #400,(R3);Сбросим признак "начало чтения"
        MOV  (R3),(R4);   и запишем в регистр
        RET

          *** 162012 П/п поиска адресного маркера ***

FINDH:  MOV  #17,R0
1$:     TST  (R5)     ;Вхолостую прочитаем
        SOB  R0,1$    ;   15. слов
        CLR  44(R3)   ;Начинаем ожидание индекса
        BICB #40,16(R3);Пока индекса нет
2$:     BITB #10,@20(R3);Сектор задан задержкой?
        BEQ  7$       ;Нет - обрабатывать
        CMPB 35(R3),#1;Да - нужен первый сектор?
        BNE  7$       ;Второй и далее задаются заголовками

                              - 17 -


        BIS  #400,(R3);Установим признак "начало чтения"
        MOV  (R3),(R4);   и перешлем в регистр
3$:     TST  (R4)     ;Индекс есть?
        BMI  3$       ;Да - ждем исчезновения
4$:     TST  (R4)     ;Индекс есть?
        BPL  4$       ;Нет - ждем появления
        DECB 55(R3)   ;Один оборот окончен
        BNE  5$       ;Не кончились - продолжаем
        SEC           ;Кончились - выходим с битом C
        BR   18$
5$:     MOV  62(R3),R0;Получим задержку после индекса
6$:     SOB  R0,6$
        BR   12$      ;Сектор, похоже, найден, идем дальше
7$:     CALL INDEX    ;Проверим наличие диска и обороты
        BCS  18$      ;Обороты кончились - выходим
        BEQ  7$       ;Какие данные? Нули пропустим
        COM  R0       ;177777?
        BEQ  7$       ;Да - тоже пропустим
8$:     CALL INDEX    ;Проверим наличие диска и обороты
        BCS  18$      ;Обороты кончились - выходим
        BEQ  9$       ;Какие данные? Нули - синхро
        COM  R0       ;177777?
        BNE  8$       ;Нет - пропустим

              *** Проверка адресного маркера ***

9$:     MOV  #3,R1
10$:    MOV  (R5),R0      ;Читаем данные
        BEQ  11$          ;Нули - продолжаем
        COM  R0           ;177777?
        BNE  7$           ;Нет - повторяем поиск
11$:    SOB  R1,10$       ;Да - повторяем 3 раза
12$:    CALL STREAD       ;Запускаем на чтение
        MOV  #74,R0       ;ОШИБКА! Здесь должно быть 2000
13$:    TSTB (R4)         ;Готовность есть?
        BMI  14$          ;Есть - считываем данные
        SOB  R0,13$       ;Нет - ждем
        BR   2$           ;Надоело ждать - повторяем поиск
14$:    TST  (R5)         ;Пропускаем A1A1
15$:    TSTB (R4)         ;Ждем готовности
        BPL  15$
        MOV  (R5),R0      ;Есть - берем данные
        CMP  #120776,R0   ;Адресный маркер (A1FE)?
        BEQ  17$          ;Да - нормальный выход
        CMP  #120773,R0   ;Нет - маркер данных (A1FB)?
        BEQ  16$          ;Да - пропускаем сектор
        CMP  #120770,R0   ;Нет - маркер скрытых данных (A1F8)?
        BNE  2$           ;Нет - повторяем поиск сначала
16$:    CALL FRESEC       ;Да - пропускаем сектор
        BR   2$           ;Повторяем поиск сначала
17$:    CLC
18$:    RET

  *** 162246 П/п проверки наличия диска и числа оборотов ***

INDEX:  TST  (R4)         ;Индекс есть?
        BPL  2$           ;Нет - идем проверять
        BITB #40,16(R3)   ;Индекс есть - он уже был?
        BNE  3$           ;Был - идем увеличивать время

                              - 18 -


        CLR  44(R3)       ;Только что появился - очистим время
        BISB #40,16(R3)   ;   и запомним факт появления
        DECB 55(R3)       ;Закончился последний оборот?
        BNE  1$           ;Нет - нормальный выход
        SEC               ;Да - выход с ошибкой
        RET
1$:     CLC
        MOV  (R5),R0      ;Забираем данные
        RET
2$:     BITB #40,16(R3)   ;Индекса нет - а он был?
        BEQ  3$           ;Нет и не было - идем считать время
        CLR  44(R3)       ;Только что исчез - очистим время
        BICB #40,16(R3)   ;   и запомним факт исчезновения
        BR   1$           ;Нормально выходим
3$:     INC  44(R3)       ;Еще один такт индекс не менялся
        CMP  44(R3),#60000;Ну сколько можно! Пора кончать?
        BLOS 1$           ;Не пора - нормальный выход
        MOV  #6,R0        ;Терпение кончилось -
        JMP  ERROR        ;   значит, диска нет - ошибка 6

             *** 162364 П/п выбора устройства ***

ENGINE: MOV  #177130,R4   ;Заполняем рабочие регистры
        MOV  R4,R5        ;   адресами РС и
        TST  (R5)+        ;   РД КНГМД
        BICB #4,16(R3)    ;Очистим признак работы двигателя
        BIT  #20,(R3)     ;Двигатель уже включен?
        BEQ  1$           ;Нет - включим
        BISB #4,16(R3)    ;Да - установим признак
1$:     BIS  #20,(R3)     ;Включим двигатель
        MOV  (R3),(R4)    ;   и запишем в регистр
        BIC  #57,(R3)     ;Сбросим все другие режимы
        TSTB 32(R3)       ;Сторона верхняя?
        BEQ  2$           ;Да - идем дальше
        BIS  #40,(R3)     ;Нет - включим нижнюю
2$:     BICB #177774,34(R3);Сбросим лишние биты
        MOVB 34(R3),R1    ;Получим номер привода
        MOV  PC,R0        ;Получим базовый адрес
        ADD  #56,R0       ;   таблицы масок для приводов
        ADD  R1,R0        ;Получим адрес нужной маски
        BISB (R0),(R3)    ;Установим бит нужного привода
        ADD  R3,R1        ;Получим базовый адрес
        ADD  #4,R1        ;   таблицы TRKTAB
        MOV  R1,2(R3)     ;Настроим указатель CURTRK
        CALL SETPTR       ;Настроим указатель FLGPTR
        BITB #4,16(R3)    ;Мотор включен только что?
        BNE  5$           ;Нет - выходим
        CLR  R1           ;Да - подождем раскручивания
3$:     SOB  R1,3$
4$:     SOB  R1,4$
5$:     MOV  (R3),(R4)    ;Записываем установки в регистр
        MOV  10(R3),R1    ;Подождем опускания головки
6$:     SOB  R1,6$
        RET






                              - 19 -


         *** Таблица масок для включения приводов ***

        .B:1  ;A:
        .B:2  ;B:
        .B:4  ;C:
        .B:10 ;D:

        *** 162540 П/п настройки указателя FLGPTR ***

SETPTR: CLR  20(R3)       ;Очистим указатель FLGPTR
        BICB #177774,34(R3);Отбросим лишние биты
        MOVB 34(R3),20(R3);Перешлем номер привода в FLGPTR
        ADD  R3,20(R3)    ;Прибавляя базовый адрес FLGTAB,
        ADD  #22,20(R3)   ;   получаем искомый адрес
        RET

            *** 162574 П/п позиционирования ***

GOTRK:  TSTB 33(R3)   ;Нужна дорожка 00?
        BEQ  GOTO00   ;Да - позиционируем прямо на нее
        TSTB @2(R3)   ;Положение головки известно?
        BPL  1$       ;Да - будем искать требуемую
        CALL GOTO00   ;Нет - придется сориентироваться
1$:     CMPB @2(R3),33(R3);Нужная дорожка совпадает с текущей?
        BEQ  3$       ;Да - так что же мы тут делаем?
        BHI  2$       ;Нет - искомая ближе к центру?
        CALL GOUP     ;Да - шагнем к центру
        BR   1$       ;Проверим, дошли ли
2$:     CALL GODOWN   ;Нет - шагнем к периферии
        BR   1$       ;Проверим, дошли ли
3$:     MOV  #23420,R0;Подождем успокоения головки
4$:     SOB  R0,4$    ;Теперь можно и выйти
        RET

                  *** Шаг к центру ***

GOUP:   INCB @2(R3)   ;Номер дорожки станет на 1 больше
        BMI  1$       ;Таких дорожек нет - выходим с ошибкой
        BIS  #100,(R3);Все в порядке - шагать будем вперед
        BR   STEP     ;Пойдем шагать
1$:     MOV  #4,R0    ;Выход с ошибкой 4
        JMP  ERROR

                *** Шаг к периферии ***

GODOWN: DECB @2(R3)   ;Номер дорожки станет на 1 меньше
        BIT  #1,(R4)  ;Дошли до дорожки 00?
        BEQ  1$       ;Нет - можно шагать
        CLRB @2(R3)   ;Дошли: теперь текущая - 00
        RET           ;   и можно выйти
1$:     BIC  #100,(R3);Шагать будем назад
STEP:   MOV  #310,R0  ;Подготовим задержку
        MOV  (R3),(R4);Перешлем направление шага в регистр
3$:     SOB  R0,3$    ;Подождем, пока контроллер "переварит"
        BIS  #200,(R3);Установим признак шага
        MOV  (R3),(R4);   и запишем в регистр
        MOV  12(R3),R0;Получим задержку перехода дорожки
4$:     SOB  R0,4$    ;   и задержимся
                               - 20 -


        BITB #1,@20(R3);Двойной шаг?
        BEQ  6$       ;Нет - можно выходить
        BITB #100,16(R3);Мы возвращаемся на 00?
        BNE  6$       ;Да - возвращаться надо одинарным шагом
        MOV  (R3),(R4);Нет - придется шагнуть еще
        MOV  12(R3),R0;Получим задержку перехода дорожки
5$:     SOB  R0,5$    ;   и задержимся
6$:     BIC  #200,(R3);Очистим признак шага
        RET

          *** 163004 П/п возврата на дорожку 00 ***

GOTO00: MOVB #200,@2(R3)  ;Установим счетчик дорожек
        BISB #100,16(R3)  ;Возвращаться надо одинарным шагом
1$:     CALL GOUP         ;Шагнем к периферии
        BIT  #1,(R4)      ;Дошли до 00?
        BNE  2$           ;Да - выходим
        TSTB @2(R3)       ;На какой дорожке должны находиться?
        BNE  1$           ;Не на нулевой - еще шагнем
        MOV  #3,R0        ;На нулевой, а ее нет - ошибка 3
        BICB #100,16(R3)  ;Сбросим режим одинарного шага
        JMP  ERROR        ;Выходим с ошибкой
2$:     CLRB @2(R3)       ;Дошли - текущая теперь нулевая
        BICB #100,16(R3)  ;Сбросим режим одинарного шага
        RET

              *** 163072 П/п пропуска сектора ***

FRESEC: MOV  64(R3),R0;Получим длину сектора
FICT:   TST  (R4)     ;Индекс есть?
        BMI  4$       ;Да - ждем начала оборота
1$:     TST  (R4)     ;Индекс все еще есть?
        BMI  3$       ;Да - оборот завершен
2$:     TSTB (R4)     ;Данные готовы?
        BPL  1$       ;Нет - снова
        TST  (R5)     ;Прочитаем данные вхолостую
        SOB  R0,1$    ;   требуемое число раз
        BR   6$       ;   и выйдем
3$:     DECB 55(R3)   ;Все обороты вышли?
        BNE  5$       ;Нет - попытаемся снова
        MOV  #5,R0    ;Да - выходим с ошибкой 5
        JMP  ERROR
4$:     TST  (R4)     ;Индекс исчез?
        BPL  2$       ;Да - оборот начался
5$:     TSTB (R4)     ;Данные готовы?
        BPL  4$       ;Нет - проверим индекс
        TST  (R5)     ;Прочитаем данные вхолостую
        SOB  R0,4$    ;   требуемое число раз
6$:     RET           ;   и вернемся к основной работе


              *** 163154 П/п записи сектора ***

   Входные параметры:
      R1 - число слов для записи

WRSEC:  MOV  26(R3),R2;Получим начальный адрес массива
        MOV  #13,R0   ;В маркере будет 11. 4E4E
        MTPS #340     ;При записи нам не мешать!

                              - 21 -


        CALL WRMAR    ;Запишем маркер данных
1$:     TSTB (R4)     ;Готовность есть?
        BPL  1$       ;Нет - ждем
        MOV  (R2)+,(R5);Запишем первое слово данных
        MOV  (R3),(R4);Снимем признак записи маркера
        BR   3$       ;   и пойдем записывать данные
2$:     TSTB (R4)     ;Готовность есть?
        BPL  2$       ;Нет - дождемся
        MOV  (R2)+,(R5);Запишем слово данных
3$:     SOB  R1,2$    ;   и так до конца
        MOV  42(R3),R1;Получим длину пустого остатка сектора
        BEQ  5$       ;Остатка нет - выходим сразу
4$:     TSTB (R4)     ;Готовность есть?
        BPL  4$       ;Дожидаемся
        MOV  #0,(R5)  ;Записываем нули
        SOB  R1,4$    ;   в нужном количестве
5$:     BIT  #40000,(R4);Ждем записи CRC
        BEQ  5$
        MOV  #47116,(R5);Записываем 4E4E
6$:     TSTB (R4)     ;Готовность есть?
        BPL  6$       ;Нет - ждем
        TST  (R5)     ;Прекращаем запись
        MTPS 52(R3)   ;Восстанавливаем PSW
        JMP  NEXT     ;Продолжаем запись массива

          *** 163266 П/п записи маркера данных ***

   Входные данные:
      R0 - число записываемых слов 4Е4Е

WRMAR:  MOV  #47116,(R5)  ;Запишем 4E4E
        BR   2$           ;Идем на повтор записи
1$:     TSTB (R4)         ;Готовность есть?
        BPL  1$           ;Нет - дождемся
        MOV  #47116,(R5)  ;Запишем 4E4E
2$:     SOB  R0,1$        ;Повторим заданное число раз
        MOV  #6,R0        ;Запишем 12. нулевых байтов
3$:     TSTB (R4)         ;Готовность есть?
        BPL  3$           ;Нет - ожидаем
        MOV  #0,(R5)      ;Записываем нули
        SOB  R0,3$        ;   в нужном количестве
        BIS  #1000,(R3)   ;Подготовим признак записи маркера
4$:     TSTB (R4)         ;Контроллер готов?
        BPL  4$           ;Нет - ждем
        MOV  #120641,(R5) ;Записываем маркер A1A1
        MOV  (R3),(R4)    ;Передаем признак в контроолер
        BIC  #1000,(R3)   ;Заранее снимем признак
5$:     TSTB (R4)         ;Готовность есть?
        BPL  5$           ;Нет - ожидаем
        MOV  40(R3),(R5)  ;Записываем маркер из буфера
        RET

         *** 163360 П/п установки прекоррекции ***

CORR:   BIC  #2000,(R3)   ;Снимем прекоррекцию
        CMPB 14(R3),@2(R3);Надо включать на текущей дорожке?
        BHI  1$           ;Нет - пропустим
        BIS  #2000,(R3)   ;Пора - включим


                              - 22 -


1$:     MOV  (R3),(R4)    ;Перешлем управляющее слово
        MOV  #310,R0
2$:     SOB  R0,2$        ;Подождем, пока контроллер воспримет
        RET

             *** 163412 П/п форматирования ***

FORMAT: MOV  SP,50(R3)    ;Сохраним SP,
        MFPS 52(R3)       ;   PSW,
        MOV  #4,R0
        MOV  (R0),46(R3)  ;  @#4 в соответствующих буферах
        MOV  PC,(R0)      ;Переназначаем вектор @#4 на себя,
        ADD  #176056,(R0) ;   теперь он равен 161512
        CALL ENGINE       ;Запустим двигатель
        CALL GOTRK        ;Спозиционируем на нужную дорожку
        CALL CORR         ;Установим прекоррекцию
        BIT  #4,(R4)      ;Защита записи включена?
        BEQ  2$           ;Нет - начнем форматировать
        MOV  #1,R0        ;Да - ошибка 1
1$:     JMP  ERROR        ;Выходим с ошибкой
2$:     SWAB 32(R3)       ;Обмениваем номера стороны и дорожки
        MOVB 17(R3),36(R3);Делаем слово-заполнитель
        MOVB 17(R3),37(R3);   из байта-заполнителя
        MOVB 60(R3),R1    ;Получим длину сектора
        MOV  #1001,R2     ;Запомним номер сектора и код длины
        MOV  #1750,R0     ;Время ожидания индекса
3$:     TST  (R4)         ;Индекс есть?
        BPL  5$           ;Исчез - начнем записывать
        SOB  R0,3$        ;Есть - ждем исчезновения
4$:     TST  (R5)         ;Так и не исчез - прекратим запись
        MOV  #6,R0        ;Диск не вращается - ошибка 6
        SWAB 32(R3)       ;Вернем все на место
        BR   1$           ;Выходим с ошибкой


             *** Запись на дорожку кода 4E4E ***

5$:     MOV  #6200,R0 ;Установим максимальную длину
        MTPS #340     ;При записи нам не мешать!!!
        MOV  #47116,(R5);Записываем 4E4E
6$:     TST  (R4)     ;Индекс появился?
        BMI  8$       ;Да - начнем запись
7$:     TSTB (R4)     ;Готовность есть?
        BPL  7$       ;Нет - ждем
        MOV  #47116,(R5);Записываем 4E4E
        SOB  R0,6$    ;И так до конца дорожки
        BR   4$       ;Однако, дорожка длинная, ошибка!
8$:     MOV  #20,R0   ;В маркере будет 16. 4E4E (GAP1)
        MOV  #177241,40(R3);Адресный маркер (FEA1) - в буфер
9$:     CALL WRMAR    ;Записываем адресный маркер
10$:    TSTB (R4)     ;Готовность есть?
        BPL  10$      ;Нет - ожидаем
        MOV  32(R3),(R5);Записываем номер стороны и дорожки
        MOV  (R3),(R4);Перешлем управляющее слово
11$:    TSTB (R4)     ;Готовность есть?
        BPL  11$      ;Нет - дождемся
        MOV  R2,(R5)  ;Записываем номер сектора и код длины
        MOV  #13,R0   ;В маркере будет 11. 4E4E (GAP2)
        MOV  #175641,40(R3);Маркер данных (FBA1) - в буфер

                              - 23 -


12$:    BIT  #40000,(R4) ;Ждем записи CRC
        BEQ  12$
        CALL WRMAR    ;Записываем маркер данных
        MOV  64(R3),R0;Получаем длину сектора
        DEC  R0       ;Одно слово запишем сейчас
13$:    TSTB (R4)     ;Готовность есть?
        BPL  13$      ;Нет - ожидаем
        MOV  36(R3),(R5);Записываем заполнитель
        MOV  (R3),(R4);Перешлем управляющее слово
14$:    TSTB (R4)     ;Готовность есть?
        BPL  14$      ;Нет - дождемся
        MOV  36(R3),(R5);Записываем заполнитель
        SOB  R0,14$   ;И так до конца сектора
        INC  R2       ;Увеличим номер сектора
        MOV  #22,R0   ;В маркере будет 18. 4E4E (GAP3)

;Примечание. Если увеличить GAP3 до 24-27 слов, то запись будет
;производиться  так  же  быстро, как и чтение (обычно заголовок
;очередного сектора проскакивает, и дорожка  записывается не за
;один, а за 10. оборотов). Однако при превышении этой величиной
;определенного значения конец последнего  сектора дорожки может
;наложиться на ее же начало.

        BIT  #4,@20(R3);Сектора длинные?
        BEQ  15$      ;Нет - все нормально
        MOV  #72,R0   ;Да - будет 116. 4E4E (можно увеличить
                      ;                       до 75)
15$:    MOV  #177241,40(R3);Адресный маркер (FEA1) - в буфер
16$:    BIT  #40000,(R4);Ждем записи CRC
        BEQ  16$
        SOB  R1,9$    ;И так все сектора до конца дорожки

               *** Окончание записи дорожки ***

17$:    TSTB (R4)     ;Готовность есть?
        BPL  17$      ;Нет - ждем
        MOV  #47116,(R5);Запишем 4E4E
        TST  (R4)     ;Индекс есть?
        BPL  17$      ;Нет - продолжим запись до появления
18$:    TSTB (R4)     ;Готовность есть?
        BPL  18$      ;Нет - дождемся
        MOV  #47116,(R5);Запишем 4E4E
        TST  (R5)     ;Прекратим запись
        MTPS 52(R3)   ;Восстановим PSW
        SWAB 32(R3)   ;Вернем все на место
        JMP  EXIT     ;Выходим


              *** Конец текста драйвера НГМД ***

EXT:        *** Драйвер расширенной арифметики ***











--------------------
Живы будем - Не помрем !
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
 
Ответить в эту темуОткрыть новую тему
Ответов
SuperMax
сообщение 20.6.2022, 21:40
Сообщение #2


Администратор
*****

Группа: Root Admin
Сообщений: 6 286
Регистрация: 7.1.2006
Из: Красноярск
Пользователь №: 1



тоже но файлом

Прикрепленный файл  326v12.asm ( 110.89 килобайт ) Кол-во скачиваний: 233



--------------------
Живы будем - Не помрем !
Пользователь в офлайнеКарточка пользователяОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

Сообщений в этой теме


Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 25.4.2024, 16:27