
Si vous avez grandi dans les années 80-90
Vous vous souvenez probablement de l’Amiga 500, cette machine révolutionnaire qui nous a tous fait rêver avec ses capacités graphiques et sonores exceptionnelles. Le Motorola 68000, son processeur mythique, nous permettait de créer des démos incroyables, des jeux spectaculaires et d’explorer les profondeurs du “bare metal programming”.
Aujourd’hui, nous allons replonger dans cette époque dorée, mais avec un twist moderne : nous allons développer un programme bootable “Hello, World!” pour Amiga 500, entièrement cross-compilé sous Linux, sans avoir besoin d’un Amiga pour développer. Seulement pour tester sur le vrai hardware !
Notre objectif est de créer un programme qui :
✓ Boot directement depuis une disquette - Pas besoin d’AmigaOS, le programme se lance au démarrage de l’Amiga
✓ Affiche “Hello, World!” à l’écran - En mode graphique, texte blanc sur fond noir, centré
✓ Contrôle directement le hardware - Programmation “bare metal” des custom chips (Copper, Bitplanes, etc.)
✓ Est compilé sous Linux (Archlinux ou Ubuntu) - Workflow moderne avec des outils open source
✓ Fonctionne sur un vrai Amiga 500 - Pas seulement dans un émulateur
Qu’allons-nous créer ?
Un fichier ADF (Amiga Disk File) bootable de 880 Ko contenant :
- Un bootblock de 1024 octets qui se charge automatiquement au démarrage
- Le programme principal (~12 Ko) qui gère l’affichage graphique
- Une police bitmap 8×8 intégrée pour le rendu du texte
Prérequis techniques
- Connaissances de base en assembleur (idéalement 68000)
- Une distribution Linux (Arch ou Ubuntu)
- Un émulateur Amiga (fs-uae) avec une ROM Kickstart 1.3
- Optionnel : Un vrai Amiga 500 pour le test final !
Installation des dépendances
Sous Arch Linux
Arch Linux facilite grandement l’installation grâce à l’AUR et à pipx.
1. Installer l’assembleur
1 | # Installer vasm (assembleur 68000, syntaxe Motorola) |
Vérification :
1 | vasmm68k_mot -v |
2. Installer l’émulateur Amiga
1 | sudo pacman -S fs-uae fs-uae-launcher |
Sous Ubuntu
Ubuntu nécessite quelques étapes supplémentaires car vasm n’est pas dans les dépôts officiels.
1. Installer vasm (depuis les sources)
1 | # Dépendances de compilation |
2. Installer fs-uae
1 | sudo apt install fs-uae |
Vérification finale de l’installation
Tous les outils devraient maintenant être disponibles :
1 | $ vasmm68k_mot -v |
✓ La chaîne de compilation est prête !
Structure du projet
Créez un répertoire pour votre projet :
1 | mkdir helloworld-amiga |
Nous allons créer 4 fichiers :
bootblock.s- Le secteur de boothello.s- Le programme principalMakefile- L’automatisation de la compilationfix_checksum.py- Le calcul du checksum du bootblock

Réalisation du bootblock
Le fichier bootblock.s
Le bootblock est le composant critique qui permet à votre programme de démarrer automatiquement. Le Kickstart de l’Amiga lit automatiquement les 1024 premiers octets de la disquette au boot et les exécute s’ils sont valides.
Créez le fichier bootblock.s :
1 | ; ============================================================================= |
Explications du bootblock
Structure obligatoire (12 premiers octets)
Le Kickstart attend une structure très précise :
- Signature “DOS\0” (4 octets) : Identifie le bootblock comme valide. Le
\0indique le type de filesystem (OFS = Old File System) - Checksum (4 octets) : Somme de contrôle qui valide l’intégrité du bootblock. Elle sera calculée par notre script Python
- Rootblock pointer (4 octets) : Pointe vers le block 880 (milieu de la disquette), même si on ne l’utilise pas
Fonctionnement du code
Lorsque le Kickstart lance le bootblock, il passe deux pointeurs essentiels :
- A6 : Pointeur vers
ExecBase, la structure système principale - A1 : Pointeur vers une
IORequestpour letrackdisk.device
Notre bootblock utilise ces pointeurs pour :
- Sauvegarder tous les registres (
movem.l) - Bonne pratique pour ne pas corrompre l’état système - Configurer une lecture disque :
- Commande :
TD_READ(lire des données) - Taille : 12 Ko (24 secteurs de 512 octets)
- Destination :
$20000(adresse en Chip RAM) - Offset : 1024 octets (juste après le bootblock)
- Commande :
- Exécuter la commande avec
DoIO()- Fonction d’exec.library - Vérifier les erreurs - Le champ
IO_ERRORindique si la lecture a réussi - Éteindre le moteur - Économie d’énergie et réduction du bruit
- Sauter au programme chargé -
jmp (a0)avec A0 =$20000
Gestion du padding
Le bootblock doit faire exactement 1024 octets. La directive dcb.b remplit automatiquement avec des zéros jusqu’à atteindre cette taille.
Réalisation du programme principal
Le fichier hello.s
C’est le cœur de notre programme. Il configure directement les custom chips de l’Amiga pour afficher notre message.
Créez le fichier hello.s (je vais montrer les parties principales, le fichier complet est long) :
1 | ; ============================================================================= |
Explications du programme principal
Architecture de l’affichage Amiga
L’Amiga utilise un système de bitplanes pour l’affichage :
- Chaque bitplane est un buffer de 40×256 octets (320×256 pixels)
- Le nombre de bitplanes détermine le nombre de couleurs : 1 bitplane = 2 couleurs, 2 bitplanes = 4 couleurs, etc.
- Nous utilisons 1 seul bitplane : bit à 0 = COLOR00 (blanc), bit à 1 = COLOR01 (noir)
Les custom chips
L’Amiga 500 possède trois coprocesseurs hardware :
- Copper : Processeur de listes qui modifie les registres de façon synchronisée avec le balayage vidéo
- Blitter : Processeur de manipulation de bitmaps ultra-rapide
- DMA : Accès direct à la mémoire pour l’affichage, le son, etc.
Notre programme utilise principalement le Copper et le DMA.
Séquence d’initialisation
Désactivation complète (
$7FFF) :- Interruptions (
INTENA) - DMA (
DMACON) - Cela nous donne un contrôle total sur le hardware
- Interruptions (
Configuration de l’écran :
BPLCON0 = $1200: Active 1 bitplane et la couleurDIWSTRT/DIWSTOP: Définit la fenêtre d’affichage PAL (320×256)DDFSTRT/DDFSTOP: Contrôle quand le hardware récupère les données
Patching de la Copper list :
- La Copper list contient les instructions pour le coprocesseur Copper
- On doit lui indiquer où se trouve notre bitplane en mémoire
- L’adresse 32 bits est séparée en partie haute (
BPL1PTH) et basse (BPL1PTL)
Activation du DMA :
DMAF_MASTER: Active le DMA globalDMAF_RASTER: Active le DMA pour l’affichage des bitplanesDMAF_COPPER: Active le coprocesseur Copper
Routine de dessin de texte
La fonction DrawText est un mini moteur de rendu :
- Parcourt chaque caractère du message “Hello, World!”
- Calcule l’offset dans la police :
(caractère - 32) × 8- ASCII 32 = espace, premier caractère de notre police
- Chaque glyphe fait 8 octets (8 lignes de 8 pixels)
- Copie ligne par ligne les 8 octets du glyphe vers l’écran
- Inverse les bits avec
not.bcar notre fond est noir (bits à 1) et le texte blanc (bits à 0) - Utilise
and.bpour “creuser” les pixels blancs (bits à 0) dans le fond noir
Le Copper
Le Copper est un processeur de listes extraordinairement puissant qui a fait la réputation de l’Amiga. Notre Copper list minimale :
1 | CopperList: |
Chaque instruction est un mot de 16 bits (registre) suivi d’un mot de 16 bits (valeur).
Synchronisation VBlank
La fonction WaitVBlank est cruciale pour éviter le “tearing” (déchirement de l’image). Elle :
- Lit le registre
INTREQR(Interrupt Request Read) - Teste le bit 5 (
INTF_VERTB= Vertical Blank) - Boucle tant que le VBlank n’est pas actif
- Acquitte l’interruption avec
INTREQ
Police bitmap
Notre police 8×8 contient 96 caractères (ASCII 32 à 127). Chaque caractère est défini par 8 octets :
1 | ; Lettre 'H' (ASCII 72) |
Réalisation du Makefile
Le Makefile automatise toute la chaîne de compilation. Créez le fichier Makefile :
1 | # ============================================================================= |
Explications du Makefile
Variables d’outils
1 | ASM = vasmm68k_mot # Assembleur 68000, syntaxe Motorola |
Options de compilation
Les options passées à vasmm68k_mot sont :
-Fbin: Génère un binaire brut (pas de header Amiga)-m68000: Cible le processeur 68000 (pas les extensions 68020+)-nosym: Pas de symboles de debug-quiet: Mode silencieux
Création de l’ADF
La cible principale $(ADF) effectue une séquence complexe :
Créer un fichier vide de 880 Ko (1760 secteurs × 512 octets) :
1
dd if=/dev/zero of=hello.adf bs=512 count=1760
Écrire le bootblock aux 1024 premiers octets :
1
dd if=bootblock.bin of=hello.adf bs=512 count=2 conv=notrunc
count=2: 2 secteurs de 512 octets = 1024 octetsconv=notrunc: Ne pas tronquer le fichier de destination
Écrire le programme à l’offset 1024 :
1
dd if=hello.bin of=hello.adf bs=512 seek=2 conv=notrunc
seek=2: Sauter les 2 premiers secteurs (le bootblock)
Calculer le checksum :
1
python3 fix_checksum.py hello.adf
Cible run
Lance l’émulateur fs-uae avec des paramètres optimisés :
--amiga_model=A500: Émule un Amiga 500--floppy_drive_0=...: Insère l’ADF dans le lecteur DF0:--window_width/height: Taille de fenêtre confortable--keep_aspect=1: Garde le ratio 4:3 de l’Amiga
Cible clean
Supprime tous les fichiers générés pour repartir de zéro.
Réalisation du script de checksum
Le checksum est crucial : sans lui, le Kickstart refuse de booter la disquette !
Créez le fichier fix_checksum.py :
1 | #!/usr/bin/env python3 |
Explications du script Python
Algorithme du checksum Amiga
Le checksum du bootblock est une somme de contrôle spéciale qui garantit l’intégrité du code. L’algorithme :
- Additionner tous les mots longs (32 bits) du bootblock (256 mots longs)
- Ignorer le mot long à l’offset 4 (c’est là qu’on écrira le checksum)
- Gérer le carry : Si la somme dépasse 32 bits, ajouter le bit de carry à la somme
- Calculer le complément :
checksum = ~somme
Le résultat : la somme de tous les mots longs du bootblock (y compris le checksum) = 0x00000000.
Gestion du carry
1 | if checksum > 0xFFFFFFFF: |
Cette ligne implémente l’addition avec carry circulaire :
- Si la somme dépasse 32 bits, on garde les 32 bits bas et on ajoute 1
- C’est équivalent à l’instruction 68000
addx(add extended)
Complément à 2
1 | checksum = (~checksum) & 0xFFFFFFFF |
Le ~ inverse tous les bits (complément à 1), et le masque & 0xFFFFFFFF assure qu’on reste sur 32 bits.
Écriture Big Endian
1 | data[4:8] = checksum.to_bytes(4, byteorder='big') |
Le Motorola 68000 est big endian : l’octet le plus significatif est stocké en premier. Python gère cela automatiquement avec byteorder='big'.
Compilation et test
Compilation
Maintenant que tous les fichiers sont créés, compilez le projet :
1 | make |
Vous devriez voir :
1 | Création de l'ADF bootable... |
✓ Le fichier hello.adf de 880 Ko est prêt !
Test dans l’émulateur
Lancez le programme dans fs-uae :
1 | make run |
L’émulateur démarre, et après quelques secondes (temps de boot du Kickstart), vous devriez voir :

Résolution de problèmes courants
L’écran reste noir
✗ Problème : Le bootblock n’a pas le bon checksum
→ Solution : Vérifiez que fix_checksum.py s’est bien exécuté
L’émulateur ne démarre pas
✗ Problème : ROM Kickstart manquante
→ Solution : fs-uae télécharge automatiquement les ROMs libres, ou utilisez fs-uae-launcher pour configurer une ROM Kickstart 1.3
Le texte n’apparaît pas
✗ Problème : Adresse du bitplane incorrecte dans la Copper list
→ Solution : Vérifiez le patching de la Copper list dans hello.s
Test sur un vrai Amiga 500
Transfert de l’ADF
Pour tester sur un vrai Amiga, plusieurs méthodes :
- Disquette physique :
- Utilisez un Greaseweazle pour écrire directement sur disquette

- Gotek avec FlashFloppy :
- Remplacez le lecteur interne par un Gotek (émulateur de lecteur USB)
- Copiez
hello.adfsur une clé USB - Sélectionnez le fichier depuis le Gotek

WHDLoad / HDD :
- Si vous avez un disque dur ou un IDE68K, copiez l’ADF et montez-le

Ce que vous devriez voir
Sur un vrai Amiga 500 :
- Insérez la disquette / sélectionnez l’ADF
- Allumez l’Amiga (ou Ctrl+Amiga+Amiga pour reset)
- Le lecteur tourne pendant ~1-2 secondes
- L’écran noir apparaît avec “Hello, World!” en blanc
- Le lecteur s’arrête (moteur éteint)
C’est un moment magique ! Voir votre code tourner sur le vrai hardware après des décennies…

Pour aller plus loin
Maintenant que vous maîtrisez les bases, quelques idées d’amélioration :
Ajout d’animations
- Scrolling horizontal : Modifiez
BPLCON1pour faire défiler le texte - Effet rainbow : Utilisez le Copper pour changer les couleurs ligne par ligne
- Sprite matériel : Ajoutez un curseur ou une petite icône animée
Utilisation du Blitter
Le Blitter est le secret des performances graphiques de l’Amiga :
- Copie ultra-rapide de bitmaps
- Opérations logiques (AND, OR, XOR)
- Remplissage de zones
Son et musique
Le chip Paula de l’Amiga permet 4 canaux audio 8 bits :
- Ajoutez un petit jingle au démarrage
- Intégrez un module ProTracker
Compression
Pour des programmes plus gros, utilisez :
- Doynax LZ : Compresseur optimisé pour 68000
- Shrinkler : Excellent ratio de compression
Ressources pour continuer

Documentation officielle
- Amiga Hardware Reference Manual : La bible du développement Amiga
- Motorola M68000 Programmer’s Reference Manual : Documentation complète du 68000
Sites web
- Amiga Hardware Database : Registres et spécifications
- 68000 Instruction Set : Toutes les instructions
- EAB (English Amiga Board) : Communauté active de passionnés
Outils modernes
- Amiga Assembly (extension VS Code) : Coloration syntaxique et auto-complétion
- vscode-amiga-debug : Débogueur intégré pour fs-uae
- Photon’s m68k vscode extension : Snippets et aide
Conclusion

Nous avons parcouru un long chemin : de l’installation des outils à un programme bootable complet qui contrôle directement le hardware de l’Amiga 500. Vous disposez maintenant d’une base solide pour explorer plus en profondeur la programmation de cette machine légendaire.
Ce qui rend l’Amiga si spécial, c’est cette sensation de contrôle total sur la machine. Pas d’API abstraite, pas de couche système : juste vous et le métal. C’était l’esprit des années 80-90, et il est toujours vivant aujourd’hui grâce à la communauté rétro-computing.
Alors, qu’allez-vous créer ? Une démo ? Un petit jeu ? Une application utilitaire ? Les possibilités sont infinies, et le Motorola 68000 attend vos instructions.
💾 Le code source complet du projet sur Github
Bon codage, et vive l’Amiga !
Article rédigé avec nostalgie et passion pour le retro-computing.
Jérémy @ Code Alchimie