Programmation de la GameBoy
Modification apporté sur le logiciel GBDK.
- Pourquoi modifier les Sources GBDK ?
GBDK offre la possibilité de dialoguer avec le port GameLink par le biais de deux fonctions :
Send_byte() et Receive_byte().
Nous allons tout d'abord etudier ces deux fonctions et ensuite nous vous expliquerons pourquoi et comment nous avons modifier les sources de GBDK pour repondre à notre probleme qui est de permettre la communication avec nos cartes interfaces.
Les fonctions Send_byte() et receive_byte() :
- Les variables utilisées pour l'émission et la réception d'un octet
_Io_out : donnée à émettre.
_Io_in : réception de la donnée
_io_status : Etat du port.
_Io_status==_IO_SENDING =>émission OK.
_Io_status == IO_RECEIVING =>réception OK ;
- Send_byte() : Cette fonction permet d'envoyer un octet sur le port GameLink.
Exemple : On désire envoyer le contenu de la variable 8 Bits A sur le port GameLink.
_Io_out=A; //On place l'octet a envoyer dans la variable _io_out
Send_byte(); //On la dirige vers le GameLink
while (_io_status==IO_SENDING) ; //On attend que l'info soit traitée
Le GameBoy émet une trame de 8 bits cadencés par son horloge interne.
- Receive_byte() : Cette fonction permet de lire un octet sur le port GameLink
Exemple : on désire lire un octet provenant du port GameLink et la placer dans la variable A.
Receive_byte() ; //On se met en attente de lecture sur le port ; While(_io_status==IO_RECEIVING) ; //On attend que l'info soit disponible dans le registre l'entrée.
A=_io_in; //On place la valeur dans la variable A ;
Le GameBoy reçoit une trame de 8 bits cadencés par une horloge externe.
Les fonctions Send_byte() et Receive_byte() sont utilisées lors d'un échange entre deux GameBoy par le GameLink.
La particularité du GameLink est de gérer l'émission et la réception simultanément. Durant a transfert, un bit est émis en même temps qu'un bit est reçu. La vitesse de ce décalage est déterminée par la fréquence de l'horloge. Si on utilise l'horloge interne, un bit est reçu toutes les 122 microSecondes. Le bit le plus significatif est émis en premier et il est également reçu en premier.
Les fonctions Send_byte() et Receive_byte() permettent d'effectuer une liaison en Half-Duplex. Un GameBoy parle pendant que l'autre écoute.
La carte Test fonctionne différemment, durant l'écriture sur les sorties, nous lisons en même temps les Entrées et vis versa (Fonctionnement Full Duplex). Par conséquent, les fonctions Send_byte() et Receive_byte() ne répondent pas au problème posé. En effet, si après avoir envoyé une donnée nous essayons de lire la donnée reçue (_io_in), nous nous apercevons que le résultat ne correspond pas a l'état des entrées. En fait, nous nous sommes aperçus, lors d'essais en half-duplex que la valeur que nous lisons correspond en réalité à la dernière valeur reçue quand la GameBoy était un mode réception.
Nous avons donc crée une fonction qui permet de réaliser la lecture et l'écriture simultanées des entrées et des sorties. Pour la réaliser, nous nous sommes inspirés de la fonction Send_byte(). Dans un premier temps, nous avons modifié la fonction Send_byte() et une fois que tout a fonctionné normalement, nous avons regarder comment faire pour ajouter une fonction sur GBDK. La fonction que nous avons crée se nomme RW_byte(). Elle est écrite en assembleur tout comme Send_byte() et Receive_byte(). Ensuite nous avons regardé comment GBDK fonctionne pour attacher une fonction C a une routine assembleur.
Les routines Send_byte() et Receive_byte()sont situées dans le fichier SERIAL.S Nous y avons inséré notre fonction RW_byte().
Les format de fonctions C sont dans le fichier GB.H, nous y avons également inséré notre fonction
· SERIAL.S Ce qui a été ajouté dans cette routine :
;; Lecture et écriture sur la carte_IO
.rw_byte:
_rw_byte:: ; Banked
LD A,#.IO_SENDING
LD (__io_status),A ; Store status
LD A,#0x01
LDH (.SC),A ; Use internal clock
LD A,(__io_out)
LDH (.SB),A ; Send data byte
LD A,#0x81
LDH (.SC),A ; Use internal clock
LD A,#.IO_RECEIVING
LD (__io_status),A ; Store status
LDH A,(.SB)
LD (__io_in),A
RET
· GB.H En prenant pour exemple la déclaration des fonctions Send_byte() et Receive_byte(), nous avons ajouté :
/* ************************************************** */
/** Send byte in _io_out to the serial port */
void
send_byte(void);/** Receive byte from the serial port in _io_in */
void
receive_byte(void);
/** Lecture et Ecriture sur la carte */
void
rw_byte(void);
Méthode de compilation
- Une fois l'ensemble de ces modifications effectuées, il faut recompiler le fichier SERIAL.S
Taper la commande suivante :
- lcc -c -o serial.o serial.s
Le fichier serial.o doit ensuite être copié dans les répertoires suivants :
- gbdk\ lib\medium\asxxxx\gb
- gbdk\lib\small\asxxxx\gb
Le programme
pour les cartes 16E/16S.
Le
programme de test du module Série.
Précédent Retour Au Sommaire Suivant