≡ Передовица » Hardware » ДЗУ » Исследование КНГМД 840 » Автомат кодирования и предкомпенсации записи
Автомат кодирования и предкомпенсации записиКусок из моей схемы. Нумерация микросхем двойная: первым идёт номер из второй официальной версии, вторым - номер в моём старом полном варианте схемы. Красным цветом обозначены связи с остальной частью схемы, синим - внутренние связи, используемые только внутри этого участка. В тексте маркировка микрух - только по официальной схеме. Сигналы:
Предкомпенсация записиНе вдаваясь в физику процесса, очень коротко обсудим: что такое предкомпенсация записи и для чего она нужна ? Так как диск крутится с постоянной скоростью и объём данных на всех дорожках одинаков, плотность записи (т.е. количество бит на миллиметр поверхности диска) на центральных дорожках возрастает, по сравнению с дорожками, находящимися на краю диска. Поверхность на краю движется мимо головки быстрее, чем поверхность у центра диска. Это приводит к тому, что диск, как устройство хранения потока бит, ведёт себя немного по разному на разных дорожках: в зависимости от комбинации записанных бит некоторые единички могут слегка "сползать" со своих мест и, что ещё хуже - их амплитуда может уменьшиться. Т.е. при чтении они окажуться чуть раньше или чуть позже, чем нужно, а может быть даже потеряются. Эффект выражен в разной степени, в зависимости от номера дорожки. Отчасти "сползание" корректируется автоматом чтения, но, для ещё лучшей коррекции, поток записываемых данных также формируется по разному, в зависимости от комбинации записываемых бит и номера дорожки. Как-то так: 1 0 1 0 0 0 1 - нормальный поток 1 0 1 0 0 0 1 - чуть подкорректированный поток Коррекция в агатовском ПО: цилиндры 0-39 - нет предкомпенсации, 40-59 - слабая предкомпенсация, 60-79 - сильная предкомпенсация. Режим предкомпенсации задаёт драйвер, это не входит в задачи контроллера. Небольшое отступление: единичка в понимании дисковода - это не определённое значение намагниченности, которое длится заданное время, а изменение намагниченности. Естестенно, изменение происходит очень быстро, но когда дисковод обнаруживает его, он формирует импульс фиксированной длительности (обычно 1 мкс). Однако изменение может произойти чуть раньше или чуть позже - именно это важно для раскодирования данных. В то же время, в силу неидеальности дисковода, моменты изменений могут немного "сползать" на внутренних дорожках. Предкомпенсация направлена на то, чтобы заранее подвинуть изменение намагниченности туда, откуда оно потом вернётся на "правильное" место. Нолик же - это ничто, дисковод не предпринимает никаких действий и при чтении тут не будет никаких изменений намагниченности, соответственно, не будет и никаких импульсов. Поэтому нолик не может никуда "сползти". ПЗУ D25 и режим обычной записиС чего начнём распутывать этот клубок ? Пусть это будет прошивка ПЗУ: 00000000 f2 f2 f2 f2 f0 f0 f0 f0 f3 f3 f3 f3 f3 f3 f3 f3 --""-- то же самое до адреса 90 --""-- 00000090 f2 f2 f2 f2 f0 f0 f0 f0 f3 f3 fb fb f3 f3 f3 f3 000000a0 f2 f2 f2 f2 f0 f0 f0 f0 f3 f3 f3 f3 fd fd fd fd 000000b0 f2 f2 f2 f2 f0 f0 f0 f0 f3 f3 fb fb f3 f3 f3 f3 000000c0 f2 f2 fa fa f0 f0 f0 f0 f3 f3 f3 f3 fd fd fd fd 000000d0 fc fc f2 f2 f0 f0 f0 f0 fb fb f7 f7 f3 f3 f3 f3 000000e0 f2 f2 fa fa f0 f0 f0 f0 f3 f3 f3 f3 f5 f5 f5 f5 000000f0 fc fc f2 f2 f0 f0 f0 f0 fb fb f7 f7 f3 f3 f3 f3 Выглядит немного гадски ? Вот я так сперва подумал. Но затем... Шаг первый: вспомним, что в дампе каждому адресу соответствует байт, но выходов у ПЗУ всего четыре. Старшую цифру можно отбросить. Шаг два: внимательно смотрим распиновку: заметьте, что старший разряд данных поступает на младший разряд счётчика. Все четыре бита стоят задом наперёд. Почему ? Не знаю. Просто в справочниках выходы 556рт4 маркируются в одном направлении (и этот дамп снят в соответствии со справочником), а в агатовских схемах - наоборот. Значит следует развернуть биты в дампе. Шаг три: внимательно смотрим на D26. Он считает вверх (сигнал счёта вниз D26.4 не используется), но по сигналу Wp, вместо очередного такта счёта, загружает данные с параллельного входа. На выходе переноса D26.12 возникает импульс в тот момент, когда счётчик переходит со значения 15 в значение 0. Правильно предположим, что в какие-то моменты счётчик загружает данные, а затем считает до 15 и, затем, 0. Так как только в этом случае на дисковод будут уходить хоть какие-то данные. Следовательно в ПЗУ хранятся дополнения до 16. Следовательно, число шагов будет равно 16 - n, где n - числа, хранимые в ячейках ПЗУ. Шаг четыре: на два старших адресных входа ПЗУ подключены сигналы выбора режима предкомпенсации записи. 00, 01 - нет предкомпенсации, 10 - слабая предкомпенсация, 11 - сильная. Три отдельные таблицы по адресам $00-$7F, $80-$BF, $C0-$FF. Итого получается: Нет предкомпенсации 00 - xx00xx xx01xx xx1xxx 12 16 4 Слабая предкомпенсация 00 - 00000x 00001x 00010x 00011x 00100x 00101x 00110x 00111x 12 12 16 16 4 4 4 4 10 - 01000x 01001x 01010x 01011x 01100x 01101x 01110x 01111x 12 12 16 16 4 3 4 4 20 - 10000x 10001x 10010x 10011x 10100x 10101x 10110x 10111x 12 12 16 16 4 4 5 5 30 - 11000x 11001x 11010x 11011x 11100x 11101x 11110x 11111x 12 12 16 16 4 3 4 4 Сильная предкомпенсация 00 - 00000x 00001x 00010x 00011x 00100x 00101x 00110x 00111x 12 11 16 16 4 4 5 5 10 - 01000x 01001x 01010x 01011x 01100x 01101x 01110x 01111x 13 12 16 16 3 2 4 4 20 - 10000x 10001x 10010x 10011x 10100x 10101x 10110x 10111x 12 11 16 16 4 4 6 6 30 - 11000x 11001x 11010x 11011x 11100x 11101x 11110x 11111x 13 12 16 16 3 2 4 4 Первая колонка - адрес внутри таблицы. Десятичное число - количество тактов !4 МГц от сигнала Wp до импульса записи. Двоичное число - адрес, в котором символом x отмечены разряды, которые не имеют значения (т.е. содержимое ячеек совпадает). Например, режим отсутствия предкомпенсации, адрес $00: в нём биты A3 = A2 = 0 - следовательно, смотрим самую левую верхнюю ячейку в таблице xx00xx, там значение 12 - столько тактов будет отсчивать счётчик до появления импульса записи. Кажется. Но не совсем так. И сейчас рассмотрим - почему. Всё дело в том, что длительность одного бита кодированного потока (т.е. бит синхронизации или бит данных) соответствует 8 шагам секвенсора. Но так как двух соседних единиц в потоке быть не может, один цикл счёта D26 (от заданной в ПЗУ константы до нуля) синтезирует два бита: ноль и следующую за ним или перед ним единицу. Если в таблице указано число 16 - это значит, что счётчик будет перезапущен до того, как досчитает до конца. Таким образом значение 16 в таблице - это не синтезируемый с некоторой задержкой импульс, а полная пауза - два нуля. И это очень интересная величина: обратите внимание, что она встречается в таблице чаще всего. Ей соответствует любой адрес, у которого A3 = 0 и A2 = 1. Что интересно: при отсутствии предкомпенсации вообще встречается всего три значения: A3 = A2 = 0 - значение 12 и A3 = 1 - значение 4. Остальные биты в этом режиме не важны. Построим диаграммку: A3 A2 время: 0 1 2 3 4 5 6 7 8 9 a b c d e f на диск запишутся 0 0 1 0 1 0 1 0 0 1 0 1 1 0 1 1 1 1 0 Ничего не напоминает ? A3 - бит до кодирования, A2 - следующий за ним бит. Время от 0 до 7 - бит данных, 8-f - бит синхронизации. В период 0-7 пишется бит A3, в период 8-F пишется единица при условии, что A3 и A2 равны нулю. Вот и вся работа автомата. На диск ушел закодированный MFM-поток. Дальше можно расковырять поправки в таблицах слабой и сильной предкомпенсации. Они, в меньшей или большей степени, сдвигают единицы в зависимости от предыдущих и последующих бит. Могут сдвинуть их на более раннее или более позднее время. В слабой предкомпенсации есть только сдвиг бита данных на один шаг (3 или 5 вместо 4), в сильной предкомпенсации есть сдвиги на 2 шага для бита данных и на 1 шаг для бита синхронизации. Кстати, а сколько это во времени - один шаг ? Это около 250 нс. (И в скобках замечу: 1818вг93 предполагала только два режима предкомпенсации. А здесь - три.) Теперь становится ясным и назначение регистра D22 - это просто линия задержки, которая хранит несколько бит данных, как недавно записанных, так и тех, запись которых ещё предстоит. Но в каждый текущий момент записывается именно значение бита D3 и, следующего за ним, расчитанного, бита синхронизации. Разобрав содержимое D25 становится видно, что, фактически, используются только пять бит: два записанных, текущий и два, стоящих в очереди на запись. Попробуем собрать все случаи в режиме слабой предкомпенсации: 001xx, xx100, 10101, x111x - нет предкомпенсации (такт 4), x1101 - бит данных будет записан чуть раньше (такт 3), 1011x - бит данных будет записан чуть позже (такт 5). Точно также можно разобрать и случаи сильной предкомпенсации. Стек передачи байт в режиме записи: часть 1Основное изучили, теперь можно взять курс на механизм синтеза синхросбоя. Согласно документации, запись синхросбоя выполняется драйвером следующим образом: записывается байт со значением ¤A4, затем на запись отправляется байт ¤FF и, не дожидаясь готовности (освобождения) регистра записи, драйвер должен дёрнуть бит, запускающий запись синхросбоя (на полной схеме тракта записи он был обозначен как "Запись синхро"). После этого драйвер ждёт готовности регистра записи и затем может записывать пролог очередного поля (адреса, данных или чего угодно ещё). Но попробуем теперь понять, в каких регистрах какие значения у нас будут ? В то время, как байт ¤A4 отправился на запись, драйвер ждёт освобождения регистра записи, чтобы записать в него байт ¤FF. Занятость регистра означает, что ¤A4 ещё пока в 580вв55. Следовательно из D21 в D22 кочует предыдущий байт, идущий на диск. Когда запись этого байта дойдёт до бита D3, возникнет сигнал "следующий байт". Кстати, а почему на D3 ? А потому что D21 в этот момент передаст последний бит D0 в D22 и будет свободен. А биты с D3 по D0 будут ещё будут катиться по конвееру D22. И вот теперь драйвер записал ¤FF в 580вв55, а D21 захватил байт ¤A4. ЦП немного тормозит, драйвера бывают написаны по разному, но примерно к записи бита D2 предыдущего байта сигнал "запись синхросбоя" дойдёт от драйвера до секвенсора. И теперь нам следует, наконец, начать изучать его программу. Программа секвенсора: записьПеред вами листинг части программы секвенсора, отвечающей за запись. Справа и слева, в крайних колонках, указан номер шага. Обозначения команд:
Программа состоит из четырёх частей. Исполняющаяся часть выбирается в зависимости наличия сигнала "запись синхро" - его формирует драйвер и сигнала "следующий байт" - его формирует счётчик D23. В любой момент, если один из этих сигналов изменится, произойдёт переход на соответствующую часть. Но чем различаются разные части ? Все команды в них почти одинаковые, различия только в некоторых переходах go. Желтым цветом отмечены части, которые различаются в зависимости от наличия/отсутствия сигнала "запись синхро" и рыжим цветом - отличия при наличии сигнала "следующий байт". Обычно исполняется часть программы в самой левой колонке от шага ¤20 до ¤3F. Она не сложная. Начнём с конца:
Видно, что цикл длится 16 тактов. Во время записи он почти всегда исполняется именно такое время. Что произойдёт, если появится сигнал "следующий байт" ? Он может возникнуть после модификации D23 на шаге ¤30. Серой стрелкой показан соответствующий переход в третью слева колонку. В нижней половине (шаги ¤20-3F) она отличается только тем, что на шаге ¤30 в регистр D23 будет записано число 8 - начнётся отсчёт бит очередного байта. Формирование синхросбояТеперь о том, что происходит при появлении команды "запись синхро". Смотрим желтые отметки. Они стоят на всех шагах, которые проходит программа при записи обычного байта. Даже на некоторых, которые не проходит (¤20). Как только, во время записи любого бита, поступает сигнал "запись синхро" исполнение переходит на ¤20 шагов выше. Т.е. на верхнюю половину программы. Она почти ничем не отличается от нижней, таким образом этот переход - своеобразное защёлкивание требования записать синхросбой. Даже если сам сигнал "запись синхро" будет снят (а он и будет снят на следующем шаге) или - наоборот - если драйвер его выдаст несколько раз - в любом случае программа будет продолжать выполнение в верхней половине. Если сравнить нижнюю и верхнюю половины левой колонки - там нет отличий. Кроме, разве что, адресов внутренних переходов: каждая половина выполняет переходы только внутри себя. Различия начиняются в третьей и четвёртой колонках - они начнут исполняться во время записи последнего бита байта. Эти моменты обозначены рыжим цветом. Шаг ¤00 не имеет значения - он не исполняется в нормальном режиме, так как на него нет ссылок. А вот на шаге ¤10 третьей колонки как раз закончилась запись последнего бита. И теперь выполняется переход на шаг ¤23, но так как в этот момент будет переключен счётчик бит D23, переход произойдёт в первую колонку. Шаги с ¤23 до ¤2A пустые, но на них будет выставлен сигнал Wp. Это как раз 8 шагов, во время которых счётчик D26 будет постоянно загружать в себя длительность следующего интервала, но не будет выполнять счёт. На шаге ¤2A будет выполнен переход на шаг ¤21, затем ¤22 и затем Wp будет снят - исполнение вернётся в привычную колею. Чего мы добивались ? В конце последнего бита секвенсор притормозил на 8 шагов поступление очередного бита и сформировал нолик в потоке записи. Но именно один нолик. Это всё ? Нет ! Не следует упускать из виду ещё одно важное действие: перед тем, как вернуться вниз левой колонки, в третьей колонке на шаге ¤1F вместо загрузки очередного бита из D21 в D22 секвенсор командует загрузить в D22 константу ¤12. Хм ? А зачем ? Если честно - не знаю. Я не нашел объяснения. Но рассмотрим, что должно записаться на диск, если следовать инструкции. Стек передачи байт в режиме записи: часть 2В предыдущей серии: И вот теперь драйвер записал ¤FF в 580вв55, а D21 захватил байт ¤A4. ЦП немного тормозит, драйвера бывают написаны по разному, но примерно к записи бита D2 предыдущего байта сигнал "запись синхросбоя" дойдёт от драйвера до секвенсора. Секвенсор, как мы видели, в этом случае продолжит запись байта... Так, ещё раз: какого байта? В D21 у нас байт ¤A4. В D22 хвост предыдущего байта. Секвенсор "защёлкнул" требование синтезировать синхросбой, но ему остаётся записать ещё 6-7 бит. Допустим, предыдущий байт был ¤AA: Биты данных: 1 0 1 0 Биты синхро: 0 0 0 0 Это была вторая цифра ¤AA. Теперь пойдут разряды из ¤A4: Биты данных: 1 0 1 0 Биты синхро: 0 0 0 1 Кстати, а почему последний синхро 1 ? А потому, что в байте ¤A4: следующий бит данных - нолик. Он ещё не успел попасть на диск, но секвенсор о нём знает. Итого 8 бит. Теперь ¤FF переходит из 580вв55 в D21. А секвенсор вспоминает, что надо бы записать лишний нолик: Биты синхро: 0 Что дальше ? А дальше бы пошли оставшиеся биты ¤A4. Но перед записью нолика секвенсор загрузил в D21 константу ¤12. Она и будет записываться. От бита D3: Биты данных: 0 0 1 0 Биты синхро: 1 0 0 0 Записали 4 бита, что там дальше ? Дальше к записи подъехал ¤FF. Биты данных: 1 1 1 1 Биты синхро: 0 0 0 0 И так далее. Итого: Биты данных: ...... 1 0 1 0 1 0 1 0 0 0 1 0 1 1 1 1 Биты синхро: 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 ...... Всё вместе: 10001000 10001001 0 01001000 10101010 Так зачем нужно было защёлкивание константы ¤12 в D22 ? Ведь можно было потребовать записать не ¤A4, а ¤A2 ? Разве получили бы не тоже самое ? Возможно, изначально требование записывать ¤A4 отсутствовало, разработчики надеялись весь шаблон синхросбоя впихнуть в программу секвенсора и удачно подобранную константу, которая бы загружалась по команде секвенсора, но затем отказались от этой идеи. Обратите внимание, что из ¤A4 используются не только 4 старших разряда, но и D3 - от него формируется последний бит синхронизации, хотя сам D3 уже не попадает в запись. Кстати, а где у нас ¤FF ? А он как раз будет потерян при чтении, ему будут соответствовать значения 0-7 счётчика D23. И всё же его старший разряд важен. Дело в том, что после сбоя синхронизации автомат начинает читать данные только получив единичку (немного напоминает 140ку, не так ли ? ;). Её он считает первым битом данных и все нули перед ней будет пропускать. Так что без неё сеанса магии не состоится. Ну а значения остальных 7 бит не важны. Итак, попробуем расшифровать полученную последовательность. Хвост байта ¤AA отбросим - там может быть любое значение, оставим только ¤A4 SYNC ¤FF: Читаем с диска: 10001001 0 01001000 10101010 Фазы декодера, вариант 1: sds!dsds d sdsdsds! dsdsdsds - случай, когда у нас фаза была сбита до синхросбоя Фазы декодера, вариант 2: dsdsdsds d sdsdsds! dsdsdsds - случай, когда синхро была в порядке до синхросбоя Видно, что программа чтения способна распознать здесь и начало байта ¤FF и отличить биты данных от бит синхронизации. Как же она устроена ? Об этом - в следующем разделе. P.S. Заметили, что добавленный нолик ни в каком случае не является элементом синхросбоя? Вокруг него даже не набирается трёх нулей. Такая вот ирония. Я над ней порядком посидел. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |