Hacking Game & Watch

Si vous êtes comme moi né dans les années 80, vous avez certainement connu les fameuses « Game & Watch » de Nintendo, ces petits jeux portables avec écran à cristaux liquides. Souvent simplistes et énervants, ils sont devenus à travers le temps très rares et une source de nostalgie de notre jeunesse.

Nintendo, devenus champion dans le domaine de réchauffer les restes pour notre plus grand bonheur, a ressorti en 2020 une Game&Watch Super Mario Bros, qui fut ensuite suivie d’une Game&Watch Zelda. La Game&Watch Mario est livrée relativement pauvrement avec Super Mario Bros et Super Mario Bros 2 : The Lost Levels ainsi qu’un jeu pur Game&Watch. La version Zelda est pour sa part un peu mieux pourvue avec Zelda et Zelda 2 sur NES ainsi que Links Awakening sur GameBoy (dans sa version d’origine non-DX, ce qui est un choix discutable).

Il ne fallu que peu de temps à certains hackers pour réussir à déplomber la machine et y injecter du code externe pour permettre de remplacer totalement le contenu de la flashrom et jouer à d’autres jeux que ceux prévus initialement. Le custom firmware injecté contient un émulateur (attention, pas celui employé par Nintendo) qui permet de faire tourner la plupart des consoles 8-Bit de l’époque, le STM32 embarqué dans ces Game&Watch ayant la puissance suffisante pour le faire.

Cet article, basé sur un guide existant plutôt sommaire, va détailler proprement comment réaliser chacune des étapes pour vous permettre de réaliser la même opération. Il s’adresse à un public averti qui maitrise les principes de base de Linux et qui est habitué à l’utilisation d’un Raspberry Pi mais qui est assez flegmard pour juste vouloir faire des copier/coller de commandes Linux pour arriver au résultat attendu 🙂

Prérequis:

  1. Une Game&Watch Super Mario Bros ou The Legend of Zelda
  2. Un Raspberry Pi avec ports GPIO
  3. Trois câbles Dupont (M-F)

Etape 1 : Préparation initiale du Raspberry Pi

  1. Téléchargez et installez sur votre SD la dernière version de Raspbian Lite.
  2. Configurez votre connéxion réseau (LAN ou WiFi)
  3. Activez le SSH (si vous souhaitez faire la suite des opérations depuis une autre machine)

Etape 2 : Script de préparation « All-in-one »

Toujours dans l’objectif d’atteindre l’objectif fixé en un minimum d’effort (qu’on se le dise, la flegmardise stimule la créativité), un utilisateur répondant au nickname de Kalle000 a créé un script va automatiser une grande partie des tâches du guide de base, en commençant par mettre votre système à jour puis en installant toutes les dépendances nécessaires au flash de votre Game&Watch.

On le télécharge :

wget https://raw.githubusercontent.com/Kalle000/game-and-watch/main/gw-rpi-install-script.sh

On le rend exécutable :

chmod a+x gw-rpi-install-script.sh

Et on se lance :

./gw-rpi-install-script.sh

La fin d’installation doit normalement se finir par l’erreur suivante :

Ce script n’est actuellement pas en mesure de supporter la dernière version des outils qui permettent de flasher autant la version Mario que la version Zelda.

A ce stade, nous avons donc presque tout le nécessaire pour aller de l’avant.

Etape 3 : Finalisation du setup

Nous allons customiser un tantinet notre setup afin d’ajouter des fonctionnalités manquantes à l’émulateur Retro-Go, l’émulateur employé dans ce hack. Il est en effet possible de lui faire afficher des vignettes de jeu, ce qui rend l’expérience utilisateur bien plus agréable et propre que d’afficher uniquement des listes des ROMs.

Pour ce faire:

sudo apt-get install libopenjp2-7
sudo apt-get install python3-pippython -m pip install -r requirements.txt
cd opt
cd game-and-watch-retro-go
git remote add olderzeus https://github.com/olderzeus/game-and-watch-retro-go.git
git fetch olderzeus
git checkout NewUI
git submodule update
make clean
git pull
chmod a+x scripts/*.sh

Etape 4 : Transfert des ROMs

Ne vous reste ainsi plus qu’à transférer vos ROMs dans le répertoire de la console émulée correspondante dans le répertoire opt/game-and-watch-retro-go/roms dans son format natif (non zippé, soit .nes pour la NES, .gb pour GameBoy, etc.).

Pour ma part, afin de le faire simplement via FTP, j’ai installé le serveur ProFTPd :

sudo apt install proftpd

Puis transféré les ROMs (vous pouvez également ajouter des PNG à cet instant pour enrichir l’interface finale) :

Pour ma part, j’ai sélectionné les jeux suivants qui passent dans les FlashROM de base (1MB pour Mario et 4MB pour Zelda) :

  • Game&Watch Super Mario Bros
    • GameBoy
      • Super Mario Land (World)
      • Super Mario Land 2 – 6 Golden Coins (USA, Europe)
    • NES
      • Mario Bros. Classic (Europe)
      • Super Mario Bros. (World)
      • Super Mario Bros. 2 (Europe)
      • Super Mario Bros. 3 (Europe)

  • Game&Watch Legend of Zelda
    • GameBoy
      • Legend of Zelda, The – Link’s Awakening (France)
    • NES
      • Legend of Zelda, The (Trad FR)
      • Zelda II – The Adventure of Link (Trad FR)

Etape 5 : Préparation matérielle de la Game&Watch

La Game&Watch dispose bien d’un port USB-C mais ce dernier ne sert qu’à recharger la batterie. Par défaut, aucune data ne transite malheureusement par son biais. Par chance, Nintendo a laissé sur le PCB des ports de debug qui vont nous permettre de réaliser certaines tâches pour mener à bien notre mission.

Commencez donc par ouvrir votre Game&Watch en dévissant les 4 vis triangulaires à l’arrière. Si vous n’avez pas de tournevis adapté, un petit torx peut faire l’affaire. Je vous recommande de ne pas forcer car ces petites vis s’abiment vite et elles deviendront rapidement difficile à utiliser dans le futur. Attention à ne pas perdre le bouton Power qui se ballade facilement.

Une fois ouvert, il vous faudra déconnecter la batterie en soulevant le connecteur avec précaution car nous alimenterons la Game&Watch par l’USB dans les étapes à venir.

Etape 6 : Connection du Raspberry Pi à la Game&Watch

L’opération physique suivante est très importante car le succès de l’opération en dépend. En effet, une mauvaise connection entre les deux équipements peut entrainer un flash présumément réussi de votre Game&Watch mais avec des donnes corrompues, une interruption de la procédure de flash ou même le refus total de flasher l’appareil.

Pour les besoins de ce guide, je vais détailler la façon de procéder pour la Game&Watch Mario mais la version Zelda est très similaire. Hormis un pin-out légèrement différent qui sera précisé, les opérations sont identiques.

Raspberry Pi GPIO

Commencez par connecter un câble Dupont à chaque Pin suivant de votre Raspberry Pi :

  • GPIO24 (Pin 18)
  • GPIO25 (Pin 22)
  • GROUND (Pin 39)

Et connectez les de la sorte sur votre Game&Watch :

  • GPIO24 vers SWDIO
  • GPIO25 vers SWCLK
  • GND vers GND

Pour Mario :

Pour Zelda :

Pour ressembler au final à quelque chose du genre (ghetto style, si vous avez des connecteurs type pinces croco, c’est beaucoup mieux) :

Etape 6 : Vérification du setup

Un script va nous permettre (soi-disant) de vérifier que tout fonctionne bien :

cd /home/pi/opt/game-and-watch-backup

./1_sanity_check.sh rpi mario

Ce script devrait vous retourner ceci :

Etape 7 : Backup de la FlashROM externe

Passé cette étape, nous allons ensuite faire une copie de votre FlashROM afin de pouvoir la restorer en cas de besoin.

./2_backup_flash.sh

Etape 8 : Backup de la FlashROM interne

Ensuite, une fois votre FlashROM d’origine sauvegardée, le script suivant va backuper la FlashROM interne de votre Game&Watch.

./3_backup_internal_flash.sh

Gardez bien les 3 fichiers générés à cette étape à la précédente de côté afin de pouvoir les restorer en cas de problèmes.

Etape 9 : Unlock de la Game&Watch

L’étape finale avant de flasher à proprement parlé votre Game&Watch sera de débloquer le STM32 de votre Game&Watch. Ce dernier va modifier l’état « pas de lecture externe » de votre STM32 pour permettre d’exécuter le payload fraichement injecté.

./4_unlock_device.sh

Si tout s’est bien déroulé, l’écran de votre Game&Watch devrait être d’un bleu resplendissant.

Etape 10 : Compilation de Retro-Go et flash

Nous allons désormais procéder à l’étape finale qui sera de compiler et flasher l’émulateur Retro-Go

cd ..

cd cd game-and-watch-retro-go/

make GCC_PATH=/home/pi/opt/xpack-arm-none-eabi-gcc-10.2.1-1.1/bin/ flash_all

Si vous disposez d’une FlashROM moddée (de 16, 32 ou 64MB), utilisez les commandes suivantes :

make GCC_PATH=/home/pi/opt/xpack-arm-none-eabi-gcc-10.2.1-1.1/bin/ COVERFLOW=1 COMPRESS=lzma EXTFLASH_SIZE_MB=16 flash_all

make GCC_PATH=/home/pi/opt/xpack-arm-none-eabi-gcc-10.2.1-1.1/bin/ COVERFLOW=1 COMPRESS=lzma EXTFLASH_SIZE_MB=32 flash_all

make GCC_PATH=/home/pi/opt/xpack-arm-none-eabi-gcc-10.2.1-1.1/bin/ COVERFLOW=1 COMPRESS=lzma EXTFLASH_SIZE_MB=64 flash_all

En cas de problème

En cas de problème de flash, sachez que vous pourrez toujours revenir en arrière en invoquant le script de restore de votre FlashROM.

./5_restore.sh

Si pour une raison ou une autre les scripts vous retournent des erreurs lors du flashage, c’est que la connéxion entre votre Raspberry Pi et Game&Watch n’est pas bonne. Vérifiez là et refaites des tentatives. J’ai du m’y reprendre à plusieurs reprises avant d’arriver un flash parfait.

Conclusion

Si tout a fonctionné comme il se doit, vous devriez être recompensé par le message suivant :

Et surtout :