Game Boy en F# : comment apprendre l'informatique en codant

Pourquoi ça compte pour toi
Si tu es curieux de comprendre les fondations de l'informatique au-delà du Python/JavaScript, ce projet montre une méthode concrète : apprendre en bâtissant quelque chose de réel. C'est aussi un cas d'école pour modéliser un domaine complexe avec un bon système de types — une compétence utile même si tu ne touches jamais à F#.
Ce qu'il faut retenir
- 1.L'émulateur tourne sur desktop et web, avec son et graphismes, ~150 heures de travail
- 2.F# et son système de types permettent de réduire 512 opcodes à 58 instructions sans états invalides
- 3.Architecture simple : interface minimaliste (2 tableaux, 2 fonctions) entre le cœur et l'interface graphique
Pourquoi un jeu vidéo pour apprendre l'informatique ?
Nick Kossolapov, développeur depuis 8 ans, réalise qu'il n'a jamais vraiment compris comment les ordinateurs fonctionnent au niveau des circuits. Au lieu de construire du hardware (comme Ben Eater le propose), il choisit une approche plus accessible : émuler une Game Boy.
Pourquoi cette console ? Elle coche toutes les cases : c'est du vrai hardware, la portée est maîtrisable (pas comme émuler un PC moderne), et elle a une valeur affective (des centaines d'heures à chasser des Pokémon enfant).
Avant de se lancer, il suit « From NAND to Tetris » pour vraiment assimiler les bases : registres, mémoire, ALU. Puis il s'échauffe en construisant un émulateur CHIP-8. Quelques mois plus tard (et pas mal de 2 h du matin), Fame Boy est prêt.
L'architecture : simple mais efficace
L'interface entre le cœur de l'émulateur et l'interface graphique tient sur une poignée d'éléments :
- ▸Framebuffer : un tableau 160×144 de nuances (blanc, clair, foncé, noir).
- ▸Audio buffer : un tampon circulaire à 32768 Hz avec têtes de lecture/écriture.
- ▸stepEmulator() : exécute une instruction CPU, retourne le nombre de cycles.
- ▸getJoypadState() : la manette parle à l'émulateur, une fois par frame.
C'est tout. Cette simplicité permet au même code de tourner sur desktop et web sans modification du cœur.
Nick a calqué Fame Boy sur l'architecture réelle du Game Boy :
- ▸CPU : modélisé d'après le Sharp LR35902 réel, il ne connaît que la memory map et les signaux d'interrupt.
- ▸Memory.fs : gère la RAM, le bus entre CPU/IO/cartouche, partage VRAM et OAM avec le PPU pour les performances.
- ▸IoController.fs : concentre la logique des registres hardware (simplification par rapport au hardware réel, mais plus sûr).
- ▸Emulator.fs : le « stepper » qui orchestre CPU, timers, audio, PPU en une seule exécution séquentielle.
À noter : le hardware réel fonctionne en parallèle sur un oscillateur maître. L'émulateur, à fil d'exécution unique, exécute tout en série mais synchronisé. Les timings sont critiques : ~17500 cycles CPU par frame à 60 FPS. Nick utilise le taux d'échantillonnage audio pour piloter l'émulation quand le son est activé, et le framerate quand c'est muet.
Pourquoi F# ?
Nick ne prétend pas être un puriste fonctionnel. Contrairement à son émulateur CHIP-8 (zéro mutation), Fame Boy utilise la mutabilité sans retenue. Copier 16+ kB de mémoire un million de fois par seconde ? Non merci.
Mais F# a deux avantages majeurs ici :
- ▸
Son système de types modélise élégamment les instructions CPU. Les opcodes de la Game Boy peuvent se regrouper : Load (lire depuis mémoire), Arithmetic (incrémenter), etc. Chacun a une source (Immediate, Direct register, Indirect via HL) et une destination (Direct, Indirect). Avec des discriminated unions, on passe de 512 opcodes à 58 instructions lisibles.
- ▸
Les états invalides deviennent inexprimables. Exemple : en utilisant un type
Locgénérique, tu pourrais écrireLoad(Loc.Direct D, Loc.Immediate)(écrire un registre à une valeur immédiate), ce que le hardware Game Boy ne prend pas en charge. AvecFrometToséparés, le compilateur refuse ce code. Les tests unitaires deviennent presque inutiles : si ça compile, c'est correct.
Un cas limite : l'opcode 0x76 n'existe pas sur Game Boy réel, mais le système de types de Nick l'autorise (logiquement un NOP). Nick l'admet comme compromis acceptable.
À retenir
Ce projet n'est pas un guide pas-à-pas pour construire un émulateur Game Boy (le billet original détaille davantage). C'est une leçon sur comment apprendre les fondations en bâtissant du réel, et comment un bon langage et un bon design te font gagner du temps et t'évitent des bugs.
Si tu dois retenir un truc : plutôt que d'accumuler des tutoriels théoriques, trouve un projet concret — même ambitieux — et laisse-le te forcer à comprendre.
Essayer maintenant
Explorer le code sur GitHub →Source
Approfondir avec un guide
Pour aller plus loin
Cet article t'a donné envie d'approfondir ? Deux formations Noésis t'attendent :
Explorer les thèmes de cet article :