3Bit #01
03 января 2005

Программинг - Нестандартное использование General Sound: эмулятор звукового сопроцессора AY-3-8910.

<b>Программинг</b> - Нестандартное использование General Sound: эмулятор звукового сопроцессора AY-3-8910.
  Нестандартное использование
        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.

     (продолжение следует)
──────────────────────────────────────────



Другие статьи номера:

От редакции - новый украинский электронный журнал под названием "3BiT".

От редакции - накануне: переписка авторов журнала с корреспондентами.

От редакции - Credits: авторы журнала.

Speccy news - новости: Scl выпустил газету Cossackos, результаты Воронежского фестиваля KidSoft'2004, Сергей Бульба архив AY музыки, Alone Coder выпустил Info Guide #6...

Программинг - новый быстрой и короткий PT3.x Player от RSM.

Программинг - дизайн исходных кодов: основные требования к листинг программы, ориентированной на широкую публику.

Программинг - процедуры печати текста шрифтами 8х8, 6х8, 5х8, 4х8 точек.

Программинг - обзор особенностей моделей оттечественного и фирменного спектрума от Rob F.

Программинг - сборник кодов: Рисование окна с рамкой в цвете, обработка дисковых ошибок TR-DOS, универсальня процедура Scroll'a экрана.

Программинг - Game Making: Mad Killer делится опытом создания игр для ZX Spectrum.

Программинг - Нестандартное использование General Sound: эмулятор звукового сопроцессора AY-3-8910.

Hacker Zone - "фрикинг": Халявные звонки на таксофонах. Бесплатные звонки в любую точку мира.

Перспективы - Dune для Спектрума от Сосюра Игоря.

Есть мнение - Mad Killer уличает Инфорком в продажности PC.

Рабочий стол - JPEG/GIF laboratory 1.1: программа для просмотра картинок в формате JPEG/GIF.

Рабочий стол - General Sound AY Emulator v1.0

Рабочий стол - обзор утилиты для поиска музыкальных файлов Pro Tracker 3.X Mod Finder v1.2

Игромания - Архивариус: обзор не очень свежей но интересно адвентюры "Последняя авантюра".

Игромания - Wolf 2004: Мир увидел то, над чем трудился Alone Coder целых 8-мь лет!!

Железячки - Кое-что о CMOS-часах: доработанная схема от Alone Coder'a.

Железячки - обзор некоторых современных контроллеров для работы с внешними накопителями информации для ZX-Spectrum.

Веселуха - Жизнь простого сисадмина И печальна и тосклива если рядом нету пива: Сисадмину посвящается.

Веселуха - юмористический рассказ: Я МАШИНА.

Веселуха - Компьютерные анекдоты.

Иной мир - Radeon X700: недорогая основа для геймерских карт.

Разное - отчет Rob F. с Украинской тусовки SpeXtream'2004.

Разное - старости: для чего нужны программы, особенно игровые и как их делать хорошо.

Разное - Конкурс от групы P7S для патриотов Спектрума!

Разное - Интервью с DESALEX'ом/XPJ.

Разное - интервью с автором одного из самых ожидаемых игровых проектов, игры Dune: The Battle for Arakkis.

Разное - интервью с автором нашумевшей демки под VIC-20 - Viznut/PWP.

Разное - интервью с известным Английским спектрумистом Gasman/Raww arse.

Разное - Интервью с Random'om взятое на Construction Chaos 2004.

Разное - Реклама - двигатель торговли и не только.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Застрял ? - Описание игры "Night Breed".
Лит. Страничка - головная боль полковника хауэлла или "Объвляю заседание открытым" (окончание).
BBS - список станций BBS ZXNet.
PartyZone! - NUO'tm - это первая виртуальная (заочная) в 2001 году.
Хорошая пресса - рекомендации будущим авторам газет и журналов.

В этот день...   14 декабря