Звук на чіпі 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

Схема пристрою: 16FUSB_driver-libusb-win32-1.2.6.0.zip
Скомпільована прошивка (.hex) та скомпільовані DLL-заглушки: 16FUSB_driver-libusb-win32-1.2.6.0.zip
Вихідні коди прошивки: 16FUSB_driver-libusb-win32-1.2.6.0.zip
Вихідні коди бібліотеки-заглушки: 16FUSB_driver-libusb-win32-1.2.6.0.zip
General Instruments AY-3-8910 / 8912 Programmable Sound Generator (PSG) data Manual: http://bulba.untergrund.net/AY-3-8910.rar

Величезний архів трекерної музики: Modland ФТП
ZX музика онлайн: http://zxtunes.com/

Всім добра!

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.