Вопрос о точности подсчета циклов при эмуляции процессора - PullRequest
5 голосов
/ 19 августа 2011

Я планирую создать эмулятор Sega Master System в течение следующих нескольких месяцев в качестве хобби-проекта на Java (я знаю, что это не лучший язык для этого, но я нахожу его очень удобным для работы, и какчастый пользователь Windows и Linux, я думал, что кроссплатформенное приложение будет отличным).Мой вопрос касается подсчета циклов:

Я просмотрел исходный код для другого эмулятора Z80, а также для других эмуляторов, и, в частности, цикл выполнения заинтриговал меня - когда он вызывается, передается intв качестве аргумента (скажем, 1000 в качестве примера).Теперь я понимаю, что для каждого кода операции требуется разное количество циклов, и что по мере их выполнения число циклов уменьшается от общего значения.Как только число оставшихся циклов <= 0, цикл выполнения заканчивается. </p>

Мой вопрос заключается в том, что многие из этих эмуляторов не учитывают тот факт, что последняя выполняемая инструкция может увеличить числоциклы к отрицательному значению - это означает, что между циклами выполнения можно в итоге сказать, что выполняется 1002 цикла вместо 1000. Это важно?Некоторые эмуляторы учитывают это, компенсируя следующий цикл выполнения, а некоторые нет - какой подход лучше?Позвольте мне проиллюстрировать мой вопрос, так как я не очень хорошо разбираюсь:

public void execute(int numOfCycles) 
{ //this is an execution loop method, called with 1000.
   while (numOfCycles > 0)
   {
      instruction = readInstruction();
      switch (instruction)
      {
         case 0x40: dowhatever, then decrement numOfCycles by 5;
         break; 
         //lets say for arguments sake this case is executed when numOfCycles is 3.
      }
}

После окончания этого конкретного примера зацикливания numOfCycles будет равен -2.Это будет только небольшая неточность, но имеет ли это значение в целом для опыта людей?Я был бы признателен за чье-либо понимание этого вопроса.Я планирую прерывать процессор после каждого кадра, так как это кажется уместным, поэтому 1000 циклов - это мало, я знаю, это всего лишь пример.

Большое спасибо, Фил

Ответы [ 3 ]

5 голосов
/ 24 октября 2015
  1. большинство эмуляторов / симуляторов, имеющих дело только с тактовыми сигналами CPU Clock

    Это хорошо для игр и т. Д ... Итак, у вас есть таймер или что-то еще, и вы запускаетесимуляция ЦП, пока ЦП не смоделирует продолжительность таймера.Затем он спит до следующего интервала таймера.Это очень легко моделировать.Вы можете уменьшить ошибку синхронизации с помощью подхода, о котором вы спрашиваете.Но, как сказано здесь для игр, это обычно не нужно.

    У этого подхода есть один существенный недостаток , и ваш код работает лишь на долю реального времени.Если интервал таймера (временная гранулярность) достаточно велик, это может быть заметно даже в играх.Например, вы нажали Клавишу клавиатуры во время, когда эмуляция спит, тогда она не обнаружена.(ключи иногда не работают).Вы можете исправить это, используя меньшую временную гранулярность, но на некоторых платформах это очень сложно.В этом случае ошибка синхронизации может быть более «видимой» в сгенерированном программном обеспечении Звук (по крайней мере, для тех людей, которые могут слышать это и не слышать таких вещей, как я).

  2. если вам нужно что-то более сложное

    Например, если вы хотите подключить реальное HW к вашей эмуляции / симуляции, то вам нужно эмулировать/ симулировать BUS'ы.Также такие вещи, как плавающая шина или конкуренция системы очень трудно добавить к подходу # 1 (это выполнимо, но с большой болью).

    Если вы перенесете время и эмуляцию на Машинные циклы Все станет намного проще и вдруг такие вещи, как конфликт или прерывание HW, плавающие шины решают сами почти самостоятельно.Я перенес свой эмулятор ZXSpectrum Z80 на этот тип времени и вижу свет.Многие вещи становятся очевидными (например, ошибки в документации кода операции Z80, время и т. Д.).Кроме того, спор стал очень простым (всего несколько строк кода вместо ужасных таблиц декодирования почти для каждой записи типа инструкции).Эмуляция HW также стала довольно простой, я добавил в Z80 такие вещи, как контроллеры FDC, эмуляцию чипов AY в Z80 (нет хаков, которые действительно работают на их оригинальном коде ... даже форматирование дискет :)), так что больше никаких TAPE загружает хаки и не работаетдля пользовательских загрузчиков, таких как TURBO

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

    Каждая инструкция представлена ​​записью в таблице с информацией о времени, операндах, функциональности ... Весь набор команд представляет собой таблицу всех записей этих тезисов длявсе инструкции.Затем я формирую базу данных MySQL для своего набора инструкций.и сформируйте подобные таблицы для каждого набора команд, который я нашел.Затем мучительно сравнивали их все, выбирая / исправляя то, что не так и что правильно.Результат экспортируется в один текстовый файл, который загружается при запуске эмуляции.Звучит ужасно, но на самом деле это сильно упрощает, даже ускоряет эмуляцию, поскольку декодирование команд теперь просто обращается к указателям.Пример файла данных набора команд можно найти здесь Какая правильная реализация для аппаратной эмуляции

Несколько лет назад я также опубликовал статью об этом (к сожалению, учреждение, которое считает, чтоконференции больше не существует, так что серверы на тех старых бумагах не работают навсегда, к счастью, я все еще получил копию) Итак, вот изображение, которое описывает проблематику:

CPU Scheduling

  • a) Полный газ не имеет синхронизации, только необработанная скорость
  • b) # 1 имеет большие пробелы, вызывающие проблемы синхронизации HW
  • c) # 2 нужно много спать с очень малой детализацией (может быть проблематично и замедлять) Но инструкции выполняются очень близко к их реальному времени ...
  • Красная линия - это скорость обработки ЦП хоста (очевидно, что выше этого уровня требуется немного больше времени, поэтому ее следует вырезать и вставить перед следующей инструкцией, но ее будет трудно нарисовать должным образом)Смоделированная скорость обработки процессора
  • чередование green/blue цветов представляет следующую инструкцию
  • обе оси - время
2 голосов
/ 19 августа 2011

Недавно в Arstechnica была довольно интересная статья, в которой говорилось о симуляции консоли, а также ссылки на довольно много симуляторов, которые могли бы послужить хорошим исследованием.идеальный эмулятор SNES

Важным моментом является то, что автор упоминает, и я склонен согласиться с тем, что большинство игр будут функционировать довольно корректно даже с временными отклонениями +/- 20%.Вероятно, проблема, о которой вы упомянули, никогда не приведет к ошибке времени, превышающей долю процента, что, вероятно, незаметно при игре в финальную игру.Авторы, вероятно, не сочли нужным иметь дело.

0 голосов
/ 19 августа 2011

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

...