Перейти к содержимому

Рекомендуемые сообщения

Спасибо огромное. Все заработало. Только мне нужно было поставить pcm только на SB3 а не на весь SPZ, но я уже это поставил. + 2 балла тебе. Владикомпер, ты говорил что сэмплы после паузы будут продолжать воспроизводиться, а у меня после паузы нету звука, почему?

О лол, я подумал что тебе нужно на весь уровень, извини, я очень слоупочу.

Поделиться сообщением


Ссылка на сообщение

Дело в SMPS. Как было написано в первом посте про флаги:

 

Если флаги панорамирования не заданы (panLR/L/R), "Mega PCM" не будет настраивать панорамирование, сохраняя настройки, сделанные SMPS.

 

"Настройки, сделанные SMPS". А если SMPS ничего не воспроизводит, то он панорамирование DAC он настраивать не будет, то есть после паузы аудио на самом деле будет играть, но оно останется заглушенным.

 

Исправить это просто: нужно сделать так, чтобы Mega PCM сам настраивал панорамирование. Для этого достаточно добавить panLR к флагам твоей DAC-песни.

 

Кстати, скоро я напишу свой гид про воспроизведение DAC-песен с Mega PCM, где постараюсь реализовать это наиболее удобным способом и без "костылей". Перед этим будет еще один важный гид "как улучшить качество воспроизведения сэмплов". Для песен это критично. Из-за того, как часто Соник 1 прeрывает Z80, качество звука заметно падает, появляются шумы. Зато если усовершенствовать SMPS и исправить процедуры VBlank'а, результат получится достойный.

Спасибо, буду ждать улучшений драйвера))) и качества сэмплов.

 

Не я лучше облегчу все - зоздам smps-ку где будет только один dac сэмпл.

Поделиться сообщением


Ссылка на сообщение

Coming Soon:

 

Поделиться сообщением


Ссылка на сообщение

Я о таком даже мечтать не мог.) (Я думаю что pcm файлы музыки будут ВНЕ рома как в Sonic CD) Давай побыстрее реализовывай, жду недождусь оценить о это чудное творенье.

Поделиться сообщением


Ссылка на сообщение
Я о таком даже мечтать не мог.) (Я думаю что pcm файлы музыки будут ВНЕ рома как в Sonic CD) Давай побыстрее реализовывай, жду недождусь оценить о это чудное творенье.

 

Нет. Сделать музыку в отдельных от РОМа файлах невозможно, если только не разработать специально заточенный под это эмулятор. Но тогда хак не будет работать ни в других эмуляторах, ни на реальном железе. В любом случае, это огромный минус, я считаю.

 

Кстати, теперь расскажу чуть подробнее о том, что я сделал в том видео.

 

Все сделано на том же старом добром Mega PCM, драйвер не подвергся абсолютно никаким изменениям. В видео играет звук 8-bit PCM с частотой 26 kHz. Чтобы улучшить качество воспроизведения и добиться максимально "чистого" звука, я модифицировал SMPS и процедуры VBlank'а, чтобы сократить время простоя Z80. Потому что как я уже писал, из-за того, что игре часто приходится останавливать Z80, воспроизведение цифрового звука тоже прерывается и качество заметно падает.

 

Итак, скоро вы увидите:

  • Гид "Как улучшить качество воспроизводимого звука"
  • Гид "Как воспроизводить цифровую музыку на уровнях"
  • Новую версию Mega PCM, с небольшими исправлениями и улучшениями

Поделиться сообщением


Ссылка на сообщение

А я знаю почему ты на видео не прошел уровень до конца. Потому что в конце акта песня какбэ должна останавливаться, но твоя DAC песня не остановится потому что она с приоритетом и будут играть FM и PSG каналы песни Got Though и все обломается. Можешь предложить как это исправить?

Поделиться сообщением


Ссылка на сообщение

Да, я не прошел до конца, потому что вместе с песней играла бы музыка Got Through, точно так же как и тема 1up. Но нет, даже музыка с приоритетом реагирует на команды "пауза" и "остановка". Это я предусмотрел. Как я показал вначале видео, пауза работает, а значит и остановка тоже. Просто мне было лень это исправлять, так как с текущей реализацией это было бы немного... нет, не сложно, просто кривовато. Перед воспроизведением любой SMPS-песни нужно проиграть сэмпл $80, чтобы DAC-песня остановилась.

 

Это видео так называемый "proof-of-concept", просто чтобы продемонстрировать, что это возможно, что это работает. Только после этого уже можно хорошей реализацией этого концепта, чем я в ближайшее время и займусь. Сейчас думаю, как сделать работу с песнями как можно проще и удобнее.

Поделиться сообщением


Ссылка на сообщение

Mega PCM v.1.1

  • Добавлен небольшой фикс на случай воспроизведения битых сэмплов.
     
    Если игра попытается воспроизвести пустой или несуществующий сэмпл, вы ничего не услышите. Например, если вы портировали SMPS песню, а некоторые DAC сэмплы для нее у вас отсутствуют. Прошлая версия Mega PCM как и многие другие драйверы выдала бы рандомный шум из-за ошибки воспроизведения
     
    Это также поможет, если на воспроизведение попадет слот из случайных байтов. Случайные оффсеты теперь не вызовут ошибку с доступом к запрещенным участкам памяти, ведь оффсеты исправляются, чтобы избежать этого.
     
  • Исправлен код синхронизации в циклах воспроизведения PCM и DPCM.
     
    Хотя и я следил за каждым циклом в коде, я слегка просчитался в вычислении циклов для кода синхронизации, из-за чего цикл воспроизведения при достижении последнего банка работал на 4 процессорных цикла быстрее. Следовательно, последний банк сэмпла воспроизводился немного быстрее, чем другие. Несмотря на то, что 4 цикла (длина команды NOP) - это ничтожно мало, ускорение воспроизведения было заметно на высоких частотах дискретизации (22 kHz и выше).
     
  • Mega PCM теперь поддерживает РОМы до 8 МБ!
     
    Прошлая версия имела ограничение до 4 МБ, хотя это не был предел возможностей драйвера. Я решил увеличить лимит и достигнуть максимума, на что способна система переключения банков в Mega PCM - 8 МБ. Это означает, что можно уместить вдвое больше музыки и сэмплов!
     
    Должен предупредить, что крайне мало эмуляторов пока поддерживает большие РОМы. Но если вы все же заинтересовались такой возможностью, постраюсь кратко ввести в курс дела (список эмуляторов см. ниже):
     
    Многие считают, что у SMD есть строгое ограничение до 4 МБ под РОМ. На самом деле консоль способна на большее. Дело в том, что все картриджи официальных игр в свое время были спроектированы так, что они не позволяли адресовать более 4 МБ РОМ-пространства, хотя сама консоль позволяла это делать. Проблема в картриджах, а не в консоли.
     
    К примеру, некоторые флэш-картриджи для Сеги (например Mega Everdrive) уже поддерживают РОМы более 4 МБ, показывая, на что на самом деле способна консоль. К сожалению, крайне мало эмуляторов пока поддерживают большие РОМы.
     
    Факт в том, что вышеупомянутый лимит был закреплен официальным руководством Genesis, где на карте памяти 68K под РОМ секцию выделялось только 4 МБ, а остальное пространство до 8МБ было помечено как "зарезервировано". Примечательно, что в наиболее ранних версиях руководства (1988-89 годы) лимит на РОМ составлял 1 МБ. Авторы многих эмуляторов решили четко следовать руководству и ограничили РОМ-пространство до 4 МБ. В принципе, это верно и ни одна официальная игра не пострадала, и все же хотелось, чтобы больше эмуляторов избавались от этого ограничения, так как оно открывает новые горизонты в разработке под SMD.
     
    Пока существует лишь немного эмуляторов, работающих с большими РОМами. Некоторые из них - хакнутые версии популярных эмуляторов. Их можно найти здесь:
    http://umk3.hacking-cult.org/rus/download.htm

 

Как обновить Mega PCM до версии 1.1

 

Легко.

Скачайте этот архив: https://dl.dropbox.com/u/44757401/MegaPCM_v11_Bin.7z

Замените MegaPCM.z80 в своем хаке на обновленную версию из архива.

Всё.

 

Исходный код Mega PCM v.1.1

 

https://dl.dropbox.com/u/44757401/MegaPCM_v11_SourceCode.7z

 

* * *

 

Если у вас еще нет Mega PCM, но вы решили его поставить, делайте все как написано в первом посте. По ссылкам из первого поста - тоже обновленная версия Mega PCM.

Изменено пользователем vladikcomper

Поделиться сообщением


Ссылка на сообщение

Исходный код Mega PCM v.1.1

 

https://dl.dropbox.c...1_SourceCode.7z

 

Мне кажется, что бесполезно выкладывать исходник, т.к. никто не знает Z80. Даже если знает, вряд ли он решится его модернизировать. Возможно, он только для практики может применить.

Кому надо - тот попросит.

Изменено пользователем Almaz

Поделиться сообщением


Ссылка на сообщение

Скажи, а что плохого в том, что я выложил исходник? Может, он и действительно никому не пригодится, никто им не воспользуется, но хуже от него точно не станет. Хехе, или кто-то потом напишет: "Влад, когда я стал смотреть твой исходник, от кода у меня вдруг закружила голова, я упал и потерял сознание. Теперь в больнице с сотрясением мозга. Зачем ты выложил чертов исходник?"

 

И все же я верю, что хоть кому-нибудь он окажется полезным. Может, это заинтересует кого-нибудь в изучении ассемблера Z80, как меня в свое время заинтересовали дизасемблы родного Z80-драйвера Соник 1 и SMPS Z80. К тому же, исходники выложены на Sonic Retro и SSRG, а там они точно кому-то пригодятся (и уже, кстати, пригодились, как мне признавались). Ну а если бы я не выложил все то, что я выложил там, на ЦИСе, это было бы нечестно.

Поделиться сообщением


Ссылка на сообщение

Скажи, а что плохого в том, что я выложил исходник? Может, он и действительно никому не пригодится, никто им не воспользуется, но хуже от него точно не станет. Хехе, или кто-то потом напишет: "Влад, когда я стал смотреть твой исходник, от кода у меня вдруг закружила голова, я упал и потерял сознание. Теперь в больнице с сотрясением мозга. Зачем ты выложил чертов исходник?"

 

И все же я верю, что хоть кому-нибудь он окажется полезным. Может, это заинтересует кого-нибудь в изучении ассемблера Z80, как меня в свое время заинтересовали дизасемблы родного Z80-драйвера Соник 1 и SMPS Z80. К тому же, исходники выложены на Sonic Retro и SSRG, а там они точно кому-то пригодятся (и уже, кстати, пригодились, как мне признавались). Ну а если бы я не выложил все то, что я выложил там, на ЦИСе, это было бы нечестно.

Ничего плохого.

Зачем я придрался...

Поделиться сообщением


Ссылка на сообщение

Как улучшить качество воспроизведения звука в Mega PCM

 

Все мы знаем, как звучит оригинальный сэмпл SEGA в Соник 1:

 

https://dl.dropbox.com/u/44757401/SEGA_Good.wav

 

Но что, если мы попробуем воспроизвести тот же сэмпл во время игры? Когда происходят массивные передачи данных между компонентами системы, работают скрипты по обновлению музыки и многое другое. Тот же самый сэмпл будет звучать так:

 

https://dl.dropbox.com/u/44757401/SEGA_Bad.wav

 

Это распространяется на все сэмплы, воспроизводимые в игре. То есть все ваши басы, ударные будут звучать с искажениями. Качество заметно падает, сэмпл как бы становится "рваным".

 

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

В конце этого поста также находится приложение - чистый дизасембл, где применен этот гид + небольшой бонус.

 

После этого вы сможете добиться впечатляющих результатов, как, например, этот:

 

Но сначала пожалуй, нам нужно установить, а почему же это происходит?

Следующий ниже текст будет содержать много теории и технических деталей. Если вы не хотите вдаваться в невероятные (!) шокирующие (!!) подробности, пропустите следующий пункт.

 

1. Теоретическое объяснение

 

Здесь проблема не в Mega PCM, а в самом движке Sonic 1.

 

В Сеге, как вы знаете, представлено два процессора - Motorola 68000 и Zilog 80. Сам движок игры работает на мощном 16-битном процессоре M68K, и именно этот процессор управляет по большей частью всеми компонентами приставки. Второй процессор - Z80, используется в Sonic 1 для вывода цифровых сэмплов. Мой драйвер Mega PCM как раз работает на процессоре Z80.

 

Как говорилось выше, во время функционирования игры, движку неизбежно приходится связываться с различными компонентами системы, как звуковые- и видео-чипы, чтобы обновлять звук и изображение. При этом, архитектура приставки накладывает свои ограничения на доступ к ресурсам. Так, например при доступе к звуковому чипу YM2651, процессор Z80 должен быть приостановлен. То же требуется, например, при доступе к памяти Z80 со стороны 68K.

 

Во время игры, Соник 1 останавливает Z80 в следующих случаях:

  1. При работе движка SMPS, так как ему нужен доступ к звуковому чипу YM2612.
  2. Во время DMA-переноса данных в видеопамять (VRAM).

SMPS и DMA-переносы постоянно работают в конце каждого кадра, причем на их выполнение требуется время. Таким образом, Z80 остановки длятся относительно долго, а вместе с тем останавливается работа Mega PCM, а значит, прерывается и обновление DAC, которое целиком лежит на плечах Mega PCM. Из-за неравномерного вывода звука появляются заметные искажения.

 

Для наглядности, представим что у нас есть звуковая волна в форме синусоиды. В идеале она выглядит так:

 

MegaPCM_HQ_Graph1.png

 

Но в Соник 1, Z80 часто останавливается. В моменты остановок Mega PCM не работает, а значит волна не обновляется. Не получая новых сигналов, звуковой чип будет генерировать последний полученный сигнал. Волна будет выглядеть так:

 

MegaPCM_HQ_Graph2.png

 

Серые области - периоды, когда Z80 остановлен и звук не обновляется. Если вырезать их из рисунка, получилась бы исходная красивая синусоида, как в первом графике, но из-за остановок в обновлении звука, волна заметно искажается.

 

Задача моего гида - сократить время остановок Z80 до минимума. К сожалению, полностью избавиться от них невозможно, так как они необходимы для доступа к памяти Z80 и YM. Поэтому добиться качественного воспроизведения цифровых сэмплов на Сеге - очень сложная задача, требующая немалых усилий. Но тут я уже постарался для вас, так что вам лишь остается правильно проследовать всем инструкциям!

 

Итак, нам потребуется максимально оптимизировать вышеперечисленные два фактора:

  1. SMPS
  2. DMA-переносы

Именно из этих двух частей и состоит гид.

 

2. Оптимизация остановок Z80 в SMPS

 

Соник 1 предпочитает останавливать Z80 с самого начала работы SMPS и до ее конца. Это объясняется тем, что звуковому движку в любой момент времени может понадобиться доступ к YM2612 или в памяти Z80 (для управления Mega PCM). Но ведь этот доступ нужен не всегда - большую часть времени движок просто обновляет внутренние события и таймеры, ведь чтение музыкальных файлов и выполнение их внутренних команд занимает большую часть времени. Получается, что Z80 простаивает "просто так" - ведь SMPS обращается к YM довольно редко.

 

Если останавливать Z80 именно в тот момент, когда отдельные процедуры SMPS требуют YM и память Z80 (а не на время выполнения всего кода SMPS), можно добиться нехилой оптимизации. Именно в этом и заключается эта часть гида.

 

Для начала, вам потребуется добавить в свой дизасембл несколько новых макросов. Они заметно упрощают процесс, так как с ними можно избавиться от использования большого и многократно повторящегося кода.

 

; =============================================================
stopZ80	macro
	 move.w	#$100,($A11100).l
	nop
	nop	
	nop

@wait\@:  btst	#0,($A11100).l
	bne.s	@wait\@
endm

; =============================================================

startZ80	macro
	move.w	#0,($A11100).l	; start	the Z80
endm

; =============================================================

waitYM		macro		
@wait\@:	move.b	($A04000).l,d2
	btst	#7,d2
	bne.s	@wait\@
	endm

 

Добавьте эти макросы в начало sonic1.asm или в файл macro.asm (если у вас S1HS, так будет предпочтительнее).

 

Теперь - за дело!

Перейдите к лейбелу sub_71B4C (UpdateMusic в S1HS). В самом начале вы увидете следующий код:

 

   	 move.w	#$100,($A11100).l ; stop the Z80
	nop
	nop
	nop

 

Это код остановки Z80. Так, SMPS останавливает его в самом начале своей главной процедуры и запускает только в самом конце.

Этот код нам здесь больше не понадобится, удалите или закоментируйте его.

 

Теперь, перейдите к лейбелу loc_71C44:

 

loc_71C44:
	move.b	($A04000).l,d2		;++
	btst	#7,d2			;++
	bne.s	loc_71C44		;++
	move.b	#$2A,($A04000).l	;++
	move.w	#0,($A11100).l	; start	the Z80
	rts

 

Учитывая, что вы уже установили Mega PCM, этот код будет выглядить, как показано выше. В самом конце - команда, запускающая Z80. Код, помеченный плюсиками (++), это дополнительный код, специально для Mega PCM. Он реализует небольшой трюк, необходимый для Mega PCM (описание этого трюка можно найти в первом посте). Нам этот код еще понадобится, но не в этом месте.

Удалите весь код, кроме имени лейбела и rts.

 

С этого момента, SMPS больше не останавливает Z80 во время своей работы. Но есть несколько мест, где остановить его необходимо.

 

Первое такое место - это где SMPS отправляет Mega PCM номер DAC сэмпла. Как я уже говорил, когда 68K обращается к памяти Z80, сам Z80 должен быть остановлен.

Идите к лейбелу loc_71C88 и найдите в коде следующую строку:

 

   	 move.b	d0,($A01FFF).l

 

Нам нужно, чтобы Z80 останавливался перед ее выполнением, и продолжал работу сразу после него. В этом нам помогут макросы. Просто замените эту строчку на:

 

   	 stopZ80
	move.b	d0,($A01FFF).l
	startZ80

 

Еще остались места, где SMPS дает Mega PCM команды паузы, снятия с паузы и остановки воспроизведения.

 

Перейдите к лейбелу loc_71E7C и найдите:

 

		move.b	#$7F,($A01FFF).l; pause DAC

 

Дополните это команду таким же образом, после чего она будет выглядеть так:

 

   	 stopZ80
	move.b	#$7F,($A01FFF).l; pause DAC
	startZ80

 

Перейдите к лейбелу loc_71EFE. Прямо над ним, вы увидите:

 

   	 move.b	#0,($A01FFF).l	; unpause DAC

 

Опять же, дополните эту команду, как было сделано выше.

 

И последнее, идите к loc_725B6 и дополните команду:

 

		move.b	#$80,($A01FFF).l ; stop DAC playback

 

И, наконец, SMPS должен остановить Z80 в процедурах обращения к YM.

В этот раз, замена кода будет выглядеть сложнее, к тому же мы применим тот самый код для Mega PCM, который убрали в самом начале.

 

Идите к процедуре sub_7272E и замените весь код на этот:

 

sub_7272E:				; XREF: loc_71E6A
	stopZ80
	waitYM
	move.b	d0,($A04000).l
	waitYM
	move.b	d1,($A04001).l
	waitYM
	move.b	#$2A,($A04000).l
	startZ80
	rts
; End of function sub_7272E

 

Затем, идите к sub_72764 и замените ее на:

 

sub_72764:				; XREF: loc_71E6A; Sound_ChkValue; sub_7256A; sub_72764
	stopZ80
	waitYM
	move.b	d0,($A04002).l
	waitYM
	move.b	d1,($A04003).l
	waitYM
	move.b	#$2A,($A04000).l
	startZ80
	rts
; End of function sub_72764

 

Если вы добрались до этого момента - поздравляю! Вы оптимизировали SMPS.

Убедитесь, что вы сделали все правильно - постройте РОМ и проверьте его в эмуляторе. Звук должен играть как обычно, и DAC сэмплы должны быть слышны.

 

Если с чем-то возникли проблемы, вы всегда можете проверить себя, сравнив ваши правки с правками в чистом дизасембле, где применен этот гид. Его можно скачать чуть ниже, смотрите Приложения в самом конце.

 

3. Оптимизация процедур VBlank

 

Соник 1 всегда останавливает Z80 при DMA-переносах во VRAM и CRAM. На самом деле, останавливать процессор в этом случае совсем необязательно.

 

Когда речь идет о DMA-переносе, VDP останавливает M68K, захватывает его шину и переносит данные из любого места (RAM или ROM) в видеопамять на очень высокой скорости. На Z80 это никак не сказывается, он может спокойно себе работать. Но если Z80 захочет обратится к 68K в этот момент (например, если он читает РОМ), он зависнет, ожидая ответа от 68K. Ответ от 68K он получит только, когда DMA-перенос закончится и 68К продолжит работу.

 

Однако, с учетом описанного выше случая останавливать Z80 принудительно (программно) не имеет смысла - он сам остановится в нужный момент. Тем более, на саму остановку уходят дополнительные циклы процессора, как со стороны 68k, так и со стороны Z80. Самое главное - эмуляторы не эмулируют остановку Z80 при DMA-переносах. Так что исключив принудительную остановку, которую делает Соник 1, мы получим колоссальную оптимизацию. На реальной системе такой оптимизации не будет, но все же получится сэкономить некую долю времени.

 

Итак, мы будем работать с процедурой VBlank. Это loc_B10 или VBlank в S1HS. Ее код очень обширен включает множество роутин.

 

Перейдите к loc_BC8, вы увидите следующий код:

 

  	 move.w	#$100,($A11100).l

loc_BC8:
	btst	#0,($A11100).l
	bne.s	loc_BC8

 

Узнаете цикл остановки Z80? С ним мы уже встречались не раз.

Полностью удалите этот код (включая имя лейбела и одну команду над ним).

 

Теперь, идите к loc_C22. Найдите и удалите эту команду:

 

   	 move.w	#0,($A11100).l

 

Это команда заново запускала Z80 после остановки.

 

Перейдите к loc_C76. Вы снова увидите код остановки Z80:

 

   	 move.w	#$100,($A11100).l ; stop the Z80

loc_C76:
	btst	#0,($A11100).l	; has Z80 stopped?
	bne.s	loc_C76		; if not, branch

 

Удалите его.

 

Затем, найдите лейбел loc_D50 (он находится чуть ниже). Там вы увидите команду запуска Z80, после его остановки в loc_C76.

 

   	 move.w	#0,($A11100).l

 

Удалите ее.

 

Теперь, вы знаете что делать. Найдите и удалите похожие коды в следующих местах:

 

loc_DAE

loc_E64 (move.w #0,($A11100).l расположен чуть выше)

loc_E7A

loc_F54

loc_FAE

loc_1060 (пару строчек выше)

loc_1076

loc_10D4 (в самом конце, перед rts)

 

 

Вот и все!

Гид был очень насыщенный и сложный, и если вы со всем успешно справились - это достойно похвал. Теперь качество воспроизведения цифровых сэмплов будет на высшем уровне и вы сможете проигрывать цифровые песни в отличном качестве.

 

4. Приложение

 

Дизасембл S1HS с установленным Mega PCM и примененным гидом:

 

https://dl.dropbox.c...h_MegaPCM_HQ.7z

 

Этот дизасембл также содержит бонус - на титульнике играет одна из высококачественных цифровых песен из Sonic 1 Megahack: Ultra Edition!

 

Наслаждайтесь!

Изменено пользователем vladikcomper
  • Лайк 2

Поделиться сообщением


Ссылка на сообщение

Узнаете цикл остановки Z80? С ним мы уже встречались не раз.

Полностью этот код (включая имя лейбела и одну строку над ней).

Влад, исправь вторую строчку. Может быть не ясно, что делать с кодом.

А так, как всегда... Круто!

Поделиться сообщением


Ссылка на сообщение

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

Поделиться сообщением


Ссылка на сообщение
Влад, исправь вторую строчку. Может быть не ясно, что делать с кодом. А так, как всегда... Круто!

Ок, исправил. Думал, и так будет понятно, хотя там все равно небольшая опечатка была.

Теперь написано "имя лейбела и одну команду над ним".

 

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

 

 

Это вполне обычное явление. Просто у Сеги очень сложная архитектура (целых два процессора), так что всплывает много тонкостей с этим. Нельзя обращаться к шине данных процессора (Z80), когда процессор выполняет какую-либо программу - тогда шина занята и используется им (через нее он читает саму программу, а программа в свою очередь, может также читать/записывать в память, например). Насколько помню, в более современных системах подобные процессы могут даже происходить автоматически, на аппаратном уровне, но в старой Сеге многое приходится регулировать самостоятельно.

 

Звуковой чип YM2612 тоже "приурочен" к адресному пространству Z80. Так что для доступа к нему, нужно запросить у Z80 шину. Процессор остановит выполнение программы и будет передавать данные от 68K в YM и обратно.

 

Ну зато Сега по крайней мере сама справляется с остановкой Z80, если он обращается к 68K во время DMA. Это происходит само собой, так как процессор Z80 ждет ответа от 68K, который не ответит, пока не справится с DMA.

 

Но в Соник 1 зачем-то сделали принудительную остановку Z80 перед DMA. Может, решили перестраховаться, или тогдашняя документация по железу советовала это делать (в ней было исправлено немало ошибок, к тому же кое-какая информация из нее не совсем точна).

Поделиться сообщением


Ссылка на сообщение

Не знаю,сталкивался ли кто с такой проблемой,и быть может она совсем уж нубская и легкорешаемая,но у меня она вот возникла.

Добавленные мной голосовые фразы звучат очень замедленно и довольно тихо.Хотя в программе GoldWave всё воспроизводится нормально и без тормозов.

Что я делаю не так?...

Поделиться сообщением


Ссылка на сообщение

Уменьшай параметр Pitch, пока не добьешься оптимальной скорости воспроизведения.

Поделиться сообщением


Ссылка на сообщение

Уменьшай параметр Pitch, пока не добьешься оптимальной скорости воспроизведения.

 

Только недавно скачал этот драйвер, сделал всё как написано, при компилящии вылезли две ошибки. Первая вела на 416 строчку. Я её очистил. (Обе ошибки говорили об одной и той же надписи). Саму надпись не помню. После того как я стёр обе, после компиляции звук пропал совсем. Что делать?

Поделиться сообщением


Ссылка на сообщение

Ivan YO говорил про замену мелодии на SBZ. Какие флаги на другие уровни?

Поделиться сообщением


Ссылка на сообщение

Я один не вижу строки Kos_Z80?

Если у тебя ещё не установлен MegaPCM то у тебя должна быть эта строка, выглядит она примерно так:

 
Kos_Z80:
                incbin sound\z80_1.bin
                dc.w ((SegaPCM&$FF)<<8)+((SegaPCM&$FF00)>>8)
                dc.b $21
                dc.w (((EndOfRom-SegaPCM)&$FF)<<8)+(((EndOfRom-SegaPCM)&$FF00)>>8)
                incbin sound\z80_2.bin
                even

Только вместо всех 8) поставь 8 ) (без пробела)

Изменено пользователем SoSic_the_hedgehog

Поделиться сообщением


Ссылка на сообщение

а как из мп3 файла сделать смпс

С помощью музыкального слуха и пары-тройки программ создать MIDI-файл на основе MP3-файла, и работать уже с ним.

Поделиться сообщением


Ссылка на сообщение

Ну, вообще я для написания MIDI использую Cakewalk Pro Audio 9. Помощь в расшифровке нот мне оказывает программа Transcribe!. Вот, собственно и все. Объяснять, что это и как это использовать, я не буду в надежде, что ты сам разберешься; я и так уже бесстыдно оффтоплю.

Поделиться сообщением


Ссылка на сообщение

Я один не вижу строки Kos_Z80?

Её и не должно быть.

Помогите пожалуйста, не знаю из-за чего но у меня начали глючить psg.

Как их починить.

 

P.S на Special Stage Соник 3 и Green Frove act 2 из Соник 3D Blast

Изменено пользователем FlyTF

Поделиться сообщением


Ссылка на сообщение
В 12.06.2012 в 00:00, vladikcomper сказал:

Mega PCM - это мой новый DAC драйвер для Соник 1, написанный с нуля. У нас уже есть DAC-драйверы от JMan'а и S1HL, которые предоставляют массу дополнительных удобств по сравнению с родным драйвером Соник 1. Лично я долго время пользовался драйвером от JMan'а, так как лучше всего подходил моим целям. Однако, как и у всех Z80-драйверов, у него были неприятные недостатки и ограничения. По большому счету, все эти "недостатки" вызваны архитектурой железа: процессор Z80 очень ограничен в плане доступа к ROM-секции (доступ осуществляется через банки в 32 кб) и процессор вынужден посылать сигналы в DAC самостоятельно, что привносит в программирование драйвера немалые трудности.

 

В своем драйвере, я постарался избавиться от неприятных ограничений, которыми обладают другие Z80-драйверы. Я стремился сохранить высокую скорость воспроизведения звука, не смотря на то, что код теперь перегружен дополнительными функциями, которые пришлось внедрить, чтобы преодолеть известные ограничения. К моему удивлению, это удалось, в данный момент Mega PCM способен воспроизводить сэмплы быстрее максимальной частоты выхода DAC у звукового чипа YM2612 (~27 kHz), так что все еще остается место для новых возможностей! ;)

 

Возможности

 

 

  • Автоматическое переключение банков
    Про банки можно забыть, располагайте сэмплы где угодно, как угодно. Сэмплы больше не требуется выравнивать по границе в 32 КБ и следить за тем, чтобы они эту границу не пересекали.
     
  • Неограниченный размер сэмплов
    Размер сэмплов больше не ограничивается 32 КБ. "Mega PCM" может проигрывать сэмплы любого размера, так что сэмплы могут быть настолько большими, насколько это позволит размер РОМа.
     
  • Поддержка двух звуковых форматов
    "Mega PCM" поддерживает форматы 4-bit DPCM и 8-bit PCM.
    Первый широко применялся в Сониковских играх как основной формат для DAC-сэмплов, так он занимает в два раза меньше места чем обычный PCM. Однако, 8-bit PCM является "родным" форматом для звукового чипа YM2612 Сеги, он занимает больше места, но отличается более хорошим качеством.
     
  • Расширенное управление воспроизведением: Стоп, Пауза, Повтор, Приоритет
    "Mega PCM" может приостанавливать и продолжать воспроизведение звука, так что если вы поставите игру на паузу, длинные сэмплы не будут обрезаны после того как вы игру с паузы снимете.
    Имеется возможности повторять сэмпл (подходит для DAC-песен).
    Приоритет означает, что воспроизведение сэмпла не будет прерываться другими, пока он не доиграет до конца (подходит для голосов в игре)
     
  • Панорамирование звука
    Можно настроить воспроизведение сэмпла только в левом или в правом динамике.
     
  • До $5F слотов для сэмплов
    К примеру, драйвер JMan'а позволял не более $1F сэмплов из-за использования в коде 8-битных поинтеров. На самом деле, количество слотов ограничивается только размером памяти, которую занимает таблица сэмплов. Однако SMPS разрешает не более $5F слотов ($81-$CF).

 

 

Как установить Mega PCM

 

Если вы заинтересовались драйвером и хотите его опробовать, тогда вперед!

В этом гиде, я расскажу как вставить драйвер в хак и слегка улучшить SMPS в угоду потребностям нового драйвера. После этого можно с легкостью включать новые сэмплы в игру!

Этот гид также содержит маленький бонус: "Как воспроизводить голоса в игре" (см. ниже)

 

Для начала, скачайте этот архив: https://dl.dropbox.com/u/44757401/MegaPCM_Bin.7z

Это почти готовая к использованию конфигурация драйвера, включающая в себя сэмплы из Соник 3 (кроме timpani, версия С3 сюда не подходит). Скопируйте все файлы в папку с дизасемблом.

 

Гид написан для дизасембла Hivebrain, а также S1HS.

 

1. Замена старого драйвера и загрузчика

 

Откройте Sonic1.asm и найдите лейбел 'Kos_Z80', вы увидите следующий код:

 

 


Kos_Z80:	incbin	sound\z80_1.bin
	dc.w ((SegaPCM&$FF)8)
	dc.b $21
	dc.w (((EndOfRom-SegaPCM)&$FF)8)
	incbin	sound\z80_2.bin
	even
 

 

 

Удалите весь этот код, вместо этого вставьте:

 

 


	include	'MegaPCM.asm'
 

 

 

Теперь, перейдите к лейбелу 'SoundDriverLoad' и замените весь код на новый:

 

 


SoundDriverLoad:			; XREF: GameClrRAM; TitleScreen
	nop
	move.w	#$100,d0
	move.w	d0,($A11100).l
	move.w	d0,($A11200).l
	lea	(MegaPCM).l,a0
	lea	($A00000).l,a1
	move.w	#(MegaPCM_End-MegaPCM)-1,d1

@Load:	move.b	(a0)+,(a1)+
	dbf	d1,@Load
	moveq	#0,d1
	move.w	d1,($A11200).l
	nop
	nop
	nop
	nop
	move.w	d0,($A11200).l
	move.w	d1,($A11100).l
	rts
; End of function SoundDriverLoad
 

 

 

2. Изменение SMPS для работы с Mega PCM

 

Найдите лейбел 'sub_71B4C' (UpdateMusic в S1HS) и чуть ниже найдите этот участок кода:

 

 


		btst	#7,($A01FFD).l
	beq.s	loc_71B82
	move.w	#0,($A11100).l	; start	the Z80
	nop	
	nop	
	nop	
	nop	
	nop	
	bra.s	sub_71B4C
; ===========================================================================

loc_71B82:
 

 

 

Удалите или закомментируйте этот код.

 

 

  Скрыть спойлер

Этот код проверял статус драйвера и не запускал движок SMPS в случае если драйвер устанавливал специальный флаг. Если флаг был задан, SMPS ждал пока драйвер не очистит его. "Mega PCM" такой флаг не нужен, эта проверка была специфична для старого драйвера.

 

 

Далее, найдите перейдите к лейбелу 'loc_71C88', найдите и удалите в коде эти команды:

 

 


		btst	#3,d0
	bne.s	loc_71CAC
 

 

 

 

  Скрыть спойлер

Это был не очень хороший "костыль" (или "хак") для старого драйвера. Хак срабатывал для слотов $88-$8B и вызывал воспроизведение сэмпла $83 (timpani) с разным темпом. Новому драйверу не нужен такой костыль, так как такие вещи можно прописать в таблице сэмплов.

И да, 'loc_71CAC' теперь неиспользованный код, его тоже можно удалить.

 

 

Найдите лейбел 'loc_71C44', в самое начало кода добавьте:

 

 


		move.b	($A04000).l,d2
	btst	#7,d2
	bne.s	loc_71C44
	move.b	#$2A,($A04000).l
 

 

 

 

  Показать спойлер

Mega PCM не настраивает YM-регистр 2A перед отправкой DAC-сигнала в цикле воспроизведения. Это освобождает от дополнительных затрат при доступе к YM. Драйвер полагается, что регистр 2A, настроенный перед началом воспроизведения, не будет сбит. Однако, SMPS во время своей работы посылает команды в другие регистры YM. Таким образом, SMPS должен восстанавливать номер регистра 2A перед возвращением шины Z80 и передачей управления драйверу.

 

 

Следующие изменения позволят Mega PCM приостанавливать воспроизведение сэмплов при паузе и продолжать после нее.

 

Найдите 'loc_71E7C' и почти в самом конце, перед командой BRA, вставьте:

 

 


		move.b	#$7F,($A01FFF).l; pause DAC
 

 

 

 

  Показать спойлер

Воспроизведение сэмпла $7F вызывают команду "пауза".

 

 

Затем, перейдите к лейбелу 'loc_71EDC' и замените весь код до лейбела 'loc_71EFE' на это:

 

 


loc_71EDC:
	adda.w	d3,a5
	dbf	d4,loc_71EC4

	lea	$340(a6),a5
	btst	#7,(a5)
	beq.s	@UnpauseDAC
	btst	#2,(a5)
	bne.s	@UnpauseDAC
	move.b	#-$4C,d0
	move.b	$A(a5),d1
	jsr	sub_72722(pc)

@UnpauseDAC:
	move.b	#0,($A01FFF).l	; unpause DAC
 

 

 

 

  Показать спойлер

Воспроизведение сэмпла $00 отменяет паузу.

 

 

И последний штрих. Будем вызывать команду "остановка", когда SMPS останавливает звук. Перейдите к лейбелу 'loc_725B6' (часть кода 'Sound_E4') и прямо перед "bra.w sub_729B6" добавьте:

 

 


		move.b	#$80,($A01FFF).l ; stop DAC playback
 

 

 

 

  Показать спойлер

Воспроизведение сэмпла $80 останавливает сэмпл.

 

 

Вот и все!

 

Как пользоваться драйвером

 

Откройте файл MegaPCM.asm. Этот файл включает в РОМ скомпилированный Z80-код драйвера, а также таблицу сэмплов. Чтобы облегчить работу с таблицей, для формирования таблицы и включения сэмплов я создал макросы и константы, которые делают часть работы за вас.

 

Прокрутите код, пока не увидите эту часть:

 

 


; ---------------------------------------------------------------
; DAC Samples Table
; ---------------------------------------------------------------

DAC_Entry	$08, Kick, dpcm			; $81	- Kick
DAC_Entry	$08, Snare, dpcm		; $82	- Snare
DAC_Entry	$1B, Timpani, dpcm		; $83	- Timpani
dc.l	0,0					; $84	- 
dc.l	0,0					; $85	- 
dc.l	0,0					; $86	- 
dc.l	0,0					; $87	- 
DAC_Entry	$12, Timpani, dpcm		; $88	- Hi-Timpani
DAC_Entry	$15, Timpani, dpcm		; $89	- Mid-Timpani
DAC_Entry	$1B, Timpani, dpcm		; $8A	- Mid-Low-Timpani
DAC_Entry	$1D, Timpani, dpcm		; $8B	- Low-Timpani

MegaPCM_End:

; ---------------------------------------------------------------
; DAC Samples Files
; ---------------------------------------------------------------

IncludeDAC	Kick, bin
IncludeDAC	Snare, bin
IncludeDAC	Timpani, bin
even
 

 

 

Первый блок -- таблица DAC сэмплов, в которой указывается какой сэмпл играть и как его играть. Таблица будет загружена в память Z80 вместе с кодом драйвера.

 

Второй блок включает сами сэмплы в РОМ. Макрос 'IncludeDAC' ищет файл с заданными именем и расширением в папке 'dac' дизасембла, которую вы добавили из скачанного архива.

 

BIN-файлы обычно используются для DPCM-формата. Благодаря тому, что Mega PCM поддерживает этот формат, можно воспроизводить любые сэмплы из Сониковских игр без преобразования в формат PCM, что сделает файл в два раза тяжелее при том же качестве звука. Если вы хотите преобразовать PCM в DPCM, используйте конвертер JMan'а: http://selbi.se.funpic.de/s1sndcomp.exe

 

WAV-файл должны быть в формате "8-bit unsigned PCM". PCM звук может также быть представлен файлом с расширением 'RAW' (звуковой поток без заголовка), некоторые трекеры работают с этим форматом.

 

Частота звука может быть любой до ~30 kHz для PCM и ~32 kHz для DPCM (Да, внезапно с более сложным в декодировании форматом мой драйвер работает быстрее, похоже я слишком сильно оптимизировал код. Думаю ему помогает то, что он посылает 2 импульса DAC за цикл воспроизведения.)

В действительности, выходная частота DAC у YM2612 ограничивается ~27 kHz (вывод DAC производится за 288 внутренних такта YM), т.е. сэмплы не должны играть быстрее (превышение частоты приводит к потере части посылаемых DAC импульсов).

Однако, эмуляторы не эмулируют такую ситуацию и если вы не заботитесь о качестве звука на реальном железе, не обращайте на это внимание.

 

Таблица DAC сэмплов формируется макросом 'DAC_Entry', у которого следующий формат:

[asm]DAC_Entry <pitch>, <sample name>, <flags>[/asm]

Настоящий 8-байтовый формат, который использует "Mega PCM" вы можете увидеть в определении этого макроса.

 

Pitch (шаг) определяет, как быстро должен играть сэмпл. Чем ниже питч, тем быстрее он играет.

 

Sample Name (имя сэмпла) ссылается на название файла с сэмплом, которое задается макросом 'IncludeDAC'.

 

Flags (флаги) может принимать следующие флаги:

* pcm - задает формат PCM

* dpcm - задает формат DPCM

* loop - заставляет сэмпл повторяться

* pri - флаг приоритета, воспроизведение не будет прервано другими сэмплами. В этом режиме, драйвер отвечает только на команды "пауза"/"остановить"

* panL - воспроизвести только в Левом динамике

* panR - воспроизвести только в Правом динамике

* panLR - воспроизвести в обоих динамиках

 

Флаги можно комбинировать, например так: dpcm+panL+loop+pri

 

Замечание: если флаги панорамирования не заданы (panLR/L/R), "Mega PCM" не будет настраивать панорамирование, сохраняя настройки, сделанные SMPS.

 

Бонус: Как воспроизводить голоса в игре

 

Небольшой пример использования "Mega PCM" -- возможность воспроизводить голоса в игре. Я почти не видел этого в хаках, потому все доступные драйвера до этого момента были весьма неудобны в этом плане.

 

Скачайте небольшой клип: https://dl.dropbox.com/u/44757401/V_Hurt.wav

Поместите его в папку 'dac' дизасембла.

 

В самом конце файла MegaPCM.asm, прямо перед 'even', запилите:

 


	IncludeDAC	V_Hurt,wav
 

 

 

Теперь нужно добавить новый сэмпл в один из свободных слотов в таблице. Для примера, я выберу номер $84. Итак, нам нужно чтобы Mega PCM проиграл сэмпл в формате PCM и с приоритетом (иначе его перебьют DAC-сэмплы из музыки).

Если записать все в таблицу, она будет выглядить примерно вот так:

 

 


	DAC_Entry	$08, Kick, dpcm			; $81	- Kick
DAC_Entry	$08, Snare, dpcm		; $82	- Snare
DAC_Entry	$1B, Timpani, dpcm		; $83	- Timpani
DAC_Entry	$07, V_Hurt, pcm+pri		; $84	- 'Hurt' voice
dc.l	0,0					; $85	- <Free>
dc.l	0,0					; $86	- <Free>
dc.l	0,0					; $87	- <Free>
DAC_Entry	$12, Timpani, dpcm		; $88	- Hi-Timpani
DAC_Entry	$15, Timpani, dpcm		; $89	- Mid-Timpani
DAC_Entry	$1B, Timpani, dpcm		; $8A	- Mid-Low-Timpani
DAC_Entry	$1D, Timpani, dpcm		; $8B	- Low-Timpani
 

 

 

Готово! Теперь сэмпл можно воспроизвести. Однако, чтобы воспользоваться этим, потребуется добавить в игру новую функцию. Найдите код 'PlaySound' и прямо над ним вставьте:

 

 


; ---------------------------------------------------------------------------
; Subroutine to	play a DAC sample
; ---------------------------------------------------------------------------

PlaySample:
move.w	#$100,($A11100).l	; stop the Z80
@0	btst	#0,($A11100).l
bne.s	@0
move.b	d0,$A01FFF
move.w	#0,($A11100).l
rts
 

 

 

Новая функция позволяет воспроизводить DAC сэмплы по их номеру. Номер нового сэмпла - $84, воспроизведем его в игре!

 

Перейдите к 'Hurt_Sound' и замените:

 


	jsr	(PlaySound_Special).l
 

 

на

 


		moveq	#$FFFFFF84,d0
	jsr	PlaySample
 

 

 

Теперь Соник будет кричать, когда его бьют. Наслаждайтесь!

 

Исходный код Mega PCM

 

Mega PCM - драйвер с открытым исходным кодом, вот он:

https://dl.dropbox.com/u/44757401/MegaPCM_SourceCode.7z

 

Я принимаю любые идеи по улучшению ядра Mega PCM а также сообщения о багах. Вы можете свободно модифицировать драйвер для своих целей или создавать новые продукты на его основе.

 

Счастливых сэмплов!

Когда Я Проверяю Об Голосе hurt У Меня Игра Крашается.

Поделиться сообщением


Ссылка на сообщение

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×