Billet #007 - 9 juin 2026
Implémentation d'une bascule D avec des portes logiques et connexion au 6502
Je suis bloqué avec le 6522 que je ne parviens pas à faire fonctionner. Pour essayer de générer de nouvelles idées je revisionne la vidéo de Ben Eater sur le VIA. Comme nous l’avons vu, la raison pour laquelle le 6502 ne peut pas piloter directement des périphériques est que les données envoyées sur le bus ne sont présentes que pendant un cycle d’horloge. Il faut donc quelque chose qui capture la donnée et la garde en mémoire. Dans des vidéos précédentes Ben Eater a expliqué comment construire des bascules de type RS ou D. Ce sont des circuits très simples qu’on peut réaliser avec quelques portes logiques et capables de mémoriser une donnée et la mettre à jour en fonction de différents signaux. La bascule RS prend en entrée un signal set qui active la sortie et un signal reset qui la désactive. La bascule D elle possède un signal de donnée et un signal d’horloge, et la donnée est capturée à chaque front montant de l’horloge. C’est exactement ce qu’il nous faut ici.
Je revisionne la vidéo sur la bascule D et implémente le circuit sur une nouvelle petite breadboard. J’utilise un 74LS02 et un 74LS08 qui contiennent respectivement 4 portes NOR et 4 portes AND. Il y a pas mal de connexions à faire et il faut être vigilent car les pins ne sont pas disposées de la même manière sur les deux puces. Pour éviter de me tromper je dessine le schéma au brouillon et notes les pins à connecter. J’ajoute deux LEDs pour visualiser l’état de la sortie (une pour la sortie normale et une pour la sortie inversée).
Comme d’habitude je teste en contrôlant manuellement les signaux d’entrée. Au début ça ne fonctionne pas, mais c’est parce que j’avais oublié de connecter ensemble les deux rails d’alimentation de la breadboard, un oubli malheureusement courant. Une fois corrigé ça fonctionne parfaitement : sur un front montant du signal d’horloge, la donnée présentée sur le signal d’entrée est capturée sur la sortie. Modifier le signal d’entrée n’affecte pas la sortie tant que l’horloge ne bouge pas. Contrairement à un verrou (latch en anglais), qui met à jour la sortie continuellement tant que le signal Enable est à 1, une bascule ne capture la donnée qu’à l’instant où l’horloge passe de 0 à 1. Je confirme que c’est bien le cas chez moi.
Le fonctionnement dans notre circuit sera le suivant : L’entrée de la bascule est connectée à une des 8 lignes du bus de données. Quand on veut changer l’état de la bascule, le CPU place la donnée à envoyer sur le bus de données. Ensuite, le signal d’horloge déclenche la capture de la donnée par la bascule. Si on s’arrête là, la bascule capture toute les données qui passent sur le bus, et le CPU n’a aucun moyen de l’en empêcher. Il faut ajouter un équivalent du Chip Select expliqué précédement, c’est-à-dire utiliser les lignes d’adresses pour n’activer la bascule que lorsque le CPU utilise une adresse qui lui est affectée. Avant de réfléchir à ça, je veux déjà tester que la bascule fonctionne bien avec le bus de données. Je vérifie dans la datasheet du 6502 que les données sont bien présentes sur le bus au moment du front montant de l’horloge, et c’est bien le cas. Ça devrait donc fonctionner.
Je branche donc l’entrée de la bascule sur la ligne D0 du 6502 et le signal d’horloge sur PHI2. Je reprends le programme de test utilisé précédemment qui est encore dans la ROM et calcule ce qu’on devrait observer. Voici le résultat :
| Adresse | R/W | Données | D0 |
|---|---|---|---|
0xFFFC |
R |
00 |
0 |
0xFFFD |
R |
80 |
0 |
0x8000 |
R |
A9 FF |
1 1 |
0x8002 |
R |
8D 02 40 |
1 0 0 |
0x4002 |
W |
FF |
1 |
0x8005 |
R |
A9 02 |
1 0 |
0x8007 |
R |
8D 00 40 |
1 0 0 |
0x4000 |
W |
02 |
0 |
0x800A |
R |
A9 05 |
1 1 |
0x800C |
R |
8D 00 40 |
1 0 0 |
0x4000 |
W |
05 |
1 |
0x800F |
R |
4C 05 80 |
0 1 0 |
J’alimente le circuits, et je vois tout de suite que la bascule s’anime, c’est bon signe. Je reset le CPU et j’observe attentivement. Après un reset le CPU prend 7 cycles d’horloge pour s’initialiser, on devrait donc voir la séquence prévue commencer 7 cycles après avoir lâché le bouton reset. Comme d’habitude c’est l’Arduino qui fournit le signal d’horloge et on peut utiliser le fait qu’il clignote à chaque changement d’état de l’horloge pour suivre l’exécution du programme. Ça demande un peu de concentration mais c’est très satisfaisant de constater que le bascule change d’état exactement aux moments prévus !
La bascule fonctionne donc bien mais pour l’instant elle capture tout ce qui passe sur le bus, ce qui n’est pas très utile. Il faut donc ajouter un peu de logique pour qu’elle ne capture que les données qui lui sont destinées. Pour pouvoir réutiliser le programme existant, je décide d’utiliser A15 et A14 pour pouvoir sélectionner l’adresse 0x4000. Je prends aussi en compte le /RW pour ne répondre qu’aux commandes d’écriture. Dans notre cas ce n’est pas forcément nécessaire vu que la bascule ne peut que recevoir des données, pas en envoyer. L’idée est d’ajouter des portes logiques ET avec les signaux d’entrée de la bascule pour que le signal reçu par celle-ci ne passe que lorsque les bonnes conditions sont réunies. Ma première idée est de mettre le ET sur la donnée, mais je me rends vite compte que c’est une erreur. C’est le signal d’horloge qu’il faut bloquer, car c’est lui qui capture la donnée. L’idée c’est que la donnée en entrée va varier au gré de ce qui passe sur le bus, mais la bascule ne va capturer cette donnée que lorsque les signaux d’activation sont présents. Le reste du temps aucun signal de capture ne parvient à la bascule.
Si on résume, on veut donc que la capture ne se fasse que si toutes les conditions suivantes sont réunies :
A15 = 0A14 = 1/RW = 0PHI2 = 1
Il faut donc connecter sur le signal de capture le résultat de l’expression suivante :
CLK = /A15 ET A14 ET /RW ET PHI2
Je n’ai pas utilisé toutes les portes logiques disponibles sur les puces pour faire la bascule. Il reste 1 NOR et 2 AND, et si besoin on a encore 5 inverseurs sur le puce utilisée pour le Chip Select de la ROM. Voyons ce qu’on peut faire avec ça.
Voici la table de vérité de la porte NOR :
a |
b |
a NOR b |
|---|---|---|
0 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
On constate que :
a NOR b
est équivalent à :
/a ET /b
Si on réarrange les termes de notre expression on peut écrire :
CLK = (/A15 ET /RW) ET A14 ET PHI2
En utilisant l’équivalence NOR/ET on peut transformer :
CLK = (A15 NOR RW) ET A14 ET PHI2
On utilise ainsi une porte NOR et 2 portes ET, exactement ce qu’on a sous la main, c’est parfait. Je réalise le montage mais avant de tester je reprends le programme et détermine ce qu’on devrait observer. Cette fois la valeur de la bascule ne devrait changer que lorsque le CPU envoie une écriture sur une adresse comprise dans la plage 0x4000-0x7FFF, ce qui donne ça :
| Adresse | R/W | Données | LED |
|---|---|---|---|
0xFFFC |
R |
00 |
0 |
0xFFFD |
R |
80 |
0 |
0x8000 |
R |
A9 FF |
0 0 |
0x8002 |
R |
8D 02 40 |
0 0 0 |
0x4002 |
W |
FF |
1 |
0x8005 |
R |
A9 02 |
1 1 |
0x8007 |
R |
8D 00 40 |
1 1 1 |
0x4000 |
W |
02 |
0 |
0x800A |
R |
A9 05 |
0 0 |
0x800C |
R |
8D 00 40 |
0 0 0 |
0x4000 |
W |
05 |
1 |
0x800F |
R |
4C 05 80 |
1 1 1 |
Comme tout à l’heure il faut se concentrer pour suivre le déroulement du programme, mais on voit que ça fonctionne !
Interfacer une bascule D au 6502 n’était pas prévu initialement mais ça s’est révélé très intéressant et ça m’a aidé à comprendre ce qui peut se jouer dans les puces qui communiquent sur un bus de données, comme la ROM ou le VIA. Je suis très content d’avoir fait ce petit détour.
La suite
Le 6502 peut désormais piloter une LED et changer son état selon la logique définie par le programme. Ça reste bien sûr limité mais c’est déjà un bon système simple à émuler. Mais avant, je voudrais rendre les choses encore un petit peu plus intéressantes en ajoutant la possibilité pour un utilisateur d’injecter des données dans le système via un bouton. L’idée est donc de créer cette fois un périphérique d’entrée, c’est-à-dire capable d’envoyer une donnée sur le bus lorsque le CPU le demande. Après ça je pourrai enfin créer des programmes interractifs et attaquer l’émulation à proprement parler.
J'utilise des outils à base d'IA générative pour rédiger et/ou traduire le contenu de ce site. J'utilise l'IA comme un outil de productivité et d'inspiration, je m'assure toujours que les textes finaux reflètent fidèlement ma voix.