Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Константы музыкального синтезатора
- const int ayAddrPort = 0xFFFD;
- const int ayPortAddrHigh = ayAddrPort >> 8;
- const int ayDataPort = 0xBFFD;
- const int ayPortDataHigh = ayDataPort >> 8;
- const int ayRegToneAL = 0;
- const int ayRegToneAH = 1;
- const int ayRegToneBL = 2;
- const int ayRegToneBH = 3;
- const int ayRegToneCL = 4;
- const int ayRegToneCH = 5;
- const int ayRegNoiseTone = 6;
- const int ayRegMixer = 7;
- const int ayRegVolumeA = 8;
- const int ayRegVolumeB = 9;
- const int ayRegVolumeC = 10;
- const int ayMixerToneA = 0x01;
- const int ayMixerToneB = 0x02;
- const int ayMixerToneC = 0x04;
- const int ayMixerNoiseA = 0x08;
- const int ayMixerNoiseB = 0x10;
- const int ayMixerNoiseC = 0x20;
- // Константы формата хранения звуковых эффектов
- const int fxTeminator = 0x20; //! Лучше использовать значение fxFlagSetTone без fxFlagTone
- const int fxFlagNoise = 0x10; //! Лучше, что бы позиция бит повторяла регистр AY
- const int fxFlagSetTone = 0x20;
- const int fxFlagSetNoise = 0x40;
- const int fxFlagTone = 0x80;
- const int fxChannel = 2; // Выводить эффекты в этот канал AY
- uint16_t fxPtr = 0; // Адрес в памяти звучащего эффекта.
- void fxInit()
- {
- musicInit();
- musicTick();
- fxPtr = hl = 0;
- }
- void fxTick()
- {
- // Музыкальный проигрыватель загрузит регистры синтезатора следующими значениями.
- // musicTick();
- // Указатель на звучащий в данный момент эффект в регистр HL.
- hl = fxPtr;
- // Нужно ли запустить новый эффект?
- a = gFx;
- if (a != 0)
- {
- // Вычисление адреса эффекта. Аналог hl = fxTable[a - 1].
- a += a;
- l = (a += [&fxTable - 2]);
- h = ((a +@= [(&fxTable - 2) >> 8]) -= l);
- a = *hl; hl++; h = *hl; l = a;
- // Сброс переменной gFx.
- gFx = (a ^= a);
- }
- // Если никакой эффект не воспроизводится, то выходим.
- if (flag_z (a = h) |= l) return;
- // Считываем первый байт содержащий громкость и флаги
- e = *hl; hl++;
- // Записываем флаги в регистр микшера. Регистр микшера пока хранится в D.
- d = 0xFF;
- if (e & fxFlagTone) d &= [0xFF ^ (ayMixerToneA << fxChannel)];
- if (e & fxFlagNoise) d &= [0xFF ^ (ayMixerNoiseA << fxChannel)];
- // Запись в регистр громкости
- bc = ayAddrPort; a = [ayRegVolumeA + fxChannel]; out(bc, a);
- b = ayPortDataHigh; (a = e) &= 0x0F; out(bc, a);
- // Запись в регистр тона, если установлен соответствующий флаг
- if (e & fxFlagSetTone)
- {
- b = ayPortAddrHigh; a = [ayRegToneAL + fxChannel * 2]; out(bc, a);
- b = ayPortDataHigh; a = *hl; hl++; out(bc, a);
- b = ayPortAddrHigh; a = [ayRegToneAH + fxChannel * 2]; out(bc, a);
- b = ayPortDataHigh; a = *hl; hl++; out(bc, a);
- }
- // Необходимо изменить шум
- if (e & fxFlagSetNoise)
- {
- a = *hl; hl++;
- // Значение шума больеш fxTeminator является терминатором
- if (a >= fxTeminator)
- {
- fxPtr = hl = 0;
- return;
- }
- // Запись шума в регистр
- b = ayPortAddrHigh; e = ayRegNoiseTone; out(bc, e);
- b = ayPortDataHigh; out(bc, a);
- }
- // Запись в регистр микшера отдельных бит
- b = ayPortAddrHigh; a = ayRegMixer; out(bc, a);
- a = in(bc);
- a |= [(ayMixerToneA << fxChannel) | (ayMixerNoiseA << fxChannel)];
- a &= d;
- b = ayPortDataHigh;
- out(bc, a);
- // Сохранение указателя
- fxPtr = hl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement