Олдскул, хардкор, AY-3-8912. «Железный» чиптюн с последовательным входом



    Клона Spectrum 128K, оснащенного музыкальным сопроцессором AY-3-8910 (YM2149F) у меня не было. Был 48K с расширенной клавиатурой и убогим блоком питания, перегревающим внутренности через час-два работы. От этого, помнится. домики посреди моря в Sim City образовывались и другие веселые артефакты. Но к делу данные воспоминания не относятся. Вдохновившись материалом tronix286, я решил восполнить пробел в ретро-образовании и склепать что-нибудь на легендарном (и при этом, легко добываемом и недорогом) чипе.

    В ходе изучения различных поделок, идея сформировалась следующая: надо делать модуль с последовательным (UART) входом. Чтобы его уже можно было подключить с минимальными затратами к любому девайсу, добавляя тем самым +146 к чиптюновости. В процессе также было решено освоить пару дополнительных навыков, вроде программирования AVR и изготовления печатных плат с применением фоторезиста.

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

    Синтезатор

    AY-3-8910 — это большой красивый DIP-чип на 40 ножек. Помимо нужных вещей, там еще два 8-разрядных порта, которые для вывода звука нормальными людьми (не пытающимися на них сколхозить адский аналог Covox) не используются. AY-3-8912 не менее красив, но одним «лишним» портом обделен и упакован уже в DIP28. И еще бывает AY-3-8913, вообще без параллельного порта (DIP24). И это только General Instrument / Microchip. Yamaha клепала еще больше вариаций: от YM2149F (аналог AY-3-8910 с делителем тактовой частоты) до YMZ284 (DIP16, один смикшированный выход каналов). Подробнее о чипах на Wiki (англ.).

    Управление

    Для загрузки данных используется 8-разрядный параллельный порт. Плюс, три управляющих линии (одну, которая BC2, подтягиваем к плюсу питания). Логика следующая:

    1. Исходное состояние — BC1=0, BDIR=0.
    2. Устанавливаем на ножках порта AY адрес регистра.
    3. BC1=1, BDIR=1. Загрузка адреса. Задержка между включением линий должна составлять не более 50 нс, поэтому всякие медленные подергивания ножек (типа ардуинского DigitalWrite) не годятся, надо, например, PORTC |= 0b00110000;
    4. BC1=0, BDIR=0.
    5. Устанавливаем на ножках порта AY значение регистра.
    6. BC1=0, BDIR=1. Загрузка значения.

    Повторяем последовательность 14 раз (для каждого нужного регистра). И все это — 50 раз в секунду. Получаем музыку.

    Выбор конкретного железа

    В моем случае следующий:
    1. AY-3-8912 — был дешевле.
    2. Atmega8A (DIP28) — доступно, достаточно выводов.
    3. Кварцевый генератор на 4 МГц — для тактирования AY.
    4. Счетчик К555ИЕ5 — как делитель частоты для тактирования AY.
    5. Кварц на 16 МГц — для Atmega8A.
    6. Для подключения к ПК — USB UART на FT232R.



    Плата разведена именно под это дело. В процессе отладки и более вдумчивого изучения возникли следующие мысли:

    1. Если использовать YM2149F, то не нужен счетчик, т.к. в этом чипе есть встроенный делитель частоты на 2.
    2. Похоже, что кварц для Atmega тоже не нужен — все прилично работает и от внутреннего генератора на 8 МГц.
    3. В теории, можно попробовать вообще избавиться от кварцевого генератора для AY, если поковыряться с аппаратными таймерами и счетчиками Atmega. Но! В этом случае мы сможем тактировать AY только на 2 МГц. А по-хорошему, надо иметь возможность тактирования на 1.7(много цифр) МГц — как это делается в Speccy. У меня кварцевый генератор на 4 МГц стоит в DIP-колодке, чтобы потом его заменить на 3.5(много цифр) МГц.

    Выход звука срисован у tronix286, там горстка резисторов и два конденсатора.

    Софт

    Для вдохновления изучалась вот эта (недо)реализация. Там описан общий принцип работы связки «источник — UART — Atmega — AY», но использование на «меге» загрузчика Arduino в данном случае показалось мне совершенно лишним. Ну и, программа на ПК, написання на C#, мне не понравилась. Шарп здесь примерно так же «нужен», как и Arduino. Формат YM разложен по полочкам здесь.

    Прошивка Atmega

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

    valToPort — запись 8-разрядного значения в «порт», состоящий из половинки порта B и половинки C. Так было удобнее разводить.
    sendToAY — запись 8-разрядного значения в регистр AY. Здесь как раз реализована логика, описанная в пункте «Управление».
    setup — инициализация портов и UART.
    main — зацикленное «получить 16 байт — записать в AY».

    Демонстрационный пример на PC



    Написан на Python 3 с использованием PySerial. Как и прошивка, лежит на гитхабе. Берет файл 1.ym (несжатый!) из текущей директории, разбирает его и заталкивает в COM6. Ради интереса пример проверен на OS X, работает «из коробки», достаточно только поменять название порта. Подозреваю, что столь же успешно будет работать на Linux, в т.ч. на «малинке».

    В выдаче дампа регистров на AY есть один нюанс. Формат YM хранит данные в виде «все значения регистра 0, все значения регистра 1...». Это очень правильно с точки зрения дальнейшего сжатия. Я же работаю с несжатым YM, и мне нужно выдавать пачки байт «регистр 0, регистр 1...». Для PC задача решена в лоб — читаем данные из файла в нужном порядке в большой массив, затем из него последовательно отдаем контроллеру. Когда нужно будет делать «головное устройство» на базе чипа с малым объемом памяти, придется изобретать какие-то буферы.

    Итого

    Стоит помнить о том, что перед запуском воспроизведения неплохо бы сбросить «мегу» и AY. Потому что если в буфере контроллера что-то есть, при передаче новых данных весь поток сместится, и звуки будут воистину душераздирающие. Пин сброса на модуле предусмотрен, но в демонстрационном примере не используется. Сброс осуществляется тычком провода в сидящий на «земле» корпус кварцевого генератора.

    Имеется и недопойманный баг. Который, наверное, прячется где-то в районе «Windows 10 — Python 3 — UART». Периодически скорость обновления падает с 50 Гц до 20 (осциллоскопировано). Системы в явлении не обнаружено, на другом компьютере глюк не воспроизвелся. Если поймаю когда-нибудь, сделаю UPD.

    В дальнейшем модуль будет прикручен к находящейся в процессе разработке поделке, об этом в относительно обозримом будущем будет статья. Ну, и к «малинке» надо попробовать подцепить. Простор для экспериментов имеется.

    Исходники, разводка платы (SL6), схема модуля (Eagle) на гитхабе.

    UPD1. Конвертировать в YM можно с помощью AYEmul.
    UPD2. Здесь берется .torrent для скачивания архива Modland.com. Там много.
    UPD3. ProjectAY. Там много музыки в AY. На момент публикации сайт лежал.

    Теперь все более-менее культурно

    UPD4. 18.03.2015 переделал код Atmega и демонстрационный (питоний). Теперь логика такая: Atmega запрашивает у хоста данные, заполняет кольцевой буфер (512 байт), затем, как половину проигрывает, запрашивает еще (т.е. точки запроса 256 и 512 (0)). Хост на запрос реагирует пачкой в 256 байт, Atmega их потребляет через обработчик прерывания. Не все отполировано, но играет куда стабильнее первоначального варианта.

    UPD5. Попробовал на малинке. Работает почти из коробки.
    0. Отключить консоль на последовательном порту (etc/inittab в конце).
    1. comPort = "/dev/ttyAMA0" (последовательный порт)
    2. regState = bytes([registerDump[currentPos + currByte]]) (так serial.write работает нормально)
    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 31

      +6
      Как минимум оригинальный дверной звонок можно сделать с заливкой мелодий по Bluetooth
        +1
        Вот примерно для таких вещей и придумывалось. Дверной звонок, будильник, какая-нибудь музыкальная шкатулка, на что еще фантазии хватит.
          0
          Прослушал на Youtube с десяток мелодий. Для дверного звонка слишком сложно и слишком мало время проигрывания мелодии, не раскрывает все возможности AY. А вот музыкальная шкатулка — это лучшее применение, особенно, если сделать шкатулку в стиле техно или с намеком на старый компьютер/игровую приставку — звук специфический. Неплохо классику играет, но с двумя AY еще лучше.
            0
            На дверной звонок можно коротких забористых семплов настругать. Два AY — понятно, что лучше, но для такого тандема надо уже целенаправленно музицировать, а не брать имеющееся.
              +11
              Использование двух чипов AY одновременно уже было реализовано в звуковой карте для Спектрума TSFM (поддерживается многими эмуляторами) и, соответственно, уже есть мелодии под два музыкальных процессора.

              В качестве примера

                +4
                Хм. А нажористо.
                  0
                  Ы! Я теперь себе два AY хочу! Схема разводки подобного девайса где-нибудь есть?
        0
        Собирала похожий девайс без кварцев и ИЕ5
        Все прекрасно работает от внутреннего генератора атмеги
          0
          Во-первых, перестраховался. Во-вторых, добиться «спектрумовского» тактирования от атмеги не выйдет. Это я упомянул.
            0
            если уж так хочется добиться «сперктрумовского» тактирования можно и кварц поставить, но атмеге то он зачем нужен?
              0
              На атмеге он был у француза, у которого я частично это дело позаимствовал. По факту, без него дествительно все хорошо.
          +3
          Есть очень безбашенная идея, но не совсем уверен что такое можно реализовать.

          Идея такая:
          1. Есть источник стререо звука (Left Front и Right Front).
          2. Есть микроконтролер (Аtmega32 должна успеть в ряд фурье разложить).
          3. Есть музыкальный сопроцесор на YM2149F.
          4. МК получаете сигналы (от Left Front и Right Front) и разлаживает их в спектр.
          5. Полученые спектры (от Left Front и Right Front) МК фильтрует, выбрасывая все не музыкально нотные частоты.
          6. Получая самые громкие по амплитуде «ноты» МК посылает значение частоты на YM2149F.
          7. В итоге получаем Left Back = A + 0.5B, Right Back = 0.5B + C.
          8. Все что будет приходить от источника стерео звука будет «подзвучиватся» олдскульным синтезатором.
          9. Получается псевдоквадрофония методом вокодера.

          Не знаю насколько большой будет задержка от начала сигнала до вывода на YM2149F. Поэтому и считаю идею безбашенной :)
            0
            Еще надо предусмотреть автоподстройку под звукоряд — далеко не во всех записях инструменты настроены под камертон 440 Гц.
              0
              Ну тогда сделать полосу захвата +-2%, этого должно хватить…
                0
                2% может оказаться недостаточно, если все настроено выше или ниже на четверть тона, а расширять полосу захвата нельзя, так как в нее попадут соседние ноты.
                К тому же, подстраивать нужно не только анализатор, но и AY, иначе она фальшиво звучать будет.
              +1
              Идея точно забавная. Насчет реализуемости — можно для начала сделать ее более софтовой — переложить анализ на ПК. Чтобы в итоге получился, скажем, плагин к программному аудиоплееру, толкающий «подзвучку» в UART.
                0
                Да именно забавная, просто выходит как бы добавление олдскульно синтезатора ко всем стерео записям… потому я ее и предложил. Думаю звучать должно прикольно ;)
                0
                А разве не проще использовать миди конвертер и sidstation?
                  0
                  А разве MOS6581 и аналоги являются полностью идентичными этой архитектуре?
                  Тем более Elektron больше не производит SIDstation.
                    0
                    Не, SID вообще из другой оперы. Штука крутая, но чипы сейчас редки и дороги относительно AY.
                      0
                      Я то об этом знаю. У меня как раз собран MBSIDv2.
                        0
                        Ага. Ну, тогда остановимся на том, что хз, откуда тут вообще SID всплыл.
                          0
                          Это я виноват. Я не различаю чипы и тонкости. Посыпаю голову пеплом.
                            +2
                            Канифолью же!
                            0
                            Ну видимо для некоторых нет разницы между чиптюном на SID и чиптюном на AY-3-8910
                  +1
                  А по-хорошему, надо иметь возможность тактирования на 1.7(много цифр) МГц — как это делается в Speccy.

                  Если точнее, то 1,7734 МГц (хотя в интернете и другие цифры встречаются) — это частота в оригинальном 128K. В большинстве отечественных клонов ровно 1,75 МГц (3,5 (для Z80) / 2), так что если слушать постсоветское, то лучше, IMHO, использовать эту частоту. Посмотрел кварцы в ЧиД — я так понимаю, для 1,75 придётся взять 7 МГц и поделить на 4 (как в клонах и делалось, вроде как)?

                  И ещё (из разряда чиптюновой аудиофилии) — в варианте tronix286, как я понимаю, в устройстве реализован буфер, а тут таймингом занимается хост, выдавая данные в порт с частотой 50 Гц (как в варианте AY-LPT), так что для максимальной точности воспроизведения (чтобы не «плыло», так скажем) нужно что-то «поточнее» пайтоновских слипов (например, всё тот же ZX Tune с соответствующей (гипотетической) либой для вывода).
                    +1
                    В клонах 14 делили на 8.
                      0
                      Кварцы на 3.58 МГц есть, можно на 2 делить. Этим я пока не заморачивался, но вообще — надо. Насчет тайминга — да, есть проблема «подплываний», причем, что интересно, на одном компе она проявляется сильно, на другом — практически не встречается, на третьем — вообще не удалось повторить — это все с одним питоньим кодом. Кстати, специально сравнивал работу со слипом и с дерганьем микросекунд из часов — на слух идентично, с теми же граблями.
                        +2
                        Переписал полностью код атмеги и частично — питоний. Теперь 50 Гц тактирует атмега, она же следит за своим приемным буфером и периодически запрашивает у хоста еще пачку байт. Играет это дело на порядок лучше.
                        0
                        Проверил на малинке, все прилично, с минимальными изменениями кода. См. UPD5 материала.

                        Only users with full accounts can post comments. Log in, please.