game-and-watch-retro-go/

Game & Watch: Super Mario Bros — это портативная игровая консоль, выпущенная Nintendo в 2020-м году по случаю 35-и летия игр про Марио. Консоль напоминает игры Game & Watch из 80-х годов , но имеет цветной дисплей. Спустя год вышла аналогичная игровая консоль Game & Watch: The Legend of Zelda . Оба устройства имеют по три игры. Две из них — игры соответствующей серии (Марио / Зельда) под Famicom, и еще одна игра в стиле Game & Watch из 80-х. Вскоре энтузиасты научились прошивать больше трех игр. Этим мы сегодня и займемся.

Важно! Повторяйте описанные шаги на свой страх и риск. Автор данных строк, ровно как и разработчики соответствующего софта, не несут ответственности за ваш потенциально окирпиченный Game & Watch.

Закупаемся

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

Портативная игровая консоль Game & Watch: Super Mario Bros

Мне больше нравятся цвета этой версии. Устройство действительно напоминает геймпад от Famicom. Также, в Марио я хоть немного играл, в отличии от Зельды. Подставка была напечатана на 3D-принтере . Модель подставки доступна здесь .

Помимо самого G&W нам понадобится программатор STLink, а также виртуалка или ноутбук с Linux . Разработчики скриптов, которые мы будем использовать, рекомендуют Ubuntu или совместимые дистрибутивы. Поддержка MacOS не заявлена. Я использовал ноутбук с Ubuntu 22.04 LTS.

На Raspberry Pi версии ≤3 повторить описанные шаги не выйдет. Некоторые зависимости не удастся скомпилировать из-за ограниченного количества памяти.

Наконец, нам понадобится чип MX25U51245GZ4I00. Он доступен на AliExpress. Чип представляет собой 64 Мб SPI flash памяти. В моем устройстве всего лишь 1 Мб флеш-памяти (Зельда имеет 4 Мб), и много игр в нее не записать. Поэтому чип будем перепаивать.

Замена SPI flash памяти в Nintendo Game & Watch

На приведенной иллюстрации сверху показан оригинальный чип ( даташит [PDF] ), а снизу — тот, который будем впаивать на замену ( даташит [PDF] ). Они имеют разные корпуса, но совместимы по пинам. Первый чип может быть заменен на второй без модификации платы.

Ставим зависимости

На Linux-ноутбуке говорим:

mkdir game-and-watch
cd game-and-watch

Ставим зависимости:

sudo apt install p7zip-full python3-pip gcc-arm-none-eabi
binutils-arm-none-eabi stlink-tools libtool pkg-config
libusb- 1.0 0 -dev libhidapi-hidraw0 libftdi1 libftdi1- 2

Еще нам понадобится пропатченная версия OpenOCD :

git clone git @ github.com:openocd-org / openocd.git
mkdir openocd-git
cd openocd
wget «https://raw.githubusercontent.com/kbeckmann/ubuntu-openocd-»
«git-builder/master/0001-Extend-bank1-and-enable-bank2-»
«of-STM32H7B0VBTx.patch»
git am < 0001-Extend-bank1-and-enable-bank2-of-STM32H7B0VBTx.patch
. / bootstrap
. / configure —prefix = / home / eax / game-and-watch / openocd-git
—enable-stlink
make -j4
make install

Затем объявляем такую переменную окружения:

export OPENOCD = «/home/eax/game-and-watch/openocd-git/bin/openocd»

С ее помощью скрипты найдут правильную версию OpenOCD. Рекомендую сразу добавить эту строчку в ~/.bashrc .

Бэкапимся

С обратной стороны устройства выкручиваем 4 самореза. Здесь понадобится трехгранная (Y-образная) отвертка. Внутри видим следующее:

Внутренности игровой консоли Nintendo Game & Watch

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

Отстегиваем аккумулятор. Разъем вынимается вверх, а не в сторону. Теперь наша задача — припаяться к SWD пинам. Они выведены справа от микроконтроллера:

Распиновка SWD в игровой консоли Nintendo Game & Watch

У Зельды распиновка та же, только справа есть два дополнительных контакта. Отмеченные выводы подключаем к соответствующим пинам программатора. STLink подключаем к ноутбуку, сам G&W запитываем штатным образом, через разъем USB-C, от внешнего источника питания. Устройство должно быть включено и показывать время.

Выполняем команды:

git clone —recurse-submodules
git @ github.com:ghidraninja / game-and-watch-backup.git
cd game-and-watch-backup
. / 1 _sanity_check.sh stlink mario

Должны увидеть:

Running sanity checks…
Looks good!

Далее:

. / 2 _backup_flash.sh stlink mario

В случае успеха увидим:


Validating checksum…
Looks good! Successfully backed up the (encrypted) SPI flash to ⏎
backups/flash_backup_mario.bin!

Далее:

. / 3 _backup_internal_flash.sh stlink mario

Следуем инструкциям. В конце должны получить:


Dumping internal flash…
Verifying internal flash backup…
Device backed up successfully

На этом шаге в каталоге backup/ должно быть три .bin файла. Это очень важные файлы. Они позволят раскирпичить устройство, если во время прошивки что-то пойдет не так. Сохраните их в надежном месте.

Теперь нужно зажать боковую кнопку на G&W и выполнить:

. / 4 _unlock_device.sh stlink mario

Ожидаемый вывод:


Unlocking device… (Takes up to 30 seconds.)
Congratulations, your device has been unlocked. Just a few more steps!
— The Game & Watch will not yet be functional
— Disconnect power from the device for the changes to take full effect
— Power it again
— Run the 5_restore.sh script to restore the SPI and Internal Flash.

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

. / 5 _restore.sh stlink mario

Скрипт должен вывести:


Restoring SPI flash…
Restoring internal flash…
Success, your device should be running the original firmware again!
(You should power-cycle the device now)

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

Перепаиваем SPI flash

Есть больше одного способа перепаять чип. Лично я воспользовался паяльным феном. Плату нужно излечь из пластикового корпуса и заклеить каптоном (термоскотчем) все, кроме самого чипа. Ставим температуру 300 градусов и среднюю силу обдува. Прогреваем чип, снимаем его пинцетом. Удаляем остатки припоя с помощью оплетки.

Чтобы впаять новый SPI flash, нужно залудить контактные площадки и нанести побольше флюса. После этого новый чип легко впаивается тем же феном. Отклеиваем каптон, отмываем плату изопропиловым спиртом, помещаем плату в корпус.

Далее говорим:

cd ..
git clone git @ github.com:BrianPugh / game-and-watch-patch.git
cd game-and-watch-patch
pip3 install -r requirements.txt
make download_sdk
cp .. / game-and-watch-backup / backups / flash_backup_mario.bin . /
cp .. / game-and-watch-backup / backups / internal_flash_backup_mario.bin . /

Удерживая боковую кнопку на устройстве, выполняем команду:

make PATCH_PARAMS = «—device=mario» LARGE_FLASH = 1
ADAPTER =stlink flash_patched

Здесь выводится много разного текста. Главное, чтобы в конце было:


Info : 4-byte address parameter table
Info : valid SFDP detected
Info : flash1 ‘sfdp’ id = 0x3a25c2 size = 65536 KiB
Error: FSIZE in DCR(1) doesn’t match actual capacity.
** Programming Started **
Warn : Adding extra erase range, 0x900d7000 .. 0x900dffff
** Programming Finished **

Отмечу, что у меня получилось не с первого раза. Если теперь обесточить устройство и снова его включить, мы должны увидеть часы. Таким образом, был получен тот же G&W, что и раньше, только с 64 Мб флеша.

Прошиваем Retro-Go

Retro-Go — это открытый (GPL 2.0) эмулятор ретро-игр для устройств на основе ESP32. Существует порт под G&W, которым мы и воспользуемся. Точнее говоря, мы воспользуемся форком с более симпатичным интерфейсом, чем в апстриме.

Говорим:

cd ..
git clone git @ github.com:olderzeus / game-and-watch-retro-go.git
cd game-and-watch-retro-go
git submodule update —init —recursive

В каталог roms/ нужно положить ROM’ы с играми. В roms/nes/ идут ROM’ы для NES (a.k.a. Famicom), в roms/md/ — для Sega Mega Drive (a.k.a. Genesis), и так далее. Хороший сборник с играми для NES называется GoodNES, а для Sega Genesis — GoodGen. Заинтересованным читателям предлагается найти их самостоятельно, в качестве упражнения. Другие платформы на данный момент меня не сильно интересуют, быть может, кроме ZX Spectrum . Однако в Retro-Go он не поддерживается, ровно как и Commodore 64. Вероятно, потому что это ПЭВМ с клавиатурой, а не игровые консоли с геймпадом.

Если вы хотите, чтобы у игры была обложка, рядом с ROM’ом нужно положить файл PNG с разрешением 160 x 160 пикселей и 8-и битным RGB цветом. Файл должен иметь то же имя, что и ROM, с точностью до расширения. Например:

-rw-r—r—  1 eax eax 2097152 Mar 26 17:15 ‘Sonic and Knuckles.md’
-rw-r—r—  1 eax eax   33212 Mar 26 17:44 ‘Sonic and Knuckles.png’

Обложки к играм есть на Википедии. Для их редактирования подходит Gimp.

Когда ROM’ы и обложки готовы, говорим:

make clean

# Команда `make clean` не удаляет закэшированные .img/.lzma файлы,
# поэтому удаляем их самостоятельно:
find . / roms / -type f -name «*.img» -delete -print
find . / roms / -type f -name «*.lzma» -delete -print

make romdef

Будет выведен список игр и найденных обложек. Если он выглядит похожим на правду, собираем Retro-Go:

make -j4 COVERFLOW = 1 GNW_TARGET =mario EXTFLASH_SIZE_MB = 63
EXTFLASH_OFFSET = 1048576 INTFLASH_BANK = 2 flash

Сборка займет некотороые время и завершится с ошибкой, потому что команде не удастся прошить устройство. Теперь зажимаем боковую кнопку на G&W и повторяем последнюю команду. Должны увидеть, что G&W прошивается:

Прошивка новых игр на Nintendo Game & Watch

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

Когда процесс завершится, выдергиваем и снова подаем питание. Должны увидеть дэфолтную прошивку с Марио. Если теперь одновременно нажать кнопки «game» и «влево», мы должны попасть в эмулятор с новыми играми.

Заключение

Если вы планируете часто загружать новые игры, то SWD можно вывести на разъем USB-C. Данный разъем используется только для питания устройства. Поэтому мы можем спокойно воспользоваться пинами D+ и D- (номера 6 и 7 из 12-и пинов разъема). Данная модификация наглядно показана в этом видео . В своем экземпляре я так и сделал. Иметь для этого микроскоп, как советует автор видео, желательно, но по моему опыту не обязательно.

Таким образом, мы получили действительно классную портативную игровую консоль. И что с ней теперь делать? Можно просто играть в любимые игры. А можно портировать перечисленные скрипты на MacOS, законтрибьютить в Retro-Go, или даже попробовать писать игры для Famicom . Как обычно, все ограничено лишь вашей фантазией.

EnglishRussianUkrainian