Звук на чипе 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. Порт 0×378 данные, Порт 0×37a передача управляющих сигналов (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.rarGeneral Instruments AY-3–8910 / 8912 Programmable Sound Generator (PSG) data Manual: http://bulba.untergrund.net/AY-3–8910.rar

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

Всем добра!

© Habrahabr.ru