Si vous vouliez que je fasse une démonstration de CP / M fonctionnant sur un Altair 8800 émulé, je sortirais une petite carte de ma poche. Vous vous demandez peut-être comment je me suis retrouvé avec un Altair 8800 qui exécute CP / M (même WordStar), qui tient dans votre poche et coûte moins de 10 $. Il s’avère que c’est une histoire qui remonte à 1975.
Lorsque l'Altair 8800 est arrivé en 1975, j'en voulais un. Mal. J'avais lu sur les ordinateurs mais je n'avais aucune expérience pratique. Mais à l'époque, en ce qui me concerne, le prix de 400 $ aurait tout aussi bien pu être d'un million de dollars. Je travaillais sans salaire réel dans le magasin de ma famille, mais en toute honnêteté, ajusté en argent d’aujourd’hui qui était d’environ 2 000 $.
J'adorerais en acheter un maintenant, mais un véritable Altair coûte encore plus cher aujourd'hui qu'à l'époque. Ils occupent également beaucoup d'espace de bureau. Bien sûr, il existe des répliques et j'en ai eu quelques-unes. J’ai même aidé à résoudre les problèmes du clone de Vince Briel que j’ai apprécié. Cependant, l'ordinateur Briel a deux problèmes. Tout d'abord, il faut un peu de travail pour piloter un port série (il utilise un VGA et un clavier PS / 2). Deuxièmement, même s'il est plus petit qu'un véritable Altair, il est toujours assez grand – un sous-produit de son magnifique panneau avant.
Donc, pour montrer rapidement CP / M à quelqu'un, vous devez sortir une grande boîte et trouver un moniteur VGA et un clavier PS / 2 – qui sont tous deux en train de disparaître. J'ai fait quelques modifications pour faire fonctionner le port série, mais il reste encore beaucoup à faire. Vous pouvez emprunter la voie du logiciel avec un simulateur comme SIMH ou Z80pack, mais maintenant, au lieu de trouver un moniteur VGA et un clavier PS / 2, vous devez trouver un ordinateur sur lequel vous pouvez installer le logiciel. Ce que je voulais vraiment, c'était un appareil simple et portable capable de démarrer CP / M.
La solution ESP32
La bibliothèque FABGL permet à l'EPS32 de piloter un moniteur VGA et fournit également des capacités de type terminal à l'aide d'un clavier PS / 2. Il couvre également de nombreuses autres fonctions, comme travailler avec un système de fichiers flash ou une carte mémoire externe. L'un des exemples est une émulation Altair 8800 adaptée d'un autre projet open source. La carte VGA32 est conçue pour fonctionner avec la bibliothèque et est très peu coûteuse. Cela a pris un peu de travail, mais l'émulation Altair a bien fonctionné sur la carte, donc j'ai fini avec un remplacement de 10 $ pour l'ordinateur Briel qui tient dans ma poche. Le seul problème était qu'il avait encore besoin d'un moniteur VGA et d'un clavier PS / 2.
Je voulais changer un peu le code pour pouvoir utiliser le port série et en raison de la belle conception de l'émulateur, il s'est avéré non seulement relativement facile mais aussi assez simple d'autoriser les deux modes – vous pouvez conduire un VGA ou utilisez-le via le câble USB avec un programme de terminal série normal.
L'émulation
Avant d’entrer dans les changements, examinons l’émulation telle qu’elle existait avant de commencer à la bricoler. Fabrizio – le FAB de FABGL – avait certainement trouvé un joli design. Le fichier principal Arduino Sketch organisait la configuration de l'Altair et comprenait des images de disque que vous pouvez monter en lecture seule ou en lecture-écriture.
Le seul problème que j'ai rencontré était que l'émulation utilisait certaines fonctionnalités qui ne semblent pas être dans la bibliothèque que l'IDE Arduino installe via le gestionnaire de bibliothèque. Le responsable prétend avoir la version 1.8 qui correspond à ce qui est sur GitHub, mais il y avait toujours des symboles non résolus lors de la création de l'exemple.
La solution consistait à supprimer la bibliothèque existante, à télécharger l'intégralité du référentiel GitHub sous forme de fichier ZIP, puis à demander au gestionnaire de bibliothèque de l'installer à partir de l'archive. Après cela, tout s'est bien passé. Si vous voulez faire l'installation, vous pouvez aussi bien commencer par mon fork, afin que vous puissiez obtenir l'exemple de code Altair mis à jour.
La couche d'abstraction suivante se trouve dans le fichier machine.cpp du répertoire / src. Ce fichier a une couche d'abstraction matérielle pour les émulations CPU réelles dans un fichier différent. Le fichier machine.cpp contient le code permettant de gérer la mémoire, les lecteurs de disque, les périphériques d'E / S et d'exécuter les programmes.
Le code CPU est en deux parties. Il existe une émulation 8080 originaire de Viacheslav Slavinsky et une émulation Z-80 par Lin Ke-Fong. Il y a eu des modifications, mais dans l'ensemble, ces fichiers ne sont que la logique d'émulation.
Lorsque vous exécutez le code, il essaie de trouver une carte SD, mais s’il n’en trouve pas, il utilisera la mémoire flash interne pour l’émulation du lecteur de disque. Il a tout le code du chargeur de démarrage et fonctionne à peu près comme un véritable Altair, bien que sans panneau avant, bien sûr. Il existe un menu d'émulation que vous pouvez afficher avec la touche Pause du clavier. Bien que cela ne nous fasse pas beaucoup de bien sans un clavier connecté. Bien évidemment, cela ne nous fera pas grand-chose sans un clavier PS / 2 connecté.
Dans le menu d'émulation, vous pouvez vider et lire les données du périphérique de perforation et de lecture. Cependant, les disques CP / M ont également des utilitaires que vous utilisez pour les fichiers XModem dans les deux sens vers votre PC. Vous pouvez également faire des choses comme sélectionner le processeur 8080 vs Z80 et définir la vitesse d'émulation.
L'enquête
J'ai commencé à fouiller dans le code pour voir à quel point il serait difficile d'ajouter le port série. Il s'avère que la configuration a la configuration du port série mais l'utilise comme dispositif de poinçon / lecteur CP / M. Dans le code, il y a trois lignes qui relient différents flux aux périphériques SIO0, SIO1 et SIO2. Les périphériques de console (SIO0 et SIO1) sont définis sur le flux de terminal fourni par FABGL. SIO2 utilise le flux série standard.
C'était un bon signe, et bien sûr, le flux terminal est compatible avec le flux série. Par simple expérience, je viens de changer les références du terminal en série. Le système a démarré et m'a donné une invite CP / M sur le terminal série.
Cela a laissé quelques problèmes mineurs. Sans clavier PS / 2, il n'y a aucun moyen d'accéder au menu d'émulation. De plus, le menu d'émulation était câblé au terminal. Il était raisonnablement facile de résoudre ces deux problèmes.
Correction du menu d'émulation
Il n'y a qu'un seul bouton utilisateur sur la carte VGA32, il était donc logique de l'utiliser pour appeler le menu d'émulation sur le port série. Il n’a pas été difficile de modifier le code qui l’appelle (dans machine.cpp):
IRAM_ATTR int Machine::nextStep(CPU cpu) { auto keyboard = fabgl::PS2Controller::instance()->keyboard(); static int inmenu=0; if (m_menuCallback && keyboard->isVKDown(VirtualKey::VK_PAUSE)) m_menuCallback(0); // check for menu if (!digitalRead(USER_BUTTON)) { if (inmenu==0) { inmenu=1; m_menuCallback(1); inmenu=0; } }
Avec ce changement, le rappel du menu d'émulation obtient un argument supplémentaire et cet argument est défini en fonction de la méthode d'entrée. Le problème est que vous devez modifier le fichier principal. J'ai pris en compte le code que le menu utilise pour lire le clavier dans une fonction getChar. Il apparaît les borniers jusqu'à ce que vous appuyiez sur une touche, mais le port série ne le fait pas, il a donc fallu un petit changement pour que cela fonctionne correctement.
Pour minimiser les changements de code, j'ai changé toutes les références de Terminal à CONSOLE et ajouté cette ligne au début de la fonction emulator_emu:
Stream &CONSOLE=stream?(Stream &)Serial:(Stream &)Terminal;
Utiliser une référence signifie que je n’ai pas eu à changer tous les points en flèches, ce qui aurait été le cas si j’avais utilisé un pointeur.
Double personnalité
Le dernier changement que je voulais faire était de permettre au code original de fonctionner afin que vous puissiez toujours utiliser le VGA et le clavier. J'ai pensé créer un nouvel élément dans le menu d'émulation mais j'ai décidé d'utiliser à nouveau le bouton utilisateur à la place. Au démarrage, le code examine l'état du bouton. Avec le bouton vers le haut, la carte démarre en mode série. Si le bouton est enfoncé, la carte configure le terminal VGA et attend que le bouton se relâche:
if (!digitalRead(USER_BUTTON)) { streamsel=0; // TTY SIO0.attachStream(&Terminal); // CRT/Keyboard SIO1.attachStream(&Terminal);
// Série
SIO2.attachStream (& Serial);
}
autre
{
streamsel = 1;
// ATS
SIO0.attachStream (& Serial);
// CRT / Clavier
SIO1.attachStream (& Serial);
// Série
SIO2.attachStream (& Serial);
}
// attend le relâchement du bouton
while (! digitalRead (USER_BUTTON));
Plaisir Open Source
Ceci est un excellent exemple de la façon dont vous pouvez tirer parti du travail d’autres. Les émulateurs provenaient de différentes sources et Fabrizio a fait un excellent travail en fournissant des composants réutilisables. C'était très simple de modifier le code pour faire ce que je voulais faire.
Est-ce que j'écris ce message en utilisant WordStar? Peut être. N'oubliez pas que vous aurez besoin de la bonne émulation de terminal ou que vous souhaiterez installer les disques WordStar sur un disque en lecture-écriture pour pouvoir exécuter WSChange et choisir le type de terminal dont vous disposez.
Pour quelques dollars, c'était un excellent moyen d'avoir un ordinateur CP / M amorçable avec de nombreuses options. L'idée ne se limite pas non plus à l'ESP32, car vous pourriez certainement assembler quelque chose en utilisant l'Arduino. Ce n’est peut-être pas tout à fait la même chose que de construire la vraie chose à partir de zéro, mais c’est certainement beaucoup moins cher.