Данные файлы хранят музыку, написанную на языке Fuxoft AY Language (терминология и формат заголовка файла из документации RDOSPLAY).
Данный язык разработал и успешно использовал на ZX Spectrum Fuxoft (Frantisek Fuka).
Смещение | Размер | Название | Описание |
---|---|---|---|
+0 | 4 | ID | Идентификатор 'FXSM' |
+4 | 2 | Addr | Адрес расположения блока данных в памяти ZX Spectrum |
+6 | ? | Data | Блок данных |
Блок данных – структура, взятая из оригинального программного обеспечения, в котором использовалась данная мелодия.
Смещение | Размер | Название | Описание |
---|---|---|---|
+0 | 2 | AddrA | Адрес первого байта программы на языке Fuxoft AY Language для канала A |
+2 | 2 | AddrB | Адрес первого байта программы на языке Fuxoft AY Language для канала B |
+4 | 2 | AddrC | Адрес первого байта программы на языке Fuxoft AY Language для канала C |
+6 | ? | Progs | Программы, подпрограммы на языке Fuxoft AY Language, сэмплы, орнаменты, а также (очень редко) подпрограммы в кодах Z80 |
Программы и подпрограммы, как и в любом языке программирования, состоят из последовательности команд. Структурно в этой последовательности можно выделить фразы (набор команд, необходимый для постановки на проигрывание одной ноты). Окончание фразы определяется командой ноты или командой выключения звука.
Для проигрывания модуля, каждому каналу выделяется стек размером в 16 слов. Таким образом, максимальное количество вызовов подпрограмм из других подпрограмм ограничено 16. Рекурсивные вызовы подпрограмм не допускаются.
Команда выключения звука, байтовый параметр XX, следующий за кодом этой команды, содержит количество прерываний, в течение которого будет выключен звук.
Устанавливает на проигрывание ноту (номер от 00 до 53) в течении XX прерываний. Номеру ноты 00 соответствует значение 0FBF тонового регистра AY, что при частоте чипа 1773400 Гц эквивалентно ноте ля субконтроктавы. Расстояние между двумя соседними номерами нот – полутон.
Простой безусловный переход по адресу XXXX (аналог JP для Z80). Обычно этой командой заканчиваются основные программы соответствующих каналов (в этом случае это переход на точку бесконечного цикла).
Сохраняет в стеке канала адрес следующей за этой команды и осуществляет переход по адресу XXXX (то есть осуществляется вызов подпрограммы, аналог команды CALL для Z80). Размер стека ограничен 16 словами.
Сохраняет в стеке адрес последующей команды – точка цикла, а затем и параметр XX – количество повторов, увеличенное на 1. Участок программы, начиная от точки цикла и заканчивая командой 83 будет повторяться (XX – 1) раз (реприза).
Повторить (XX – 1) раз с точки, заданной командой 82 XX. Команда извлекает из стека параметр XX и адрес точки цикла, уменьшает XX на 1, если он не равен нулю, то обратно сохраняет в стеке оба параметра и переходит на точку цикла.
Параметр XX (00..1F) задаёт значение регистра шума AY.
Параметр XX (установленный или сброшенный бит 0 соответственно разрешает и запрещает вывод тона в данном канале, а бит 3 – шума, остальные биты обнулены) задаёт значение регистра миксера AY для соответствующего канала.
Параметр XXXX определяет адрес орнамента для устанавливаемой в данной фразе ноты (по умолчанию будет использован и в последующих фразах).
Параметр XXXX определяет адрес сэмпла для устанавливаемой в данной фразе ноты (по умолчанию будет использован и в последующих фразах, при этом команды 8A и 8B определяют, продолжать исполнять сэмпл с текущей позиции или начать его заново при установке последующей ноты, изначально установлен второй режим).
Устанавливает транспозицию равной XX полутонам, при этом XX является числом со знаком. Изначально транспозиция равна нулю.
Извлекает из стека адрес и осуществляет переход на него (аналог команды RET для Z80).
Включает режим, при котором постановка каждой последующей ноты не приводит к рестарту воспроизведения сэмпла
Включает режим, при котором постановка каждой последующей ноты приводит к рестарту воспроизведения сэмпла (этот режим включён изначально).
Передаёт управление по адресу XXXX (подпрограмме в кодах Z80). Я встретил только одну мелодию, где используется данная команда, и там эта подпрограмма не делала ничего, связанного с выводом звука. В Ay_Emul эта команда не поддержана. Видимо, задумано Fuxof'ом для синхронизации некоторых визуальных эффектов с музыкой.
Добавка к текущему значению регистра шума по модулю 20 (в некоторых версиях по модулю 10, см. описание параметра Andsix в AY-файлах).
Добавка к текущему значению транспозиции в полутонах.
Сохраняет текущее значение транспозиции в стеке канала.
Восстанавливает значение транспозиции из стека канала.
Сэмпл в данном языке имеет простую структуру и отвечает только за амплитуду выходного сигнала. Как и программы, сэмпл – это последовательность команд.
Определяет значение регистра громкости данного канала в течение этого и последующих прерываний (количество прерываний определяется параметром XX).
Определяет значение регистра громкости данного канала в течение только этого прерывания (увеличено на 32).
Безусловный переход на точку цикла XXXX в данном сэмпле.
Орнамент является более сложной структурой и изменяет частоту тонового регистра в данном прерывании на заданную величину.
Безусловный переход на точку цикла XXXX в данном орнаменте.
Указывает на то, что, начиная с данного прерывания, прибавки в данном орнаменте осуществляются в полутонах.
Указывает на то, что, начиная с данного прерывания, прибавки в данном орнаменте осуществляются в единицах тонового регистра AY.
Инвертирует оба бита миксера для данного канала.
Изменяет значение тонового регистра AY соответствующего канала путём добавления к нему данной прибавки (число со знаком). Осуществляется или в полутонах или единицах тонового регистра (команда 82 и 83 соответственно).