Удаление Изображений С Картриджей Для Dendy/Famicom/Nes

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

Ромы этих же игр вы легко найдете в Интернете.

Часто люди скачивают их и даже не задумываются о том, как кто-то когда-то прочитал их с картриджа.

В этой статье я попытаюсь рассказать, как это было сделано в случае с NES/Famicom, которая была нам более известна как «Денди», и покажу, как это можно сделать самостоятельно.



Удаление изображений с картриджей для Dendy/Famicom/NES

Сразу скажу, меня уговорили сняться в целом многосерийном шоу на тему того, как устроены и работают игровые консоли.

Поэтому публикация сегодня идет сразу в двух вариантах: в виде видео и по старинке в виде статьи.

Кому как больше нравится, тем более что целевая аудитория у каждого варианта явно разная.

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



Видео:

(Связь: www.youtube.com/watchЭv=gPSpk2gbAD4 )

Статья:

Итак, как же работает картридж Famicom? Многие сразу скажут, что это всего лишь ПЗУ с параллельным доступом, и в ее чтении не должно быть ничего сложного, но это не совсем так.

Во-первых, картридж содержит два типа памяти: с кодом игры и с изображениями из игры.

Каждый из них включается непосредственно в консольную шину данных.

Первый параллельно с оперативной памятью и процессором (CPU), а второй параллельно с видеопамятью и видеочипом (PPU).

Таким образом, картридж представляет собой что-то вроде оперативной памяти, куда уже загружена игра.



Давайте рассмотрим распиновку гнезда картриджа и принцип ее работы.



Удаление изображений с картриджей для Dendy/Famicom/NES

Вид на консоль сверху.

Слева — перед. → ЦП A0-A14 — контакты, через которые задается адрес чтения памяти процессора ЦП D0-D7 — контакты, через которые мы передаем данные памяти процессора → ППУ А0-А13 — контакты, через которые задается адрес чтения памяти ППУ ППУ Д0-Д7 — контакты, через которые передаем данные памяти ППУ → М2 — локальный тактовый сигнал, принимает высокий уровень при обращении к памяти ЦП → /РОМСЕЛЬ - логическое NAND между M2 и CPU A15, к которому нет прямого доступа → Процессор Чтение/Запись - определяет тип операции: высокий уровень - чтение, низкий - запись ← /IRQ - позволяет картриджу генерировать прерывание, внутри пульта подтягивается до +5В → ППУ/РД - переходит в низкий уровень, когда консоль читает память PPU → ППУ/ВР - переходит в низкий уровень, когда консоль записывает в память PPU → ППУ/А13 — просто инвертированный сигнал с ППУ А13 ← ЦИРАМ А10 — позволяет картриджу определить принцип зеркалирования видеопамяти в консоли ← CIRAM /CE - при низком уровне включает видеопамять внутри консоли → Звук (вход) - здесь звук с аудиочипа идет в картридж ← Звук (вход) - здесь звук исходит из картриджа в том виде, в котором мы его уже слышим * Земля и еда — без комментариев, напряжение 5 вольт Теперь более подробно, немного технической информации.

Объем памяти ЦП консоли варьируется в диапазоне от 0 И $FFFF (16 бит адресации).

На картридже обычно указаны адреса $8000-$FFFF .

Обратите внимание, что у нас нет контактов ЦП А15 , который должен отвечать на самый старший бит адреса.

Вместо этого есть /РОМСЕЛЬ , который становится низким только тогда, когда М2 и теоретический ЦП А15 в то же время занять высокий уровень.

Те.

когда консоль читает или записывает адреса $8000-$FFFF .

Поэтому его обычно можно напрямую подключить к ножке /CE ПЗУ.

Чтение или запись по выбору через Процессор Чтение/Запись .

Зачем нужно писать на картридж? Да, причин много, но об этом ниже.

Память PPU имеет адреса из 0 до 3 доллара США (14 бит адресации), что обычно относится к картриджу 0-$1FFF .

Именно в этом диапазоне хранятся образы, причем это может быть как ПЗУ, так и ОЗУ, но картридж сам определяет, какие адреса принадлежат ему, а какие внутренней части консоли, для чего он и используется.

ЦИРАМ/СЕ .

Обычно (почти всегда) он подключается напрямую к ППУ/А13 , т.е.

память консоли активируется при А13 равный единице - в диапазоне от $2000 до 3 доллара США .

Обратите внимание, что внутренняя память Famicom и NES приведена ниже.

$2000 и нет вообще, он должен быть в картридже.

PPU использует отдельные контакты для чтения и записи: ППУ/РД И ППУ/ВР .

Отдельно стоит упомянуть ЧИРАМ А10 - этот вывод определяет, как зеркалируется память в диапазоне между $2000 И $2FFF внутри консоли.

Обычно это важно определить в зависимости от того, движется ли игра вертикально или горизонтально.

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

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

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

Эти контакты больше не были доступны на РЭШ.

В современных китайских «Денди» и других клонах они тоже не припаяны.

Конечно, вытащить звуковой чип из картриджа нет возможности.

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



Перейдем к практике.

Так что, вроде, ничего особо сложного нет. Вам просто нужно как-то прочитать все данные по всем адресам и сохранить их в NES-файл.

Для этого я решил взять два микроконтроллера ATMEGA64. Да, это очень избыточно, но мне просто нужно огромное количество ножек — в картридже их все равно 60. Хотя память CPU и PPU не обязательно считывать одновременно, и их можно было подключить к одним и тем же ножкам, но для первого эксперимента я решил их изолировать.

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



Удаление изображений с картриджей для Dendy/Famicom/NES

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

После сборки и печати корпуса устройство получилось вот такое:

Удаление изображений с картриджей для Dendy/Famicom/NES

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

Неужели все так просто? Увы, не совсем.

Срок жизни NES и Famicom был довольно долгим, и разработчики игр очень быстро (уже в 1985 году) столкнулись с тем, что при таком подходе в картридж можно впихнуть очень мало информации.

И вовсе не из-за небольшого размера, а потому, что адресное пространство для кода было ограничено этими самыми $8000-$FFFF, а это всего 32 килобайта.

В этот размер умещаются только самые простые игры, такие как «Battle City», «Ледолаз», «Утиная охота», «Тетрис», «Lode Runner».

Проще говоря, все то, что мы привыкли видеть на сборниках типа «9999999 в 1» с повторяющимися играми.

Поэтому картографы начали ставить в картриджи.



Удаление изображений с картриджей для Dendy/Famicom/NES

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

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

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

То же самое касается и видеопамяти.

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

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

Но существует несколько сотен различных картографов и способов их подключения.

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

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

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

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

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

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

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

Кстати, в картриджах было всё.

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

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

Я решил реализовать хотя бы игры для чтения на самых популярных мапперах.

Клиентскую часть дампера я пишу на C#, поэтому просто описал интерфейс IMapper и класс, соответствующий каждому мапперу:

Удаление изображений с картриджей для Dendy/Famicom/NES

В каждом реализованы методы дампа данных.

Вот как выглядит метод чтения программной памяти игры на маппере MMC3:

   

public void DumpPrg(FamicomDumperConnection dumper, List<byte> data, int size) { dumper.WritePrg(0xA001, 0); byte banks = (byte)(size / 0x2000); for (byte bank = 0; bank < banks-2; bank += 2) { Console.Write("Reading PRG banks #{0} and #{1}.

", bank, bank+1); dumper.WritePrg(0x8000, 6); dumper.WritePrg(0x8001, bank); dumper.WritePrg(0x8000, 7); dumper.WritePrg(0x8001, (byte)(bank | 1)); data.AddRange(dumper.ReadPrg(0x8000, 0x4000)); Console.WriteLine("OK"); } Console.Write("Reading PRG banks #{0} and #{1}.

", banks-2, banks-1); data.AddRange(dumper.ReadPrg(0xC000, 0x4000)); Console.WriteLine("OK"); }

Если кому интересно, описание этого маппера можно прочитать здесь: wiki.nesdev.com/w/index.php/MMC3 Я решил попробовать побыть в шкуре первопроходцев и сбросить картридж с таким необычным меню:

Удаление изображений с картриджей для Dendy/Famicom/NES

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

Вскоре я нашел нужную мне инструкцию:

Удаление изображений с картриджей для Dendy/Famicom/NES

После этого я прочитал картридж еще раз, предварительно записав по адресу $B600, и получил полностью работоспособный ПЗУ .

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

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

Еще мне попался лицензионный картридж одной из самых знаковых игр того времени — «The Legend of Zelda».

Без проблем работает и с дампером и с Фамиком через простой пассивный переходник.

Нет смысла бросать эту игру; меня это интересовало и в другом смысле.

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

Эта память находится в диапазоне $6000-$7FFF. Я попробовал прочитать его и скормить эмулятору.

Он это понял без проблем.

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

Это сработало.



Удаление изображений с картриджей для Dendy/Famicom/NES

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

Многие наверняка спросят, зачем я вообще за это взялся, когда в интернете можно найти практически любой ROM. Да, просто из любопытства и самообразования.

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

Но об этом в следующий раз.

Ссылки на источники: github.com/ClusterM/famicom-dumper — сам дампер (исходники на C, разводка платы, 3D модели корпуса) github.com/ClusterM/famicom-dumper-client — клиент на C# Теги: #nes #famicom #Dendy #avr #dump #dumper #dumper #dumping #reverse Engineering

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.