Aller au contenu
Eliott65wiki
Sommaire

Eliott65 pour les nuls

Vous n’avez jamais touché à un microcontrôleur ? Aucune importance. En dix minutes, une photo et quelques schémas, voici ce qu’est Eliott65 et pourquoi il est un peu particulier.

Dans cette page

1. La machine : un ordinateur 8 bits d’aujourd’hui

La Neo6502kbd est un petit ordinateur vendu par Olimex, avec son clavier dans le boîtier. Son cœur est un vrai 6502, le processeur des Apple II, Commodore 64, Oric et BBC Micro : une puce neuve, fabriquée aujourd’hui par WDC sous le nom W65C02S.

Voici la carte, sortie de son boîtier, sur notre banc :

Carte Olimex Neo6502kbd Rev.A sous tension, vue de dessus, avec une clé USB, un câble HDMI et trois fils de sonde sur le connecteur SWD1 ; des numéros repèrent les composants décrits dans la légende
  1. W65C02S (U6) — le vrai processeur 6502. Il exécute les programmes, mais n’a aucune mémoire à lui.
  2. 3 × 74LVC245 (U7 à U9) — trois aiguillages : ils font passer à tour de rôle l’adresse basse, l’adresse haute et la donnée sur les mêmes 8 fils.
  3. RP2040 (U3) — le microcontrôleur à deux cœurs ARM. Il joue la mémoire de la 6502 et fait tourner tout Eliott65 : noyau, vidéo, USB, fichiers.
  4. Flash P25Q16 (U1) — 2 Mo où dort le firmware Eliott65 quand la carte est éteinte.
  5. Hub USB FE1.1s (U5) — répartit l’unique port USB du RP2040 sur les quatre prises.
  6. Prises USB-A — clavier, clé USB, souris. Le clavier du boîtier est un clavier USB ordinaire.
  7. Sortie HDMI — l’image, produite bit par bit par le RP2040, sans puce vidéo.
  8. USB-C : alimentation et PGM — l’alimentation, et la prise PGM pour parler au PC (elle met alors le hub en pause).
  9. Connecteur SWD1 — le port de débogage : trois fils vers une sonde qui lit et écrit la mémoire du RP2040 en marche.
  10. Haut-parleur (SPK1) — un transducteur magnétique : Eliott65 lui fait jouer notes et mélodies (service SON).
  11. Connecteur UEXT — extensions I2C, SPI et série (non utilisées par Eliott65).

Photo de notre banc : la carte sous tension, clé USB branchée, sonde de débogage sur SWD1.

Ce qui surprend quand on regarde de près : il n’y a pas de puce de mémoire à côté de la 6502. Pas de ROM, pas de RAM. La 6502 n’est reliée qu’à trois petites puces d’aiguillage (repère 2), et derrière elles, à un RP2040 (repère 3), le microcontrôleur du Raspberry Pi Pico.

2. L’astuce de la carte : un RP2040 qui joue la mémoire

Un processeur passe son temps à dire « donne-moi l’octet à telle adresse » ou « range cet octet à telle adresse ». Sur un ordinateur classique, c’est une puce de mémoire qui répond. Ici, c’est le RP2040 : il écoute chaque demande de la 6502 et répond lui-même, plusieurs millions de fois par seconde. Les 64 Kio que la 6502 croit avoir sont en réalité un morceau de la mémoire du RP2040.

Qui fait quoi sur la Neo6502kbdLa 6502 n'est reliée qu'à trois aiguillages 74LVC245, eux-mêmes reliés au RP2040. Dans le RP2040 : le bus servi par PIO et DMA, la mémoire de 64 Kio de la 6502, le cœur 0 qui fait tourner le noyau et le cœur 1 qui produit l'image. Autour : la flash, le hub USB et l'écran HDMI.W65C02Sle processeursans mémoire à luibus3 × 74LVC245aiguillages8 fils partagésRP20402 cœurs ARM, 264 Kio de mémoirePIO + DMA : le bussert chaque cycle de la 6502Mémoire de la 6502 : 64 Kioun morceau de la RAM du RP2040Cœur 0 : le noyauappels système, fichiers, USBCœur 1 : la vidéoencode l'image ligne par ligneFlash 2 Mole firmwareHub USBclavier, clé,sourisÉcranHDMI
Qui fait quoi. La 6502 ne parle qu’au RP2040 ; le RP2040 fait tout le reste : la mémoire, l’image, l’USB, les fichiers. Le firmware Eliott65 tourne entièrement dans le RP2040.

3. L’idée d’Eliott65 : laisser toute la mémoire à la 6502

Sur un micro-ordinateur des années 80, le système occupe une bonne partie de la mémoire : ROM du BASIC, zone de l’écran, variables du système. Ce qui reste pour vos programmes est souvent bien moins que les 64 Kio que la 6502 sait adresser.

Puisque le RP2040 est là, à côté, avec ses deux cœurs et ses 264 Kio de mémoire, Eliott65 y installe tout le système : le noyau, les pilotes, la gestion des fichiers. Dans la mémoire de la 6502, il ne garde que 8 octets.

La mémoire vue par la 6502 sous Eliott65Sur 65 536 octets, 65 528 sont libres pour les programmes, de $0000 à $FFF7. Seuls 8 octets sont pris : la porte d'appel en $FFF8–$FFF9 et les vecteurs en $FFFA–$FFFF.65 528 octets pour vos programmes$0000$FFF78 octets : porte d'appel ($FFF8–9) + vecteurs ($FFFA–F)$FFF8–$FFFFLe noyau, les pilotes, l'écran et les fichiers vivent ailleurs : dans le RP2040.(Les 8 octets sont agrandis pour être visibles : à l'échelle, ils feraient 0,1 pixel.)
La mémoire telle que la voit la 6502 : 65 528 octets sur 65 536 sont à vous.

Ces 8 octets, ce sont :

  • 2 octets de « porte » (en $FFF8 et $FFF9) : c’est par là que les programmes demandent un service au système ;
  • 6 octets de vecteurs (de $FFFA à $FFFF) : la 6502 les exige, ils lui disent où démarrer et où aller en cas d’interruption.

4. Demander un service : la porte d’appel

Quand un programme veut afficher du texte, lire un fichier ou connaître l’heure, il fait un appel système. Avec Eliott65, cela se passe comme au guichet : on remplit un formulaire, on le glisse par la fente, on attend la réponse.

Un appel système, pas à pasLe programme range ses paramètres dans un bloc de sa mémoire, écrit l'adresse du bloc en $FFF8–$FFF9 et attend en relisant $FFF9. Le noyau, sur le cœur 0, lit le bloc, fait le travail, écrit les résultats et remet $FFF9 à zéro. Le programme repart. Environ 5 microsecondes pour un appel simple.Programme 6502Noyau (cœur 0 du RP2040)① prépare un bloc de paramètres② écrit l'adresse du bloc en $FFF8–$FFF9③ attend en relisant $FFF9LDA $FFF9 / BNElit le bloc, fait le travail,écrit les résultats dans le bloc④ remet $FFF9 à 0⑤ repart avec ses résultats≈ 5 µs pour un appel simple, soit ≈ 36 cycles de la 6502
Le programme écrit l’adresse de son « formulaire » dans la porte, puis attend. Le noyau, qui tourne sur un cœur du RP2040, fait le travail et rend la main. Le tout prend environ 5 millionièmes de seconde.

Le formulaire (le bloc de paramètres) est rangé où le programme veut, dans sa propre mémoire. Rien n’est réservé d’avance pour lui. C’est ce qui permet de ne garder que 8 octets.

5. Ce qu’on voit à l’écran

Au démarrage, Eliott65 lance un petit programme de test qui vérifie la mémoire et affiche l’état du système, puis il cherche un shell sur la clé USB : une ligne de commande où l’on tape le nom d’un programme pour le lancer.

Écran de démarrage d'Eliott65 en texte coloré sur fond bleu : titre ELIOTT65 arc-en-ciel, somme de contrôle $7F80, erreurs mémoire $0000, palette de 16 couleurs
L’écran de démarrage : le test de la mémoire est bon (0 erreur), les 16 couleurs du mode texte s’affichent. La 6502 écrit directement ces caractères dans sa mémoire ; le RP2040 les lit là pour fabriquer l’image.

Eliott65 sait aussi faire du graphisme : des décors en tuiles qui défilent et des lutins (les sprites, ces petits personnages qui se déplacent par-dessus le décor).

Écran graphique : un damier de tuiles colorées qui défile, avec huit losanges de couleur qui rebondissent par-dessus
GRAPHE.E65 : un décor de tuiles qui défile en diagonale et 8 lutins en forme de losange qui rebondissent. Le programme ne fait que changer quelques octets dans sa mémoire ; le RP2040 dessine.

6. Plusieurs programmes à la fois

Eliott65 peut faire tourner jusqu’à 8 programmes en même temps. Un seul a l’écran et le clavier (on change avec Ctrl+Tab) ; les autres continuent en arrière-plan.

Mais la 6502 n’a qu’une seule mémoire de 64 Kio. L’astuce : quand on passe d’un programme à l’autre, le RP2040 range les pages utiles du premier dans sa propre réserve et remet celles du second à leur place. Comme la plupart des programmes n’utilisent qu’une petite partie de leurs 64 Kio, cela tient.

Plusieurs programmes dans la même mémoireLa 6502 voit toujours une seule fenêtre de 64 Kio, découpée en 16 pages de 4 Kio. À chaque changement de programme, les pages non nulles du programme actif sortent vers une réserve de 31 cadres de 4 Kio, et les pages du suivant entrent. Une page entièrement à zéro n'occupe aucun cadre.Fenêtre de la 650264 Kio = 16 pages de 4 Kio010000000000000Fsortent : ses pages non nullesentrent : celles du suivantRéserve du RP204031 cadres de 4 KioAAABBBBCCCtableprogramme actif (A)programme B en attenteprogramme C en attentecadre libreUne page restée à zéro ne prend aucun cadre : un programme typique n'en remplit que 3.
La 6502 voit toujours la même mémoire. Au changement de programme, seules les pages qui contiennent quelque chose font l’aller-retour vers la réserve du RP2040.

Et si un programme ne rend jamais la main ? Le noyau l’interrompt quand même, grâce à une interruption matérielle de la 6502 (la NMI) : c’est le multitâche préemptif.

7. Éteindre sans rien perdre : l’hibernation

Puisque toute la mémoire de la 6502 est dans le RP2040, le système peut la sauvegarder dans un fichier sur la clé, avec l’état de l’écran et du clavier. Plus tard, on « lance » ce fichier comme un programme, et la machine reprend exactement où elle en était, au même octet près.

8. En résumé

QuestionRéponse courte
C’est quoi ?Un firmware, un noyau et un petit système d’exploitation pour la Neo6502kbd.
Qu’est-ce qui change ?Le système vit dans le RP2040 ; la 6502 garde 65 528 octets sur 65 536.
Ça marche vraiment ?Oui : tout ce qui est décrit ici a été mesuré et validé sur la carte.
Ça remplace quoi ?Le firmware d’origine de la carte. Les deux ne sont pas compatibles : les programmes doivent être écrits pour Eliott65.
Et ensuite ?Voir Où en est le projet.

Pour aller plus loin, chaque idée de cette page a son article : le bus, les appels système, la vidéo, le multitâche, l’hibernation. Et les mots techniques sont expliqués dans le glossaire.

Sources dans le dépôt : README.md, docs/journal/00-synthese.md, docs/etude/ETUDE-Eliott65-Neo6502kbd.md.