Нестандартное использование General Sound (с) Dr.Lion/RSM ────────────────────────────────────────── Приведенный ниже материал является авто- рским достоянием! При его использовании ссылка на автора обязательна! На многое ли способна звуковая карточка General Sound (далее GS)? Кроме проигрива- ния mod'ов и sample'ов она может еще много чего, если заставить работать ее нестанда- ртным способом. Для этого нам нужно загру- зить в GS свою программу, передать ей уп- равление и получить полную ВЛАСТЬ над же- лезом GS. А железо то у GS весьма нехилое: Процессор: Z80 12MHz Прерывания: INT 37500Hz Память: 128-512Kb (страницами по 32Kb) DAC: 4 канала x 8 бит каждый Громкость: 4 канала x 5 бит каждый Меня долго мучала одна бредовая идея. А можно ли создать на базе Z80 устройство, которое могло бы эмулировать работу муз. сопроцессора AY-3-8910 или его YAMAHA ана- лога? Конечно можно, но каким должно быть такое устройство? Оно должно програмно-ап- паратным способом формировать выходной си- гнал трех каналов A,B,C. Но по самым скро- мным подсчетам частота процессора устрой- ства должна быть не менее 14MHz. Даже если устройство я и соберу, то кто, кроме меня захочет собрать его и поцепить на свой старичок SPECCY? Кто поддержит новый стан- дарт? А как быть людям, которые сидят на эмуляторах ZX-SPECTRUM? Вот тут-то и поя- вилась идея использавать для эмуляции AY железо GS. GS более-менее стандартный де- вайс и поддерживается серьёзными эмулято- рами ZX. Хоть частота CPU GS и меньше нео- бходимых 14MHz, реализовать на нем упроще- нный вариант эмулятора AY все-таки можно. Через несколько минут я сумею убедить вас в этом. Итак, давайте подробнее разберемся, как нам заставить зазвучать GS до боли знако- мыми звуками AY. Во-первых, давайте уяс- ним, что такое AY и как он работает. AY - это микросхема, которая содержит в себе три генератора прямоугольных импульсов (цифровой тон), генератор шума, генератор огибающей, регистры амплитуды, регистр сме сителя, регистр формы огибающей и три ЦАП. Генераторы тона Они представляют собой некие счетчики- делители с предустановкой 12-ти битного коэффициента деления и выходом цифрового тона. Счетчики-делители считают на убыва- ние и при достижении 0-го значения меняют выходной логический сигнал на противопо- ложный. Входной частотой для счетчиков- делителей является тактовая частота AY, разделённая на 16. Генератор шума Он, по-сути, состоит из счетчика-делите- ля, аналогичного генератору тона и устрой- ства генерации псевдо-случайного выходного логического сигнала. Это устройство собра- но на сдвигающем регистре и элементе "Ис- ключающее ИЛИ". Сигнал генератора шума фо- рмируется примерно так: тактовый генератор AY, разделенный на 16 -> 5-ти битный счет- чик-делитель -> генератор псевдо-случайно- го выходного логического сигнала. Генератор и форма огибающей Генератор огибающей состоит из 16-ти би- тного счетчика делителя к логическому вы- ходу которого подключен 4-х разрядный ре- версивный счетчик. Режим работы реверсив- ного счетчика задают биты регистра формы огибающей. На выходе реверсивного счетчи- ка формируется 4-х разрянная последовате- льность амплитуд огибающей которая подае- тся вначале на смеситель а потом на ЦАП. Регистры амплитуды Так же, как и генераторы тона представ- лены для каждого канала AY раздельно. Мла- дшие 4-ре бита регистра являются кодом ам- плитуды и подаются на смеситель. Бит 4 - это флаг, указывающий смесителю на источ- ник амплитуды. При 0 - источник младшие биты регистра амплитуды, при 1 - источник код на выходе реверсивного счетчика гене- ратора огибающей. Регистр смесителя Биты 0-2 разрешают/запрещают поступление в смеситель выходных логических сигналов генераторов тона для каждого канала, биты 3-5 разрешают/запрещают поступление в сме- ситель выходного логического псевдо-случа- йного сигнала от генератора шума для каж- дого канала отдельно. Если логический сиг- нал источника равен 0, то его код амплиту- ды тоже равен 0, если равен 1, то источник кода амплитуды определяется в зависимости от флага огибающей в регистре амплитуды. Цифро-аналог. преобразователи На ЦАП каждого канала подаются сформиро- ваные смесителем коды амплитуд тона, шума и огибающей. Эти коды складываются и ЦАП формирует на выходе определенный уровень напряжения. Следует отметить, что шкала уровней напряжений ЦАП AY логарифмическая. Из всей описаной выше начинки AY в GS имеются лишь ЦАП'ы, которые к тому же име- ют линейную шкалу выходного напряжения. Поэтому недостающие узлы мы будем строить из особых "кирпичиков" - команд CPU Z80. Прежде всего давайте определим задачи, которые должен выполнять эмулятор AY. Их всего две: 1. Генерация выходных сигналов каналов AY. 2. Интерпретация поступающих на эмулятор входных данных (данные в формате реаль- ного AY), перенастройка эмулятора. Т.е. у нас должно работать одновременно две задачи (процесса). Причем первая из них должна работать так, чтобы ничто не могло прервать её работу, а значит повли- ять на стабильность и качество звука - это задача с абсолютным приоритетом. Очевидно, что вторую задачу можно выполнять по мере возможности но не следует забывать, что скорость её работы напрямую связана со скоростью обмена между эмулятором AY и ZX. Теперь перенесем изложенные рассуждения на железо GS. Задача N1 должна работать в цикле обработки маскируемых прерываний (именно этот тип прерываний доступен в GS) а задача N2 - в оставшееся после обработки прерываний время. Давайте прикинем длину одного цикла прерываний GS в тактах: Lgsi=Fgsc/Fgsi где Lgsi - длина цикла прерывания, такт; Fgsc - тактовая частота GS Z80 =12MHz; Fgsi - частота прерываний GS =37500Hz. Lgsi=12000000/37500=320 тактов Полученая цыфра вам, на первый взгляд,ни о чем не говорит. Но, 320 тактов - это 80 элементарных комманд или 30-35 более-мение серьезных комманд. Поверте, этого недоста- точно для эмуляции всех узлов AY. Мало то- го, доже 640 тактов не хватает. Поэтому для процедуры эмуляции придетля выделить 3 прерывания по 320 тактов, т.е. 960 тактов. За это время можно просчитать все необхо- димые узлы AY. Вот так выглядит процедура эмуляции, подвешеная на прерывания: ;------ Процедура генерации работы AY (обработчик INT в GS) ---- GS_INT EXA ;4 OUT to DAC EXX ;4 LD A,(#6000) ;13 LD A,(#6100) ;13 LD A,(#6200) ;13 LD A,(#6300) ;13 WorkTime=60 A_SetA LD DE,#0000 ;10 TONE A A_NumA LD HL,#0000 ;10 ADD HL,DE ;11 LD (A_NumA+1),HL ;16 A_NumB LD A,#00 ;7 A_SetB ADC A,#00 ;7 LD (A_NumB+1),A ;13 JR NC,B_SetA ;7/12 LD A,C ;4 XOR %00000001 ;7 MinTime=86 LD C,A ;4 MaxTime=96 B_SetA LD DE,#0000 ;10 TONE B B_NumA LD HL,#0000 ;10 ADD HL,DE ;11 LD (B_NumA+1),HL ;16 B_NumB LD A,#00 ;7 B_SetB ADC A,#00 ;7 LD (B_NumB+1),A ;13 JR NC,C_SetA ;7/12 LD A,C ;4 XOR %00000010 ;7 MinTime=86 LD C,A ;4 MaxTime=96 C_SetA LD DE,#0000 ;10 TONE C C_NumA LD HL,#0000 ;10 ADD HL,DE ;11 LD (C_NumA+1),HL ;16 C_NumB LD A,#00 ;7 C_SetB ADC A,#00 ;7 LD (C_NumB+1),A ;13 JR NC,E_SetA ;7/12 LD A,C ;4 XOR %00000100 ;7 MinTime=86 LD C,A ;4 MaxTime=96 E_SetA LD DE,#0000 ;10 ENVELOP E_NumA LD HL,#0000 ;10 ADD HL,DE ;11 LD (E_NumA+1),HL ;16 E_NumB LD A,#00 ;7 E_SetB ADC A,#00 ;7 LD (E_NumB+1),A ;13 JR NC,N_SetA ;7/12 LD B,(IX) ;19 MinTime=86 INC LX ;8 MaxTime=108 N_SetA LD DE,#0000 ;10 NOISE N_NumA LD HL,#0000 ;10 ADD HL,DE ;11 LD (N_NumA+1),HL ;16 N_NumB LD A,#00 ;7 N_SetB ADC A,#00 ;7 LD (N_NumB+1),A ;13 JR NC,Mixer ;7/12 LD A,R ;9 RRCA ;4 LD R,A ;9 JR NC,Mixer ;7/12 LD A,C ;4 XOR %00111000 ;4 MinTime=86 LD C,A ;4 MaxTime=122 Mixer LD A,C ;4 MIXER MixVal OR 0 ;7 LD L,A ;4 WorkTime=15 AEnFlag LD H,B ;4/7 DAC A VALUE NOP ;4/0 LD A,H ;4 BIT 0,L ;8 JR NZ,ASetVo0 ;7/12 ADD A,H ;4 ASetVo0 BIT 3,L ;8 JR NZ,ASetVo1 ;7/12 ADD A,H ;4 MinTime=64 ASetVo1 LD (#6000),A ;13 MaxTime=63 BEnFlag LD H,B ;4/7 DAC B VALUE NOP ;4/0 LD A,H ;4 BIT 1,L ;8 JR NZ,BSetVo0 ;7/12 ADD A,H ;4 BSetVo0 BIT 4,L ;8 JR NZ,BSetVo1 ;7/12 ADD A,H ;4 BSetVo1 LD (#6100),A ;13 MinTime=77 LD (#6200),A ;13 MaxTime=76 CEnFlag LD H,B ;4/7 DAC C VALUE NOP ;4/0 LD A,H ;4 BIT 2,L ;8 JR NZ,CSetVo0 ;7/12 ADD A,H ;4 CSetVo0 BIT 5,L ;8 JR NZ,CSetVo1 ;7/12 ADD A,H ;4 MinTime=64 CSetVo1 LD (#6300),A ;13 MaxTime=63 EXX ;4 OTHER EXA ;4 EI ;4 RET ;10 WorkTime=22 ;MinWorkTime=732 MaxWorkTime=817 MidWorkTime=775 Free=143-10 Путем подсчета минимального и максималь- ного времени работы процедуры можно уста- новить, что период ее запуска составляет 3 прерывания (внутри процедуры не может возникнуть прерывание) т.е. базовая часто- та дискретизации равна: Fgsd=Fgsi/3=37500/3=12500Hz Чтобы сформировать один период генерато- ра частоты тона Fayt необходима частота дискретизации 2*Fayt (т.к. за один период частоты дискретизации формируется только один полупериод Fayt). В нашем случае ба- зовая частота дискретизации равна 12500Hz, следовательно максимальная частота генера- тора тона составляет Fgsd/2=6250Hz, т.е. минимальное значение регистра тона - 18. (продолжение следует) ──────────────────────────────────────────