Зачем эмулировать определенное количество циклов?

Я видел более чем в одном месте - следующий способ подражания

т.е. циклы передаются в функцию эмуляции

int CPU_execute(int cycles) {
    int cycle_count;

    cycle_count = cycles;
    do {

         /* OPCODE execution here */

    } while(cycle_count > 0);

    return cycles - cycle_count;
}     

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

Сердечно приветствуем любую помощь !!!


person kofhearts    schedule 04.12.2012    source источник


Ответы (3)


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

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

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

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

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

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

person Tommy    schedule 05.12.2012
comment
Обычно это не точный способ воспроизвести поведение реального компьютера ... Он все еще может быть точным, поскольку микросхему часто не требуется синхронизировать на определенное количество циклов. Например, графический чип gameboy рисует только одну строку развертки каждые 456 циклов, и, следовательно, циклы ЦП могут выполняться между каждым обновлением графики, сохраняя при этом точность. - person nijoakim; 13.02.2013
comment
@Profetylen неверно сказать, что чип сидит и ничего не делает в течение 456 циклов, а затем мгновенно извлекает все данные, необходимые для вывода строки, и мгновенно выводит их. Поэтому неточно моделировать это так - это не соответствует тому, как работает реальное оборудование. Я думаю, вы утверждаете, что пользователь обычно не осознает неточности, и я думаю, что это полезно указать на исходный плакат. Авторы эмуляторов часто создают преднамеренно неточную эмуляцию, оптимизируя три аспекта: усилия, вычислительную мощность и воспринимаемую точность. - person Tommy; 13.02.2013
comment
Я бы назвал эмулятор, который отображается на экране и излучает из динамиков то же самое, что и оборудование, с той же точностью. Хотя я понимаю, что вы имеете в виду, и утверждаю, что ваше определение точности больше подходит для симулятора, чем для эмулятора (см. Этот вопрос: Симулятор или эмулятор? В чем разница?). В крайнем случае, вы бы назвали любой эмулятор, который не учитывает электрические токи, протекающие по проводам оборудования, неточным? - person nijoakim; 14.02.2013
comment
@Profetylen показывает не то же самое, а то, что трудно различить для подмножества приложений, которые работают «как ожидалось». В 95% случаев, когда авторы эмуляторов делают некоторые упрощающие предположения, они затем находят крайний случай, который не работает, добавляют несколько тысяч строк, чтобы обойти это, находят что-то еще, что не работает, и т. Д. Пример: Elite работает на Nesticle только в том случае, если вы вручную настраиваете счетчик горизонтальных циклов, потому что он умело переписывает карту листов по мере отображения. Где на реальном оборудовании находится циферблат для регулировки количества горизонтальных циклов? - person Tommy; 14.02.2013
comment
@Profetylen Я бы сказал, что эмуляторы точны с заявленной точностью. Если вы сделаете субъективное оценочное суждение, что быть «точным до линии сканирования» достаточно хорошо, тогда отлично. Со своей стороны, я работал на этом уровне, на уровне точности цикла (см., Например, github.com/TomHarte/ ElectrEm) на уровне точности перехода шины (github.com/TomHarte/Clock-Signal) и обратно на уровне точности кода операции (github.com / TomHarte / CP-M-for-OS-X). Из них CP / M, вероятно, технически наиболее точен, потому что это именно тот уровень, на котором указан CP / M. - person Tommy; 14.02.2013
comment
Я все еще не уверен, что что-то, что нужно синхронизировать, происходит между этими 456 циклами. Я много лет работал над эмулятором gameboy (на данный момент полуфункциональным) и не видел причин, по которым его нельзя разделить при сохранении точности. Возможно, я просто пропустил это, но я все же считаю вероятным, что для такой простой системы, как gameboy, возможно, что эта оптимизация не повлияет на точность. - person nijoakim; 14.02.2013
comment
позвольте нам продолжить это обсуждение в чате - person Tommy; 14.02.2013

Поскольку вы упомянули z80, я знаю просто идеальный пример платформы, где иногда требуется такая точная эмуляция: ZX Spectrum. Стандартная область вывода графики на ZX Spectrum представляла собой прямоугольник размером 256 x 192 пикселей, расположенный в центре экрана, окруженный довольно широкой областью «границы», заполненной сплошным цветом. Цвет границы контролировался путем вывода значения в специальный выходной порт. Идея компьютерного дизайнера заключалась в том, чтобы просто выбрать цвет рамки, наиболее соответствующий тому, что происходит на главном экране.

ZX Spectrum не имел точного таймера. Но программисты быстро сообразили, что «жесткие» (по современным меркам) тайминги z80 позволяют рисовать синхронно с движением луча монитора. В ZX Spectrum можно было дождаться прерывания, возникающего в начале каждого кадра, а затем буквально подсчитать точное количество циклов, необходимых для достижения различных эффектов. Например, одна полная строка сканирования на ZX Spectrum сканировалась за 224 цикла. Таким образом, можно было менять цвет границы каждые 224 цикла и генерировать линии толщиной в пиксель на границе.

Графические возможности ZX Spectrum были ограничены в том смысле, что экран был разделен на блоки 8x8 пикселей, которые могли использовать только два цвета в любой момент времени. Программисты преодолели это ограничение, меняя эти два цвета каждые 224 цикла, что эффективно увеличило цветовое разрешение в 8 раз.

Я вижу, что обсуждение под другим ответом сосредоточено на том, может ли одна строка сканирования быть достаточно точным разрешением для эмулятора. Что ж, некоторые эффекты скроллера границы, которые я видел на ZX Spectrum, в основном синхронизированы с одним циклом z80. Эмулятор, который хочет воспроизвести правильный вывод таких кодов, также должен быть точным до одного машинного цикла.

person Aleksey Pichugin    schedule 12.03.2013

Если вы хотите синхронизировать свой процессор с другим оборудованием, это может быть полезно сделать так. Например, если вы хотите синхронизировать его с таймером, вы хотели бы контролировать, сколько циклов может пройти, прежде чем таймер прервет CPU.

person nijoakim    schedule 04.12.2012