Вход

Просмотр полной версии : Эмуляция 1801ВП1-128 в ПЛИС



Woland
29.11.2012, 01:39
В процессе решения обозначенной задачи обнаружили, что внутри ВП1-128 есть некий алгоритм определения готовности записи, о котором ничего не сказано в скудных доках на эту микросхему. Были предположения, что этот алгоритм содран с контроллера MX, но изучение его схемы не дало ответа на вопросы.
Алгоритм приблизительно ясен для форматирования (т.к. бит готовности выставляется строго одновременно с битом наличия индекса), но для записи есть только предположения, а хотелось бы конкретики. Может у кого-то есть какие-то данные от первоисточника?

UPDATE 14.10.2013: Благодаря уважаемым Vslav (http://zx.pk.ru/member.php?u=7624) и BarsMonster (http://zeptobars.ru/ru/) был вскрыт и документально воспроизведен кристалл БМК КР1801ВП1-128 (http://forum.pk-fpga.ru/viewtopic.php?f=43&t=5482).

К сожалению, пока это не помогло пролить свет на оставшуюся проблему в работе FPGA-аналога данного чипа (нечастые зависания при чтении), но будем надеяться, что скоро это уже случится.

UPDATE 01.11.2014: Итак, для любознательных прикладываю исходники прошивки cpld для SMK-512. ̶С̶к̶о̶р̶е̶е̶ ̶в̶с̶е̶г̶о̶ ̶о̶к̶о̶н̶ч̶а̶т̶е̶л̶ь̶н̶а̶ я̶ ̶в̶е̶р̶с̶и̶я̶.̶
68854
68853

UPDATE 23.04.2019: gid'ом реализована блокировка регистров 177130, 177132 в режиме 20 с целью получения работоспособности дискового Бейсика на БК-0010-01:
68852
68851

Patron
29.11.2012, 10:54
хотелось бы конкретикиМожно подключить один канал логического анализатора к сигналу готовности, а другие два к Index и Rdata - и узнать точный момент, когда ВП1-128 выдаёт готовность записи.

Woland
29.11.2012, 14:35
Можно подключить один канал логического анализатора к сигналу готовности, а другие два к Index и Rdata - и узнать точный момент, когда ВП1-128 выдаёт готовность записи.

так как же "точный момент" узнать, если готовность - это бит в слове состояния, и он как сигнал наружу не выходит ?
Но даже если считывать это слово, то для записи мы все равно ничего не поймем, т.к. готовность будет сразу как слово данных записалось.

Бит устанавливается в слове состояния по адресу 177130 (для БК), когда сдвиговый регистр опустел и готов к приему нового слова. Но данные в сдвиговый регистр пишутся не напрямую, а с буферного регистра данных, который пишется с шины, поэтому там "точные" моменты ловить абсолютно бесполезно при наличии такой двойной буферизации, тем более, что нужен не сам бит готовности, а тот сигнал, который разрешает установку готовности, а он никак сам по себе не доступен снаружи микросхемы.
Для эксперимента пока сделали, чтобы бит готовности ставился по факту опустения регистра, но так не хочет работать с дисководом IBM.
В спецификации ВП1-128 тоже написано, что по факту опустения регистра. Только регистру не дают опустошаться, пока диск не начнет вертеться, чего в доке нет в помине. Сейчас пытаемся как-то вычислись точный алгоритм определения микросхемой 1801ВП1-128 факта вращения мотора.

Patron
29.11.2012, 16:01
Только регистру не дают опустошаться, пока диск не начнет вертеться, чего в доке нет в помине. Сейчас пытаемся как-то вычислись точный алгоритм определения микросхемой 1801ВП1-128 факта вращения мотора.Насколько я понимаю - у ВП1-128 есть блок синхронизации, который непрерывно анализирует сигнал с диска. Нормальная скорость вращения детектируется по нормальному потоку синхроимпульсов. Сигнал маркера детектируется по пропуску синхроимпульсов в коде А1 (10100001).

Алгоритм работы ВП1-128 при записи (на мой взгляд) следующий:

1. Ожидание маркера.
2. Чтение байта.
3. Чтение CRC.
4. CRC Good ? Нет -> пункт 1. Да -> Байт == номер сектора.
5. Это нужный сектор ? Нет -> пункт 1.
6. Ожидание маркера.
7. Запись 512 байт.
8. Запись CRC.

Woland
29.11.2012, 16:18
Откуда же возьмется "нормальный поток синхроимпульсов", если например диск девственно чист и не форматирован ?

Patron
29.11.2012, 16:23
Откуда же возьмется "нормальный поток синхроимпульсов", если например диск девственно чист и не форматирован ?Если диск чист, сигнал индекса не анализируется и привод не имеет сигнала "готовность" - определить момент готовности записи невозможно.

Если привод имеет сигнал "готовность" - определить готовность записи можно только по этому сигналу.

Woland
29.11.2012, 16:46
При таком раскладе чистый диск никогда не начнет форматироваться, все будет ждать готовность для записи и так и не дождется.

Patron
29.11.2012, 17:01
При таком раскладе чистый диск никогда не начнет форматироваться, все будет ждать готовность для записи и так и не дождется.Значит, анализируется и синхросмесь, и индекс, а бит готовности устанавливается по ИЛИ этих двух признаков.
Тогда у неразмеченного диска сигнал готовности появится только после первого индекса, а у размеченного - сразу после синхронизации с сигналом RDATA.

.........

Я тоже собираюсь сэмулировать ВП1-128, поэтому у меня есть несколько вопросов:

1. Как часто ВП1-128 может писать маркер ( в каждом втором байте ? ).

2. В каком порядке пишутся байты слова ( сначала старший, потом младший ? ).

3. Формат регистра состояния:



Формат РС по записи :

------------------------------------------------------------
I15I14I13I12I11I 10I 9I 8I 7I 6I 5I 4I 3I 2I 1I 0I
------------------------------------------------------------
I**I**I**I**I**IRezIWm IGdrI StIDirI HsIMswIDs3IDs2IDs1IDs0I
------------------------------------------------------------

Значение разрядов РС :
0-й - выбор накопителя 0;
1-й - выбор накопителя 1;
2-й - выбор накопителя 2;
3-й - выбор накопителя 3;
4-й - включ. э.д.;
5-й - выбор поверхности;
6-й - направление перемещения;
7-й - шаг;
8-й - признак 'начало чтения';
9-й - признак 'запись маркера';
10-й - резервный;
Разряды 11-15 не используются.

Формат РС по чтению:

-------------------------------------------------------
I 15I 14I13I12I11I10I 9I 8I 7I 6I 5I 4I 3I 2I 1I 0I
-------------------------------------------------------
IIndICrcI**I**I**I**I**I**I TrI**I**I**I**IWprIRdyITr0I
-------------------------------------------------------

Значение разрядов РС :
0-й - признак '0-я дорожка';
1-й - признак 'накопитель готов к работе'(отсутствует
на 6022);
2-й - запрет записи;
7-й - признак 'готовность';
14-й - при чтении - признак 'прочлось без ошибок', при
записи - признак 'записывается контр. код на
диск';
15-й - индекс накопителя.
Разряды 3-6 и 8-13 не используются.


3.1. В каком бите читается маркер ?

3.2. Какой бит переключает, а какой запускает чтение/запись ?

Woland
29.11.2012, 18:23
Битов для переключения режима чтения-записи там нет, в отличие от контроллера MX. Там вообще никаких специальных битов вроде нет сверх того, что в официальной доке, просто происходит хитрая манипуляция тем, что есть.
Переход в режим записи происходит автоматом, когда пишутся данные в регистр 177132, когда не пишутся - записывает CRC и переходит в режим чтения, или если при записи считать регистр 177132, то выходит из режима записи без записи CRC.
Записывается сначала младший байт, потом старший. С битами - наоборот, сначала старший.

Patron
29.11.2012, 18:43
Там вообще никаких специальных битов вроде нет сверх того, что в официальной докеА как определить, что прочитан маркер?


Записывается сначала младший байт, потом старший.Из описания
В режиме 'запись' 7-й разряд РС (TR) устанавливается в единицу
после того, как младший байт РДЗ переписался в сдвиговый регистр.
можно заключить, что в сдвиговый регистр переписывается сначала старший байт, а потом младший - это ошибка описания ?

Woland
29.11.2012, 19:49
А как определить, что прочитан маркер?


Никак не определять. Когда маркер обнаруживается, начинается чтение тех данных, что идут следом, а по мере их чтения устанавливается бит готовности.
Вообще, значение маркера можно прочитать в регистра 177132, чтобы программа могла определить, какой именно из маркеров у нас тут появился (в программе WORK монитора это используется); но специальных битов в регистре состояния под это дело нет, только готовность.

С точки зрения содержимого - адресный маркер ничем не отличается от данных, а пропуск синхроимпульса используется внутри контроллера автоматически и никак не отражается регистре состояния.

Маркеры там идут дуплетами, сначала обязательный A1A1 с двумя пропущенными синхроимпульсами, затем A1FB, A1FE, A1F8, ... c одним пропуском синхроимпульса, которые уже маркируют тип сектора.


можно заключить, что в сдвиговый регистр переписывается сначала старший байт, а потом младший - это ошибка описания ?

Это все относительно сдвигового регистра, туда загружаются байты наоборот.

Конкретно в нашей эмуляции в схеме сдвиговый регистр сделан не так, как (вроде бы) он должен быть в ВП1-128. Он у нас 16-разрядный и из регистра данных все слова перегружаются сразу. В оригинале для целей экономии пересылка делается (вроде бы) по байту. На логику работы это никак не влияет.

Patron
29.11.2012, 20:51
Когда маркер обнаруживается, начинается чтение тех данных, что идут следомТ.е. если дорожка заполнена данными без маркеров - прочитать не удастся ни одного слова.. Это так?


Маркеры там идут дуплетами, сначала обязательный A1A1 с двумя пропущенными синхроимпульсами, затем A1FB, A1FE, A1F8, ... c одним пропуском синхроимпульса, которые уже маркируют тип сектора.А как при записи выбирается тип маркера - один там синхроимпульс пропустить или два ?

Woland
29.11.2012, 22:00
Если маркеров нет, дорожка не прочитается.
Тип маркера выбирается засылкой нужного значения в регистр данных при записи, перед этим выставляется бит "запись маркера",
синхроимпульс пропускается в байтах A1,
после того, как оба маркера записаны, бит "запись маркера" сбрасывается и далее на дорожку пишутся обычные данные.

Patron
29.11.2012, 22:21
Если маркеров нет, дорожка не прочитается.Т.е. читаются только слова между маркером и контрольной суммой, включая маркер и исключая контрольную сумму ?

Woland
30.11.2012, 14:05
Если нет маркера, то и начала чтения нет. Системе надо знать, где заканчиваются синхронизирующие импульсы и начинаются собственно данные, адресные маркеры служат именно для этого.

Patron
30.11.2012, 17:38
Если нет маркера, то и начала чтения нет.А когда маркер есть и чтение началось - то оно будет продолжаться до каких пор ?

И первым будет прочитано какое слово - слово с маркером ?

Woland
30.11.2012, 20:36
Первым будет прочитано слово с маркером A1A1. Продолжаться чтение будет бесконечно, пока программе не надоест.

Patron
01.12.2012, 01:53
Первым будет прочитано слово с маркером A1A1. Продолжаться чтение будет бесконечно, пока программе не надоест.Не встретив A1A1, но встретив другой маркер ( например, A1FB ) - чтение начнётся ?

А как ведёт себя бесконечное чтение, выходя из зоны синхронизации, например - после царапины. Если прочитано несколько бит младшего байта, потом сбой синхронизации - и опять идут биты? Как возможно дальнейшее чтение, если непонятно на какие позиции ставить получаемые биты ?

...

Что если на форматированный диск возможна только синхронная запись.. И именно поэтому сигнал готовности записи не устанавливается до достижения синхронизации. Ведь, когда импульсы RDATA приходят синхронно с работой сдвигового регистра - пропадание любого их количества не приводит к настоящему сбою синхронизации. Даже если из-за продольной царапины выпадает несколько секторов подряд - синхронизация не теряется и первый же удачно прочитанный (или записанный) бит точно занимает своё место.

Похоже, что даже если чистую дорожку прописать разметкой только на один сектор - любые последующие записи на такую дорожку будут идти синфазно с уже имеющимся форматом.

Patron
01.12.2012, 16:31
В приложении - исходник ПЗУ SMK64_v2.05 пригодный для редактирования в Windows и компиляции в эмуляторе ДВК.

После команд


MAC/LIST:SMK64 SMK64
LINK SMK64

создаётся файл листинга SMK64.LST и образ памяти SMK64.SAV, в котором коды ПЗУ занимают адреса 160000..167777.

...

Woland
06.01.2013, 15:26
Похоже в КР1801ВП1-128 есть еще одна недокументированная "особенность", которая выводит программные циклы из ожидания готовности. Там есть пара-тройка мест в мониторе БК, которые могут быть потенциально ловушками неприятностей на диске, скажем, ожидание адресного маркера. ПЛИС-эмулятор ВП1-128 сейчас виснет на таких местах в случае сбоев чтения.

Если предполагать, как ведет себя оригинальная ВП1-128 в такой ситуации, то может она выдает готовность просто скажем когда новый индекс пришел, а контрольная сумма потом разумеется не совпадает. В общем случае, если сумма не совпала, программа должна пойти на новый заход, пока не исчерпается какое-то число попыток. Также, может быть у ВП1-128 более слабая логика определения адресного маркера для экономии элементов микросхемы. В ПЛИС сейчас сделано определение очень жестко, как нарушение синхронизации плюс значение слова A1A1, это удобно для отладки, но может быть избыточно на практике. Есть варианты определения - просто по нарушению синхропотока, либо сравнению только одного байта с A1.

Patron
06.01.2013, 15:46
1. Если оригинал ВП1-128 может синхронизироваться с сигналом RDATA по любому синхробайту или одиночному A1, то он должен быть способен начинать бесконечное чтение на дорожке, отформатированной без использования маркеров A1A1. Надо написать специальную программу форматирования и проверить - будет ли оригинал ВП1-128 способен начать чтение при таком формате.

2. Появление сигнала INDEX в режиме синхронизации с дорожкой приводит к выходу из режима синхронизации. Т.к. синхронизацию и при записи, и при чтении осуществляет один и тот же блок ( который при записи выходит из режима синхронизации и по маркеру, и по индексу ) то разницы в алгоритме синхронизации с дорожкой при чтении и записи быть не должно.

Alex_K
06.01.2013, 17:13
По режиму поиска маркера в 1801ВП1-128. Сама микросхема имеет два режима чтения - режим поиска маркера и собственно режим чтения данных. В режим поиска маркера она входит после включения питания, по сигналу шины INIT, а также по сбросу из единицы в ноль бита 8 в регистре 177130. Собственно в MFM нужно решить две проблемы - определить начало двоичного бита и определить начало байта. Первая проблема решается после исчезновения сигнала сброса. Если читается MFM-бит "1", то считается, что начинается двоичный бит. Недаром перед маркерами всегда записывается синхрозона из 12 байтов "0". После того, как контроллер посчитал, что начало бита схвачено правильно, то формируется поток двоичных битов и он начинает входить в сдвиговый регистр. Сразу отмечу, что ничего в данном случае в регистр данных не копируется и бит готовности (бит 7) в регистре 177130 не устанавливается. Если же был замечен синхросбой (т.е. бит "0" закодирован как "00", а не как "10") и в сдвиговом регистре оказалось 0xA1, то тогда считается, что определили и границу байта. Он сразу же копируется в регистр данных, затем прочитывается очередной байт, также копируется в регистр данных, и уже после прочтения двух байтов устанавливается признак готовности в регистре 177130. Далее микросхема работает уже в режиме чтения данных, она в этом случае аккуратно нарезает байты в сдвиговом регистре каждые 32 мкс. Если остановить двигатель или вынуть дискету, то будут формироваться нулевые байты, но будут формироваться аккуратно каждые 32 мкс.
Сигнал INDEX для синхронизации и чтения абсолютно не используется. Он нужен программе форматирования только для определения начала дорожки, а также для определения того, что вставлена дискета или нет (сигнал должен появляться в этом случае периодически на заданное время).

Patron
06.01.2013, 17:24
Дело в том, что (как предполагается) оригинал 1801ВП1-128 может выходить из режима поиска маркера и когда находит его, и когда не находит. Копия же ВП1-128 (насколько я понял) всегда ищет маркер "до упора" и не выходит из поиска до его обнаружения, а подпрограммы ПЗУ БК при работе с ней ( из за этого ? ) регулярно зависают, тогда как при работе с оригиналом такого никогда не происходит.

Alex_K
06.01.2013, 18:12
Дело в том, что (как предполагается) оригинал 1801ВП1-128 может выходить из режима поиска маркера и когда находит его, и когда не находит. Копия же ВП1-128 (насколько я понял) всегда ищет маркер "до упора" и не выходит из поиска до его обнаружения, а подпрограммы ПЗУ БК при работе с ней ( из за этого ? ) регулярно зависают, тогда как при работе с оригиналом такого никогда не происходит.

1801ВП1-128 не выходит из режима поиска маркера до тех пор, пока она его не найдет.

Patron
06.01.2013, 18:41
1801ВП1-128 не выходит из режима поиска маркера до тех пор, пока она его не найдет.А в режиме поиска маркера ВП1-128 только 0xA1 ищет или любой байт с пропуском синхробита ?

Alex_K
06.01.2013, 18:50
А в режиме поиска маркера ВП1-128 только 0xA1 ищет или любой байт с пропуском синхробита ?
Только 0xA1.

Patron
06.01.2013, 19:00
Только 0xA1.Т.е. ВП1-128 позволяет записать любой байт с пропуском синхробита, но опознать пропуск снихробита может только в байте 0xA1.

Или при установке признака 'запись маркера' - ВП1-128 не всякий байт с пропуском синхробита запишет ?

Alex_K
06.01.2013, 19:14
Т.е. ВП1-128 позволяет записать любой байт с пропуском синхробита, но опознать пропуск снихробита может только в байте 0xA1.

Или при установке признака 'запись маркера' - ВП1-128 не всякий байт с пропуском синхробита запишет ?
Опознать только 0xA1, а вот записать возможно может и любой, это мне никак не узнать. Во всяком случае в прошивке 1801РЕ2-255 есть функция форматирования в формате IBM, так там пишуться байты 0xC1 при записи маркера дорожки, и пишуться с пропуском синхроимпульса. Но маркеры дорожки 1801ВП1-128 не опознаются, поэтому на УКНЦ и такие проблемы при чтении первого сектора на дорожке, если дискета отформатирована в формате IBM, а не ISO. В ту же прошивку -255 внесли изменения для чтения IBM-овских дискет, а вот -091 имела те же проблемы.

Woland
07.01.2013, 00:19
1801ВП1-128 не выходит из режима поиска маркера до тех пор, пока она его не найдет.

Каким же тогда образом удается избежать попадания процессора в бесконечный цикл ожидания, в случае, если на дорожке будут некачественные данные?

Alex_K
07.01.2013, 00:32
Каким же тогда образом удается избежать попадания процессора в бесконечный цикл ожидания, в случае, если на дорожке будут некачественные данные?
Если дискета отформатирована, то в конце концов на какой-нибудь маркер и наткнетесь, их же на дорожке целых двадцать штук - на каждый сектор по маркеру заголовка и маркеру данных. А если не удалось сцепиться при этом обороте диска, то сцепится на следующем. Главное чтобы начало маркера соответствовало тому MFM-биту с которым сцепился контроллер.

Patron
07.01.2013, 00:49
Тестирование рулит - можно "вручную" отформатировать дорожку абсолютно как угодно и выяснить - выйдет ли сам 1801ВП1-128 из режима поиска маркера или нет.

Alex_K
07.01.2013, 01:01
Тестирование рулит - можно "вручную" отформатировать дорожку абсолютно как угодно и выяснить - выйдет ли сам 1801ВП1-128 из режима поиска маркера или нет.

Это уже проходили с tnt23. У него есть своя разработка - эмулятор флоппи. Делал он его для Amiga, но вот потом решил испытать для УКНЦ. До этого его испытавал также Сергей Вакуленко с БК. Так вот с 1801ВП1-128 эмулятор не очень хорошо работал. Разбирались с tnt23 долго, но разобрались. Все оказалось просто - в эмуляторе дискета идеальная в прямом смысле этого слова, все байты четко выровнены, поэтому все байты начинались на четном MFM-бите, а если 1801ВП1-128 цеплялся после сброса за нечетный MFM-бит, то соответственно маркер 0xA1 никогда в сдвиговом регистре и не оказывался. Ситуация могла меняться когда осуществлялся переход на другую дорожку и останавливался запускался двигатель. Выход был простой - добавление в дорожку MFM-битов "010", т.е. полтора бита данных. В итоге при неправильной первоначальной сцепке при следующем обороте происходил сдвиг на один MFM-бит и уже маркер нормально находился. С УКНЦ после нормально работало.

Patron
07.01.2013, 01:11
Выход был простой - добавление в дорожку MFM-битов "010", т.е. полтора бита данных.Но при этом ещё, наверное, на дорожке остаётся и "пустое" место, совсем без установленных битов.

Известно, что
Если остановить двигатель или вынуть дискету, то будут формироваться нулевые байты, но будут формироваться аккуратно каждые 32 мксКак же тогда записанные биты влияют на синхронизацию, если контроллеру без разницы - есть на дорожке биты или нет и режим синхронизации сохраняется даже на пустых местах..

Alex_K
07.01.2013, 01:17
Но при этом ещё, наверное, на дорожке остаётся и "пустое" место, совсем без установленных битов.
Вообще-то и на УКНЦ, и на БК, и на ДВК с MY дорожка форматируется от индекса до индекса. Тут в отличии от MX, надо форматировать, т.к. запись может осуществляться в любой сектор, не надо писать целиком дорожку.


Известно, что Как же тогда записанные биты влияют на синхронизацию, если контроллеру без разницы - есть на дорожке биты или нет и режим синхронизации сохраняется даже на пустых местах..
А это не FM, а MFM, тут такой синхронизации, как в FM нету. Бит "1" представляется как "01", бит "0" после "1" как "00", а бит "0" после "0" как "10". А так называемый сбой синхронизации в маркере - это представление бита "0" после "0" не как "10", а "00" (как после "1").

Patron
07.01.2013, 01:20
Но всё же, если контроллер считает, что синхронизация достигнута и "нарезает" по байту каждые 32 мкс, а дорожка отформатирована от индекса до индекса и биты круг-за-кругом идут непрерывно - то как какие-то "специальные" полтора бита данных могут что-то изменить ?

Alex_K
07.01.2013, 01:33
Но всё же, если контроллер считает, что синхронизация достигнута и "нарезает" по байту каждые 32 мкс, а дорожка отформатирована от индекса до индекса и биты круг-за-кругом идут непрерывно - то как какие-то "специальные" полтора бита данных могут что-то изменить ?
Patron, сперва Вам надо прочесть какую-то литературку по MFM. Вопрос объемистый, и все описывать мне нету времени. Сам бит данных состоит из двух битов MFM, если происходит сдвиг на один MFM-бит, то уже и данные будут формироваться другие. Простой пример - идет последовательность MFM-битов - ...010101010101010101... Если начинать с единичного бита, то будут читать биты данных "0", а если с нулевого бита - то будут читаться биты данных "1". Вот поэтому в MFM так важно правильно сцепится с заданным битом. Поэтому перед маркерами и записывают специально 12 нулевых байт. В зависимости от того в каком режиме находится контроллер, он эти байты может прочитывать как 0x00 или как 0xFF. Поэтому в программах управления 1801ВП1-128 всегда перед поиском маркера ищут последовательность слов 0000000 или 0177777, но это в том случае, если контроллер находится в режиме чтения данных. А при реальной записи сдвиги будут. Если на свежеформатированной дорожке Вы после индекса поймаете маркер первого сектора, то всю дорожку можно прочесть идеально до индексного отверстия вместе с оставшимися маркерами, контрольными кодами и межсекторными промежутками. Но если в какой-то сектор сделали запись (например в третий), то идеально считается только по адресный маркер третьего сектора, а далее читаться будет, но будет полная каша.

Patron
07.01.2013, 01:43
Я код MFM довольно хорошо представляю, поэтому и не вполне понятно про "полтора бита". Ведь тогда получается, что для 1801ВП1-128 есть какая-то разница хотя бы между форматированными и неформатироваными участками дорожки, не говоря уже о случаях, когда вся дорожка отформатирована от индекса до индекса. Тогда-то куда это "полтора бита" добавлять..

Alex_K
07.01.2013, 01:50
Тогда-то куда это "полтора бита" добавлять..
Добавлялось в образ формируемый эмулятором флоппи.

Patron
07.01.2013, 02:02
Добавлялось в образ формируемый эмулятором флоппи.У которого (понятное дело) в конце дорожки эмулировался "неформатированный" участок.

А это означает, что в режиме поиска маркера сдвиговый регистр 1801ВП1-128 на пустых местах останавливается.

Alex_K
07.01.2013, 02:06
У которого (понятное дело) в конце дорожки эмулировался "неформатированный" участок.

А это означает, что в режиме поиска маркера сдвиговый регистр 1801ВП1-128 на пустых местах останавливается.
Нет не останавливается, биты аккуратно формируются каждые 4 мкс, ведь на микросхему поступает 4 МГц, когда сказали к какому биту цепляться, каждые 2 мкс выцепляется по MFM-биту и из двух MFM-бит формируется бит данных, который поступает в сдвиговый регистр.

Patron
07.01.2013, 02:11
А разве в режиме поиска меркера ( до его обнаружения ) биты данных формируются? Что-то не верится. Весь смысл добавления "полутора битов" именно в том, что когда идёт поиск маркера - сдвиговый регистр двигается не тактовой частототой, а "битовой" частотой с дорожки. Иначе пустое место будет точно таким же источником битов, как и пресловутые "полтора бита" и они уже ничего изменить не смогут.

Alex_K
07.01.2013, 02:14
Пресловутые три MFM-бита делают сдвиг для другого формирования данных.
А в режиме поиска маркера биты данных также формируются и поступают в сдвиговый регистр, но не в регистр данных. Иначе как произойдет сравнение с маркером 0xA1.

Patron
07.01.2013, 02:23
А в режиме поиска маркера биты данных также формируются и поступают в сдвиговый регистрНо если бы пустое место формировало биты, точно так же влияющие на работу сдвигового регистра, как и пресловутые "полтора бита" - то их добавление ничего не могло бы дать.

В том и дело, что раз добавление плутора битов на "пустое место" изменяет фазу сдвигового регистра - значит пустое место иначе влияет на работу сдвигового регистра в режиме поиска маркера, чем "не пустое".

Alex_K
07.01.2013, 02:26
У 1801ВП1-128 нету понятия пустого места, раз запустилось чтение, то оно нарезает биты данных в соответствии с временным интервалом. И что Вы подразумеваете под пустым местом - приведите конкретный пример.

Patron
07.01.2013, 02:29
Или имелось в виду изменение "битовой длины" дорожки и добавление этих самые "полутора битов" имело вид простого удлинения интервала времени от индекса до индекса.. Что-то не верится.

---------- Post added at 01:29 ---------- Previous post was at 01:28 ----------


У 1801ВП1-128 нету понятия пустого места, раз запустилось чтениеТ.е. в режиме поиска маркера чтение уже идёт ?

Alex_K
07.01.2013, 02:38
Или имелось в виду изменение "битовой длины" дорожки и добавление этих самые "полутора битов" имело вид простого удлинения пустого промежутка от маркера до маркера.. Что-то не верится.

---------- Post added at 01:29 ---------- Previous post was at 01:28 ----------

Т.е. в режиме поиска маркера чтение уже идёт ?

Ох, Patron, все-таки прочитайте литературу по MFM. Я уже вроде несколько раз акцентировал на том, что на каком MFM-бите произойдет сцепка, то так и будут формироваться данные. Пример - вся дорожка аккуратно заполнена MFM-битами ...010101010101010101.. Число MFM-битов в идеальной дорожке четно, поэтому если сцепка произошла с MFM-битом "1", то будут все время формироваться биты данных "0", что соответствует MFM-последовательности "10". Если дорожку дополнить MFM-битами "010", то число MFM-битов станет нечетным, и при одном обороте будут формироваться биты данных "0", а при следующем уже биты данных "1".

В режиме поиска маркера идет чтение потока битов данных (не MFM) в сдвиговый регистр, но сдвиговый регистр не копируется в регистр данных, т.к. начало байта еще не определено.

Patron
07.01.2013, 02:41
Похоже, что я понял про "полтора бита".
Идея в том, что если битовая длина дорожки ( в смысле длительности, а не в смысле "содержания" ) не кратна биту - у контроллера нет шанса "зависнуть" на неправильной фазе синхронизации.

Alex_K
07.01.2013, 02:47
Похоже, что я понял про "полтора бита".
Идея в том, что если битовая длина дорожки ( в смысле длительности, а не в смысле "содержания" ) не кратна биту - у контроллера нет шанса "зависнуть" на неправильной фазе синхронизации.

Да, если не удалось на этом обороте диска, то получиться на следующем. Но такая проблема возникла только на эмуляторе флоппи после того, как MFM-образ был сформирован из DSK-файла. На реальной дискете все проще -длина дорожки не идеальная, не кратная по MFM-битам. К тому же после записи данных в сектора маркеры данных уже расположены не идеально по дорожке, поэтому какой-нибудь маркер и поймается по пути. А после поимки маркера уже проще - контроллер переходит в режим формирования данных и сигнал готовности появляется каждые 64 мкс. Далее все уже зависит от качества программы чтения данных.

Patron
07.01.2013, 04:07
Есть ещё один интересный аспект - потребная глубина фазовой авто-подстройки частоты ( ФАПЧ ) сдвигового регистра.
ГОСТ допускает отклонение скорости диска +-1.5%, из чего можно заключить, что:

1. Разница между скоростью записи и скоростью чтения может составлять до 3%.
2. Прочитать в таком случае без фазовой авто-подстройки частоты сдвигового регистра можно не больше 30 битов подряд.
3. "Пустое место" на диске - это такое место, где ФАПЧ приёмника не работает, т.к. отсутствует "несущая".

Интересно также:

1. В каких пределах отклонений скорости записи и чтения сохраняет работоспособность 1801ВП1-128.
2. В каких пределах отклонений скорости записи и чтения сохраняет работоспособность его копия.

...

Alex_K
07.01.2013, 14:05
1. В каких пределах отклонений скорости записи и чтения сохраняет работоспособность 1801ВП1-128.

В довольно больших пределах. Я готовил дискету на PC на дисководе 1,2 Мб. Потом считывал ее на УКНЦ, на МС-5313, на нем мотор работал медленнее, и все нормально читалось. В 1801ВП1-128 при сцепке бита в нулевой зоне перед маркером осуществляется также и подстройка под скорость диска, т.к. в нулевой зоне следуют чередующиеся MFM-биты "1" и "0".

И еще - как такового пустого места на диске нет. При форматировании дорожки она обычно сначала заполняется байтами 0x4E, а потом с начала индекса идет уже запись секторов. Но после окончания записи последнего сектора обычно также до индекса идет заполнение байтами 0x4E. В принципе это видно в любой программе форматирования, можно посмотреть как под УКНЦ, и прошивку 1801РЕ2-255, есть исходники с комментариями.

Patron
07.01.2013, 14:51
В довольно больших пределах.Этот аспект слабо отражён в справочной литературе по контроллерам. Относительно механизма реализации - я вообще ничего не видел.


как такового пустого места на диске нетНа обычном реальном диске.

Когда речь идёт о максимально точном воспроизведении всех аспектов работы оригинального контроллера - интерес представляет и то, как он работает на "неполных" дорожках.

Alex_K
07.01.2013, 14:55
Этот аспект слабо отражён в справочной литературе по контроллерам. Относительно механизма реализации - я вообще ничего не видел.
И вряд ли где увидете. А 1801ВП1-128 по всей видимости так и останется "черным ящиком".


Когда речь идёт о максимально точном воспроизведении всех аспектов работы оригинального контроллера - интерес представляет и то, как он работает на "неполных" дорожках.
Ну неполных дорожек не бывает. А про этот аспект я уже описывал. Если контроллер вошел в режим чтения данных, т.е. аккуратно формирует слово каждые 64 мкс, и если при этом пропал сигнал (вынули дискету, остановили мотор и т.д. и т.п.), то будут аккуратно формироваться ноли каждые 64 мкс.

Patron
07.01.2013, 15:20
Если контроллер вошел в режим чтения данных, т.е. аккуратно формирует слово каждые 64 мкс, и если при этом пропал сигнал (вынули дискету, остановили мотор и т.д. и т.п.), то будут аккуратно формироваться ноли каждые 64 мкс.Тонкость тут в том, что если скорость чтения отличается от скорости записи (а это в общем случае всегда так) - то на тех местах, где разметка есть - контроллер будет формировать новые слова данных отнюдь не каждые 64 мкс, а с той скоростью, с которой получает их с дорожки, тогда как на тех местах, где разметки нет - скорость формирования слов данных будет "правильной".

Alex_K
07.01.2013, 15:26
Тонкость тут в том, что если скорость чтения отличается от скорости записи (а это в общем случае всегда так) - то на тех местах, где разметка есть - контроллер будет формировать новые слова данных отнюдь не каждые 64 мкс, а с той скоростью, с которой получает их с дорожки, тогда как на тех местах, где разметки нет - скорость формирования слов данных будет "правильной".

Patron, я упоминал о подстройке по нулевой синхрозоне. Она служит не только для того, чтобы правильно произвести сцепку для определения двоичного бита, но и подстроится под скорость вращения и передачи данных. Во всяком случае я когда экспериментировал с 1801ВП1-128, хватал первый адресный маркер после индекса, и после этого успешно считывал всю дорожку (естественно дорожка должна быть свежеотформатирована и на нее после этого не производилось записи).

Patron
07.01.2013, 15:34
Точно! Блок синхронизации у 1801ВП1-128 срабатывает только один раз в начале чтения, поэтому после выхода на неразмеченную зону - слова данных будут формироваться с той скоростью, которая была определена на этапе синхронизации.

Из-за того, что синхронизация у 1801ВП1-128 выполняется только один раз - он и зависает ( в "идеальных" условиях ) в режиме поиска маркера при ошибке битовой синхронизации.

Alex_K
07.01.2013, 15:48
Из-за того, что синхронизация у 1801ВП1-128 выполняется только один раз - он и зависает ( в "идеальных" условиях ) в режиме поиска маркера при ошибке битовой синхронизации.

В идеальных условиях он зависал не из-за этого. Т.к. при сбое нулевая зона может читаться как 0x00, так и 0xFF, то в данном случае программа чтения данных при поиске маркера может ошибится и дать команду не на синхрозоне, а на зоне данных, там где записаны байты 0xFF. Соответственно после сцепки контроллер их воспринимает как 0x00, а т.к. диск в эмуляторе был идеальным, то произошло смещение на один MFM-бит (полбита данных), уже после этого ни один маркер не найдется.

Patron
07.01.2013, 15:53
Ещё один аспект работы 1801ВП1-128, который мне не вполне понятен - где пропускается, а где не пропускается синхробит при записи слова данных с установленным флагом 'запись маркера'..

Alex_K
07.01.2013, 16:14
Ещё один аспект работы 1801ВП1-128, который мне не вполне понятен - где пропускается, а где не пропускается синхробит при записи слова данных с установленным флагом 'запись маркера'..

Сразу скажу, что в MFM, в отличие от FM, как таковых синхробитов нет. Просто при записи маркера 0xA1 шестой слева бит записывается не как "10", а как "00". Т.е. байт 0xA1 (10100001) в режиме записи обычных данных записывается как "0100010010101001", а в режиме маркера как "0100010010001001". Вот по этой записи нуля и различают маркер, соответственно в 1801ВП1-128 еще в сдвиговом регистре должно оказаться 0xA1. Предполагаю, что в 1801ВП1-128 фиксация этого события сделана на 8 бит данных, т.к. если за 8 вдвигов битов данных в сдвиговый регистр не оказалось 0xA1, то признак должен сброситься.

Patron
07.01.2013, 16:40
Предполагаю, что в 1801ВП1-128 фиксация этого события сделана на 8 бит данных, т.к. если за 8 вдвигов битов данных в сдвиговый регистр не оказалось 0xA1, то признак должен сброситься.Т.е. записать при помощи 1801ВП1-128 можно только маркер 0xA1 и только в младшем байте передаваемого слова. Байт 0xA1 в старшем байте слова будет записан как обычный байт данных.

А вот это (полагаю) очень важно в плане адекватности копирования 1801ВП1-128 - и это вполне можно протестировать !


Маркеры там идут дуплетами, сначала обязательный A1A1 с двумя пропущенными синхроимпульсамиЭто показал логический анализатор в сигнале RDATA ?


Опознать только 0xA1, а вот записать возможно может и любой, это мне никак не узнать. Во всяком случае в прошивке 1801РЕ2-255 есть функция форматирования в формате IBM, так там пишуться байты 0xC1 при записи маркера дорожки, и пишуться с пропуском синхроимпульса.Но 0xC1 - это не 0xA1.

Значит, не только 0xA1 может писаться с пропуском синхроимпульса?

Alex_K
07.01.2013, 16:50
Т.е. записать при помощи 1801ВП1-128 можно только маркер 0xA1 и только в младшем байте передаваемого слова. Байт 0xA1 в старшем байте слова будет записан как обычный байт данных.


Я говорил не про запись, а про чтение при поиске маркера. Т.к. если при чтении признак не сбросится за 8 попыток задвига бита данных, то можно по ошибке и байт данных 0xA1 принять за маркерный.

---------- Post added at 16:50 ---------- Previous post was at 16:47 ----------


Но 0xC1 - это не 0xA1.

Значит, не только 0xA1 может писаться с пропуском синхроимпульса?
Полагаю, что да. При записи врядли схема следит за тем, что записывают. Если стоит признак записи маркера, то просто при записи очередного байта третий подряд нулевой бит запишется не как "10", а как "00".
Только вот поиск маркера идет именно по 0xA1.

Patron
07.01.2013, 17:02
Полагаю, что да. При записи врядли схема следит за тем, что записывают. Если стоит признак записи маркера, то просто при записи очередного байта третий подряд нулевой бит запишется не как "10", а как "00".Вот это разработчики копии 1801ВП1-128 вполне могли бы протестировать.

Сделать программу, которая будет писать на дорожку парами все значения байтов подряд с установленным признаком 'запись маркера', а потом прицепить к RDATA логический анализатор и узнать правильный ответ.

Alex_K
07.01.2013, 17:04
Вот это разработчики копии 1801ВП1-128 вполне могли бы протестировать.

Сделать программу, которая будет писать на дорожку парами все значения байтов подряд с установленным признаком 'запись маркера', а потом прицепить к RDATA логический анализатор и узнать правильный ответ.
Вряд ли это они будут делать, сложно и муторно. Да и зачем надо? Известно, что при поиске маркера ищется 0xA1 с записью "0" как "00", а не "10". А для записи остальных данных это роли не играет, тем более они не ищутся при поиске маркера.

Patron
07.01.2013, 17:12
Да и зачем надо?Если копия будет пропускать синхроимпульс только у байтов 0xA1 - функция форматирования в формате IBM, где в качестве маркеров пишуться байты 0xC1 - на копии будет работать не так, как на оригинале.

Зачем делать менее точную копию, если можно сделать более точную..

...

А как при помощи 1801ВП1-128 пропустить синхроимпульс при записи только в одном байте, а не в двух подряд ?

Alex_K
07.01.2013, 17:22
Если копия будет пропускать синхроимпульс только у байтов 0xA1 - функция форматирования в формате IBM, где в качестве маркеров пишуться байты 0xC1 - на копии будет работать не так, как на оригинале.

Зачем делать менее точную копию, если можно сделать более точную..
Ну эти байты 0xC1 не используются и на PC при чтении, видно какая-то совместимость с древних времен, а по международному стандарту ISO маркеров начала дорожки (0XC1) не используется.


А как при помощи 1801ВП1-128 пропустить синхроимпульс при записи только в одном байте, а не в двух подряд ?
А вот это вряд ли. Сам бит записи маркера устанавливается перед записью в регистр данных, потом данные пишутся в регистр данных. И уже когда данные попадают в сдвиговый регистр, то записываются с учетом установленного бита маркера. Но записываются с учетом текущей установки, или при копировании в сдвиговый регистр бит маркера может также копируется в отдельный триггер, это мне не известно. А так в программах записи он устанавливается при записи всех четырех байтов маркера. Ну первые три байта это всегда 0xA1, а последние могут быть 0xFA, 0xFB и т.д., там уже нет третьего подряд нулевого бита в потоке данных.

Patron
07.01.2013, 17:32
в программах записи он устанавливается при записи всех четырех байтов маркера. Ну первые три байта это всегда 0xA1, а последние могут быть 0xFA, 0xFB и т.д., там уже нет третьего подряд нулевого бита в потоке данных.Т.е. при записи слова 0xA1A1 - оба байта пишутся с пропущенными импульсами, а при записи слова 0xFAA1 - только младший байт 0xA1.

Получается, что у 1801ВП1-128 есть "секретная таблица маркеров", где записаны байты, при попадании которых в сдвиговый регистр в режиме записи маркера - у тех стирается нужный синхроимпульс.

На сегодня мы знаем два значения из этой таблицы - 0xA1 и 0xC1

Интересно было бы узнать весь список.

Alex_K
07.01.2013, 17:48
Т.е. при записи слова 0xA1A1 - оба байта пишутся с пропущенными импульсами, а при записи слова 0xFAA1 - только младший байт 0xA1.

Получается, что у 1801ВП1-128 есть "секретная таблица маркеров", где записаны байты, при попадании которых в сдвиговый регистр в режиме записи маркера - у тех стирается нужный синхроимпульс.

На сегодня мы знаем два значения из этой таблицы - 0xA1 и 0xC1

Интересно было бы узнать весь список.
Да нету никакого списка - пишется вроде только шестой нулевой бит. Маркер индекса к тому же не 0xC1, а 0xC2. Вот информация (http://vak.ru/doku.php/proj/megadrive/mfm).

Patron
07.01.2013, 17:53
Да нету никакого спискаНо как тогда "специальные" байты 0xA1 и 0xC2 отличаются в сдвиговом регистре от всех остальных ( у которых не формируется пропуск синхроимпульса при записи в режиме 'запись маркера' ).

Alex_K
07.01.2013, 17:58
Но как тогда "специальные" байты 0xA1 и 0xC2 отличаются в сдвиговом регистре от всех остальных ( у которых не формируется пропуск синхроимпульса при записи в режиме 'запись маркера' ).

Если пятый и шестой биты слева нулевые, то шестой бит при записи маркера кодируется не как бит "0" после "0", а как бит "0" после "1".

Patron
07.01.2013, 18:07
Если пятый и шестой биты слева нулевые, то шестой бит при записи маркера кодируется не как бит "0" после "0", а как бит "0" после "1".Тогда 1801ВП1-128 должен писать следующие маркеры:



00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43 50 51 52 53
60 61 62 63 70 71 72 73 80 81 82 83 90 91 92 93 A0 A1 A2 A3 B0 B1 B2 B3
C0 C1 C2 C3 D0 D1 D2 D3 E0 E1 E2 E3 F0 F1 F2 F3
Внушительный список !

Есть смысл это проверить при помощи логического анализатора ( можно даже на выводе WDATA контроллера во время записи ).

Alex_K
07.01.2013, 18:21
Внушительный список !

Есть смысл это проверить при помощи логического анализатора ( можно даже на выводе WDATA контроллера во время записи ).

Нету смысла проверять никакого. Реально используется только 0xA1, маркер 0xC2 используется только при форматировании дорожки в формате IBM, эта функция недокументирована, она появилась только в прошивке -092, в -091 ее не было.

Vslav
14.10.2013, 15:32
Предлагаю немного освежить тему - Цифровая археология 1801: неудержимое диско 128 (http://forum.pk-fpga.ru/viewtopic.php?f=43&t=5482)

Кстати, Alex_K, спасибо Вам за посты в этой теме - они мне очень помогли при реверсе, и очень много из сказанного Вами подтвердилось полностью.

Patron
15.10.2013, 12:14
Предлагаю немного освежить темуОчень кстати - я как раз почти созрел написать эмулятор ВП1-128, который будет работать с байтовыми образами дорожек ( в текстовом формате *.TRK ).

Patron
13.12.2013, 01:28
В описании ВП1-128 написано, что CRC вычисляется по формуле: 1 + x^5 + x^12 + x^16.
Но по такой формуле работают несколько разных алгоритмов CRC-16, дающих разные результаты, например:



KERMIT ( CCITT )
width=16 poly=0x1021 init=0x0000 refin=true refout=true
xorout=0x0000 check=0x2189

XMODEM
width=16 poly=0x1021 init=0x0000 refin=false refout=false
xorout=0x0000 check=0x31C3

CRC-16
width=16 poly=0x1021 init=0xFFFF refin=false refout=false
xorout=0x0000 check=0x29B1

X-25
width=16 poly=0x1021 init=0xFFFF refin=true refout=true
xorout=0xFFFF check=0x906E

Есть ли возможность уточнить, какой именно алгоритм у генератора CRC ВП1-128 ?

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

Titus
13.12.2013, 02:03
Есть ли возможность уточнить, какой именно алгоритм у генератора CRC ВП1-128 ?

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

По идее, стандартный CRC-16, иначе он не был бы совместим со стандартным форматом MFM.

Vslav
13.12.2013, 03:26
В описании ВП1-128 написано, что CRC вычисляется по формуле: 1 + x^5 + x^12 + x^16.
Но по такой формуле работают несколько разных алгоритмов CRC-16, дающих разные результаты, например:
Есть ли возможность уточнить, какой именно алгоритм у генератора CRC ВП1-128 ?


Update:
Я тут начал моделировать запись сектора, выявил еще один косяк ВП1-128, она оказывается бит готовности данных ставит сильно заранее (до момента перенесения старшего байта из регистра данных в сдвиговый регистр), и если быстрая шина МПИ (как в используемой сейчас модели процессора - он пишет-читает максимально быстро), то она успевает переписать регистр данных быстрее чем из него успевает переписаться старший байт в сдвиговый регистр (потому что увидела раннюю готовность). Сейчас ввел в транзакции МПИ задержки, будут результаты - отпишу.

Patron
13.12.2013, 14:27
Инициализация регистра перед началом вычисления суммы производится нулем. Запись вычисленной суммы на диск выполняется в инвертированном виде (значит при чтении она будет считана также проинвертированной). Корректность прочитанного блока + инвертированная сумма определяется по равенству регистра значению 0xFFFF.Контроллеры DEC и IBM ( если верить документации ) вычисляют CRC так:

1. Начальное значение CRC = 0xFFFF ;
2. Старший бит идёт первым ;
3. Запись вычисленной суммы без инверсии.

Т.е. по сути - это одно и то же, только инверсия результата выполняется до начала вычисления CRC, а не после.

...

Вычисление CRC начинается в момент записи маркера, поэтому возникают два вопроса:

1. Что именно запускает генератор CRC при записи:

1.1. Установка бита WM (9) ;
1.2. То же + байт 0xA1 в сдвиговом регистре.

2. Если генератор CRC в ходе записи не был запущен - будет ли выполнена запись CRC ( 0xFFFF ) в момент пропуска требования ?

---------- Post added at 13:08 ---------- Previous post was at 12:16 ----------


алгоритм уже завтра на свежую голову восстановлюПохоже, что алгоритм такой. Байтовый вариант выглядит так:


unsigned short crc16( unsigned char byte, int step )
{
static unsigned short crc = 0;
if( step == 0 ) { crc = 0; }
crc ^= unsigned short ( byte ) << 8;
for( int i = 0 ; i < 8 ; i++ ) {
if( crc & 0x8000 )
crc = (crc << 1) ^ 0x1021;
else
crc = crc << 1;
}
return crc;
}


---------- Post added at 13:27 ---------- Previous post was at 13:08 ----------

Также ( если я правильно понял ) при чтении CRC проверяется так - если требование выполнено, то содержимое регистра данных интерпретируется как данные и включается в расчёт CRC, если же требование не выполнено - содержимое регистра данных интерпретируется как инверсное значение CRC, прибавляется к рассчитанному значению CRC и результат проверяется на равенство 0xFFFF.

Но тогда получается, что если продолжать забирать данные из регистра данных - инверсное значение CRC будет прочитано как обычные данные и чтение пойдёт дальше.

А что в таком случае произойдёт при считывании маркера:

1. Чтение продолжится, но произойдёт сброс генератора CRC и расчёт CRC начнётся заново со считанного байта 0xA1 ;
2. Произойдёт что-то ещё..

Vslav
13.12.2013, 14:31
Вычисление CRC начинается в момент записи маркера, поэтому возникают два вопроса:

1. Что именно запускает генератор CRC при записи:

1.1. Установка бита WM (9) ;
1.2. То же + байт 0xA1 в сдвиговом регистре.

Установка бита WM игнорируется, достаточно обнаружения 0xA1 в сдвиговом регистре.
Я сейчас выполил такое моделирование:


qbus_write(16'O177130, 16'O000000);
qbus_write(16'O177132, 16'H0000);
qbus_waitr();
qbus_write(16'O177132, 16'H0000);
qbus_waitr();
qbus_write(16'O177132, 16'HA1A1);
qbus_waitr();
qbus_write(16'O177132, 16'H3130);
qbus_waitr();
qbus_write(16'O177132, 16'H3332);
qbus_waitr();


На выходе записываемых данных получилось:

0x00
0x00
0x00
0x00
0xA1 (в этот момент обнулился регистр CRC и началось вычисление с этого маркера, еще я пробовал писать снова 0xA1A1 но сброса боьлше не было - это однократный процесс после перехода от чтения к записи)
0xA1
0x30 (то есть, сначала МЛАДШИЙ байт, старший бит первым)
0x31 (то есть, потом СТАРШИЙ байт, старший бит первым)
0x32
0x33 (после этого байта содержимое регистра CRC = 0x6EE9)
0x91 (инвертированное 0x6E. Сначала пишется СТАРШИЙ байт инвертированной суммы)
0x16 (инвертированное 0xE9. Потом пишется МЛАДШИЙ байт инвертированной суммы)


Вот текст программки которая соответствует извлеченному алгоритму:
(она отличается от канонического вида - на инверсию влияет XOR входного бита и выдвигаемого):


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

unsigned short int crc16(unsigned short crc, unsigned char data)
{
int i, bit;

printf("\r\n %02X(%04X,", data, crc);
for(i=0; i<8; i++)
{
bit = (data >> 7) & 1;
if (crc & 0x8000)
{
bit ^= 1;
}
crc <<= 1;
crc |= bit;
if (bit == 0)
{
crc ^= 0x1020;
}
data <<= 1;
}
printf("%04X)", crc);
return crc;
}

int main(int argc, char *argv[])
{
unsigned short crc, tmp;

crc = 0;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0x30);
crc = crc16(crc, 0x31);
crc = crc16(crc, 0x32);
crc = crc16(crc, 0x33);
tmp = ~crc;
printf("\r\nCRC: %04X", tmp);

crc = 0;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0x30);
crc = crc16(crc, 0x31);
crc = crc16(crc, 0x32);
crc = crc16(crc, 0x33);
crc = crc16(crc, (tmp >> 8) & 0xFF);
crc = crc16(crc, (tmp >> 0) & 0xFF);
printf("\r\nTMP: %04X", crc);
if (crc == 0xFFFF) printf(" CRC OK");

printf("\r\n");
return 0;
}




2. Если генератор CRC в ходе записи не был запущен - будет ли выполнена запись CRC ( 0xFFFF ) в момент пропуска требования ?

Да (промоделировал, заменил в примере выше A1 на A2), будет выполнена запись, но поскольку регистр CRC не был правильно проинициализирован нулем, запишется два мусорных байта (взависимости что там в регистре CRC было при начале записи)



Также ( если я правильно понял ) при чтении CRC проверяется так - если требование выполнено, то содержимое регистра данных интерпретируется как данные и включается в расчёт CRC, если же требование не выполнено - содержимое регистра данных интерпретируется как CRC, прибавляется к рассчитанному значению CRC и результат проверяется на равенство 0xFFFF.

Похоже что тут ситуация такая - CRC читается как обычные данные, и после того как они прочитаны просто проверяется регистра CRC на 0xFFFF. Невыполнение требования (чтения) просто приводит к защелкиванию признака CRC_VALID и дальнейшее вычисление СRC на потоке вычисляемых данных уже никак на этот признак не влияет. То есть - просто идет поток данных чтения, без разбора - CRC/данные. Как только прекратили выполнять требование чтения - защелкнулся признак VALID (триггер J34) и дальше хранится, а поток продолжает обрабатываться, регистр CRC изменяется итд.

Patron
13.12.2013, 14:53
достаточно обнаружения 0xA1 в сдвиговом регистре. я пробовал писать снова 0xA1A1 но сброса больше не было - это однократный процесс после перехода от чтения к записиТ.е. запуск генератора CRC в режиме записи происходит после первого байта 0xA1 в сдвиговом регистре, перезапуск не происходит никогда, а остановка ( и запись инверсного значения CRC на диск ) происходит при пропуске требования.

---------- Post added at 13:53 ---------- Previous post was at 13:47 ----------


Похоже что тут ситуация такая - CRC читается как обычные данные, и после того как они прочитаны просто проверяется регистра CRC на 0xFFFF. Невыполнение требования (чтения) просто приводит к защелкиванию признака CRC_VALID и дальнейшее вычисление СRC на потоке вычисляемых данных уже никак на этот признак не влияет. То есть - просто идет поток данных чтения, без разбора - CRC/данные. Как только прекратили выполнять требование чтения - защелкнулся признак VALID (триггер J34) и дальше хранится, а поток продолжает обрабатываться, регистр CRC изменяется итд.Получается, что:

1. Запуск генератора CRC при чтении происходит в режиме поиска маркера по первому байту 0xA1 в сдвиговом регистре.

2. В процессе чтения признак CRC_VALID непрерывно отражает равенство текущего значения CRC величине 0xFFFF.

3. Повторное чтение маркера не сбрасывает генератор CRC. Чтобы перевести ВП1-128 в режим поиска маркера - нужно записать в регистр статуса бит "начало чтения" ( 8 ).

Vslav
13.12.2013, 14:53
Байтовый вариант выглядит так:

Увы, Ваш вариант не совпадает. Мой вариант crc16() - точно соответствует результатам моделирования. И дает при проверке требуетмый результат 0xFFFF.

Patron
13.12.2013, 15:35
Сообщение от Vslav

Я сейчас выполил такое моделирование:

qbus_write(16'O177132, 16'H3130);
На выходе записываемых данных получилось:


0x30 (то есть, сначала МЛАДШИЙ байт, старший бит первым)
0x31 (то есть, потом СТАРШИЙ байт, старший бит первым)
Вот и верь после этого описаниям.

Значит, хотя в описании ВП1-128 написано:
В режиме 'запись' 7-й разряд РС (TR) устанавливается в единицу
после того, как младший байт РДЗ переписался в сдвиговый регистр.Но на самом деле - первым пишется младший байт регистра данных, а требование выставляется при копировании в сдвиговый регистр старшего байта регистра данных.

---------- Post added at 14:25 ---------- Previous post was at 14:12 ----------

Здесь (http://forum.pk-fpga.ru/viewtopic.php?f=43&t=5482) написано так:
шестнадцатибитный регистр данных чтения принимает два байта данных из сдвигового регистра. В процессе считывания данных с диска сначала сохраняется старший байт, затем младший данных.Получается, что и там в описании ошибка и сначала сохраняется младший байт, а затем старший данных.

Так ?

---------- Post added at 14:35 ---------- Previous post was at 14:25 ----------

Сообщение от Vslav
0x91 (инвертированное 0x6E. Сначала пишется СТАРШИЙ байт инвертированной суммы)
0x16 (инвертированное 0xE9. Потом пишется МЛАДШИЙ байт инвертированной суммы)Но если слово контрольной суммы пишется в обратном порядке байтов относительно слов данных, то как порядок байтов при чтении получается для всех слов одинаковым ?

Vslav
13.12.2013, 16:02
1. В процессе чтения признак CRC_VALID непрерывно отражает равенство текущего значения CRC величине 0xFFFF.

CRC_VALID - да, но он не эквивалентен биту в регистре 177130. Читаемый бит в регистре называется CSR_CRC и получается с выхода триггера J36. А триггер защелкивается именно в момент окончания чтения (когда не выполняем требование считывания слова CRC).



2. Повторное чтение маркера не сбрасывает генератор CRC.

Промоделировал чтение - повторное обнаружение маркера не обнуляет регистр CRC, только первый маркер.

Patron
13.12.2013, 16:22
Сообщение от Vslav

На выходе записываемых данных получилось:

0x30 (то есть, сначала МЛАДШИЙ байт, старший бит первым)
0x31 (то есть, потом СТАРШИЙ байт, старший бит первым)
0x32
0x33 (после этого байта содержимое регистра CRC = 0x6EE9)
0x91 (инвертированное 0x6E. Сначала пишется СТАРШИЙ байт инвертированной суммы)
0x16 (инвертированное 0xE9. Потом пишется МЛАДШИЙ байт инвертированной суммы)
Похоже, что с моделированием какие-то проблемы. По логике работы контроллера - порядок байтов на диске у слова данных и слова CRC не может быть разным ( в обоих случаях первым должен идти СТАРШИЙ байт ).

Vslav
13.12.2013, 16:30
как порядок байтов при чтении получается для всех слов одинаковым ?

По результатам моделирования чтения СТАРШИЙ байт слова идет первым. То есть первый прочитанный с диска байт помещается в старший, второй прочитанный помещается в младший байт регистра данных. Получается что при чтении байты в словах надо переставлять. Странная ситуация, порядок байт при чтении/записи отличается, анализ кода драйвера это подтверждает?

Сумма CRC при записи сдвиговый регистр не проходит - данные сдвигаются в самом регистре CRC, поэтому порядок байт там не важен - всегда пишется 16-битное инвертированное слово суммы, начиная со старшего бита. Тасовка же байт данных происходит на уровне мультиплексора 16-битного регистра данных в сдвиговый регистр.

Vslav
13.12.2013, 16:44
Сообщение от Vslav
Похоже, что с моделированием какие-то проблемы. По логике работы контроллера - порядок байтов на диске у слова данных и слова CRC не может быть разным ( в обоих случаях первым должен идти СТАРШИЙ байт ).
Да, согласен, очень странно. Еще помоделировал, поискал ошибку, вроде нету. Полез в исходники РЕ2-326.
Фрагмент процедуры записи:


0DX: TSTB (R4) ;ЖДЕМ ГОТОВНОСТИ
BPL 0DX
MOV (R2)+,(R5) ;ПИШЕМ ДАННЫЕ
0DW: SOB R1,0DX ;ПИШЕМ ПОКА НЕ КОНЧАТСЯ ДАННЫЕ


Фрагмент процедуры чтения:


BD: MTPS #340
MOV 26(R3),R2 ;ЗАНЕСЕМ АДРЕС БУФЕРА
0BL: TSTB (R4) ;ОЖИДАНИЕ ДАННЫХ
BPL 0BL
MOV (R5),R0 ;ЧИТАЕМ СЛОВО
SWAB R0 ;ДЕЛАЕМ ЕГО НОРМАЛЬНЫМ
MOV R0,(R2)+ ;ЗАНОСИМ В БУФЕР
SOB R1,0BL ;ЧИТАЕМ ОПРЕДЕЛЕННОЕ КОЛ-ВО СЛОВ

Мне очень понравился комментарий - "делаем его нормальным" :)
Значит ВП1-128 таки ненормальная, ну и текущая модель ее ненормальность отображает нормально :)

Patron
13.12.2013, 16:47
анализ кода драйвера это подтверждает?Я сейчас пишу эмулятор контроллера MY - там роль драйвера выполняет прошивка -255:

Vslav
13.12.2013, 16:54
Я сейчас пишу эмулятор контроллера MY - там роль драйвера выполняет прошивка -255:
Похоже что 255-ая точно так же работает, фрагмент чтения:



; Подпрограмма чтения сектора
7254$: TST R2 ; Перешли за границу "окна"?
BPL 7304$ ; Нет
ROR R2 ; На начало "окна"
ADD #401,@#177102 ; Увеличить адрес старшей части "окна"
BNE 7304$ ; Еще не перешли границу памяти
BIS #4000,0(R3) ; Установить ошибку адреса в РСО
JMP 7500$ ; Завершить операцию с ошибкой
7304$: TSTB @R4 ; Очередное слово сформировано?
BPL 7304$ ; Нет
MOV @R5,R0 ; Прочесть слово
SWAB R0 ; Обменять байты
MOV R0,(R2)+ ; Передать слово в ОЗУ вычислителя
7316$: SOB R1,7254$

В процедуре записи команды SWAB нет. В-общем, Цирк уехал, клоуны остались :)

Patron
13.12.2013, 17:09
Значит ВП1-128 таки ненормальная, ну и текущая модель ее ненормальность отображает нормальноА ещё это значит, что требование в регистре статуса ( бит 7 ) выставляется не после пересылки в сдвиговый регистр младшего байта регистра данных ( как это написано в описании ВП1-128 ), а после пересылки СТАРШЕГО байта регистра данных, который пишется на диск следом за младшим.

Это так ?

Vslav
13.12.2013, 18:35
А ещё это значит, что требование в регистре статуса ( бит 7 ) выставляется не после пересылки в сдвиговый регистр младшего байта регистра данных ( как это написано в описании ВП1-128 ), а после пересылки СТАРШЕГО байта регистра данных, который пишется на диск следом за младшим.
Это так ?

Да, иначе ведь и быть не может - требование можно выставить только при условии что 16-битный регистр хранения данных полностью свободен. Последний байт (старший при записи) из регистра переписался в сдвиговый - ставим требование.
По факту требование ставится в последний битовый интервал перед освобождением регистра. Если МПИ быстрая (как было сначала при моделировании), то есть шанс успеть переписать регистр данных и на выходе переписать уже новые данные в сдвиговый регистр. На реальной МПИ такое маловероятно - процессор будет читать коды команд, данные из памяти и прочее - битовый интервал успеет пройти и регистр успеет фактически освободиться.

Patron
13.12.2013, 19:50
По факту требование ставится в последний битовый интервал перед освобождением регистра. Если МПИ быстрая (как было сначала при моделировании), то есть шанс успеть переписать регистр данных и на выходе переписать уже новые данные в сдвиговый регистр. На реальной МПИ такое маловероятно - процессор будет читать коды команд, данные из памяти и прочее - битовый интервал успеет пройти и регистр успеет фактически освободиться.Выходит, что в течение 4000 нс после выставления требования при записи - содержимое регистра данных находится под угрозой уничтожения. При тактовой частоте 10 МГц - это 40 тактов.

---------- Post added at 18:50 ---------- Previous post was at 18:43 ----------

Не удивлюсь, если 1801ВМ1 работает в контроллере MY на частоте ВП1-128 ( 4 МГц ).

Vslav
13.12.2013, 21:12
Выходит, что в течение 4000 нс после выставления требования при записи - содержимое регистра данных находится под угрозой уничтожения. При тактовой частоте 10 МГц - это 40 тактов.

Я помоделировал - интервал между выставлением требования и перезаписью данных (момент при котором в сдвиговый регистр могут попасть новые свежезаписанные данные) примерно 4 такта частоты 4МГц - то есть порядка 1 мкс. У меня процедуры МПИ вообще не были никак привязаны к тактовой, полностью асинхронные, чтение занимало менее 3 тактов. На МПИ реального процессора такое невозможно, так что проблема условная.

Patron
13.12.2013, 23:20
Вот текст программки которая соответствует извлеченному алгоритмуДля прикола - ещё один вариант того же алгоритма, использующий только сдвиги:



unsigned short int crc16( unsigned short crc, unsigned char data )
{
printf("\r\n %02X ( %04X,", data, crc);

crc = ~crc;
crc = unsigned char (crc >> 8) | (crc << 8);
crc ^= data;
crc ^= unsigned char (crc) >> 4;
crc ^= crc << 12;
crc ^= unsigned char (crc) << 5;
crc = ~crc;

printf(" %04X )", crc );
return crc;
}


Результат запуска:



A1 ( 0000, BBC4 )
A1 ( BBC4, 6974 )
30 ( 6974, A1D3 )
31 ( A1D3, 4EB6 )
32 ( 4EB6, 1714 )
33 ( 1714, 6EE9 )
CRC: 9116
A1 ( 0000, BBC4 )
A1 ( BBC4, 6974 )
30 ( 6974, A1D3 )
31 ( A1D3, 4EB6 )
32 ( 4EB6, 1714 )
33 ( 1714, 6EE9 )
91 ( 6EE9, E9FF )
16 ( E9FF, FFFF )
TMP: FFFF CRC OK

---------- Post added at 22:20 ---------- Previous post was at 22:04 ----------

В оригинале - это алгоритм CRC-16:


CRC-16
width=16 poly=0x1021 init=0xFFFF refin=false refout=false
xorout=0x0000 check=0x29B1


unsigned short int crc16( unsigned short crc, unsigned char data )
{
printf("\n %02X ( %04X,", data, crc);

crc = unsigned char (crc >> 8) | (crc << 8);
crc ^= data;
crc ^= unsigned char (crc) >> 4;
crc ^= crc << 12;
crc ^= unsigned char (crc) << 5;

printf(" %04X )", crc );
return crc;
}

int main(int argc, char *argv[])
{
unsigned short crc, tmp;

crc = 0xFFFF;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0x30);
crc = crc16(crc, 0x31);
crc = crc16(crc, 0x32);
crc = crc16(crc, 0x33);
tmp = crc;
printf("\nCRC: %04X", tmp);
}

Alex_K
13.12.2013, 23:55
Уж для того, чтобы разобраться какой алгоритм используется для подсчета CRC, в архиве "сырые данные" с нулевой дорожки нижней стороны отформатированной на УКНЦ дискеты. Там все - и межсекторные промежутки, и маркеры, и заголовки, и данные, ну и соответственно CRC.

Patron
14.12.2013, 00:53
Там все - и межсекторные промежутки, и маркеры, и заголовки, и данные, ну и соответственно CRC.Чтобы далеко не ходить - возьмём заголовок первого сектора:
A1 A1 A1 FE 00 00 01 02 CA 6F
Запустим эти байты в стандартный алгоритм CRC-16:
printf("Write:");
crc = 0xFFFF;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xFE);
crc = crc16(crc, 0x00);
crc = crc16(crc, 0x00);
crc = crc16(crc, 0x01);
crc = crc16(crc, 0x02);
tmp = crc;
printf("\nCRC: %04X", tmp);

printf("\n\nRead:");
crc = 0xFFFF;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xFE);
crc = crc16(crc, 0x00);
crc = crc16(crc, 0x00);
crc = crc16(crc, 0x01);
crc = crc16(crc, 0x02);
crc = crc16(crc, 0xCA);
crc = crc16(crc, 0x6F);
printf("\nTMP: %04X", crc);
if ( crc == 0x0000 ) printf(" CRC OK");

Результат запуска:
Write:
A1 ( FFFF, 443B )
A1 ( 443B, 968B )
A1 ( 968B, CDB4 )
FE ( CDB4, B230 )
00 ( B230, B799 )
00 ( B799, 4E3C )
01 ( 4E3C, 852B )
02 ( 852B, CA6F )
CRC: CA6F

Read:
A1 ( FFFF, 443B )
A1 ( 443B, 968B )
A1 ( 968B, CDB4 )
FE ( CDB4, B230 )
00 ( B230, B799 )
00 ( B799, 4E3C )
01 ( 4E3C, 852B )
02 ( 852B, CA6F )
CA ( CA6F, 6F00 )
6F ( 6F00, 0000 )
TMP: 0000 CRC OK


ВП1-128 "внутри себя" использует инверсный вариант CRC-16, но перед записью на диск инвертирует CRC, поэтому на диск пишется в точности то же, что генерит стандартный алгоритм CRC-16:

CRC-16
width=16 poly=0x1021 init=0xFFFF refin=false refout=false
xorout=0x0000 check=0x29B1

Vslav
14.12.2013, 01:22
В оригинале - это алгоритм CRC-16:


CRC-16
width=16 poly=0x1021 init=0xFFFF refin=false refout=false
xorout=0x0000 check=0x29B1

У меня вопрос есть. Описание алгоритма по Вильямсу это хорошо. Но у нас очевидно используется не банальное деление на полином 0x1021 и получение остатка. Алгоритм модифицирован так что на выходе получается некоторое магическое число, которое будучи пропущено вместе с блоком данных дает в итоге конкретное фиксированное значение. Я когда-то с этим разбирался, там небольшая математическая хитрость, но сейчас в упор не могу найти эту информацию. Не внесет ли кто ясность?

Update: кажется тут деление не самого сообщения (блока данных), а деление сообщения умноженого на разрядность образующего полинома (в данном случае на x^16). То есть находим остаток не от деления блока данных, а от деления блока данных умноженного на x^16. Потом когда мы из него вычитаем (в полиномиальной арифметике эквивалентно добавлению) остаток от деления, то результат делится на полином нацело, и остаток для проверки нулевой (или 0xFFFF в инверсном варианте). Но пока свести программу к делению на 1021 у меня не получается с нужным результатом.


---------- Post added at 23:22 ---------- Previous post was at 23:18 ----------


Чтобы далеко не ходить - возьмём заголовок первого сектора:
A1 A1 A1 FE 00 00 01 02 CA 6F

Любопытно, какой глубокий смысл в трех маркерах, если они все включаются в контрольную сумму. Если первый не раcпознан - сумма некорректная. Ну разве что проигнорировать сумму и пытаться вытащить из сектора хоть что-то.

Patron
14.12.2013, 11:32
у нас очевидно используется не банальное деление на полином 0x1021 и получение остаткаНу, это как посмотреть. Вот внутренний алгоритм ВП1-128 в каноническом виде:



unsigned short int crc16( unsigned short crc, unsigned char data )
{
printf("\n %02X ( %04X,", data, crc);

crc = ~crc;
crc ^= unsigned short (data) << 8;

for( int i = 0 ; i < 8 ; i++ )
{
if( crc & 0x8000 ) { crc = (crc << 1) ^ 0x1021; }
else { crc = (crc << 1); }
}
crc = ~crc;

printf(" %04X )", crc );
return crc;
}

int main(int argc, char *argv[])
{
unsigned short crc, tmp;

crc = 0x0000;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0x30);
crc = crc16(crc, 0x31);
crc = crc16(crc, 0x32);
crc = crc16(crc, 0x33);
tmp = ~crc;
printf("\nCRC: %04X", tmp);
}



А вот - стандартный алгоритм CRC-16 в каноническом виде:

unsigned short int crc16( unsigned short crc, unsigned char data )
{
printf("\n %02X ( %04X,", data, crc);

crc ^= unsigned short (data) << 8;

for( int i = 0 ; i < 8 ; i++ )
{
if( crc & 0x8000 ) { crc = (crc << 1) ^ 0x1021; }
else { crc = (crc << 1); }
}

printf(" %04X )", crc );
return crc;
}

int main(int argc, char *argv[])
{
unsigned short crc, tmp;

crc = 0xFFFF;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0x30);
crc = crc16(crc, 0x31);
crc = crc16(crc, 0x32);
crc = crc16(crc, 0x33);
tmp = crc;
printf("\nCRC: %04X", tmp);
}



Оба алгоритма пишут на диск одно и то же, но алгоритм ВП1-128 использует начальное значение 0 и дважды инвертирует CRC, а стандартный алгоритм CRC-16 - использует начальное значение -1 и ни разу не инвертирует CRC.

...

Vslav
14.12.2013, 12:10
Алгоритм-то мы вытащили, уже у нас есть достоверные и софтовые и аппаратные реализации, но я хочу докопаться до математической сути.

Если упрощенно и в терминах обычной арифметики, то у нас есть некоторое число m - сообщение (передаваемый блок полезных данных). Есть некоторая константа делитель p. Мы берем вычисляем остаток от деления: r = m mod p. Понятно что остаток от деления: (m - r) mod p будет нулевым и на этом можно выполнять простую проверку.

CRC - это остаток полиномиального деления на полином. У нас в данном случае используется методика проверки CRC "one-pass" - это когда сама CRC принимается и загоняется в тот же поток вместе с данными, а результирующая CRC сравнивается с константой. Чтобы такая методика работала надо делить не само сообщение, а конкатенацию: i | m | c, где i представляет собой начальное значение, а c - некоторая дополняющая константа (магическое число, разрядностью такой же как и у остатка, которое получится на приемном конце после вычисления CRC для блока + принятая сумма), часто c нулевое (как и в нашем случае). Принимающая сторона уже выполняет деление i | m | (c - r) и в итоге получает в остатке константу c.

Классическое полиномиальное деление "в столбик" (методы сдвигов и табличный - суть оптимизация, нам сейчас надо понять первичный алгоритм):


unsigned short int crc16_m2(unsigned short crc, unsigned char data)
{
int i;
for(i=0; i<8; i++)
{
if (crc & 0x8000)
{
crc <<= 1;
crc |= (data >> 7) & 1;
crc ^= 0x1021;
}
else
{
crc <<= 1;
crc |= (data >> 7) & 1;
}
data <<= 1;
}
return crc;
}


Вот я и хочу привести процедуру к использованию этой канонической функции. В Вашем коде делится сообщение уже сдвинутое на 16 разрядов влево, то есть имеет место добавление той самой константы c состоящей из 16 нулевых битов. В-общем, тут загвоздка похоже просто чтоi достаточно хитрое и не является простым префиксом из 0xFFFF, поэтому у меня не получается аналогичный результат. А так - да, ясно что вдвигание данных по факту в 17-бит - это и есть учет последних нулевых бит, которые отдельно в конце у нас не вдвигаются.

Patron
14.12.2013, 13:39
В Вашем коде делится сообщение уже сдвинутое на 16 разрядов влево, то есть имеет место добавление той самой константы c состоящей из 16 нулевых битов.Вот классический "безразмерный" вариант, вычисляющий CRC-16 для произвольной последовательности битов.

Внутренний вариант ВП1-128:

unsigned short int crc16_bitstep( unsigned short crc, int bit )
{
int crc_high_bit = ( crc & 0x8000 ? 1 : 0 );
int DoInvert = bit ^ crc_high_bit;

if( DoInvert ) { crc = (crc << 1) ^ 0x1021; }
else { crc = (crc << 1); }

return crc;
}

unsigned short int crc16( unsigned short crc, unsigned char data )
{
printf("\n %02X ( %04X,", data, crc);

crc = ~crc;
for( unsigned char mask = 0x80 ; mask ; mask >>= 1 )
{
int bit = ( data & mask ? 1 : 0 );
crc = crc16_bitstep( crc, bit );
}
crc = ~crc;

printf(" %04X )", crc );
return crc;
}

int main(int argc, char *argv[])
{
unsigned short crc, tmp;

crc = 0x0000;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0x30);
crc = crc16(crc, 0x31);
crc = crc16(crc, 0x32);
crc = crc16(crc, 0x33);
tmp = ~crc;
printf("\nCRC: %04X", tmp);
}



Стандартный алгоритм CRC-16:

unsigned short int crc16_bitstep( unsigned short crc, int bit )
{
int crc_high_bit = ( crc & 0x8000 ? 1 : 0 );
int DoInvert = bit ^ crc_high_bit;

if( DoInvert ) { crc = (crc << 1) ^ 0x1021; }
else { crc = (crc << 1); }

return crc;
}

unsigned short int crc16( unsigned short crc, unsigned char data )
{
printf("\n %02X ( %04X,", data, crc);

for( unsigned char mask = 0x80 ; mask ; mask >>= 1 )
{
int bit = ( data & mask ? 1 : 0 );
crc = crc16_bitstep( crc, bit );
}

printf(" %04X )", crc );
return crc;
}

int main(int argc, char *argv[])
{
unsigned short crc, tmp;

crc = 0xFFFF;
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0xA1);
crc = crc16(crc, 0x30);
crc = crc16(crc, 0x31);
crc = crc16(crc, 0x32);
crc = crc16(crc, 0x33);
tmp = crc;
printf("\nCRC: %04X", tmp);
}

Vslav
14.12.2013, 14:13
Вот классический "безразмерный" вариант, вычисляющий CRC-16 для произвольной последовательности битов.

Внутренний вариант ВП1-128:

unsigned short int crc16_bitstep( unsigned short crc, int bit )
{
int crc_high_bit = ( crc & 0x8000 ? 1 : 0 );
int DoInvert = bit ^ crc_high_bit;

if( DoInvert ) { crc = (crc << 1) ^ 0x1021; }
else { crc = (crc << 1); }

return crc;
}


Да, спасибо, в хороший вид привели (кстати, делятся инвертированные данные, иначе было бы - if(!DoInvert ))

Я вижу отличие в том что каждый новый бит данных добавляется в СТАРШИЙ разряд сдвигового регистра. А когда мы "по-школьному" делим "в столбик" новый разряд (цифру) мы всегда добавляем справа - то есть в МЛАДШИЙ разряд. На самом деле понятно почему так - мы же после блока данных не вдвигаем еще дополнительных два нулевых байта, вместо этого мы умножаем каждый бит данных на 0x10000 сразу при вдвигании, поэтому дополнительные байты не нужны. То есть математика тут у нас та же - полиномиальное деление конкатенации сообщения и шестнадцати дополнительных замыкающих нулей. Просто хотелось бы привести к обычному делению "в столбик" (с вкидыванием нового разряда вправо), но видимо такая модификация алгоритма к нему не приводится.

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

Patron
14.12.2013, 14:52
Я вижу отличие в том что каждый новый бит данных добавляется в СТАРШИЙ разряд сдвигового регистра.Биты вообще не добавляются.

Аппаратный алгоритм такой:

1. 16-разрядный регистр CRC сдвигается влево, старший разряд при этом выходит в триггер.
2. Выход триггера бывшего старшего разряда CRC и старший бит сдвигового регистра ( т.е. текущий бит данных ) логически складываются и их исключающее ИЛИ управляет инверсией 0-го, 5-го и 12-го битов регистра CRC.

Вот и весь алгоритм CRC-16.

---------- Post added at 13:52 ---------- Previous post was at 13:32 ----------

Перед делением полиномов - делимое ( у нас - один бит ) сдвигается влево на кол-во разрядов, равное степени делителя ( у нас - на 16 разрядов ).

Vslav
14.12.2013, 15:51
Биты вообще не добавляются.
Добавляются, добавляются. В этом суть деления "в столбик".



1. 16-разрядный регистр CRC сдвигается влево, старший разряд при этом выходит в триггер.

На самом деле регистр делителя 17-битный. Но старший 16-й бит (нумерация битов здесь и далее с 0 - 0..16) при делении всегда нулевой, потому что регистр всегда содержит только остаток. А перед сдвигом достаточно проверить 15-й бит, поэтому старший 16-й бит регистра обычно не реализовывают ни в софте, ни в железе. В наших примерах можно объявить переменную crc 32-битным и проверять 0x10000 ПОСЛЕ сдвига - это сути деления более соответствует, чем проверять 0x8000 ДО сдвига.

Итерация деления такая (нас только остаток интересует) - cначала в регистре некоторое имеем 17-битное значение - 0xxxx. Поскольку старший бит нулевой то ПОЛНЫЙ 17-битный полином 0x11021 мы вычесть не можем. Поэтому сдвигаем 17-битное значение влево, а в младший разряд добавляем новый бит данных. Ну как в школе - берем из делимого очередную цифру и приписываем к остатку справа. Ессно, в школе цифры десятичные, а тут двоичные. Если в 17-ом разряде оказывается единица - то мы вычитаем ПОЛНЫЙ полином 0x11021. Операция вычитания/сложения в полиномиальной арифметике это XOR. Поэтому 17-бит всегда в начале и конце итерации нулевой.

Так вот, в реализации ВП1-128 (ну и вообще, видимо, в алгоритмах CRC заточенных под one-pass checking) происходит сдвиг, при этом добавление новой цифры (из входящего битового потока) происходит не справа в младший разряд, а самый старший - в нереализуемый 17-бит. Что соответствует умножению бита данных на 0x10000 (как в обычной так и в полиномиальной арифметике).



2. Выход триггера бывшего старшего разряда CRC и старший бит сдвигового регистра ( т.е. текущий бит данных ) логически складываются
Старший разряд 16-битного регистра CRC - это будет как раз 16-й виртуальный бит после сдвига. А очередной бит данных добавляемый к 16-му разряду - это и есть результат неявного умножения битов сообщения на 0x10000. XOR - это и есть сумма. Это есть по сути внесение новой цифры - приписывание цифры справа в школе означает умножение текущего остатка на 10 и добавление цифры. Так и тут - умножили остаток на 2 и добавили новую цифру, только не просто так, а умноженную на 0x10000 - попадает на 16-й разряд . Потом смотрим на получившийся 16-бит - результат - 1? значит можно вычитать (операция XOR для полиномов) полный полином 0x11021. 0? - ничего не делаем - вычесть нельзя. Ну как в школе - приписали цифру, вычесть не можем? значит цифра частного - 0, а остаток не меняем.



Перед делением полиномов - делимое ( у нас - один бит ) сдвигается влево на кол-во разрядов, равное степени делителя ( у нас - на 16 разрядов ).

Не-а, это не перед делением полиномов. Это именно частность алгоритма CRC - дополнительное неявное умножение (сдвиг влево) на разрядность остатка, чтобы потом прошло one-pass checking (получение 0 в результате вычисления суммы на приемном конце).

Вот так выглядит Ваша функция в ПОЛНОМ виде:

unsigned short int crc16_bitstep( unsigned short crc, int bit )
{
unsigned long reg;
//
// Перенесли в более длинный регистр (нам надо 17 бит)
//
reg = crc;
//
// Умножили текущий остаток на x (на 2)
//
reg = reg << 1;
//
// Добавили к остатку новые данные умноженные на x^16 (0x10000)
//
reg = reg ^ ((unsigned long)bit << 16);

if (reg & 0x10000)
{
//
// Можем вычесть полином x^16 + x^12 + x^5 + x^0
//
reg ^= 0x11021;
}
crc = (unsigned short)reg;
return crc;
}


Если же обычное деление полиномов - то без умножения на 0x10000, пишется просто: reg = reg ^ (unsigned long)bit;
Насчет что добавляются инвертированные данные был неправ, похоже делится все в прямом виде.

Patron
14.12.2013, 16:58
А перед сдвигом достаточно проверить 15-й бит, поэтому старший 16-й бит регистра обычно не реализовывают ни в софте, ни в железе.Вообще, аппаратная реализация стандартного алгоритма CRC-16 выглядит несложной - кроме сдвигового регистра CRC там надо только 4 логических элемента.

Vslav
15.12.2013, 10:28
Все, привел я к обычному делению на полином. Нужно просто было понять что же реально делится и подавать фактическую последовательность делимого:


crc = 0;
crc = crc16_m2(crc, 0xA1 ^ 0xFF);
crc = crc16_m2(crc, 0xA1 ^ 0xFF);
crc = crc16_m2(crc, 0x30);
crc = crc16_m2(crc, 0x31);
crc = crc16_m2(crc, 0x32);
crc = crc16_m2(crc, 0x33);
crc = crc16_m2(crc, 0x00);
crc = crc16_m2(crc, 0x00);

где - crc16_m2() - обычное деление на полином, с вдвиганием бита данных в младший разряд. Контрольные суммы совпадают, все выкладки полностью подтвердились.

Patron
15.12.2013, 11:20
где - crc16_m2() - обычное деление на полином, с вдвиганием бита данных в младший разрядА как выглядит на C исходный код функции crc16_m2() ?

Vslav
15.12.2013, 12:43
А как выглядит на C исходный код функции crc16_m2() ?


unsigned short int crc16_m2(unsigned short crc, unsigned char data)
{
int i;

printf("\n %02X ( %04X,", data, crc);
for(i=0; i<8; i++)
{
if (crc & 0x8000)
{
crc <<= 1;
crc |= (data >> 7) & 1;
crc ^= 0x1021;
}
else
{
crc <<= 1;
crc |= (data >> 7) & 1;
}
data <<= 1;
}
printf(" %04X )", crc );
return crc;
}

Patron
15.12.2013, 13:50
crc16_m2() - обычное деление на полином, с вдвиганием бита данных в младший разрядНасколько я понимаю - деление бита на полином 16 степени требует сдвигания бита на 16 разрядов влево.

Из-за этого, для получения правильного результата деления всех добавленных справа битов - после обрабатываемой последовательности битов приходится пропускать через обработчик ещё 16 "проталкивающих" нулевых битов:

crc = crc16_m2(crc, 0x00);
crc = crc16_m2(crc, 0x00);В результате - все добавленные в регистр CRC биты данных делятся на полином именно там, где и должны - в 17-ом бите CRC.

Vslav
15.12.2013, 14:53
Насколько я понимаю - деление бита на полином 16 степени требует сдвигания бита на 16 разрядов влево.

Есть два отдельных понятия - операция полиномиальной арифметики "нахождение остатка при делении на полином" и набор действий называемый "алгоритм CRC". Это разные вещи, относящиеся к разным категориям. Часто просто говорят - "CRC это нахождение остатка от деления на полином" и при этом не вдаются в подробности. И мало кто в подробности вникает, незачем - в Сети полно программных и аппаратных реализаций на любой вкус.

Операция деления на полином - можно показать как простое деление в столбик. Выполняется точно так же как школьная операция деления десятичных чисел в столбик, только с двоичными цифрами и операции сложения/вычитания реализованы как XOR. В том же руководстве Виллиамсa по CRC есть банальный пример как оно выполняется (правда там пририсовали нули в конце сообщения, поэтому вероятно народ заблуждается насчет операции деления).

Алгоритм CRC - находит остаток именно при помощи этой операций деления и никакой другой. Вопрос только в том что делится. Алгоритму CRC-16 надо чтобы на проверяющем конце в итоге получился 0 (или другая константа). Поэтому сообщение умножают на 0x10000 и вычитают из него вычисленную на передающем конце сумму - в нашем случае это выглядит просто как два добавленных байта суммы в конце. Математическое обоснование почему надо умножать и вычитать я писал выше - это свойство остатков. Умножить же сообщение на 0x10000 можно либо добавлением двух нулевых байтов, либо встроить это умножение в саму процедуру деления, что и сделано в ВП1-128 - в ней вдвигание по факту производится в виртуальный 16-ый бит.

Таким образом утверждение "деление бита на полином 16 степени требует сдвигания бита на 16 разрядов влево" неверно, потому что сдвигания требует оптмизированный алгоритм вычисления CRC, а не собственно операция деления.

Patron
15.12.2013, 15:23
Алгоритму CRC-16 надо чтобы на проверяющем конце в итоге получился 0 (или другая константа). Поэтому сообщение умножают на 0x10000 и вычитают из него вычисленную на передающем конце сумму - в нашем случае это выглядит просто как два добавленных байта суммы в конце.Даже если не требовать "проверочного нуля" ( или другой константы ) - алгоритм функции crc16_m2 даёт корректный результат только при умножении входного сообщения на 0x10000. Иначе CRC вообще не вычисляется.

Чтобы коректно вычислять CRC без умножения входного сообщения на 0x10000 - нужен совсем другой алгоритм.

---------- Post added at 14:23 ---------- Previous post was at 14:13 ----------

Корректный алгоритм вычисления CRC должен для сообщения из одного бита "1" давать результат 0x1021.

Функция crc16_m2 даст такой результат только для сообщения "10000000000000000", т.е. для бита "1", умноженного на 0x10000.

Vslav
15.12.2013, 15:54
Функция crc16_m2 даст такой результат только для сообщения "10000000000000000", т.е. для бита "1", умноженного на 0x10000.
Моя функция crc16_m2() - это НЕ алгоритм CRC. Это итеративная функция полиномиального деления, как оно понимается в математике. Она умножает аргумент crc на 0x100, добавляет data и находит остаток от деления на полином 0x11021. Чтобы получить результат алгоритма CRC для одного бита надо эту функцию вызвать трижды - добавить еще два нулевых байта.
И моей задачей было именно показать как алгоритм CRC базируется на канонической операции деления.

---------- Post added at 13:54 ---------- Previous post was at 13:49 ----------



Функция crc16_m2 даст такой результат только для сообщения "10000000000000000", т.е. для бита "1", умноженного на 0x10000.

Правильно, только умножение на 0x10000 это есть этап алгоритма CRC, а НЕ свойство собственно функции полиномиального деления. Я выделил чистую операцию деления и показал как алгоритм CRC его использует. Без всяких вводящих в заблуждение оптимизаций.

Patron
15.12.2013, 16:33
Моя функция crc16_m2() - это НЕ алгоритм CRC. Это итеративная функция полиномиального деления, как оно понимается в математике. Она умножает аргумент crc на 0x100, добавляет data и находит остаток от деления на полином 0x11021.Но нужен остаток от деления именно бита данных на полином, а не остаток от деления 17-го бита CRC на полином.

Какой смысл делить 17-й бит CRC на полином, если деление бита данных на полином при этом не происходит и приходится дополнительно вызывать функцию 16 раз, чтобы бит данных наконец поделился на полином и сформировал остаток..

---------- Post added at 15:33 ---------- Previous post was at 14:58 ----------

Насколько я понимаю, функция crc16_m2 - это не итеративная функция полиномиального деления CRC, а функция полиномиального деления 17-го бита CRC для каждого бита данных:



unsigned short int crc16_m2(unsigned short crc, unsigned char data)
{
int i;

printf("\n %02X ( %04X,", data, crc);
for(i=0; i<8; i++) // для каждого бита данных
{ // выполнить деление 17-го бита CRC на полином 0x11021
if (crc & 0x8000)
{
crc <<= 1;
crc |= (data >> 7) & 1;
crc ^= 0x1021;
}
else
{
crc <<= 1;
crc |= (data >> 7) & 1;
}
data <<= 1;
}
printf(" %04X )", crc );
return crc;
}

Когда в 17-м бите CRC находится текущий бит данных - это именно то, что надо, но когда текущий бит данных находится на 16 битов правее - функция даёт корректный результат только после 17-го вызова, с задержкой выдачи результата для текущего бита данных на 16 вызовов. Т.е. чтобы учесть корректный результат полиномиального деления для последнего бита данных - после передачи в функцию последнего бита данных нужно вызвать функцию crc16_m2 ещё 16 раз.

Vslav
15.12.2013, 16:36
Какой смысл делить CRC на полином, если деление бита данных на полином при этом не происходит и приходится дополнительно вызывать функцию 16 раз, чтобы бит данных наконец поделился на полином и сформировал остаток..
Делится не CRC. Аргумент crc содержит остаток от деления предыдущих битов сообщения, функция-то итеративная. А додвигание - это и есть умножение, требуемое алгоритмом CRC.

Еще раз, суть алгоритма CRC (хотя уже писал в этой ветке).
У нас есть некоторое число m - сообщение (передаваемый блок полезных данных). Есть некоторая константа p. Есть некоторая операция mod. В-общем случае это может быть необязательно операция нахождения остатка от полиномиального деления, а например остаток от обычного, с переносом (эх, давно я в теорию групп не заглядывал, щаз бы поумничал "кольцом вычетов" :))

Допустим мы вычисляем значение:
r = m mod p

Если мы найдем значение:
r`= (m - r) mod p,

то это r' будет нулевым потому что:
(m - r) mod p = (m mod p - r mod p) mod p
m mod p = r
r mod p = r
r`= r - r = 0.

На практике такая реализация не очень удобна - при проверке надо хранить m и r, потом вычислять их разность (особенно сложно если арифметика с переносом а не полиномиальная).
Поэтому алгоритмы CRC вычисляют mod не от самого m а умножают его дополнительно на разрядность остатка (назовем s):
crc = (m*s) mod p.

И при отправке данных тупо добавляют после самого m вычисленный crc. Конкатенированная последовательность m | crc эквивалентна значению m*s - crc, поэтому когда мы выполним:
(m*s - crc) mod p,

то это и будет итоговый остаток, который как я выше показал нулевой. Умножение на s - это просто фишка алгоритма CRC, чтобы была более удобна практическая реализация, никакой математики в этом нет.
функция crc16_m2() - это и есть итерация чистой операции mod. Все Ваши функции - просто одновременно c делением умножают аргумент на s.

Patron
15.12.2013, 17:02
функция crc16_m16() - это и есть итерация чистой операции modфункция crc16_m2 - это функция деления 17-го бита CRC на полином 0x11021. Итеративное полиномиальное деление CRC там не производится.

---------- Post added at 16:02 ---------- Previous post was at 15:47 ----------


Аргумент crc содержит остаток от деления предыдущих битов сообщенияНе содержит.

После подачи первого бита данных - остаток от деления данных на полином появляется в CRC только на 17-й вызов, поэтому после подачи последнего бита данных - нужно выполнить ещё 16 холостых вызовов. Иначе последний бит данных не будет подвергнут полиномиальному делению.

Vslav
15.12.2013, 17:13
функция crc16_m2 - это функция деления 17-го бита CRC на полином 0x11021. Итеративное полиномиальное деление CRC там не производится.
Переменная/параметр crc - это текущее значение остатка при делении длинного сообщения. То есть то что у Вас при делении в столбик в новую строчку переносится. Поэтому Ваш добавленный комментарий "деление 17-го бита CRC" некорректен и делится именно сообщение. А значение CRC уже появится в этой переменной когда все что нужно (в том числе финальные нули для умножения *s) будет поделено.

---------- Post added at 15:13 ---------- Previous post was at 15:06 ----------



Не содержит.

Содержит содержит :)

Математически:
0x00001 mod 0x11021 = 0x00001
0x00002 mod 0x11021 = 0x00002
0x00004 mod 0x11021 = 0x00004
0x00008 mod 0x11021 = 0x00008
0x00010 mod 0x11021 = 0x00010
....
0x08000 mod 0x11021 = 0x08000
0x10000 mod 0x11021 = 0x01021

Так что функция находит именно полиномиальный mod, а если ее правильно вызывать то можно реализовать алгоритм CRC получить нужное значение суммы CRC. Сумма CRC - это результат работы алгоритма (см. описание в сообщении #110) , а не просто операции mod.

Patron
15.12.2013, 18:07
делится именно сообщениеЧтобы делению на полином 16 степени подверглось сообщение - сообщение нужно дополнить 16-ю нулевыми битами.

Поэтому, итеративное полиномиальное деление сообщения выполняет программа в целом ( когда вслед за байтами сообщения посылает в функцию два нулевых байта ).

---------- Post added at 17:07 ---------- Previous post was at 16:47 ----------


0x00001 mod 0x11021 = 0x00001А чему равен остаток итеративного полиномиального деления "в столбик" сообщения 0xA1 на полином 0x11021 ?

Vslav
15.12.2013, 18:18
А чему равен остаток итеративного полиномиального деления "в столбик" сообщения 0xA1 на полином 0x11021 ?

Именно остаток от деления равен 0xA1. Остаток для деления любого числа меньшего 0x10000 (по факту - меньше старшей степени полинома-делителя) равен самому числу. Так же как в десятичной арифметике. Когда мы в третьем классе искали 12 mod 5 то мы же не умножали предварительно 12 на 4 либо на что-то еще.
А чтобы найти CRC-16 для сообщения 0xA1 надо фактически найти остаток от деления числа 0xA10000.

Patron
15.12.2013, 18:29
Именно остаток от деления равен 0xA1. А чтобы найти CRC-16 для сообщения 0xA1 надо фактически найти остаток от деления числа 0xA10000.Теперь понятно - добавление нулевых битов в конце сообщения нужно только для того, чтобы влияние каждого бита сообщения на результат деления не зависело от количества последующих битов в сообщении.

Patron
21.12.2013, 21:21
Ещё вопросы по работе 1801ВП1-128.

1. Когда при записи пропущено требование - на диск пишется контрольная сумма. Но что 1801ВП1-128 делает потом:

1.1. Переходит в режим чтения.
1.2. Переходит в режим поиска маркера.


2. Что произойдёт, если при получении требования в режиме записи - выполнить чтение регистра данных вместо записи:

2.1. Требование "удовлетворится" и на диск будет записано старое содержимое регистра данных.
2.2. Требование не "удовлетворится" и на диск будет записана контрольная сумма.
2.3. 1801ВП1-128 перейдёт в режим чтения без записи контрольной суммы.

Alex_K
21.12.2013, 21:39
Ещё вопросы по работе 1801ВП1-128.

1. Когда при записи пропущено требование - на диск пишется контрольная сумма. Но что 1801ВП1-128 делает потом:

1.1. Переходит в режим чтения.
1.2. Переходит в режим поиска маркера.
Остается в режиме записи, это видно по подпрограммам форматирования. Свежеотформатированную дорожку можно считать целиком, начиная с маркера самого первого заголовка. Если бы был переход в режим чтения (поиск маркера является его подвидом), то были бы пробелы, и при чтении дорожки целиком происходила бы рассинхронизация после чтения байтов CRC. А вот если требование не удовлетворять, то что будет далее записываться я не знаю, об этом надо спросить у Vslav, он разбирал работу контроллера.


2. Что произойдёт, если при получении требования в режиме записи - выполнить чтение регистра данных вместо записи:

2.1. Требование "удовлетворится" и на диск будет записано старое содержимое регистра данных.
2.2. Требование не "удовлетворится" и на диск будет записана контрольная сумма.
2.3. 1801ВП1-128 перейдёт в режим чтения без записи контрольной суммы.
То что перейдет в режим чтения это точно. Вряд ли запишется CRC, т.к. требование возникает в момент копирования последнего байта из регистра записи в сдвиговый регистр. Весьма вероятно может не записать и последний байт из сдвигового регистра, но тут надо анализировать схему.
Во всяком случае после начала записи CRC подпрограмма записи записывает в регистр записи 0x4E4E, и после ждет появление бита готовности, а потом переводит контроллер в режим чтения, прочитав регистр 177132.

Patron
21.12.2013, 21:52
Бит 14 CSR сбрасывается по INIT и обновляется при пропуске требования. А сбрасывается ли этот бит при выполнении требования или когда-то ещё ?

Alex_K
21.12.2013, 21:57
И при каждом пропущенном требовании пишет на диск новую контрольную сумму ? Я уже выше сказал, что не знаю, таких опытов не делал. Думая Vslav ответит, он же разбирал работу схемы и даже моделировал ее, может быть он об этом уже и говорил, надо читать весь топик.

---------- Post added at 21:57 ---------- Previous post was at 21:52 ----------

Полезной информацией Vslav поделился здесь (http://zx.pk.ru/showpost.php?p=651726&postcount=77).

Patron
21.12.2013, 22:07
Весьма вероятно может не записать и последний байт из сдвигового регистраЭто вряд ли - байты там различаются на старшие и младшие, поэтому нет смысла пропускать запись старшего байта - ведь начинать чтение надо всегда с младшего байта, а очередь младшего байта наступает после старшего.

Alex_K
21.12.2013, 22:23
Бит 14 CSR сбрасывается по INIT и обновляется при пропуске требования. А сбрасывается ли этот бит при выполнении требования или когда-то ещё ?
Если этот бит установился, то в режиме чтения не сбросится, так и будет установленным, пока его не сбросят битом GOR. В режиме записи он устанавливается при пропуске требования, т.е. при начале записи CRC.

А вообще схема такая, что черт ногу сломит. Сложно вникать во все.

---------- Post added at 22:23 ---------- Previous post was at 22:19 ----------


Это вряд ли - байты там различаются на старшие и младшие, поэтому нет смысла пропускать запись старшего байта - ведь начинать чтение надо всегда с младшего байта, а очередь младшего байта наступает после старшего.
Все это можно проверить практически, но все УКНЦ у меня сейчас отключены. Подключить надо время, да и программу написать. После этого достаточно прочесть уже записанную зону данных вместе с CRC и несколькими байтами дальше. Если после CRC будет один байт 0x4E, то старший байт не пишется, если два, то записывается.

Patron
21.12.2013, 22:32
И ещё вопрос - регистр данных обнуляется по INIT ?

---------- Post added at 21:32 ---------- Previous post was at 21:27 ----------


В режиме записи он устанавливается при пропуске требования, т.е. при начале записи CRC.Но при начале чтения - бит 14 уже должен быть сброшен, значит - он должен сбрасываться и при переходе из режима записи в режим чтения.

Хотя нет. Пока не прочитан маркер - контрольная сумма чтения некорректна, поэтому нет смысла сбрасывать бит 14.

Alex_K
21.12.2013, 22:36
И ещё вопрос - регистр данных обнуляется по INIT ?
Нет не обнуляется, это хорошо видно по схеме. Соответственно ни регистр чтения данных, ни регистр записываемых данных.
Кстати, насчет бита 14, по схеме видно, что он имеет два источника, в зависимости от того, в каком режиме находится контроллер - чтения или записи. Собственно получается, что если он установился у нас в режиме чтения, потом перешли в режим записи, записали несколько слов с удовлетворением требования. При переходе в режим записи он (бит 14) очистится. Потом перейдем в режим чтения, и бит 14 снова установится.

Patron
21.12.2013, 23:10
А если в режиме записи, после удовлетворения очередного требования - установить в CSR бит GOR - что тогда будет ?

Alex_K
21.12.2013, 23:52
А если в режиме записи, после удовлетворения очередного требования - установить в CSR бит GOR - что тогда будет ?
Сложновато ответить. Надо капитально анализировать схему. Установка режима записи происходит под влиянием сигнала LAST_WR. Сброс в режим чтения - сигнал INIT на шине, а также еще целая куча сигналов, которые должны сбросить в режим чтения. Кстати, каким-то боком в этом участвует и сигнал IND, судя по схеме.

Vslav
22.12.2013, 00:23
Ещё вопросы по работе 1801ВП1-128.
1. Когда при записи пропущено требование - на диск пишется контрольная сумма. Но что 1801ВП1-128 делает потом:

1.1. Переходит в режим чтения.
1.2. Переходит в режим поиска маркера.

Остается в режиме записи и продолжает писать нулевые данные.


Ещё вопросы по работе 1801ВП1-128.2. Что произойдёт, если при получении требования в режиме записи - выполнить
чтение регистра данных вместо записи:

Запись прекращается немедленно (так же nWRE сразу выставляется в высокий уровень), потом переходит в режим чтения, но неполноценное - не ищется маркер и не обнуляется CRC по приходу маркера. То есть полноценно прочитать следующий сектор без инициализации битов GDR не получится.

Alex_K
22.12.2013, 00:29
Остается в режиме записи и продолжает писать нулевые данные.
Т.е. расчет CRC прекращается? И записанная ранее CRC рассчитывается сама с собой - получается ноль, и он дальше записывается?

Vslav
22.12.2013, 03:24
Т.е. расчет CRC прекращается? И записанная ранее CRC рассчитывается сама с собой - получается ноль, и он дальше записывается?
Нет, она не может сама с собой рассчитаться - она же на выход сдвигового CRC-регистра уходит, а считается со входа. Там чуть хитрее - когда пишется сама сумма после задержанного требования становится активным сигнал CRC_IN0, в регистр при этом начинают вдвигаться единицы (чтобы не искажать вычисленную сумму, то есть регистр CRC просто превращается в сдвиговый, XOR-ы блокируются), и после посылки суммы просто продолжают посылаться уже эти инвертированные единицы.

Patron
22.12.2013, 16:03
Запись прекращается немедленноНасколько немедленно:

1. Дописывается на диск младший байт из сдвигового регистра, а вместо переноса в сдвиговый регистр старшего байта - начинается чтение.

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

---------- Post added at 12:14 ---------- Previous post was at 12:11 ----------


полноценно прочитать следующий сектор без инициализации битов GDR не получится.В описании КМД этот бит называют GOR:

http://s6.hostingkartinok.com/uploads/images/2013/12/89a848bdd71a05767ecac0d1e8e3d64e.jpg

---------- Post added at 12:18 ---------- Previous post was at 12:14 ----------


Остается в режиме записи и продолжает писать нулевые данные.И сигнал IND никак на это не влияет ?

А если не обращаясь к регистру данных - установить в CSR бит GOR, что-нибудь в такой ситуации изменится ?

---------- Post added at 14:17 ---------- Previous post was at 12:18 ----------

Ещё вопрос - по пропуску "синхробита" при записи.

Программа форматирования пишет на диск четыре байта: 0xA1,0xA1,0xA1,0xFE с установленным в CSR битом WM. В каких байтах при этом происходит пропуск "синхробита":

1. Только в байтах 0xA1.
2. Только в первом записываемом байте из каждого слова.
3. Во всех байтах, записываемых с битом WM в CSR.

---------- Post added at 15:03 ---------- Previous post was at 14:17 ----------


В режиме записи бит 14 устанавливается при пропуске требования, т.е. при начале записи CRC.По логике работы программы форматирования - этот бит должен сбрасываться, а генератор CRC перезапускаться то ли после каждого перехода бита WM из 0 в 1 при котором в сдвиговом регистре находится байт 0xA1, то ли просто после каждого попадания при записи байта 0xA1 в сдвиговый регистр, если при этом установлен бит 14.

Записав заголовок сектора - программа форматирования ждёт установки бита 14, чтобы была выполнена запись CRC, потом без единого перехода в режим чтения - пишет промежуток, маркер данных, данные и затем повторно ожидает записи CRC:



5552$: CALL 7614$ ; Запись GAP, синхрозоны и маркера заголовка
5556$: TSTB @R4 ; Контроллер готов к приему?
BPL 5556$ ; Нет
MOV 14(R3),@R5 ; Записать дорожку/сторону в заголовок
MOV 2(R3),@R4 ; Выключить запись маркера
5572$: TSTB @R4 ; Контроллер готов к приему?
BPL 5572$ ; Нет
MOV R2,@R5 ; Записать длину/номер сектора в заголовок
MOV #13,R0 ; R0 = длина GAP2
MOV #175641,16(R3) ; Будет записываться маркер данных 0xFBA1
5612$: BIT #40000,@R4 ; CRC заголовка записана?
BEQ 5612$ ; Нет
CALL 7614$ ; Запись GAP2, синхрозоны и маркера данных
MOV R1,R0 ; R0 = размер сектора в словах
5626$: TSTB @R4 ; Контроллер готов к приему?
BPL 5626$ ; Нет
MOV 34(R3),@R5 ; Записать первое слово заполнителя
MOV 2(R3),@R4 ; Выключить запись маркера
DEC R0 ; Уменьшить число записываемых слов
5644$: TSTB @R4 ; Контроллер готов к приему?
BPL 5644$ ; Нет
MOV 34(R3),@R5 ; Записать заполнитель в цикле
SOB R0,5644$
INC R2 ; Увеличить номер сектора
MOVB 62(R3),R0 ; R0 = размер GAP3 в словах
MOV #177241,16(R3) ; Далее записывается маркер заголовка 0xFEA1
5672$: BIT #40000,@R4 ; CRC зоны данных записана?
BEQ 5672$ ; Нет


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

Alex_K
22.12.2013, 18:40
Насколько немедленно:

1. Дописывается на диск младший байт из сдвигового регистра, а вместо переноса в сдвиговый регистр старшего байта - начинается чтение.

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

---------- Post added at 18:29 ---------- Previous post was at 18:27 ----------


Ещё вопрос - по пропуску "синхробита" при записи.

Программа форматирования пишет на диск четыре байта: 0xA1,0xA1,0xA1,0xFE с установленным в CSR битом WM. В каких байтах при этом происходит пропуск "синхробита":

1. Только в байтах 0xA1.
2. Только в первом записываемом байте из каждого слова.
3. Во всех байтах, записываемых с битом WM в CSR.
Во всех байтах записываемых с битом WM, но получится только в 0xA1, т.к. в 0xFE отсутствует требуемого количество нулевых битов (ноль после нуля).

---------- Post added at 18:40 ---------- Previous post was at 18:29 ----------


По логике работы программы форматирования - этот бит должен сбрасываться, а генератор CRC перезапускаться то ли после каждого перехода бита WM из 0 в 1 при котором в сдвиговом регистре находится байт 0xA1, то ли просто после каждого попадания при записи байта 0xA1 в сдвиговый регистр, если при этом установлен бит 14.

Записав заголовок сектора - программа форматирования ждёт установки бита 14, чтобы была выполнена запись CRC, потом без единого перехода в режим чтения - пишет промежуток, маркер данных, данные и затем повторно ожидает записи CRC:



5552$: CALL 7614$ ; Запись GAP, синхрозоны и маркера заголовка
5556$: TSTB @R4 ; Контроллер готов к приему?
BPL 5556$ ; Нет
MOV 14(R3),@R5 ; Записать дорожку/сторону в заголовок
MOV 2(R3),@R4 ; Выключить запись маркера
5572$: TSTB @R4 ; Контроллер готов к приему?
BPL 5572$ ; Нет
MOV R2,@R5 ; Записать длину/номер сектора в заголовок
MOV #13,R0 ; R0 = длина GAP2
MOV #175641,16(R3) ; Будет записываться маркер данных 0xFBA1
5612$: BIT #40000,@R4 ; CRC заголовка записана?
BEQ 5612$ ; Нет
CALL 7614$ ; Запись GAP2, синхрозоны и маркера данных
MOV R1,R0 ; R0 = размер сектора в словах
5626$: TSTB @R4 ; Контроллер готов к приему?
BPL 5626$ ; Нет
MOV 34(R3),@R5 ; Записать первое слово заполнителя
MOV 2(R3),@R4 ; Выключить запись маркера
DEC R0 ; Уменьшить число записываемых слов
5644$: TSTB @R4 ; Контроллер готов к приему?
BPL 5644$ ; Нет
MOV 34(R3),@R5 ; Записать заполнитель в цикле
SOB R0,5644$
INC R2 ; Увеличить номер сектора
MOVB 62(R3),R0 ; R0 = размер GAP3 в словах
MOV #177241,16(R3) ; Далее записывается маркер заголовка 0xFEA1
5672$: BIT #40000,@R4 ; CRC зоны данных записана?
BEQ 5672$ ; Нет


Понятно, что в ходе записи маркера данных - бит 14 сбросился, а генератор CRC перезапустился, но обязательно ли для этого устанавливать бит WM и сработает ли такой "перезапуск" до записи CRC - не понятно.
Битов 14 целых два - один для режима чтения, другой для записи. И отображается в регистр состояния тот, в каком режиме находится контроллер. Vslav уже вроде писал, что расчет CRC при записи начинается при попадании 0xA1 в сдвиговый регистр, а бит WM нужен, чтобы при записи выполнить необходимые пропуски синхроимпульсов.
По поводу комментариев, они не всегда могут быть верные, т.к. когда я разбирал работу ПЗУ УКНЦ, а далее и фирмваре КМД ДВК, то писал так, как понимал на тот момент работу 1801ВП1-128, документации не было, и все приходилось додумывать самому. Кстати по адресу 5300 правильный комментарий, о том, что CRC начала записываться.

Patron
22.12.2013, 19:08
По поводу комментариев, они не всегда могут быть верныеДело не в комментариях.

Я сейчас прогоняю форматирование на эмуляторе ВП1-128 и получается, что если бит CRC остался установленным после записи заголовка сектора - у CRC данных просто нет шанса записаться на диск ( бит CRC уже стоит и программа форматирования не ждёт, когда он установится, а сразу начинает писать следующий промежуток ).

Кроме того - если после записи заголовка сектора генератор CRC не перезапустится на маркере данных - у блока данных неоткуда взяться корректной CRC.

Ведь блок данных при форматировании пишется в одной операции записи с заголовком сектора. Пропускается одно требование, чтобы записать CRC заголовка - и запись байтов формата дорожки немедленно продолжается.

Получается, что если установлен бит CRCw и в сдвиговом регистре находится байт 0xA1 - бит CRCw должен сбрасываться, а генератор CRC - перезапускаться.

Alex_K
22.12.2013, 19:30
Я сейчас прогоняю форматирование на эмуляторе ВП1-128 и получается, что если бит CRC остался установленным после записи заголовка сектора - у CRC данных просто нет шанса записаться на диск ( бит CRC уже стоит и программа форматирования не ждёт, когда он установится, а сразу начинает писать следующий промежуток ).
Бит 14 устанавливается в начале записи CRC. Пишется два байта из регистров CRC, из регистра записываемых данных ничего не копируется. При установке бита 14 начинается запись CRC, бит 7 также установлен, т.к. требование было выполнено, но не удовлетворено. Сразу же после установки бита 14 в регистр данных записи надо скопировать новые данные. Они во время записи CRC никуда не уходят, бит 7 сбрасывается при записи новых данных. Сбросится и бит 14, т.к. сбросился бит 7 и должен сняться сигнал LATCH_TR, но об этом лучше скажет Vslav. После того как CRC записалась, записывается младший байт данных, а потом, при копировании старшего байта в сдвиговый регистр, устанавливается бит 7, приглашая записать новые данные.


Кроме того - если после записи заголовка сектора генератор CRC не перезапустится на маркере данных - у блока данных неоткуда взяться корректной CRC.
Ведь блок данных при форматировании пишется в одной операции записи с заголовком сектора. Пропускается одно требование, чтобы записать CRC заголовка - и запись байтов формата дорожки немедленно продолжается.
Почему не перезапустится - перезапустится, и далее будет считать CRC заголовка данных плюс данные. [/QUOTE]


Получается, что если установлен бит CRCw и в сдвиговом регистре находится байт 0xA1 - бит CRCw сбрасывается, а генератор CRC перезапускается.
Во время записи бит 14 должен сбрасываться после сброса бита 7.

Patron
22.12.2013, 19:50
Почему не перезапустится - перезапуститсяА какие условия перезапуска генератора CRC при записи..

Почему генератор CRC не перезапускается при записи второго и третьго байтов заголовка ?

Vslav
22.12.2013, 21:55
Извиняюсь, меня тут работой привалило...


Насколько немедленно:

Немедленно - прекращается запись на текущем бите. Если писались данные, то бросит писать данные. Если писалась CRC, то бросит писать CRC. Как только прошло чтение - то LAST_WR немедленно становится высоким - сразу при чтении процессором 177132. Ну и MODE_nR/W становитс низким (не мгновенно, синхронизируется в какой-то фазе битового интервала). Все, nWRE сразу высокий, даже если бы оно продолжило выдачу данных - дисковод запись блокирует. Далее я ему подсунул маркер, и типа поток данных идет, но требование на чтение не выставляется, сумма не обнуляется, в-общем, читать данные не получится.



В описании КМД этот бит называют GOR:

У меня текстовый файлик .txt, я по нему работал, там Gdr, видимо человек набирал с плохой копии.



И сигнал IND никак на это не влияет ?

Элементы N21, N22, N23 представляют собой синхронный D-триггер (вход D - LAST_WR), который записывает сигнал с этого входа по ниспадающему фронту тактового сигнала (выход H15 4-9), и общий асинхронный сброс INIT_073. Поэтому сигнал IND - он максимум может сформировать лишний фронт записи в этот триггер, но повлиять на режим R/W - никак. Я долго не мог поверить что IND никуда больше не идет, тщательно изучал фото, всю цепь перепроверил. В итоге полагаю фактическое НЕ обрабатывание сигнала индекса - косяк 128-ой. Ну или индекс просто банально блокирует смену режима. При высоком уровне на ноге IND микросхема работает, при низком - смена режима блокирована. В-общем, про сигнал индекса можно забыть.



А если не обращаясь к регистру данных - установить в CSR бит GOR, что-нибудь в такой ситуации изменится ?

К регистру данных надо обращаться обязательно - иначе LAST_WR/MODE_R/W правильно не перекинется. Ну или INIT внешний дать.



Программа форматирования пишет на диск четыре байта: 0xA1,0xA1,0xA1,0xFE с установленным в CSR битом WM. В каких байтах при этом происходит пропуск "синхробита":

Во всех байтах маркера A1. Ессно, при чтении пропущенный импульс никак не повлияет на читаемое значение (потому что 128-ая анализирует середину интервала - был имульс в середине - бит данных 1, не было - бит данных 0), Байт FE пишется нормально, без пропусков, потому что все его биты единичные и кодируются имульсом в середине МФМ интервала. Кстати, после FE я начал писать 0x30 - там тоже импульс выкушен, но в 5-ой позиции - не там где в A1. Но на читаемые данные это не повлияет - 128-ая прочтет все правильно, даже несмотря на пропущенный импульс.



По логике работы программы форматирования

Сначала пишем первую порцию, потом игнорим требование записи - начинает записываться CRC, при этом в регистр суммы вдвигаются единицы, сигнал CRC_IN0 - активен. После записи всей CRC регистр приобретет значение 0xFFFF и поэтому после окончания записи CRC будет активен признак CRC_VALID и мы увидим этот флаг в CSR при чтении 177130. Если мы запишем маркер в 177132, то начнется процесс записи нового сектора.



Записав заголовок сектора - программа форматирования ждёт установки бита 14, чтобы была выполнена запись CRC, потом без единого перехода в режим чтения - пишет промежуток, маркер данных, данные и затем повторно ожидает записи CRC:

Именно так.



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

Бит WM на перезапуск не влияет - он управляет только работой МФМ-кодировщика.

---------- Post added at 19:55 ---------- Previous post was at 19:49 ----------



Бит 14 устанавливается в начале записи CRC.

Нет, бит 14 устанавливается ПОСЛЕ того как СRC физически выведена на выходы DOx, то есть записана на диск. Микросхема остается в режиме записи и продолжает писать нули (инвертированный регистр суммы, в котором FF-ы). Если записать маркер в регистр данных - начнется запись новой последовательности, бит WM на этот процесс не влияет, только на кодировщик МФМ. Да, и запись нового маркера сбрасывает бит 14, не мгновенно, а как начнется запись маркера на диск.

Patron
22.12.2013, 23:00
Далее я ему подсунул маркер, и типа поток данных идет, но требование на чтение не выставляется, сумма не обнуляется, в-общем, читать данные не получится.Значит, любое чтение регистра данных после записи и до установки 8-го бита - блокирует чтение.

А повторная запись в регистр данных приведёт к восстановлению нормальной работы или последующая запись также блокируется ?

Alex_K
22.12.2013, 23:02
Нет, бит 14 устанавливается ПОСЛЕ того как СRC физически выведена на выходы DOx, то есть записана на диск. Микросхема остается в режиме записи и продолжает писать нули (инвертированный регистр суммы, в котором FF-ы). Если записать маркер в регистр данных - начнется запись новой последовательности, бит WM на этот процесс не влияет, только на кодировщик МФМ. Да, и запись нового маркера сбрасывает бит 14, не мгновенно, а как начнется запись маркера на диск.
А вот здесь я не согласен. При записи сигнал CSR_CRC формируется из сигналов MODE_nR/W и nLATCH_TR. Если бы бит 14 выставлялся бы после физической записи CRC на диск, то был бы разрыв между CRC и последующими данными. А ведь данные в регистр записи заносятся после установки этого бита, а там исполняется несколько команд.
А вот сигнал MODE_R/nW и защелкнутый CRC_VALID формируют бит 14 при чтении, соответственно он формируется уже после физического чтения CRC с диска.

Vslav
22.12.2013, 23:18
А вот здесь я не согласен. При записи сигнал CSR_CRC формируется из сигналов MODE_nR/W и nLATCH_TR. Если бы бит 14

Да, я ошибся - перепутал на диаграмме при моделировании CSR_CRC и CRC_VALID (не туда посмотрел когда писал пост). CSR_CRC устанавливается в момент начала записи контрольной суммы на диск.

Patron
22.12.2013, 23:38
К регистру данных надо обращаться обязательно - иначе LAST_WR/MODE_R/W правильно не перекинется. Ну или INIT внешний дать.Просто интересно, как идёт запись после того как в CSR:

1. Установлен и не сброшен 8-й бит
2. Установлен и сброшен 8-й бит

в случаях, когда:

1. дальнейшая запись в регистр данных после установки 8-го бита не производится
2. дальнейшая запись в регистр данных после установки 8-го бита продолжается по тебованию



После записи всей CRC регистр приобретет значение 0xFFFF и поэтому после окончания записи CRC будет активен признак CRC_VALID и мы увидим этот флаг в CSR при чтении 177130. Если мы запишем маркер в 177132, то начнется процесс записи нового сектора.Фокус в том, что после записи CRC заголовка сектора - нужно записать промежуток, который не учитывается в CRC блока данных, потом записать маркер блока данных с последующими данными - и в этот момент генератор CRC должен перезапуститься.

У генератора CRC есть только один шанс отличить первый байт маркера от второго - если бит CRCw сбрасывается только при записи байта маркера. Тогда запись маркера при установленном бите CRCw должна перезапускать генератор CRC.

Но тогда по INIT бит CRCw должен устанавливаться, а не сбрасываться - как иначе определить, что первый байт первого записываемого маркера не является его вторым байтом..

Vslav
22.12.2013, 23:46
Исправленое описание процесса записи:

- старт записи начинается записью данных в регистр 177132, при этом записываемые данные пишутся на диск, по новому требованию можно записывать произвольное количество слов данных
- при первой записи A1 в регистр данных 177132 и начале вывода этого A1 сбрасывается регистр CRC
- при необслуживании требования записи начинается вывод вычисленной CRC на диск
- при начале записи CRC на диск выставляется бит CSR_CRC (14-ый)
- после выставленного CSR_CRC можно обслужить требование записи
- можно писать в 177132 любые данные и они будут выводится на диск, но только при обнаружении записи первого нового маркера A1 опять сбросится CRC
- цикл можно повторить нужное число раз



Просто интересно, как идёт запись после того как в CSR:
1. Установлен и не сброшен 8-й бит
2. Установлен и сброшен 8-й бит

Как повезет - сигнал nGDR стробируется на триггере G35 импульсами входных данных, если импульсов нет, то бит GOR никак не влияет - запись промоделировалась штатно. А вот если сработает - то все встанет - будут активны RDINIT0 и RDINIT1 - остановится счетчик битов, не будет выставлятся требование и прочее - запись просто не пойдет

Patron
22.12.2013, 23:54
Исправленое описание процесса записи:

- при первой записи A1 в регистр данных 177132 и начале вывода этого A1 сбрасывается регистр CRC
- можно писать в 177132 любые данные и они будут выводится на диск, но только при обнаружении записи первого нового маркера A1 опять сбросится CRCНо из этого прямо следует, что бит CRCw должен устанавливаться по INIT - иначе невозможно отличить запись первого байта 0xA1 самого первого маркера от записи второго байта 0xA1 того же маркера.

Alex_K
23.12.2013, 00:13
Но из этого прямо следует, что бит CRCw должен устанавливаться по INIT - иначе невозможно отличить запись первого байта 0xA1 самого первого маркера от записи второго байта 0xA1 того же маркера.
Не устанавливается он по INIT, а по INIT и установке GOR сбрасывается. А для того, чтобы отличить первый байт от второго, есть еще куча триггеров, и как я понял, за это отвечают сигналы RDR_STB, FIN_STB и nMARK_A1. Там на мелочи есть два триггера и целая куча логики. Вот все это и формирует сигнал nCRC_RST.

Patron
23.12.2013, 00:43
Не устанавливается он по INITПридётся добавлять в эмулятор ВП1-128 ещё один флаг, который будет заниматься только тем, что отличать самый первый байт 0xA1, записываемый после INIT и GOR, от второго.

Все перезапуски CRC происходят, когда записывается первый байт 0xA1 при установленном CRCw - поэтому там дополнительные флаги не нужны.

Vslav
23.12.2013, 01:18
Все перезапуски CRC происходят, когда записывается первый байт 0xA1 при установленном CRCw - поэтому там дополнительные флаги не нужны.

Нет, Alex_K правильно написал - есть безымянный триггер плюс одновибратор на G37, H37, H36, I39 - который формирует сигнал CRC_RST. Импульс CSR_RST очень короткий. Как я понял из моделирования (разбирать очень муторно - нарисован это кусок неудачно - не влазило оно в листик, пришлось ногами утаптывать), то схема находится в состоянии ожидания среза на nMARK_A1. Когда обнаруживается срез, то на CRC_RST формируется короткий импульс, и более по новым срезам на nMARK_A1 импульсы не формируются, сумма не обнуляется. Далее заканчивается запись, пропускается требование, записывается сумма, и после записи суммы проскакивает короткий импульс FIN_STB. Этим имульсом снова взводится одновибратор и он снова готов ждать среза nMARK_A1.

Если сектор начали писать, потом бросили - сформируется неудовлетворенное требование и FIN_STB. Если хотите читать - то надо GOR подергать (тоже сформирует FIN_STB).

Patron
23.12.2013, 01:27
есть безымянный триггер плюс одновибраторА при записи бит CRC в регистре статуса сбрасывается при любой записи в регистр данных или только при записи байта 0xA1 ?

Vslav
23.12.2013, 01:46
А при записи бит CRC в регистре статуса сбрасывается при любой записи в регистр данных или только при записи байта 0xA1 ?
Бит 14 (CSR_CRC) формируется мультиплексором на J36 в зависимости от режима чтение-запись. В режиме записи CSR_CRC совпадает с сигналом LATCH_TR. LATCH_TR устанавливается высоким когда есть неудовлетворенное требование, держится высоким в течение записи слова суммы и потом сбрасывается FIN_STB. То есть - бит 14 в CSR сбросится независимо от обращений к 177132.

Patron
23.12.2013, 01:56
То есть - бит 14 в CSR сбросится независимо от обращений к 177132.В смысле - этот бит установлен только 64 мкс, пока пишется контрольная сумма..

А если в регистр данных записи больше нет и на диск каждый раз пишется инвертированное содержимое сдвигового регистра контрольной суммы, то что при этом происходит с битом 14 ?

Vslav
23.12.2013, 02:42
В смысле - этот бит установлен только 64 мкс, пока пишется контрольная сумма..

А если в регистр данных записи больше нет и на диск каждый раз пишется инвертированное содержимое сдвигового регистра контрольной суммы, то что при этом происходит с битом 14 ?
Остается в нуле. В приложении картинка для такой ситуации:



//
// *** Write data model start ***
//
qbus_write(16'O177130, 16'H0300);
qbus_write(16'O177132, 16'H0000);
qbus_waitr();
qbus_write(16'O177132, 16'H0000);
qbus_waitr();
qbus_write(16'O177132, 16'HA1A1);
qbus_waitr();
qbus_write(16'O177132, 16'HFEA1);
qbus_waitr();
qbus_write(16'O177132, 16'H3130);
qbus_waitr();
qbus_write(16'O177132, 16'H3332);
qbus_waitr();

#40000
qbus_waitr();
qbus_write(16'O177132, 16'H0000);
qbus_waitr();
qbus_write(16'O177132, 16'HA1A1);
qbus_waitr();
qbus_write(16'O177132, 16'HFEA1);
qbus_waitr();

Patron
23.12.2013, 13:46
И ещё вопрос - может ли безымянный триггер ожидания байта 0xA1 сброситься до записи контрольной суммы ?

Например, при чтении из регистра данных или при установке бита GOR.

Vslav
24.12.2013, 01:06
И ещё вопрос - может ли безымянный триггер ожидания байта 0xA1 сброситься до записи контрольной суммы ?
Например, при чтении из регистра данных или при установке бита GOR.
Он сбрасывается или по записи суммы, или по GOR. Если шла запись на диск и тут прочитали вдруг регистр данных, то переходим в режим "псевдочтения", триггер остается установленным и чтение нормально не работает. Чтобы начать читать - GOR надо. Чтобы начать писать - тоже GOR надо сначала, потому что сумма не записывалась и триггер остался установленным, новая запись не начинается (моделирование подтвердило).

Patron
24.12.2013, 16:35
Чтобы начать писать - тоже GOR надо сначала, потому что сумма не записывалась и триггер остался установленным, новая запись не начинается (моделирование подтвердило).Но если режим записи ВП1-128 находится в состоянии NOT A1_WRITTEN ( т.е. до записи 0xA1 или после записи контрольной суммы ) - то чтение регистра данных переводит ВП1-128 в какой режим:

1. В режим ожидания, выход из которого возможен как в режим поиска маркера ( по GOR ), так и в режим записи ( при записи в регистр данных ) ?

2. Сразу в режим поиска маркера ?

Vslav
24.12.2013, 18:10
Но если режим записи ВП1-128 находится в состоянии NOT A1_WRITTEN ( т.е. до записи 0xA1 или после записи контрольной суммы ) - то чтение регистра данных переводит ВП1-128 в какой режим:

Сразу в режим поиска маркера, триггер то активен, придет маркер - выработается CRC_RST и начнется чтение.

Patron
24.12.2013, 18:53
Сразу в режим поиска маркера(...) Как выяснилось позже - переходит в тот режим чтения ( поиск маркера или обычное чтение ) который имел место до начала записи.


Как повезет - сигнал nGDR стробируется на триггере G35 импульсами входных данных, если импульсов нет, то бит GOR никак не влияет - запись промоделировалась штатно. А вот если сработает - то все встанет - будут активны RDINIT0 и RDINIT1 - остановится счетчик битов, не будет выставлятся требование и прочее - запись просто не пойдетА откуда берутся импульсы входных данных в режиме записи ?

Ведь в режиме записи ( насколько я понимаю ) дисковод не выдаёт сигнал на линию RDATA.

---------- Post added at 17:53 ---------- Previous post was at 17:38 ----------

Значит, если начать запись и затем установить бит GOR - запись не зависнет, но сбросится признак A1_WRITTEN. Так ?

Vslav
24.12.2013, 22:07
А откуда берутся импульсы входных данных в режиме записи ?
Ведь в режиме записи ( насколько я понимаю ) дисковод не выдаёт сигнал на линию RDATA.

Зависит от дисковода и, в общем случае от схемы контроллера дисковода.



Значит, если начать запись и затем установить бит GOR - запись не зависнет, но сбросится признак A1_WRITTEN. Так ?

Если GOR останется установленным, то запись зависнет. Признак A1W cбросится.

Patron
24.12.2013, 22:27
Зависит от дисковода и, в общем случае от схемы контроллера дисковода.Т.е. у некоторых дисководов в едином конструктиве головки есть отдельная головка чтения и отдельная головка записи, причём при записи головка чтения читает старые данные за мгновение до того, как они перезаписываются головкой записи..

Ведь если у дисковода только одна общая головка чтения/записи и она пишет данные - данным чтения взяться физически неоткуда.


Если GOR останется установленным, то запись зависнет. Признак A1W cбросится.И даже если запись при этом ведётся на неформатированную дорожку - запись всё равно зависнет ?

Vslav
24.12.2013, 23:00
Т.е. у некоторых дисководов в едином конструктиве головки есть отдельная головка чтения и отдельная головка записи, причём при записи головка чтения читает старые данные за мгновение до того, как они перезаписываются головкой записи..

Ведь если у дисковода только одна общая головка чтения/записи и она пишет данные - данным чтения взяться физически неоткуда.

Я с конструкцией приводов знаком только в общих чертах и просто предположил что может быть всякое - потому что приводов разнообразных очень много. Блокируется ли дисководами канал чтения при активной записи и что они в этот момент выдают на линии читаемых данных - мне точно неизвестно. Надо иметь ввиду что просто так GOR дернуть мало - в этот момент должны идти импульсы читаемых данных. Если нет импульсов, то GOR далеко внутрь схемы не проходит. INIT имеет более радикальное воздействие.


И даже если запись при этом ведётся на неформатированную дорожку - запись всё равно зависнет ?

Если не будет импульсов RDATA то может и не зависнет. А есть эти импульсы или нет - в общем случае неизвестно, зависит от внешних факторов - схемы контроллера, схемы и устройства дисковода, и банально от помех.

Patron
24.12.2013, 23:44
Если не будет импульсов RDATA то может и не зависнет.Получается, что если в режиме записи установить и сбросить бит GOR - это без побочных эффектов приведёт к переходу режима записи в "начальное" состояние ( до записи первого байта 0xA1 ).

Vslav
24.12.2013, 23:51
Записываемый бит GOR попадает безусловно сначала в триггер G36 и на выходе формируется два сигнала CSR_GDR и инверсия ~CSR_GDR. Эти сигналы поступают исключительно только на триггер G35, который вырабатывает сигнал ~GDR (активный уровень низкий). Этот триггер G35 тактируется импульсами RDATA, нет импульсов - состояние не меняется, GDR не отрабатывает. Также триггер сбрасывается (~GDR становится высоким) по INIT. То есть можно деактивировать внутренний GDR внешним сбросом.

Далее этот ~GDR идет исключительно на L21 (вторая страница), где уже формируются широкорасходящиеся по схеме активные высокие RDINIT0 и RDINIT1. RDINIT0 формирует в том числе высокий FIN_STB и перевзводит триггер A1_WRITTEN, начинаем ждать маркер.

Также RDINITx сбрасывает PLL, блокирует выработку стробов и удерживает в нуле счетчик битов. Пока активен внутренний ~GDR - ничего не работает, ни чтение, ни запись.


Но вероятнее всего, что вариантов только два:
1. Сигнал RDATA блокируется сигналом WGATE.
2. При установленном сигнале WGATE сигнал RDATA копирует сигнал WDATA.

Стандарт на интерфейс дисковода надо смотреть, но знаю какой именно.

Patron
24.12.2013, 23:53
Стандарт на интерфейс дисковода надо смотретьПохоже, я уже нашёл нужное место:

http://s6.hostingkartinok.com/uploads/images/2013/12/e3f1471864d587008aa8f48c97aba784.png

Vslav
25.12.2013, 00:00
Похоже, я уже нашёл нужное место:

Это откуда цитата?
Получается что если импульсов RDATA не будет, то установка GOR при записи никак не влияет на работу схемы. Надо перейти в чтение, дождаться RDATA и только тогда сработает GOR.

Patron
25.12.2013, 00:14
Это откуда цитата?Отсюда: FD-235HF-C891.pdf (http://www.google.ru/url?q=http://www.msc-ge.com/download/itmain/datasheets/teac/FD-235HF-C891.pdf&sa=U&ei=GOi5UuW6Acfk4QTwi4CIDQ&ved=0CB8QFjAA&usg=AFQjCNFFHArHmGEb-iE9yWrqUtBCmaCAIw)

А вот цитата отсюда: FD55_Spec.pdf (http://www.google.ru/url?q=http://bitsavers.trailing-edge.com/pdf/teac/FD55_Spec.pdf&sa=U&ei=6um5Uoz2DMOG4AS164CYBA&ved=0CB8QFjAA&usg=AFQjCNHSsOk6RAo7jFAEgpOnB4Xj22RLTA)

http://s4.hostingkartinok.com/uploads/images/2013/12/22bd8bd4388c30316d8f453a73d1ef5b.png




Получается что если импульсов RDATA не будет, то установка GOR при записи никак не влияет на работу схемы. Надо перейти в чтение, дождаться RDATA и только тогда сработает GOR.Но триггер ожидания записи байта 0xA1 должен сброситься при установке бита GOR в режиме записи или нет ?

Vslav
25.12.2013, 00:24
Но триггер ожидания записи байта 0xA1 должен сброситься при установке бита GOR в режиме записи или нет ?

Ну я же подробно расписал как работает GOR. Будут импульсы RDATA - будет внутренний GDR, RDINITx, FIN_STB. Вот FIN_STB и приведет триггер в исходное состояние ожидания чтения/записи A1. Но, судя по цитатам из описания дисководов, импульсов RDATA в режиме записи нет, то GOR будет полностью проигнорирован микросхемой.

Patron
26.12.2013, 18:41
Судя по программе форматирования - любое чтение регистра данных немедленно обрывает запись, поэтому при записи сектора, после появления в регистре статуса флага записи контрольной суммы - в регистр данных пишется слово 0x4E4E и только после выставления требования - выполняется чтение регистра данных.

Patron
26.12.2013, 21:45
В процессе эмуляции КМД выяснилось, что если режим записи ВП1-128 находится в состоянии NOT A1_WRITTEN ( т.е. до записи 0xA1 или после записи контрольной суммы ) - то чтение регистра данных переводит ВП1-128 в режим предварительного чтения - не выровненного ни на границу байта, ни на границу бита. Поэтому, в данном режиме можно только искать синхрозону. При чтении в районе синхрозоны - слово читаемых данных будет иметь значение 0x0000 или 0xFFFF.

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

Alex_K
26.12.2013, 22:46
В процессе эмуляции КМД выяснилось, что если режим записи ВП1-128 находится в состоянии NOT A1_WRITTEN ( т.е. до записи 0xA1 или после записи контрольной суммы ) - то чтение регистра данных переводит ВП1-128 в режим предварительного чтения - не выравненного ни на границу байта, ни на границу бита. Поэтому, в данном режиме можно только искать синхрозону. При чтении в районе синхрозоны - слово читаемых данных будет иметь значение 0x0000 или 0xFFFF.
Перевод осуществляется в любом режиме, не зависит от того записали 0xA1 или CRC, или не записали. На дискете в реальности вся дорожка аккуратно выровнена только после форматирования, а стоит записать сектора, то все и пойдет наперекосяк. Потому при поиске синхрозоны и проверяют и на 0x0000, и на 0xFFFF. Но так будет читаться только если контроллер не находится в подрежиме поиска маркера. Если маркер еще не найден, то вся информация с дискеты, проходящая через сдвиговый регистр, не попадает в регистр данных.

Patron
27.12.2013, 02:55
Перевод осуществляется в любом режиме, не зависит от того записали 0xA1 или CRC, или не записали.
Немедленно - прекращается запись на текущем бите. .. Далее я ему подсунул маркер, и типа поток данных идет, но требование на чтение не выставляется, сумма не обнуляется, в-общем, читать данные не получится.Получается, что в режиме предварительного чтения содержимое регистра данных обновляется, но требование не выставляется.

Код прошивки -255 это подтверждает:



; Пропуск не нулей при неактивном ИНДЕКСЕ
6704$: MOV #51010,R1 ; R1 = длина дорожки в цикле
6710$: TST @R4 ; Линия ИНДЕКС активна?
BMI 6762$ ; Да
MOV @R5,R0 ; Считанное слово равно нулю?
BEQ 7014$ ; Да
INC R0 ; Считанное слово равно 177777?
BEQ 7014$ ; Да
SOB R1,6710$ ; Цикл по пропуску не нулей
BR 6666$ ; Нет дискеты - ошибка

; Удостоверение в том, что попали на синхрозону
7014$: MOV #3,32(R3) ; Счетчик для удостоверения
7022$: MOV @R5,R0 ; Считанное слово равно нулю?
BEQ 7032$ ; Да
INC R0 ; Считанное слово равно 177777?
BNE 7066$ ; Нет - не синхрозона
7032$: DEC 32(R3) ; Уменьшить счетчик
BNE 7022$ ; Продолжаем дальше

Patron
27.12.2013, 16:12
Ещё вопрос - чем отличается поведение ВП1-128 при установленном сигнале защиты записи ?

Alex_K
27.12.2013, 16:38
Получается, что в режиме предварительного чтения содержимое регистра данных обновляется, но требование не выставляется.
А что это за режим предварительного чтения? Есть только режим чтения и его подрежим поиска маркера. Так вот в режиме поиска маркера требование не выставляется, но регистр данных чтения не обновляется, данные идут только через сдвиговый регистр.
А коду прошивки не всегда стоит доверять, авторы прошивки работы с дисководом (и на УКНЦ, и на КМД) судя по всему тоже не все знали. Как можно по такой скудной документации написать код, мне непонятно.

Patron
27.12.2013, 17:43
Есть только режим чтения и его подрежим поиска маркера. Так вот в режиме поиска маркера требование не выставляется, но регистр данных чтения не обновляетсяТогда какой режим устанавливается в этом случае:
Немедленно - прекращается запись на текущем бите. Если писались данные, то бросит писать данные. Если писалась CRC, то бросит писать CRC. Как только прошло чтение - то LAST_WR немедленно становится высоким - сразу при чтении процессором 177132. Ну и MODE_nR/W становитс низким (не мгновенно, синхронизируется в какой-то фазе битового интервала). Все, nWRE сразу высокий, даже если бы оно продолжило выдачу данных - дисковод запись блокирует. Далее я ему подсунул маркер, и типа поток данных идет, но требование на чтение не выставляется, сумма не обнуляется, в-общем, читать данные не получится.Если при чтении регистра данных в режиме записи - устанавливается один и тот же режим чтения, незавивисимо от состояния записи A1_WRITTEN - то в этом режиме чтения данные должны выдаваться, но требование выставляться не должно.

В любом случае устанавливается третий режим чтения, вопрос лишь в том - один и тот же ли этот режим при любом чтении в ходе записи или устанавливающийся режим зависит от фазы прерванной записи по состоянию A1_WRITTEN ( что менее вероятно ).

---------- Post added at 16:43 ---------- Previous post was at 16:04 ----------

Техническая разница между режимами предварительного чтения и нормального чтения в том, что предварительное чтение не выровнено даже по границе бита. Алгоритмическая же разница ( насколько я понимаю ) в том, что в режиме предварительного чтения не выставляется требование. Это вполне логично - при пропуске требования надо проверять контрольную сумму, но о какой контрольной сумме может идти речь, когда заранее известно, что чтение не выровнено по границе байтов.

Alex_K
27.12.2013, 18:43
Техническая разница между режимами предварительного чтения и нормального чтения в том, что предварительное чтение не выровнено даже по границе бита. Алгоритмическая же разница ( насколько я понимаю ) в том, что в режиме предварительного чтения не выставляется требование. Это вполне логично - при пропуске требования надо проверять контрольную сумму, но о какой контрольной сумме может идти речь, когда заранее известно, что чтение не выровнено по границе байтов.
Ну нету в контроллере никакого режима предварительного чтения. Если уж он начал читать, то читает. Хотя по схеме есть один тонкий момент, что если установился признак LATCH_TR, то сбросить его может только сигнал FIN_STB, а при активном LATCH_TR признак требования не устанавливается. Надо посмотреть повнимательнее схему, проанализировать.
Приеду домой, осмотрю и напишу.

Patron
27.12.2013, 19:13
Ну нету в контроллере никакого режима предварительного чтения.Это режим обычного чтения, при котором не устанавливается требование. Режим этот был обнаружен экспериментально.

Если игнорировать результаты экспериментов и при невыровненном чтении требование устанавливать - все прошивки работают точно так же, потому что в режиме предварительного чтения никогда не проверяют бит требования.

Но если при невыровненном чтении действовать в соответствии с экспериментально наблюдаемыми результатами и требование НЕ УСТАНАВЛИВАТЬ - то все прошивки полностью сохраняют работоспособность именно потому, что в режиме предварительного чтения никогда не проверяют бит требования.

Alex_K
27.12.2013, 20:07
Это режим обычного чтения, при котором не устанавливается требование. Режим этот был обнаружен экспериментально.
В результате каких экспериментов?

Если игнорировать результаты экспериментов и при невыровненном чтении требование устанавливать - все прошивки работают точно так же, потому что в режиме предварительного чтения никогда не проверяют бит требования.
Не проверяют они его потому, что неизвестно состояние контроллера. Он может находится в режиме поиска маркера, и пока он его не найдет, то и чтение данных не начнется. Есть еще момент - бит требования устанавливается только после чтения двух байтов, а ведь сдвиговый регистр байтовый. Поэтому таким чтением можно прочесть уже следующий байт без установки бита требования. Представим записано на диске 1 2 3 4 5 6 ... Сначала в регистре данных чтения прочтется <1 2> и выставится бит требования, потом будет <3 2>, но бита требования не будет стоять, а уже когда окажется <3 4>, то установится бит требования. Потому в программах поиска синхрозоны и не проверяют бит требования, чтобы не подвиснуть на долгое время.
А если контроллер перешел в режим чтения, то он аккуратно будет нарезать данные каждые 64 мкс, при присутствии сигналов на входе в соответствии с подстройкой ФАПЧ, а если сигнала нет, то будут поступать нули каждые 64 мкс.

А так надо знать как формируются сигналы STB_**, зная их можно точно сказать как работает и чтение и запись.

Patron
27.12.2013, 21:39
В результате каких экспериментов?Вот таких:
требование на чтение не выставляется
Не проверяют они его потому, что неизвестно состояние контроллера. Он может находится в режиме поиска маркера, и пока он его не найдет, то и чтение данных не начнется.В режиме поиска маркера данные в регистр данных не передаются, поэтому читать регистр данных при не установленном требовании - совершенно бессмысленно.


Потому в программах поиска синхрозоны и не проверяют бит требования, чтобы не подвиснуть на долгое время.Нет никакой разницы - 21000 раз прочитать бит требования или 21000 раз прочитать регистр данных. Однако, программа поиска синхрозоны именно 21000 раз читает регистр данных, ни разу при этом не проверяя бит требования ( хотя бит индекса в том же самом регистре статуса программа поиска синхрозоны проверяет 21000 раз - перед каждым чтением регистра данных ):



; Пропуск не нулей при неактивном ИНДЕКСЕ
6704$: MOV #21000.,R1 ; R1 = длина дорожки в цикле
6710$: TST @R4 ; Линия ИНДЕКС активна?
BMI 6762$ ; Да
MOV @R5,R0 ; Считанное слово равно нулю?
BEQ 7014$ ; Да
INC R0 ; Считанное слово равно 177777?
BEQ 7014$ ; Да
SOB R1,6710$ ; Цикл по пропуску не нулей
BR 6666$ ; Нет дискеты - ошибка


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

Alex_K
27.12.2013, 21:58
Вот таких:В режиме поиска маркера данные в регистр данных не передаются, поэтому читать регистр данных при не установленном требовании - совершенно бессмысленно.
Об этом я говорил много раз, сохраняется старое значение.

Весьма похоже, что ни одна программа поиска синхрозоны ни в одной прошивке, работающей с ВП1-128 - не проверяет бит требования в режиме предварительного чтения.
Естественно ни одна.

Так я все-таки не понял, что за режим предварительного чтения? Я знаю только два режима чтения: собственно чтение и поиск маркера. Во время поиска маркера неактивен сигнал PLL_RDY, соответственно сигналом BCNT_CLK не крутится 4-хразрядный счетчик битов, не вырабатывается сигнал RDR_STB, соответственно отсюда нет сигналов RDR_HSTB и RDR_LSTB, вся информация со сдвигового регистра не поступает в регистр данных чтения. Но вот как только появился маркер, то активизируется сигнал PLL_RDY, начинает работать счетчик, ну и информация копируется в регистр данных чтения. Бит требования TR устанавливается по сигналу RDR_LSTB при неактивном LATCH_TR. А вот если требование не удовлетворено, то активизируется признак LATCH_TR по сигналу RDR_HSTB. Он остается установленным до следующего сигнала RDR_HSTB, когда выработается FIN_STB и сбросит признак LATCH_TR. Вот если при установке LATCH_TR прочесть регистр данных и сбросить требование, то следующим сигналом RDR_LSTB оно установлено не будет, т.к. активен LATCH_TR.

Patron
27.12.2013, 22:19
Так я все-таки не понял, что за режим предварительного чтения?Это режим, в котором находится ВП1-128, когда выполняется этот код:


; Пропуск не нулей при неактивном ИНДЕКСЕ
6704$: MOV #21000.,R1 ; R1 = длина дорожки в цикле
6710$: TST @R4 ; Линия ИНДЕКС активна?
BMI 6762$ ; Да
MOV @R5,R0 ; Считанное слово равно нулю?
BEQ 7014$ ; Да
INC R0 ; Считанное слово равно 177777?
BEQ 7014$ ; Да
SOB R1,6710$ ; Цикл по пропуску не нулей
BR 6666$ ; Нет дискеты - ошибка
Хорошо видно, что программа поиска синхрозоны 21000 раз читает регистр статуса, но не проверяет там бит требования. Вместо это программа 21000 раз читает регистр данных, каждый раз предполагая, что его значение изменилось без установки бита требования.

Сам я обратил на это внимание только тогда, когда Vslav сообщил, что при переводе ВП1-128 из режима записи в режим чтения путём простого чтения регистра данных - запись мгновенно обрывается на случайном бите и начинается такое чтение, при котором
требование на чтение не выставляется

Alex_K
27.12.2013, 22:35
Хорошо видно, что программа поиска синхрозоны 21000 раз читает регистр статуса, но не проверяет там бит требования. Вместо это программа 21000 раз читает регистр данных, каждый раз предполагая, что его значение изменилось без установки бита требования.

Сам я обратил на это внимание только тогда, когда Vslav сообщил, что при переводе ВП1-128 из режима записи в режим чтения путём простого чтения регистра данных - запись мгновенно обрывается на случайном бите и начинается такое чтение, при котором
Ну то что читает данные, это еще не значит, что бит требования не устанавливается. По аналогии можно читать регистр терминала 177562 без опроса регистра 177560. При этом содержимое 177562 может меняться, но при этом и будет устанавливаться флаг готовности в 177560, просто мы его игнорируем и сбрасываем чтением регистра 177562.
Точно также и у 1801ВП1-128, если активен сигнал PLL_RDY, то сигналом RDR_LSTB при неактивном LATCH_TR будет установлено требование, сбрасывается требование чтением или записью регистра 177132.
А после записи, если переводят в режим чтения, то схема чтения может находится или в режиме чтения, или в режиме поиска маркера. Кстати, в режим чтения переход осуществляется не сразу, а по определенным условиям.

А когда программа 21000 раз читает регистр данных, то это не значит, что 21000 раз разные значения.

Vslav
27.12.2013, 22:49
Ну то что читает данные, это еще не значит, что бит требования не устанавливается.

Не устанавливается, я специально смотрел. Если мы были в режиме записи, и уже была запись маркера и потом вдруг прочитали регистр данных, тем самым перейдя в чтение, то начнется чтение с диска, данные будут помещаться в регистр, но требования не будет. Это как режим поиска маркера, только маркер обнаружен не будет, поскольку триггер A1W общий для режимов чтения/записи и он сброшен нормально не был (сумму то мы не писали).

Alex_K
27.12.2013, 22:57
Не устанавливается, я специально смотрел. Если мы были в режиме записи, и уже была запись маркера и потом вдруг прочитали регистр данных, тем самым перейдя в чтение, то начнется чтение с диска, данные будут помещаться в регистр, но требования не будет. Это как режим поиска маркера, только маркер обнаружен не будет, поскольку триггер A1W общий для режимов чтения/записи и он сброшен нормально не был (сумму то мы не писали).
А на временные диаграммы посмотреть можно? И что это за триггер, какой элемент в схеме? Вроде запись маркера никак особо на работу не влияет.

Patron
27.12.2013, 23:20
А после записи, если переводят в режим чтения, то схема чтения может находится или в режиме чтения, или в режиме поиска маркера.Если при эмуляции ВП1-128 сделать так, что чтение регистра данных при записи переводит ВП1-128 в режим поиска маркера - дорожка начинает писаться за 10 оборотов вместо одного и программа TESTMY.SAV сообщает, что контроллер неисправен.


Не устанавливается, я специально смотрел. Если мы были в режиме записи, и уже была запись маркера и потом вдруг прочитали регистр данных, тем самым перейдя в чтение, то начнется чтение с диска, данные будут помещаться в регистр, но требования не будет.Надо проверить то же самое, но уже при чтении регистра данных после записи контрольной суммы, записи ещё одного слова в регистр данных и появления требования записи - будет тогда выставляться требование при невыровненном чтении или не будет..

Судя по коду прошивки - требование при чтении тогда тоже не выставляется.

Vslav
27.12.2013, 23:42
А на временные диаграммы посмотреть можно? И что это за триггер, какой элемент в схеме? Вроде запись маркера никак особо на работу не влияет.
Про триггер написано в этом сообщении (http://zx-pk.ru/showpost.php?p=655065&postcount=143).
Диаграмма моделирования чтения регистра данных без пропуска требования в аттаче.
P.S. Было бы хорошо если кто-нибудь еще поставил Quartus+ModelSim, проект 128-ой для Quartus открыто выложен, разобраться с основами и запустить моделирование помогу. Потому что много нюансов, я могу где-то и ошибиться.

Patron
27.12.2013, 23:46
И ещё небольшой вопрос - чем отличается поведение ВП1-128 при установленном сигнале защиты записи ?

Alex_K
28.12.2013, 00:06
Если при эмуляции ВП1-128 сделать так, что чтение регистра данных при записи переводит ВП1-128 в режим поиска маркера - дорожка начинает писаться за 10 оборотов вместо одного и программа TESTMY.SAV сообщает, что контроллер неисправен.
Если записываются сплошняком все 10 секторов, то после записи данных, при чтении регистра данных, контроллер переходит именно в режим чтения, т.к. до записи схема чтения находилась не в режиме поиска маркера.
Кстати в УКНЦ, если подряд записываются сектора, то поиск следующей синхрозоны происходит с опросом бита требования. Подпрограмма по адресу 134132.

---------- Post added 28.12.2013 at 00:06 ---------- Previous post was 27.12.2013 at 23:48 ----------


Про триггер написано в этом сообщении (http://zx-pk.ru/showpost.php?p=655065&postcount=143).
Диаграмма моделирования чтения регистра данных без пропуска требования в аттаче.
Про это я читал. Просто при моделировании у Вас схема чтения находилась в режиме поиска маркера. Это видно, как только перешли в режим чтения, то сразу же кончились импульсы BCNT_CLK. Для того, чтобы перейти в режим чтения, надо дать маркер 0xA1 именно с пропущенным синхроимпульсом, ну и чтоб он совпал по фазе. А вот схема для сброса CRC останется взведенной и регистры CRC не очистятся, это факт, считаться будет полный бред и в итоге контрольная сумма не сойдется.

Patron
28.12.2013, 00:14
Кстати в УКНЦ, если подряд записываются сектора, то поиск следующей синхрозоны происходит с опросом бита требования. Подпрограмма по адресу 134132.Вот программа поиска синхрозоны в ПЗУ УКНЦ:

132656$:MOV #4,R1
CMPB #5,23301 ; Формат 1024 байта в секторе ?
BNE 132702$ ; Нет
TST @R4 ; Присутствует линия индекс ?
BPL 132702$ ; Нет
MOV #36,R1
132702$:MOV @R5,R0 ; Прочесть слово с дискеты
BEQ 132730$ ; Это нуль
INC R0
BEQ 132730$ ; Это минус один
TSTB @#177710 ; Таймер окончил счет
BPL 132656$ ; Нет
CALL 134242$ ; Сбросить готовность таймера
SOB R2,132656$
BR 133002$ ; Ошибка (не найден межсекторный промежуток)Это практически точная копия программы из прошивки -255 и смысл её именно в том, что в режиме предварительного чтения бит требования не проверяется.

---------- Post added at 23:14 ---------- Previous post was at 23:08 ----------

Интересно найти хотя бы одну прошивку, которая не сможет работать, когда в режиме предварительного чтения ВП1-128 не выставляет требование.

Vslav
28.12.2013, 00:30
Кстати, я тут посмотрел внимательно на этот триггер A1W и выяснил что он только CRC_RST генерирует. А вот за запуск чтения другой триггер отвечает - на A30, который PLL_RDY выдает. Я сейчас немного сместил выдачу маркера на чтение - и начало выставляться требование! То есть при предыдущем моделировании просто оно не распознало маркер (попало на противофазу). Но при этом чтении все равно CRC не сбросилась, поэтому результирующая сумма будет неверная.

В-общем, мне кажется все работает так:
- есть два отдельных триггера - A1W и A30(PLL_RDY)
- триггер A1W устанавливается FIN_STB, сбрасывается при обнаружении A1 в сдвиговом регистре, в момент перехода 1->0 вырабатывает nCRC_RST и обнуляет сумму
- триггер A30(PLL_RDY) сбрасывается GOR и взводится по обнаружении полноценного маркера с пропущенным синхроимпульсом
- запись на диск начинается при записи любого значения в регистр данных
- сброс суммы CRC (обнуление) произойдет только при записи первого A1, и только если триггер A1W установлен. При обнулении CRC триггер A1W уже сброшен, следующие записи A1 и сбросы A1W не обнуляют сумму (нет перехода триггера 1->0).
- чтение регистра данных всегда переводит в режим чтения
- чтение всегда сначала ищет маркер, при обнаружении срабатывает триггер A30/PLL_RDY.
- если PLL_RDY установлен то в режиме чтения будет устанавливаться требование
- режим поиcка маркера - только при сброшенном A30. То есть если маркер был найден то новый поиск маркера начнет только после GOR, иначе продолжается чтение, даже при необслуженном требовании. Необслуживание требования при чтении, видимо, имеет одну цель - подсчет суммы и выработку FIN_STB. Потом чтение вполне себе продолжается и даже обнулит сумму если вдруг найдет A1.

---------- Post added at 22:30 ---------- Previous post was at 22:29 ----------



то сразу же кончились импульсы BCNT_CLK. Для того, чтобы перейти в режим чтения, надо дать маркер 0xA1 именно с пропущенным

Ага, я это только сейчас заметил.

Patron
28.12.2013, 00:36
Дальнейшая проверка работы прошивок в режиме предварительного чтения.

Прошивка БК-0011:


.SbTtl Check for Data
20$: Call ChkInd
Bcs 100$
Beq 20$ ;Zero, skip it
Com R0
Beq 20$ ;---"----"-----
30$: Call ChkInd
Bcs 100$
Beq 40$
Com R0
Bne 30$
.SbTtl Real Adress mark Checking
40$: MovB #3,ErrCnt ;Retry Counter
50$: Mov @R5,R0 ;Data = Zero ?
Beq 60$ ;Yes,
Com R0 ;Inverted Zero ?
Bne 20$ ;No
60$: DecB ErrCnt ;Yes, Wait once more
Bne 50$
Call StrtRd ;Set GoR
Mov #20.,R0
70$: TstB @R4 ;Wait for Data ready
Bmi 80$ ;Ready
Sob R0,70$ ;Not Ready, Timeout
Br 20$
Видно, что синхрозона ищется без проверки требования, а сразу после установки GOR - начинается ожидание требования.

Alex_K
28.12.2013, 00:45
P.S. Было бы хорошо если кто-нибудь еще поставил Quartus+ModelSim, проект 128-ой для Quartus открыто выложен, разобраться с основами и запустить моделирование помогу. Потому что много нюансов, я могу где-то и ошибиться.
Это отсюда (http://dl.altera.com/?product=modelsim_ae#tabs-2) качать?

---------- Post added at 00:43 ---------- Previous post was at 00:37 ----------



- запись на диск начинается при записи любого значения в регистр данных
Вот, как я понял, контроллер переходит в режим записи сразу же. Так как активен режим записи, то импульсы BCNT_CLK идут всегда и счетчик битов всегда работает. Но этот счетчик не сбрасывается, поэтому если он работал ранее в режиме чтения данных, то возможны такие варианты:
- запишется несколько битов из сдвигового регистра (то что было);
- в зависимости от числа счетчика может записаться сначала младший байт, затем старший и выставится требование;
- может записаться только старший байт и выставится требование, младший уже не запишется.

---------- Post added at 00:45 ---------- Previous post was at 00:43 ----------


И ещё небольшой вопрос - чем отличается поведение ВП1-128 при установленном сигнале защиты записи ?
При установленном сигнале WRP с дисковода, на дисковод в режиме записи не подается сигнал WRE, и соответственно он (дисковод) остается в режиме чтения.

Vslav
28.12.2013, 00:46
Это отсюда (http://dl.altera.com/?product=modelsim_ae#tabs-2) качать?

Нет, надо WEB-edition (http://dl.altera.com/?edition=web), он бесплатный.

Alex_K
28.12.2013, 00:53
Нет, надо WEB-edition (http://dl.altera.com/?edition=web), он бесплатный.
Спасибо! Правда вникать я наверное буду долго. А так надо бы прояснить все временные диаграммы сигналов STB_**, как контроллер переключается в режим чтения, ну и тд и тп.

Patron
28.12.2013, 13:11
надо бы прояснить все временные диаграммы сигналов STB_**, как контроллер переключается в режим чтения, ну и тд и тп.Интереснее всего проверить, что происходит при поиске синхрозоны заголовка следующего сектора после записи блока данных предыдущего сектора.

Последовательность при этом следующая:

1. Прочитать регистр данных
2. Установить и сбросить GOR
3. Ждать требование
4. Записать 0xA1A1
5. Ждать флаг CRC
6. Записать 0x4E4E
7. Ждать требование
8. Прочитать регистр данных

В результате ВП1-128 переходит в такое состояние чтения, в котором ни одна из прошивок не проверяет требование. При этом ( например ) УКНЦ, для определения смены слова в регистре данных, вместо того, чтобы проверять требование - использует таймер УКНЦ.

Какой был бы смысл использовать таймер вместо бита требования, чтобы определить момент смены слова в регистре данных, если бы бит требования в режиме предварительного чтения выставлялся как обычно..

Alex_K
28.12.2013, 13:29
В результате ВП1-128 переходит в такое состояние чтения, в котором ни одна из прошивок не проверяет требование. При этом ( например ) УКНЦ, для определения смены слова в регистре данных, вместо того, чтобы проверять требование - использует таймер УКНЦ.

Какой был бы смысл использовать таймер вместо бита требования, чтобы определить момент смены слова в регистре данных, если бы бит требования в режиме предварительного чтения выставлялся как обычно..
Ох, Patron, прицепились вы к этому требованию и придумали какой-то режим предварительного чтения, которого нет. Повторюсь еще раз, что требование не проверяется потому, что неизвестно в каком режиме находится контроллер - поиск маркера (где оно не выставляется до тех пор, пока не будет найден) или режим чтения.
А про использование программируемого таймера в прошивке УКНЦ я Вам сейчас все расскажу. Периферийный процессор в УКНЦ обслуживает кроме дисковода еще эмулятор терминала, который принимает данные по каналу 0, использует сетевой таймер для скроллинга и мигания курсора. Чтобы все это хорошо работало надо чтобы возникали прерывания в нужный момент времени, т.е. нужна система более-менее реального времени. А 1801ВП1-128 как известно не имеет ни режима прерываний, ни ПДП, т.е. чтение данных с дискеты должно идти при полностью запрещенных прерываниях. А вот теперь представьте, что мы прочитали заголовок сектора, а номер сектора не тот, что нам надо. Или прочли маркер данных. Вот здесь, чтобы тупо не читать этот ненужный нам сектор до конца, программа управления дисководом в УКНЦ поступает очень умно. Она программирует таймер на время прохождения сектора, и отдает управление прерванной программе. Когда головка дисковода подходит к концу сектора, то вырабатывается прерывание от программируемого таймера, и программа чтения уже может искать следующий маркер. В КМД ДВК это не надо, и там, если нашли не тот маркер или заголовок, тупо пропускаются все данные.

Patron
28.12.2013, 13:56
требование не проверяется потому, что неизвестно в каком режиме находится контроллер - поиск маркера (где оно не выставляется до тех пор, пока не будет найден) или режим чтения.Т.е. при чтении регистра данных в режиме записи - контроллер всегда переходит в тот режим чтения, который был до этого ( поиск маркера или обычное чтение ).

Когда Vslav проводил эксперимент с чтением регистра данных перед записью контрольной суммы - до начала эксперимента у ВП1-128 был режим поиска маркера, поэтому он и установился в момент чтения регистра данных. Если бы перед началом эксперимента уже был режим обычного чтения, то в ходе эксперимента - после чтения регистра данных установился бы режим обычного чтения.

Alex_K
28.12.2013, 13:57
Последовательность при этом следующая:
1. Прочитать регистр данных
Контроллер переходит в режим чтения, возможно и поиск маркера, в зависимости от состояния триггера PLL_RDY.

2. Установить и сбросить GOR
Если с дисковода поступают данные, то сбросится триггер PLL_RDY и контроллер перейдет в режим поиска маркера.
Если данных с дисковода не поступает, то установка и сброс GOR ничего не меняют.

3. Ждать требование
Контроллер нашел маркер и перешел в режим чтения. В регистре считанных данных находится 0xA1A1. Начинается подсчет CRC. Триггер A1 сброшен.

4. Записать 0xA1A1
А вот это тонкий момент. То что контроллер перейдет в режим записи это точно. Но зависит все от того, что было в счетчике битов. Так что записывать начнет наверное остаток сдвигового регистра, а потом скорее всего только один байт 0XA1. Но так как триггер A1 был сброшен, то CRC не начнет снова считаться, а продолжиться.

5. Ждать флаг CRC
Начнет записываться CRC сосчитанная из того, что прочитали, и того, что записали. Но вот прочитали не только 0xA1A1, но и то, что за ним (несколько бит). Выработается сигнал FIN_STB и взведется триггер A1.

6. Записать 0x4E4E
Запишется в регистр данных записи.

7. Ждать требование
После установки требования уже будет записана CRC и один байт 0x4E, начинает писаться следующий 0x4E.

8. Прочитать регистр данных
Прерывается запись 0x4E, контроллер спустя некоторое время переходит в режим чтения без поиска маркера, именно чтения. Невыровненные данные будут поступать в регистр данных с установкой требования. Так как триггер A1 взведен, то если произойдет чудо и попадется маркер не смещенный по фазе, то сброситься регистр CRC и начнется счет снова. Но это при условии, что регистр считываемых данных будут считывать при установке требования.

Alex_K
28.12.2013, 14:03
Т.е. при чтении регистра данных в режиме записи - контроллер всегда переходит в тот режим чтения, который был до этого ( поиск маркера или обычное чтение ).

Когда Vslav проводил эксперимент с чтением регистра данных перед записью контрольной суммы - до начала эксперимента у ВП1-128 был режим поиска маркера, поэтому он и установился в момент чтения регистра данных. Если бы перед началом эксперимента уже был режим обычного чтения, то в ходе эксперимента - после чтения регистра данных установился бы режим обычного чтения.
Да, здесь я полностью согласен. Единственный тонкий момент, это следить за состоянием триггера A1, чтобы знать в какой момент сбрасывать регистр CRC. А так генератор CRC никогда не прекращает считать. На него все время поступает информация со сдвигового регистра, ну или нули в режиме записи CRC (при установленном признаке LATCH_TR).

Patron
28.12.2013, 14:07
генератор CRC никогда не прекращает считать. На него все время поступает информация со сдвигового регистра, ну или нули в режиме записи CRC (при установленном признаке LATCH_TR).Или всё же единицы..

Ведь на диск пишется инвертированное содержимое сдвигового регистра CRC, а в режиме "холостого хода записи" ( насколько я понял ) - нули пишутся именно на диск.

Alex_K
28.12.2013, 14:20
Или всё же единицы..

Ведь на диск пишется инвертированное содержимое сдвигового регистра CRC, а в режиме "холостого хода записи" ( насколько я понял ) - нули пишутся именно на диск.
Может и единицы, ибо сигнал по схеме инвертируется несколько раз.

Patron
28.12.2013, 14:42
Может и единицы, ибо сигнал по схеме инвертируется несколько раз.То, что CRC инвертируется перед записью на диск - это точно. Поэтому, если на диск при "холостой записи" пишутся нули - в регистр CRC добавляются единицы.

---------- Post added at 13:42 ---------- Previous post was at 13:31 ----------

Vslav сообщал, что при "холостой записи" на диск пишутся нули - это точно так ?

Alex_K
28.12.2013, 20:27
Vslav сообщал, что при "холостой записи" на диск пишутся нули - это точно так ?
Возможно. Когда требование не удовлетворилось, то по обратному фронту RDR_HSTB защелкивается триггер LATCH_TR. При активном LATCH_TR в регистр CRC начинают вдвигаться единицы. После записи CRC в регистре CRC оказываются все единицы. По новому сигналу RDR_HSTB формируется сигнал FIN_STB. Этот сигнал очищает триггер LATCH_TR, но после очистки LATCH_TR исчезает и FIN_STB, он получается очень короткий. Сигнал RDR_HSTB подлиннее, и по идее снова должен защелкнуться LATCH_TR, и соответственно пойти запись регистра CRC, а там уже все единицы, они же снова и будут вдвигаться.
Получается, что так, пишутся одни нули.
Есть еще один момент. Получается когда задвинуты все единицы, то должен сформироваться признак CRC_VALID, который защелкнется в триггере J34 по сигналам nLATCH_TR и nSTB_P03. А этот триггер выводится в бит 14 регистра состояния при нахождении контроллера в режиме чтения.

Patron
28.12.2013, 21:04
Есть еще один момент. Получается когда задвинуты все единицы, то должен сформироваться признак CRC_VALID, который защелкнется в триггере J34 по сигналам nLATCH_TR и nSTB_P03. А этот триггер выводится в бит 14 регистра состояния при нахождении контроллера в режиме чтения.В этом случае при переходе в режим чтения установится флаг CRC, который можно сбросить только по INIT/GOR ?

А так будет после любой записи CRC или только при пропуске требования записи после записи CRC ?

Alex_K
28.12.2013, 21:22
В этом случае при переходе в режим чтения установится флаг CRC, который можно сбросить только по INIT/GOR ?
Да, сбросить его можно только этими сигналами.

А так будет после любой записи CRC или только при пропуске требования записи после записи CRC ?
Так будет, если активны сигналы LATCH_TR и STB_P03. LATCH_TR устанавливается при неудовлетворенном требовании на следующие 64 мкс. А вот времянку сигналов STB_** я не знаю. Сложноватая схема формирования. Кстати, в схеме много различных триггеров сделано на мелкой логике. Её в принципе можно сильно уменьшить и привести в удобоваримый вид.

Alex_K
30.12.2013, 23:39
Нет, надо WEB-edition (http://dl.altera.com/?edition=web), он бесплатный.
Перекачал и установил Quartus II Software (includes Nios II EDS) и ModelSim-Altera Edition (includes Starter Edition). Quartus требует еще установить устройства. Можно любое, поменьше, например MAX II, MAX V device support ? А то остальные очень сильно пожирают место на диске.

Vslav
31.12.2013, 13:36
Перекачал и установил Quartus II Software (includes Nios II EDS) и ModelSim-Altera Edition (includes Starter Edition). Quartus требует еще установить устройства. Можно любое, поменьше, например MAX II, MAX V device support ? А то остальные очень сильно пожирают место на диске.
Если только для моделирования - то, наверное, лучше что-то из Циклонов 1/2/3. У MAX может просто ячеек не хватить. Для поведенческого моделирования выбор конкретного FPGA не важен - все временные параметры из модели берутся.

Alex_K
31.12.2013, 16:40
Если только для моделирования - то, наверное, лучше что-то из Циклонов 1/2/3. У MAX может просто ячеек не хватить. Для поведенческого моделирования выбор конкретного FPGA не важен - все временные параметры из модели берутся.
Перекачал и поставил Cyclone III, Cyclone IV device support (includes all variations).

Patron
01.01.2014, 21:03
В "технологическом" режиме КМД ДВК выполняет следующее тестирование работы ВП1-128:



; Тестирование регистров контроллера накопителя
MOV #177130,R2 ; R2 = адрес РСН
MOV @R2,R1 ; R1 = значение РСН
CMPB @#177716,#3 ; Установлен технологический режим ?
BNE 2416$ ; Нет
RESET ; СБРОС
TST @R2 ; Значение РСН равно нулю
BEQ 2350$ ; Да
2342$: MOV #100010,R0 ; R0 = ошибка - ошибка РСН накопителя
BR 2372$
2350$: MOV #177777,@R2 ; Занести в РСН 177777
CMP #100007,@R2 ; Считывается 100007 из РСН?
BNE 2342$ ; Нет - ошибка
MOV R1,(R2)+ ; Занести старое значение РСН R2=адрес РДН
TST @R2 ; Перевести контроллер в режим чтения
DEC @R2 ; Перевести контроллер в режим записи
BR 2424$
2372$: CMPB @#177716,#3 ; Установлен технологический режим ?
BNE 2412$ ; Нет
INC R5 ; Увеличить счетчик ошибок
CMP #37,R5 ; Количество ошибок превысило 30?
BHIS 2424$ ; Нет
2412$: JMP 202$
2416$: TST (R2)+ ; R2 = адрес РДН
TST @R2 ; Перевести контроллер в режим чтения
BR 2442$
2424$: COM @#177130
BIC #177774,@#177130
JMP 372$ ; На начало тестов


Судя по этому тесту - после записи 0xFFFF в регистр статуста ВП1-128 - там должно читаться 0x8007 ( 0100007 ).

Это так и есть ?

Alex_K
01.01.2014, 21:22
Судя по этому тесту - после записи 0xFFFF в регистр статуста ВП1-128 - там должно читаться 0x8007 ( 0100007 ).

Это так и есть ?
При прогоне в технологическом режиме к контроллеру скорее всего подключаются не дисководы, а специальные перемычки, то что подается на выходы (DS0, DS1, DS2, DS3, HS, MSW, DIR, REZ) должно идти на входы (TR0, RDY, WRP, IND).

Patron
02.01.2014, 17:04
Судя по содержимому прошивки КМД - 1801ВП1-128 может также полноценно записывать маркеры 0xC2:



MOV #0,@R5 ; Запись синхрозоны
SOB R0,11664$ ; Цикл записи синхрозоны
BIS #1000,2(R3) ; Установить в копии РСН бит записи маркера
11704$: TSTB @R4 ; Контроллер готов к приему?
BPL 11704$ ; Нет
MOV #141302,@R5 ; Записать маркер 0xC2C2
MOV 2(R3),@R4 ; Включить режим записи маркера
BIC #1000,2(R3) ; Сбросить в копии РСН бит записи маркера
11726$: TSTB @R4 ; Контроллер готов к приему?
BPL 11726$ ; Нет
MOV 16(R3),@R5 ; Записать маркер 0xFСС2
11736$: TSTB @R4 ; Контроллер готов к приему?
BPL 11736$ ; Нет
MOV #47116,@R5 ; Записать первое слово промежутка GAP1
MOV 2(R3),@R4 ; Сбросить режим записи маркера
MOV #31,R0 ; R0 = размер GAP1 в формате IBM (50 байт)

Alex_K
02.01.2014, 17:15
Судя по содержимому прошивки КМД - 1801ВП1-128 может также полноценно записывать маркеры 0xC2:
Ну 1801ВП1-128 по барабану какие маркеры записывать. Схема записи пропускает синхроимпульсы после нуля, который кодируется, как "10". Vslav где-то писал об этом, что при установленном бите WM, идет пропуск синхроимпульсов не только на 0xA1.

Patron
02.01.2014, 20:10
Схема записи пропускает синхроимпульсы после нуля, который кодируется, как "10".А как выглядит обобщённый алгоритм пропуска синхроимпульса в байте..

Сколько нулей подряд должно быть в двоичном представлении байта и/или с какого бита в байте должны начинаться эти нули, чтобы у третьего из них ( или не у третьего ? ) был пропущен синхроимпульс ?

---------- Post added at 19:10 ---------- Previous post was at 17:17 ----------


после FE я начал писать 0x30 - там тоже импульс выкушен, но в 5-ой позиции - не там где в A1И где в итоге ВП1-128 пропускает синхроимпульс при установленном бите WM:

1. В конкретном месте байта, если там 0 ?
2. В третьем нулевом бите на выходе сдвигового регистра ?

Alex_K
02.01.2014, 20:21
И где в итоге ВП1-128 пропускает синхроимпульс при установленном бите WM:

1. В конкретном месте байта, если там 0 ?
2. В третьем нулевом бите на выходе сдвигового регистра ?
Должна в третьем нулевом бите. Схема записи не распознает начало байта, биты со сдвигового регистра или регистра CRC двигаются сплошным потоком. Де-факто в схеме запоминаются четыре бита, а пятый - это выход сдвигового регистра или CRC. Вот на основе этих данных и бита записи маркера WM и строится выходной поток.

Patron
02.01.2014, 20:36
Должна в третьем нулевом бите.А если пишутся только нулевые биты - в каких из них будут пропускаться синхроимпульсы ?

А если циклически пишутся последовательности:

1) 00001
2) 0001

в каких тогда битах будут пропускаться синхроимпульсы ?

Alex_K
04.01.2014, 15:54
Посмотрел внимательно схему формирования выходных сигналов DO1, DO2, DO3. Для анализа разложил отдельно по логическим элементам формирование каждого из сигналов. В качестве данных использовал диаграмму, которую выкладывал Vslav в этом сообщении (http://zx.pk.ru/showpost.php?p=655078&postcount=147). Также использовал файл для описания диаграммы wave.do. В диаграмме для анализа использовались сигналы DO3, DO2, DO1 (в самом верху), WDATA (бит для записи, соответствует выходу D32 на схеме, а также сигналу WBIT0), WCLK и nWCLK (они перепутаны со схемой, на схеме соответственно nWCLK и WCLK). Далее буду руководствоваться названиями сигналов на схеме.
Сама схема записи состоит из:
-фактически мультиплексора D32, который в зависимости от сигнала LATCH_TR, выбирает или выход с регистра CRC (LATCH_TR=1, пропущенное требование, идет запись CRC), или выход со сдвигового регистра (LATCH_TR=0, запись данных). На выходе получается сигнал WBIT0 (на диаграмме WDATA);
-сдвигового регистра на триггерах D37 (WBIT1), D36 (WBIT2), C37 (WBIT3), C38 (WBIT4), B37 (WBIT5), B36 (WBIT6), A37 (WBIT7), A36 (WBIT8). Хотя разрядов и восемь, но де-факто запоминаются четыре или пять, так как тактируются триггера разными сигналами, нечетные - nWCLK, четные - WCLK. Порядок продвижения битов будет описан чуть ниже;
-собственно целая куча логики для формирования выходных сигналов на DO1, DO2, DO3, в зависимости от значения сигналов WBIT0-WBIT8 и значения бита записи маркера CSR_WM.
Сама схема тактируется двумя сигналами WCLK и nWCLK. Сигналы эти поступают только тогда, когда контроллер находится в режиме записи и дискета не защищена от записи. Также, если нет сигналов WCLK и nWCLK, регистр из триггеров находится все время в режиме сброса (сигнал nWRE). Длительность двоичного бита данных составляет 4 мкс. Сам этот интервал для записи MFM-сигнала делится на два интервала по 2 мкс. В середине этих MFM-интервалов проскакивают импульсы - сначала nWCLK, затем WCLK. Как известно в MFM бит "1" кодируется как "01", бит "0" после "1" как "00" и бит "0" после нуля - "10". Из этого следует, что единичный бит данных надо записывать на импульсе WCLK, а нулевой после нуля - на nWCLK.
Рассмотрим схему продвижения битов по сдвиговому регистру. Они обозначены по порядку, как 1, 2, 3 и т.д.

876543210
---------
000000011 nWCLK
000000111 WCLK
000001122 nWCLK
000011222 WCLK
000112233 nWCLK
001122333 WCLK
011223344 nWCLK
112233444 WCLK
122334455 nWCLK
223344555 WCLK
233445566 nWCLK
Для записи единичного бита используется сигнал WBIT3, для записи нулевого - WBIT4(предыдущий бит данных) и WBIT2(текущий бит данных).
Вот теперь о распределении сигналов по выходам DO1, DO2, DO3. Как описывал Vslav, что это скорее всего разнесенные по времени сигналы. Но анализ схемы этого не подтвердил. Схема распределяет сигнал на соответствующий вывод в зависимости от того, какие были предыдущие биты данных и какие будут последующие. А уже далее эту информацию использует схема внешней прекоррекции. Если прекоррекция не нужна, то сигналы с трех выводов нужно просто сложить. При этом сигнал на выходе будет только на одном выводе.
А теперь о распределении сигналов:
- вывод DO1: "1" - если предыдущий(WBIT5) и следующий(WBIT1) биты данных равны. "0" - если второй слева(WBIT6) и следующий(WBIT0) биты данных равны.
- вывод DO2: "1" - предыдущий(WBIT5)=0 и следующий(WBIT1)=1. "0" - второй слева(WBIT6)=1 и следующий(WBIT0)=0.
- вывод DO3: "1" - предыдущий(WBIT5)=1 и следующий(WBIT1)=0. "0" - второй слева(WBIT6)=0 и следующий(WBIT0)=1.
При установленном бите записи маркера CSR_WM все нулевые биты направляются на вывод DO1.
Ну а теперь самое интересное - как же делаются пропуски синхроимпульсов при записи маркера. По идее бит "0" должен записываться как "00", если предыдущие биты данных равны "100", а следующий - "0". Но разработчики 1801ВП1-128 поступили проще - они анализируют только третий слева бит данных на равенство "1". И то, что хорошо получается при записи маркера 0xA1, может наделать лишних пропусков при записи других данных.
Фрагмент из диаграммы от Vslav:

! 30 ! 31 ! 32 ! 33 ! 62 ! A7 ! 00 ! 00 ! A1 ! A1 ! A1 ! FE !
1 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 1 0 1 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 1 0 1

01000000010100000010101001010000000100100101000001 00100001010000010100010100000001000100010010010101 00000010101010101010101010101010010001001000100101 0001001000100101000100100010010101010101010100
---- --** ---- -- -- -- ---- --** ** ** **
01001010010100101010101001010010100100100101001001 00101001010010010100010100101001000100010010010101 00101010101010101010101010101010010001001010100101 0001001010100101000100101010010101010101010100
Сверху указаны шестнадцатеричные данные с границами байтов, ниже двоичный поток. Еще ниже показаны два MFM-потока - с установленным битом маркера CSR_WM и сброшенным битом маркера. Между потоками с помощью "--" указано, что пропуска не должно быть, а он есть, "**" - пропуск нужен и он есть.
Также диаграмма маркера C2:

4E ! 00 ! 00 ! C2 ! C2 ! C2 ! FC !
0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 1 1 1 0 0

00010010010101000000101010101010101010101010101001 01000000100100010100000010010001010000001001000101 010101010000
--** --** --** --** --
00010010010101001010101010101010101010101010101001 01001010100100010100101010010001010010101001000101 010101010010

Patron
04.01.2014, 17:10
то, что хорошо получается при записи маркера 0xA1, может наделать лишних пропусков при записи других данныхВыходит, что маркер 0xC2 пишется с двумя пропусками синхроимпульсов вместо одного..

Alex_K
04.01.2014, 17:14
Выходит, что маркер 0xC2 пишется с двумя пропусками синхроимпульсов вместо одного..
Выходит, что так. Но на чтении это сказаться не должно. ФАПЧ подстраивается под существующие импульсы, а если они исчезают, то держит нужную скорость. В итоге при отсутствии сигнала будут считываться нули.

Patron
04.01.2014, 17:25
Сегодня Voland сообщил, почему 1801ВМ1 иногда зависает при работе с 1801ВП1-128.

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

Alex_K
04.01.2014, 17:35
Сегодня Voland сообщил, почему 1801ВМ1 иногда зависает при работе с 1801ВП1-128.

Выяснилось, что причиной зависания является изменение содержимого регистра статуса или данных в тот момент, когда этот регистр читается процессором.
Чего-то я никогда не слышал о зависаниях 1801ВМ1 с 1801ВП1-128. Вроде и БК работает с этим чипом и КМД ДВК также на 1801ВМ1.

Patron
04.01.2014, 18:26
Чего-то я никогда не слышал о зависаниях 1801ВМ1 с 1801ВП1-128.А я наоборот - регулярно читал у пользователей БК такие сообщения:

? foot - 22.12.2013 22:37
[? gid @ - 18 декабря 11:59]
[Когда зависания меня в конец достали, особенно при записи каталога, я просто выпаял кварц с контроллера, а частоту на ВП1-128 стал брать с МПИ с ноги А20. В результате зависать стало в разы меньше, но всё равно не перестало.]
У меня все имеющиеся контроллеры были подобным образом переделаны.
Зависаний после переделки стало меньше на порядки.


Вроде и БК работает с этим чипом и КМД ДВК также на 1801ВМ1.Если сигнал индекса у ВП1-128 не буферизуется - содержимое регистра статуса должно регулярно изменяться в момент его чтения программой форматирования.

Если при этом КМД не виснет, то БК-0011 скорее виснет при работе с ВП1-128 по какой-то другой причине, нежели изменение битов на шине данных при установленном RPLY.

Alex_K
04.01.2014, 18:36
Если сигнал индекса у ВП1-128 не буферизуется - содержимое регистра статуса должно регулярно изменяться в момент его чтения программой форматирования.
Да, этот сигнал поступает прямо с дисковода, через логические элементы. Также это относится и к сигналам TR0, WRP, RDY. Да и схема работы с МПИ никак не завязана на работу других схем контроллера.

Если при этом КМД не виснет, то БК-0011 скорее виснет при работе с ВП1-128 по какой-то другой причине, нежели изменение битов на шине данных при установленном RPLY.
У 1801ВМ1 была неприятная особенность - надо было привязывать входящие сигналы к тактовой частоте, это относится в частности к RPLY. Но в БК это вроде реализовано. У 1801ВП1-128 RPLY исчезает только тогда, когда снимается сигнал DIN или DOUT, или же SYNC.

Woland
19.05.2014, 10:20
Сегодня Voland сообщил, почему 1801ВМ1 иногда зависает при работе с 1801ВП1-128.

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

Небольшое уточнение - является причиной зависания ПЛИС-реализации ВП1-128 в рамках контроллера СМК512,
а на оригинальном СМК64, построенном на заводской ВП1-128 - именно такие зависания отсутствуют.

Закономерным будет вопрос - откуда зависания взялись. Логика контроллера не менялась, логика формирования самих данных в регистрах осталась абсолютно прежней, отчасти это подтверждается тем, что на БК0010-01 данная проблема зависаний ИЗНАЧАЛЬНО ОТСУТСТВОВАЛА. Другое дело, что никто точно не знает, почему 1801ВМ1 так может реагировать на происходящее на шине, ибо это нормально, когда содержимое какого-нибудь периферийного регистра может меняться в процессе считывания - это же асинхронные события. Вполне возможно, что к примеру у оригинального контроллера задержки и фронты длинее, поэтому такие модификации при чтении не сбивают процессор. Для защиты теперь поставили регистр-защелку, который фиксирует состояние шины во время чтения из регистров FDD.

CodeMaster
19.10.2014, 16:37
Благодаря уважаемым Vslav и BarsMonster был вскрыт и документально воспроизведен кристалл БМК КР1801ВП1-128

А аппаратные, пинсовместимые эмуляторы планируются?

Vslav
19.10.2014, 21:23
А аппаратные, пинсовместимые эмуляторы планируются?
Пока нет, но если будут желающие, то можно сделать как побочный продукт от основного проекта БК-на-FPGA. Писать свою версию 128-ой "по мотивам реверса" я все равно буду.

Woland
01.11.2014, 12:27
Итак, для любознательных прикладываю исходники прошивки (http://zx-pk.ru/attachment.php?attachmentid=49779&d=1414834268) cpld для SMK-512. Скорее всего окончательная версия.

Vslav
01.11.2014, 13:14
Отлично, дойдут руки - покурим. Наверное на базе этого сделаю еще вариант штатного контроллера FDD от БК.

MacBuster
25.03.2017, 18:55
Сообщение от CodeMaster
А аппаратные, пинсовместимые эмуляторы планируются?
Пока нет, но если будут желающие, то можно сделать как побочный продукт от основного проекта БК-на-FPGA. Писать свою версию 128-ой "по мотивам реверса" я все равно буду.
Судя по всему, 128-е закончились совсем. Пора делать «пинсовместимую» замену.

Vslav
25.03.2017, 22:23
128-е закончились совсем
Да вроде есть еще немножко :)
http://s61.radikal.ru/i174/1703/0a/3259416e0eact.jpg (http://radikal.ru/big/93rr0wp3ktnw1)

Только конструкторы огорчают - они корпус 429-42 ухитрились тремя разными способами на платы посадить. Поэтому совсем универсально не получится, или надо делать три варианта замен.

svinka
26.03.2017, 01:18
приделать 42 гибких вывода и пусть кто как хочет так и формует Ж)

perestoronin
26.03.2017, 11:02
делать три варианта замен

кто как хочет
планировать все три варианта, и каждый какой ему нужен из трех выбирает, или все три про запас

MacBuster
26.03.2017, 12:13
По-моему получится две платы - одна с FPGA, вторая - просто переходник.

Я готов даже к вертикальному монтажу на PLD, который потом надо вставлять в плату-переходник с пинами-PLS распаянными в нужной конфигурации.

Замена будет выглядеть как SIP/SIMM. Можно ещё светодиоды для индикации активности туда поместить :)

MM
26.03.2017, 13:34
планировать все три варианта, и каждый какой ему нужен из трех выбирает, или все три про запас...
Видимо, господ, причастных к разработке ИС здесь совсем мало - порядка 2 чел.
Господин svinka предложил абсолютно правильное решение, т.к. есть еще и поверхносный монтаж без шахматных выводов, применяющийся в изделиях с высокой плотностью посадки компонентов.
Для такого варианта может понадобится несколько меньшая МПП с глухими переходными отверстиями. Например, снизу - плюшка, сверху пользователь напаивает выводы от резисторов и формует согласно имеющейся посадке.
*
Кстати, какая планируется цена новодела ?
*
КР1801ВП1-128 до сих пор имеются в розничной продаже ( 250 руб ) по почте у энтузиастов БК :
http://market.zx-pk.ru/forum/viewtopic.php?f=4&t=815

- - - Добавлено - - -

Конструктив под замену 1801ВП1 был бы интересен в первую очередь для 037 прошивки, с целью хотя бы в пару раз сократить тайминги доступа к ДОЗУ БК.
Можно предусмотреть и отдельный вход для 12 мгц, для технологических целей.
Я не особо в курсах содержания ячеек в данной плюшке - может и не хватить...

Vslav
26.03.2017, 13:53
Кстати, какая планируется цена новодела ?

Оставшиеся комплекты из трех пустых плат (две на фото плюс еще замена 014 с USB-клавиатурой) распродам по себестоимости - $5/комплект.



Конструктив под замену 1801ВП1 был бы интересен в первую очередь для 037 прошивки

А это универсальная плата - может заменить 037/065/128 и много чего еще, там есть и свой отдельный генератор (я ставлю 48МГц), и можно выдать 12МГц на основную плату чтобы синхронизировать и видео.



с целью хотя бы в пару раз сократить тайминги доступа к ДОЗУ БК.

В пару-не в пару, а раза в полтора реально, буду пробовать. Но сначала сделаю 014-ую, потому что древние клавиатуры меня задолбали, и обрывами и ЙЦУКЕНГ-ом, ничего на БК делать не могу.



Я не особо в курсах содержания ячеек в данной плюшке - может и не хватить...

На плату можно ставить 3064/3128 в TQFP-100, в зависимости от сложности прошивки. Оригинальная 037 может и в 3064 влезть.

MacBuster
26.03.2017, 14:37
Оставшиеся комплекты из трех пустых плат (две на фото плюс еще замена 014 с USB-клавиатурой) распродам по себестоимости - $5/комплект.
Я бы взял один чтобы заменить ВП1-128, если подскажете какие мс ставить, что и как прошить.

Vslav
26.03.2017, 15:04
Я бы взял один чтобы заменить ВП1-128, если подскажете какие мс ставить, что и как прошить.
По готовности проект открою, все выложу, расскажу и проконсультирую.

MacBuster
26.03.2017, 17:33
По готовности проект открою, все выложу, расскажу и проконсультирую.
Спасибо, буду ждать.

vwarlock
27.03.2017, 10:20
По готовности проект открою, все выложу, расскажу и проконсультирую.

Я тоже от комплекта не отказался бы

ISV
09.10.2025, 15:15
Проект заглох?