Triceraprog
La programmation depuis le Crétacé

  • Brève présentation de l'Intel 8008 ()

    Le 8008 d'Intel est un processeur assez particulier. C'est le premier micro-processeur 8 bits, et on peut même dire : le premier micro-processeur tout court. Son grand frère, le 4004, étant plutôt considéré comme un micro-contrôleur. D'autres sites expliquent le pourquoi de cette distinction.

    Je veux ici me pencher sur le 8008 sous certains aspects techniques. Une brève introduction d'une puce qui va en générer d'autres (8080, 8086, Z80,...)

    Cette puce, je l'ai étudiée à travers son utilisation dans le Micral N de la R2E, mais ceci est une autre histoire. Le 8008 est rapidement utilisé dans une série de micro-ordinateurs (le terme apparaît avec le Micral N) sur un cours laps de temps. Dans le désordre, MDC/70, SCELBI, Intellec-8, Mark-8, MCS 8, Bill-1,... Certaines de ces machines reçoivent très rapidement une mise à jour vers le 8080, beaucoup plus flexible. Cependant, c'est bien avec le 8008 que cela commence.

    La puce

    Et le voici en image de synthèse. Ou du moins, dans l'un des boîtiers existant, car il en existe plusieurs. C'est celui que j'avais en référence, et c'est donc celui que j'ai modélisé.

    Image de synthèse d'un 8008 avec brochage.

    Une première chose étonnante : pas de masse. Le 8008 prend du +5V et du -9V. Il semble que la raison soit une volonté d'être compatible avec des circuits électroniques 5V, mais avec un besoin d'une tension totale de 14V... Ce n'est pas trop mon rayon, alors je laisse ça en note. Pour plus de précisions, jusqu'au niveau transistor, je vous dirige vers l'analyse en anglais de Ken Shirriff.

    Branchements

    Mis à part VCC et VDD, les deux tensions nécessaires, le 8008 communique avec l'extérieur à travers 16 autres broches.

    À noter que le 8008 travaille en « logique physique inversée » par rapport aux signaux logiques : le 0 logique est à +5V, le 1 logique est entre ~0.8V et -9V.

    Broche de synchronisation

    En entrée, le 8008 reçoit en entrée deux horloges déphasées, de même fréquence (500 kHz) : Ø1 et Ø2. Ces deux horloges lui permettent de cadencer les opérations internes.

    À partir de ces impulsions, le 8008 forme en sortie le signal SYNC/ qui est haut pendant un premier cycle Ø1, Ø2, puis bas pendant un second cycle Ø1, Ø2. Le tout forme un état processeur complet.

    Vu qu'il y a un temps de 2µs entre deux fronts de Ø1, cela signifie qu'un état du 8008 dure 4µs.

    Chronogramme des horloges et de la synchro du 8008.

    Broches d'états

    Trois autres broches en sortie : S1, S2 et S3, forment un triplet indiquant dans quel état le processeur se trouve.

    Les états sont les suivants : T1 et T1I, T2, T3, T4, T5, WAIT et STOPPED.

    Les états T1 et T2 forment ensemble une demande d'information au reste du système. Lors de T1, le 8008 place la partie basse de l'adresse de l'information à obtenir sur les broches d'entrées/sorties. Lors de T2 y est placée la partie haute de l'adresse, ainsi que deux bits indiquant le type de cycle actuel et donc la nature de la donnée attendue : est-ce une instruction, une lecture ou une écriture de donnée en mémoire, ou une opération d'entrée/sortie ?

    Cette manière de placer une adresse sur le bus se fera toujours de la même manière lors de différents cycles d'une instruction, et toujours sur les états T1 et T2 : d'abord les 8 bits bas de l'adresse, puis les 6 bits haut (le 8008 a un espace d'adressage de 14 bits), complétés par 2 bits indiquant au système ce que ce couple d'information représente.

    T1I est une variante de T1 qui est utilisée lorsque le processeur a validé une interruption. L'état est le même que T1 à l'exception du traitement du compteur d'instruction (le registre interne PC), qui n'est pas avancé. Après T1I, le 8008 passera à un état T2.

    Lors de l'état T3, le processeur lit la donnée obtenue. Si c'est une instruction à exécuter, celle-ci est stockée pour les états suivants, sauf pour l'instruction HLT, qui est immédiate.

    Les états T4 et T5 sont des états supplémentaires qui existent dans certaines instructions.

    Et chaque instruction peut répéter l'ensemble de ces états dans l'ordre pour compléter son exécution. L'instruction INr (incrément d'un registre) va s'exécuter en un seul cycle avec les états T1, T2, T3, T4 et T5, pour un total de 5 états. L'instruction JMP (branchement à une adresse absolue) aura besoin de trois cycles : le premier et le second avec T1, T2 et T3, le troisième avec T1, T2, T3, T4 et T5, pour un total de 11 états.

    Chronogramme des horloges et de la synchro du 8008.

    Broches d'entrée

    Le 8008 possède deux broches en entrée en plus des deux phases d'horloges : INTERRUPT/ et READY/.

    READY/

    La broche READY/ permet de synchroniser le temps que prend l'acquisition d'une donnée avec le 8008. En effet, le cycle T3 s'attend à pouvoir lire une donnée sur les broches d'entrées/sorties. L'emplacement de cette donnée a été complètement caractérisée (emplacement et nature) lors du cycle T2.

    Pour être certain que le monde extérieur est prêt, le 8008 ne passera de l'état T2 à T3 que si READY/ est au 1 logique. Dans le cas contraire, il se placera dans l'état WAIT et patientera... Dès que READY/ est signalé par le reste du système, le 8008 reprend sa course en passant vers l'état T3.

    INTERRUPT/

    La broche INTERRUPT/, comme son nom l'indique, place le 8008 dans un état d'interruption. La gestion des interruptions par le 8008 est très rudimentaire. Lorsqu'une instruction est terminée, si INTERRUPT/ est signalée, alors le processeur passe en état T1I plutôt que T1.

    Et c'est tout !

    C'est aussi le seul moyen pour le processeur de sortir de l'état STOPPED si une instruction HLT (halt) a été exécutée. Et de la même manière, le premier état sera alors T1.

    Comme indiquée plus haut, la différence entre l'état T1 et T1I est que pour T1, le registre PC est incrémenté après l'émission de l'adresse. Pas dans le cas de T1I. L'idée est pour le système de placer sur le bus lors d'un état T1I une instruction particulière, généralement RST (Restart).

    L'instruction RST est une instruction d'un octet de taille qui permet de brancher sur une sous-routine (comme un CAL) à une des 8 adresses multiples de 8 en mémoire. Elle est faite pour être utilisée dans ce contexte.

    Le 8008 doit donc être aidé par le reste du système pour gérer des interruptions. Le processeur lui-même ne fait que le strict minimum...

    Les broches d'entrées/sorties

    Il reste 8 broches à décrire, et celles-ci fonctionnent en entrée comme en sortie. Elles forment l'interface d'échange de données entre le 8008 et le reste du système. Ces broches ne sont pas spécialisées : toute donnée passe par là, que ce soit un morceau d'adresse, une données à échanger avec la mémoire ou avec un périphérique.

    Comme indiqué plus haut, une combinaison de l'état courant du 8008 et des deux bits hauts placés en T2 sur ces broches permet de déterminer la fonction de ces 8 broches.

    Sur T1 et T2, ce sont des broches en sortie qui indiquent deux morceaux d'adresse ainsi que la nature du cycle. Sauf dans le cas d'une données adressée à un périphérique, qui se trouvera en cycle T1 du second cycle.

    En T3, ce sont des broches en entrée qui vont y lire une donnée... ou rien (dans le cas de OUT lors du second cycle).

    Les broches ne servent pas lors des autres états.

    Les registres

    Le 8008 possède des registres accessibles par le code utilisateur, ainsi que quelques registres internes, non accessibles.

    Passons sur la plupart des registres internes, qui servent au fonctionnement... interne (deux registres temporaires, celui d'instruction, de cycle,...) mais arrêtons nous sur une particularité : le pointeur d'instruction, généralement nommé PC sur les micro-processeurs, n'est pas accessible au code exécuté !

    Le PC

    En premier lieu, il faut dire que ce registre n'existe pas vraiment. Le 8008 possède une mémoire de 8 x 14 bits organisée en pile, munie de son pointeur de pile. L'adresse pointée est le PC actuel. Lors d'un branchement, l'adresse pointée est mise à jour, avec une mise à jour potentielle du pointeur dans le cas d'instruction d'appel de sous-routine (CAL par exemple).

    Cela signifie au passage que le 8008, sans aide externe et avec ses seules instructions, ne peut pas dépasser une profondeur d'appel de plus de 8. Ou plutôt, il peut, mais la mémoire étant cyclique, il ne pourra pas remonter correctement.

    Et le contenu de cette mémoire est parfaitement inaccessible. Il n'y a pas d'instruction permettant dans lire le contenu de la pile, ni le niveau du pointeur.

    Les autres registres

    Les registres accessibles sont A, B, C, D, E, H et L. Rien de très étonnant si vous connaissez le Z80 par exemple.

    A est l'accumulateur. Toutes les opérations logiques et arithmétiques se font par rapport à A, et le résultat potentiel est stocké dans A. Sauf pour les opérations d'incréments et décréments, qui ne peuvent être appliqués que sur les registres généraux qui suivent.

    B, C, D et E sont 4 registres généraux. On peut copier le contenu de n'importe lequel vers n'importe quel autre (y compris l'accumulateur). On peut même copier le contenu d'un registre vers lui-même. Et c'est d'ailleurs, par convention, la copie de A vers A (LAA) qui forme l'instruction NOP du 8008.

    H et L sont 2 autres registres généraux qui se comportent comme les précédents, mais qui ont une capacité supplémentaire. Pris ensemble, ils forme HL, nommé aussi M, un pseudo registre de pointeur vers la mémoire.

    Ainsi, l'instruction LAM copie le contenu du pseudo registre M vers l'accumulateur. Autrement dit, l'octet pointé par la paire HL est chargée dans A.

    Mot de la fin.

    Le 8008, conçu et construit par Intel, est avant tout une commande pour reproduire dans un petit volume les fonctionnalités d'un appareil existant. C'est sous cet aspect qu'il est à comprendre et comprendre une partie des choix techniques et donc de ses limitations.


  • Récréation 3D, Pascaline ()

    Depuis longtemps, très longtemps, les humains cherchent des moyens pour aider aux calculs. Blaise Pascal fut de ceux-ci, lorsqu'il conçu un modèle fonctionnel d'une machine mécanique permettant d'additionner et de soustraire des nombres.

    La Pascaline devient la première machine à calculer de bureau commercialisée (même si elle le fut à très peu d'exemplaires).

    En voici une modélisation que j'ai terminée récemment.

    une Pascaline


  • VG5000µ, Schémas de principe mis à jour en v1.4 ()

    Il y a deux ans et demi, je publiais ici une remise au propre du schéma de principe de la documentation du VG5000µ.

    Cette première version a été mise à jour avec la découvertes d'erreurs, ou de précisions à apporter.

    Cette fois-ci, c'est l'œil exercé de 6502man du forum system-cfg qui, lors de la réparation d'un VG5000µ, m'a fait parvenir des corrections. Et je le remercie ici à novueau.

    Les modifications par rapport à la v1.3 sont :

    • retirer la broche A14 de la ROM 7802 et les broches A13 des deux RAM en accès direct par le Z80, 7804 et 7805. Du copier coller raté très probablement.
    • correction d'un inversion des broches 26 et 28 sur la ROM 7802. Le +5V arrive sur 28.
    • inversion des broches 4 et 5 de la porte NAND fournie par 7812. Les broches indiquées sur les versions précédentes sont fidèles au schéma de la documentation, mais le relevé sur le matériel montre le contraire. Il est possible qu'il existe différente carte mère, mais je donne la priorité à un relevé vérifié. D'un point de vue logique, inverser les branches d'une porte NAND ne change rien.
    • ajout de la mention 4Mhz sur la sortie HP du VDP 7801, pour plus d'information lors de la recherche de panne.

    Ce qui donne, mis à jour.

    La platine principale

    Image cliquable pour une version en haute définition. (mise à jour 29 avril 2021)

    Platine principale

    La platine K7/Son

    Image cliquable pour une version en haute définition. (mise à jour 9 sept. 2018)

    Platine K7/Son


  • Programmer sur Nintendo Switch en BASIC ()

    « Petit Computer » est un environnement de programmation qui est apparu initialement sur la Nintendo DSi. Cet environnement se programme dans un dialecte de BASIC du nom de « Smile BASIC ». Et c'est sous le nom « Smile BASIC v4 » qu'il est disponible en version numérique sur l'eShop de la Nintendo Switch.

    Après un lancement un peu chaotique en Europe au printemps 2020, à cause d'une erreur dans la classification d'âge il semblerait, il a été à nouveau disponible. Une fois téléchargé et après avoir branché un clavier et une souris en USB sur la Switch, la console se transforme en ordinateur programmable en BASIC. Et c'est amusant !

    Un environnement presque à l'ancienne...

    Au démarrage, on est pris en main avec des explications sur l'environnement. Les explications ne sont pas très poussées, et même après avoir parcouru le très bavard tutoriel, je pense que des apprentis programmeurs resteront un peu sur leur faim.

    Ah, une autre précision : le logiciel n'existe qu'en anglais et en japonais.

    Niveau documentation, le site officiel donne une référence plutôt complète, et trois PDFs d'explications parcellaires qui donnent quelques idées du fonctionnement.

    Très pratique cependant, l'aide en ligne est disponible et est très complète. F1 après un mot clé donne les explications. F1 sans mot clé amène au manuel général.

    Malgré tout cela, au début, on retrouve un peu la sensation d'une machine à l'ancienne : il semble y avoir plein de possibilités, mais il va falloir les découvrir en tâtonnant, et faisant des essais. En ce sens, « Smile BASIC » est ludique.

    Cloud et Partage

    Moyennant l'achat d'un « ticket » supplémentaire à l'achat du logiciel, on peut sauvegarder et surtout partager ses créations sur un serveur dédié à la communauté Smile BASIC. Et puisqu'il y a partage, il est aussi possible de télécharger les créations des autres, pour s'en inspirer, les modifier ou tout simplement y jouer.

    Sans le ticket, on ne pourra charger qu'une seule création toutes les huit heures, et pas partager les siennes.

    Par contre, pas moyen d'échanger des données avec le monde extérieur, comme un PC. Ou du moins pas simplement. Ce qui est créé dans Smile BASIC reste dans Smile BASIC. Cela inclus le code BASIC tout autant que les musiques, sprites,...

    Ça ressemble à quoi ?

    Lorsque l'on passe en mode « création », on arrive sur un écran qui ne dépayse pas lorsque l'on est habitué de vieilles machines.

    La résolution de l'écran est de 400 par 240, mais cela peut se changer jusqu'à du 720p.

    Note: mes captures bavent à cause de mon périphérique d'acquisition, ce n'est pas le cas de l'image en sortie de la Switch, qui est très bonne.

    Le mode direct de Smile Basic 4

    En mode direct, on peut taper des commandes et voir le résultat. Il est possible de dessiner grâce à des primitives telles que point, ligne, cercle, rectangle ou triangle. Le système propose aussi un système de sprites avec collisions possibles et de la composition de plans d'affichages.

    Cela peut commencer très simple, mais être poussé assez loin.

    Commandes de dessin avec Smile Basic 4

    Et pour créer ces sprites, ou n'importe quel dessin, un logiciel de pixel art est disponible sur F10.

    Editeur graphique Smile Basic 4

    La programmation est sans numéro de ligne. On bascule dans un éditeur de texte pour entrer un programme résident. Il est possible de sauver les fichiers bien entendu, et d'en rappeler d'autres. Le tout, comme je le mentionnais, avec une aide en ligne.

    L'aide en ligne Smile Basic 4

    Conclusion pour le moment

    « Smile BASIC » est plutôt sympathique. On est un peu perdu en arrivant dessus la première fois, mais à force d'essais, de lectures de la référence et de l'aide en ligne, on peut commencer à faire des petites choses sympa.

    Le système, bien qu'assez complet, n'est pas là pour pousser la Switch à fond, ce n'est pas le but. L'idée est plutôt de s'amuser à programmer dans un environnement simple, avec des outils et ressources clés en main (il y a aussi des effets sonores et des musiques disponibles de base).

    La communauté à l'air assez réduite hors Japon cependant, c'est un peu dommage, mais assez compréhensible.

    Un petit programme


  • Automatisation : utilisation de Visual Studio Code ()

    Il y a presque trois ans (déjà !), j'avais mis en place un environnement de programmation pour me permettre de mettre au point un programme en assembleur Z80 et de l'envoyer vers MAME, afin de réduire le nombre d'opérations manuelles. Le tout à partir de Sublime Text 3.

    Peut-être parce que la documentation de cet éditeur n'est pas des plus détaillée, ou peut-être parce que c'est avant tout un éditeur de texte, les extensions autour de l'assembleur Z80 sont peu nombreuses. C'est plutôt du côté de Visual Studio Code que ces extensions sont apparues.

    Récemment, j'ai donc fait deux changements dans ma chaîne de mise au point pour VG5000µ. Tout d'abord, j'utilise à présent Visual Studio Code comme éditeur, et ensuite, j'ai changé d'assembleur.

    Visual Studio Code

    Tout comme Sublime Text 3, l'important pour moi est que l'éditeur puisse fonctionner sur diverses plateformes, et entre autre sur celle que j'utilise pour mes projets rétro : Ubuntu Linux. De ce côté, c'est ok.

    Pour la syntaxe colorée, j'utilise le plugin Z80 Macro-Assembleur. Le plugin apporte aussi un « problem matcher », qui est la façon pour l'éditeur de savoir si des erreurs ont été levées lors de phase de construction.

    Il offre aussi un support d'Intellisense, mais que je n'ai pas encore mis en fonctionnement. A priori, ça ne fonctionne pas tout seul.

    J'ai aussi ajouté Z80 Assembly meter qui permet d'évaluer le nombre de cycles pris par du code sélectionné, avec une option MSX qui allonge d'un cycle les instructions, ce qui est aussi valable pour le VG5000µ.

    L'assembleur

    Auparavant, j'utilisais l'assembleur z80asm livré avec l'environnement z88dk. C'était un choix historique venant de mes essais en C sur le Z80. Cet assembleur fonctionne bien, mais est très minimaliste. En effet, un assembleur derrière un compilateur n'a pas besoin de beaucoup d'aides, le compilateur pouvant générer le code in extenso.

    Lorsque l'on met au point du code à la main, rapidement, pouvoir écrire des macros, manipuler des adresses via des expressions, devient un outil nécessaire.

    C'est vers sjasmplus que je me suis tourné. Comme souvent, l'assembleur est fait avec une machine particulière en tête, ici la ligne des Spectrum. Mais ce n'est pas bien grave. L'assembleur a des macros, est assez souple sur la syntaxe, a pas mal d'instructions pour déclarer ce que l'on veut faire.

    La tuyauterie

    Voici le fichier tasks.json que j'ai écris. Il est probablement perfectible car je ne connais pas toutes les subtilités de Visual Studio Code, mais il fait l'affaire pour le moment.

    Pour le fonctionnement du script vgboot.lua, je vous renvois à cet article. Le script n'a pas bougé depuis.

        "version": "2.0.0",
        "tasks": [
            {
                "label": "sjasmplus - Build",
                "type": "shell",
                // Options: No fake instructions, Warning as Errors, Multi arg is ',,'
                "command": "sjasmplus --syntax=FLwa ${fileBasename} --raw=${fileBasenameNoExtension}.bin --lst",
                "problemMatcher": [
                    "$errmatcher-sjasmplus"
                ],
                "group": {
                    "kind": "build",
                    "isDefault": true
                },
                "options": {
                    "cwd": "${relativeFileDirname}"
                }
            },
            {
                "label": "sjasmplus - Run on Mame",
                "type": "shell",
                "command": "mame64 vg5k -ramsize 48k -nomax -window -autoboot_delay 0 -autoboot_script vgboot.lua -debug -debugger none -natural",
                "problemMatcher": [
                    "$errmatcher-sjasmplus"
                ],
                "dependsOn": [
                    "sjasmplus - Build"
                ],
                "options": {
                    "cwd": "${relativeFileDirname}"
                }
            },
            {
                "label": "sjasmplus - Debug on Mame",
                "type": "shell",
                "command": "mame64 vg5k -ramsize 48k -nomax -window -autoboot_delay 0 -autoboot_script vgboot.lua -debug -debugger qt -natural",
                "problemMatcher": [
                    "$errmatcher-sjasmplus"
                ],
                "dependsOn": [
                    "sjasmplus - Build"
                ],
                "options": {
                    "cwd": "${relativeFileDirname}"
                }
            }
        ]
    }
    

    La suite

    Les environnements pour des machines connues vont encore plus loin, avec par exemple de l'intégration de debugger directement dans Visual Studio Code. Il y a aussi un support de tests unitaires, qui me plaît bien. Reste qu'il faut faire quelques branchements pour que cela fonctionne pour un VG5000µ. Je ne sais pas encore si j'irai vers là.


« (précédent) Page 2 / 17 (suivant) »