image

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

Если вы не хотите его проходить, то:

  • возьмите готовый эмулятор;
  • повторите то, что в нём уже сделано.

Но если это не ваш путь, то милости просим в статью.

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

Хорошо, тогда я постараюсь вас отговорить от этого «гиблого» дела!

Меня зовут Сергей. Я пишу эмулятор Nes на Pascal, и уже написал статью, где рассматриваю разработку процессора. Также сделал перевод статьи, где люди делали многое до меня. На момент написания этой статьи уже выпущена версия PZ_Nes, и небольшой опыт в написании эмуляторов я уже набрал (может, это кому-то покажется не таким уж и малым опытом, а кому-то очень малым, но я сравниваю себя с собой).

С учётом всего того, что я написал выше, статья не будет касаться именно Nes.

Статья будет относиться к эмуляции какого-либо устройства.

▍ С чего начинать?


Всегда надо начинать с банального. И самое банальное — это выбор эмулируемого устройства. И выбор ваш должен падать на наиболее простые приставки или ПК (возможно, игровой автомат?). Лично я новичкам, наверное, не советовал бы даже Nes эмулировать. Это не так просто, как кажется, потому начните лучше с Chip-8 (здесь гляньте и здесь, а также поищите по Хабру и вообще по интернету, немало информации по нему). А также есть ещё более простые системы, где эмулируется несколько инструкций, несколько регистров и взаимодействие с пользователем (LC-3).

Дальше вы должны ознакомиться с устройством. Для этого необходимо:

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

Постарайтесь не смотреть симуляторы. Они вложат в вас лишнюю информацию поначалу (но если вы хорошо разбираетесь в теме, то, возможно, стоит взглянуть).

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

Напоминаю — я ориентируюсь на то, что вы решили реализовать эмулятор своими силами!!!

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

▍ Так когда же начинать делать эмулятор?


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

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

Не думайте, что чем раньше вы начнёте делать, тем раньше закончите. Дело в том, что если начинаешь что-то делать, то в большинстве своём это невозможно «закончить». Можно подвести к концу разработку. А улучшать эмулятор (вашу программу) можно до бесконечности.

Но начать всегда важно! Если не начнёте, то ничего и не сделаете.

▍ Не бегите впереди паровоза


Всегда начинайте с эмуляции процессора. Это будет одно из самых долгих занятий. Как вы читали выше, вам надо быть уже знакомым очень хорошо с процессором и понимать, как работают инструкции, сколько регистров, какие регистры, какие флаги существуют для данного процессора, как они работают в инструкциях (взаимодействуют с инструкциями). С какой памятью работает процессор, как он с ней работает. Работает ли с памятью (работает! Если вы возьмёте какие-то новые процессоры и будете утверждать, что процессор не работает с памятью, то вы не правы, у процессора есть кэш-память, с ней он работает напрямую, у всех процессоров есть регистры — а это тоже память!).

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

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

Не пытайтесь сделать всё сразу. Лучше всего запишите, что вы хотите сделать, и пошагово реализуйте процесс (да, в большинстве случаев я так не делал, за что зачастую плачу вновь, перечитывая документацию и прочую информацию).

Ну вот вы реализовали процессор, что же дальше? Вы, конечно же, возьмётесь за эмуляцию видеоадаптера устройства. Но не надо этого делать, если вы в самом деле решили создать эмулятор, то дальше надо потратить очень много времени опять не на эмулятор…

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

▍ Так что же делать дальше?


А для этого надо делать отладчик. Нет, ну вы, конечно, можете взять готовые тесты для процессора. Погонять его, посмотреть в обычном отладчике, что там происходит, но представьте, что у вас 65 тыс инструкций в процессоре. И все надо проверить… Я думаю, вручную вы точно не захотите это делать. А значит, запускаем процессор, заставляем его выдавать логи о его работе и на этом можно завершить данный раздел!

Но… нельзя. Да, логи это уже какая-никакая отладка. Но мы можем получить логи длиной в несколько книжек.

Если вас устраивает такой расклад, то вы можете уже делать эмулятор, я вас не задерживаю (хотите, можете пролистать дальше информацию, а не задерживаться здесь).

Ну а для тех, кто всё же решил остаться, то давайте разберём, что же нам именно нужно?

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

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

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

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

▍ Подготовительный этап пройден


Всё, теперь можете браться за видеоадаптер. Это же так интересно. Потратить на его изучение ещё кучу времени.

Если вы делаете эмулятор для устройства, которое уже было эмулировано, то можно посмотреть, как это делали люди, и сделать так же. Однако если вы так горите желанием, то вы вполне можете сами разработать свой способ эмуляции видеоадаптера (но всё же посмотрите, как это делали люди, лишним не будет). Лично я так и сделал и для Nes делаю свою эмуляцию PPU, но об этом не в этой статье.

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

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

▍ Тесты


Будем основываться, что вы эмулируете какую-то приставку (допустим, Nes).

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

И потому для тестов вам надо брать простейшие игры. Как пример для Nes это игры 0-го маппера: Bomberman, Lode Runner, Battle City и другие.

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

Как же можно проверить работоспособность видеоадаптера? Если рассматривать Nes, то там есть спрайты, фон и фон (смешно...). Да, там два фона, но один статичный — одноцветный (будем называть его задним фоном), а второй рисуется поверх него тайлами (будем называть его передним фоном). Так вот, задний фон заполняет весь экран Nes одним заданным цветом, а всё остальное рисуется уже поверх него. И вот этот фон как раз проще всего проверить. Вот берём и выводим задний фон:

// получаем цвет фона
backNesColor := Color_FindOrAdd_Single(Palette[videoRAM[$1f00] and $3F, 0], Palette[videoRAM[$1f00] and $3F, 1], Palette[videoRAM[$1f00] and $3F, 2], Palette[videoRAM[$1f00] and $3F, 3]);
// закрашиваем область экрана заданным цветом
pr2d_Rect(NesPPU.Screen, backNesColor, PR2D_FILL);

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

Не забывайте тестировать эмулятор, особенно если всё уже готово для вывода видеоинформации! Тесты, тесты и ещё раз тесты! Это очень важно!

▍ Информация, которой нет


Если вы эмулируете устройство, которое популярно и уже часто эмулировалось, то, скорее всего, информация почти вся есть. А если её нет, то вы либо её не нашли, либо пропустили.

О! Это частая проблема! Вы читаете документацию, вроде бы всё учли — и вдруг бац: что-то работает не так, как надо. Приходится сидеть, просматривать работу инструкций, устройств и регистров иногда часами. А вот не было бы у вас отладчика, то просматривать бы пришлось ещё дольше (ну можете многотомник логов почитать и сравнить с работой соседского эмулятора).

Но есть ли информация, о которой практически не узнать, или её нет?

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

А вот если вы делаете сами… то тут начинаются проблемы. Эти проблемы может никто не описывал, может описывали на каком-то форуме и забыли (ну и не забываем, что банально мы сами могли пропустить информацию). В этом случае Да, вы столкнётесь с такой информацией. От этого никуда не убежать.

При реализации PPU я обнаружил, что Y смещён на 1 вниз. Ну где-то на просторах интернета написано что:

Sprite data is delayed by one scanline; you must subtract 1 from the sprite's Y coordinate before writing it here.

Данные спрайта задерживаются на одну строку развёртки; перед записью их сюда необходимо вычесть 1 из координаты Y спрайта.

И тут информация, которая будет противоречить реализованному мной PPU. В этой реализации Y надо наоборот увеличить (да, реализация PPU была сделана полностью мной, потому так и пишу от своего имени; подобных реализаций на данный момент я нигде не видел).

Абсолютно всю информацию вы не сможете сразу узнать, что-то выяснится в процессе тестирования эмулятора.

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

Если вы разбираетесь в радио/схемотехнике, то вы должны понимать, что программирование и работа в железе — это разные вещи. И то, что происходит в железе, не всегда можно точно эмулировать.

Какая-то информация «свалится с неба» (вы что-то увидите в процессе работы, подправите, и всё станет работать стабильно, а вот в документации может быть всё с точностью до наоборот, но не надо на это надеяться, это один шанс из миллиона).

Какую-то информацию вам смогут подсказать люди (я очень много информации «пропустил мимо ушей» пока изучал и люди чуть ли не носом тыкали меня в мои же ошибки или они могут подсказать, что и как работает, чего вы не знали).

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

И вот ещё момент: все стараются гнаться за точностью эмуляции. Это правильно! Но не забываем, что мы делаем эмулятор! А эмулятор должен правильно выполнять запускаемые программы! Не важно как, важно, чтобы эти программы сами по себе точно работали на вашем эмуляторе. Вы же не симулятор писать собрались? Поэтому соблюдать точность нужно, но точность эмуляции может быть не критична (а может и критична!).

▍ Баги, и определённые реализации


Приготовьтесь к ним, к багам. Это ваши верные друзья на всё время написания эмулятора.

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

Создание эмулятора — это путь проб и ошибок. Если вы написали эмулятор без единой ошибки, значит его писали не вы, а вы просто прошлись по чьим-то стопам и повторили всё (Плохо это? Да нет, не плохо, главное, чтобы знания вы получили, остальное вторично).

Если у вас пытливый ум, то для реализации определённых частей эмуляции вы приложите голову и решите, как по-своему можно реализовать тот или иной функционал. И неважно, что где-то вы подсмотрели подобное, важно, что вы вспомнили об этой возможности и воспользовались. Допустим в Nes есть «зеркальная» память — это память, которая повторяется друг за другом множество раз. Для её реализации можно выделить участок памяти, которая зеркалируется, а по остальным адресам указать ссылку на эту память (лично я, например, реализовывал отдельно участки памяти и ставил для всех областей указатели на эту память).

▍ Окончание


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

  • вы потеряете много времени на изучение информации;
  • вы потеряете много времени на реализацию эмулятора (различных его частей);
  • на каждом шагу будете сталкиваться с новыми багами;
  • на каждом шагу будете исправлять свои же ошибки;
  • для отладки определённых моментов вас потребуются сутки-двое-трое-неделя;
  • вам нужно писать свой дебаггер.

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

  • вы почерпнёте много информации (возможно ненужной вам, тогда зачем брались?);
  • вы изучите устройство вдоль и поперёк, узнаете о его работе и работе его устройств, инструкций, регистров и прочего;
  • вы узнаете о многих скрытых багах;
  • вы узнаете, что вы тоже совершаете ошибки;
  • вы напишите отладчик;
  • вы получите удовлетворение, что у вас получается задуманное и другие могут попробовать результат вашего труда.

Надеюсь, я сумел отговорить вас от создания собственного эмулятора!?

▍ Постскриптум


Можно долго и упорно писать статью, о том, что вас ждёт, какие ошибки вы можете совершить, какую информацию изучать. Но по сути надо донести основу: Решили делать! И хотите делать! Делайте! Остальное не так важно.

С чем лично я сталкивался? Я портировал эмулятор на Android и запустил его. Результат меня подразочаровал…

Ютуб


Рутуб


Лично я надеялся, что мне удастся хотя бы в 40 кадров уложиться, но эмулятор и до 30 кадров не дотянул.

На текущий момент я исправил эту проблему и довёл до 60 кадров с мелкими просадками. В данное время этого вполне хватит, но надо будет ещё улучшать эту часть кода. И проблема была не только в самом эмуляторе, проблема была и в разрабатываемой мной библиотеке ZenGL (я продолжатель). Андрей сделал возможность сборки приложений под Android и реализовал вывод посредством эмуляции glBegin/glEnd и это было давно (2011 или 2012-й года), а я использовал эту функциональность для вывода. Избегая этой функциональности, я ускорил вывод кадра на 3-4 (притом, что до этого я вообще ни на кадр сдвинуться не мог). Но переделывать PPU пришлось полностью, чтобы избавиться от основной проблемы — частого переключения текстур (видимо, на мобильных системах это немалая проблема).

Также была проблема с выводом спрайтов/тайлов. Эта проблема, по сути, требует большого разбора. Если в двух словах, то надо читать документацию, узнавать, как всё работает. Не забывать, как выводятся большие спрайты и куча прочей мелочёвки, которую надо учитывать (но получилось всё равно прикольно).

Ютуб


Рутуб


Большинство недочётов я изначально хотел отложить подальше, так как считал, что не очень они важны, но часть из них говорит об обратном )))

А в следующей статье я глядишь распишу, как я создавал свой PPU для Nes. Ну и постараюсь там побольше технической информации предоставить.

Успехов вам в ваших начинаниях! И терпения, если вы всё же решились сделать свой эмулятор.

Контакты для связи со мной
Ютуб канал
Рутуб канал
Я на gamedev.ru
телега: @SeenkaoSerg

© 2025 ООО «МТ ФИНАНС»

Telegram-канал со скидками, розыгрышами призов и новостями IT ?

Комментарии (20)


  1. Zara6502
    16.06.2025 05:29

    у всех процессоров есть регистры — а это тоже память!

    для начала всё же нужно утвердить терминологию, а не скатываться в обобщения. Регистры - это не память, так как память - это ОЗУ. Если вам очень хочется сказать "ну регистры же запоминают своё состояние а значит "помнят", ну да, но зачем опускаться до формализации неважного? (надеюсь мы не рассматриваем частные случае ЦПУ у которых сами регистры хранятся в ОЗУ?)

    проблема эмуляции приставок, в отличии от проблемы эмуляции ЦПУ ровно в том, что у приставки кроме ЦПУ может быть еще какое-то число чипов, которые так же работают с тем же ОЗУ, скорее всего имеют прерывания, которые позволяют например отключать ЦПУ от шины или останавливать его работу и т.д. Поэтому эмуляция самого ЦПУ 8-битного из 80-х большой проблемы не представляет. Кому интересно как можно быстро написать эмулятор - можете глянуть видео Алексея Морозова по эмуляции ЭВМ Океан 240, там вообще всё сделано на JS.

    Я хотел как-то написать свой эмуль ATARI XE, для начала полез читать описание аппаратуры с сайта Altirra (неплохого эмулятора для ATARI) и там я понял, что я не хочу возиться с прерываниями, таймингами и еще с эмуляцией ANTIC (видео ЦПУ). На этом история моего супер-эмулятора и закончилась ))))


    1. Seenkao Автор
      16.06.2025 05:29

      Регистр - это ячейка памяти для временного хранения информации и работы с ней (статью по сути надо дополнять подобными ссылками, где ты был когда я писал статью?).

      Да, это не такая память как мы привыкли её видеть, но всё же память и это надо понимать. )))

      А по эмуляции, даже процессоры из 80-х не так просто эмулировать, даже приставку Nes. Кто возьмётся сразу за неё, не имея опыта, вероятнее всего и забросит. Вот и написал статью, чтоб либо удержать человека на его пути, либо показать что это не его путь.


      1. Zara6502
        16.06.2025 05:29

        я скорее о том что когда рисуют блок-схему ЦПУ никому не придет в голову внутри ЦПУ нарисовать квадратик с надписью RAM, а внутри квадратик с надписью Registers. Это свойство не влияет на работу как таковую, поэтому и нет смысл в таком контексте об этом говорить. Поэтому в контексте эмулятора разговор о регистрах как о ячейках памяти вообще не имеет смысла. Вот я о чем.

        NES имеет видео и звук и без эмуляции хотя бы видео вы даже на экране ничего нарисовать не сможете, а это квест куда более сложный чем класс MOS6502. У Атари можно хотя бы вместо ANTIC вкорячить заглушку с поддержкой только GRAPHICS 0, что позволит уже запустить БИОС и Бейсик.


        1. Seenkao Автор
          16.06.2025 05:29

          Поэтому в контексте эмулятора разговор о регистрах как о ячейках памяти вообще не имеет смысла.

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

          Нюансов много, я и писал в статье, что просто невозможно всю информацию затронуть. Если расписать как сделать простейший эмулятор, то можно книжку маленькую сделать, страниц на 200 и наверняка что-нибудь упустишь. )))


          1. Zara6502
            16.06.2025 05:29

            когда знаешь схемотехнику и программирование, проще понимать что и как надо сделать

            Какие ваши доказательства? (c) Red heat

            Это же просто условность.

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

            Какая разница как вы это реализуете? Вы это делаете на языке высокого уровню и можете использовать любую удобную обёртку.

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

            Это вы прочитаете в спецификации в ЦПУ, к "памяти" и "регистрам" это не относится.

            Нюансов много, я и писал в статье, что просто невозможно всю информацию затронуть. Если расписать как сделать простейший эмулятор, то можно книжку маленькую сделать, страниц на 200 и наверняка что-нибудь упустишь. )))

            Я ссылку не прикреплял, но предлагаю посмотреть как пишется "за 20 минут" эмулятор для советского Микро-80 на JS (в прошлом комментарии ошибся и написал Океан 240). Это как раз тот случай когда для эмуляции достаточно просто обработки команд ЦПУ.


            1. Seenkao Автор
              16.06.2025 05:29

              Это вы прочитаете в спецификации в ЦПУ, к "памяти" и "регистрам" это не относится.

              это как раз и есть внутренние теневые регистры. Читаем здесь и здесь.

              как пишется "за 20 минут" эмулятор

              только сбор информации занимает намного больше времени, чем двадцать минут, а само видео почти 40 минут, при том что многие участки ускорены и предоставлены пользователю в конечном варианте.


              1. Zara6502
                16.06.2025 05:29

                это как раз и есть внутренние теневые регистры. Читаем здесь и здесь.

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

                только сбор информации занимает намного больше времени, чем двадцать минут, а само видео почти 40 минут

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

                Суть видео в том, что если у устройства нет ничего кроме памяти и ЦПУ, то эмуляция превращается просто в создание класса, описывающего набор действий. Фактически это парсер набора байт. Эту мысль я вам озвучиваю не первый раз и не думаю что с этим есть смысл спорить, ведь я же показал вам доказательство моих слов.

                ---

                Резюмирую, а то вы опять что-то поймёте не так:

                1. Эмуляция голого ЦПУ это не сложно

                2. Эмуляция конечной машины с дополнительным набором логики может представлять сложности (видеоадаптеры, ускорители графики, звуковые чипы и т.д.)

                Объясню по п.1 - почему же это не сложно? Потому что это просто парсер потока байт. Увидели байт, по case перешли в какое-то другое состояние, опять взяли байт, опять изменили состояние и так до тех пор пока существует вселенная.


                1. Seenkao Автор
                  16.06.2025 05:29

                  факт того что в какой-то умной книжке регистры описаны как часть памяти абсолютно ничем нам не поможет в написании эмулятора. вот вообще никак.

                  ну вот я применил эту информацию в своём эмуляторе и добавил промежуточные регистры для того чтоб было легче вычислять конечные значения. Я знал эту информацию и применил на своё усмотрение.

                  есть такая штука у людей, называется "фигуральное выражение"

                  Извиняюсь, не обратил внимания на кавычки!

                  Объясню по п.1 - почему же это не сложно?

                  Хорошо, я поясню почему это сложно, особенно новичку и особенно с нуля. Если человек не писал эмулятор, то всё кажется достаточно простым, но когда начинаешь писать эмулятор, то первая сложность - это время. Тратится очень много времени как на изучение информации, так и на её реализации в коде. Вторая сложность - это отладка кода инструкций. На это тоже уходит время и даже при небольшом количестве инструкций, спокойно можно поймать неправильное выполнение определённой инструкции. А чужие тесты мы не всегда можем применить, для проверки работоспособности. Третья сложность - это время выполнения инструкций (и не только). Мы должны учитывать время, на которое ушло выполнение инструкции, для того чтоб процессор правильно работал. При неправильном вычислении времени, инструкция может выполнится в другом временно интервале.

                  По сути можно расписывать ещё много всего. Допустим на Nes я не мог использовать тесты когда сделал процессор и не мог узнать правильно ли я сделал его, ведь PPU ещё не был готов. А все тесты выводят информацию на PPU. Возможность отладки было только запуская ещё один эмулятор и отслеживая параллельно их действия. Это не сложно, но времени теряется очень много.

                  А время - это как раз и есть основная сложность. ))) Особенно новичку, особенно с нуля.


                  1. Zara6502
                    16.06.2025 05:29

                    ну вот я применил эту информацию в своём эмуляторе и добавил промежуточные регистры для того чтоб было легче вычислять конечные значения. Я знал эту информацию и применил на своё усмотрение.

                    ну так вы и пишите, было-стало и почему это необходимо, а то получается как в Ералаше "ты на улицу не ходи, а то тебя всякому научат".

                    почему это сложно

                    первая сложность - это время

                    время - это не сложность, это трудоёмкость.

                    Тратится очень много времени как на изучение информации, так и на её реализации в коде

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

                    Вторая сложность - это отладка кода инструкций

                    Как и отладка любого кода. Почему отладка эмулятора такая сложная, а отладка чего-то другого (порой гораздо более сложного) уже не сложная? Отладка - это рутина.

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

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

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

                    Написание тестов - вероятно будет сложным процессом, но это так же вопрос скилла самого программиста.

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

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

                    Допустим на Nes я не мог использовать тесты когда сделал процессор и не мог узнать правильно ли я сделал его, ведь PPU ещё не был готов

                    и это логично, так как это эмуляция конечного оборудования.

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

                    ну послушайте, в NES стоит 6502 с весьма простым набором инструкций, куда проще чем в Z80 и вы наверное всё же должны понимать разницу между эмуляцией ЦПУ и эмуляций NES??? Вы точно внимательно читаете что я вам пишу это не первый раз?

                    Это не сложно, но времени теряется очень много

                    Время - это не фактор сложности процесса. Здесь вы вроде это понимаете, а выше писали что это сложность.

                    А время - это как раз и есть основная сложность. ))) Особенно новичку, особенно с нуля.

                    господи, ну вот опять XD время и сложность не таким образом связаны. Например у вас есть гиря на 32 кг, можете ли вы её поднять? Ну взяли и подняли, ну тяжело, но подняли. А дальше можно прикрутить время - удержать поднятую гирю 10 часов.

                    когда вы программируете - вы пишете код, но кроме этого вы так же думаете над самой задачей и над тем как вы её реализуете. Это всегда так происходит. Так почему фактор времени именно в эмуляции ЦПУ становится таким особенным и вы только его и учитываете? вот когда я пишу статью я трачу на это например 3 месяца или пол года, получается статья была очень сложная к написанию? Нет. Сложно было настроиться на определенную тему и найти время на то, чтобы его посвятить работе над статьёй.

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


                    1. Seenkao Автор
                      16.06.2025 05:29

                      и это логично, так как это эмуляция конечного оборудования.

                      отвечу только на это. Потому что явное непонимание происходящего.

                      Я произвёл эмуляцию самого процессора, а не конечного оборудования! И, этот процессор должен точно выполнять инструкции заданное время. Потому что помимо этого, он производит ожидание в определённых ситуациях, так как производится передача данных.

                      В других процессорах этого может не быть, но могут быть другие проблемы.

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

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

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


                      1. Zara6502
                        16.06.2025 05:29

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

                        почему?

                        Потому что помимо этого, он производит ожидание в определённых ситуациях, так как производится передача данных.

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

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

                        я смотрю с позиции преподавателя, который научил массу ДЕТЕЙ программированию. И парсер бинарного потока, коим и является эмулятор 6502 - это просто один огромный switch/case (или большой набор if/else). В видео, ссылку на которое я вам дал Алексей показывает кусок i8080.js и там же показывает что из себя представляет эмулятор этого ЦПУ. В том же видео он замедляет эмулятор и переводит работу на тики, делать это нужно только в том случае если от этого будет зависеть еще что-то, например работа другого чипа.

                        и что там такого страшного в этом ЦПУ что это невозможно понять? скан байта приводит вас к тому какая именно команда выполняется, следующий набор байт может являться аргументами, они декодируются в адреса и читают или пишут данные в массив RAM[], всё, там нет больше ничего. Вот вам исходный код эмулятора i8080, можете сами всё изучить.

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

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

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

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

                        И! При изучении информации будет очень много подводных камней, которые не расписаны, расписаны, но не известно где, расписаны, но не правильно и прочее.

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

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

                        абалдеть, только после первой сделанной табуретки человеку становится проще сделать следующую табуретку!!! никогда такого не было.

                        И вот тогда сложность падает очень сильно. Человек понимает что делает, знает что искать, знает многие подводные камни.

                        Перефразируя ваши откровения - только когда человек что-то изучит ему станет легче работать в этой области.

                        PS: вы в ВУЗе обучались? Просто ваши откровения тянут на открытия которые делают школьники в 7-8 классе. Вы несомненно можете кинуть страйк на меня в ТП Хабра, но это моё оценочное суждение, не хотел вас задеть.


                      1. Seenkao Автор
                        16.06.2025 05:29

                        почему?

                        Потому что дальнейшее развитие процессора строится именно на взаимодействии с внешними/внутренними устройствами и обработкой прерываний.

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

                        я смотрю с позиции преподавателя, который научил массу ДЕТЕЙ программированию.

                        С этого надо было начинать.

                        И парсер бинарного потока, коим и является эмулятор 6502 - это просто один огромный switch/case (или большой набор if/else).

                        В момент прерывания весь ваш парсер "ломается" и ему приходится выполнять дополнительные действия для перестройки программы на другой процесс. Это сохранение состояние процессора на момент прерывания и восстановление данных после прерывания.

                        Заметьте, прерывания - это не инструкции! Но по приходу прерывания, так же выполняются инструкции.

                        Обработка приходящих сигналов и отправка сигналов по необходимости. Приходящие сигналы обрабатываются самим процессором выставляя согласно пришедших сигналов определённые данные, обычно в самом процессоре (обычно это определённые флаги).

                        Теперь про свитч или условия.

                        Так лучше не делать! Это можно делать в процессорах, в которых малое количество инструкций, но когда инструкций в процессоре очень много, свитч (или условия) только ухудшит читаемость кода.

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

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

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

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

                        Другой человек вполне может с этими проблемами не столкнуться вовсе.

                        Да, с трудностями можно не столкнуться.

                        Первый вариант я уже писал, это просто взять готовый эмулятор и повторить то, что в нём сделано.
                        Второй вариант - ни чего не делать.

                        При варианте когда делаешь с нуля и сам - с трудностями всегда столкнёшься.

                        Перефразируя ваши откровения - только когда человек что-то изучит ему станет легче работать в этой области.

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

                        Потому что этого результата он добился сам! И, если в этом ему помогло образование и информация которую он изучил, то это только плюс этому человеку. Он применил свои теоретические знания для реализации конечного продукта.

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

                        И сейчас, извиняюсь, я общаюсь с теоретиком, а не с практиком!

                        Реализуйте эмулятор, который вы хотели реализовать, и посмотрите правы вы были или нет.

                        вы в ВУЗе обучались?

                        обучался. Но я бросил учёбу.

                        Просто ваши откровения тянут на открытия которые делают школьники в 7-8 классе.

                        Это базовые знания, которыми вы не пользуетесь. А я продолжаю ими пользоваться. База - она всегда останется базой!

                        Вы несомненно можете кинуть страйк на меня в ТП Хабра

                        бегу и падаю, поднимаюсь и снова бегу...

                        мне больше заняться нечем? )))

                        это моё оценочное суждение

                        я так же могу ошибаться в вас! Мы друг друга практически не знаем. И вполне возможно просто недопоняли друг друга.


                      1. Zara6502
                        16.06.2025 05:29

                        Потому что дальнейшее развитие процессора строится именно на взаимодействии с внешними/внутренними устройствами и обработкой прерываний.

                        То есть вы категорически не хотите читать что я вам пишу? Ну ок.

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

                        Как только мы об этом поднимем тему - я приму это к сведению.

                        С этого надо было начинать

                        Зачем?

                        В момент прерывания весь ваш парсер "ломается" и ему приходится выполнять дополнительные действия для перестройки программы на другой процесс

                        Какого прерывания?

                        Заметьте, прерывания - это не инструкции! Но по приходу прерывания, так же выполняются инструкции.

                        В этом месте только разведу руками.

                        Так лучше не делать! Это можно делать в процессорах, в которых малое количество инструкций, но когда инструкций в процессоре очень много, свитч (или условия) только ухудшит читаемость кода.

                        У меня другое мнение.

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

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

                        В данной дискуссии вы тратите и моё и своё время

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

                        В которой ни вы не переубедите меня, потому что вы не понимаете о чём я пишу

                        Ну читать я умею, вы пишете что сложность написания эмулятора ЦПУ состоит в количестве затрачиваемого на это времени. Это уже глупость. И второе, когда я вам даже привёл доказательство реализации не только ЦПУ, но и полноценного эмулятора ЭВМ, вы не посчитали, что это является доказательством и даже под видео Алексей написали очень странный комментарий. Так что вернее будет сказать, что вы не понимаете предмет обсуждаемый. (вы кстати до сих пор не поняли что я вам говорю, и не первый раз, про эмуляцию ЦПУ, без поддержки эмуляции взаимодействия ЦПУ с другими устройствами, хотя я на это указывал явно уже несколько раз)

                        Ни я не переубежу вас, потому что вы решили что новичок уже всё знает и умеет

                        Не люблю когда люди врут и приписывают мне то, чего я не говорил. Будьте добры приведите цитату, которая об этом говорит.

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

                        Что я там и где забыл? Вы зачем про меня выдумываете какую-то ерунду? Где я написал про какой-то простой путь? Я однозначно и ясно написал контраргументом к вашему тезису что эмуляция ЦПУ это сложно - что это не так и что эмуляция ЦПУ это как раз весьма простая задача, а вот эмуляция готовой системы с несколькими чипами - это уже задачка. Я это написал сразу в самом начале. И это легко видно по видео Алексея, что является прямым доказательством моего тезиса. То что лично вы этого не понимаете - ну я-то тут не виноват.

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

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

                        Первый вариант я уже писал, это просто взять готовый эмулятор и повторить то, что в нём сделано.

                        То есть чтобы собрать машину Мерседес в гараже достаточно пригнать к гаражу другой Мерседес - раз-два и у вас два Мерседеса? Вы считаете что реверс-инжениринг чужой программы это хороший путь для новичка?

                        При варианте когда делаешь с нуля и сам - с трудностями всегда столкнёшься.

                        Ну, допустим для вас написание цепочки из case это трудность, но для кого-то это не трудность.

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

                        Мне это напоминает смешные изречения Джейсона Стэтема, что-то в духе "если хочешь прыгнуть - прыгай", "если хочешь в отпуск - отпускай" и т.д.

                        Потому что этого результата он добился сам! И, если в этом ему помогло образование и информация которую он изучил, то это только плюс этому человеку. Он применил свои теоретические знания для реализации конечного продукта.

                        Ну ок. Вы сейчас всему миру рассказали как он работает.

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

                        Это что-то новенькое. Всегда было так - есть теория, вы под неё делаете реализацию (если мы говорим про программирование). Реализаций может быть очень много, но они все дружат с теорией. А вы утверждаете что вы пишете реализацию, она там что-то делает, но теория к самой реализации никак не прикручивается - это как?

                        И сейчас, извиняюсь, я общаюсь с теоретиком, а не с практиком!

                        Реализуйте эмулятор, который вы хотели реализовать, и посмотрите правы вы были или нет.

                        А мне-то зачем это делать? Я уже дал вам ссылку на эмулятор i8080 который полностью соответствует моим словам, я уже вам всё показал и доказал. То что вы или не понимаете что вам показывают или не хотите в этой ситуации оказаться неправы - это совсем другой разговор.

                        обучался. Но я бросил учёбу

                        Я почему спросил, этой не попытка вас задеть, просто то что вы там написали - всё это студенты проходят в ВУЗе и в последствии это вопросов не вызывает. То есть это база. А вы базу нащупали сами и воспринимаете как открытие.

                        Это базовые знания, которыми вы не пользуетесь. А я продолжаю ими пользоваться. База - она всегда останется базой!

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

                        я так же могу ошибаться в вас! Мы друг друга практически не знаем. И вполне возможно просто недопоняли друг друга.

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

                        Я не думаю что есть смысл продолжать.


                      1. Seenkao Автор
                        16.06.2025 05:29

                        facepalm

                        всё это студенты проходят в ВУЗе и в последствии это вопросов не вызывает.

                        это пишет мне человек, который принимает мои работы у своих студентов (образно выражаясь), или ты в самом деле решил, что все студенты делают всё сами? )))


                      1. Zara6502
                        16.06.2025 05:29

                        facepalm

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

                        это пишет мне человек, который принимает мои работы у своих студентов (образно выражаясь), или ты в самом деле решил, что все студенты делают всё сами? )))

                        не совсем ясно какое это имеет отношение к разговору и да, если студент не сам написал код то это ясно сразу.

                        Да, и вот вам пример как "просто" делается процессор.

                        видео ни о чем, так как там не "процессор", а эмулятор спектрума. Повторяю еще раз - вернитесь наверх и с самого начала перечитайте о чем идет разговор.


                      1. Seenkao Автор
                        16.06.2025 05:29

                        Да, и вот вам пример как "просто" делается процессор.


    1. artmel
      16.06.2025 05:29

      У Алексея Морозова действительно получилось просто замечательное видео. Он сумел в небольшой объем по времени, вложить пошагово большой объем информации для тех кто только начинает.


    1. vvbob
      16.06.2025 05:29

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


      1. Zara6502
        16.06.2025 05:29

        в этом и смысл - эмулировать ЦПУ трудоёмкая, но не такая сложная задача.


  1. oOLokiOo
    16.06.2025 05:29

    >>С чего начинать?

    >>Всегда надо начинать с банального. И самое банальное — это 

    НЕ ПИСАТЬ ЭМУЛЯТОР ЧЕГО УГОДНО НА PASCAL!!!

    всё, спасибо за статью, дальше даже не читал...