AY-3-8910/12 ZX Spectrum Sound Chip Emulator

FXM

Данные файлы хранят музыку, написанную на языке Fuxoft AY Language (терминология и формат заголовка файла из документации RDOSPLAY).

Данный язык разработал и успешно использовал на Спектруме Fuxoft (Frantisek Fuka).

Структура FXM файла следующая.

Смещение        Размер  Название        Описание
+0              4       ID              Идентификатор ‘FXSM’
+4              2       Addr            Адрес расположения блока данных в памяти Спектрума
+6              ?       Data            Блок данных

Блок данных – структура, взятая из оригинального спектрумовского программного обеспечения, в котором использовалась данная мелодия.

Формат блока данных

Смещение        Размер  Название        Описание
+0              2       AddrA           Адрес первого байта программы на языке Fuxoft AY Language для канала A
+2              2       AddrB           Адрес первого байта программы на языке Fuxoft AY Language для канала B
+4              2       AddrC           Адрес первого байта программы на языке Fuxoft AY Language для канала C
+6              ?                       Далее вперемешку идут программы, подпрограммы на языке Fuxoft AY Language, сэмплы, орнаменты, а также (очень редко) подпрограммы в кодах Z80.

Программы и подпрограммы, как и в любом языке программирования, состоят из последовательности команд. Структурно в этой последовательности можно выделить фразы (набор команд, необходимый для постановки на проигрывание одной ноты). Окончание фразы определяется командой ноты или командой выключения звука. Для проигрывания модуля, каждому каналу выделяется стек размером в 16 слов. Таким образом, максимальное количество вызовов подпрограмм из других подпрограмм ограничено 16. Рекурсивные вызовы подпрограмм не допускаются.

Далее описаны команды этого языка (шестнадцатеричная система счисления).

00 XX – выключение звука.

Команда выключения звука, байтовый параметр XX, следующий за кодом этой команды, содержит количество прерываний, в течение которого будет выключен звук.

01..54 XX – номер ноты, увеличенный на 1.

Устанавливает на проигрывание ноту (номер от 00 до 53) в течении XX прерываний. Номеру ноты 00 соответствует значение 0FBF тонового регистра AY, что при частоте чипа 1773400 Гц эквивалентно ноте ЛЯ субконтроктавы. Расстояние между двумя соседними номерами нот – полутон.

80 XX XX – переход по адресу XXXX.

Простой безусловный переход по адресу XXXX (аналог JP для Z80). Обычно этой командой заканчивается основные программы соответствующих каналов (в этом случае это переход на точку бесконечного цикла).

81 XX XX – вызов подпрограммы по адресу XXXX.

Сохраняет в стеке канала адрес следующей за этой команды и осуществляет переход по адресу XXXX (то есть осуществляется вызов подпрограммы, аналог команды CALL для Z80). Размер стека ограничен 16 словами.

82 XX – задает точку цикла и количество повторов.

Сохраняет в стеке адрес последующей команды – точка цикла, а затем и параметр XX – количество повторов увеличенное на 1. Участок программы, начиная от точки цикла и заканчивая командой 83 будет повторяться (XX – 1) раз (реприза).

83 – реприза.

Повторить (XX – 1) раз с точки, заданной командой 82 XX. Команда извлекает из стека параметр XX и адрес точки цикла, уменьшает XX на 1, если он не равен нулю, то обратно сохраняет в стеке оба параметра и переходит на точку цикла.

84 XX – шум.

Параметр XX (00..1F) задает значение регистра шума AY.

85 XX– миксер.

Параметр XX (установленный или сброшенный бит 0 соответственно разрешает и запрещает вывод тона в данном канале, а бит 3 – шума, остальные биты обнулены) задает значение регистра миксера AY для соответствующего канала.

86 XX XX – орнамент.

Параметр XXXX определяет адрес орнамента для устанавливаемой в данной фразе ноты (по умолчанию будет использован и в последующих фразах).

87 XX XX – сэмпл.

Параметр XXXX определяет адрес сэмпла для устанавливаемой в данной фразе ноты (по умолчанию будет использован и в последующих фразах, при этом команды 8A и 8B определяют, продолжать исполнять сэмпл с текущей позиции или начать его заново при установке последующей ноты, изначально установлен второй режим).

88 XX – транспозиция.

Устанавливает транспозицию равной XX полутонам, при этом XX является числом со знаком. Изначально транспозиция равна нулю.

89 – возврат из подпрограммы.

Извлекает из стека адрес и осуществляет переход на него (аналог команды RET для Z80).

8A – не инициализировать сэмпл.

Включает режим, при котором постановка каждой последующей ноты не приводит к рестарту воспроизведения сэмпла

8B – инициализировать сэмпл.

Включает режим, при котором постановка каждой последующей ноты приводит к рестарту воспроизведения сэмпла (этот режим включен изначально).

8C XX XX – передача управления подпрограмме Z80.

Передает управление по адресу XXXX (подпрограмме в кодах Z80). Я встретил только одну мелодию, где используется данная команда, и там эта подпрограмма не делала ничего, связанного с выводом звука. В данном Эмуляторе эта команда не поддержана. Видимо, задумано Fuxof'ом для синхронизации некоторых визуальных эффектов с музыкой.

8D XX – добавка к шуму.

Добавка к текущему значению регистра шума по модулю 20 (в некоторых версиях по модулю 10, см. описание параметра Andsix в AY-файлах).

8E XX – добавка к транспозиции.

Добавка к текущему значению транспозиции в полутонах.

8F – сохранить транспозицию в стеке.

Сохраняет текущее значение транспозиции в стеке канала.

90 – восстановить транспозицию из стека.

Восстанавливает значение транспозиции из стека канала.

Сэмпл в данном языке имеет простую структуру и отвечает только за амплитуду выходного сигнала. Как и программы, сэмпл – это последовательность команд.

00..0F XX – амплитуда.

Определяет значение регистра громкости данного канала в течение этого и последующих прерываний (количество прерываний определяется параметром XX).

32..41 – амплитуда.

Определяет значение регистра громкости данного канала в течение только этого прерывания (увеличено на 32).

80 XX XX – переход на точку цикла.

Безусловный переход на точку цикла XXXX в данном сэмпле.

Орнамент является более сложной структурой и изменяет частоту тонового регистра в данном прерывании на заданную величину.

80 XX XX – переход на точку цикла.

Безусловный переход на точку цикла XXXX в данном орнаменте.

82 – полутона.

Указывает на то, что, начиная с данного прерывания, прибавки в данном орнаменте осуществляются в полутонах.

83 – единицы тонового регистра.

Указывает на то, что, начиная с данного прерывания, прибавки в данном орнаменте осуществляются в единицах тонового регистра AY.

84 – инвертировать биты миксера.

Инвертирует оба бита миксера для данного канала.

Прочие значения – прибавка.

Изменяет значение тонового регистра AY соответствующего канала путем добавления к нему данной прибавки (число со знаком). Осуществляется или в полутонах или единицах тонового регистра (команда 82 и 83 соответственно).

Глядя на структуру данного модуля, читающий эти строки должен понять, почему автопоиск FXM модулей не так надёжен, как того хотелось бы. Видимо при вытаскивании большой части этих модулей из программ Спектрума, без ручной работы не обойтись (но всегда прежде стоит попробовать встроенный в Эмулятор инструмент поиска FXM прежде чем делать такой печальный диагноз для конкретного файла). При вытаскивании FXM модулей можно ориентироваться на коды проигрывателя Z80, так как они одинаковы у всех модулей. Однако поиск в данном эмуляторе ищет только по самим данным модуля.