Предлагаю вашему вниманию реализацию нового кассетного формата для ZX Spectrum.
Среди современных ему компьютеров, кассетный формат ZX Spectrum всегда выглядел в выгодном свете. По сравнению с Atari, C64, Радио-86РК и др., он не требовал специализированных магнитофонов, имел относительно высокую плотность записи и надежность хранения информации на кассете. Тем не менее, мне издавна не давал покоя вопрос о некоторой неэффективности формата "FM", как его называли в литературе. Ведь для записи каждого бита используется два фронта сигнала, да и само слово "FM" всегда ассоциируется со словом "MFM", где применяется более эффективное кодирование. По прошествии лет я так и не придумал, как можно прикрутить MFM к кассете, зато наткнулся на более интересную вещь - код 8b/10b.
Этот код заменяет каждые 8 бит данных на последовательность из 10 бит, обладающую следующими важными свойствами:
1) Количество нулей и единиц в такой последовательности либо одинаково, либо отличается нормированно. Тем самым кодированный сигнал имеет нулевую постоянную составляющую, что позволяет записывать его на магнитофон, передавать по линии без связи по постоянному току и т.д. без потери информации.
2) Количество подряд идущих одинаковых бит никогда не превышает 4. Тем самым снижаются требования по передаче низких и ультранизких частот, а также гарантируется достаточно фронтов сигнала для синхронизации.
Меня заинтересовал вопрос реализации формата для записи на кассету в ZX Spectrum, использующего этот код, и я сначала сделал программу сохранения - чтобы послушать, как звучат данные в этом формате, а затем и загрузчик: ведь мало ли, как они звучат, если их загрузить нельзя!
При реализации формата я делал упор на устойчивость к типичным искажениям сигнала магнитофона, а именно: отличающаяся на разных магнитофонах скорость записи, ограниченный спектр пропускаемых частот. Так как оригинальный кассетный формат Sinclair весьма неприхотлив к качеству записи и состоянию кассеты - то я постарался сделать новый формат таким, чтобы он не уступал, а по возможности - и превосходил оригинальный формат в этом. Время между ближайшими фронтами сигнала было выбрано таким же: 0.25мс. В результате требуемый диапазон частот составляет 2кГц, причем его верхняя часть может быть даже подрезана. Я специально обрабатывал сигнал фильтром Баттерворта с частотой среза около 1700Гц (при этом 2кГц, хоть и ослабленная, но немного пропускается), и загрузка происходила без ошибок. Также я менял скорость записи в пределах +-30%, в том
числе плавно во время загрузки - и это тоже не приводило к ошибкам. Справедливости ради следует заметить, что оригинальный формат имеет примерно такие же требования к скорости и полосе частот сигнала.
Добиться такой устойчивости стало возможным только за счет тщательно разработанного загрузчика. В нем, для подстройки к скорости записи, используется программно реализованная система ФАПЧ. Вместо ожидания фронта сигнала, как это сделано в загрузчике от Sinclair, в моем загрузчике используется фазовый детектор. При загрузке каждого бита производится два измерения сигнала магнитофона: одно в середине временного интервала, который приходится на этот бит, а второе - на границе между битами. Если два подряд идущих бита различны
(если был фронт) - то измерение "на границе" совпадет с предыдущим, либо последующим битом. И тогда, если оно совпало с предыдущим - значит "внутренние часы" загрузчика идут быстрее, чем скорость записи, а если совпало с последующим - то наоборот, медленнее. На этой основе
производится подстройка "внутренних часов" загрузчика. Подобным образом в современной электронике осуществляется прием данных по линиям связи с автоподстройкой к скорости и/или к задержке. При этом собственно данные считываются в наиболее выгодный момент времени - в середине временного интервала, в котором записан
бит. Это дает дополнительную устойчивость к шумам и искажениям сигнала. Не исключено, что устойчивость нового формата даже выше, чем оригинального, но тут надо еще проводить испытания. На реале я пока что ничего не испытывал, нет возможности. Поэтому, если кто-нибудь может проверить мою систему на реале с магнитофоном - это будет очень полезно для проекта.
Загрузчик также может корректно принимать инвертированный сигнал - для тех случаев, когда тракт магнитофона его инвертирует.
Скорость. Тут ситуация не очень простая. Формат 8b/10b дает постоянную скорость записи независимо от состава данных, однако скорость оригинального синклеровского формата зависит от их состава. У синклеровского формата на запись 8 нулей расходуется 16 временных интервалов по 0.25мс, а на запись 8 единиц - 32 интервала. У формата
8b/10b для записи любых 8 бит используется 10 интервалов. Поэтому, если все данные нулевые - то формат 8b/10b дает приращение скорости записи в 1.6 раза, если все единицы - в 3.2 раза, а если данные содержат примерно одинаковое количество нулей и единиц, что имеет место в случае компрессированных данных - то средняя скорость записи выше оригинала в 2.4 раза.
Контроль ошибок. В своей реализации формата я применил контрольную сумму Флетчера, которая имеет лучшую способность к обнаружению ошибок, чем простая битовая четность, примененная в оригинальном синклеровском формате.
Применение. Думаю, что формат мог бы найти применение у тех владельцев реалов, которые все еще используют магнитофон для загрузки программ. Можно делать новые кассетные релизы
дем или игр в этом формате. Также из него могла бы получиться неплохая защита от копирования, если бы это в настоящее время имело смысл.
"Музыка загрузки". Данный формат, как и оригинальный синклеровский, дает некоторую "музыкальность" на последовательностях данных, содержащих закономерности. Попробуйте сохранить в нем какой-нибудь экран, например! На случайных данных звук сигнала 8b/10b ближе к "белому шуму". Это и логично: повышение плотности записи при той же полосе частот должно приближать сигнал к шумоподобному виду.
Приложение. Программы сохранения и загрузки, имеющие такой же интерфейс, как и оригинальные синклеровские загрузчик и сохранялка. LD IX, addr, LD DE, len, LD A, flag. Также прилагается программа на Си, которая конвертирует tzx- и bin-файлы в tzx- или csw-файлы в кодировке 8b/10b, так что их можно подставить загрузчику на эмуляторе или реале.
Надеюсь, кому-нибудь будет интересно!
Вторая версия от 25.05.2013 (устарела)
Последнее обновление от 17.07.2013: существенно улучшена работа загрузчика, уменьшено фазовое дрожание ФАПЧ, верхний предел скорости записи поднят до +30% (было +25%). Новая программа на Си (исходник и екзешник) для создания tzx- и csw-файлов с данными в формате 8b/10b.