Remise en jambe en assembleur Z80 pour Amstrad CPC

Remise en jambe en assembleur Z80 pour Amstrad CPC

Envie de (re)plonger, quelques temps,  dans les joies du langage machine avec ce cher Amstrad CPC? C’était une excellente machine pour apprendre la programmation en assembleur, et aujourd’hui cela le reste encore. Aujourd’hui on peut considérer le Z80 comme un micro contrôleur, et intégré dans l’Amstrad CPC, il y a tout ce qu’il faut comme périphérique. Pas nécessaire d’acquérir un Arduino ou un Raspberry PI, si vous avez un CPC! Enfin, il existe une quantité impressionnante de ressources (démos, jeux, utilitaires) sur internet, grâce à des passionnés qui ont su les collecter et les archiver [1-5].
Pour les curieux et les nostalgiques, voici donc un petit tutoriel pour se remettre en jambes. Nous allons mettre en place une chaîne d’outils nécessaires pour éditer, assembler, et tester du code en langage machine.

Outillage

Il existe de nombreux émulateur (Arnold, Sugarbox, JavaCPC[6],  WinAPE[7], WinCPC[8]..) , ainsi que différents assembleurs, pour différentes plateformes. Néanmoins en ce qui concerne l’émulation et la conversion vers des disques virtuels (DSK) ou des disquettes 3.5 pouces, la balance penche pour la plateforme Windows, qui est mieux dotée.

  • Coté assembleur, j’ai opté pour l’utilisation de RASM[9] (Roudoudou’s Assembler), qui fonctionne aussi bien sous Windows ou linux. il se recompile sans difficulté. Il est très rapide, propose la possibilité de définir des macros, différents segments, voire de la compression, et est activement maintenu.  (version testée 0.74).
  • Pour l’édition du code source, notepad++, il n’y a pas grand chose a dire concernant cet excellent éditeur, si ce n’est qu’on peut trouver des profil de style pour afficher le code source assembleur Z80 avec des couleurs selon la syntaxe [10] pour repérer les mnémoniques, les labels, etc. De plus le mode d’édition en colonnes est parfois fort pratique.
  • WINCPC pour l’émulation. En plus d’une bonne qualité d’émulation (beaucoup de démo passent parfaitement), il est très pratique pour tester du code: Il est possible d’importer directement un fichier binaire, inspecter la mémoire, mettre des points d’arrêt, exécuter pas à pas le code machine… Tout cela en sachant à quel moment par rapport à la synchronisation vidéo on se situe. D’autres émulateurs peuvent être utilisés à la place, WinAPE et JavaCPC en particulier.
  • Enfin pour la conversion en DSK et le transfert sur disquettes 3.5 pouces, CPCDiskXP[11] va s’avérer très pratique. A Noter que depuis la version 0.68 de RASM, il est possible d’exporter le code assemblé dans un fichier DSK. Enfin pour le transfert disque, il faut aussi citer dskwrite, qui a l’avantage de tourner sous linux.

Premier programme

Comme premier programme, on ne va pas tout de suite se lancer tête baissée dans l’utilisation poussée Il du hardware du CPC. Nous allons commencer avec une simple fonction de remplissage de l’écran vidéo. J’aurai peut être l’occasion d’aborder des thèmes comme les rasters, l’overscan, la rupture, etc. dans de futurs billets.

Ce sera l’occasion de rappeler la façon originale dont est organisée la mémoire vidéo.Par défaut, la mémoire vidéo correspond à un bloc de 16KB (0x4000 en hexadécimal), qui commence à l’adresse 0xC000, et finit à l’adresse 0xFFFF.

Chaque ligne correspond à 80 octets de la mémoire vidéo. Mais, et c’est la ou ça devient original, les lignes ne sont pas rangées les unes après les autres: l’adresse 80 correspond au premier pixel de la 8ème ligne de l’écran, et non pas le premier pixel de la 2ème ligne. La 2ème ligne commence en réalité à l’adresse 0xC800, la 3ème en 0xD000, etc. En résumé, la mémoire vidéo doit être vue comme 8 banques de 2KB (0x800),  qui sont entrelacées en sortie vidéo.

Ce premier programme effectue plusieurs boucles pour remplir l’écran:

L’écriture est réalisée a l’instruction LD (HL),A. Cette instruction est répétée 8*25*80 fois pour des valeurs de HL qui couvrent la partie visible de l’écran vidéo. La valeur du registre A est initialisée au début du programme, et modifié à chaque bloc vidéo (RRCA). En mode 2, on voit bien le motif avec un seul pixel se décaler à chaque bloc vidéo:

Le programme n’est pas écrit pour être le plus efficace possible, mais plutôt pour être simple à comprendre et modifier. Par exemple on pourra changer le nombre de lignes, modifier le motif écrit dans la mémoire vidéo (le contenu du registre A au début, ou la façon dont il est modifié). L’appel à la routine d’attente du balayage écran peut être commenté pour que le remplissage soit beaucoup plus rapide.

Test sur émulateur

Compiler

Après avoir copié le code source dans un fichier fillscreen.asm et en supposant que rasm.exe est accessible (soit dans un répertoire référencé par la variable PATH, soit dans le répertoire de travail)

rasm.exe -i fillscreen.asm -o fillscreen

ce qui produit un fichier fillscreen.bin

Transférer

Une fois WinCPC démarré, la combinaison CTRL+F11 ouvre un menu pour sélectionner un fichier binaire a charger en mémoire. On peut aussi directement glisser le fichier .bin sur la fenêtre. Une seconde fenêtre s’ouvre et permet de choisir l’adresse a laquelle on veut charger les données. Ici, nous le chargerons à l’adresse 0x9000:

Exécuter

Dans la console du CPC émulé, l’exécution du programme se fait avec la commande call &9000

On a déja vu le résultat en mode 2. En mode 1 et 0, le motif écrit est interprété différemment:

Test sur machine réelle

CPCDisk  XP

Pour créer une image disquette (DSK), on peut utiliser CPCDisk XP, qui fonctionne sous windows, et ce, même sur les dernières versions, comme son nom ne l’indique pas. Il y a deux aspects de ce logiciel qui vont nous intéresser ici:

Le premier c’est la création de fichier DSK.

Le second, qui nécessite d’avoir un lecteur de disquette 3,5 pouces sur un PC, va servir a transferer ce fichier DSK sur une disquette, qui sera utilisable par le CPC. Il est en outre nécessaire d’installer un driver bas niveau pour le lecteur de disquette. Ce driver est fourni avec CPCDisk XP.

Création d’un DSK

En cliquant sur le bouton central DSK Editor, on accède à une fenêtre de sélection du format que l’on va utiliser. On ne vas pas chercher la complication, en acceptant le choix par défaut, qui est le format compris nativement par le CPC.

Ensuite on va ajouter un ou plusieurs fichiers au disque ainsi créé. A la question sur l’entête Amsdos, répondre « OUI », ainsi le binaire sera considéré comme exécutable, par la commande RUN. Pour que cela marche, il faut que les adresses de début du fichier et le point d’entrée soient fixés à 0x9000:


DSK directement généré par RASM

Une autre possibilité pour générer le fichier DSK, est d’utiliser la directive SAVE de RASM, qui permet des exports dans différents formats, en particulier:

SAVE "nom",start,size -> save binary
SAVE "nom",start,size,AMSDOS -> save binary with Amsdos header
SAVE "nom",start,size,DSK,"dskname" -> save binary on DSK data format

Avec start l’adresse de début, et size la taille du fichier a exporter. Par exemple, si on ajoute un label ENDOFCODE à la fin de notre code, on pourra générer un fichier fill.dsk, qui contiendra le fichier FILLSCREE.BIN:

SAVE "FILLSCREE.BIN", #9000, EndOfCode-#9000,DSK,"fill.dsk"

Test sur Emulateur

On peut tester le DSK sur émulateur, cette fois ci en insérant le disque virtuel. Le plus simple est de glisser le fichier DSK sur la fenêtre de l´émulateur. vérifier le contenu du disque avec la commande cat, et lancer la commande

run "fillscree.bin"

Normalement, il n’y a pas de différence, avec les tests précédents en émulation. Il est temps de passer à une machine réelle!

Ecriture sur Disquette 3,5 pouces

Le DSK passé sur disquette peut enfin être testé sur une vraie machine!

DSKTools

Une autre possibiité pour transferer les fichiers DSK sur disquette, consise à utiliser DSKTools[12], qui a l’avantage d’etre utilisable en ligne de commande, et qu’il tourne sous linux. Il se recompile sans difficulté, et consiste en deux executables, dskread et dskwrite.

dskwrite image.dsk

 

En guise de conclusion

Premier constat, attendu, en 2017, développer pour Amstrad CPC est très confortable.
A l’époque j’utilisais DAMS pour éditer et compiler et tester du code depuis le CPC. Le nombre de redémarrage et de rechargement, l’impossibilité de déboguer rendait la tâche sinon ardue, du moins laborieuse. Pour éviter d’endommager son CPC, il était courant d’ajouter un bouton reset[13], et éviter ainsi d’avoir à complètement éteindre et rallumer l’ordinateur, ce qui peut etre stressant pour son électronique.

Aujourd’hui, à nous les joies de la cross compilation, du test sur émulateur: Le temps de compilation, transfert en mémoire et test est raccourci, la syntaxe acceptée par les assembleurs est bien plus complète: macros, portions discontinues de code, inclusion de fichiers, compression du code généré… il est temps de s’y remettre!

Liens

Sites d’archive

Emulateurs

Outils