Чувствуется, идея плавно подползает к Core i7, как предполагали изначально ;-) А Мега 8515 не подойдёт, на ней самоделок много и она распространена среди народа?
Вид для печати
Действительно, ардуино без экрана (atmega328), выбор на спектруме, разве не оптимальный вариант в плане легкости повторения
и низкой стоимости?
TRD где то кроме спектрума используется? А без экрана легко сделать, есть несколько сигналов которые либо минуют ВГ93 либо достаточно легко читаются через регистр статуса, к примеру INDEX, Выбор дисковода, SIDE
может еще что то, нужно смотреть, но уже этих сигналов достаточно что бы без экрана реализовать обмен с контроллером
- - - Добавлено - - -
Arduino c 328 уже готовый девайс, подключил шильд с SD у устройство без производства готово
Скорее всего видели, на всякий случай, может наведёт на какие полезные мысли..
SD-контроллер Vinxru
https://youtu.be/lo2y5ZJLkPo?t=7m30s
https://github.com/vinxru/86RKSD
ps может уже есть подобный контроллер SD карт для спектрума?
- - - Добавлено - - -
Сделать только для спектрума, для начала, лучше меньше, да лучше)
UPD:
Controlling Floppy Disk Drive with Arduino
http://arduino.stackexchange.com/que...e-with-arduino
UPD2:
Флеш-карта с интерфейсом FDD
http://hxc2001.free.fr/floppy_drive_...Floppyemulator
http://kazus.ru/forums/showpost.php?...56&postcount=6
http://zx-pk.ru/showthread.php?t=13735
http://service4u.narod.ru/html/emulator.html
В идеале, предусмотреть модульность как в железе, так и в софте, т.е. экран цепляется по желанию.
Обычно - контроллер выбирают под задачу! А не задачу урезают под контроллер! :) Выбрать контроллер с 2-4мя кб рам минимум - ну как бы совершенно не проблема! Но как обычно вмешивается "да у меня мешок контроллеров .... модели в любимом мной xxx корпусе..." И начинается год бодания с ограничениями железа. В конце концов - оказывается что реализовать базовые хотелки с лету не получается и проект тихо умирает :) . Знакомая ситуация. Для не любителей ARM есть еще вполне ногодрыгательный С51 и по моему даже с достаточным количеством ОЗУ на борту - силабс делает мешок целый.
328p по идее должно с головой хватить, он же юзается в Ardiuno Uno
Да, именно на нем и начну, скорее всего это оптимальный вариант, попробую взять одну дорожку из TRD и загнать её во флеш, потом генерить все остальные из неё :) т.е. проверить будет ли отображаться оглавление на эве, если да. то буду уже карту цеплять.
PS: насчет 8535, посмотрел даташит на него, нет там Master SPI у USART, так же как и у 8-ой атмеги, у Atmega128, как оказалось, его тоже нет, пичалька...
Рискну даже начать это реализовывать прямо на ардуине :) Если не хватит ресурсов тогда на студию перейду. Разумеется без всяких там digitalWrite :) Начну завтра, завтра буду посвободнее, ну и прощайте выходные, конечно же :)
У меня конечно есть PIC18F4620, но это на самый крайний случай... Хотя там разницы с 328 атмегой практически нет
Может учесть все плюсы и минусы, цену, доставаемость, грядущие проблемы с авр.
И уже исходя из этого заложить камень.
Авр в данном случае имеет лишь один плюс и то лишь для адепетов. В остальном сливает по полной во всем...
это фигня какая то, не должен он пульсировать, может подтяжка на стороне дисковода отвалилась, либо звон, либо не туда подключен
- - - Добавлено - - -
discovery стоит раза в 4 дороже arduino, я думаю тут в другом дело, одно дело выжать из железа 146% другое, взять арм на с++ жуя семечки неспешно заниматься скучной вещью, arm не интересно, напрягаться не надо
- - - Добавлено - - -
Еще стоит учеть момент, возможно человек знает avr, смысл ему тратить н-ное кво месяцевечеров осваивая новое
Так посудить, спектрум тоже ниочем по сравнению с современными пк..
Atmega128 распространенный, недорогой, и судя по всему достаточный вариант,
от того искать что-то более модное не обязательно.
А сколько атому обвязки надось, ась? А здесь меньше габарит той меги, единственное соглпсование уровней.
да микромодуль, уже со всей обвязкой + wifi на борту, подал питание, он уже работает, припаял дип штыри, можно хоть в бредборду вставлять
- - - Добавлено - - -
вот такого плана модули
только подешевле, поменьше бывают, лень искать
Так, сгенерил на ардуине сигнал, но выбрать данные из 2 массивов в прерывании оно не успевает, видимо много пушей там, так что придется всё-таки переходить на асм или Algoritm Builder, второе мне кажется предпочтительнее. Вариант с HFE пока что рассматривать не хочу, хочется всё-таки TRD.
Нижний это клок, с периодом 2мкс
На ардуине - это с использованием бабуиновской IDE, компилятора и библиотек, где на каждую инструкцию кода добавляется еще 10 мусорных?
Что именно пытались генерить и насколько сильно не успевает AVR?
Пушей "видимо много", или на самом деле много (легко понять по листингу)?
GCC с ассемблерными вставками как вариант не рассматриваете?
Библиотека работы с SDHC и FAT32 на ассемблере или Algoritm Builder-е уже существует или планируете писать и отлаживать сами?
Можно, но толку от них, если неизвестно, что в каком регистре и их нужно сохранять перед использованием
Вот такая LPM конструкция работает нормально
а вот такая уже нетЦитата:
ISR(USART_UDRE_vect)
{
tmp2 = MFM_tab[1];
UDR0=(byte)(tmp2 >> 8);
UDR0=(byte)tmp2;
}
GCC со вставками опять же упрется в сохранение регистров.Цитата:
ISR(USART_UDRE_vect)
{
tmp2 = MFM_tab[track0[i++]];
UDR0=(byte)(tmp2 >> 8);
UDR0=(byte)tmp2;
}
Для AB думаю не составит большой сложности FatFs переделать, там кода не много.
В принципе, если на компе TRD перегнать в MFM, и потом эти данные выдавать, то ардуины должно хватить (теоретически)
а вот такая уже нет
ISR(USART_UDRE_vect)
{
tmp2 = MFM_tab[track0[i++]];
UDR0=(byte)(tmp2 >> 8);
UDR0=(byte)tmp2;
}
это на ассемблере делать нужно
причем что бы шустрее работало, MFM_tab выравнять в памяти по 256байт граице, в ISR можно сказать каждый такт на счету
причем что бы быстрее было, 2 таблицы, сначала 256 старших байт, потом младших
Идея писать все на ассемблере - это преждевременная оптимизация, классическая ошибка проектирования. GCC умеет оптимизировать код, тем более, такой тривиальный. Перенос на ассемблер может дать не более ~10% ускорения, что в данном случае не имеет никакого значения.
Для начала надо оптимизировать код на Си. А для этого надо смотреть его ассемблерный листинг.
Сейчас бросаются в глада две вещи:
1. MFM_tab[track0[i++]] - зачем тут два массива? нельзя сразу поместить подготовленные данные в массив track_data[] ?
2. ну и да, алгоритм надо преобразовать так, чтобы индексы были однобайтными - это сокращает код в разы.
Перегонять TRD во что угодно можно и на самом девайсе - есть SD-карта, и ничто не мешает на нее сохранять временные данные в любом удобном формате
тогда на буфер сектора надо будет 512 байт а не 256
- - - Добавлено - - -
как вариант можно нечто такое расмотреть
тело ISR где то 19 тактов, GCC раз 5 больше выхлоп даетКод:
alignas(256) static const uint8_t mfmtab_h[256] = { .... };
alignas(256) static const uint8_t mfmtab_l[256] = { ... };
alignas(256) static uint8_t sect_data[2][256];
register uint8_t rdbuff asm("r3"); // тут держим старшую половину адреса текущего буфера
register uint8_t rdpos asm("r4"); // тут позиция в буфере
ISR(USART_UDRE_vect, ISR_NAKED)
{
asm ("push r31");
asm ("push r30");
asm ("push r29");
// формируем указатель в буфере сектора
asm ("mov r31, r3");
asm ("mov r30, r4");
// читаем данные из буфера сектора
asm ("ld r29, Z");
asm ("inc r3");
// формируем указатель на mfmtab_h
asm ("ldi r31, hi8(mfmtab_h)");
asm ("mov r30, r29");
// чтение mfm_h
asm ("lpm r29, Z");
asm ("sts 0xc9, r29");
// формируем указатель на mfmtab_l
asm ("inc r31");
// чтение mfm_l
asm ("lpm r29, Z");
asm ("sts 0xc9, r29");
asm ("pop r29");
asm ("pop r30");
asm ("pop r31");
asm ("reti");
/* аналог на Си
uint8_t* pos = (uint8_t*)((rdbuff << 8) | rdpos);
UDR0 = mfmtab_h[*pos];
UDR0 = mfmtab_l[*pos];
rdpos++;
*/
}
Ерунда. В данном случае писать на ассемблере можно и нужно, особенно если прикинуть длительность bit cell (500нс) и время выполнения однотактовой AVR инструкции на 16МГц (62.5нс).
Топикстартеру - я это все уже проходил на ATmega256@16MHz. Помогал только выпрямленный tight loop c очень плотным кодированием по тактам, а также высушенные и обрезанные по самое немогу обработчики прерываний. Да, и еще у меня была привешана внешняя DRAM c программной же регенерацией.
Мой вам совет (с) маркер из "Шерлока Холмса" - выкинуть AVR и взять любой STM32.
- - - Добавлено - - -
Например, самый простой из семейства STM32F0 на Терраэлектронике - 84р (восемьдесят четыре рубля, Карл!). Тактовая 48МГц, фигова куча периферии - а кстати, для формирования MFM потока можно использовать SPI, - и вообще.
итого при 120 инструкций на байт MFM, ISR в 20-30 тактов, оставляет уйму времени для подкачки данных с SDCARD, 20-25% времени ядра на ISR это ниочем, зачем тут ARM с кучей не нужной для задачи перефирии?
Кстати в ARM почти весь профит от частоты съест вход в ISR, возможно даже будет не хватать
А разве 256 байт - это критично для m328? Массивы mfmtab так вообще 512 байт занимают..
На ассемблере есть смысл писать критичные к скорости выполнения куски кода в конечном приложении. Это позволить немного ускорить код. Сейчас же речь о прототипе, который только формирует сигнал и ничего при этом не делает, с картой не работает. Эти 10% выигрыша быстродействия тут не должны играть решающую роль. Когда добавится работа с картой требования к процессорному времени, затрачиваемому на формирования сигнала могут возрасти.
Проходил нечто подобное когда делал поддержку воспроизведения WAV 44100 Гц в своём магнитофоне. Сначала все тормозило и скорости не хватало. Переписывания кода обработчика прерывания на Си, разбиение массивов длиной 512 байт на два массива по 256 байт дало ощутимый прирост в скорости выполнения. Небольшие оптимизации библиотеки поддержки SD-карты и FAT-а (разворачивания циклов, inline-зация нескольких функций и отключение лишних проверок) ещё немного ускорило прошивку.
Потом переписал обработчик прерывания на ассемблер. Да, он стал работать чуть быстрее, но основной вклад внесла именно оптимизация Си-кода и отказ от 16-битных индексов массивов.
PS. использование 48МГц МК для эмуляции флопа для компьютеров, частота которых измеряется единицами МГц - как-то неприлично, имхо :)
один буфер выводится, второй в это время заполняется на каждый надо по 512байт, если сразу в буфере mfm держать
- - - Добавлено - - -
причем затраты +- одинаковые на преобразования 256 байт данных в 512 mfm, разница только где это время будет потрачено в ISR или главном цикла, что по мне все равно, а вот расход памяти сразу виден, причем без веской причины
У меня тут мысль появилась, а зачем нам вообще эти 512байт? Можно же читать не весь сектор, а скажем по 64 или 128 байт, наверное лучше 128, чтобы получилось как раз 256 в MFM, из считанных данных гнать в MFM по кольцу через 2 указателя. Основная проблема будет с подсчетом последнего бита и с CRC. При переключении на дургую сторону можно один оборот прогнать то что заполняется
Ктати, SWAP, ROL и AND 0x1F экономит нам 224 байт под MFM_tab_h, т.к. таблица там такая
MFM_tab_l, думаю аналогично, тут даже меньше, всего 16 значений, хватит одного AND 0x0FЦитата:
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,
0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,
0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,
0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,
0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,
0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,
0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,
0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,
0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,0x8A,
0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,0xA4,
0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,
0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,0xA9,
0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,
0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
Цитата:
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
0x55,0x52,0x49,0x4A,0x25,0x22,0x29,0x2A,
0x95,0x92,0x89,0x8A,0xA5,0xA2,0xA9,0xAA,
И еще там есть DMA, что для циклически повторяющихся задач (к которым и относится проигрывание дорожки) вообще идеально подходит.
- - - Добавлено - - -
Не очень понятно, откуда оценка в 20-30 тактов на ISR (и что ISR делает?). Далее, с SD данные подкачивать нужно, видимо, с файловой системой (FatFS/TinyFS/PicoFS/etc), что совсем не быстро, если предполагается это делать периодически ввиду отсутствия буфера на дорожку.
Опять же, с какого перепугу в ARM профит будет съедать вход в ISR? мне немножечко приходилось работать с тем и с другим, уверяю, это достаточно быстро даже на 48МГц.
Если у вас идиосинкразия на ARM, тогда другое дело. Наличие ненужной периферии огорчает? Возьмите Z80, будет благолепно. Просто я не понимаю, отчего не взять современный дешевый (84р, да?) МК с кучей возможностей уже включенных в эти 84р, если нужно решить задачу, а не потрахаться :)
- - - Добавлено - - -
Дисковод от ленты немножечко отличается. Скажем, у дисковода есть определенные требования к скорости позиционирования головок (читай - к загрузке/отдаче новой дорожки) - допустим, 3мс на шаг и 15мс на стабилизацию после последнего шага. Для достоверной эмуляции хорошо бы эти требования выдерживать. Есть платформы, под которые существует ненулевое количество софта, смертельно обижающегося на "неуспеваемость" эмуляции.
Про неприличность 48МГц - ну вы же наверняка пользуетесь часами в смартфоне, без особых угрызений совести :)
512 байт - размер сектора SD-карты, читать блоками меньшего размера будет, скорее всего, неудобно, если использовать готовые библиотеки.
Так интерес, насколько понимаю, как раз в том, чтобы сделать самому, и не палить при этом из пушки по воробьям :) Ну и да, потрахаться, но сделать ретро-железку на почти-ретро-микроконтроллере :)Цитата:
Сообщение от tnt23
Кстати, в случае использования STM придётся же конвертер 3.3В <-> 5.0В ставить?
Так то телефон, я же с него не только время смотрю, а еще звоню и всякими там интернетами пользуюсь :) Но если бы делал простые часы, то точно взял бы AVR-ку, а не ARM 48МГц :)Цитата:
Сообщение от tnt23
Ну, давайте еще вспомним STM8... та же атмега8...
PS: alignas ардуина не понимает, а вот регистры мапить дает, уже плюс!
Вот такая штука в ардуинке отлично работает
.........устаревший код удален, см. код на следующей странице.........
PS: вариант с размещением таблиц во флеше отпадает, т.к. скорость считывания очень медленная, только SRAM.
код выше, выводит через SPI MFM
можно при открытии файла получить список всех кластеров и расчитать координаты всех секторов образа, тогда в основном цикле будет тупо чтение с SD карты по известным номерам
ну смотре, мега 20мгц 4такта вход, арм 48 мгц, 12тактов вход, + NVIC
тут другое, avr достаточно по ресурсам + доступность dip корпуса (берборды беспаечные) + ардруина (цена в несколько раз доступнее того же дискавери), человек судя по сайту с Avr знаком
был аргумент что там круче перефирия, он то так, только какая разница если не юзается
дискавери дороже, ардуина у каждого 3 имеется (наличие usb-com + мега в дипе + бердборда, считай у тебя есть ардуина)
решается вообще без напрягов
- - - Добавлено - - -
PS: задрали проповедники ARM, в каждую ветку с AVR лезут, чешется что ли?
Я не проповедник ARM, и лезу не в каждую ветку, а конкретно думал, что мой опыт реализации эмулятора дисковода на AVR кому-то может быть полезен.
>>PS: alignas ардуина не понимает, а вот регистры мапить дает, уже плюс!
Alidnas это нужно компилятору сказать что нужно ждать c11 или gnu-c99
Если есть опыт реализации на AVR, так поделитесь опытом реализации на AVR :-D
А то, как пример, я бы спросил, на каком транзисторе лучше сделать усилитель для пищалки, а мне бы стали советовать какую TDA выбрать... всё, на этом умолкаю насчет AVR, STM, PIC и т.д. Проект будет на AVR, кому хочется сделать на другом - делайте, выкладывайте, думаю, все будут рады.
PS: просьба к спецам, проинспектируйте код на предыдущей странице на предмет оптимизации и сохранения регистров. Код 100% рабочий, сигналы генерируются корректно, проверил лог анализатором.
При такой реализации получается кодирование данных в коде ISR, т.е. буфер под данные остается размером с сами данные! Ну и под заголовки дорожки/сектора нужно будет что-то придумать. С CRC пока что не знаю, то ли при переключении дорожек генерить, то ли еще как, но все не войдут в память при монтировании, получается 2.5кб данных. Еще вариант сгенерить CRC во временный файл при монтировании.