Ze Skeud's guide sur l'asm

 
_
_Sommaire
_Introduction
_SNES
_Compression
_Megadrive
_Final Thoughts
_
 


LA SNES




Infos rapides sur la snes:
Processeur : 65816. Mode, little endian (C'est à dire, les bits sont inversés).
Le reste? Allez voir harware.txt dans le zip de snes9X :-P

On va commencer par de l'asm simple : les modification "textuelles"
Allez, un ptit titre pour illustrer ça:



La modification d'une routine de calcul de pointeur

Le jeu en exemple sera final fantasy 6 (Jap, ou Us, c'est pareil).
Vala le code (récuperé avec X65dis)

1-C0:7FBF A9 CD 
2-C0:7FC1 85 CB
3-C0:7FC3 C2 20
4-C0:7FC5 A5 D0
5-C0:7FC7 0A
6-C0:7FC8 AA
7-C0:7FC9 BF 02 E6 CC
8-C0:7FCD 85 C9
9-C0:7FCF A5 D0
10-C0:7FD1 CF 00 E6 CC
11-C0:7FD5 90 05
12-C0:7FD7 7B
13-C0:7FD8 E2 20
14-C0:7FDA E6 CB
15-C0:7FDC 7B
16-C0:7FDD E2 20
17-C0:7FDF A9 01
18-C0:7FE1 8D 68 05
19-C0:7FE4 60
LDA #$CD
STA $CB
REP $20
LDA $D0
ASL
TAX
LDA $CCE602,X
STA $C9
LDA $D0
CMP $CCE600
BCC $7FDC
TDC
SEP $20
INC $CB
TDC
SEP $20
LDA #$01
STA $0568
RTS


Moui, on va encore me dire, "tu fous des routines, sans expliquer, ca sert à rien!". mais non, mais non.
Je vais expliquer :
1. Comment on la trouve cette routine
2. Comment elle marche
Sisi, promis!



1. Comment qu'on la trouve?

Tout d'abord, vous devez savoir où se trouve le texte. Là, le texte d'intro de FF6 se situe à D0200. convertissez cette adresse en adresse SNES avec UHR par exemple. Vous obtenez CD 0000. Vous savez donc que le texte se trouve dans la "bank" CD. Mais qu'est-ce qu'une bank? C'et une zone de memoirede la snes. Elle commence à C0 pour les jeux High Rom, et à 80 pour les jeux Low Rom. Plus d'infos dans la doc d'Anus Pee.

Lancez snes9x, et après avoir fait ce que je vous ai dit plus haut, vous vous retrouvez avec un Bô fichier log. Editez le, et recherchez quelque chose comme #$CD. Ca signifie "valeur CD" et non "adresse CD" qui est écrit comme ça : "$CD" (sans les guillemets biiiien sûr!).

Si vous trouvez plusieurs #$CD; cherchez un LDA ou un LDX avant. Ca signifie que ca charge CD dans l'accumulateur ou dans X.
Mais il se peut que, pour des questions d'optimisation, le jeu ne mette pas #$CD mais $#FFCD ou $#CDFF dans la mem, cela dépend si l'accumulateur est 16 bits ou 8 bits à ce moment là (voir dans la doc de jay les SEP et REP, ou après pour plus d'infos).

Maintenant que vous 'croyez' avoir trouvé la bonne routine, essayez de changer le CD en CE par exemple, et relancez le jeu. Ca bousille le texte? C'est parfait! (enfin, façon de parler ;-) ). Ca fait quedalle? Pas de chance! Faut vite aller dans la partie "aide".



2. Comment qu'elle marche?

Ligne par ligne:
1. Transfert le bank du texte dans l'accumulateur. C'est le bank du Début du texte.
2. le met dans l'adresse memoire $CB.
3. Cette commande met l'accumulateur du jeu en mode 16 bits. Avant, c'était 8 bits (c'est pour ça que l'on avait seulement #$CD).
4. Charge la valeur de 'position' de $D0. C'est une valuer qui dit au jeu où on en est dans le dialogue : quel phrase doit être écrite après.
5. ASL multiplie par 2. on multiplie par 2 la position.
6. Cette nouvelle valeur est mise dans X, pour....
7. ...lire la table des pointeurs. En effet, à $CCE602 se situe le premier pointeur du jeu, et grâce au X, on va chercher le pointeur de la prochaine phrase.
8. Le pointeur lu (en 16 bits, vous suivez?) est mis dans $C9 (il prend donc les memoires $C9 et $CA. Souvenez vous, le bank est à $CB!).
9. On recharge encore la 'position' de la phrase....
10. ... que l'on compare à la chaine hexa qui se situe à $CCE600 (adresse SNES), et c'est 2606. Pour savoir comment le jeu calcule ça, il faut tracer pas mal de code, est ce n'est pas vraiment important. Tout ce qu'il faut retenir c'est que, après, le jeu compare cette valeur, et si...
11. ... c'est égal, alors, on ne BRANCHE pas. (BCC, brach if carry clear, mais le carry se serait mis si le résultat de la comparaison serait Oui)
12. Donc,  TDC (pas utile pour la compréhension)
13. Remet en 8 bits
14. Pour augmenter la bank de 1. En clair, avant, on était dans la bank #$CD, et maintenant, on est dans la bank #$CE
15. Encore TDC, et c'est ici que l'on a branché si le résultat de la comparaison au 10 était Non.
16. Mode 8 bits.
17. Charge 01
18. et le met dans $0568 (inutile pour la comp... c'est bon, vous avez compris ;-))
19. On retourne dans le code "normal".
En effet, cette routine est une "sous" routine, elle est appellée tout le temps pour connaitre le pointeur de la phrase suivant.
Il est appelé par ça:

$C0/A49A: 20 BF 7F     JSR $7FBF [$00:7FBF]

Vous avez compris où faire la modification pour avoir encore plus d'espace?
Non? Mais si, il suffit de changer la bank. Mettons que la rom se finisse à 300200, on l'agrandit, et on remplace #$CD par #$F0 (300200 en PC = F00000 en SNES). Ainsi, le texte peut s'agrandir, et le nombre de bank n'importe pas. (enfin, tant que ca ne dépasse pas 4 Mo!).

-------Wouuup!
Petite remarque : Meradrin à une technique pour modifier cette routine : il la transforme pour permettre au jeu de charger dans la foullée la bank et le pointeur du texte.
Cette méthode à 2 points positifs : elle permet de placer du texte n'importe où dans le jeu, avec un bon programme de réinsertion adapté pour, il serait possible de mettre des phrases dans chaque emplacement dispo dans la rom! Mais c'est juste pour dépanner! L'autre point positif .. heu.... j'en ai pas trouvé ;-)
Mais elle a un GROS défaut : elle demande de la place! un peu ironique, non? Elle serait donc inutile dans une rom de 4Mo!
Elle demande plus de place car CHAQUE pointeur 16 bits sera suivit (ou precédé au choix) du bank. La taille de la table des pointeurs serait multipliée ainsi par 1,5!
-------Whippppp!

Cette modification fonctionne pour beaucoup de jeux. En fait, si le jeu a des pointeurs, alors FORCEMENT vous aurez une routine de ce type. Le tout est de savoir la trouver. Ce sera le thème de la 2 eme partie.



A l'aide! Ta technique ne marche pas!

Si c'est votre ca, j'ai des ptite technique de secours.
D'abord, essayez de faire une recherche sur l'adresse des pointeurs. Par exemple, vous savez que la table des pointeurs se situe à 49DF, donc, vous cherchez quelque chose comme C047DF, mais pas forcément CETTE adresse, mais quelque chose approchant...
Sinon, vous lancez 2 fois snes9X, et vous cherchez à avoir 2 .log différents, c'est a dire avant l'affichage de 2 phrases différentes. Puis, vous comparez les adresses données par SNES9X. Je m'explique, avec un exemple tiré de FF6.
LDA $CCE602,X [$CC:E60E]
Vous voyez entre les crochets? Cette adresse change pour toutes les phrases, c'est le resultat de la somme de CCE602 et de la valeur contenue dans X.
Après avoir noté différents changements, vous editez et modifiez les valeurs (CCE600 au lieu de CCE602 par exemple) et vous lancez le jeu.

C'est tout pour cette partie. Je ne traiterait pas des jeux sans pointeurs, car je n'ai pas encore bossé sur de jeux sans.

C'est parti pour l'étape encore plus 'avancée' que la précedente.
En effet, ce qui est décrit ici est la BASE de ce que vous pouvez modifier en ASM.