Для чего вообще это нужно
Коллекционирование штука странная, кто-то собирает только запечатанные экземпляры и хранит их в защитных коробках. Кто-то напротив беспощадно модифицирует свои приставки и играет именно в физические картриджи. Есть еще технические энтузиасты, по типу меня, которым просто важно разобраться, найти решение и реализовать.
FF5 можно без проблем поиграть на самом дешевом китайском flash-картридже, просто скопировав файл на флешку, но не всем это по душе.
В целом, причин можно назвать несколько:
Низкая цена картриджей японского региона. В настоящее время они наиболее доступные, цена может быть от пары сотен рублей. Картриджи американского/европейского региона заметно дороже. Я использую малоинвазивный и обратимый метод локализации картриджей, в случае необходимости, можно удалить все новые микросхемы, платы-переходники и вернуть картридж в исходное состояние.
Эксклюзивность некоторых игр, особенно RPG, для японского региона. В частности FF5 не выходил для американского или европейского региона. С помощью "прошивки" мы получим в коллекцию играбельный физический картридж с удобной локализацией.
Есть доля игр для snes/sfc, которые выходили на картриджах с дополнительными микросхемами (на хабре была хорошая статья-перевод по этой теме: Внутри картриджей Super Nintendo). Такие игры на простых flash-картриджах не запустить, нужен либо плата-донор, либо продвинутый flash-картридж с поддержкой FX и других чипов. Лично я начал интересоваться перепрошивкой игр по этой причине.
Оригинальная плата

Картридж SHVC-F5 содержит плату SHVC-2J3B-01 с двумя микросхемами масочного ПЗУ (MASKROM) суммарным объемом 2048КБ, работающих в режиме HiROM, ОЗУ (SRAM) с питанием от батарейки CR2032 для сохранений. Дешифратор SRAM на микросхеме 74LS139, дешифратор ROM на микросхеме 74LS00.

Дешифратор работает следующим образом: при обращении по адресам менее 1МБ (низкий уровень на линии A20), активируется микросхема P0, при адресах в диапазоне от 1МБ до 2МБ (высокий уровень на линии A20) — микросхема P1.
Процесс программирования не совсем тривиальный. Во-первых, локализованная версия игры больше оригинала, видимо, переводчикам пришлось использовать ��ополнительные банки памяти под ресурсы: размер оригинального rom японского региона "Final Fantasy V (Japan).sfc" — 2048КБ, размер образа с переводом (английская или русская версии) "Final Fantasy V (J) [T+Rus1.11 Shedevr (10.10.2001)][f1].smc" — 2560КБ. Второй момент, данный тип платы напрямую не поддерживается дампером cardreader, необходимо будет его доработать.
Прошиваемый образ имеет размер 2560КБ, поэтому потребуется небольшая хитрость для адресации более 2МБ, будем заменять P0 на Flash 29F1610 объемом 2МБ, а адресную линии A20 микросхемы 29F1610 придется соединить проводком с адресной линией A21 слота картриджа в подходящем месте (например, к выводу 14 микросхемы U4), вместо P1 будем устанавливать Flash 29F800 объемом 1МБ.
Исходный образ игры нужно разделить на две неравные части для прошивки в каждую микросхему отдельно, т.к. типы микросхем разные, и одновременно прошить их наш дампер не сможет:
P0.bin - объемом 1536КБ, блоки исходного файла (0x000000 - 0x0FFFFF), (0x200000 - 0x27FFFF)
P1.bin - объем 1024КБ, блоки исходного файла (0x100000 - 0x1FFFFF).
Доработка дампера cardreader
Для прошивки будем использовать дампера sanni cardreader. Элегантный способ поддержки нестандартных плат - это использование маппингов, для этого нужно доработать код в файле Cart_Reader\FLASH.ino.
Добавим в функции writeByte_Flash и readByte_Flash два новых маппинга 221 и 223 для программирования P1 и P0 соответственно:
// A0-A7
PORTF = myAddress & 0xFF;
...
// for SNES HiRom repro with 2MB+1MB (FF5.P1)
else if (mapping == 221) {
// A8-A15
PORTK = (myAddress >> 8) & 0xFF;
// A16-A23
PORTL = (myAddress >> 16) & 0xFF;
// Flip BA5(PL5) to address second rom chip
PORTL ^= (1 << 4);
// Switch SNES BA6(PL6) to HIGH to disable SRAM
PORTL |= (1 << 6);
}
// for SNES ExHiRom repro with 2MB+1MB (FF5.P0)
else if (mapping == 223) {
// A8-A15
PORTK = (myAddress >> 8) & 0xFF;
// A16-A22
PORTL = (myAddress >> 16) & 0xFF;
// Reset A20 to enable P0 rom and shift to address to A21
if ((((myAddress >> 16) & 0xFF) & 0x10)) {
// Switch A21
PORTL |= (1 << 5);
// Reset A20 to enable P0
PORTL &= ~(1 << 4);
} else if (!(((myAddress >> 16) & 0xFF) & 0x10)) {
// Reset A21
PORTL &= ~(1 << 5);
}
}
Включать нужный маппинг нужно в функции flashMenu, изменив значение переменной mapping. Далее нужно скомпилировать прошивку и прошить cardreader.
Программирование P0

Отрезаем или отпаиваем выводы maskrom P0.31 (OE#) и соединяем с Vсс
Соединяем тестовую площадку WE# с SRAM.27
Вывод 43 (A20) микросхемы 29f1610 соединяем с выводом 14 микросхемы U4 (74LS139)
В прошивке cardreader выставляем значение маппинга 223. В программаторе выбираем "Flashrom Programmer"->"8bit Flash": Erase, Blankcheck, Write (выбираем файл P0.bin)
Снимаем дамп для проверки "Flashrom Programmer"->"8bit Flash": Read
Если все в порядке, соединяем WE# с Vcc
Программирование P1

Отрезаем или отпаиваем выводы maskrom P0.31 (OE#) и соединяем с Vсс
У микросхемы флеш памяти 29f800 цоколевка в части WE#, RST# немного отличается от 29f1610 для которой разводилась плата-переходник, поэтому использовать удобные тестовые площадки на плате-переходнике не получится
Соединяем вывод 44 (RST#) с Vcc
Соединяем вывод 43 (WE#) с SRAM.27
В прошивке cardreader выставляем значение маппинга 221. В программаторе выбираем "Flashrom Programmer"->"8bit Flash": Erase, Blankcheck, Write (выбираем файл P1.bin)
Снимаем дамп для проверки "Flashrom Programmer"->"8bit Flash": Read
Если все в порядке, соединяем вывод 43 (WE#) с Vcc
Проверка и сборка

Делаем сброс cardreader и снимаем дамп всего картриджа
Проверяем батарею, заменяем в случае необходимости
Делаем красивые фото и закручиваем винты картриджа


Ссылки
Образы и информация об игре (https://www.emu-land.net/en/consoles/snes/roms/final-fantasy-v)
Дампер (https://github.com/sanni/cartreader)
KiCad и gerber для плат-переходников (https://github.com/pavelkokorin/snes_maskrom_adapters)