Мэппер 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
Адресное пространство процессора
| Адреса | Длина | Назначение |
|---|---|---|
| 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) или непрокручивающуюся панель.
- Выполняет редко:
- Даёт дополнительную оперативную память — рабочую, на плитки, или на оставшиеся две страницы видеопамяти. Иногда эта память поддерживается батарейкой и предназначена для сохранений.
- Выполняет крайне редко:
- Выполняет крайне редко, только в японской 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 2 3 4 https://www.youtube.com/watch?v=abC8KedfP_Y
- ↑ https://videogamegeek.com/geeklist/72455/japanese-famicom-launch-titles
- ↑ 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
- ↑ https://habr.com/ru/companies/ruvds/articles/784788/
- ↑ Здесь и далее килобайты двоичные, 1K (ка) = 1024
- ↑ 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
- ↑ https://nescartdb.com/profile/view/4678/hyper-olympic-gentaiban
- ↑ 1 2 3 4 Why Your Game Paks Never Forget // Nintendo Power выпуск 020 — с.28‒31
- ↑ https://nescartdb.com/profile/view/3924/battletoads
- ↑ https://www.youtube.com/watch?v=0cfa4Vdo1AE
- ↑ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 https://habr.com/ru/companies/ruvds/articles/784926/
- ↑ https://nescartdb.com/profile/view/2459/super-mario-bros
- ↑ https://nescartdb.com/profile/view/3728/ice-climber
- ↑ https://www.youtube.com/watch?v=o9Ohvi10sM0
- ↑ 1 2 https://nescartdb.com/profile/view/685/felix-the-cat
- ↑ 1 2 https://habr.com/ru/companies/sberbank/articles/812573/
- ↑ https://somethingnerdy.com/unlocking-the-nes-for-former-dawn/
- ↑ 1 2 Скан схемы картриджа NROM
- ↑ https://nescartdb.com/profile/view/59/adventure-island
- ↑ https://www.nesdev.org/wiki/Bus_conflict
- ↑ 1 2 https://nescartdb.com/profile/view/52/contra
- ↑ https://nescartdb.com/profile/view/2562/punch-out
- ↑ https://www.youtube.com/watch?v=7rvy4eof7YY
- ↑ 1 2 https://nicole.express/2022/the-nes-as-an-artifact.html
- ↑ https://nescartdb.com/profile/view/10/super-mario-bros-duck-hunt
- ↑ https://nescartdb.com/profile/view/1949/super-mario-bros-2
- ↑ https://nescartdb.com/profile/view/3986/contra
- ↑ https://nescartdb.com/profile/view/1569/gradius
- ↑ https://nescartdb.com/profile/view/1783/salamander
- ↑ https://nescartdb.com/profile/view/1412/life-force-salamander
- ↑ https://nescartdb.com/profile/view/3316/akumajou-densetsu
- ↑ https://nescartdb.com/profile/view/1411/castlevania-iii-draculas-curse