Для чего вообще это нужно

Коллекционирование штука странная, кто-то собирает только запечатанные экземпляры и хранит их в защитных коробках. Кто-то напротив беспощадно модифицирует свои приставки и играет именно в физические картриджи. Есть еще технические энтузиасты, по типу меня, которым просто важно разобраться, найти решение и реализовать.
FF5 можно без проблем поиграть на самом дешевом китайском flash-картридже, просто скопировав файл на флешку, но не всем это по душе.

В целом, причин можно назвать несколько:

  1. Низкая цена картриджей японского региона. В настоящее время они наиболее доступные, цена может быть от пары сотен рублей. Картриджи американского/европейского региона заметно дороже. Я использую малоинвазивный и обратимый метод локализации картриджей, в случае необходимости, можно удалить все новые микросхемы, платы-переходники и вернуть картридж в исходное состояние.

  2. Эксклюзивность некоторых игр, особенно RPG, для японского региона. В частности FF5 не выходил для американского или европейского региона. С помощью "прошивки" мы получим в коллекцию играбельный физический картридж с удобной локализацией.

  3. Есть доля игр для snes/sfc, которые выходили на картриджах с дополнительными микросхемами (на хабре была хорошая статья-перевод по этой теме: Внутри картриджей Super Nintendo). Такие игры на простых flash-картриджах не запустить, нужен либо плата-донор, либо продвинутый flash-картридж с поддержкой FX и других чипов. Лично я начал интересоваться перепрошивкой игр по этой причине.

Оригинальная плата

Оригинальная плата картриджа
Оригинальная плата картриджа

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

Дешифратор ROM P0 и P1
Дешифратор ROM P0 и P1

Дешифратор работает следующим образом: при обращении по адресам менее 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МБ.

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

  1. P0.bin - объемом 1536КБ, блоки исходного файла (0x000000 - 0x0FFFFF), (0x200000 - 0x27FFFF)

  2. 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

Программирование P0
Программирование P0
  1. Отрезаем или отпаиваем выводы maskrom P0.31 (OE#) и соединяем с Vсс

  2. Соединяем тестовую площадку WE# с SRAM.27

  3. Вывод 43 (A20) микросхемы 29f1610 соединяем с выводом 14 микросхемы U4 (74LS139)

  4. В прошивке cardreader выставляем значение маппинга 223. В программаторе выбираем "Flashrom Programmer"->"8bit Flash": Erase, Blankcheck, Write (выбираем файл P0.bin)

  5. Снимаем дамп для проверки "Flashrom Programmer"->"8bit Flash": Read

  6. Если все в порядке, соединяем WE# с Vcc

Программирование P1

Программирование P1
Программирование P1
  1. Отрезаем или отпаиваем выводы maskrom P0.31 (OE#) и соединяем с Vсс

  2. У микросхемы флеш памяти 29f800 цоколевка в части WE#, RST# немного отличается от 29f1610 для которой разводилась плата-переходник, поэтому использовать удобные тестовые площадки на плате-переходнике не получится

  3. Соединяем вывод 44 (RST#) с Vcc

  4. Соединяем вывод 43 (WE#) с SRAM.27

  5. В прошивке cardreader выставляем значение маппинга 221. В программаторе выбираем "Flashrom Programmer"->"8bit Flash": Erase, Blankcheck, Write (выбираем файл P1.bin)

  6. Снимаем дамп для проверки "Flashrom Programmer"->"8bit Flash": Read

  7. Если все в порядке, соединяем вывод 43 (WE#) с Vcc

Проверка и сборка

Готовая плата
Готовая плата
  1. Делаем сброс cardreader и снимаем дамп всего картриджа

  2. Проверяем батарею, заменяем в случае необходимости

  3. Делаем красивые фото и закручиваем винты картриджа

Проверка работоспособности на железе
Проверка работоспособности на железе
Проверка локализации
Проверка локализации

Ссылки