Programmer le Micral N

Par Sylvain Glaize

Nous avons donc un matériel fonctionnel, une émulation fonctionnelle. Nous avons aussi de quoi communiquer avec la machine via le port série. Il est temps de prévoir quelques programmes qui pourraient être lancés.

Pour cela, il est prévu d’utiliser un simulateur de lecteur de disquette, mais cette partie là viendra dans un article futur.

Pour le moment, parlons programmation du Micral N.

Le boot

Au démarrage de la machine dans la configuration de notre exemplaire, la ROM présente sur la carte de « boot » se charge d’aller chercher des données depuis un lecteur de disquette.

Ce n’est pas obligatoire sur un Micral N, qui pourrait contenir directement un logiciel à exécuter, ou bien lire des données depuis un autre périphérique. Notre configuration semble être faite pour s’adapter à un logiciel qui peut être modifié facilement.

Ce programme de démarrage lit les 14 premiers kilo-octets de données présents sur la disquette et les copie en mémoire vive à partir des adresses basses. La carte de « boot » est alors dans un mode où la lecture de données se fait depuis la ROM, mais où l’écriture se fait en RAM pour les adresses communes.

Une fois le chargement des données terminé, le programme provoque un reset de la machine, qui est repéré par la carte de « boot » qui ne permet plus l’accès à la ROM. Ainsi, le programme venant de la disquette est entièrement disponible, et a le contrôle complet de la machine.

Le système

Nous n’avons pas de logiciel original pour cette machine, à part le contenu des deux ROMs. Cependant, il est possible d’imaginer que ces données peuvent soit constituer un programme utilisé directement soit un système d’exploitation.

Les 2 kilo-octets du moniteur en haut de la mémoire ne forment pas un système en soit. C’est un programme dans lequel on peut entrer pour opérer et debugger la machine. Mais cette partie n’est pas construite comme un système dont on pourrait appeler des fonctions prédéfinies. En fait, cette ROM moniteur pourrait être tout aussi bien remplacée par de la RAM.

Particularités du programme de boot

Ce programme, très court (199 octets utiles), utilise les deux cartes Pile/Canal. L’une d’elles est utilisée comme mémoire secondaire sous forme de pile. En effet, le 8008 n’a pas de gestion de pile en RAM comme on peut en trouver sur le Z80. Ce processeur n’a qu’une toute petite pile d’adresses, interne et non accessible, qui servent aux appels de sous-routines.

Cette carte de mémoire secondaire sert pour calculer la somme de contrôle des données lues depuis la disquette, sans avoir besoin de la RAM, qui est en train d’être remplie par ces dites données.

Cela nous apprend donc que pour écrire dans cette pile, il faut utiliser l’instruction `OUT $16` (envoyer sur le port de sortie numéro $16 en hexadécimal). Pour lire depuis la pile, il faut utiliser l’instruction `INP $6` (lire depuis le porte d’entrée numéro 6).

L’autre carte sert de buffer de lecture. Le programme y place le nombre d’octets attendus, puis demande au contrôleur de disquette de lancer la lecture. Une fois le nombre d’octets attendus reçus par la carte, celle-ci le signale, et le processeur peut alors les lire pour les traiter.

Le temps qui passe

Une autre chose intéressante de ce programme de « boot » est l’utilisation de l’horloge générée par la carte processeur. Ce fonctionnement est théoriquement optionnel, car il est possible de le désactiver. Cependant, sur notre exemplaire, il est obligatoire.

En effet, chaque coup d’horloge génère une interruption sur le 8008 qui va brancher sur le `Reset 7`, à l’adresse $38 (les habitués du Z80 reconnaîtront). À cette adresse se trouve une gestion de compteur, qui est initialisé puis lu dans une routine qui sert donc de boucle d’attente sur un temps précis.

Cette routine est nécessaire à la génération des signaux envoyés à la carte contrôleur de disquettes.

Particularités du moniteur

La première particularité du moniteur est qu’il faut l’appeler explicitement. Soit depuis un programme en RAM, soit depuis une séquence entrée par le panneau de contrôle.

Ce programme a besoin d’une plage de RAM réservée pour loger quelques variables de fonctionnement, entre $070e et $07ff. À garder en tête si l’on veut utiliser un programme en RAM en même temps que le moniteur.

Dans ces variables se trouvent sauvé l’état des registres au moment de l’arrivée dans le moniteur. À une exception notable prêt : il n’est pas possible d’accéder au pointeur d’instruction (registre PC) depuis un programme.

Une autre de ces variables sert de trampoline pour programmer un saut indirect. En effet, il n’y a pas d’instruction dans le 8008 pour faire un saut vers l’adresse contenue dans un registre. Il faut donc générer cette séquence par code auto modifiable.

Dans le moniteur, cela se fait en deux étapes : d’abord modifier l’adresse de destination d’une instruction de saut (`JMP`) à partir d’un registre. Puis de faire un saut à l’adresse absolue de cette instruction modifiée.

Cette technique est utilisée partout dans le code du moniteur, conjointement à l’utilisation de la carte Pile pour suivre les piles d’appels de sous-routine. Mon analyse est que cela permet, au prix d’une certaine lenteur, de préserver la pile d’appels interne au 8008. Il n’y a jamais plus d’une seule profondeur d’appel de sous-routine dans le moniteur.

Lire et écrire

Autre partie très intéressante du moniteur : le programme lit et écrit sur le port série. Il peut aussi lire et écrire sur un matériel pour ruban perforé. Il est même capable d’injecter en mémoire des données depuis un tel ruban.

Mais ce qui nous intéresse en premier lieu, c’est les échanges avec la carte d’entrée/sortie série.

Et ce système est très simple : en écriture, un bit est lu jusqu’à ce qu’il indique que la carte est prête à recevoir. Dès qu’elle est prête, l’octet est envoyé. Pour la lecture, c’est presque pareil : attente d’un bit signalant que la donnée peut être lue, puis lecture d’un octet jusqu’à ce que celui-ci soit différent de 255.

Le protocole, incluant le débit, est géré par la carte série. Il n’y a donc pas besoin de s’occuper de temps au niveau du processeur.

Niveau 1 : Chenillard maison

Le premier programme que j’ai écrit à destination du matériel réel a été un chenillard : un programme qui allume les LEDs du panneau de contrôle les unes après les autres.

C’est un standard. Et surtout, cela permettait de s’assurer de l’exécution du programme sans avoir à brancher la liaison série.

Comme il n’est pas possible d’accéder directement aux LEDs du panneau de contrôle, qui ne fait qu’afficher ce qui se trouve sur les bus d’adresses et de données, l’astuce classique est de faire tourner en boucle un programme qui se situe à des adresses particulières afin de générer l’affichage des bonnes LEDs.

Une petite boucle de temporisation se trouve donc aux adresses $0100, $0200, $0400, $0800, $1000 et $2000.

Le programme émet aussi sur le port série une forme ASCII du logo de l’association.

“Logo” MO5.com affiché sur la sortie série.

20230501 MicralN Emulation Panel Chenillard

Chenillard affiché sur le panneau de commande, sur l’émulateur du Micral N (les LEDs sont vertes sur l’émulateur, et non rouge comme sur le vrai matériel)

Niveau 2 : Shooting Stars

Si nous n’avons pas pu trouver de logiciel spécifiquement écrit pour Micral N, il en existe pour d’autres machines construites autour du 8008. C’est le cas du SCELBI sur lequel on peut trouver quelques programmes de jeu.

J’en ai choisi un, nommé Shooting Stars, car assez simple, et je l’ai adapté.

Le voici sur l’émulateur, en attendant de le voir tourner sur la vraie machine.

20230501 MicralN Emulation ShootingStars

Le jeu Shooting Stars, originellement créé pour le SCELBI, porté sur Micral N

Niveau 3 : un BASIC

C’est encore le SCELBI qui nous dépanne pour cette troisième expérience. En effet, une version de BASIC a été implémentée sous le nom de SCELBAL, et les sources sont disponibles et documentées.

Il a fallu quelques adaptations, mais le programme était assez bien pensé pour être modifié facilement. Il est même prévu de pouvoir y brancher des routines de sauvegarde et de chargement du programme, ce qui serait tout à fait possible sur le Micral N avec son contrôleur de disquette.

Cependant, ce n’est pas un exercice que j’ai poussé jusque-là.

En attendant, programmons en BASIC dans l’émulateur du Micral N.

20230501 MicralN Emulation Scelbal

SCELBAL, le BASIC du SCELBI, porté sur Micral N

Voilà, on y est presque. Il reste à mettre ces programmes sur l’émulateur de disquette, brancher le tout et de laisser la magie s’opérer.

Ce sera le sujet du prochain article.

En attendant, n’oubliez pas de participer à notre campagne ! https://micral.mo5.com