Мэппер NES

Мэппер — неофициальное название устройств в картриджах Famicom/NES/Dendy для расширения рабочей памяти приставки, управления видеопамятью и (только в конструктиве Famicom) синтеза дополнительного звука. Официальное название от Nintendo — memory management controller.

Сцена эмуляции знает сотни разных мэпперов, у одной Nintendo их было не менее 7 штук. Эмуляция мэпперов — важная часть эмуляции Dendy.

История

На старте Famicom были три автоматных игры — Donkey Kong, Donkey Kong Jr. и Popeye[1][2] жанра «одноэкранная аркада»; разработчик признался[3], что приставка должна была достоверно передавать Donkey Kong. Неизвестно, для чего Nintendo вывела в разъём картриджа сигналы записи в память, но именно они позволили[4] расширять память приставки в 10 и более раз и делать игры значительно более сложные. Это продлило активную жизнь приставки до 11 лет: появилась 1983, достаточно массовый выпуск игр 1994 — для бурно развивавшейся отрасли видеоигр это немало.

Считается, что игра Super Mario Bros. (1985) выжала последние возможности из 40-килобайтного[5] картриджа (32K рабочего ПЗУ + 8K плиточной памяти). Nintendo поставила[6] на Famicom Disk System (февраль 1986), позволяющей загружать код, данные и графику по желанию программиста — но ещё до появления таковой издатели попытались расширить память: Track & Field (Konami) в расширенной версии для Famicom (по разным данным октябрь или ноябрь 1985) использовала мэппер[7]. Ставка на дискеты сработала частично: все недостатки дискет (неудобство, низкая ёмкость, плохая пиратозащита даже с выштамповками) и попытка пробиться на рынок США вынудили работать и с картриджами.

Чтобы кризис 1983 года не повторился, Nintendo поставила американским издателям драконовские условия: не более 5 игр на издателя в год (поэтому появилась мода дробить юридические лица) и использовать картриджи только производства Nintendo, с чипом 10NES. Потому некоторые игры были вынуждены в американских изданиях сменить мэппер и ухудшить графику; наиболее известная из них — Contra.

Ещё во время активной жизни платформы Nintendo щеголяла продающими словами вроде memory management controller[8]. Глубоко техническое слово «мэппер» (отображатель) приписывают сцене эмуляции.

Крупные игры начала 1990-х вроде Battletoads[9] занимали 256 килобайт памяти. Рекорд из официально выпущенных — Metal Slader Glory, японская игра в жанре квеста (1 мегабайт), использовавшая мэппер MMC5[10]. Рекорд из международных — Kirby’s Adventure (768K), выпущенная на излёте NES.

Мэпперы и пиратство

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

Известны случаи, когда пираты адаптировали игры с других мэпперов под MMC3, чтобы не копировать весь «зоопарк» микросхем[11].

Игры с нестандартным мэппером или редкой его конфигурацией практически не пиратили. Выросшим на фамиклонах неизвестны такие хиты, как The Legend of Zelda и Metroid. Игру Contra они видели в обрезанной международной версии, а не в полной японской.

Возможности Dendy

Адресное пространство процессора

Адресное пространство процессора Dendy
Адреса Длина Назначение
0000…07FF 2K ОЗУ приставки
0800…1FFF 3 шт × 2K Зеркала ОЗУ приставки
2000…2007 8 байт Регистры PPU (видеоадаптера)
2008…3FFF 1023 шт × 8 байт Зеркала регистров PPU
4000…4017 24 байта Регистры аудио и ввода-вывода
4018…401F 8 байт Тестовые регистры, в готовой приставке отключены
4020…FFFF 48K без 32 байт Используется на нужды картриджа, обычно так…
• 6000…7FFF 8K ОЗУ картриджа (если есть; иногда энергонезависимое с батарейкой)
• 8000…FFFF 32K ПЗУ картриджа (PRG ROM), из него…
•• FFFA…FFFF 6 байт Три вектора прерываний

Сигнала A15 в картридже нет, есть ¬ROMSEL = ¬(A15 & M2) — он в нуле, когда адрес в диапазоне 8000…FFFF и адресные шины стабильны, и он служит командой к чтению из ПЗУ. Потому картриджи неохотно расширяют память в адреса ниже 8000.

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

В память PPU (видеоадаптера) входят:

  • Две таблицы плиток 8×8 (CHR ROM), каждая по 4 килобайта = 256 штук · 8 · 8 · 2 бита. Любую из них можно пустить как на фоны, так и на спрайты. Два бита — это номер цвета в палитре, при этом 00 — для фона это базовый цвет (общий для всех палитр), для спрайта прозрачный.
    • Традиционно эти таблицы в ПЗУ картриджа, но ничего не мешает сделать их ОЗУ и перезаписать командой видеоадаптеру.
    • Они занимают ровно половину адресного пространства PPU, так что линия PPU A13 определяет, к чему доступ: к плиткам или видеопамяти.
  • Четыре видеостраницы по 1 килобайту, квадратом 2×2. Каждая представляет собой плиточный буфер в 32×30 плиток (nametable, 960 байт = 32 · 30 · 1 байт) и палитровый буфер, по палитре на блок 2×2 плитки (attribute table, 64 байта = 16 · 16 · 2 бита). Палитры собраны в большие блоки 4×4 плитки, по байту на каждый, отсюда 16·16: в последней строке не используются четыре бита в каждом байте. Видеоадаптер может свободно прокручивать между этими страницами.
  • Восемь палитр по 3 цвета: четыре на фоны и четыре на спрайты. Для программиста это видеопамять, но картридж за них не отвечает.

Хотя видеостраниц четыре, встроенное видео-ОЗУ приставки всего 2K. На доступ к памяти картридж может сказать одно из двух: «вот данные» или «обратись к нулевой/первой странице ОЗУ, нижние 10 бит адреса те же». Практически всегда картридж работает с плитками сам, а страницы перенаправляет одним из трёх методов:

  • Две верхние — рабочие, две нижние их повторяют (вертикальное зеркалирование, для игр с горизонтальной прокруткой[12]).
  • Две левые — рабочие, две правые их повторяют (горизонтальное зеркалирование, для игр с вертикальной прокруткой[13]).
    • В этом режиме возможна прокрутка во всех направлениях на одной встроенной видеопамяти, без внешнего ОЗУ и продвинутых мэпперов (Mega Man 3), для этого видеоадаптер способен скрывать левые «мусорные» 8 пикселей[14].
  • Все четыре проецируются на внутреннюю память картриджа (в мэпперах MMC3 и 5, для игр с прокруткой во всех направлениях — Felix the Cat[15]).

Процессор доступа к видеопамяти не имеет. Видеоадаптер занят всё время, пока генерируется кадр, и единственный способ изменить видеопамять — дождаться момента смены кадра (VBLANK) и дать ему команду через регистры[16].

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

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

Звук

Результат микширования APU (аудиочипа) в японской Famicom идёт на контакт 45 картриджа, тот с этим звуком может делать что угодно и возвращает результат через контакт 46 (обычно они просто соединены). В американской NES возможность вмешательства в звук убрана[11].

Функциональность мэппера

  • Выполняет всегда:
    • Обеспечивает доступ к памяти картриджа через адреса памяти.
    • Разбивает адресное пространство PPU (видеоадаптера) на память картриджа и встроенное видео-ОЗУ приставки.
    • При отсутствии своего видео-ОЗУ — отображает четыре страницы виртуальной видеопамяти на 2K физической тем или иным методом.
  • Выполняет часто:
    • Расширенное ПЗУ с переключением банков.
    • Реагирует на кнопку сброса и подставляет стартовое меню или другую игру (на многоигровках).
    • Генерирует прерывания по определённым строкам развёртки, чтобы точно и быстро перенастроить видеоадаптер. Например, чтобы нарисовать параллаксную прокрутку (Ninja Gaiden) или непрокручивающуюся панель.
  • Выполняет редко:
    • Даёт дополнительную оперативную память — рабочую, на плитки, или на оставшиеся две страницы видеопамяти. Иногда эта память поддерживается батарейкой и предназначена для сохранений.
  • Выполняет крайне редко:
    • Более сложное устройство видеопамяти — больше плиток, установка атрибутов на меньшие блоки, чем 2×2 плитки: 1 плитка (MMC5)[8], 8×1 пиксель (любительский мэппер для игры Former Dawn, 2020-е[17]).
    • Дополнительное оборудование вроде сопроцессора для умножения.
  • Выполняет крайне редко, только в японской Famicom:
    • Дополнительная звукогенерация.
  • Мэпперы не способны:
    • Дать больше одновременных спрайтов — этим занимается видеоадаптер в обход картриджа.
    • Расширить палитру сверх 25 одновременных цветов — аналогично.

Банк памяти переключается мгновенно, ещё до перехода к следующей команде. Dendy не знает о мэппере, о нём знает только код игры[11]. Нужно быть осторожным, меняя банк, который исполняется — или собрать самомодифицирующийся код в ОЗУ, или аккуратно расположить функции в памяти, чтобы точно перейти из банка в банк.

Основные мэпперы Nintendo

NROM (тривиальный, № 0)

(Все номера — по договорённости сцены эмуляции. Никакой системы в нумерации нет, новые номера даются по мере нахождения новых плат и микросхем.)

Физический вид: разводка картриджа[11][18]

Первая игра: существовал изначально

Примеры игр: Circus Charlie, Donkey Kong, Excitebike, Ice Climber, Super Mario Bros.

Назван по одной из схем картриджа Nintendo. Другие названия: HROM, RROM, RTROM, SROM… На линиях данных просто находятся микросхемы на 16 или 32 килобайта рабочего ПЗУ, 8 килобайт плиточного ПЗУ. Вся память несменная. В случае, если ПЗУ всего 16 килобайт, оно повторяется по адресам 8000 и C000.

Сложное устройство видеопамяти сделано исключительно разводкой дорожек картриджа. Один пример: метод отображения видеопамяти (горизонтальный или вертикальный) задаётся перемычкой — номер страницы берётся из 10-го или 11-го бита адреса[18].

Family BASIC (интерпретатор Бейсика) имеет 8 килобайт ОЗУ с батарейкой.

CNROM (№ 3)

Физический вид: логическая микросхема — счётчик 74HCT161, корпус DIP-16[11][19]

Первая игра: разные источники указывают на City Connection (1985) или Track & Field (в расширенной версии конца 1985)[11]

Примеры игр: Adventure Island, Paperboy

Подставляет только плиточную память, имеет 4 банка по 8 килобайт. Переключение банков — запись в любой адрес ПЗУ, кода игры в постоянной памяти это не изменит. Рабочее ПЗУ несменное, 16 или 32 килобайта.

Аналогично NROM, имеет настраиваемый перемычкой метод проецирования страниц видеопамяти.

Такая подстановка плиточной памяти — подменяются все 8 килобайт сразу — неэффективна[11]. Плиточная память содержит самую разную информацию: шрифт и фоны, героя и врагов — так что несменная информация вроде шрифта и героя должны дублироваться в каждом банке. По богатству геймплейных ситуаций CNROM-игры мало отличаются от NROM, но возросло визуальное разнообразие[11]. Организация CNROM’ных игр хорошо видна на той же City Connection: четыре фона, каждый со своими полицейскими машинами и портретом возлюбленного, но геймплей тот же.

Конфликты шины

Простым мэпперам на логических микросхемах, в том числе данному, свойственны конфликты шины — микросхема ПЗУ всегда производит чтение независимо от наличия сигнала записи. Так что случается знаменитая недопустимая в цифровой логике ситуация — за один провод конкурируют процессор и память картриджа, и «пересиливает» тот, у кого меньше сопротивление. Разработчик держит в памяти массив всех возможных чисел, и если нужно передать мэпперу, например, 3 — находит ячейку с числом 3 и пишет в неё тоже 3[11][20]. Конфликты редко эмулируют, предполагая, что процессор всегда выигрывает — для корректно написанных игр не нужно[11]. (В действительности на большинстве видов логики 0 пересиливает единицу.)

UNROM и UOROM (№ 2)

Физический вид: две логических микросхемы, счётчик 74HC161 + ИЛИ 74HC32, корпуса DIP-16 и DIP-14[11][21]

Первая игра: Ghosts ’n Goblins (1986)[11]

Примеры игр: Contra (США/Европа), Duck Tales 2, Prince of Persia

32 килобайта рабочего ПЗУ делятся на два куска по 16 килобайт: первый сменный, второй фиксированный. В UNROM может быть до 128 килобайт памяти, в UOROM до 256, а в самоделках — и все 4 мегабайта.

Переключение банка представляет собой простую запись в любой адрес ПЗУ. Нижние 3 бита (для UNROM), 4 бита (для UOROM) и целый байт (для самоделок-расширений) — номер банка.

UNROM стоит особняком от остальных мэпперов: вместо плиточного ПЗУ стоит 8-килобайтный чип ОЗУ[11]. Изначально это ОЗУ заполнено мусором, запись по тому же принципу, как и в остальную видеопамять: через команды видеоадаптеру в моменты смены кадров[16]. Такая методика не позволяет много плиточной анимации, зато плитки можно хранить в оптимальном формате без дублей, а то и сжато.

Обучающий картридж «Сюбора» и некоторые самодельные картриджи добавляют 8 килобайт ОЗУ без батарейки.

MMC1 (№ 1 и 155)

Физический вид: специализированная микросхема, корпус уменьшенный DIP-24

Первая игра: Morita Shougi (1987)[11]

Примеры игр: Chip 'n Dale Rescue Rangers 1 и 2, Castlevania II: Simon's Quest, Dr. Mario, Final Fantasy

Имеет до 512 килобайт рабочего ПЗУ, переключая их на манер UNROM (16 сменные + 16 фиксированные). Плюс до 128 килобайт плиточного ПЗУ — заменяются сразу все 4 килобайта фона или спрайтов. Конфликты шины ушли.

Для уменьшения количества выводов сделано сложное переключение через сдвиговый регистр. Переключение банка представляет собой несколько записей в любой из адресов ПЗУ, и на пятую запись произойдёт переключение банка. Четыре диапазона адресов представляют собой четыре регистра: управляющий, плиточные таблицы 0/1 и рабочее ПЗУ.

Слабость MMC1 — перерасход ПЗУ из-за полной подмены плиточных таблиц. Однако даже такая система позволила большие разнообразные уровни.

Отдельные картриджи имеют 8 килобайт рабочего ОЗУ — обычного или запитанного батарейкой для сохранений.

MMC2 (№ 9)

Физический вид: специализированная микросхема, корпус уменьшенный DIP-42[22]

Единственная игра: Punch-Out!! (1987)[8]

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

Интересной функцией MMC2 было среагировать на определённую плитку и переключить банк без участия процессора. Это важная функция Punch-Out!!, ведь в ней большие враги[23].

Рабочее ПЗУ состоит из фиксированных 24K и сменных 8K, всего 128K.

MMC3 (№ 4)

Физический вид: специализированная микросхема, корпус TQFP-44

Первая игра: 8 Eyes (1988)[11]

Примеры игр: Adventure Island II, Captain America and the Avengers, Felix the Cat, Kirby’s Adventure, Power Blade, Super Mario Bros. 2 и 3

Продвинутый мэппер, дающий:

  • на рабочее ПЗУ — 2 банка по 8K сменные, 16K фиксированные, всего до 512K;
  • в таблице плиток 0 (программист сам определяет, фоны это будут, спрайты или оба вместе) — 4 банка по 1K сменные, всего до 256K;
  • в таблице плиток 1 — 2 банка по 2K сменные, проецируются в ту же память;
  • метод проецирования страниц: горизонтальный или вертикальный; возможна также собственная видеопамять на все четыре страницы для прокрутки во всех направлениях со статус-строкой (Felix the Cat[15]);
  • генерирует прерывание при проходе через определённую строку развёртки — чтобы делать статус-строку, параллаксную прокрутку;
  • иногда 8K дополнительного ОЗУ.

Мелкие сменные банки позволили анимированный фон в Batman (1989/90)[11], Super Mario Bros. 2 (1988)[24].

Есть также похожий MMC6, обладающий 1 килобайтом встроенного ОЗУ. Использовался мало.

MMC5 (№ 5)

Физический вид: специализированная микросхема, корпус PQFP-100

Первая игра: Nobunaga’s Ambition II (1990)

Примеры игр: Castlevania III: Dracula’s Curse (США/Европа), Metal Slader Glory

Самый сложный мэппер, дающий:

  • 1M ПЗУ, 128K ОЗУ.
  • Два квадратных звуковых канала и один 8-битный волновой (только в японском Famicom).
  • Два раздельно прокручивающихся окна, в том числе с разделением по вертикали;
  • Расширенную видеопамять, адресующую 16K плиток и присваивающую атрибут каждой отдельной плитке (а не блоку 2×2)[8].
  • Быструю заливку экрана одним цветом для переходов.
  • Умножение byte·byte → word.

Использовался мало из-за дороговизны.

По сути мэппер, она имела 32K рабочего ОЗУ по необычным адресам 6000…DFFF, 8K ПЗУ-загрузчика E000…FFFF и 8K плиточного ОЗУ. Четырёх видеостраниц не было, использовались встроенные в приставку 2K видео-ОЗУ.

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

Номера не имеет: эмуляция FDS — отдельная задача.

Игры, пережившие смену мэппера

Многоигровки

Как уже сказано, игре с тривиальным мэппером (№ 0) достаточно дать нужное количество ПЗУ и правильно сконфигурировать видеопамять, и она будет работать на любом мэппере. Этим пользуются многоигровки (multicarts) — картриджи (часто пиратские) с несколькими играми.

Сама Nintendo иногда выпускала многоигровки — в частности, Super Mario Bros. + Duck Hunt (1988), использовавшую нечастый мэппер MHROM[25] (в эмуляторной классификации № 66), подменявший весь объём ПЗУ одной командой.

Nintendo

Прототип Super Mario Bros. 2, называвшийся Doki Doki Panic, вышел на Famicom Disk System. Переход на MMC3[26] добавил фоновую анимацию[24].

Konami

Как указано выше, в США Nintendo запрещала собственные наработки в картриджах под предлогом борьбы с более могущественными компаниями, способными подорвать всю отрасль. Картриджи надлежало брать у Nintendo, и японская Konami, имевшая свой парк мэпперов, несколько пострадала.

Первой пострадавшей игрой стал платформер-боевик Contra (1988). Японская игра имела 256K ПЗУ и мэппер под названием VRC2 (в эмуляторной классификации № 23)[27], имевший большой объём памяти и мелкие банки, что позволяло богатую фоновую анимацию с незначительными дублями. В игре шёл снег, колыхались ветки, были видеовставки[1] — в международных изданиях пришлось перейти на 128K и мэппер UNROM[21], зато геймплей аккуратно сохранили.

Скролл-леталка Gradius имела клон CNROM[28] и перешла на аппаратуру Nintendo без потерь, однако вся игра была урезана по сравнению с автоматом: из четырёх апгрейдов звездолёта осталось два, ушли уровни с прокруткой во все стороны. Сиквел же Salamander был расширен и плохо перенёс смену мэппера. Японская версия работала на мэппере VRC3 (№ 73), имела 128K ПЗУ, 8K рабочего ОЗУ и 8K видео-[29]. Порт Life Force Salamander перешёл на UNROM, потерял рабочее ОЗУ[30], видеовставки, и у звездолёта осталось только два апгрейда вместо трёх[1]. Триквел Gradius II (1988), имевший прокрутку во всех направлениях и очень красивую графику благодаря мэпперу VRC4 (№ 25), 2-м килобайтам рабочего ОЗУ и 256K ПЗУ, так за пределы Японии и не вышел.

Платформер-боевик Castlevania III: Dracula’s Curse (1989) без потерь перешёл с VRC6 (№ 24)[31] на избыточно мощный MMC5[32] — но нестандартная музыка превратилась в стандартную[1], ведь в любом случае конструктив американской NES не поддерживал вмешательство в звук.

Примечания

  1. 1 2 3 4 https://www.youtube.com/watch?v=abC8KedfP_Y
  2. https://videogamegeek.com/geeklist/72455/japanese-famicom-launch-titles
  3. https://www.nintendo.com/en-gb/Iwata-Asks/Super-Mario-Bros-25th-Anniversary/Vol-2-NES-Mario/2-Playing-Donkey-Kong-at-Home/2-Playing-Donkey-Kong-at-Home-216037.html
  4. https://habr.com/ru/companies/ruvds/articles/784788/
  5. Здесь и далее килобайты двоичные, 1K (ка) = 1024
  6. https://www.nintendo.com/en-gb/Iwata-Asks/Super-Mario-Bros-25th-Anniversary/Vol-2-NES-Mario/4-The-Grand-Culmination-of-Cartridges/4-The-Grand-Culmination-of-Cartridges-216138.html
  7. https://nescartdb.com/profile/view/4678/hyper-olympic-gentaiban
  8. 1 2 3 4 Why Your Game Paks Never Forget // Nintendo Power выпуск 020 — с.28‒31
  9. https://nescartdb.com/profile/view/3924/battletoads
  10. https://www.youtube.com/watch?v=0cfa4Vdo1AE
  11. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 https://habr.com/ru/companies/ruvds/articles/784926/
  12. https://nescartdb.com/profile/view/2459/super-mario-bros
  13. https://nescartdb.com/profile/view/3728/ice-climber
  14. https://www.youtube.com/watch?v=o9Ohvi10sM0
  15. 1 2 https://nescartdb.com/profile/view/685/felix-the-cat
  16. 1 2 https://habr.com/ru/companies/sberbank/articles/812573/
  17. https://somethingnerdy.com/unlocking-the-nes-for-former-dawn/
  18. 1 2 Скан схемы картриджа NROM
  19. https://nescartdb.com/profile/view/59/adventure-island
  20. https://www.nesdev.org/wiki/Bus_conflict
  21. 1 2 https://nescartdb.com/profile/view/52/contra
  22. https://nescartdb.com/profile/view/2562/punch-out
  23. https://www.youtube.com/watch?v=7rvy4eof7YY
  24. 1 2 https://nicole.express/2022/the-nes-as-an-artifact.html
  25. https://nescartdb.com/profile/view/10/super-mario-bros-duck-hunt
  26. https://nescartdb.com/profile/view/1949/super-mario-bros-2
  27. https://nescartdb.com/profile/view/3986/contra
  28. https://nescartdb.com/profile/view/1569/gradius
  29. https://nescartdb.com/profile/view/1783/salamander
  30. https://nescartdb.com/profile/view/1412/life-force-salamander
  31. https://nescartdb.com/profile/view/3316/akumajou-densetsu
  32. https://nescartdb.com/profile/view/1411/castlevania-iii-draculas-curse