Мапперы на Famicom, NES, Денди: откуда взялись и зачем нужны (часть 2/2)
Средний 24 мин Блог компании RUVDS.com История IT Старое железо Игры и игровые консоли Обзор
Продолжаем обстоятельный разговор про «мапперы» — устройства управления расширенной памятью на игровых консолях Famicom, NES и Денди. Во второй части статьи рассмотрим особенности нескольких основных видов мапперов и их влияние на содержание игр, сложности программирования, а также ситуацию с мапперами на других платформах.
Содержание статьи:
▍ Обзор мапперов
В результате описанных в первой части статьи перипетий на рынке, а также участию пиратов, было создано около двухсот разновидностей мапперов — от простейших на одной-двух микросхемах дискретной логики 74-ой серии, до очень сложных на заказных БИС, с самыми разными возможностями. На первый взгляд, разобраться в этом многообразии нелегко, но задачу упрощает то, что в более чем половине всех существующих игр используется всего четыре маппера, имеющих несколько вариаций и аналогов.
Краткая сводка по частоте применения различных мапперов:
iNES | Название | Количество игр | Примечания |
1 | MMC1 | 448 | ASIC маппер |
4 | MMC3 | 437 | ASIC маппер |
2 | UNROM | 203 | Простой маппер на дискретной логике |
0 | NROM | 149 | Базовая конфигурация консоли без маппера |
3 | CNROM | 122 | Простой маппер на дискретной логике |
7 | AxROM | 43 | Подобен UNROM, но банки по 32 килобайта |
16 | FCG | 18 | Подобен MMC3, использовался только в японских релизах Bandai |
19 | N129, N163 | 16 | Продвинутый MMC3-подобный маппер, версия N163 имеет дополнительный звуковой синтезатор |
Далее мы рассмотрим пятёрку лидеров и их ключевые особенности более подробно.
▍ NROM (маппер 0)
Стандартная конфигурация в списке мапперов iNES имеет номер 0. Поэтому о ней часто говорят как о «нулевом» маппере, но фактически это означает отсутствие маппера и расширенной памяти. Возникла с самой консолью, применялась во всех ранних играх, которые выходили до 1987 года.
Платы NROM, японская сверху, американская снизу
В англоязычной любительской документации она обычно называется NROM, по названию самой распространённой «безмапперной» платы производства Nintendo. Есть много аналогичных плат других производителей, но их названия можно встретить в основном в базе данных по платам картриджей. Главный опознавательный признак плат с подобной конфигурацией — из микросхем на них установлено только два ПЗУ и чип региональной защиты (кроме японского региона, где защита не применяется).
Оригинальные платы NROM разработки Nintendo встречаются в двух основных вариантах — NROM-128 и NROM-256, различающихся только объёмом ПЗУ кода, который указан непосредственно в этих названиях (в килобитах). На них может устанавливаться 16 или 32 килобайта ПЗУ кода и 8 килобайт ПЗУ графики. Таким образом, получается общий объём памяти 16+8 или 32+8 килобайт.
Технически NROM позволяет иметь конфигурации и с меньшим объёмом ПЗУ. Лишние линии шины адреса при этом никуда не подключаются, и содержимое ПЗУ повторяется в адресном пространстве несколько раз. Так как формат iNES имеет фиксированные размеры банков в 16 килобайт для кода и 8 килобайт для графики, для конфигураций с нестандартным объёмом памяти содержимое ПЗУ должно повторяться несколько раз, дополняя файл до стандартного размера (так называемый overdump).
Программное управление так называемым миррорингом — конфигурацией внутренней видеопамяти консоли — у NROM отсутствует. Он задаётся только перемычкой на плате, выбирающей горизонтальную или вертикальную организацию. Для эмуляторов это указывается соответствующими флагами заголовка iNES.
Существует несколько экзотических подвидов NROM. Например, поддержанная большинством эмуляторов конфигурация с дополнительными 2 или 4 килобайтами ОЗУ кода в области $6000..$7fff с батарейным питанием, применявшаяся для Family BASIC.
Некоторые игры, работающие в конфигурации NROM
Работа в конфигурации NROM для игр означает, что они могут иметь не так уж много кода, музыки и уровней, и чтобы вместить побольше, разработчикам приходилось идти на большие упрощения и использовать хитроумные схемы сжатия. Например, составлять однотипные локации из больших кубиков, как уровни в Battle City или Nuts & Milk, или описывать отличия в целом одинаковых локаций, как в Ice Climber. Что касается графики, абсолютно вся она должна быть составлена всего лишь из 512 разных блоков размером 8×8 пикселей. Для увеличения визуального разнообразия в ход часто шло перекрашивание в остальном сильно похожих визуально локаций.
В прошлом главной игрой, полностью раскрывающей потенциал конфигурации NROM была всем известная Super Mario Bros (1985). В наши дни подобный же качественный максимум, поднявший планку возможного ещё выше, был достигнут в игре Micro Mages (2019), выполненной в совершенно ином, современном визуальном стиле. Обе эти игры отличаются большим количеством уровней, разнообразием игровых локаций, а также наличием полноценного музыкального сопровождения, состоящего из нескольких достаточно длинных и хорошо аранжированных композиций.
Некоторые другие известные классические игры в этой конфигурации:
- Bomberman (1985)
- Donkey Kong (1983)
- Lode Runner (1984)
- Lunar Ball (1985)
- Popeye (1983)
- Road Fighter (1985)
- Sky Destroyer (1985)
▍ CNROM (маппер 3)
Самый простой маппер, родившийся путём повторения первого в истории Famicom маппера из игры Hyper Olympic Gentaiban! (Track & Field в США). Начал использоваться с апреля 1986 года.
CNROM — это плата Nintendo, на которой реализована полностью совместимая, но удешевлённая версия оригинального маппера. Также есть несколько столь же похожих аналогов от других разработчиков, используемых на платах с другими названиями. Все они реализованы на одной микросхеме дискретной логики 74HCT161 (в оригинале две микросхемы) и отличаются только разным поддерживаемым количеством банков ПЗУ. Эти вариации объединены в стандарте iNES под общим номером 3, тогда как их предшественник получил номер 87.
Плата CNROM и одноимённый маппер
CNROM позволяет расширить только объём ПЗУ графики, со стандартных 8 до 32 килобайт. Он переключает память банками по 8 килобайт, то есть только сразу обе страницы по 256 тайлов, что приводит к неэффективному расходу памяти. Для игр типична ситуация, когда тайлы спрайтов главного героя и врагов расположены в первой странице, а тайлы фона во второй. Если игре нужно несколько наборов графики фона, графику повторяющихся на уровнях спрайтов придётся продублировать в каждой второй странице. Так сделано, например, в Adventure Island. Последующие, более сложные мапперы, решили эту проблему снижением гранулярности банков до 4 килобайт и менее — уже при 4-килобайтных банках появляется возможность выбирать любые сочетания страниц с графикой спрайтов и фона.
ПЗУ кода при использовании маппера CNROM остаётся стандартного размера, 32 килобайта. Однако, не стоит забывать, что видеопамять доступна не только на запись, но и на чтение. Это позволяет размещать некоторый объём данных, например, игровые уровни, в ПЗУ графики и копировать их по мере необходимости в основное ОЗУ. В частности, это используется в игре Milon’s Secret Castle.
Некоторые игры, использующие маппер CNROM
Игры с маппером CNROM в целом остались на том же уровне, что и предыдущие «безмапперные», но возросло их визуальное разнообразие. Ярким примером является игра Adventure Island — в плане содержания, разнообразия геометрии локаций и объёма музыкального сопровождения она близка к Super Mario Bros, но теперь стали возможны более крупные, лучше анимированные спрайты героя и противников, а также несколько различных визуальных сеттингов для локаций. При этом игре всё так же свойственна большая повторяемость элементов, уровни сильно похожи один на другой.
Другие примеры игр:
- Arkanoid (1987)
- Cybernoid (1989)
- Gradius (1986)
- Karateka (1985)
- Mickey Mousecapade (1987)
- Solomon’s Key (1986)
▍ UNROM (маппер 2)
Под номером 2 в стандарте iNES объединены однотипные по устройству мапперы и платы — семейство, имеющее общее название UxROM, но обычно наименуемое по самой известной вариации, UNROM.
Концептуально UNROM стоит особняком от других мапперов. Его ключевой особенностью является использование для хранения графики не отдельного графического ПЗУ, а основного, в котором хранится и код. Графика же загружается игрой в установленные на плате картриджа 8 килобайт ОЗУ. Эта система аналогична реализованной в Famicom Disk System, только там загрузка данных происходила с дискеты. Возможно, сама идея такого маппера и была подсказана появлением FDS.
Плата с маппером UNROM
В UNROM реализовано переключение только одного 16-килобайтного окна ПЗУ с кодом, находящегося в младших адресах. Количество графического контента в игре ограничено только объёмом ПЗУ кода, максимальный объём которого на практике составлял 256 килобайт. К тому же, возможно не просто загружать готовые наборы графических элементов, а комбинировать их, или применять техники сжатия данных. Использование ОЗУ открыло и совершенно новую технику работы с графикой: можно обновлять часть графики динамически, прямо во время работы игры — например, загружать кадры главного героя, что позволяет не держать их все в видеопамяти одновременно, и использовать освободившееся место для других игровых элементов.
Технически маппер UNROM реализуется на двух микросхемах дискретной логики, 74HC161 и 74HC32. Конфигурация тайловых карт всё ещё задаётся перемычками, то есть не может быть изменена в процессе работы игры.
Существуют аналогичные по концепции мапперы AxROM и BNROM, отличающиеся только переключением банков сразу по 32 килобайта. Также возможность применения ОЗУ вместо ПЗУ для графики предусмотрена во всех последующих, более сложных мапперах.
В наши дни любители разработали улучшенный вариант маппера, известный под названием UNROM 512 (имеет номер 30 в iNES). Он поддерживает до 512 килобайт ПЗУ кода, до 32 килобайт ОЗУ графики с 8-килобайтными банками, а также, в некоторых реализациях, самопрограммируемую Flash-память для игровых сохранений и управление конфигурацией тайловых карт. Маппер получил большую популярность, так как он — единственный, поддерживаемый в конструкторе игр NESmaker, нашумевшем в 2018 году.
Некоторые игры, использующие маппер UNROM
Первая игра, использующая UNROM, вышла в июне 1986 года — знаменитая Ghosts & Goblins от Capcom. Одного этого примера достаточно, чтобы понять значение нового маппера для игр, которые вышли на качественно новый уровень. Теперь в каждом уровне игры есть своё уникальное оформление, уникальная карта, сложная музыка, и крупные, хорошо анимированные спрайты игрока и противников.
Хотя после UNROM появлялись и другие, ещё более продвинутые мапперы, его возможностей вполне хватало многим играм практически до самого конца коммерческой жизни платформы. Среди них:
- Castlevania (1986)
- Contra (1988)
- DuckTales (1989)
- DuckTales 2 (1993)
- Jackal (1988)
- Lifeforce (1987)
- Little Mermaid (1991)
- Prince of Persia (1992)
▍ MMC1 (маппер 1)
Впервые этот маппер компании Nintendo был задействован в игре Morita Shougi компании Seta, вышедшей в апреле 1987 года.
По сравнению с предыдущими мапперами MMC1 обладает значительно более продвинутыми возможностями. Он позволяет переключать ПЗУ кода в двух окнах размером 16 килобайт, а также ПЗУ графики одним окном в 8 килобайт или же двумя раздельными, размером по 4 килобайта. Максимальный объём ПЗУ кода составляет 512 килобайт, а ПЗУ графики — 128 килобайт. Также поддерживается дополнительное ОЗУ с батарейным питанием, размером до 32 килобайт. С MMC1 впервые стало доступно программное управление конфигурацией тайловых карт. Впрочем, как правило, игры не пользуются всеми возможностями управления памятью, предпочитая UNROM-подобную конфигурацию с одним переключаемым банком в младших 16 килобайтах.
Плата SLROM с маппером MMC1
Маппер имеет крайне необычное управление. Все пять управляющих регистров последовательные: пятибитное значение передаётся через младший бит пятью записями байт в нужный диапазон адресного пространства ПЗУ. Это довольно медленно и неудобно, и является основным недостатком MMC1.
В отличие от более простых мапперов, MMC1 существует только в виде ASIC, то есть заказной микросхемы. Существует как минимум шесть её ревизий, применявшейся в семействе SxROM, включающем 25 различных плат (SLROM, SOROM и другие), а также на платах NES-EVENT, использовавшихся исключительно для особых картриджей Nintendo World Championship, созданных для проведения публичных игровых конкурсов компании.
Первая ревизия чипа производилась компанией ROMH, появившаяся в 1988 году ревизия MMC1A и последующие версии выпускались другим производителем, предположительно Ricoh. Китайские производители также создали полный клон маппера, известный под обозначением AX5904. Почти все версии имеют «узкий» корпус PDIP-24, за исключением редкой MMC1B2F, имевшей корпус SOIC-24.
Некоторые игры, использующие маппер MMC1
Влияние на содержание игр у MMC1 было примерно таким же, как у UNROM. Однако, возможности маппера позволили проще реализовать более сложную логику кода. Стали доступными внутриигровые сохранения (реализованы только в некоторых играх). Программное управление конфигурацией тайловых карт позволило реализовывать и совмещать чуть более сложные визуальные решения, чем обычно. В том числе стало проще реализовывать прокрутку карты уровня большого размера во всех 8 направлениях, что можно видеть в игре Blaster Master. Несмотря на некоторые недостатки, MMC1 стал одним из, если не самым популярным маппером на платформе.
- Bionic Commando (1988)
- Castlevania II: Simon’s Quest (1989)
- Chip ‘n Dale (1990)
- Chip ‘n Dale 2 (1993)
- Darkwing Duck (1992)
- Double Dragon (1988)
- RoboCop 3 (1992)
▍ MMC3 (маппер 4)
Первой игрой с маппером MMC3 стала ещё одна игра компании Seta — 8 Eyes, вышедшая в сентябре 1988 года. Однако, основы архитектуры маппера были заложены гораздо раньше, ещё в 1986 году, в маппере Namco N108 — основной его функционал схож, но несколько проще по сравнению с MMC3.
Плата TSROM с маппером MMC3
Семейство из пары десятков плат на основе маппера MMC3, отличающихся конфигурацией и объёмами памяти, называется TxROM — например, TLROM, TSROM. Всем им назначен номер 4 в стандарте iNES. Помимо типового включения, есть несколько специфических альтернативных, реализованных на платах TxSROM и TQROM. Им назначены отдельные номера, 118 и 119.
Существует как минимум три ревизии чипа MMC3, а также его версия MMC6. Все они выполнены в виде ASIC в корпусе TQFP-44. Впоследствии другие компании создали несколько своих ASIC-мапперов, аналогичных по возможностям, но не совместимых программно. Например, это FME-7 от Sunsoft и VRC6 от Konami.
Пираты очень полюбили MMC3 и создали множество его модификаций, под которые даже адаптировали игры с других мапперов, чтобы не заморачиваться с клонированием всего зоопарка оригинальных микросхем. Самый известный пиратский прямой клон маппера — AX5202P, выполненный в старом добром формате DIP-40. Прочие же клоны часто выполнялись в бескорпусном исполнении.
В своих разных конфигурациях MMC3 позволяет использовать от 64 до 512 килобайт ПЗУ кода, а также до 256 килобайт ПЗУ графики, с опцией использования вместо него 8-килобайтного ОЗУ. Поддерживается ОЗУ с батарейным питанием для сохранений, правда, более скромного, чем у MMC1 размера — 8 килобайт. Присутствует и программное управление конфигурацией тайловых карт. Управление маппером — нормальное человеческое, обычной разовой записью значений в несколько регистров, спроецированных на разные диапазоны адресного пространства.
MMC3 предложил более гибкое управление банками, но без излишних усложнений, оптимально соответствующее типичным потребностям игровых программ, которые определились к тому моменту. Наибольшее улучшение произошло в управлении банками графического ПЗУ: теперь доступно целых шесть окон, два из которых имеют размер два килобайта (128 тайлов), и четыре — по килобайту (64 тайла). Это открыло возможности для удобной и быстрой анимации фона или спрайтов. Например, с помощью этих возможностей реализованы анимации фоновых элементов в играх Batman (1989) и Tiny Toon Adventures (1991).
Что касается ПЗУ кода, MMC3 представляет два переключаемых окна по 8 килобайт в нижней половине адресного пространства — простое и оптимальное решение, позволяющее держать в разных подключаемых банках и процедуры, и их данные.
Изюминкой же маппера стала поддержка так называемых строчных прерываний, IRQ, генерируемого в начале заданной строки. Это позволило реализовывать разнообразные визуальные эффекты, такие как многоплановый параллакс, с более эффективным расходом процессорного времени.
Некоторые игры, использующие маппер MMC3
Пожалуй, главная игра, явно демонстрирующая преимущество этого маппера — Super Mario Bros 3 (октябрь 1988). Огромное количество контента, графики, анимации, музыки, уровней, и всего, что только можно. Этих возможностей хватило для реализации множества других лучших игр, и в итоге MMC3 и его аналоги стали своего рода золотым стандартом, продлившийся до конца коммерческой жизни платформы. Среди игр:
- Batman Returns (1993)
- Bucky O’Hare (1992)
- Contra Force (1992)
- Felix the Cat (1992)
- Power Blade (1991) и Power Blade 2 (1992)
- Super C (1990)
- Super Mario Bros. 2 (1988) и Super Mario Bros. 3 (1988)
- TMNT 2 (1990) и TMNT 3 (1991)
▍ Остальные
Перечисление особенностей всех прочих существующих мапперов, конечно, не представляется возможным, или хотя бы разумным. Но некоторые экземпляры выделяются исключительно, и потому заслуживают хотя бы краткого упоминания
Прежде всего это, конечно, все мапперы с расширением звуковых возможностей. Famicom позволял пропускать аналоговый звук из приставки через картридж. Несколько крупных японских разработчиков воспользовались этим и создали свои чипы-синтезаторы звука, установленные в каждой копии игры и сильно улучшающие её звучание. Использовались такие чипы только в японских версиях игр — возможность подключения внешнего источника звука в NES не была реализована. Конечно, сейчас её возможно добавить с помощью простейшей аппаратной модификации внутри консоли, но в те времена это закрыло путь играм с улучшенным звучанием на Запад.
Плата с маппером VRC7
Мапперы, содержащие дополнительный синтезатор звука и краткий перечень их возможностей:
- Konami VRC6 — два прямоугольных канала с переменной скважностью и один пилообразный
- Konami VRC7 — шесть каналов двух-операторного FM-синтеза
- Namco 106 — от одного до восьми каналов табличного синтеза
- Sunsoft 5B — по сути всеми любимый AY-3-8910 (точнее, YM2149F)
- MMC5 — два прямоугольных канала, точно таких же, как в основном синтезаторе
Следующие мапперы, которые стоит упомянуть — MMC2, MMC4 и MMC5 разработки самой Nintendo.
MMC2 и MMC4 являются вариантами одного и того же маппера с незначительными отличиями. Их уникальной особенностью является возможность переключения между наборами графики в момент, когда луч развёртки достигает одного из двух специальных тайлов. Маппер переключает ПЗУ графики двумя окнами по 4 килобайта, для каждого из них можно выбрать сразу два банка, между которыми будет происходить переключение в нужный момент. Такая хитроумная схема позволила увеличить количество отображаемых на экране тайлов с 256 до 512 без применения прерываний или других трюков. Впервые маппер был задействован в 1987 году, наиболее известные игры с его применением — Mike Tyson’s Punch-Out!!! и Fire Emblem.
MMC5 — самый продвинутый маппер, созданный во время коммерческой жизни платформы, в 1990 году, и таким он остаётся до сих пор. Все его возможности перечислить непросто, но самая заметная — одновременное отображение на экране до 16384 тайлов фона с размером цветовых атрибутов 8×8 пикселей, а самая необычная — аппаратный умножитель, мгновенно перемножающий два 8-битных числа. В теории эти возможности позволяют очень существенно поднять детализацию и цветность графики, а также усложнить сами игры. Однако, по каким-то причинам десяток вышедших игр, использовавших этот маппер, едва ли раскрывают хотя бы малую часть его потенциала. Применение же настолько сложного маппера в любительских проектах остаётся коммерчески нерентабельным даже в наши дни, реплика получается слишком дорогой.
Рядом с рассказом о столь продвинутом маппере уместно отметить, что компания Rare регулярно использовала простой маппер AOROM, представляющий собой вариант UNROM с 32-килобайтными банками. Отсутствие продвинутых возможностей не помешало разработчикам компании создать целый ряд наиболее впечатляющих игр платформы — например, Battletoads и Battletoads & Double Dragon.
Самодельная плата с одним ПЗУ (не моя)
И в качестве другой крайности в рассказе о мапперах стоит упомянуть про крайне любопытную безмапперную конфигурацию всего с одним ПЗУ. Она изобретена энтузиастами и применялась в начале 2010-х годов в паре микро-игр Magic Floor и Starfight, ей присвоен номер 218 в списке мапперов iNES.
Игры для маппера 218, всё их содержание целиком
Идея заключается в том, что архитектура Famicom позволяет перекоммутировать внешнюю шину адреса видеоконтроллера перемычками на разъёме картриджа таким образом, что в качестве внешнего видео ОЗУ будут использоваться встроенные в консоли 2 килобайта видеопамяти, обычно применяемых для тайловых карт. Если ограничиться применением всего одной тайловой карты вместо традиционных двух, это освободит 1024 байта видеопамяти — их будет достаточно для набора из 64 загружаемых из ПЗУ кода тайлов. Конечно, сделать в подобных условиях хоть что-то — задача нетривиальная, но в самый раз для любителей экстремального программирования и героического преодоления собственноручно создаваемых трудностей.
▍ Трудности кода
Конечно, внедрение мапперов не только решило проблему расширения памяти, но и принесло разработчикам дополнительные сложности. Некоторые из них довольно занимательные и не самые очевидные, и о них стоит рассказать.
Для начала нужно перечислить целую охапку особенностей архитектуры Famicom, которые необходимо держать в голове, планируя архитектуру кода игры с применением маппера:
- Управление мапперами практически всегда реализовано посредством записи значений в область ПЗУ. Его содержание от этого никак не поменяется, на то оно и ПЗУ, но такую запись легко перехватить на плате картриджа по установке соответствующих сигналов шины, и направить в регистр-защёлку маппера.
- Запись в регистр маппера переключает банк памяти мгновенно, ещё до перехода к следующей команде кода. И если код, выполняющий переключение банка, сам находится в переключаемом окне, после завершения команды записи регистра маппера чтение следующей команды продолжится уже из нового банка.
- Никакая аппаратура консоли не знает про существование мапперов и не может с ними взаимодействовать. Наличие маппера учитывает только написанный программистом код.
- В самом конце его адресного пространства процессора 6502 находятся так называемые векторы сброса и прерывания — адреса, указывающие на код, который начинает выполняться после сброса, а также на код обработчиков прерываний. Процессор читает эти данные каждый раз в момент сброса, а также при каждом срабатывании прерывания. Изменить эти адреса никак нельзя.
- У звукового синтезатора Famicom есть так называемый DMC, канал, проигрывающий фрагменты оцифрованного звука. Он устроен таким образом, что чтение и воспроизведение звука выполняются полностью аппаратно, без участия процессора. В устройстве зафиксировано расположение сэмплов — всегда в старших 16 килобайтах адресного пространства.
- На разъёме картриджа нет сигнала от кнопки сброса. Таким образом, устройства, расположенные на картридже, не имеют возможности узнать, что игрок нажал кнопку сброса, и произвести свою инициализацию.
Учитывая всё вышесказанное, возникает множество проблем и ограничений, требующих тщательного планирования работы с маппером, а также продуманной стратегии распределения кода по переключаемым банкам: нужно спланировать, каким частям кода могут понадобится те или иные данные, и в каких комбинациях.
Во многих мапперах переключаемой сделана ровно половина адресного пространства, отведённого для ПЗУ кода, его младшие 16 килобайт. Таким образом, код выбора банков, векторы 6502, а также звуковые сэмплы для DPCM-канала всегда находятся в части ПЗУ, которая никогда не переключается. С одной стороны, это устраняет многие проблемы, но с другой, место в этой области памяти становится на вес золота, ведь в этой же области удобно расположить и весь код, обращающийся к данным в банках.
Второй распространённый вариант — переключается всё адресное пространство ПЗУ целиком, все 32 килобайта. В этом случае, конечно, требуется дублировать векторы 6502 во всех банках, а если применяется DPCM — то и сэмплы. Но даже это не главная проблема. Ведь если переключить банк, на месте следующей команды процедуры переключения окажется совсем другой код. Чтобы этого не произошло, процедуру приходится дублировать в каждом банке в одном и том же месте. А если коду нужно обратиться к данным, находящимся в другом банке — частая ситуация в играх — он и вовсе не может этого сделать. Чтобы обойти эту проблему, часть кода помещается в ОЗУ — он может включить банк с данными, прочесть их в буфер, и вернуть обратно банк с кодом. Размер ОЗУ крайне ограничен, поэтому такой код нужно планировать очень аккуратно и делать минимального размера.
Некоторые продвинутые ASIC-мапперы умеют переключать банки по 8 килобайт. Это практически идеальный вариант — можно получить и фиксированные 16 килобайт в верхней памяти, и два окна по 8 килобайт, в которые могут подключаться и банки с кодом процедур, и одновременно банки с нужными для этих процедур данными. Конечно, в этом случае длина непрерывного кода процедуры или блока данных ограничена 8 килобайтами, но на практике этого вполне достаточно.
Если маппер умеет переключать самую верхнюю часть памяти, в которой процессор 6502 при сбросе читает стартовый адрес кода, там может оказаться вовсе не начало программы, а тот банк, который был включён в момент сброса. Поэтому игры с подобными мапперами дублируют векторы процессора в каждом банке, заодно с процедурой инициализации, принудительно устанавливающей нужный банк при старте игры. Аналогичным образом решается и проблема с обработчиками прерываний.
Что касается сэмплов DPCM, при любой схеме использования маппера приходится сильно ограничивать их размер: с фиксированным верхним окном место в нём требуется для других вещей, а для переключаемого банка пришлось бы дублировать сэмплы или код в каждом таком банке. В связи с этим далеко не все игры используют DPCM-канал для музыки и звуковых эффектов, а те, которые это делают, обходятся всего несколькими очень короткими звуками ударных инструментов. Вероятно, это одна из главных причин, почему так называемый Sunsoft Bass — жирно звучащий бас в музыке, сделанный из сэмплов, требующих несколько килобайт ПЗУ — не получил широкого распространения.
Наконец, ещё одна интересная особенность — так называемый «bus conflict», то есть конфликт шины. Она свойственна всем простым мапперам на дискретной логике в силу их максимально упрощённой схемотехники. Знание этой особенности довольно важно для современных разработчиков homebrew проектов, так как она не эмулируется в большинстве эмуляторов (корректно проходят любые записи), а также не во всех случаях реализована на Flash-картриджах.
Как я уже говорил, практически все мапперы управляются записью в область ПЗУ. Однако, в простых мапперах у ПЗУ в целях удешевления всегда активен сигнал чтения, и когда такая запись выставляет на шине адрес, ПЗУ добросовестно выдаёт на шину данных соответствующее этому адресу содержимое. Процессор же также выставляет на шину данных только что записанное значение. Возникает недопустимая в цифровой схемотехнике ситуация — нельзя напрямую соединять выходы логические элементов, так как выходные уровни начинают бороться друг с другом. Какой из них победит — зависит от особенностей схемотехники, в любом случае итоговое значение, попадающее в регистр-защёлку маппера, окажется не тем, которое записывал код, окажется выбран не тот банк, и игра будет работать некорректно.
Чтобы избежать этой неприятности, достаточно, чтобы записываемое значение и значение, хранящееся в ПЗУ по такому адресу, совпали. Тогда борьбы разных уровней просто не произойдёт, и в защёлку маппера будет гарантированно записано корректное значение. По этой причине игры с мапперами на дискретной логике содержат табличку всех возможных значений, какие могут быть записаны игрой в регистры маппера. В мапперах на ASIC эта проблема, как правило, решается на аппаратном уровне — при записи в область ПЗУ сигнал чтения с него снимается и его выходы переходят в среднее состояние.
▍ Другие платформы
Наверное, самое время сказать, что сами по себе мапперы не являются эксклюзивной особенностью архитектуры Famicom. Страничная адресация с переключением банков — стандартное решение для расширения памяти, применявшееся, например, в 8-битных домашних компьютерах, обладавших более чем 64 килобайтами памяти. Относительно необычным, но типичным для картриджных систем является расположение маппера снаружи. Уникальной же особенностью Famicom является ситуация с количеством мапперов и разнообразием их возможностей. На других игровых консолях они также применялись, но или не так широко, или изначально были стандартизированы и поэтому представлены в значительно меньших количествах.
▍ Atari 2600
Впервые мапперы в составе картриджа появились, вероятно, на Atari 2600. Её жизненный цикл также оказался очень длительным, с 1977 по 1992 год. Штатно система поддерживает максимум 4 килобайта внешнего ПЗУ, но уже в самом начале 1980-х годов, ещё до выхода Famicom на рынок, на ней появились первые 8-килобайтные игры.
Впоследствии объёмы росли, и к концу коммерческой жизни платформы составляли 32 килобайта (игра Fatal Run, 1990), а современные любительские разработки поддерживают и значительно большие объёмы. Всего на Atari 2600 известно около трёх десятков мапперов. Часть из них по сути является просто переключателем игр для сборников-многоигровок, другие же являются полноценными мапперами.
Платформа имеет свою особую специфику. Дело в том, что на разъёме картриджа не предусмотрен сигнал записи, а значит, нельзя ничего передать железу на картридже хотя бы для переключения банков, и тем более нельзя разместить в картридже дополнительное ОЗУ. Выход из ситуации, конечно, был найден.
Для переключения банков используется перехват чтения из определённого адреса. Например, при чтении из адреса $1FF8 выбирается один банк, а при чтении из адреса $1FF9 — другой. Это, конечно, требует более полной дешифрации шины адреса.
Для записи во внешнее ОЗУ используется идея разделения адресного пространства на два диапазона. В оба диапазона отображается один и тот же участок ОЗУ. Например, один килобайт ОЗУ отображается в адреса $1000..$13FF и $1400..$17FF При этом любое обращение в первый диапазон считается чтением, а любое обращение во второй диапазон — записью.
▍ Sega Master System
В 1986 году Sega вступила в прямую борьбу с Nintendo за рынок домашних видеоигр, выпустив свою консоль Sega Mark III (позже Master System). К тому времени тенденция к росту объёма игр стала очевидной, поэтому расширение памяти в ней было заложено изначально.
Адресное пространство процессора используется более эффективно: в конфигурации без маппера доступно 48 килобайт ПЗУ. Правда, графика всегда хранится в основном ПЗУ, и так как она 16-цветная, для неё требуется больше места, чем на Famicom. Поэтому первые игры с использованием мапперов вышли уже в 1986 году.
Маппер на Master System могут расширять только память для основного процессора. Графическая и звуковая системы для устройств на картридже недоступны. Для регистров маппера предусмотрены специальные адреса в карте памяти. Почти все игры, за исключением некоторых ранних японских релизов, имеют заголовок, в котором указан объём ПЗУ (от 8 килобайт до 1 мегабайта). Информация об объёме ПЗУ используется BIOS для сверки контрольной суммы ПЗУ перед запуском игры.
Официальный маппер для системы был всего один, но в трёх версиях, с поддержкой от 128 до 512 килобайт ПЗУ. Первая, самая редкая версия, была выполнена в виде отдельной микросхемы, последующие же версии для снижения себестоимости картриджей были интегрированы с масочным ПЗУ. Также существовало два маппера от сторонних разработчиков, представлявших собой по сути упрощённые варианты официального маппера. Стандартизация позволила избежать зоопарка несовместимых устройств, а интеграция с масочным ПЗУ обеспечила определённый контроль над платформой.
▍ NEC PC Engine
Игровая консоль PC Engine (TurboGrafx-16 в США), разработанная компанией Hudson Soft — той самой, ранее оказавшей значительное влияние на развитие Famicom — и производившаяся NEC, вышла на рынок в 1987 году. Изначально она была призвана конкурировать с NES и Master System, но фактически столкнулась на рынке с консолями следующего, 16-битного поколения.
PC Engine — вероятно самая совершенная 8-битная игровая система, в которой технологические решения прошлого были доведены до совершенства. За счёт применения бескорпусных микросхем картридж, называемый здесь HuCard, был уменьшен до формата кредитной карточки, что, конечно, повлияло на возможность как его производства «на стороне», так и на возможность добавления дополнительных устройств.
HuCard и его устройство
В отличие от предыдущих систем, маппер был предусмотрен в самой консоли, и, более того, был встроен прямо в процессор HuC6280, ускоренный вариант 65C02 с дополнительными устройствами и 21-битной внешней адресной шиной. Для управления маппером в процессоре было предусмотрено две специальные команды и восьми регистров. Маппер разделял адресное пространство на 8 окон по 8 килобайт и позволял подключать в них до 2 мегабайт ПЗУ. Также консоль имела 8 килобайт основного и 64 килобайта видео ОЗУ. Таким образом, необходимость в использовании внешних мапперов была полностью устранена.
Неочевидным недостатком этого решения стал отказ от поддержки «батарейных» сохранений в играх — батарейку было сложно размещать внутри HuCard, и тем более менять. Для поддержки сохранений предлагалось докупать дополнительные устройства от NEC и сторонних производителей — первый шаг к ныне ушедшей в прошлое концепции карт памяти, ставший нормой с появлением PlayStation в 1994 году. Такое решение было неоднозначным по причине дополнительных трат и ограниченной совместимости между устройствами и играми. В последующих версиях своей консоли NEC попыталась устранить этот недостаток, добавив встроенную память для сохранений — подход, актуальный в наши дни.
▍ Nintendo Game Boy
Сама Nintendo провела своеобразную работу над ошибками в 1989 году, в своей первой портативной игровой консоли Game Boy.
Технически всё осталось примерно на том же уровне, на каком закончилось на NES: 32 килобайта ПЗУ без маппера и ASIC-мапперы в картридже для расширения ПЗУ до 256-8192 килобайт и добавления ОЗУ для сохранений. Как и в Master System, расширяется только память процессора, хотя сигналы на разъёме картриджа предусматривали и подключение разнообразной периферии.
Изначально более жёсткий контроль над платформой добавил упорядоченности. Сама Nintendo разработала и производила всего четыре очень схожих маппера, для разных объёмов ПЗУ. Также был аналог официального маппера от Hudson Soft.
▍ Sega Genesis и SNES
Платформам четвёртого поколения мапперы были не особо нужны, так как архитектура их процессоров непосредственно предусматривала поддержку относительно больших объёмов памяти, а расширение видеопамяти не предусматривалось. Но применение мапперов всё же случалось.
Sega Genesis теоретически способна адресовать до 16 мегабайт памяти процессора, и на разъёме картриджа предусмотрены необходимые для этого сигналы. Однако, непосредственно для ПЗУ кода выделен участок памяти размером в 4 мегабайта, а остальное пространство было зарезервировано для возможных будущих расширений, которые, как известно, случились в лице Sega CD и Sega 32x. И хотя в картридже можно разместить более 4 мегабайт ПЗУ без дополнительных ухищрений, такой объём памяти будет конфликтовать с этими расширениями — для нормальной работы их пришлось бы отключать от консоли физически.
Единственный пример превышения объёма в 4 мегабайта из периода коммерческой жизни платформы — игра Super Street Fighter II. Она имеет объём 6 мегабайт, и для обеспечения бесконфликтной работы в любой конфигурации в ней реализован так называемый Sega Mapper, разработанный самой компанией Sega. Он разделяет адресное пространство 4 мегабайта на 8 окон по 512 килобайт. Нижнее окно всегда фиксированное, так как в нём расположена точка старта и векторы прерываний, а в остальные семь можно включать нужный фрагмент ПЗУ записью в соответствующие 8-битные регистры маппера. Таким образом, теоретический максимальный объём ПЗУ, который позволяет задействовать этот маппер — 128 мегабайт.
Плата картриджа Super Street Fighter II. Маппер находится в верхнем правом углу, остальные микросхемы — масочные ПЗУ объёмом по 2 мегабайта каждое
В современной истории к применению мапперов на Sega Genesis обратился независимый разработчик Water Melon в своих играх Pier Solar and the Great Architects (2010) и Paprium (2020).
Pier Solar имеет объём 8 мегабайт и использует маппер, схожий с Sega Mapper, но с управляющими регистрами, расположенными по другим адресам, и с защитой от копирования.
Плата картриджа Pier Solar. Секретная электроника щедро залита компаундом
Paprium имеет такой же же объём, но также использует очень сложное дополнительное оборудование в составе картриджа, называемое разработчиком «Datenmeister». Оно состоит из FPGA, 32-битного микроконтроллера, современного 3-вольтового Flash ПЗУ и ОЗУ объёмом 2 мегабайта. Помимо управления памятью, на этом оборудовании реализован ускоритель обработки спрайтов и дополнительный звуковой синтезатор.
Datenmeister. На этот раз клякса компаунда прикрыта красивой крышечкой
Ситуация на конкурирующей консоли, Super Nintendo, сильно отличается. Эта платформа известна довольно широким применением дополнительных, более мощных микропроцессоров в составе картриджей. Хотя этот подход и выглядит чем-то схожим — какой-то умный чип на плате, улучшающий игры — технически они являются совершенно иными устройствами с другими принципами работы и другими решаемыми задачами, поэтому называть их мапперами некорректно.
Тем не менее, свой «маппер» на SNES есть, и применялся он повсеместно. Он всего один, и так и называется — «The Mapper». Несмотря на говорящее название, он не занимается организацией страничной адресации памяти как таковой, его задачи несколько иные.
Плата картриджа для SNES. Маппер — небольшая микросхема в центре сверху
Реализуется The Mapper на микросхеме 74LS139 или на заказном чипе MAD-1, и нужен он для конфигурирования доступа к ПЗУ картриджа по одной из двух возможных схем, так называемых LoROM и HiROM, в которых память разбивается на блоки по 32 или 64 килобайта. Эти схемы имеют свои преимущества и недостатки, которые очень затруднительно объяснить на пальцах, но в целом это просто специфика местной архитектуры — 16-битный процессор 65C816 имеет строго 8-битные корни в лице своего прародителя 6502, и поэтому в разных режимах умеет работать как с полным объёмом памяти, так и с 16-битным адресным пространством. Также The Mapper декодирует адреса для подключения ОЗУ с батарейкой для игровых сохранений.
▍ Заключение
История мапперов закончилась так же, как и история многих других технологий прошлого — прогресс просто сделал её невостребованной. Процессоры следующего поколения уже не требовали применения страничной адресации, а видеосистема новых платформ более не предполагала расширяемости и внешней конфигурации. Мапперы Famicom и NES остановились на довольно скромных объёмах поддерживаемой памяти (768 килобайт в Kirby’s Adventure 1993 года), потенциал расширения графических возможностей также оказался лишь поверхностно затронут в маппере MMC5 и немногочисленных играх для него. Остались нереализованными и идеи компании Color Dreams по установке в картридж дополнительного процессора Z80.
В настоящее время у платформы есть большое и активное сообщество энтузиастов. Выходят десятки новых игр, новые инструменты для разработки. Случаются и попытки развития технологии мапперов — например, ставший современным стандартом UNROM 512, или вариация на тему UNROM, поддерживающая до 128 мегабайт ПЗУ (о моём старом проекте на её основе есть статья на Хабре). Всё ещё не создан экономически эффективный аналог MMC5, но ожидания уже давно витают в воздухе. И возможно, в эту историю ещё будут вписаны новые занимательные главы.
Скидки, итоги розыгрышей и новости о спутнике RUVDS — в нашем Telegram-канале 🚀
Теги:
- денди
- nes
- famicom
- 8-bit
- 8-бит
- приставки
- консоли
- mmc1
- mmc3
- mmc5
- unrom
- nrom
- маппер
- ruvds_статьи
Хабы:
- Блог компании RUVDS.com
- История IT
- Старое железо
- Игры и игровые консоли