Важная информация

User Tag List

Показано с 1 по 10 из 530

Тема: Планирую сделать FDD эмулятор на Atmega8

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Master
    Регистрация
    20.01.2016
    Адрес
    п. Власиха, Московская обл.
    Сообщений
    593
    Спасибо Благодарностей отдано 
    6
    Спасибо Благодарностей получено 
    32
    Поблагодарили
    19 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Планирую сделать FDD эмулятор на Atmega8

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

    После обсуждений решено, что проект будет реализовываться на Arduino!

    Проект уже работает на Arduino с SD картой! Поддерживается только чтение, записи нет!

    Внимание, при использовании Arduino Pro Mini пины RX/TX расположены наоборот!

    Исходники проекта на GitHub: https://github.com/EvgeniyRU/ZX_FDD_Emulator Схема подключения находится там же.
    В GitHub можно скачать любую предыдущую версию прошивки выбрав в списке коммитов https://github.com/EvgeniyRU/ZX_FDD_...commits/master нужный коммит, затем Browse Files (справа), затем Clone or Download и после Download ZIP


    В последних версиях работа ведется с SD/SDHC/MMC картой, файловая система FAT32, поддерживаются карты от 512Мб до 32Гб, больше не проверялись. Данные берутся из TRD образов, дисплей 1602.


    За основу взята следующая спецификация флопа FD1035_Product_Description_Jul84.pdf.
    Еще вот этот документ принимается во внимание http://www.mcamafia.de/pdf/ps2_fdd_trm_s42g2194_00.pdf

    Насколько я понимаю, работа с устройством происходит по сигналам

    1. DRIVE SELECT выбирает нужное устройство из 4-ех DS0-DS3, на нужном устанавливается уровень LOW (INPUT)
    2. STEP двигает голову на дорожку вперед/назад в зависимости от сигнала DIRECTION (INPUT)
    3. DIRECTION - направление движения головок HIGH - к центру, LOW - к краю (track 0).
    4. SIDE SELECT выбирает сторону HIGH - Head 0, LOW - Head 1 (INPUT)
    5. WRITE GATE определяет ЧТЕНИЕ[HIGH]/ЗАПИСЬ[LOW] (INPUT)
    6. WRITE DATA данные которые записываются на дискету (INPUT)
    7. MOTOR ON - запуск шпинделя LOW запуск, HIGH останов (INPUT)
    8. TRK00 - генерируется, если головка на нулевой дорожке, LOW означает, что мы на нулевой дорожке (OUTPUT)
    9. READY - насколько я понял, для ZX не актуален (OUTPUT) ***
    10. READ DATA - данные считываемые с дискеты и отправляемые в BDI (OUTPUT) формат MFM
    11. WRITE PROTECT - генерируется для защиты от записи (LOW), на этапе разработки он всегда будет генерироваться, пока не заработает чтение нормально, потом уже перейду к разработке записи, если это будет представляться возможным. (OUTPUT)

    Принцип работы устройства (насколько я пока что понимаю)

    1. Читаем нулевой цилиндр, вычисляем CRC для секторов нижней и верхней дорожки, выставляем TRK00
    (можно вычислить CRC для всех дорожек при монтировании)

    2. Организуется цикл c выходом на повтор, если нужный нам DS в положении HIGH
    Как только он стал LOW и MOTOR ON - LOW начинаем обрабатывать

    3. Обработчик
    a) Вешаем пин STEP на прерывание.
    b) Методично (циклично) шлем данные дорожки посекторно в READ DATA в формате MFM, пульсируя INDEX в начале отправки дорожки
    b2) После отправки сектора проверяем DS и MOTOR ON, если не наши значения, отключаем прерывания, переходим на пункт 2
    ------------------------
    Функция STEP (в обработчике прерывания)
    1. Проверяем DIRECTION, HIGH - увеличиваем дорожку (прибавляем к смещению 8192 байт), LOW - проверяем, если дорожка больше нуля - уменьшаем (вычитаем 8192 байт), если дорожка стала = 0, ставим TRACK00 в LOW.
    2. Если трек изменился ставим флаг об изменении трека.
    3. Выходим из прерывания.



    Вроде с виду всё просто, но есть много вопросов.


    1. Где посмотреть формат передаваемых данных (READ DATA, WRITE DATA) Уже разобрался
    2. Как происходят операции с секторами, пишется/читается вся дорожка целиком? С этим тоже разобрался
    3. Почему вход SIDE пульсирует? (тоже разобрался, в процессе чтения сторона может измениться в любой момент)

    То что уже нашел буду отмечать красным, то что уже неактуально зеленым.

    Информацию по сигналам возьму отсюда http://zx-pk.ru/showthread.php?t=126...l=1#post825463


    Нашел еще интересную информацию:
    http://www.avrfreaks.net/comment/328274#comment-328274


    PS: по форматам дорожек нашел инфу, есть в экселевском файле по ссылке про сигналы, но в книжке Ларченко и Родионова приводится немного другая инфа http://zxpress.ru/book_articles.php?id=1868 http://zxpress.ru/article.php?id=8992 Кому верить? (оказалось, формат может немного отличаться)


    PS2: Так в целом понятно по формату дороги, если смотреть по экселю, там для адресного поля CRC можно заранее табличку сделать в коде прошивки, данные подсовываются в поле данных, с этим тоже не сложно, 256 байт можно в памяти хранить и считывать следующие перед генерацией INDEX, вот CRC для поля данных налету генерировать это уже сложнее, хотя в процессе отправки думаю можно успеть, а можно и при открытии образа сгенерировать, но налету кажется это сделать проще.
    Налету оказалось достаточно просто генерировать CRC по таблице размещенной во Flash памяти

    PS3: пожалуй начну с того, что буду генерировать пустой образ дискеты, т.е. чистой отформатированной, если диск доктор начнет читать нормально нули в секторах, то буду двигаться дальше. Это было сделано достаточно быстро

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

Название:	track_format.jpg 
Просмотров:	1312 
Размер:	41.6 Кб 
ID:	56523

    Окончательный вариант формата дорожки, в конце дорожки 598 байт это крайний случай, реально конечно будет меньше
    Нажмите на изображение для увеличения. 

Название:	track_format2.jpg 
Просмотров:	931 
Размер:	27.4 Кб 
ID:	56524
    ВНИМАНИЕ!!! В описании дорожки данные в ячейках A1 и C2 являются командами контроллера дисковода! Т.е. на их месте в закодированном виде должны быть значения 0x4489 и 0x5224 соответственно

    Генерация CRC16 для Адресного поля и Поля данных
    Используется CRC-CCITT нач. значение 0xFFFF, полином 0x1021. Кодируются данные вместе с A1 и маркером, начиная с первого значения 0xA1, т.е. используется именно A1!!!



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

Название:	diagram.jpg 
Просмотров:	761 
Размер:	54.7 Кб 
ID:	56526

    Выходит, по приходу сигнала MOTOR ON дисковод начинает слать данные в READ DATA без перерыва и WG и WD стоят неактивные в режиме чтения, так что всё еще проще оказалось.

    Расписываю основные времянки, снимал на частоте 1МГц:
    INDEX - LOW - 3.52ms, между индексами HIGH примерно 196ms, погрешность 0.1%
    MOTOR активен LOW пока требуется чтение
    WR GATE, WR DATA всегда не активны HIGH в режиме чтения
    TRK00 всегда выставлено LOW после прихода MOTOR ON
    STEP период четко 3мс, пульс 1-2мкс

    READ DATA пульсирует LOW на время 1мкс, вот как выглядит
    Нажмите на изображение для увеличения. 

Название:	read_data.jpg 
Просмотров:	630 
Размер:	12.2 Кб 
ID:	56527
    Интервал окна составляет 4, 6 и 8 мкс


    ВАЖНО! По поводу кодирования в MFM отличная инфа здесь http://firmware.altervista.org/Data%...20Decoding.htm и тут http://info-coach.fr/atari/hardware/...le_of_CRC_Code

    Вот из этой картинки становится понятно, что и как кодируется




    Схема кодирования такая

    Например, есть байт 0xC6 - 1100 0110

    Если бит данных равен 1, то он заменяется на 01
    Если бит данных равен 0, предыдущий бит равен 0, то он заменяется на 10
    Если бит данных равен 0, предыдущий бит равен 1, то он заменяется на 00

    Кодированными данными будет значение |01|01|00|10|10|01|01|00|

    Разбиваем это по биту 1, получаем 10, 100, 10, 100, 10, 100

    На выходе получаем сигналы такой последовательности:
    4мкс(10), 6мкс(100), 4мкс(10), 6мкс(100), 4мкс(10), 6мкс(100)

    Остается только скорректировать первый бит последовательности в потоке данных, если старший бит равен 0, то проверить младший предыдущего, и на основе этого скорректировать.

    Получается такая схема, если встретилась единица в потоке данных, то опускаем уровень в LOW на 1мкс, затем поднимаем и ждем 1мкс, если встретился ноль, то просто ждем 2мкс, всё оооочень просто

    Кодировать данные проще всего по таблице ОБНОВЛЕНА 28.03.2016
    0xAAAA, 0xAAA9, 0xAAA4, 0xAAA5, 0xAA92, 0xAA91, 0xAA94, 0xAA95,
    0xAA4A, 0xAA49, 0xAA44, 0xAA45, 0xAA52, 0xAA51, 0xAA54, 0xAA55,
    0xA92A, 0xA929, 0xA924, 0xA925, 0xA912, 0xA911, 0xA914, 0xA915,
    0xA94A, 0xA949, 0xA944, 0xA945, 0xA952, 0xA951, 0xA954, 0xA955,
    0xA4AA, 0xA4A9, 0xA4A4, 0xA4A5, 0xA492, 0xA491, 0xA494, 0xA495,
    0xA44A, 0xA449, 0xA444, 0xA445, 0xA452, 0xA451, 0xA454, 0xA455,
    0xA52A, 0xA529, 0xA524, 0xA525, 0xA512, 0xA511, 0xA514, 0xA515,
    0xA54A, 0xA549, 0xA544, 0xA545, 0xA552, 0xA551, 0xA554, 0xA555,
    0x92AA, 0x92A9, 0x92A4, 0x92A5, 0x9292, 0x9291, 0x9294, 0x9295,
    0x924A, 0x9249, 0x9244, 0x9245, 0x9252, 0x9251, 0x9254, 0x9255,
    0x912A, 0x9129, 0x9124, 0x9125, 0x9112, 0x9111, 0x9114, 0x9115,
    0x914A, 0x9149, 0x9144, 0x9145, 0x9152, 0x9151, 0x9154, 0x9155,
    0x94AA, 0x94A9, 0x94A4, 0x94A5, 0x9492, 0x9491, 0x9494, 0x9495,
    0x944A, 0x9449, 0x9444, 0x9445, 0x9452, 0x9451, 0x9454, 0x9455,
    0x952A, 0x9529, 0x9524, 0x9525, 0x9512, 0x9511, 0x9514, 0x9515,
    0x954A, 0x9549, 0x9544, 0x9545, 0x9552, 0x9551, 0x9554, 0x9555,
    0x4AAA, 0x4AA9, 0x4AA4, 0x4AA5, 0x4A92, 0x4A91, 0x4A94, 0x4A95,
    0x4A4A, 0x4A49, 0x4A44, 0x4A45, 0x4A52, 0x4A51, 0x4A54, 0x4A55,
    0x492A, 0x4929, 0x4924, 0x4925, 0x4912, 0x4911, 0x4914, 0x4915,
    0x494A, 0x4949, 0x4944, 0x4945, 0x4952, 0x4951, 0x4954, 0x4955,
    0x44AA, 0x44A9, 0x44A4, 0x44A5, 0x4492, 0x4491, 0x4494, 0x4495,
    0x444A, 0x4449, 0x4444, 0x4445, 0x4452, 0x4451, 0x4454, 0x4455,
    0x452A, 0x4529, 0x4524, 0x4525, 0x4512, 0x4511, 0x4514, 0x4515,
    0x454A, 0x4549, 0x4544, 0x4545, 0x4552, 0x4551, 0x4554, 0x4555,
    0x52AA, 0x52A9, 0x52A4, 0x52A5, 0x5292, 0x5291, 0x5294, 0x5295,
    0x524A, 0x5249, 0x5244, 0x5245, 0x5252, 0x5251, 0x5254, 0x5255,
    0x512A, 0x5129, 0x5124, 0x5125, 0x5112, 0x5111, 0x5114, 0x5115,
    0x514A, 0x5149, 0x5144, 0x5145, 0x5152, 0x5151, 0x5154, 0x5155,
    0x54AA, 0x54A9, 0x54A4, 0x54A5, 0x5492, 0x5491, 0x5494, 0x5495,
    0x544A, 0x5449, 0x5444, 0x5445, 0x5452, 0x5451, 0x5454, 0x5455,
    0x552A, 0x5529, 0x5524, 0x5525, 0x5512, 0x5511, 0x5514, 0x5515,
    0x554A, 0x5549, 0x5544, 0x5545, 0x5552, 0x5551, 0x5554, 0x5555,
    0x00:0xAAAA, 0x01:0xAAA9, 0x02:0xAAA4, 0x03:0xAAA5, 0x04:0xAA92, 0x05:0xAA91, 0x06:0xAA94, 0x07:0xAA95,
    0x08:0xAA4A, 0x09:0xAA49, 0x0A:0xAA44, 0x0B:0xAA45, 0x0C:0xAA52, 0x0D:0xAA51, 0x0E:0xAA54, 0x0F:0xAA55,
    0x10:0xA92A, 0x11:0xA929, 0x12:0xA924, 0x13:0xA925, 0x14:0xA912, 0x15:0xA911, 0x16:0xA914, 0x17:0xA915,
    0x18:0xA94A, 0x19:0xA949, 0x1A:0xA944, 0x1B:0xA945, 0x1C:0xA952, 0x1D:0xA951, 0x1E:0xA954, 0x1F:0xA955,
    0x20:0xA4AA, 0x21:0xA4A9, 0x22:0xA4A4, 0x23:0xA4A5, 0x24:0xA492, 0x25:0xA491, 0x26:0xA494, 0x27:0xA495,
    0x28:0xA44A, 0x29:0xA449, 0x2A:0xA444, 0x2B:0xA445, 0x2C:0xA452, 0x2D:0xA451, 0x2E:0xA454, 0x2F:0xA455,
    0x30:0xA52A, 0x31:0xA529, 0x32:0xA524, 0x33:0xA525, 0x34:0xA512, 0x35:0xA511, 0x36:0xA514, 0x37:0xA515,
    0x38:0xA54A, 0x39:0xA549, 0x3A:0xA544, 0x3B:0xA545, 0x3C:0xA552, 0x3D:0xA551, 0x3E:0xA554, 0x3F:0xA555,
    0x40:0x92AA, 0x41:0x92A9, 0x42:0x92A4, 0x43:0x92A5, 0x44:0x9292, 0x45:0x9291, 0x46:0x9294, 0x47:0x9295,
    0x48:0x924A, 0x49:0x9249, 0x4A:0x9244, 0x4B:0x9245, 0x4C:0x9252, 0x4D:0x9251, 0x4E:0x9254, 0x4F:0x9255,
    0x50:0x912A, 0x51:0x9129, 0x52:0x9124, 0x53:0x9125, 0x54:0x9112, 0x55:0x9111, 0x56:0x9114, 0x57:0x9115,
    0x58:0x914A, 0x59:0x9149, 0x5A:0x9144, 0x5B:0x9145, 0x5C:0x9152, 0x5D:0x9151, 0x5E:0x9154, 0x5F:0x9155,
    0x60:0x94AA, 0x61:0x94A9, 0x62:0x94A4, 0x63:0x94A5, 0x64:0x9492, 0x65:0x9491, 0x66:0x9494, 0x67:0x9495,
    0x68:0x944A, 0x69:0x9449, 0x6A:0x9444, 0x6B:0x9445, 0x6C:0x9452, 0x6D:0x9451, 0x6E:0x9454, 0x6F:0x9455,
    0x70:0x952A, 0x71:0x9529, 0x72:0x9524, 0x73:0x9525, 0x74:0x9512, 0x75:0x9511, 0x76:0x9514, 0x77:0x9515,
    0x78:0x954A, 0x79:0x9549, 0x7A:0x9544, 0x7B:0x9545, 0x7C:0x9552, 0x7D:0x9551, 0x7E:0x9554, 0x7F:0x9555,
    0x80:0x4AAA, 0x81:0x4AA9, 0x82:0x4AA4, 0x83:0x4AA5, 0x84:0x4A92, 0x85:0x4A91, 0x86:0x4A94, 0x87:0x4A95,
    0x88:0x4A4A, 0x89:0x4A49, 0x8A:0x4A44, 0x8B:0x4A45, 0x8C:0x4A52, 0x8D:0x4A51, 0x8E:0x4A54, 0x8F:0x4A55,
    0x90:0x492A, 0x91:0x4929, 0x92:0x4924, 0x93:0x4925, 0x94:0x4912, 0x95:0x4911, 0x96:0x4914, 0x97:0x4915,
    0x98:0x494A, 0x99:0x4949, 0x9A:0x4944, 0x9B:0x4945, 0x9C:0x4952, 0x9D:0x4951, 0x9E:0x4954, 0x9F:0x4955,
    0xA0:0x44AA, 0xA1:0x44A9, 0xA2:0x44A4, 0xA3:0x44A5, 0xA4:0x4492, 0xA5:0x4491, 0xA6:0x4494, 0xA7:0x4495,
    0xA8:0x444A, 0xA9:0x4449, 0xAA:0x4444, 0xAB:0x4445, 0xAC:0x4452, 0xAD:0x4451, 0xAE:0x4454, 0xAF:0x4455,
    0xB0:0x452A, 0xB1:0x4529, 0xB2:0x4524, 0xB3:0x4525, 0xB4:0x4512, 0xB5:0x4511, 0xB6:0x4514, 0xB7:0x4515,
    0xB8:0x454A, 0xB9:0x4549, 0xBA:0x4544, 0xBB:0x4545, 0xBC:0x4552, 0xBD:0x4551, 0xBE:0x4554, 0xBF:0x4555,
    0xC0:0x52AA, 0xC1:0x52A9, 0xC2:0x52A4, 0xC3:0x52A5, 0xC4:0x5292, 0xC5:0x5291, 0xC6:0x5294, 0xC7:0x5295,
    0xC8:0x524A, 0xC9:0x5249, 0xCA:0x5244, 0xCB:0x5245, 0xCC:0x5252, 0xCD:0x5251, 0xCE:0x5254, 0xCF:0x5255,
    0xD0:0x512A, 0xD1:0x5129, 0xD2:0x5124, 0xD3:0x5125, 0xD4:0x5112, 0xD5:0x5111, 0xD6:0x5114, 0xD7:0x5115,
    0xD8:0x514A, 0xD9:0x5149, 0xDA:0x5144, 0xDB:0x5145, 0xDC:0x5152, 0xDD:0x5151, 0xDE:0x5154, 0xDF:0x5155,
    0xE0:0x54AA, 0xE1:0x54A9, 0xE2:0x54A4, 0xE3:0x54A5, 0xE4:0x5492, 0xE5:0x5491, 0xE6:0x5494, 0xE7:0x5495,
    0xE8:0x544A, 0xE9:0x5449, 0xEA:0x5444, 0xEB:0x5445, 0xEC:0x5452, 0xED:0x5451, 0xEE:0x5454, 0xEF:0x5455,
    0xF0:0x552A, 0xF1:0x5529, 0xF2:0x5524, 0xF3:0x5525, 0xF4:0x5512, 0xF5:0x5511, 0xF6:0x5514, 0xF7:0x5515,
    0xF8:0x554A, 0xF9:0x5549, 0xFA:0x5544, 0xFB:0x5545, 0xFC:0x5552, 0xFD:0x5551, 0xFE:0x5554, 0xFF:0x5555
    В таблице предполагается, что последний бит предыдущего байта данных был равен 0! Поэтому, если это не так, то нужно корректировать старший бит, если старший бит текущего байта данных равен нулю!


    ПОСЛЕДНИЕ ИССЛЕДОВАНИЯ ПОКАЗАЛИ, ЧТО ДАННЫЙ ШАГ МОЖНО ОПУСТИТЬ!!! Т.Е. бит можно не исправлять!!!

    Самые последние исследования показали, что достаточно менять 1 на 01, а 0 на 10 (для инвертированного сигнала наоборот) и контроллер такой сигнал нормально хавает через Master SPI
    ВНИМАНИЕ! Вышесказанное справедливо только для ВГ93!!! Если у вас другой контроллер (импортный), то, скорее всего, придется делать полное MFM кодирование, что, в принципе, делается в последних версиях прошивки.


    Сигнал генерируется с использованием USART в режиме MasterSPI (поддерживается контроллерами Atmega48/88/168/328, может еще какими-то но точно не Atmega8,128...) Затем сигнал инвертируется (проще всего программно) на выходе получается код, совместимый с MFM.

    Пример
    Код:
    uint8_t MFM_tab[32] =
    {
      0xAA,0xA9,0xA4,0xA5,0x92,0x91,0x94,0x95,0x4A,0x49,0x44,0x45,0x52,0x51,0x54,0x55,
      0x2A,0x29,0x24,0x25,0x12,0x11,0x14,0x15,0x4A,0x49,0x44,0x45,0x52,0x51,0x54,0x55,
    };
    
    first_mfm_byte = sector_byte; // current data byte
    first_mfm_byte >>= 4;
    first_mfm_byte = MFM_tab[first_mfm_byte]; // get first MFM byte from table
    if((prev_byte & 1) && !(sector_byte & 0x80)) first_mfm_byte &= 0x7F;
    
    prev_byte = sector_byte;
    
    second_mfm_byte = sector_byte & 0x1f;
    second_mfm_byte = MFM_tab[second_mfm_byte]; // get second MFM byte from table
    Спасибо за комментарии.
    Последний раз редактировалось EvgenRU; 07.01.2018 в 17:33.

  2. Эти 3 пользователя(ей) поблагодарили EvgenRU за это полезное сообщение:

    Lapu-Leen (28.07.2019), Rio444 (15.03.2023), Z80trdos (15.03.2024)

  3. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ответов: 24
    Последнее: 08.12.2012, 19:00
  2. Тестер транзисторов на ATmega8
    от ILoveSpeccy в разделе Творчество
    Ответов: 10
    Последнее: 19.05.2011, 15:03
  3. Ответов: 0
    Последнее: 31.01.2007, 18:18

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •