Triceraprog
La programmation depuis le Crétacé

Articles avec le tag « VG5000 ».

  • Du langage machine à l'assembleur sur VG5000µ ()

    Après cette pause estivale, reprenons là où l'on était restés. Dans l'article précédent, je parlais du langage machine, une suite de signaux provoquant l'activité d'un processeur selon des directives précises.

    Un inconvénient du langage machine, c'est qu'il est peu pratique à manipuler. Par exemple, sur un Z80, charger l'accumulateur (une mémoire spécifique interne au processeur) avec la valeur 1, je dois écrire : 00111110 00000001 en binaire, ou encore 3E 01 en système hexadécimal.

    Écrire de cette manière n'est pas simple, prend beaucoup de temps avec un grand risque d'erreurs. Relire est encore pire. Programmez une machine de cette manière et vous ressentirez a priori rapidement le besoin de manipuler des éléments plus faciles à comprendre pour un Humain.

    Et c'est ainsi que du langage machine on passe au langage d'assemblage, ou, par abus de langage, à l'assembleur.

    L'assembleur

    La première chose à savoir est que l'assembleur est un programme. Mais par extension, le langage qui est utilisé par ce programme est aussi appelé assembleur. Dans la suite, le mot servira principalement à désigner le langage en lui-même.

    L'assembleur donc, est un langage à la syntaxe et à la grammaire extrêmement proche du langage machine. Chaque instruction en assembleur est directement traduisible dans sa version en langage machine et chaque instruction en langage machine a son écriture en assembleur.

    En assembleur Z80, pour continuer sur le même exemple, la suite de signaux 00111110 00000001 qui charge 1 dans l'accumulateur s'écrit LD A, 1 en assembleur. C'est toujours un peu cryptique, mais ça se lit bien plus facilement. LD pour « load », charger en anglais, est suivi de deux paramètres : la destination A, qui désigne l'accumulateur, et la valeur 1.

    Je précise bien assembleur Z80 car, tout comme le langage machine diffère d'un processeur à l'autre, l'assembleur, qui est une transcription lisible de ce langage machine est lui aussi spécifique à chaque processeur.

    Ça reste ardu non ?

    Les commandes du processeur Z80 couvrent le chargement de données dans sa mémoire interne (les registres), des calculs, des comparaisons,... Ces commandes étant très simples, il en faut souvent un certain nombre pour arriver au résultat voulu. Et la programmation est sans filet : le processeur exécutera à la lettre les commandes envoyées.

    C'est pour cela que des langages de plus haut niveau d'abstraction, comme le BASIC (pour rester sur le VG5000µ), ont été créés. Le BASIC a des instructions simples à utiliser, son interpréteur se charge de vérifier les erreurs, de gérer la mémoire,... Les instructions de base du BASIC sont aussi les mêmes, pour ce qui est du coeur du langage, d'une machine à une autre, alors qu'il existe un assembleur différent dès que l'on change de processeur.

    Toute la simplification des actions et la gestion d'erreurs a par contre un coût. De plus, le BASIC des machines telles que le VG5000µ est interprété, c'est-à-dire que les instructions et leurs paramètres sont décodées à chaque fois qu'elles sont exécutées. Cette interprétation amène au final à des instructions machines, mais très nombreuses.

    Programmer en assembleur permet de s'affranchir de toute la lourdeur d'un langage interprété comme le BASIC, au prix d'un peu d'effort et d'attention. Et sur ce point, programmer une ancienne machine en 2017 aide beaucoup. Imaginez : programmer sur la machine elle-même à l'époque nécessitait de charger un programme d'édition, ce qui pouvait être long, et de repartir de zéro au moindre problème, puisqu'une erreur pouvait amener au plantage de la machine.

    En 2017, avec émulation et outils d'assemblage qui tournent sur un ordinateur récent pour une vérification ultime sur la vraie machine, c'est beaucoup, beaucoup plus simple.

    La mission

    Le premier objectif en assembleur sur VG5000µ va être d'afficher une chaîne de caractères à l'écran. L'équivalent d'un PRINT "Bonjour!". Mais avant cela, il me faut parler un peu de la ROM de la machine.

    La ROM est une mémoire persistante, son contenu reste le même à chaque fois que la machine est en fonctionnement et il ne peut pas être modifié pendant l'exécution. On l'oppose souvent à la RAM, qui est une mémoire volatile, dont le contenu est perdu dès que la machine est éteinte.

    La ROM, dans une machine comme le VG5000µ, contient l'ensemble des opérations nécessaires à son fonctionnement : comment dialoguer avec le processeur qui s'occupe de l'affichage, comment jouer un son, comment charger et sauver des données sur cassette,... La ROM contient aussi l'interpréteur BASIC et la gestion de l'interaction avec l'utilisateur.

    Si son contenu n'est pas modifiable, il est par contre tout à fait possible de le lire, ou même d'en appeler des routines.

    Dans le cadre de cette mission, je vais donc utiliser la routine d'affichage de chaîne de caractères. C'est exactement la même qui est utilisée in fine par l'instruction PRINT, mais je vais l'utiliser directement.

    La routine

    La routine d'affichage de chaîne de caractères est située à l'adresse $36AA (le préfixe $ indique un nombre hexadécimal, en décimal, c'est l'équivalent de l'adresse 13994).

    Cette routine se charge en fait de l'impression à l'écran, sur une imprimante ou sur une cassette de sauvegarde. À défaut d'une action spéciale, l'affichage se fait à l'écran, je ne touche donc à rien.

    La chaîne de caractères doit se terminer par le caractère de valeur 0 en mémoire.

    La routine a besoin de connaître l'adresse en mémoire de la chaîne de caractères à afficher et pour celui utilise le registre HL. Tous les autres registres seront modifiés, il faudra donc en préserver le contenu.

    Aparté sur les registres : programmer en assembleur nécessite de connaître l'architecture logique du processeur. Une de ses composantes est que sa mémoire interne est découpée en registres. On peut imaginer les registres comme des conteneurs d'informations numériques.

    Le programme va donc ressembler à quelque chose comme ça :

    • Sauvegarde des registres
    • Charger le registre HL avec l'adresse de la chaîne de caractères
    • Appeler la routine $36AA
    • Restaurer les registres
    • Revenir au programme appelant


    La dernière étape de retour au programme appelant est nécessaire car l'appel depuis le BASIC se fera par l'instruction CALL qui appelle une routine en assembleur qui doit rendre la main afin que le programme BASIC puisse continuer.

    Écriture en assembleur

    Pour sauvegarder les registres, je vais utiliser la pile. La pile est une zone de mémoire dans laquelle on peut pousser des informations pour les récupérer plus tard, dans un ordre tel que la dernière information poussée est la première information récupérée. Vous pouvez imaginez une pile de feuilles de papiers sur laquelle vous pouvez ajouter une nouvelle feuille sur le dessus, ou bien retirer la feuille du dessus pour en lire le contenu.

    Pousser tous les registres sur la pile peut se faire comme ceci :

    PUSH AF
    PUSH BC
    PUSH DE
    PUSH HL
    

    À la fin de ce petit programme, il faudra dépiler les valeurs de registre dans l'ordre inverse :

    POP HL
    POP DE
    POP BC
    POP AF
    

    Pour charger le registre HL avec l'adresse de la chaîne de caractère, on va demander de l'aide à l'assembleur (le programme, ici). Cette adresse en effet pourrait être fixée à la main, mais cela ne serait pas très flexible. Plutôt qu'une adresse, on utilise plutôt une étiquette (un label) comme une référence au contenu pointé.

        LD HL, chaine
        (... plus loin ...)
    chaine:
        DEFB "Bonjour !", 0
    

    DEFB n'est pas réellement une instruction qui s'associe au langage machine. C'est une pseudo instruction, ou directive d'assemblage, qui indique à l'assembleur les valeurs numériques à placer directement en mémoire. Ici, on y place les valeurs numériques correspondantes aux caractères de "Bonjour !", suivi de la valeur 0, qui indique la fin de la chaîne. L'étiquette chaîne prendra automatiquement lors de l'assemblage l'adresse mémoire calculée.

    Si DEFB est séparé de programme lui-même, c'est qu'une fois en mémoire, le processeur Z80 exécutera les instructions une à une, sans avoir de moyen de distinguer ce qui est une véritable instruction de ce qui est de la donnée. Si la chaîne de caractères se trouve sur son chemin d'exécution, elle sera prise pour une série d'instructions.

    Pour les curieux : « Bonjour! » pris comme une suite d'instructions donne ce qui suit et qui n'a pas beaucoup de sens

    LD B,D
    LD L,A
    LD L,(HL)
    LD L,D
    LD L,A
    LD (HL),L
    LD (HL),D
    LD HL,$0000
    


    Reprenons... appeler la routine $36AA est simplement :

    CALL $36AA
    

    Et revenir au programme appelant se fait avec l'instruction RET.

    Dernière petite opération, il faut spécifier à l'assembleur l'adresse de début du programme, afin que les adresses des étiquettes puissent être calculées. Cela peut se faire, entre autre méthode, par l'utilisation de la directive d'assemblage ORG, comme origin.

    Ce qui donne au final la séquence suivante :

        ORG $7000
    
        PUSH AF
        PUSH BC
        PUSH DE
        PUSH HL
    
        LD HL, chaine
        CALL $36AA
    
        POP HL
        POP DE
        POP BC
        POP AF
    
        RET
    chaine:
        DEFB "Bonjour !", 0
    

    Ce qui donne une fois passé à l'assembleur la séquence en langage machine suivante (en représentation hexadécimale) :

    E5 C5 F5 D5 CD AA 36 D1 F1 C1 E1 C9 42 6F 6E 6A 6F 75 72 21 00
    

    Lancement du programme

    Cette séquence en langage machine doit ensuite être implantée dans la mémoire et appelée depuis le BASIC. Une manière de faire est d'utiliser les instructions DATA et POKE du BASIC. DATA indique des séquences de valeurs à lire avec READ. POKE modifie une valeur de la mémoire à l'adresse spécifiée par le premier paramètre avec la valeur en deuxième paramètre.

    Voici un exemple de chargeur de programme en langage machine écrit en BASIC sur VG5000µ.

    10 S=&"7000"
    20 READ A$
    30 IF A$="FIN" THEN END
    40 A=VAL(A$):POKE S,A
    50 S=S+1
    60 GOTO 20
    300 DATA E5,C5,F5,D5,CD,AA,36,D1,F1,C1,E1,C9,42,6F,6E,6A,6F,75,72,21,00 
    400 DATA FIN
    

    Une fois ce programme entré et lancé avec RUN, la routine d'affichage peut être appelée avec CALL &"7000" et affichera Bonjour! à l'écran.

    Résultat

    Forcément, j'ai déployé beaucoup d'efforts pour afficher une simple chaîne de caractères. Il n'y a pas vraiment d'intérêt autre que pédagogique. Le programme en lui-même est long à cause de la sauvegarde et la restauration des registres, il faut l'accompagner d'un chargeur qui est plus grand que le programme en assembleur lui-même, et l'action n'étant appelée qu'une fois, il n'a pas d'intérêt en vitesse d'exécution.

    Mais nous avons pu voir à quoi ressemblait la programmation en assembleur.

    Bonjour! Bonjour!


  • Z80 et VG5000µ ()

    Lors des articles précédents sur l'affichage, un résultat était net : c'est lent ! Extrêmement lent. Les magazines ou de livres consacrés à la programmation des machines personnelles des années 1980 affirmaient tous ceci : si vous voulez quelque chose de rapide, passez à l'assembleur.

    Que signifie utiliser l'assembleur, et en quoi c'est différent du BASIC ? Pourquoi est-ce que c'est plus rapide ? Était-ce vraiment la seule solution ? C'est ce que nous allons voir dans cet article et les suivants.

    J'ai tenté plusieurs approches pour arriver au premier programme en assembleur dans une série d'articles. Et j'en suis arrivé à la conclusion qu'il n'y a pas moyen de passer outre quelques explications rapides des constituants de l'ordinateur et de leurs fonctionnements.

    On va tout de même garder une vue large et schématique pour la plupart des composants. Pour le microprocesseur, un Z80 sur le VG5000µ, il faudra descendre un peu vers le fonctionnement de la puce, sans y sombrer.

    En effet, programmer en assembleur, c'est programmer la machine au plus près, suivant ses caractéristiques, sans l'aide d'un langage de programmation offrant des abstractions.

    La machine, en très bref

    Le VG5000µ est composé de :

    • Un microprocesseur Z80A, que je désignerai plus simplement comme Z80, qui est le nom générique pour cette série. Le microprocesseur est souvent désigné comme le cœur de l'ordinateur. Je préfère le désigner comme chef d'orchestre. C'est ce composant qui exécute les instructions du programme.
    • Un clavier, qui est une série d'interrupteurs agencés sous forme de matrice dont l'état peut-être lu grâce au contrôleur d'entrée/sortie du Z80.
    • Une mémoire au contenu figé (ROM) de 16ko, qui contient le programme de gestion de la machine.
    • Trois mémoires vives (RAM) de 8ko, contenant toutes les données dynamiques de la machine. Deux de ces mémoires servent au fonctionnement général, la troisième est réservée au fonctionnement du processeur graphique.
    • Un processeur graphique, EF9394, qui gère l'affichage.
    • Une interface cassette.
    • Des BUS et des circuits logiques pour relier le tout.


    Schéma simplifié VG5000

    Le fonctionnement du CPU, en très bref

    Au démarrage de la machine, le Z80, alimenté, va entrer dans une boucle d'exécution jusqu'à son extinction :

    • Acquérir une instruction à l'adresse mémoire de l'instruction suivante (adresse 0 au démarrage).
    • Changement de l'adresse de l'instruction suivante.
    • Exécution de l'instruction acquise.

    À cela s'ajoute le traitement des interruptions. Lorsque le processeur reçoit une interruption, l'adresse mémoire de l'instruction suivante est forcée à une valeur spécifique. Une instruction dédiée permet de reprendre plus tard l'exécution là où elle avait été interrompue.

    Boucle du CPU

    C'est une vue un simplifiée du fonctionnement du Z80, je laisse de côté les détails, comme le fait que l'acquisition d'une nouvelle instruction n'attend pas la fin de l'exécution de la précédente. D'un point de vue logique, en ce qui nous concerne, cela revient au même.

    Voyons les étapes plus en détails.

    Acquisition de l'instruction

    Le Z80 est relié via trois BUS aux mémoires du VG5000µ, exception faite de la mémoire dédiée au processeur graphique. Un BUS, c'est tout simplement une série de conducteurs électriques (disons, des fils) qui permettent à différents composants de communiquer.

    Pour acquérir son instruction, le Z80 va utiliser un premier BUS, celui d'adresse, pour signaler de quelle adresse mémoire l'instruction courante est voulue. Puis, via un second BUS, celui de contrôle, le Z80 signal qu'il veut lire le contenu à cette adresse. Après une brève attente, le troisième BUS, celui de données, pourra être lu et contiendra l'information recherchée, fournie par l'une des mémoires.

    Une instruction complète pour un Z80 peut être composée d'un ou plusieurs octets. Dans le cas d'instructions à plusieurs octets, ceux-ci seront demandés les uns après les autres.

    Exécution de l'instruction

    Une fois l'instruction acquise, celle-ci est décodée et exécutée. Une instruction en langage machine Z80 est une suite de 1 à 4 octets. Chaque octets est une série de 8 informations binaires. Ces informations binaires, au niveau du microprocesseur, sont des informations électriques : est-ce que le signal est haut (1), ou bas (0) ?

    La manière dont est architecturé le Z80 fait que ces signaux activent à leur tour d'autres signaux, qui provoquent le transfert d'information à travers les circuits internes au Z80. Ces circuits internes peuvent être des mémoires (les registres), des unités de calculs simples, des unités de calculs et de logique. Les signaux peuvent aussi atteindre les BUS pour émettre des informations ou en recevoir.

    Ainsi, par exemple, l'instruction de retour d'un sous-routine, dont le nom est 'RET', se compose en langage machine des signaux suivants 11001001. C'est une instruction sans argument qui déclenche une série de micro-actions . La première est de demander à la mémoire le contenu à l'adresse désignée par le registre SP, qui est un registre dédié à ce genre d'opérations, tout en augmentant la valeur de SP de 1. La seconde est identique : demander le contenu mémoire à l'adresse SP nouvellement modifiée tout en l'incrémentant de 1.

    Le résultat de ces deux octets obtenus est placé dans le registre PC, qui est le registre qui désigne l'instruction suivante à obtenir.

    Ouf !

    C'est un peu lourd ? Voilà ce qu'il faut retenir : une instruction en langage machine déclenche une série de micro instructions influant les composants internes du microprocesseur.

    C'est justement parce que tout ce détail est encombrant pour réfléchir à la résolution d'un problème que nous allons vite monter d'un cran en abstraction, et passer à l'assembleur, dans le prochain article.


  • Récréation 3D, VG5000µ version 2 ()

    Il y a deux mois, je publiais ma première récréation en 3D, une évocation d'un VG5000µ. J'avais modélisé la machine un peu au jugé et au final, il y avait pas mal d'erreurs dans les dimensions. Un peu trop à mon goût. J'ai donc refait l'exercice, cette fois avec un VG5000µ et une règle à côté de moi.

    Et voici le nouveau résultat, bien plus satisfaisant.

    VG5000µ en 3D, version 2


  • VG5000µ, haute résolution ()

    Dans les articles précédents sur l'affichage du VG5000µ, je travaillais dans une résolution que je nomme « gros pixels », basée sur des caractères semi-graphiques. Grâce à l'implémentation d'une routine d'affichage de pixel, j'avais pu programmer un affichage de ligne et un affichage de cercle.

    Avec ce mode d'affichage, on obtient une résolution de 80 pixels horizontalement par 75 pixels verticalement. Ce qui donne un total de 6000 pixels. Cependant, le manuel d'utilisation de la machine indique une définition d'image de 80 000 points. Plus de 13 fois plus. Existe-t-il une façon d'afficher des pixels plus petits et d'atteindre une haute (toute proportion gardée) définition ?

    Petit rappel : je ne m'occupe pour le moment que des capacités du VG5000µ offertes par le BASIC, et se mettant à la place d'une utilisation à l'époque, avec juste le manuel de base.

    Plus fin

    Pour atteindre une définition plus fine depuis le BASIC, il faut utiliser les informations du Chapitre 16, sur les jeux de caractères définissables par l'utilisateur.

    Comme on l'a vu avec les caractères semi-graphique, l'écran du VG5000µ est organisé suivant une grille de 40 colonnes et 25 lignes, avec chaque emplacement pouvant afficher un caractère. Ce caractère peut être un chiffre, une lettre, de la ponctuation, ou bien un caractère semi-graphique. Mais il existe aussi des caractères laissés libres dont il est possible de définir le contenu.

    C'est un peu comme si l'on pouvait définir une nouvelle police de caractères. Et la manière dont est configuré le VG5000µ laisse deux plages de 96 de ces caractères. Une plage pour le mode texte et une plage pour le mode graphique. Ce qui, si l'on met de côté les restrictions d'attributs d'affichage qui sont différents en texte (mode TX) et en graphique (mode GR), donne 192 caractères programmables.

    Ces caractères, comme les autres prédéfinis, sont des blocs de 8 pixels de large par 10 pixels de haut. Ce qui donne donc un total théorique de 15360 pixels qui peuvent être simultanément affichés en haute définition à l'écran. Avec des contraintes sur les couleurs, sur les emplacements et les enchaînements des modes TX et GR.

    Cela donne une théorie d'un peu moins de 20% de l'écran qui peut être en haute définition.

    Par la réutilisation de caractères identiques à plusieurs emplacements et le mélange de ces caractères avec les caractères de bases texte et semi-graphique, il est possible de pousser la théorie. Au prix d'un effort considérable. Dessiner de belles images directement sur la machine est long et complexe.

    Définition des caractères

    L'objectif de cet article est d'obtenir sur le VG5000µ une image en haute définition affichée depuis le BASIC. Voyons donc déjà le principe de la programmation de ces caractères, qui est similaire à celui que l'on trouve sur d'autres machines, comme le CPC6128.

    Chaque caractère est composé de 10 lignes de 8 pixels, chacun des pixels pouvant avoir deux états : allumé et éteints, ou plutôt, couleur d'encre et couleur de fond.

    8 pixels avec deux états, c'est parfait pour tenir dans un octet de 8 bits. Un caractère sera donc défini par une série de 10 octets.

    La manière de créer un caractère est de prendre du papier quadrillé, de colorier des cases, puis de transformer ces cases coloriées en 1, celles qui ne le sont pas en 0 pour obtenir les valeurs d'encodage du caractère.

    Voici par exemple ce qui pourrait être une sorte de vaisseau pour un jeu.

    Sprite

    Ce qui, donne l'encodage suivant.

    ContenuCodage en base 10
    00000000->0
    00000000->0
    00011000->24
    01111110->126
    10100101->165
    01111110->126
    00011000->24
    00000000->0
    00000000->0
    00000000->0

    La commande VG5000µ pour programmer les caractères demande de transformer cette série de nombre sous une écriture hexadécimal, puis, par d'écrire le tout sous une forme de chaîne de caractères.

    Hexadécimal : cette notation sort du cadre de l'article. Rapidement, il s'agit de compter dans une base de 16 chiffres, plutôt que les 10 habituels. Les 6 chiffres après le 9 sont notés A, B, C, D, E et F.

    Dans notre exemple, la série de nombres (en base 10) de haut en bas 0, 0, 24, 126, 165, 126, 24, 0, 0, 0 se transforme en série de nombres (en base 16) 0, 0, 18, 7E, A5, 7E, 18, 0, 0, 0. Comme un nombre hexadécimal de 0 à 255 ne prendra jamais plus de deux caractères, la commande demande à mettre tous les nombres sur deux caractères et assembler le tout. Cela donne au final : 0000187EA57E18000000.

    Exemple plus poussé

    Calculer une grille pour chaque caractère voulu est fastidieux. Très fastidieux. C'est pourquoi pour essayer ce mode, je me suis servi d'un programme annexe, sur une machine moderne, afin de transformer une image en série de caractères définis.

    Par simplicité, je me suis limité à la palette graphique étendue, et donc à 96 caractères maximum. J'ai pris l'image de la maison que j'avais tracée dans l'article sur le tramage, je l'ai redimensionnée puis je l'ai passé à ma moulinette.

    Maison d'origine, dithered low

    Le programme BASIC en sorti est constitué de trois parties.

    5 INIT 6:EG0,6
    10 FOR Y=0 TO 12
    20 FOR X=0 TO 9
    30 READ I
    40 CURSORX X+14:CURSORY Y+4
    50 PRINT CHR$(I);
    60 NEXT X
    70 NEXT Y
    

    La première partie efface l'écran et pioche dans une liste de données les numéros de caractères à afficher à l'écran. Pour cela, deux boucles FOR imbriquées font parcourir au curseur la zone à afficher.

    À noter ligne 50 le point-virgule à la fin du PRINT, qui empêche l'instruction d'afficher le caractère de retour chariot, pas nécessaire car ce n'est pas un caractère affichable dans ce mode, mais qui évite certains calculs au BASIC.

    L'instruction READ prend une à une les valeurs fournies par l'instruction DATA de la troisième partie du programme.

    La seconde partie est une liste des définitions de tous les caractères.

    100 SETEG 115,"5CE854B4D868AAB855DB"
    110 SETEG 55,"FAAFDA77DDB6ED77ADFB"
    120 SETEG 93,"94224885284214429449"
    ...
    ...
    ...
    1020 SETEG 103,"44922449924491249249"
    1030 SETEG 119,"08020000000000000000"
    1040 SETEG 39,"00000000000000010103"
    

    Enfin, la troisième partie indique les caractères à afficher, lus par la première partie.

    1050 DATA 32,32,32,32,33,34,32,32,32,32,32,32,32,35,36,37
    1060 DATA 38,32,32,32,32,32,39,40,41,42,43,44,32,32,32,45
    1070 DATA 46,47,48,49,50,51,52,32,32,53,54,55,56,57,58,59
    1080 DATA 60,32,61,62,63,64,65,66,67,68,69,70,71,72,73,74
    1090 DATA 75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90
    1100 DATA 91,92,93,94,95,96,97,98,99,100,32,101,102,103,104,105
    1110 DATA 106,107,108,109,32,110,111,112,113,114,115,116,117,118,32,32
    1120 DATA 119,120,121,122,123,124,32,32,32,32,32,32,125,126,32,32
    1130 DATA 32,32
    

    On y remarque la répétition du caractère 32, qui est un caractère entièrement de la couleur du fond (et qui, avec un peu plus de travail, aurait pu être ignoré, afin de gagner un caractère programmable).

    Le fait d'afficher d'abord les caractères puis de les définir offre au passage un petit effet intéressant d'affichage progressif.

    Ça consomme !

    Cette manière d'afficher permet du détail, mais, surtout en BASIC, elle consomme beaucoup de place en mémoire. Le programme pour afficher l'image en fin d'article prend un peu moins de 4 ko, ce qui est énorme considérant les capacités de la machine. On pourrait stocker 3 images comme celle-ci pour la configuration mémoire sans extension, et puis c'est tout.

    Le fait d'utiliser les commandes BASIC pour cela est en parti le problème. La place nécessaire à ces données est plutôt de l'ordre de 1 ko, et le programme qui décode l'image peut-être plus léger. J'y reviendrai plus tard.

    Le résultat

    Voilà un exemple d'affichage en haute définition depuis le BASIC du VG5000µ. Cela conclue la série d'article d'exploration des capacités graphiques du VG5000µ en n'utilisant que les instructions décrites par le manuel d'utilisation. La prochaine fois que je reviendrai sur l'affichage, cela sera pour aller au-delà des limitations du BASIC.

    Maison en haute résolution


Page 1 / 5 »