Звук на чипе AY-3-8910 (или Yamaha YM2149F) родом с ZX Spectrum на PC через USB

    Прошло около года, с момента успешного подключения музыкального синтезатора YM2149F к LPT порту компьютера. LPT это конечно хорошо, однако время не стоит на месте, и найти компьютер или ноутбук с LPT портом становится все сложнее и сложнее. Да и сам автор (то есть я) устал лазить каждый раз под стол, где стоит системник, и перетыкать LPT плату на что-то другое, например программатор (у меня LPT-программатор Willem, ну да не суть). Поэтому на сей раз подключать чип YM2149F будем к USB. Ну и конечно, чтобы соотвествовать эпохе, будем это делать на копеечном древнем микроконтроллере PIC16F628.

    image

    Вкратце, YM2149F (или ее функциональный аналог AY-3-8910) — микросхема звукового трехголосного синтезатора, применялась в старых компьютерах типа Atari ST, Amstrad CPC, ZX Spectrum, MSX и некоторых других для проигрывания музыки. В России чип приобрел определенную известность благодаря установки в различные клоны ZX Spectrum'а. За время шествования ZX Spectrum по бывшему СССР музыкантами были написаны тысячи мелодий под этот звуковой программируемый генератор. Да и сейчас можно вполне найти людей, создающих музыку именно под этот чип. В конце статьи будут приведены ссылки на огромнейший архив чип-тюнов для YM/AY на сотни часов непрерывного прослушивания.

    Демо


    Как и в прошлый раз, перед началом, даю сразу ссылку на прослушивания конечного результата: https://soundcloud.com/tronix286 Последние записи сделаны как раз с этого устройства. Записывал так-себе плеером, который пишет максимум в 128Kb/s MP3, поэтому в реальности устройство звучит «ярче». Но составить общее представление о звуке можно.

    Железо


    Почему такой странный выбор контроллера? Почему не AVR/ARM/iCore i7/FTDI на худой конец? Частично ответ на этот вопрос дан в начале топика: ретро синтезатору — ретро микроконтроллер! Тем более, что у AY-3-8910 и фирмы Microchip, можно сказать, общие корни. А вообще, так сложилась серия странных обстоятельств. Во-первых я наткнулся в интернете на библиотеку, реализующую программный (софтварный) стек USB 1.1 для микроконтроллеров PIC16F628 — вот эта библиотека: 16FUSB. Во-вторых, у меня давно лежала и пылилась парочка PIC16F628A, которые я не знал куда деть. В третьих, на компе уже стоял настроенный софт (MPLABX, MPASM) и имеется программатор для PIC. Ну и в отличии от программного стека V-USB на AVR, известного многим, на PIC'ах без аппаратного USB проектов мало или даже вообще нет. А это значит, что нужно восстановить историческую несправедливость.

    Вот типовая схема включения с сайта библиотеки 16fusb:

    image

    В комплекте с библиотекой 16fusb идет хороший пример под названием «direct-io». Смысл прост — посылаем через USB байт и он «отображается» на восьми ножках микроконтроллера. Так же можно посылать дополнительно два управляющих сигнала, то есть еще два бита (или две ножки). И в обратном направлении, то есть от контроллера к хосту (компьютеру).
    image

    Для управления YM2149F используется восьмибитная шина данных D0-D7 и три управляющих сигнала BC1, BDIR и RESET. BC1 и BDIR управляют выбором адреса регистра и его значением, а так же переводят микросхему в неактивное состояние. Сигнал RESET используется для сброса всех регистров на первоначальное значение. Таким образом, чтение из PIC в компьютер не нужно; нужна только возможность посылать команды на YM. И нужен еще третий управляющий сигнал, а значит еще одна ножка МК.

    В своей прошивке для управления конкретно YM2149F было сделано следующее:
    • выкинуто все, что связано с чтением сигналов из PIC в хост (компьютер) для увеличения быстродействия обработки реквестов USB;
    • состояние направлений портов ввода-вывода жёстко задано при инициализации МК и не изменяется в процедурах выдачи байта на ноги.
    • организован кольцевой буфер на 64 байта. При декодировании запроса от хоста байты складываются в буфер. Когда есть свободное время, данные из буфера выдаются на YM.
    • оптимизирована скорость выдачи байта на ноги МК. Частично за счет жестко указанных направлений ввода-вывода, частично из-за известности предыдущего состояния управляющих бит.
    • пофикшен глюк с зацикливанием PIC через несколько тысяч пакетов (развернут цикл RxLoop в файле isr.asm, вместо goto RxLoop вставлена проверка на признак конца пакета)
    • что-то еще, не помню


    Как уже сказано выше, возникает потребность в еще одном управляющем сигнале — RESET, а свободных ножек уже нет. Поэтому для тактирования PIC применен кварцевый генератор, а не кварц, тем самым высвобождая одну ногу МК (RA6), необходимую для управления сигналом RESET. Нога RA5, торчащая в воздухе, в данном семействе работает только на вход и не может быть использована для управления выходным сигналом. На нее можно было-бы переложить функционал по отлавливанию конца USB пакета (EOP) с ножки RB2, однако это не так просто — в отличии от ножки RB2 ножка RA5 делит функционал с MCLR и VPP для программирования и внутри организован вход как триггер шмитта. Ему просто не хватит напряжения после диодов для сработки. С другой стороны, для тактирования YM2149F собран генератор на микросхеме 74HC02 и кварце 3.579545 MHz. Можно было бы попробовать использовать вторую свободную половину микросхемы для сборки аналогичного генератора и для PIC, но остановило два момента: 1) у меня нету кварца на 24МГц (а кварцевый генератор был, с какой-то древней мамки) 2) я не знаю, как поведет себя 74HC02, если с «разных боков» у нее будут разные частоты, причем одна из них довольно высокая (24МГц все таки очень большая частота). Еще один из вариантов, как освободить ногу RA6 для кварца: Сигналы BC1 и BDIR принимают только такие значения:

    BC1    BDIR
     0       0
     0       1
     1       1
    

    И никогда BC1 = 1, BDIR = 0. Это можно использовать как RESET, добавив NOT и NOR логику из половинки микросхемы 74HC02 и проинвертировав сигнал на выходе с помощью транзистора. Конечно для выдачи BC = 1 и BDIR = 0 нужно немного подправить прошивку.

    И еще, нога RA4, которая управляет сигналом BDIR, с открытым коллектором, поэтому ее обязательно нужно подтянуть к питанию — на схеме это 10K резистор R5.

    Софт


    Со стороны компьютера, в качестве музыкального проигрывателя, выступает отличный кросс-платформенный плеер чип-тюнов ZX Tune:

    image

    Напрямую он не поддерживает USB, зато если находит у себя в директории одну из библиотек dlportio.dll/inpout32.dll/inpoutx64.dll, то позволяет переключится в настройках вывода звука на YM-LPT (для прошлого проекта), а затем использует функцию __stdcall void DlPortWritePortUchar(unsigned short port, unsigned char val); для выдачи байт YM2149. Порт 0x378 данные, Порт 0x37a передача управляющих сигналов (D1 — ~BDIR, D2 — BC1, D3 — ~RESET). Таким образом, можно написать маленькую библиотеку-заглушку с одной единственной функцией DlPortWritePortUchar, в которой перенаправлять выдачу байт на USB-устройство, что и было сделано. Я просто взял исходники библиотеки inpout32 за основу и написал функцию-заглушку для перенаправления выдачи байт на это устройство. В итоге, достаточно положить эту библиотеку-заглушку inpout32.dll или inpoutx64.dll, в зависимости от используемой версии плеера (x86/x64), в одну директорию с плеером ZX Tune, запустить его и в настройках звука переместить устройство aylpt на самый верх (как на скриншоте выше).

    Скачать бесплатно и без СМС


    Драйвера для Win XP, Win 7 (x32/x64) можно скачать здесь: 16FUSB_driver-libusb-win32-1.2.6.0.zip

    Схема устройства: ym-usb_scheme_1.0.rar
    Скомпилированная прошивка (.hex) и скомпилированные DLL-заглушки: ym-usb_firmware_and_DLLs_v1.2.rar
    Исходные коды прошивки: ym-usb_PIC16F628A_source_v1.2.rar
    Исходные коды библиотеки-заглушки: inpout32-64_DLL_source_v1.2.rar
    General Instruments AY-3-8910 / 8912 Programmable Sound Generator (PSG) data Manual: http://bulba.untergrund.net/AY-3-8910.rar
    Тема на форуме ZX.PK.ru, из которой «родилось» устройство: http://zx-pk.ru/showthread.php?t=22202

    Огромный архив трекерной музыки: Modland (ФТП)
    ZX музыка онлайн: http://zxtunes.com/

    Всем добра!
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 56
    • +9
      Слёзы ностальгии льются из моих глаз!
      Но подключать ямаховский чип к PIC-контроллеру неправославно. Только к тёплому ламповому Z80!
      • +2
        Спасибо тебе, добрый человек! Увы, этот чип в моем провинциальном городе был редким и дефицитным, так что я потом уже, в зрелом возрасте, увлекся написанием его эмуляторов. Первая попытка была на Java (MIDP2.0) Потом уже было вот это на ардуине. А сейчас валяются в дальнем углу харда потуги сделать это же на ATtiny13 (sic!) Код синтезатора, кстати, вполне в его килобайт вмещается. На музыку уже места, увы, не хватает. Но это все не то… Скажите, а где сейчас достать YM2149F? (P.S. А звучит-то хоть похоже на реальный?)
      • +1
        Ааа! Люди добрые, что ж творится то!!! Пока YM2149F будет месяц из Китая идти я ж от любопытства умру! И как раз PIC16F628 так же лежит без проекта… Спасибо огромное за проект! Обязательно соберу себе такую железяку.
        • 0
          И кстати про LPT: это же по сути был такой себе GPIO той эпохи!
          • 0
            Почему был!? До сих пор это единственный real time вариант GPIO на x86 совместимых(главная причина почему linuxcnc использует только LPT для управления ЧПУ ).
            Был Covox на LPT в те давние времена
            • 0
              Вы что-то путаете, сейчас GPIO чуть ли не в каждом x86 SoC, и это не LPT.
              • 0
                Приведите пример пожалуйста!?

                Доступных GPIO, а не те которые используются кнопками/сведидиодами или I2C. GPIO которые без подпайки к контактным площадкам доступны в виде разъема или слота в обычной массовой модели материнских плат для x86

                amd gizmo board пока экзотика, а в intel nuc см. абзац выше
                • 0
                  Если говорить о материнских платах для десктопа, скорее всего там GPIO в легкодоступном виде нет, но это не значит, что линии отстутствуют в x86.
                  • 0
                    Так в этом контексте и говорил, про то что можно использовать обычному пользователю! Прошу прощения, что не уточнил)
          • 0
            Мне тут подсказали, что 74HC02N не потянет 24МГц. Кварцевый генератор тоже найти не получается. Не могли бы Вы сделать необходимые изменения для использования варианта «кварц+транзистор»? И выложить как ещё один проект. Ассемблер для меня очень уж тяжко. И схему, если можно. Хотя бы теоретически. Потом через месяц по приходу YM2149F отчитаюсь о работоспособности.
            • 0
              Или если пихнуть 2 микросхемы 74HC02N, то всё будет норм? Я совсем запутался.
              • 0
                Если запихнуть две 74HC02, то можно не корячится с транзистором, а инвертировать с помощью одного блока NOR из второй HC02. Тут уж кому как проще — или один лишний DIP корпус, или один транзистор и два сопротивления… Хотя если таки ставить DIP корпус, то ставить уж лучше NOT просто, типа К155ЛН1
                • 0
                  И вместо первой 74HC02 тоже можно взять К155ЛН1?
                  • +1
                    Нет, вместо первой нельзя. Вместо первой можно попробовать 555ЛЕ1, если прет на отечественные компоненты -)
              • +1
                Схема в теории проста: от RA6 отрезаем провод до RESET, включаем кварц 24Мгц между RA6 и RA7, как на оригинальной схеме (в статье на картинке). Дальше у нас есть два неиспользуемых блока NOR из 74HC02 и сигналы BC1 и BDIR. Для формирования RESET, когда на BC1 будет 1 и на BDIR будет 0 собираем что-то вроде этого:
                , то есть в схему добавляется какой-нибудь КТ315 и пара сопротивлений. Внимание! Схему не тестировал, набросал по быстрому без проверки, поэтому настоятельно рекомендую подумать перед тем как повторять это.

                Прошивку подправить тоже не сложно, чуть позже здесь комментарием выложу.
                • +1
                  Вроде поправил прошивку для использования кварца, а не кварцевого генератора. Но тестировать не на чем (нет кварца на 24 Мгц). Взять можно здесь
                • 0
                  И ещё пара вопросов. 1) Громкостью же софтово из ZXTune управлять можно? 2) Если добавить 2 светодиода (на левый и правый канал), то куда их лучше садить? Прям на выходы Jack? А на качестве музыки не скажется?
                  • 0
                    1) Нельзя. 2) У меня один светодиод просто на питании (как индикатор питания), второй на какой-то дата-линии, предположим D7, как индикатор что идет обмен между компом и чипом. А чтоб в такт музыки мигали это что-то типа простейшей «светомузыки» имхо надо собирать.
              • +2
                Много лет идея AY-USB не давала покоя участникам zx.pk.ru, свершилось!
                Он дождался:

                (да, это более «короткий» 8912 (DIP28), в оригинальном 128K (и в моём Scorpion'е) использовался он)
                • 0
                  спасибо за ваши статьи, заставляют не откладывать ямаху в долгий ящик
                  • +1
                    Все таки живой чип звучит сильно жирнее эмуляторов! я последние полгода много слушал ZXTune и тут прямо сильно слышно разницу.
                    • 0
                      Pro Tracker + AY ) были времена…
                      • +2
                        А мне чип AY-3-8912 ПОДАРИЛ друг в далеком 1994 году! Я слушал музыку с него круглосуточно. А потом другой мой друг «взял послушать», ну и слушает по сегодняшний день. И книгу по ассемблеру Z80 он же взял почитать. И тоже до сих пор читает )). А вашу статью читал, конечно же, под музыку с AY.

                        ZX Spectrum AY-3-8910 demo music mix
                        • 0
                          Угуу. Осталось совсем чуть-чуть до отказа от компа в этом чудо-устройстве.
                          • 0
                            Тоже задумывался об этом. Да, можно пихнуть музыку на СД-карту, а сам код проигрывателя в какой-нибудь современный контроллер. Только зачем? В общественном транспорте слушать по дороге на работу? И париться ещё по поводу размера, питания, стабильности и т.п. Лично мне в транспорте хватает мобильника с наушниками. А вдумчиво музыку слушаю обычно именно возле компа. Там и настроить удобно можно всё, и музыки сотнями гигабайт держать, и докачать при надобности.
                            • 0
                              Да, я тоже музыку слушаю исключительно с компа. Но почему-то кажется, что забавно было бы сделать именно самодостаточное «трекерное» устройство, в форм-факторе не плеера, а, скажем, радиоприемника. Но это так, пока только мысли. Я думаю повторить описанную конструкцию, а дальше посмотрим.
                              • 0
                                Меня больше веселит идея добавить поддержку этой железяки в Android-версию ZXTune. Тогда можно будет и портативно с собой таскать! А из тех же китаев взять портативные активные колоночки — вот и почти формфактор радиоприёмника.
                                • 0
                                  Дык вот же.
                                  • 0
                                    Это видел. Не обнаружил там открытого кода, что для меня с точки зрения самопала важно.
                              • +1
                                на всякий случай оставлю это здесь
                                www.youtube.com/watch?v=6Bj6zMlTw10
                              • +1
                                Все же МЛТ добавляет «теплоты и ламповости» устройству. Жаль, что купить их уже для такого рода плат трудно. На рынках говорят «у бомжей спрашивай», а так чтобы в ассортименте — нереал :(
                                • 0
                                  Вот бы ещё иметь возможность выбора схемы каналов (ABC/ACB/BAC) и тактовую частоту микросхемы (1774400, 1750000 и 3500000 Гц)…
                                  • 0
                                    Для выбора каналов можно поставить DIP-переключатель или просто тупо джамперы. Я так и хотел сделать, да место на плате закончилось. Насчет тактовой — в ym2149f есть встроенный делитель на 2, то есть при внешней 3.579545 можно получить 1.7897725. Для переключения на схеме уже есть джампер.
                                    • 0
                                      Можно аналоговые ключи применять для коммутации: 176КТ1 (CD4016), К561КТ3 (CD4066A).
                                      • 0
                                        Да можно конечно. Лучше штук 6 реле — щелкали бы так прикольно… -)
                                      • 0
                                        а в чем прикол такой частоты?
                                        давала чипу частоту от внутреннего генератора atmega ~2MHz, вроде работал и играл.
                                    • 0
                                      PIC16F627A/628A/648A FAMILY OF DEVICES
                                      Maximum Frequency of Operation (MHz)
                                      20


                                      Видел, недавно, этот чип работает с превышением по питанию в 1.5 раза, а у вас по частоте?
                                      Или у вас спец. партия. Очень, на мой взгляд, годный чип.
                                      Хотя, пару тройку инструкций я бы добавил.
                                      Спасибо.
                                      • +3
                                        Да, немного разогнан по частоте, иначе не успевал бы декодировать биты с USB. Чип холодный, не греется. Вообще, финт с разгоном далеко не нов, он еще применялся начиная с серий, где окошко для УФ-стирания было. Видел, например, когда на ПИКах делали вывод PAL-сигнала (гнали с 4 Мгц до 7 с чем-то) и тд. В целом, ПИКи очень неплохо «гонятся», порой до 50% от заявленной в даташите максимальной частоты, хотя, нужно конечно понимать, что такое нестандартное использование годится только для домашней поделки (сгорел — выкинул — поставил новый / заглючило — включил-выключил заработало) и никак не для какого-то массового устройства. На сколько знаю, гонятся в принципе все МК — и атмеги и АРМы… Но смысла гнать АРМ я не вижу вообще.
                                      • +3
                                        Уххххх, какая офигенская музыка! Статья не по моей части, ничего не понимаю в этом, но музыка как бальзам на душу! Мир, тепло, лампы C64 =)
                                        • 0
                                          А с обратной стороны макетки «мясо» из проводов? Или это можно как-то культурнее сделать? Фотку можно?
                                          • 0
                                            «Мясо» из проводов. Культурней — развести плату в чем-нибудь и лутом сделать. Фотика нет, но там обычный монтаж МГТФ…
                                          • 0
                                            Начинает приходить первое железо. Как оказалось, 74HC02 и её советские аналоги — довольно редкая штука штука в моём городе. Зато имеются чуть ли не вагоны К555ЛА3 / К533ЛА3 (2И-НЕ). Можно ли как-то перестроить генератор под них?

                                            Ещё вроде были микросхемы с чистым НЕ. Тут есть схема генератора (рис.3) на 2 резисторах, 2 конденсаторах и 2 НЕ. Визуально мне напомнило Вашу схему. Не подскажете, можно ли в таком «сократить» схему на 1 кондёр и 2 резистора?
                                            • +1
                                              Ну да, на чистом НЕ это классика, можно так:


                                              А вообще, что есть, на том и можно собрать…
                                              • 0
                                                155/555ЛН1 — шесть чистых НЕ.
                                              • 0
                                                Уррра! Работает! Спасибо Вам огромное! =(^_^)=

                                                image

                                                Из замечаний — генератор на одном резисторе работал очень не стабильно. Зато аналогичная схема на двух резисторах работает прекрасно.

                                                Ещё у меня почему-то не работает с микросхемой «Microchip AY-3-8910A». Самба из примеров ZXTune играет как-то так: dl.dropboxusercontent.com/u/4548378/Hardware/YamahaPlayer/dx-01.wma
                                                А вот с Yamaha YM2149F всё без проблем! ^_^

                                                И ещё — для полного счастья хотелось бы немного громче. Если, например, заменить резисторы на выходе с 2к на 1к, то музыка же станет громче? Тогда ещё и регулятор громкости попробую какой-нибудь прикрутить.
                                                • 0
                                                  Круто! А под Linux думалось написать драйвер? И что думаете по поводу разводки GPIO с чипа, их там, если я правильно помню, 16.
                                                  • 0
                                                    Да, и ещё один вопрос, а почему не вариант CH341a? Совместимость со старым софтом, готовый драйвер под разные ОС.
                                                  • 0
                                                    Под линукс, если я все правильно понимаю, libusb уже должна цеплятся по дефолту. Вопрос только в плеере. А вообще, я — не планирую под линукс. Если нужно — исходники всего есть, можете сделать.
                                                    • +1
                                                      Под Linux планирую написать я. ZXTune есть, libusb есть — портирование обещает быть не сложным. И может под Android. Но пока никак не могу выкроить время, чтобы сесть и написать.
                                                    • 0
                                                      Сейчас потихоньку ваяю свою реализацию, цель — сделать модуль, не привязанный к PC. Т.е., с последовательным входом. Вдохновляюсь вот этой реализацией: electronicfields.wordpress.com/2012/04/09/ym2149-sound-generator-arduino-fast-pin-switching/. Разводка платы под mega8 + AY-3-8912 готова. Реально, не понимаю пока только одного — можно ли тактировать чип на 2 МГц, как в указанной реализации.
                                                      • 0
                                                        Придется самому себе отвечать. 1.7… МГц — частота тактирования AY в Spectrum, 2 МГц — в Atari. А частота звука в итоге танцует от тактовой, так что, например, демка, написанная для «спеки» будет на железяке с тактированием в 2 МГц звучать несколько выше. Впрочем, не думаю, что это сильно важно.
                                                        • 0
                                                          "

                                                          Железяка с последовательным входом и Atmega8. Сделаю юзабельное что-то, пихающее в нее данные — напишу материалец. Как-то с бубном уже играет и радует.

                                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.