Articles avec le tag « BASIC ».

Family BASIC, le BASIC sur Famicom

L'hiver dernier, j'ai découvert le Family Basic, ou Famibe, un BASIC pour la Famicom (le petit nom de la Family Computer de Nintendo, dont la version occidentale donnera la Nintendo Entertainment System, ou NES).

Le Family Basic, qui vient dans une boite bien visible sur une étagère, comprend une cartouche, un clavier et un manuel. Le clavier est un vrai clavier et est assez agréable à utiliser. Il se branche sur le port d'extension en façade de la console, là où se branchent les périphériques d'entrées supplémentaires, les deux manettes étant connectées à la console « en dur ».

La cartouche est plus haute que les cartouches Famicom classiques, presque la taille d'une cartouche NES. Dedans, il y a de la rom PRG (le programme), de la rom CHR (les données graphiques) et de la RAM (la mémoire vive) supplémentaire. Cette RAM peut d'ailleurs être alimentée par piles lorsque la console est …

Lire la suite →

Mattel Aquarius, scan des touches en assembleur

Le scan du clavier, sur Mattel Aquarius, à lieu dans la ROM à l'adresse $1e80. Cette fonction traite les minuscules, les majuscules mais aussi les raccourcis BASIC, en injectant au fur et à mesure les touches nécessaires comme si elles avaient été tapées au clavier.

C'est beaucoup trop pour un scan de clavier dans un jeu, et peut même poser quelques soucis. Mais c'est une bonne base pour écrire une routine de lecture de clavier, car la lecture des valeurs des touches n'est pas forcément très simples.

Ce que nous apprends la lecture de la routine en ROM est qu'il semble falloir attendre une stabilité dans les valeurs avant d'accepter la touche. En effet, la routine fait plusieurs lectures et ne considère la touche appuyée que si cette lecture est stable.

Voici une version de la routine, où j'ai enlever ce qui était traitement de raccourcis BASIC, ainsi que le …

Lire la suite →

Mattel Aquarius, entrées des commandes BASIC

Commençant à étudier le Mattel Aquarius afin de participer à la nouvelle session de « Retro Programmers United for Obscure Systems », et devant le manque de documentation, j'ai regardé ce qu'il y avait dans la ROM. Et c'est un BASIC Microsoft qui y est implémenté, ce qui est bien pratique puisque c'est un BASIC que j'ai bien étudié à travers le VG5000µ.

J'ai donc ressorti ma trousse à outils et voici la liste des points d'entrées des commandes et fonctions du BASIC.

La première colonne est le token BASIC, la seconde l'adresse du point d'entrée en ROM et la troisième le nom.

Les commandes

    128     $0c21         end
    129     $05bc         for
    130     $0d13         next
    131     $071c         data
    132     $0893         input
    133     $10cc         dim
    134     $08be         read
    135     $0731         let
    136     $06dc         goto
    137     $06be         run
    138     $079c         if
    139     $0c05         restore
    140     $06cb         gosub
    141     $06f8         return
    142     $071e         rem
    143 …
Lire la suite →

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 …

Lire la suite →

VG5000µ, Set Point assembleur depuis le BASIC

Cet article est la suite de deux précédents articles. Le premier, en plusieurs parties, était l'implémentation de l'affichage d'un « gros pixel » sur l'écran du VG5000µ. Le second était celui sur la possibilité (ou plutôt la difficulté) d'ajouter des commandes au BASIC du VG5000µ.

Il existe cependant une façon d'ajouter des commandes au BASIC... ou presque. Cette possibilité est évoquée brièvement dans le livre « Clefs pour VG5000 » page 98. À charge au lecteur de se débrouiller.

Cette méthode, indiquée dans le livre, est à vrai dire celle qui est utilisée par l'implémentation BASIC de la machine. Chaque routine d'instruction démarre avec HL qui pointe dans le buffer du texte BASIC sur l'octet suivant le token d'instruction, et donc sur ses éventuels paramètres.

C'est donc le cas, comme les autres, de l'instruction CALL. La routine de l'instruction se charge de lire l'adresse puis de l'appeler. Par lecture de ce paramètre, HL a …

Lire la suite →

VG5000µ, nombres aléatoires

Comment donc les nombres aléatoires sont-ils générés sur un VG5000µ. C'est ce que je vous propose de suivre aujourd'hui en décortiquant le code.

Afin de suivre, il est important de comprendre comment les nombres sont stockés sur VG5000µ, et je vous propose pour cela un petit détour par cet article.

Petit rappel avant de commencer : un générateur de nombres aléatoires est une procédure qui émet une suite de nombres sur un intervalle, cette suite tentant d'avoir des propriétés intéressantes qui donnent l'illusion de l'aléatoire. La suite est cependant parfaitement définie, même si pas toujours simple à suivre, et c'est ce que nous allons voir par la suite.

L'initialisation

Tout commence très tôt pour le générateur de nombres aléatoires. Dès l’initialisation de la machine, une série de valeurs est copiée depuis la ROM vers les variables systèmes. Cela se passe en $1071, juste après l'initialisation de l'affichage.

             ld       hl …
Lire la suite →

VG5000µ, jouer avec les nombres

Suite à l'article précédent, j'ai mis sur le dépôt GitHub un petit utilitaire Python qui reproduit les conversions entre la valeur du nombre et son codage en 4 octets.

Parfois, voir du code est plus simple qu'un long discours.

Et parce qu'on ne sait jamais trop quel sera la vie future du dépôt, voici le code des deux principales fonctions de l'outil.

import math


def get_byte(number):
    """Takes the current number, and returns the next byte encoding it with the reminder of the number to encode. """

    number *= 256
    result = int(number)
    return result, (number - result)


def encode(number):
    """Gets a number, returns it's encoded four bytes (memory layout, so exponent at the end)."""

    # If the number is zero, the encoding is immediate.
    # In fact, only the exponent has to be 0.
    if number == 0:
        return [0, 0, 0, 0]

    # Gets the sign from the number for later encoding …
Lire la suite →

VG5000µ, traitement des nombres

Lors d'une discussion sur le forum system-cfg à propos de la fonction RND une question a été posée sur le format des nombres dans le VG5000µ. C'est une question qui revient et que je voulais documenter pour mémoire, me posant régulièrement la question et oubliant juste après...

Différents formats

Distinguons déjà deux choses : les nombres manipulés par le système, et les nombres manipulés par le BASIC. Les premiers sont de diverses formes en fonction des besoins, de type entier, signé ou pas, sur 8 ou 16 bits la plupart du temps. Il n'y a pas grand chose à dire sur eux.

Les seconds sont ceux manipulés par le BASIC, qui est un BASIC Microsoft sur VG5000µ, et ce qui sera valide dans cet article le sera pour d'autres machines avec BASIC Microsoft et un processeur Z80. Au moins dans les grandes lignes, mais pour ce que j'ai vu en comparant …

Lire la suite →

VG5000µ, les hooks d'entrées/sorties

Pour ces quatre nouveaux hooks, je ne suis pas très inspirés. Il s'agit de hook destiné au traitement des entrées sorties. Trois d'entre eux sont appelés lors d'une impression de caractères, le quatrième pour de l'acquisition.

Routines en sorties

Voici les trois premières :

  • $47DF, prthk : début de commande PRINT.
    • Est appelé en tant que première instruction de l'exécution de l'instruction PRINT.
    • À ce moment là, HL pointe vers les arguments de PRINT et le flag Z est à 1 s'il n'y a rien dans ces arguments.
    • Si vous rendez la main à la routine, elle déroulement l'affichage.
  • $47E2, outhk : début d'impression de caractère -> pour rerouter vers de nouvelles sorties
    • Est appelé pour chaque caractère envoyé sur un périphérique de sortie (en $3bd0)
    • La variable système (prtflg) désigne le périphérique.
    • Le caractère à afficher est dans le registre A.
    • Attention, ce caractère est à comprendre par rapport aux modes d'affichage : est-ce …
Lire la suite →

VG5000µ, les hooks d'appel

Dans la série des hooks sur VG5000µ, voyons en cette fois la paire probablement la plus simple. Ça sera donc rapide.

Le hook CALL

Du nom de calhk et d'adresse $47D3, ce hook est utilisé en interne par la commande BASIC CALL.

Le code de cette instruction est extrêmement simple :

inst_call:   call     eval_num_ex
             call     deint_impl
             ld       a,$c3
             ld       (calhk),a
             ld       (calhk+1),de
             jp       calhk

En premier, l'argument passé à CALL est évalué, puis est ensuite transformé en entier sur 16 bits.

Cette adresse, précédée par l'opcode pour JP à une adresse absolue 16 bits est placée dans le hook calhk. La routine saute enfin vers cette adresse, qui agit comme un tremplin vers l'adresse indiquée à l'instruction CALL.

Comme c'est le RET de la routine appelée qui fera office de RET pour l'ensemble de l'instruction CALL, la préservation de l'environnement est à la charge de la routine …

Lire la suite →

VG5000µ, les hooks de périphériques

L'article précédent présentait un accrochage sur un hook d'interruption. Dans cet article, je vais regarder du côté des hooks de commandes de périphériques.

Ces hooks sont initialisés différements des 10 premiers, selon le code qui suit :

             ld       a,$c3
             ld       (inst_lpen),a
             ld       (inst_disk),a
             ld       (inst_modem),a
             ld       hl,no_device
             ld       ($47f2),hl
             ld       ($47f5),hl
             ld       ($47f8),hl

L'instruction placée au début de chaque vecteur de redirection est un JP et l'adresse par défaut est celle d'une routine indiquant que le périphérique n'est pas géré.

Il s'agit d'une extension de commandes mise à disposition par le VG5000µ, permettant de traiter les commandes LPEN, MODEM et DISK. Il est d'ailleurs amusant de voir que dans le manuel d'utilisation, ces trois commandes sont mentionnées dans le rappel des instructions reconnues, mais qu'elles ne sont pas décrites.

Dans la table des instructions, le décodage de ces tokens …

Lire la suite →

VG5000µ, les hooks

Pour cet article, nous allons laisser de côté la partie BASIC-80 pour regarder du côté d'un fonctionnement spécifique au VG5000µ. Pas que le principe soit original, il est présent dans de nombreuses machines, mais que les capacités sont diverses suivant les différentes machines.

Les « hooks » (la traduction de « crochet » me semble un peu hasardeuse, une « accroche » me semble un peu meilleur) est un moyen qu'offre le système pour intervenir lors de certaines opérations en augmentant le fonctionnement de la ROM. En y mettant son grain de sel en quelque sorte.

Plus prosaïquement, les « hooks » sont des appels à des adresses précises, en RAM, à des routines qui peuvent être modifiées. Il peut s'agir aussi sur d'autres machines de récupérer dans une variable système une adresse d'indirection. Sur le VG5000µ, toutes les adresses de « hooks » sont fixes.

Les « hooks » sont parfois aussi appelés vecteurs d'indirection. Ou bien tout simplement vecteurs.

L'initialisation …

Lire la suite →

VG5000µ, les chaînes de caractères

Dans l'article précédent, on avait vu la création d'une variable dans la zone principale de la mémoire. Cette variable a par défaut un contenu nul, et ne s'occupe pas de savoir si ce contenu est un nombre ou une chaîne de caractères. Les quatre octets de contenus qui suivent les deux octets du nom sont donc tous les quatre à $00.

Pour qu'une valeur soit associée à une variable, il faut une instruction d'assignation, directement via LET (éventuellement de manière implicite), plus indirectement avec une instruction FOR, ou encore plus indirectement par un couple READ/DATA.

Dans tous les cas, la valeur à assigner à la variable est le résultat de l'évaluation d'une expression, c'est-à-dire le résultat d'un calcul numérique ou d'une opération à partir de chaînes.

Afin de comprendre comment sont créées et stockées les chaînes de caractères, c'est donc du côté de l'évaluation d'expression qu'il faut …

Lire la suite →

VG5000µ, les variables en mémoire

Pour terminer cette série sur la gestion de la mémoire par le BASIC sur VG5000µ, j'aborde la manière dont sont stockées les variables en mémoire.

Les variables systèmes

On l'a vu dans l'article sur la cartographie de la mémoire, il y a six variables systèmes intéressantes sur ce sujet :

  • (vartab) est la première adresse d'une variable. C'est ici que sont stockés les noms des variables numériques (avec leur valeur) ou chaînes (avec un pointeur vers leur contenu),
  • (arytab) est la première adresse de stockage du contenu des tableaux dimensionnés par DIM (ou bien les tableaux crées par défaut par le BASIC avec un DIM implicite), avec leur nom, leur taille, et leur contenu (ou pointeurs),
  • (strend) est la première adresse de la zone libre de stockage, tout ce qu'il y a à partir de cette adresse et « au-dessus » jusqu'à la pile (pointée par le registre SP) est la mémoire BASIC …
Lire la suite →

VG5000µ, le BASIC cherche ses lignes

Peut-être l'avez vous remarqué, certains programmes en BASIC sont construits avec leur programme principal avec des numéros de ligne « hauts » et ont leurs traitements souvent appelés dans les lignes « basses ».

Ainsi, dans l'article précédent sur le listing, le programme commence par un GOTO 10000 et le décodage de ligne est en 1300. À vrai dire, avant que je ne stocke les adresses des tokens dans un tableau, le décodage systématique de leurs noms étaient dans des lignes encore plus basses.

La raison en est toute simple : lorsque le BASIC sur VG5000µ cherche un numéro de ligne, il le cherche systématiquement depuis le début du programme.

C'est où que ça cherche ?

La routine de recherche de ligne est en $2347 et est appelée par GOTO, RESTORE, RENUM (beaucoup !), LIST, AUTO (à chaque nouvelle ligne), NEW, mais aussi lorsqu'il s'agit d'insérer une nouvelle ligne dans le listing au bon endroit …

Lire la suite →

VG5000µ, un listing en BASIC

Un programme en BASIC qui ferait un listing de lui-même. Reprogrammer l'instruction LIST. C'est un peu inutile, mais cela est un prétexte pour expliquer comment le programme est stocké en mémoire dans la machine.

Le VG5000µ utilise une version du BASIC-80 de Microsoft. Ce BASIC se retrouve sur d'autres machines dans des versions variées, mais dont on retrouve les grands principes.

Structure générale d'un programme en mémoire

Comme on l'a vu précédemment, le BASIC respecte un pointeur vers le début du programme qui se nomme (txttab), situé en $488E. Par défaut avec la ROM interne du VG5000µ, si aucune extension ne l'a modifié, (txttab) vaut $49FC au démarrage.

Chaque ligne est composée par les éléments suivants :

  • Une adresse mémoire (sur 2 octets) vers l'emplacement de la ligne suivante, ou $0000 pour marquer la fin de la liste de lignes,
  • Un numéro de ligne (sur 2 octets) qui correspond au numéro …
Lire la suite →

VG5000µ, une Cartographie de la Mémoire BASIC

Quand j'ai commencé à étudier les documentations sur le VG5000µ, des incohérences sur certains points me sont apparues. Les différentes sources ne donnaient pas les même renseignements. Ou alors je lisais mal. Mais un truc ne collait pas.

En étudiant la ROM, là encore, ça ne collait pas avec les documentations. Mais le code ne ment pas, j'ai donc débuté une quête de la vérité : que se passe-t-il vraiment ?

... ce n'était peut-être pas si épique, mais bon...

L'anomalie qui m'intéresse aujourd'hui est celle de la gestion de la mémoire par le BASIC. Et voici les pièces qui ont provoqué mon étonnement.

Première pièce

La manuel de l'utilisateur, page 46, indique que le premier paramètre de la commande définit la totalité de l'espace occupé par les chaînes de caractères et doit être compris entre -32768 et 32767. Spécifier une mémoire à réserver négative est un peu étrange, et un test rapide …

Lire la suite →

Bonne Année 2019 !

Bonjour à tous. Cette année, j'espère pouvoir faire aboutir un projet autour du VG5000µ que j'ai commencé il y a longtemps et que j'avance petit pas par petit pas.

En attendant, je vous souhaite :

10 B$="AAHGGGGGCB00A@GGGGCBCB00998898=<10"
20 LB=LEN(B$)
30 FOR I=1 TO LB STEP 2
40 A=ASC(MID$(B$,I,1))+ASC(MID$(B$,I+1,1))-64
50 PRINT CHR$(A);
60 NEXT I

À essayer sur votre ancienne machine sous BASIC préférée. Ça devrait être portable sur à peu près toutes les machines avec interpréteur BASIC et des capactités par trop limitées sur les chaînes de caractères (adieu ZX81...). Sur certains, il faudra ajouter LET aux lignes 10, 20 et 40 pour les assignations de variable.

Lire la suite →

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 …

Lire la suite →

Tracé d'un cercle en BASIC sur VG5000µ

Maintenant que nous avons un algorithme pour tracer un cercle ainsi que le moyen d'afficher un gros pixel à l'écran, nous voilà prêts pour traduire tout cela en BASIC, comme cela a été fait auparavant avec le segment de droite.

Pour rappel, voici l'implémentation en BASIC d'affichage d'un point à l'écran.

100 REM AFFICHE UN POINT DANS L'ESPACE SEMI-GRAPHIQUE
110 REM X CONTIENT L'ABSCISSE ENTRE 0 et 79
120 REM Y CONTIENT L'ABSCISSE ENTRE 0 et 74
130 ZX=INT(X/2):ZY=INT(Y/3)
140 RX=X-ZX*2:RY=Y-ZY*3
150 CH=2^(RY*2+RX)
160 DI=&"4000"+ZY*80+ZX*2
170 AT=PEEK(DI+1)
200 OL=64:IF (AT AND 128) = 128 THEN OL=PEEK(DI)
220 IF (OL AND 128) = 128 THEN OL=64
230 POKE DI,OL OR CH
240 POKE DI+1,224
250 RETURN …
Lire la suite →

Après la ligne, le cercle

Après avoir tracé des segments de droite à l'écran grâce au BASIC du VG5000µ, passons au cercle.

Si vous avez fait un peu de trigonométrie à l'école, vous devez savoir que, pour un angle α allant de 0 à , tracer des points aux coordonnées (cos(α), sin(α)). Ces coordonnées sont multipliées par le rayon et déplacées au centre du cercle. Et c'est comme cela qu'il peut sembler de prime abord intéressant de tracer un cercle.

Cela ressemble à quelque chose comme ça.

  • initialiser cx et cy avec les coordonnées du centre du cercle, r avec son rayon
  • initialiser a à 0
  • tant que \(a < 2\pi\)
    • \(x = cx + r.cos(a)\)
    • \(y = cy + r.sin(a)\)
    • tracer un point en (x, y)
    • augmenter a
  • fin

Super simple.

Mais trop simple.

Dans l'algorithme ci-dessus, la ligne qui indique augmenter a n'indique pas de combien il faudrait augmenter a.

Lorsque …

Lire la suite →

VG5000µ, tracer une ligne en BASIC

Après avoir décrit un algorithme de tracé de segment de droite de manière générique, voyons un peu comment traduire ça en BASIC sur le VG5000µ. Pour ce premier article, il s'agira d'une implémentation simpliste, qui servira de base.

Pour rappel, voici l'algorithme générique :

  • En entrée, on a deux points de coordonnées (x, y) et (x', y')
  • Si x' est plus petit que x, échanger les valeurs de x et x' ainsi que de y et y'
  • Choix de l'octant en fonction de |y' - y| et de |x' - x|
  • Si on fait un balayage des x, alors
    • Calculer la pente \(a = \frac{(y' - y)}{(x' - x)}\)
    • Calculer \(b = \frac{x'y - xy'}{x'-x}\)
    • Pour tous les x'' de x à x', calculer \(y'' = ax'' + b\).
    • Tracer un pixel en (x'', y'').
  • Si on fait un balayage des y, alors
    • Si y' est plus petit que y, échanger les valeurs de x …
Lire la suite →

Après le point, la ligne

Après avoir vu le point, si nous passions à la ligne ? Ou plus exactement, au segment de droite.

Sur une feuille de papier, tracer un segment de droite entre deux points est une chose simple : un crayon, un règle, on positionne la règle sur les deux points et l'on trace un trait en tenant fermement cette dernière.

Le trait a alors une allure continue ; du moment que l'on n'utilise pas un microscope pour en détailler la composition. Et c'est une représentation suffisante, dans la plupart des cas, de l'objet mathématique sous-jacent.

Sur un écran d'ordinateur, c'est un tout autre problème. En effet, un écran traditionnel est constitué d'une matrice de petits carreaux, les pixels. Les pixels des écrans récents sont très petits et malgré cela, tracer un beau segment de droite n'est pas si simple. Alors imaginez avec les gros carreaux formant les affichages d'anciens ordinateurs ?

Plutôt que de l'imaginer …

Lire la suite →

VG5000µ, SetPoint en BASIC, l'implémentation

Ça y est, après avoir vu la structure des caractères semi-graphiques, l'arrangement en mémoire des valeurs d'affichage et fait un essai de manipulation de ces valeurs, nous voici prêts pour écrire un morceau de programme qui peut prendre en entrée des coordonnées et allumer ou éteindre un point à l'écran.

Le BASIC est un langage, dans les versions de l'époque de cette machine, assez limité. Il n'y a entre autre pas de notion de portée lexicale des variables. La portée lexicale d'une variable, c'est l'ensemble des parties d'un code source depuis lesquelles une variable, ou plus généralement un symbole, est accessible. En BASIC sur VG5000µ, comme sur les BASIC d'autres machines de cette période, c'est simple, les variables simples sont accessibles de partout à partir du moment où elles ont été définies.

À cela s'ajoute le fait que seuls les deux premiers caractères d'une variable sont significatifs. ABC et ABD …

Lire la suite →