Site logo

Triceraprog
La programmation depuis le Crétacé

  • VG5000µ, Arrangement de la mémoire vidéo ()

    Cet article est la version française de cet autre que j'ai écrit suite à une demande d'aide dans le forum System.cfg forum. Je me suis dit que c'était le moment de mettre à plat mes notes, même si du coup cela cassait un peu la progression des articles en français sur l'affichage.

    Cela donne un article un peu plus austère que d'habitude, et un peu plus dense.

    Pour commencer, le processeur vidéo du VG5000µ est un EF9345. On peut y accéder de deux façons, soit en discutant directement, soit à travers la RAM lorsqu'on utilise le BASIC embarqué dans la machine. La manière directe est plus puissante, la seconde est plus simple.

    Le signal de début d'affichage (Blank Start) du processeur vidéo est connecté à la broche d'interruption du Z80. Cela provoque une interruption IRQ qui, dans le mode dans lequel le BASIC initialise le Z80, fait un appel à l'adresse 0x0038 en tant qu'interruption.

    La routine IRQ utilises des drapeaux (flags) pour décider si le contenu de la RAM doit être envoyé au EF9345. Pour cela, le moniteur regarde les valeurs en 0x47FA (compteur décrémenté jusqu'à 0), 0x47FB (force un rafraîchissement si différent de 0) et 0x47FC (valeur de référence pour le compteur en 0x47FA). En BASIC, cela correspond à la commande DISPLAY.

    Si le rafraîchissement est enclenché, la mémoire vidéo est décodée et transférée au EF9345. Pour avoir une idée de comment est effectué cette opération, sur une version 1.1 du BASIC, cela commence à l'adresse 0x0056, puis un peu plus loin en 0x00bc et se termine en 0x018b. Le registre ix est toujours à la valeur 0x47fa lorsque le BASIC est en route. Il se sert de ce registre d'index pour repérer les variables d'affichage (ne touchez pas à ix si vous laissez le système BASIC gérer la vidéo, ou alors en masquant les interruptions).

    La mémoire vidéo est de la mémoire RAM standard. Elle n'est pas branchée d'une manière spécifique et si vous voulez contrôler l'affichage vous même, vous pouvez utiliser n'importe quel endroit disponible et le format qui vous chante. L'arrangement utilisé par le BASIC en ROM, lui, commence en 0x4000. L'arrangement ligne/colonne est comme suit :

    Offset (decimal) Colonne 0 Colonne 1 Colonne 2 ... Colonne 38 Colonne 39
    Ligne 0 +0/+1 +2/+3 +4/+5 ... +76/+77 +78/+79
    Ligne 1 +80/+81 +82/+83 +84/+85 ... +156/+157 +158/+159
    Ligne 2 +160/+161 +162/+163 +164/+165 ... +236/+237 +238/+239
    ...
    Ligne 24 +1840/+1841 +1842/+1843 +1844/+1845 ... +1916/+1917 +1918/+1919
    Ligne 25 +1920/+1921 +1922/+1923 +1924/+1925 ... +1996/+1997 +1998/+1999

    Chaque unité affichable est codée sur une paire d'octets. Le premier octet contient principalement le numéro du caractère. Le second octet contient principalement ses attributs. La page de caractères est sélectionnée avec 1 bit dans chaque octet.

    Le premier octet de la paire se présente comme suit :

    Bit 7 6 / 5 / 4 / 3 / 2 / 1 / 0
    Contenu N (0)/E (1) numéro du caractère

    Le second octet de la paire se présente comme suit :

    Bit 7 6 5 4 3 2 / 1 / 0
    Contenu TX (0) Inverse vidéo Largeur x2 Hauteur x2 Clignotement Couleur
    Contenu GR (1) Couleur ... ... de ... ... fond Clignotement Couleur

    Grâce à N/E (Normal/Étendu) et TX/GR, la page de caractères est choisie. Cela correspond aux diverses sélection de caractères en BASIC. TX/Normal est TX, TX/Étendu est ET, GR/Normal est GR, GR/Étendu est EG. Le mode étendu permet de redéfinir les caractères. Le texte normal est ASCII, et le graphique normal contient les caractères semi-graphiques.

    Comme vous pouvez le voir, il n'y a pas de moyen pour spécifier une couleur de fond en mode texte. La couleur de fond utilisée est la couleur de fond fixée par le dernier caractère graphique précédent sur la même ligne. C'est pour cela que lorsqu'on utilise la commande INIT du BASIC pour effacer l'écran, la colonne 0 est remplie avec un caractère graphique invisible ayant pour couleur de fond la couleur spécifiée. Et c'est aussi pour ça que le BASIC n'utilise pas la première colonne.

    Un dernier mot: le EF9345 est beaucoup plus puissant que ce qui est induit par son utilisation par le VG5000µ. Vous pouvez trouver sur Internet des ressources pour l'utiliser en 80 colonnes, ou bien avec plus de 7 couleurs. Cela nécessite plus de travail car il faut alors communiquer directement avec le EF9345 à travers les ports I/O 0x8F et 0xCF du Z80.


  • Human Resource Machine, le jeu assembleur ()

    Human Resource Machine est un jeu de Tomorrow Corporation de type résolution de défi. Ces défis se présentent tous sous la même formes : une série de chiffres et/ou lettres à transformer en une autre série de chiffres et/ou lettres, en fonction de directives.

    Et pour cela, le joueur a à sa disposition une série de commandes. Au début, très peu, leur nombre s'étoffe au fur et à mesure des 42 niveaux de la ligne principale. Ces commandes sont exécutées par l'avatar du joueur, qui va courir d'un bout à l'autre d'une pièce pour prendre des données, les transformer, les ajoutes, les comparer, les stocker...

    C'est ici que cela m'intéresse dans le cadre de Triceraprog. Le personnage que contrôle le joueur simule le fonctionnement d'un ordinateur (en parti). Le joueur au fur et à mesure de la résolution des puzzle apprend « tout simplement » un langage d'assemblage.

    Un langage d'assemblage, ou langage assembleur, est un langage très proche des opérations effectuées par un processeur d'ordinateur. Résoudre des problèmes avec ce seul langage est assez fastidieux et c'est sur ce ressort que joue Human Resource Machine.

    Le joueur a la possibilité de copier/coller les programmes du jeu, et ce qui est intéressant est que ce qui est sauvé dans le presse-papier ressemble à un vrai langage d'assemblage pour une machine inventée pour l'occasion. Voici un exemple de résolution d'un des premiers niveaux du jeu, copié dans un éditeur de texte :

    -- HUMAN RESOURCE MACHINE PROGRAM --
    
    a:
        INBOX   
        COPYTO   0
    b:
    c:
        INBOX   
        JUMPZ    e
        SUB      0
        JUMPN    d
        JUMP     c
    d:
        ADD      0
        COPYTO   0
        JUMP     b
    e:
        COPYFROM 0
        OUTBOX  
        JUMP     a
    

    En termes plus clairs (attention soyez attentif !) :

    1. le programme indique qu'il faut prendre une donnée dans celle qui se présentent en entrée (INBOX)
    2. la copier dans une case mémoire nommée 0 (COPYTO 0)
    3. puis prendre une autre donnée
    4. aller à la ligne indiquer e: si cette donnée est égale à zéro (JUMPZ).
    5. Dans le cas contraire, retrancher le contenu de la case 0 à la donnée courante (SUB 0)
    6. Si le résultat est négatif, allez en d:
    7. Sinon revenir en c:

    8. Dans le cas où le résultat était négatif et que l'on est maintenant en d:, cela signifie que la nouvelle donnée était plus petite que celle dans la case 0.

    9. La nouvelle donnée est rétablie (ADD 0... on ajoute ce qu'on avait retranché) et est mise dans la case 0.
    10. On revient en b: pour lire une nouvelle donnée

    11. Dans le cas où la donnée était égale à 0, on arrive en e:

    12. La donnée présente dans la case 0 est copiée dans la sortie (COPYFROM 0 puis OUTBOX)
    13. On reprend tout le depuis le début.

    Plus clair ? Mouais... Et en français ? Voici : en entrée se trouvent des suites de nombres qui sont séparées par des 0 (zéro). Pour chaque série, le plus petit des nombres est recopié en sortie. Ce qui est exactement l'énoncé du défi.

    Apprentissage ?

    Je ne suis pas entièrement persuadé que le jeu soit didactique au point d'enseigner la programmation en assembleur. Cependant, il présente une manière de décrire des problèmes et fait ressentir ce qu'est la programmation de ce type.

    Pour un programmeur déjà habitué à l'exercice, le jeu n'est pas très long. Je l'ai terminé en moins de 3 heures, à l'exception du dernier des puzzles optionnels, qui aurait été vraiment long à mettre au point, je n'en avais pas vraiment envie.

    Je me demande cependant, pour quelqu'un qui n'est pas programmeur, si le jeu est intéressant et à quel point il est complexe.

    Au final, un jeu sympathique avec une petite histoire amusante en fil rouge. Si vous voulez jouer à programmer en assembleur, ce jeu est fait pour vous.

    Aperçu du jeu Human Resource Machine


  • Tramage basse définition pour le VG5000µ ()

    La dernière fois, j'avais présenté le début d'une idée pour accéder à des pixels « basse définition » sur le VG5000µ en se servant de caractères semi-graphiques.

    Avant de continuer sur l'idée, je me demandais ce que donnerais, sans trop de traitement, une image de synthèse en niveau de gris avec une telle technique.

    Afin de transformer cette image en niveaux de gris vers du noir et blanc, je fais appel à une technique appelée « Dithering » ou « tramage » en français. Il s'agit de transformer le niveau de lumière en série de points plus ou moins dense.

    Plus la résolution est dense, plus le résultat est bon. Forcément, en basse résolution semi-graphique, il ne faut pas s'attendre à des merveilles.

    Voici donc deux couples d'images. En premier le rendu en niveau de gris d'une image de synthèse assez simple. Puis un rendu avec du tramage. Il existe de nombreuses techniques de tramages, et j'en utilise une parmi d'autre, pour me donner une idée grossière de ce que cela peut donner. Il ne s'agit pas là de rendu faits sur un VG5000µ, cela sera l'objectif suivant.

    Cube et Sphère d'origine Cube et Sphère d'origine, dithered low

    Maison d'origine Maison d'origine, dithered low

    Un second but sera de faire sortir au VG5000µ une image en plus haute résolution. Mais pour cela, il faudra aller au-delà des caractères semi-graphiques.

    Cela pourrait donner quelque chose comme ça.

    Cube et Sphère d'origine, dithered high Maison d'origine, dithered high


  • Livre - Commodore VIC-20, a Visual History ()

    Après une première campagne Kickstarter manquée, Giacomo M. Vernoni n'a pas baissé les bras et lancé une nouvelle campagne pour l'édition d'un livre entièrement consacré au VIC-20 de Commodore.

    Le VIC-20, c'est un peu le grand frêre du beaucoup plus connu Commodore 64, un grand frêre aux capacités bien plus limitées. Mais c'est avant tout pour moi le premier de mes ordinateurs. Pas le premier que j'ai utilisé, ni celui sur lequel j'ai commencé la programmation, mais le premier qui était vraiment à moi.

    Alors forcément, la promesse d'un livre consacré à la machine m'a fait de l'oeil, et j'ai embarqué dans ce projet. Quelques mois après, je peux parcourir ce livre compact mais très fourni en détails et illustrations. C'est une très belle édition et je félicite son auteur pour le boulot accompli. Le livre respire le travail bien fait mêlé à la passion.

    Comme je ne suis pas toujours dans le détail les campagnes Kickstarter, j'ai été agréablement surpris de voir joint au livre des mini-posters, disons de grandes illustrations, d'un schéma de la machine, de photos des différentes cartes mère, et même un aimant aux couleurs de la marque.

    Je ne sais pas si mon VIC-20 fonctionne toujours, cela fait bien longtemps qu'il n'a pas été allumé. Je l'espère, et j'espère pouvoir ainsi en parler plus longement ici dans le futur.

    En attendant, je vous laisse avec une photo de la couverture du livre et d'un des posters.

    Image de la couverture du livre et d'un poster


  • Les caractères semi-graphiques du VG5000µ ()

    Lorsque l'on regarde de près la structure des caractères semi-graphiques du VG5000µ, on voit qu'elle a été réfléchie pour être facile à manipuler. Voici quelques observations :

    1. les caractères sont divisés en deux plages, l'une numérotée de 0 à 63, l'autre de 64 à 127.
    2. si on prend un caractère de la première plage, contenant les caractères « quadrillés » et que l'on ajoute 64 à son numéro, on obtient le même caractère en format « plein »
    3. de manière similaire, si on soustrait 64 au numéro d'un caractère plein, on obtient sa forme quadrillée.

    Le caractère 127, par exemple, est le caractère complètement rempli. Le caractère 127 - 64, c'est-à-dire 63, est le caractère rempli, quadrillé.

    Tous les caractères semi-graphiques du VG5000µ

    Une observation supplémentaire est plus visible si l'on réarrange les blocs de chaque caractère semi-graphique sur une seule ligne. Pour cela, je prends les deux blocs du haut, puis j'y ajoute les deux blocs du milieu, et enfin les deux blocs du bas.

    En remplaçant les blocs noirs par des « X » et les blocs blancs par des « . », voici ce que cela donne :

    ......
    X.....
    .X....
    XX....
    ..X...
    X.X...
    .XX...
    XXX...
    ...X..
    X..X..
    .X.X..
    XX.X..
    ..XX..
    X.XX..
    .XXX..
    XXXX..
    ....X.
    Et ainsi de suite pour les 64 possibilités.
    

    Ceux qui sont à l'aise avec le comptage en base binaire auront probablement déjà repéré la structure. Pour les autres, essayez ceci :

    1. À partir d'un caractère donné regardez la position la plus à gauche
    2. Si la position contient un point, placez un X, puis allez à l'étape 5
    3. Sinon, c'est que la position contient un X. Remplacez le par un point
    4. Considérez à présent la position juste à droite du point que vous venez de placer, et retournez à l'étape 2.
    5. Terminé.

    Au passage, cette série d'instructions donnant des étapes à suivre pour effectuer une opération s'appelle un algorithme, un terme que nous croiserons à nouveau.

    Félicitations, vous savez compter en binaire ! Plus traditionnellement, les « X » sont notés « 1 » et les « . » sont notés « 0 », mais le principe est le même.

    Le grand avantage d'utiliser cette structure, où des nombres binaires forment les motifs des caractères semi-graphiques, c'est qu'il est assez facile de trouver le numéro d'ordre d'un caractère en fonction du ou des blocs que l'on veut allumer.

    Pour cela, il suffit d'associer à chaque position un numéro, suivant ce schéma :

    Position 0 1 2 3 4 5
    Numéro associé 1 2 4 8 16 32

    L'association est la suivante : multipliez le chiffre 2 par 2 autant de fois que la position de la colonne. On considère que multiplier 0 fois donne 1. Par exemple, pour la position 5, cela donne : 2 * 2 * 2 * 2 * 2 = 32. Je vous laisse vérifier les autres colonnes.

    Je laisse la partie mathématique de l'histoire de côté, il y a de quoi faire un article complet dessus, et il y en a déjà beaucoup sur Internet.

    Essayons maintenant. Je voudrais le caractère avec le bloc du milieu à droite allumé. Ce bloc, si on réarrange le caractère en ligne, est à la position 3 (rappelez-vous qu'on commence à numéroter à zéro) :

    ..
    .X donne ...X..
    ..
    

    En se référant au tableau ci-dessus, on trouve que la colonne 3 est associée au nombre 8. Je cherche le caractère dans sa forme pleine, j'ajoute donc 64 à 8 pour obtenir 72. Je vérifie dans le tableau du manuel... gagné !

    Comment faire maintenant si l'on veut un caractère semi-graphique avec plusieurs blocs allumé ? Simple, il suffit de faire la somme de tous les numéros associés aux colonnes. Par exemple :

    X.
    .X donne X..XX.
    X.
    

    Les blocs allumés sont donc aux positions 0, 3 et 4. Les nombres associés à ces positions sont 1, 8 et 16. Je fais la somme 1 + 8 + 16 = 25. Je veux les caractères pleins, j'ajoute donc 64. 64 + 25 = 89. Je vérifie dans le manuel le caractère 89. Encore gagné !

    Nous voilà donc avec un algorithme très simple pour trouver un caractère semi-graphique en fonction d'un ensemble de points que l'on veut allumer. Il reste à afficher ce caractère au bon endroit à l'écran, et nous pourrons obtenir de quoi allumer et éteindre des blocs de pixels individuellement.


« (précédent) Page 21 / 22 (suivant) »

Tous les tags

3d (14), 6809 (1), 8bits (1), Affichage (24), AgonLight (2), Altaïr (1), Amstrad CPC (1), Apple (1), Aquarius (2), ASM (30), Atari (1), Atari 800 (1), Atari ST (2), Automatisation (4), BASIC (30), BASIC-80 (4), C (3), Calculs (1), CDC (1), Clion (1), cmake (1), Commodore (1), Commodore PET (1), CPU (1), Debug (5), Dithering (2), Divers (1), EF9345 (1), Émulation (7), Forth (3), Game Jam (1), Hector (3), Histoire (1), Hooks (4), i8008 (1), Image (16), Jeu (14), Jeu Vidéo (4), Livre (1), Logo (2), Machine virtuelle (2), Magazine (1), MAME (1), Matra Alice (3), MDLC (7), Micral (2), Motorola (1), MSX (1), Musée (2), Nintendo Switch (1), Nombres (3), Optimisation (1), Outils (3), Pascaline (1), Peertube (1), Photo (2), Programmation (3), Python (1), ROM (15), RPUfOS (5), Salon (1), SC-3000 (1), Schéma (5), Synthèse (14), Tortue (1), Triceraprog (1), VG5000 (62), VIC-20 (1), Vidéo (1), Z80 (20), z88dk (1)

Les derniers articles

Instance Peertube pour Triceraprog
Environnement de développement pour Picthorix
Un jeu en Forth pour Hector HRX : Picthorix
Yeno SC-3000 et condensateurs
Suite de tests pour VG5000µ
Un peu d'Atari ST
Le Forth sur Hector HRX
J'MSX 24 et un micro jeu
Récréation 3D, Matra Alice
Tuiles des plus très-curieuses

Atom Feed

Réseaux