PDA

Просмотр полной версии : Помогите в написании эмуля!



molodcov_alex
27.06.2008, 16:50
Товарищи программисты! Помогите, плиз, с написанием эмуля!
Вопрос номер раз: как наиболее грамотно организовать рабочий цикл (тот что от инта до инта), если конкретнее, организацию цикла каждые 20 мс (внутренности уже написаны и работают). В данный момент сделано через timeSetEvent, что ИМХО является неграмотным и неприличным.
Вопрос номер два: звук. Как его сделать, скажем через WaveOut? Размер буффера? И т.д.. Алгоритм в общем. (со звуком никогда дела не имел)
Как вы наверное поняли эмуль пишется пока под Винду на Си.
Заранее благодарен. :)

boo_boo
27.06.2008, 19:18
насчет 20мс
про винду мало что знаю, но в целом -- либо по звуку либо по таймеру высокого разрешения, причем чем евент по расписанию, ИМО лучше замерять тики до и после отработки фрейма, и когда все что надо на фрейм сделано, висеть оставшееся кол-во тиков, ожидая начала следующего фрейма

molodcov_alex
27.06.2008, 19:44
Ну вот щаз как раз через таймер высокого разрешения, но это не кошерно...
Через тики можно попробовать.

Vitamin
27.06.2008, 19:49
Еще можно завязываться на звук. Асинхронно запускаем воспроизведение 20мс звука и начинаем выполнять одно прерывание (проверка по счетчику тактов). Как только закончили- ожидаем, пока буфер до конца воспроизведется. Если отключить звук- получим режим максимальной скорости работы. Так сделано в US например.

Raydac
27.06.2008, 21:43
считай длительность команд в тактах и увязывай прерывание к количеству тактов в "20 ms", так же можешь высчитывать отрезок реального времени между своими прерываниями и увязывать чере цепь обратной связи время задержки выполнения отдельной эмулируемой команды для получения "реалистичного" быстродействия эмулятора

Vitamin
28.06.2008, 00:49
увязывать чере цепь обратной связи время задержки выполнения отдельной эмулируемой команды для получения "реалистичного" быстродействия эмулятора
Это ОЧЕНЬ ресурсозатратно и абсолютно не нужно. Эмуляция с точностью до кадра вполне достаточна для подавляющего большинства случаев

cyrax inc
28.06.2008, 09:57
как в этом случае реализуются эффекты мультиколора и полос на бордюре? обрабатываются отдельно?

Vitamin
28.06.2008, 16:35
как в этом случае реализуются эффекты мультиколора и полос на бордюре? обрабатываются отдельно?
Не забывай, что ты эмулируешь не только выполнение команд процессора, но и все остальные вещи. В том числе и луч ЭЛТ, выполняющий отрисовку экрана. Это позволяет даже клешинг эмулировать.
Со звуком момент тонче- заполнение буфера идет параллельно с воспроизведением. Но в подавляющем большинстве случаев разница в скорости позволяет забивать на это. Главное, не делать большого объема работ в начале кадра- как раз начинается воспроизведение буфера, надо как можно скорее его забить, а уж потом делать прочие операции, пока карта будет играть.

molodcov_alex
30.06.2008, 17:06
В общем сделал я с привязкой на звук... Теперь вот такой вопрос: как грамотно расчитывать эээ... sample чтоли?.. Есть у меня, конечно, один вариант, но он не очень.

Vitamin
30.06.2008, 18:41
Теперь вот такой вопрос: как грамотно расчитывать эээ... sample чтоли?..
То есть? В какое место буфера надо пихать звук в данный момент? Дык, простой математикой

F-частота дискретизации звука (44100,48000 и т.д.)
buf_samp=F/20 - число семплов в буфере

buf_pos = 0; //текущая позиция в буфере
ticks_per_samp = ticks_per_frame / buf_samp; //тактов на один звуковой семпл
last_buf_ticks = buf_pos; //граница текущего семпла в тактах
//цикл по тактам фрейма
for (unsigned ticks = 0; ticks < ticks_per_frame;)
{
ticks += do_cpu_cmd(); //выполняем процессорную команду и увеличиваем счетчик тактов
if (ticks >= last_buf_ticks) //если вышли за пределы текущего семпла
{
wave_buffer[buf_pos++] = current_audio_level; //генерим звук
last_buf_ticks += ticks_per_samp; //сдвигаем границу
}
}

воспроизведение физически должно начинаться вместе с началом цикла

molodcov_alex
30.06.2008, 19:20
Можно конечно и так... Меня только беспокоит то что замер уровня только один раз за сэмпл. А куды пихать итак в принципе понятно.

Добавлено через 2 часа 20 минут
Не, не катит... Надо бы все такты учитывать...

Vitamin
01.07.2008, 00:41
Не, не катит... Надо бы все такты учитывать...
Абсолютно ничто не мешает считать средний уровень звука за все время рендеринга семпла. А уж как считать и как фильтровать- поле для экспериментов.

Vladimir Kladov
01.07.2008, 16:11
А разве не проще посмотреть исходники какого-нибудь эмулятора? (Нет, можно. Разобраться. Даже в исходниках Unreal).

Raydac
01.07.2008, 16:53
да.. Unreal написан жестко... в лучших традициях "мифологических индусов" :) я помнится в нем хотел посмотреть работу ВГ93, да так и забил, потому что проще техническую доку перелопатить в нескольких источниках чем в этой каше разобраться :)

Vitamin
01.07.2008, 17:31
Raydac,
ты исходники glukalka еще посмотри. Вот где перелом мозга. Один 600-кбайтный исходник на голом С (емнип).

Vladimir Kladov
01.07.2008, 19:21
посмотреть работу ВГ93
Забавно, но именно эта часть написана практически так же во всех других эмуляторах, исходники которых я видел. Там по-другому просто не получится: это реализация автомата с множеством состояний, управлением и данными на входе, состоянием и данными на выходе. И даже язык программирования ничего не меняет, кроме синтаксических конструкций.

Один 600-кбайтный исходник на голом С
И чем это отличается от unreal? Только тем, что в unreal файл разбит на включаемые в основной модуль части?

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

Я прикола ради выложил (недорабочий, правда) вариант EmuZGL в исходниках. Можно там глянуть. Но это Паскаль (но лучше, чем EmuZWin - там 3/4 - ассемблер).

MEGAMONSTER
01.07.2008, 20:59
Кстати эмулятор Юдина очень даже ничего, компактный и хорошо совместимый, интересно исходники обнародованы? Только он наверняка ведь на ассемблере.

Alexandr Medvedev
02.07.2008, 18:11
интересно исходники обнародованы?Нет. Ни DOS ни Win32 версии не доступны в исходниках.
Только он наверняка ведь на ассемблере.Win32 версия на Borland Builder, DOS версия -- вероятно TASM.

Добавлено через 5 минут

да.. Unreal написан жестко... я помнится в нем хотел посмотреть работу ВГ93Библиотека из Unreal Speccy для эмуляции контроллера дисковода давно приведена к удобочитаемому виду и распространяется отдельно в виде исходников (портированных на C++) предназначенных для использования в других эмуляторах.

Raydac
02.07.2008, 18:18
Библиотека из Unreal Speccy для эмуляции контроллера дисковода давно приведена к удобочитаемому виду и распространяется отдельно в виде исходников (портированных на C++) предназначенных для использования в других эмуляторах.

ну может мне старые исходники попались

Titus
06.07.2008, 03:42
Со звуком момент тонче- заполнение буфера идет параллельно с воспроизведением. Но в подавляющем большинстве случаев разница в скорости позволяет забивать на это.
Если завязываться на звук, то можно позабыть о четкой синхронизации кадров ПЦ и эмулируемого спекки. В идеале (например при 100Гц развертке на ПЦ) за 2 пц-шных кадра - 1 спековский, ни больше, ни меньше. Так что синхронизироваться в таком случае нужно исключительно на развертку, а как подогнать звук - это уже извращение номер 2...

Vitamin
06.07.2008, 13:08
Если завязываться на звук, то можно позабыть о четкой синхронизации кадров ПЦ и эмулируемого спекки.
Как раз наоборот. Набор частот звука довольно ограниченный (22, 44.1, 48, 96кГц) и рассчитать количество семплов/время не составляет труда. А частота кадров в общем случае у каждого пользователя своя (менять ее не стоит), да и не делится она на число кадров. Конечно, можно закладываться на RTC, но тогда прийдется узнавать частоту кадров и опять-таки ждать завершения. Плюс в винде точность таймеров оставляет желать лучшего.
И качества синхронизации по звуку в большинстве случаев более чем достаточно...

Titus
06.07.2008, 18:44
Как раз наоборот. Набор частот звука довольно ограниченный (22, 44.1, 48, 96кГц) и рассчитать количество семплов/время не составляет труда. А частота кадров в общем случае у каждого пользователя своя (менять ее не стоит), да и не делится она на число кадров. Конечно, можно закладываться на RTC, но тогда прийдется узнавать частоту кадров и опять-таки ждать завершения. Плюс в винде точность таймеров оставляет желать лучшего.
И качества синхронизации по звуку в большинстве случаев более чем достаточно...
Лично для меня идеальный вариант это когда эмулятор подстраивается под ближайшую наиболее подходящую развертку (например, эмулируем пентагон с частотой кадров, скажем 58Гц; значит ставим развертку на ПЦ, скажем 100Гц или 50Гц (если позволяет монитор)), подгоняем тайминги эмулируемой машины под развертку ПЦ (если это был пентагон, то он начинает бысрее работать на 4%), и в результате получаем абсолютную плавность эмуляции, т.к. каждому новому изображению, выводимому на ПЦ соответствует новый кадр эмулируемого спекки. Без пропусков и дублирований кадров.
А вот со звуком в таком случае сложнее, по скольку дже имея гарантированные стандартные наборы (44.1, 48 и т.д.) и зная точную текущую развертку, мы все равно не сможем полагаться на эти данные, т.к. как минимум тактирование звуковухи и видюхи идет от разных кварцев, а стало быть получаем еще целый ряд проблем.