Копия по мотивам «ячейки звукового синтеза Агат» для IBM PC/XT — «музыкальная ячейка»

ЯЗС — Ячейка Звукового Синтеза — дополнительная плата расширения для компьютера «Агат», нечто вроде примитивной звуковой карты, имеющая пять тональных и два ударных канала. Подробнее про нее можно почитать здесь: http://agatcomp.ru/agat/Hardware/SoundNCL/jzs52.shtml. Когда-то давно мне очень понравилась видео-демонстрация работы ЯЗС, и особенно понравился звук, издаваемый этим устройством. Так, как ПЭВМ Агат у меня нет, и никогда не было, а побаловаться с извлечением звуков и таймером КР580ВИ53 хотелось, появилась мысль повторить устройство, только на более доступную для меня (да наверное, и не только для меня) шину ISA-8 от компьютеров IBM PC — благо на барахолках купить любую плату с ISA шиной пока еще представляется возможным. 

e8e3689453ea994c1e2d550fd9cf89ad.jpg

Итак, в основе платы у нас есть две микросхемы программируемых таймеров КР580ВИ53. Каждая микросхема имеет три независимых друг от друга счетчика с несколькими режимами работы, нас же интересует режим генерации прямоугольных импульсов с программно изменяемой частотой. Так, с каждой микросхемы мы можем получить три независимых канала, а с двух микросхем — шесть каналов генераторов прямоугольных импульсов. Следует учесть, что в оригинальной Агат'овской плате один из выходов таймера используется непосредственно как таймер, поэтому количество тональных каналов у оригинальной ячейки — пять, а не шесть. Далее, позволю себе процитировать статью про ячейку звукового синтеза с вышеупомянутого сайта, которая рассказывает нам, что на плате так же имеются:

  1. Блок регистров на основе к555тм7 — SRAM, хранящая настройки каналов.

  2. Пять блоков коммутации тональных каналов — обеспечивают плавную атаку и передачу сигналов от таймеров/счётчиков на полосовые фильтры.

  3. Пассивные полосовые RC-фильтры — выделяют части спектра в тональных каналах.

  4. Генератор шума и генераторы ударных (группа из трех КМОП-микросхем) — образуют два ударных канала.

  5. Выходной усилитель-микшер (к157уд2 + кт602 б) — суммирует сигналы от пяти тональных и двух ударных каналов и выдаёт результат на задний разъём.

  6. Блок триггеров на основе к555тм2 — управляет флагами прерываний, флагом разрешения работы счётчиков/таймеров и выдачей сигнала IRQ.

  7. Блок параллельного ввода (к555ап3) — позволяет считывать 8 бит с заднего разъёма.

Учитывая всё это, пришло время продумать концепцию по переносу платы с Агат на ISA-шину. Задачу сильно упрощало то, что схема оригинальной Агат'овской ячейки доступна, поэтому всю аналоговую часть возьмем как есть без изменений, а в цифровую часть внесем необходимые изменения для обеспечения работы платы на шине ISA. Основные отличия от оригинальной ячейки Агат, которые я выделил при создании новой платы:

  • я не стал делать на плате внешний 8-битный порт. Подключать у меня к нему, естественно, нечего. Плюс в IBM PC (если мы говорим о эре плат с ISA шиной) и так есть хороший 8-битный порт — называется LPT;

  • я не делал IRQ от таймера одной из ВИ53 и управления IRQ. На IBM PC и так уже есть таймер , даже не один — если нужны прецизионные задержки никто не мешает повесить свой обработчик прерывания прямо на таймер в DOS;

  • за счет этого высвободился один канал ВИ53, который использовал как еще один тональный канал. У оригинала было 5 тональных каналов, здесь стало 6 тональных канала;

  • появилась возможность чтения регистров обоих ВИ53. В оригинале такой возможности не было. Зачем — пока не очень понятно, но оно не сложно и может использоваться для авто-детекта карты и номера основного порта.

Упрощенно, схему аналогового тракта нашей будущей платы можно изобразить так:

49e8ad521088394d44a7db59f6e2533a.png

За счет появления дополнительного шестого тонального канала немного поменялось расположение портов, хотя и осталось близкое к оригиналу — сдвинулись порты управления ударными каналами. Перемычка выбора портов на адреса 300,310,320,330,380,390,3A0,3B0, чтоб никому не помешать если что. Распределение портов такое:

  • 3n0…3n3 — регистры первой ви53 (тональные каналы 1–3).

  • 3n4…3n7 — регистры второй ви53 (тональные каналы 4–6).

    Порты 3n0–3n7 доступны как на запись, так и на чтение;

  • 3n8…3nD — управление блоками коммутации тональных каналов.

  • 3nE…3nF — управление ударными каналами.

    Порты 3n8–3nF доступны только на запись.

Что же касается непосредственно схемы новой платы, которую, кстати, решено было назвать — »Музыкальная ячейка», предстояло решить ряд основных вопросов: — во-первых сделать новый декодер адресов, с чем никаких проблем не ожидалось. Далее, разобраться с системой клоков: плате нужно две основные частоты — 1МГц на счетчики ВИ53 и 64КГц на генератор шума. В оригинале у Агата есть 2МГц на системном разъеме, поэтому они берут две штуки ИЕ5 и на них все делают как надо. В IBM PC 2МГц нету, зато есть 14МГц, которые хорошо бы сразу поколоть на 14, что бы получить 1 МГц, но я не придумал как изящно это сделать не нагородив кучу счетчиков и AND’ов вместе с XOR’ами. Поэтому не долго думая поставил 555ИЕ2 с одним лог элементом И, которая 14МГц делит на 7, давая 2МГц точно такой же скважности как и в Агате. В Агате, кстати, они 2МГц на системном разъеме получают из тех же 14,3МГц с помощью 155ИР3 и NOT на фидбэке, но такую дичь я не решился повторять. В общем, наверное не оптимально, но по первым прикидкам работать было должно:

fcktj1oshzfgntqnwrilozu_t6u.png

Так же небольшая заминка случилась в подключении GATE0,1,2 у обоих ВИ53. Где-то я краем уха слышал, что после подачи питания ВИ53 начинает сразу считать, и из-за этого динамики в каких-то компах пищат после включения. В оригинальной плате GATE’ы управлялись через тригер на порту nF, у меня же в связи с появлением шестого дополнительного канала этот порт занят, и вообще все порты от 0 до F заняты. Но подумав, решил все-таки GATE’ы у ВИ53 завести через триггер, линия сброса которого связана с сигналом RESET, примерно так же как и в оригинале, что должно нам дать после включения запрет счета, и соответственно, тишину на выходах OUT обоих ВИ53:

nmls9spdpkf9xekreqm_agi5evi.png

Единственное, так все порты уже заняты, пришлось разрешающий бит управления GATE’ами впихнуть в порт управление ударным каналом 8. Поэтому распределение его битов стало такое:

Это не особо помешает, просто при инициализации нужно дернуть бит D7 у ударного канала 8, что бы включить GATE’ы. Далее работать по обычной «Агатовской» схеме с каналом ударных. Ну и раз поставили сюда триггер 555ТМ2, то и клоки немного переделались — убралась одна ИЕ5, вместо нее поставилась вторая половинка триггера ТМ2:

rdsps6nagg6ta-k2coyq_f5acss.png

Декодер адресов выполнен в стандартном стиле с использованием двух дешифраторов ИД7 и нескольких блоков мелкой логики, тут ничего необычного:

jd-hp66rkgi16m4fpoflcmlze_a.png

В принципе, на этом вроде и заканчиваются какие-либо изменения в цифровой схемотехнике, ну разве что еще вместо почему-то дефицитной ныне 555ТМ7 я поставил более доступные для покупки 555ИР23. На этом, пожалуй, со схемой и всё. Настало время расставлять компоненты и разводить плату:

nhvyaxnlug4jkfkkpiiqmlrbbac.png

После недели мучений, верчения компонентов, кое-как, но музыкальная ячейка вроде развелась наконец. Размеры платы получились солидные- 118×275,25 мм, хотя я старался не «жать» компоненты друг к другу вплотную, под все микросхемы предусмотрел возможность установки панелек. Аналоговую часть по возможности перерисовал вручную с P-CAD платы оригинальной ячейки. А вот цифру руками увы, не осилил, хотя честно пробовал неоднократно. Уже все шло к тому, что бы делать 4 слоя, но все-таки вывел на двух слоях полу-руками, полу-автороутером. Закинул еще в аналоговую часть огромный GND полигон и сверху и снизу, прошив все via. Заказал платки.

g1midfq2dyd8dh6yrh-jl5niyqo.png

Пока платы были в производстве, я время зря не терял, и написал простенький тест для данной железки, что бы после сборки ее можно было проверить:

swhtiy8y-wd7a6jl4po3hz8oizq.png

Интерфейс в наглую срисовал с оригинального Агатовского теста авторства «Ravodin» aka «tmptmp15» aka «Voldemar0», прямо по стоп-кадру с видео из ютуба. Потому что очень лаконично, простенько и со вкусом. И через какое-то время платы приехали, и началась сборка:

or__97e0wurcrm85ecmvgsfyuje.jpeg

Сначала я собрал основную цифровую часть, проверил схему генераторов частот на 555ИЕ2, 555ИЕ5 и 555ТМ2 — всё отлично работает, выдает необходимые 1,021 МГц на тактирование ВИ53 с шириной импульсов близкой к 50%, и 63.8 КГц для генератора шума. А самое главное, работает управление обоими ВИ53, значит декодер адресов также работает правильно:

gvagnhtk4jnzt1_yhvj9eho3fvo.jpeg

Регистры ВИ53 доступны как на запись, так и на чтение. Выходы ВИ53 управляются из тестовой утилиты, частота полностью соответствует расчетной из программы управления. Далее началась сборка и проверка отдельных тональных каналов, микшеров и выходной части. Спустя какое-то время плата была собрана полностью:

nxjdbytncgcoawkqayhqjekzndy.jpegjauufnmrrnen3fhm5l6fp-spm7o.jpegxxbpurlqkkkec4i4sml9rxa5drq.jpegi9ymo8mqo78jtjsmvy1art4tr34.jpegny0qvqkvkcezbnohieoklmqtxeu.jpeg

И наступило самое трудное — софт… Думаю понятно, что никакого софта под эту карту на IBM PC в природе не существует, кроме, разве что, показанного выше простенького самописного теста.

Начал я с проекта с открытым исходным кодом DOSMID — это несложный проигрыватель MIDI для DOS. Я скачал его последние исходники, понемногу добавил тональные каналы и один канал ударных на пробу. С «наскока» получилось как то примерно так:

Далее, я попытался сделать проигрыватель оригинальных .MUS файлов с Агата. Сначала хотел переписать его начисто, а потом подумал -, а что если взять уже имеющийся плеер под Агат, благо стараниями avivanov76 он дизассемблирован и хорошо комментирован (хотя я и не бум-бум в 6502 ассемблере). Поэтому я взял бинарный файл плеера PLAYERR.O в машинных кодах 6502 процессора, взял ядро эмулятора M6502 от Marat Fayzullin, ну и собрал как мог все во-едино. То есть запускается эмулятор CPU 6502, в нем крутиться оригинальный PLAYERR.O с Агата, а когда он обращается к адресам в памяти, в которых в Агате сидит муз ячейка, я делаю перенаправление уже на PC-шные порты ввода-вывода. Ну и таймер используется от PC, а не на плате муз ячейки (потому что в PC версии на плате его нет). И вроде бы даже что-то получилось:

На слух еще вроде-бы ощущаю некоторую проблему с таймингами выполнения 6502 кода плеера в эмуляторе, надо будет попробовать доразобраться…

Потом я встроил в программу SoftMPU сэквенсор MIDI для музячейки. Это позволило запускать почти любые игры, в которых в настройках звука можно выбрать «General MIDI / MPU401» в качестве звуковой карты. Например, вполне успешно поиграл со звуком в Heroes 2, Warcraft 2, The Increditable Machines 1–2, Lotus, Stunts, Monkey Island, Prince of Persia и тд. General MIDI или MPU-401 порт — это практически обычные стандартные MIDI команды, которые в него посылаются (играми, программами), а уже какая-либо железяка на порту должна эти MIDI команды сама распарсивать и управлять своим синтезатором. В нашем же случае, с помощью программы SoftMPU этот порт MPU-401 эмулируется (в виртуальном режиме 386 можно перехватывать обращение к портам ввода-вывода, ставить так называемую ловушку) и когда какая-либо программа или игра пишет что-то в порт MPU401 срабатывает ловушка, в ее обработчике распарсиваются пришедшие MIDI-данные, и в зависимости от них управляется музыкальная ячейка, которая играет звук. Небольшое видео демонстрирующее процесс, снятое на тапочек:

Сэквенсор, который сейчас реализован и в DOSMID, и теперь вот в SoftMPU — очень примитивный. Фактически, я просто играю с нужной частотой ноты, без всяких эффектов, типа там экспрессии, вибрато, детюна и прочего прочего, чего бы можно было бы сделать. Единственное, что сейчас реализовано из «фишек» — так это pitch band’ы. Барабаны расставлены кое-как, можно сказать «от балды», без всякого соответствия General MIDI — регистры управления каналами ударных муз ячейки. Громкость никак не управляется, хотя наверное ей можно управлять через полосовые фильтры и бит громкости в каждом микшере каналов. Бит «атаки» так же никак не используется, а он есть в муз ячейки. И тд и тп. Немного проконсультировавшись на форуме по Агату, avivanov76 подсказал , что, цитирую:

«Условно можно выделить в музыке бас, гармонию и ведущий голос. И вот, похоже, что ЯЗС вокруг этого построена:
1) Бас нужно завести через фильтр НЧ. Он очень сильно режет верха, там почти голый синус остается, поэтому гармоники баса никому не мешают.
2) Гармония — это аккорды, это несколько одновременно звучащих нот. Чтобы они не забили все остальные голоса фильтр СЧ ослабляет громкость.
3) Ведущий голос передает мелодию. Фильтр ВЧ как раз делает звук звонким и резким, он будет хорошо слышен на фоне всех остальных.

Проблема тут только в том, что мелодия изначально должна быть с учетом этого принципа написана. В MIDI плеере вообще непонятно, как на лету определить, какой голос ведущий, а какие голоса относятся к гармонии.

Так же в управляющий регистр можно записать значения $1x, $2x, $3x и это будут разные огибающие.Огибающая 1 (резкая, быстро затухающая) подходит для струнных инструментов, у которых звук извлекают руками. Например гитара, балалайка, арфа.Огибающая 2 (плавная, незатухающая) подходит для струнных инструментов, на которых играют смычком. Например, скрипка, альт, виолончель. Также эта огибающая подходит для духовых и всяких синтезаторных подкладов.Огибающая 3 (резкая, незатухающая) подойдет для пианино и солирующих синтезаторов.»

Поэтому есть куда расти, есть куда стремиться.

Вот такая вот безделушка получилась, надеюсь кому-то было интересно. А если вдруг кто-то дочитал до сюда, то страничка моего проекта на гитхабе:  https://github.com/Tronix286/MuzCell. Там все схемы, плата, герберы, фотографии собранной платы в хорошем разрешении, весь софт, который я на данный момент адаптировал.

Ссылки:

http://agatcomp.ru/agat/Hardware/SoundNCL/jzs52.shtml — Ячейка звукового синтеза 5/2

http://forum.agatcomp.ru//viewforum.php? id=20 — форум по ЯЗС

https://zx-pk.ru/threads/34081-kopiya-po-motivam-quot-muzykalnoj-yachejki-agat-quot-dlya-ibm-pc.html — тема на zx.pk.ru

© Habrahabr.ru