La quête de la Cartouche Idéale

Jan 5, 2009 Author Gatchan

Depuis l’apparition des premières cartouches GBA permettant de lire des données à partir d’une carte SD ou Compact Flash, beaucoup de personnes se sont mises à rêver d’un équivalent pour la SNES, console ô combien populaire. Dans le cas des cartouches flash "pures" (uniquement à base de mémoire réinscriptible), il y a bien eu la cartouche Tototek de Tomy, malheureusement plus disponible, et ne fonctionnant qu’avec un port parallèle. Il y a aussi un projet de Mash-Mods, qui ressemble fortement à la Tototek, le port USB en plus. Et je ne compte pas les tentatives qui parsèment les différents forums du net. D’autres alternatives existent, comme mettre des eprom dans les cartouche, et de les reprogrammer dès que nécessaire, mais rien en ce qui concerne l’utilisation d’une quelconque carte mémoire.
Bien sûr, beaucoup de personnes sont intéressées, mais peu de projets ont dépassé le stade d’idée. Neoflash nous annonce une cartouche depuis plus de trois ans maintenant, mais ils restent constants dans leurs rapports avec les clients (futurs ou passés) : déplorables.
Mon article ne va rien changer à cet état de fait (j’en entend deux soupirer au fond :D), mais j’ai voulu m’intéresser aux méthodes permettant de concevoir une telle cartouche. Vous ne verrez donc pas l’ombre d’un typon, ni même un embryon de schéma électronique. Que du texte, et aucune image (là, j’ai perdu les 3/4 de mon auditoire! 😉 ) Avant toute chose, sachez que je n’ai aucune intention de fabriquer une telle carte. Je n’ai ni le temps, ni les ressources nécessaires (surtout le temps!). Par contre, je reste disponible pour des précisions ou d’autres questions. Inutile de dire que je serai le premier intéressé par ce genre d’appareil ^_^!

L’indispensable.

Trois composants sont indispensables :

  • La mémoire flash. Elle contiendra le menu de boot. Sa taille dépendra du nombre de fonctions à implémenter, mais 1 Mo parait suffisant (2 Mo si il faut de beaux graphismes pour le menu 😉 )
  • La SDRAM. "16 MB should be enough for everything". Le bus d’adressage de la SNES fait 24 bits, soit 16 Mo. Si on ôte les zones relatives à la RAM, et aux registres de la console, on atteint une taille maximale de 96 Mb (12 Mo). Mais comme une puce mémoire de cette taille n’existe pas, on choisi 16 Mo. J’écris SDRAM, mais n’importe quelle RAM assez rapide (plus de 120 ns) pourra fonctionner. Même celle peuplant de la RAM EDO!
  • Le CPLD (ou un FPGA, selon la complexité). Son rôle principal sera de faire le lien entre tout ce bon monde. Il sera l’interface entre la console, et les composants de la cartouche (SDRAM, FLASH, et les autres composants éventuels).

On peut rajouter les composants suivants :

  • SRAM, pour sauvegarder des données (sauvegardes de jeux, paramètres en cours).
  • Microcontrôleur, pour aider à la gestion des composants, ou simuler des puces additionnelles.
  • Et bien sûr un lecteur de carte SD (ainsi que sa carte). Il faut faire attention à la consommation électrique de tous ces composants, pour ne pas abimer la console.

Les points importants

La carte SD.

La carte SD est plus qu’une simple mémoire. Elle contient un microprocesseur chargé de la communication, et de la gestion d’erreurs. Elle dispose de trois modes de communication, dont deux très proches. Pour plus de détails, consultez les documents mis à disposition.

Le mode SD est composé de deux sous-modes différents : SD 1 bit et SD 4 bits. La différence tient dans le nombre de lignes utilisées. Encore une fois, pour plus de précisions, lisez les docs.
Le troisième mode, SPI (Serial Peripheral Interface), est le plus simple d’utilisation. Compatible avec les MMC, il compense sa vitesse plus faible comparé au mode SD par une utilisation plus facile. Le protocole SPI est très simple à mettre en oeuvre. Je reviendrait plus tard sur l’utilisation de la carte SD avec un exemple pratique.

Le mapping

Les cartouches de SNES ne fonctionnent pas de la même façon. On entend parler de ‘hirom’ et ‘lorom,’ et des raccourcis sont souvent pris (du genre "les lorom sont pour les roms dont la taille est inférieure à 3Mo, les hirom pour le reste"). C’est un peu plus complexe que ça.
Nintendo parle de "mapping", et les nomme "20" et "21". Il existe des variantes, qui ne sont utilisées que lorsque la cartouche contient un chip additionnel, ou qu’elle réclame une plus grande taille de mémoire (qui a dit Tales of Phantasia ?).

Pour déterminer le mapping d’une rom, l’émulateur bsnes calcule différentes choses, et selon ces résultats, ce mapping est définit.
Par exemple, le checksum de la rom est d’abord calculé. Dans la rom, il n’est pas placé au même endroit (0x7fc0 + 0x1e pour une lorom, 0xffc0 + 0x1e pour une hirom). Bsnes va donc lire à ces deux endroits, et si l’un des deux contient la même valeur que le checksum calculé, alors il y a plus de chance que le mapping corresponde.
Ce type de calcul est fait pour chaque élément du header (a ne pas confondre avec le header généré par un copieur) : le nom du jeu, le type de rom, la taille de la rom, de la ram, la région, la société, etc… Zsnes et Snes9x, quand à eux, essaient de "deviner" quel est le mappeur utilisé par le jeu. Ces méthodes, même si elles fonctionnent, ne sont pas les plus fidèles. L’idéal serait d’avoir une base de donnée où, à chaque rom (calculé via son CRC) est associé un pcb, et donc un "mapping". Une discussion à ce sujet à lieu actuellement sur le forum de Zsnes, dans la partie relative à bsnes.

Après avoir défini ce mapping, il faudra faire pointer les adresses mémoires au bons endroits. Pour les connaitre, il faut soit regarder les sources de bsnes (src\smemory\mapper\generic.cpp), soit regarder le fichier PCB de Overload (la dernière version est toujours disponible avec l’émulateur Super Sleuth). Ensuite, il faut lire dans le header si le jeu contient de la sram, ainsi que sa taille.

Ceci fait, il faut maintenant configurer le CPLD pour qu’il dirige les lignes vers les bonnes destinations : vers la ROM, en prenant compte des zones "mirror" (des copies d’autres zones), vers la SRAM (en faisant attention à avoir exactement la bonne taille prévue, pour contourner les éventuelles protections), et vers la console.

Sur la SNES, ce sont des multiplexeurs, comme le MAD-1 qui s’occupent de ça. Voici d’ailleurs un fichier qui explique le fonctionnement de ce dernier. Les informations sur les mappeurs peuvent être soit enregistrées directement dans le menu de la cartouche, soit, à l’instar de la cartouche NES Repropack, dans des fichiers décrivant le fonctionnement de ces mappeurs. Cette dernière solution est la plus flexible, elle permet à la cartouche de reconnaitre n’importe quel jeu exotique, sans avoir à obtenir une nouvelle version du menu (ainsi, même certains jeux BS pourront fonctionner sans patch).

La mémoire (SRAM, SDRAM et mémoire Flash).

Là encore, le CPLD doit s’occuper de tout. A l’allumage de la console, le signal doit être redirigé vers la mémoire flash, et donc le menu de la cartouche. Ensuite, il doit y avoir des entrées/sorties pour communiquer avec la SDRAM et la carte SD, c’est à dire des registres que l’on peut lire et/ou écrire. Il en existe suffisament (par exemple, entre $8000 et $FFFF). La SRAM, quand à elle, doit être connectée en fonction du mapper choisi.

Voici les trois composants principaux. Il ne faut pas oublier la pile pour alimenter la SRAM. On peut rajouter encore un composant, pour avoir une cartouche idéale.

Le microcontrôleur.

Certains jeux SNES possèdent des puces additionnelles. Mais elles ne sont pas comparables en terme de complexité. Le DSP est largement plus simple que le SuperFX, qui est un véritable processeur. Et que dire du SA-1 qui est quasiment une SNES en miniature. Inutile de dire que ces deux puces ne peuvent pas être reproduites par un microcontrolleur.
Par contre, dans le cas du DSP, il est tout à fait concevable d’incorporer ses fonctions dans le microcontroleur (ainsi que ses variantes, voir le site de Overload).
Le microcontrôlleur pourra aussi éventuellement servir à piloter la carte SD.

Le logiciel (firmware)

Véritable coeur de la cartouche, il se chargera de :

  • Lire les données de la carte SD (noms des fichiers, fichiers, SRAM) et enregistrement dans la SDRAM.
  • Ecrire les données (sauvegarde de la SRAM dans un fichier, configuration) – Reprogrammation du CPLD en fonction du mapper.
  • Lancement du jeu localisé dans la SDRAM, et désactivation des registres non officiels (on peut toujours en laisser un, permettant ainsi à certains jeux de savoir si ils tournent sur la cartouche spéciale).

Lecture/Ecriture de la carte SD

C’est l’un des points les plus important, et sûrement le plus compliqué à programmer. Soit la console s’occupe de toutes les fonctions lecture/ecriture, soit le microcontrôleur l’assiste dans cette tâche. Cette dernière solution est la plus facile à mettre en oeuvre, mais la moins élégante, et source de problème (difficile à debugger si des soucis apparaissent).

La première solution est plus lente, mais pour s’en rendre vraiment compte, il faudra tester sur le hardware.
Toujours pour cette première solution, il faut comprendre qu’il faudra programmer en 65816 au moins les routines suivantes :

  • Initialisation de la carte
  • Lecture/ecriture de secteur
  • Lecture de la FAT (16 et 32)
  • Support des noms longs
  • Lecture/Ecriture de fichiers (via la lecture/ecriture de secteurs)

Pour cela, soit on utilise un compilateur C, et on compile la librairie FatFs (après programmation du module bas niveau pour la rendre compatible avec la cartouche). L’avantage de cette solution est que le travail est minimal : la librairie est assez complète, et la programmation bas niveau peut se faire assez rapidement. Le désavantage est le temps d’exécution. Selon Lint, le compilateur C n’est pas très optimisé, et après essai moi même sur cette librairie, le code est assez imbuvable.

Ou alors on fait tout à la mano, en assembleur. Pas la peine de s’enfuir, c’est largement possible.
Long, sûrement. Réclamant une certaine rigueur, assurément, mais possible.
Prenez l’exemple de Oliver Achten pour sa cartouche MMC64. Voici un autre exemple de TNT/Beyond Force, toujours en assembleur.

Voici un autre exemple de Sasq, toujours pour le MMC64, qui implémente le support de la FAT 16.
La solution idéale est donc de tout programmer en assembleur. Une bonne modélisation de l’application, avec tous les modules nécessaires, accompagné de Xkas, et d’une bonne structuration des fichiers permet des miracles. J’insiste sur la modélisation de l’application, car elle fonctionnera sous forme de couches, du bas niveau (avec les E/S) vers le haut niveau (l’affichage). Si chaque fonction est bien pensée et programmée, la mise en place finale ne posera pas trop de problèmes.

Le lancement des jeux

Le menu de boot doit permettre au moins le lancement des jeux (évidemment). En tout premier, il devra reconnaitre le mapping de la rom. Puis, il devra vérifier si un éventuel fichier de sauvegarde existe, et copier son contenu dans la SRAM. Ensuite, il recâblera le CPLD en fonction du mapping, et lancera le jeu. Le mieux est d’exécuter ces fonctions en RAM, vu qu’au moment du lancement, la zone précédemment occupée par le menu le sera par les données du jeu.

La sauvegarde

Voilà un point un peu délicat. Deux solutions sont au moins possible. Soit, lors du redémarrage de la cartouche, le menu lit la SRAM, ainsi que les informations sur le jeu précédemment lancé, et enregistre tout ça dans un fichier spécifique (nommé avec le même nom que la ROM par exemple). Soit au lancement du jeu, le menu place un hook sur la zone de la SRAM vers une fonction qui la sauvegardera dans un fichier, à chaque demande d’écriture de la part du jeu.

Les points bonus

Les jeux protégés.

Certains jeux sont protégés contre l’import, ou bien détectent si ils sont lancés à partir d’un copieur, via un test de la SRAM disponible. Ce dernier point est traité par le CPLD, qui allouera uniquement la mémoire nécessaire. Le premier point se contournera de la manière suivante : la cartouche détecte la nationalité de la console sur laquelle elle tourne (via le registre $213F), puis, elle détecte la nationalité du jeu à lancer. Ensuite, elle reprogramme le cpld pour "capturer" tous les appels à $213F, pour renvoyer la valeur que désire le jeu : PAL ou NTSC. Par contre, il est impossible de passer logiciellement la console en 50 Hz ou 60 Hz, cela se fait uniquement via les deux pin des PPU.

 

Action Replay / Game Genie

Vous connaissez certainement ces deux périphériques servant principalement à tricher dans les jeux.
Par contre, leur fonctionnement est différent : le Game Genie modifie des octets dans la zone de la ROM (en les patchant à la volée), tandis que l’action Replay peut aussi modifier des octets dans la RAM (ainsi que dans la zone de la ROM).
Cette fonctionnalité réclame beaucoup plus de travail, elle est plus longue à mettre en place, néanmoins, cela est techniquement possible.

 

Conclusion

Voici le résultat de mes recherches sur le sujet. Cela est loin d’être complet, mais reste une bonne base pour ceux intéressés par la création d’une telle cartouche. Il ne faut pas oublier qu’il faut avoir de bonnes connaissances en électronique, logique combinatoire, conception des circuits, CPLD/FPGA et informatique (spécialement la SNES et son fonctionnement) pour arriver à créer un tel projet (bien sûr, il peut y avoir plusieurs personnes avec chaqun sa spécialité 😉 ).

2 Responses į “La quête de la Cartouche Idéale”

  1. remy @ janvier 9th, 2009 08:34

    Salut gatchan,

    je sait que bon tu m’envoi des vannes comme quoi il est difficile de réaliser tel ou tel chose mais si tu ne l’avait pas remarquer, http://www.ultimate-console.fr a en projet de réaliser une tel carte ( ce qui a due te mettre la puce a l’oreille ) et je voit que tu a réaliser quelque recherche sur ce sujet la !!

  2. Gatchan @ janvier 10th, 2009 21:57

    Quel susceptible ce Remy 😉
    Je ne vois pas où je t’envoie des vannes?
    Sinon je n’ai pas mis de liens vers Ultimate-Console (comme je n’en ai pas mis vers les différents projets de ce genre que j’ai pu croiser sur Internet), tout simplement parce que pour l’instant ce sont tous des projets, et qu’aucune infos n’est publiquement disponible.

Leave a Reply:

*