Le problème
J'ai fabriqué des adaptateurs permettant d'utiliser des
jeux SMS sur une console Megadrive et
jeux MarkIII/SMS-J sur une console Megadrive
. Cela
fonctionne bien, mais il y a une petite complication:
Lorsqu'un jeu est exécuté sur une console Megadrive, ce n'est pas après l'exécution
d'un «bios» comme sur une console master system. En fait, le dès la mise sous
tension, le jeu est exécuté. Cela en empêche certains de fonctionner car ils ont
été codés en assumant que le «bios» se serait déjà chargé de certaines choses,
notamment l'initialisation du pointeur de pile («stack pointer»).
Pour faire démarrer un jeu qui ne démarre pas à cause de cela, il suffit de
d'abord d'allumer la console avec un jeu fonctionnel, l'éteindre et changer
pour le jeu qui ne fonctionne pas. Mettre à nouveau la console sous tension
et il devrait démarrer. C'est que le premier jeu a initialisé le pointeur,
et malgré que l'alimentation ait été coupée momentanément, le registre de
pointeur de pile contient encore la dernière valeur utilisée!
Bien que ce truc semble bien fonctionner, ce n'est pas idéal. Il faut
répéter cette manipulation à chaque fois, et il faut aussi posséder un
jeu qui fonctionne.
La solution de Sega dans le Power base converter
Un produit équivalent à mon adaptateur a été à l'époque vendu par Sega sous les
noms
Power base converter,
Mega Adaptor(メガアダプタ),
Master System Converter ou
Adaptador Para os Jogos Master System
selon la région du monde
[1].
Il se trouve que ce produit officiel n'a pas le problème de démarrage de certains
jeux exposé dans les paragraphes précédents. Une
discussion dans le forum smspower nous apprends qu'une puce de logique programmable
simple est utilisée pour faire exécuter quelques instructions au CPU qui servent
à initialiser la pile avant que le jeu soit exécuté:
21 01 E1 : LD HL, $E101
25 -- -- : DEC H
F9 -- -- : LD SP,HL
C7 -- -- : RST $00
La même discussion nous présente également les équations de logique
qui montrent que l'adresse sur le BUS est utilisée pour présenter
les octets formant les instructions ci-dessus dans le bon ordre, et
comment un conflit d'adresse avec la cartouche est évité en faisant
passer les signaux "chip enable" via cette même puce. Voir la discussion
pour une explication technique complète.
Fait intéressant: Comme la puce de logique n'avait pas assez de sorties
pour piloter les 8 lignes de data du Bus, le bit 0 est tiré à un niveau
logique 1 via une résistance externe. Les instructions ci-dessus
ont donc tous le bit le moins significatif à 1!
[1] Source:
http://segaretro.org/Power_Base_Converter.
Ma solution avec un AVR
Je voulais règler mon problème rapidement avec le matériel dont je disposais sans
refaire le circuit imprimé de l'adaptateur à partir de zéro. J'ai donc décidé d'essayer
mon petit
circuit à usage multiple
lequel est basé sur un micro-contrôleur AVR d'atmel.
Le micro-contrôleur surveille le signal de lecture (RD) et à chaque impulsion, présente
les bits de l'instruction suivante sur le BUS (D0 à D7), jusqu'à ce que les 6 octets soient
passés, suite à quoi les broches du micro-contrôleur sont toutes mises en mode entrée
pour laisser le jeu s'exécuter sans rien perturber.
Le micro-contrôleur ne surveille pas le signal CE car il n'est pas assez rapide. Les
signaux data du bus sont pilotés continuellement, alors que normalement ils
devraient l'être seulement lorsque RD et CE sont bas. Ce n'est pas très propre, mais comme
nous contrôlons les instructions et savons qu'elles n'impliquent aucune écriture,
je ne crois pas qu'il y ait de problème.
Pour isoler le signal CE de la cartouche de jeu, j'ai installé une résistance de 1.5k entre la
megadrive et la cartouche. Le micro-contrôleur est relié au signal du côté de la cartouche.
Pour empêcher un conflit lorsque le micro-contrôleur présente les instructions d'initialisation
sur le BUS, il suffit de mettre un niveau logique 1 sur la ligne. Bien que du côté console de la résistance
ce signal soit à zéro, il n'y a pas de danger car la résistance limite le courant. Lorsque
le micro-contrôleur a terminé son travail et qu'il est temps d'exécuter le jeu, la broche
correspondant au signal CE est mise en mode entrée et le signal CE passe alors de
la console vers la cartouche de jeu via la résistance. La valeur de la résistance
est assez basse pour ne pas trop ralentir les transitions.
J'ai simplement imité ce que Sega a fait pour le bit D0, bien que j'avais encore un
bit de libre (PORTB3). Je ne me souviens pas pourquoi (car j'ai attendu trois mois
avant d'écrire cette page) mais c'était peut-être pour faciliter la programmation
lors du développement (un des signaux passe par là). Quel que soit la raison,
il y a donc présentement besoin d'avoir une résistance pull-up sur D0, mais il
serait facile de modifier le code pour l'éliminer.
Voici quelques photos du circuit installé sur l'adaptateur de cartouche. Si vous
avez fabriqué un adaptateur comme moi ou en possédez un non fabriqué par Sega qui
n'a pas de circuit d'initialisation de la pile, ce circuit peut être installé
pour rectifier la situation.
Contactez-moi si cela vous serait utile et j'ajouterai ce circuit dans mon magasin en ligne.
Le code source est disponible:
stackchip.tar.gz
Voici une version abrégée pour montrer l'essentiel:
#define WAIT_RD() do { } while (PIND & 0x04)
#define WAIT_RD_HIGH() do { } while (!(PIND & 0x04))
#define OUTVAL(a,b) do { PORTC = a; PORTB = b | 0x10; } while(0)
#define RD_SYNC() do { WAIT_RD(); WAIT_RD_HIGH(); } while(0)
...
/* LD HL, $E101 */
OUTVAL(0x10, 0x00);
RD_SYNC();
OUTVAL(0x00, 0x00);
RD_SYNC();
OUTVAL(0x70, 0x20);
RD_SYNC();
/* DEC H */
OUTVAL(0x12, 0x00);
RD_SYNC();
/* LD SP,HL */
OUTVAL(0x7C, 0x20);
RD_SYNC();
/* RST $00 */
OUTVAL(0x63, 0x20);
RD_SYNC();
// hands-off the bus
while (1) {
DDRC = 0;
DDRB = 0;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
}
Avertissement
Je ne saurais être tenu responsable pour les dommages
que l'utilisation des informations ou la mise en œuvre des instructions présentées
sur cette page pourrait causer à votre équipement,
à vous-même ou à autrui. Aussi, je ne donne aucune garantie quant
à l'exactitude des informations et à leur fonctionnement.