Кодинг

Пишем эмулятор игровой консоли. Как устроена легендарная приставка Nintendo и как ее воссоздать самому


Ты наверняка сталкивался с эмуляторами игровых приставок и, возможно, даже просиживал за ними не один час. Но задавался ли ты вопросом, как это работает? На примере NES, известной в России как Dendy, я покажу, как создать собственный эмулятор. А заодно разберемся с хитрой архитектурой этой приставки, выдававшей потрясающе хорошую картинку для своего времени и своей скромной цены.

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

Nintendo Entertainment System. В России таких почти ни у кого не было, поэтому все помнят ее по клонам типа Dendy
 

Виды эмуляции

  • Интерпретация. Интерпретатор позволяет программно эмулировать все части консоли. Этот способ самый простой и вместе с тем наименее производительный.

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

 

MOS 6502: регистры, режимы адресации и инструкции

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

Как и в случае с компьютером, основная логика программ выполняется на центральном процессоре приставки. Поэтому лучше всего начинать написание эмулятора именно с него. В NES установлен восьмибитный процессор MOS 6502 с комплексным набором инструкций (то есть как у Intel, а не как у ARM или PowerPC).

У процессора MOS 6502 шесть регистров, один из которых недоступен пользователю:

  • A — регистр, куда складываются результаты всех арифметических операций;
  • X, Y — индексные регистры;
  • SP — указатель на вершину стека;
  • P — регистр флагов, в x86 EFLAGS выполняет ту же функцию;
  • PC — счетчик команд, регистр, который указывает, какую команду выполнять следующей. Этот регистр недоступен напрямую.

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

Название Определение Пример
Аккумуляторный Операндом инструкции является аккумулятор Арифметический сдвиг влево ASL
Предполагаемый Операнд явно указывается инструкцией Перенос значения A в X TAX
Немедленный Операнд дается в инструкции Загрузка значения в A LDA #$34
По абсолютному адресу Операндом является значение по абсолютному адресу Загрузка значения в X LDX $9010
По адресу в нулевой странице По абсолютному адресу первых 256 байт Загрузка значения в Y LDY $23
Относительный Адрес задается относительно PC Ветвление, если предыдущий операнд равен 0 BEQ $4A

Всего у нашего процессора 256 инструкций, из которых 78 — это настоящие инструкции без учета разных режимов адресации. Сразу сократим работу: мы не будем писать обработчик для всех 256 инструкций. Напишем обработчики для всех режимов адресации и для 78 инструкций.

Начнем с кода для режима адресации нулевой страницы.

void
addr_mode_zp()
{
  cpu_addr = ram_getb(reg.PC);
  reg.PC++;
}

В данном случае инструкция состоит из двух байт: один — это сама инструкция, второй — адрес операнда инструкции. Функция ram_getb возвращает значения байта в RAM по адресу.

А вот пример кода для инструкции STX.

void
op_stx()
{
  ram_setb(cpu_addr, reg.X);
}

Функция ram_setb заменяет значение байта в RAM по адресу cpu_addr (операнд инструкции) на значение регистра X.

Таблица инструкций

Также не стоит забывать, что MOS 6502 — мультицикличный процессор и разные инструкции могут выполняться разное время. Поэтому, чтобы выверить точное время выполнения, нужно знать, за сколько циклов выполняется инструкция.

Источник: xakep.ru

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *