Si vous aussi vous jetez régulièrement un œil sur les adressages possibles et valides pour le 6502,
voici un tableau récapitulatif qui pourra vous servir. En tout cas, il me servira.
Cela aura pris un peu de temps, entre autres raisons car d'autres activités se sont invitées entre-temps, mais ACCEPT est enfin implémenté ! ACCEPT est un mot qui lit une ligne de texte entrée par l'utilisateur et la stocke dans une adresse mémoire fournie lors de l'appel. Généralement, cette adresse est le TIB (Terminal Input Buffer), qui sera ensuite fournie à l'interpréteur Forth.
Comme indiqué lors du précédent article, se posait la question de savoir comment récupérer les données. J'ai tenté deux versions et je suis finalement partie sur celle que je pressentais : utiliser la mémoire PPU pour stocker les données en cours d'édition, puis les récupérer lorsque la touche RETURN est appuyée.
Oui, mais... même si la mémoire représentant les caractères est linéaire, depuis le début de l'implémentation j'ai réservé des caractères sur les bords de l'écran pour ne rien y afficher, afin de respecter les marges nécessaires …
En attendant le prochain article de la série sur le développement d'un Forth sur Famicom, qui prend un peu de temps, je voulais faire une petite aparté pour présenter les deux livres qui m'accompagnent, en plus de différentes ressources en ligne.
En effet, un livre que l'on peut feuilleter, où on peut retrouver un passage rapidement, c'est pratique.
Making Games for the NES
Le premier livre est en anglais et aborde le développement de jeux pour la NES, et donc pour la Famicom. Très progressif, il amène chaque aspect de la machine avec clarté. Pas forcément dans les plus obscurs des détails et c'est aussi ce qui est intéressant : c'est une bonne première approche.
Le livre date un peu. Ça n'est pas très important pour la console elle-même, qui n'a pas bougé, mais quelques outils évoqués ne sont plus forcément les meilleurs choix.
Le clavier est pour le moment implémenté avec deux mots. L'un qui sera gardé, KBDSCAN et l'autre qui est là en attendant de pouvoir écrire la même chose en Forth, KBDPROCESS. L'objectif premier est de transformer KBDPROCESS en son équivalent Forth que je placerai dans ma boucle principale (pas encore QUIT, qui n'est pas encore prêt).
Mais avant toute chose, j'ai quelque chose à corriger avec le curseur. Pour le moment, j'affiche le curseur avec EMIT, ce qui fait avancer la prochaine position d'affichage de caractère. Ce que je veux, c'est afficher le caractère reçu du clavier avec EMITpuis afficher le caractère du curseur sans faire avancer la position d'affichage. Ainsi, le caractère du curseur sera toujours une position après le dernier caractère affiché.
Pour cela, j'ai un peu remanié le code afin de séparer l'envoi du caractère à afficher et la mise …
C'est triste un démarrage de Forth... COLD, ABORT, QUIT. On aurait pu imaginer des mots comme WARMUP, READY, LOOP. Mais je n'ai pas prévu de renommer les mots standards de Forth. Et comme indiqué dans l'article précédent, il est temps de déplacer le code de démarrage vers les mots officiels.
Et à vrai dire, comme prévu, il n'y avait pas grand chose à faire.
Tout d'abord, le code de démarrage devient juste initialiser l'interpréteur avec le mot COLD :
boot_forth:; Set the Work Register to the first word to execute:lda#<COLD_word_cfastaREG_Wlda#>COLD_word_cfastaREG_W+1; And use itjmpdocol
Et pour faire simple, ABORT et QUIT appellent juste des mots cachés qui contiennent le code assembleur que j'avais déjà. Cela donne :
; COLDDEFINE_FORTH_WORDCOLD,0,0.wordRESET_ENV_word_cfa.wordABORT_word_cfa; ABORT never returns, no need for DO_SEMI; ABORTDEFINE_FORTH_WORDABORT,COLD,0.word …
Lors du précédent article, l'ajout de variables et de la pile des paramètres nous a approché de l'objectif actuel : afficher des caractères à l'écran. Ou plus exactement, remplacer l'affichage de la chaîne de caractères depuis l'assembleur au démarrage du programme vers la partie Forth.
Pour commencer et s'assurer que j'ai du code qui peut transformer des coordonnées en adresse PPU et afficher un caractère, je crée un mot TEST_EMIT qui va prendre ces coordonnées et afficher un unique caractère comme curseur. Comme je n'ai que 26 lettres majuscules actuellement dans mes données graphiques, il est temps d'aller modifier les données. J'ajoute en caractères 255 un carré plein. Cela fera un bon curseur.
Il me faut aussi deux variables pour stocker les coordonnées du curseur : CURSOR_X et CURSOR_Y que j'initialise à l'emplacement où je veux afficher le curseur au démarrage (en effet, je n'ai pas encore de moyen …
L'étape d'aujourd'hui va permettre de se diriger vers l'affichage d'un texte à l'écran depuis la boucle Forth. Pour cela, il faut revenir un peu sur le fonctionnement de la Famicom.
Le processeur qui s'occupe de l'affichage est le PPU (Picture Processing Unit). Ce processeur a son espace d'adressage mémoire propre de 16 ko dont le routage est configuré par la cartouche insérée. Dans la console, 2 ko de RAM sont dédiés au PPU, assez pour stocker les informations de deux écrans (index de caractères et attributs). La cartouche doit apporter a minima les informations de caractères (en ROM généralement, mais peut aussi offrir un espace RAM pour les construire) ; elle peut aussi étendre le nombre d'écrans (jusqu'à 4) ou ajouter un système de banking de pages.
De manière générale, tout le mapping de la mémoire du PPU est contrôlé par …
Depuis le début de l'implémentation de ce Forth sur 6502, j'ai parlé de « pseudo mots ». Ces mots ont un CFA (Code Field Address) et un PFA (Parameter Field Address), mais pas d'entête de mot ni de principe de dictionnaire.
Or pour qu'un mot soit complet en Forth, il faut ces deux autres concepts. Dans cette implémentation je vais utiliser deux autres sections : le NFA (Name Field Address) et le LFA (Link Field Address).
Ce qui donne la structure complète suivante :
NFA : entête du mot, dont le premier octet est la longueur du nom du mot, suivi du nom lui-même. Seuls les 5 bits de poids faible sont utilisés pour la longueur (ce qui limite la longueur des noms à 31 caractères). Le bit de poids fort est toujours à 1, les deux autres bits seront vus plus tard. De plus, le dernier octet du nom a …
Jusqu'à présent, la boucle principale du programme en Forth était basée sur un hack. Ce hack consistait à réinitialiser l'IP (Instruction Pointer) à la fin du traitement. C'est un peu comme si à chaque fois qu'on avait fini le traitement, on relançait le programme depuis le début.
Il est temps d'implémenter un nouveau mot Forth : BRANCH. Ce mot, suivi dans le PFA par un offset, opère un saut inconditionnel en additionnant cet offset à l'IP courant. En choisissant un offset négatif, l'exécution va revenir en arrière et donc créer une boucle infinie.
Le pseudo code est le suivant :
(IP) -> X lit l'offset pointé par l'Instruction Pointer
L'IP ayant été positionné sur l'emplacement après le mot BRANCH
par NEXT.
IP + X -> IP ajoute l'offset à l'IP
NEXT appelle NEXT pour continuer l'exécution
Nous y voilà ! Après avoir mis en place un framework de tests dans l'article précédent, il est temps d'implémenter le mot NEXT.
Un petit rappel du premier article de Moving Forth : NEXT est le mot qui permet de faire avancer l'exécution d'une séquence de pointeurs vers des mots Forth. Son pseudo-code (en modèle Indirect Threaded Code) est le suivant :
En 6502, le code est un peu long, car l'adressage indirect nécessite de passer par des registres en page zéro. Et les manipuler demande plusieurs instructions. Je …
Depuis le dernier article, je me suis surtout concentré sur la mise en place d'un framework de tests, ainsi que sur une réflexion de « comment commencer » ?
La lecture de l'article 2 de Moving Forth m'a donné une liste de mots à implémenter en priorité : NEXT, DOCOL et ;S. Cela afin d’arriver rapidement sur une boucle écrite en Forth. J'y reviendrai plus loin dans l'article.
Côté tests, ça a été une aventure en plusieurs étapes. Dans l'idée d'augmenter le nombre de tests, je voulais m'appuyer sur un framework de tests LUA tout fait. J'en ai trouvé un, luaunit qui m'a semblé tout à fait répondre à mes attentes. Pour l'utiliser, je dois utiliser un require("luaunit") dans mon script de tests. Et là ont commencé les ennuis. Tout d'abord, require() n'est pas permis par défaut dans Mesen2, il faut aller permettre les fonction E/S dans les …
Avant de passer à la lecture de l'article 2 de la série Moving Forth, je veux mettre en place un projet « minimal ». Plus exactement, c'est initialement ce que je voulais faire, avec un petit code source pour Famicom qui affiche un texte, un Makefile et bien entendu, un framework de tests.
Mais les notes que j'avais prises sur la Famicom remontaient à un petit moment, et il y a quelques trucs à initialiser avant d'afficher un caractère à l'écran. J'ai donc cherché un squelette de projet déjà fait. Sur une machine populaire, ça doit bien
exister.
Mon choix s'est porté sur Nes Template de Mike Moffitt. Le squelette n'est
pas minimaliste, mais a une bonne base, avec un système de configuration flexible pour la ROM destination, et assez de quoi
écrire un message à l'écran, ainsi que manipuler des banques de mémoire. C'est bien écrit, bien …
En m'intéressant au langage de programmation Forth, j'ai parfois croisé l'affirmation que pour bien comprendre Forth, il fallait en développer un.
C'est cohérent avec son histoire, qui débute comme une trousse à outils de son inventeur pour lui faciliter les développements qu'il fait pour ses employeurs.
J'ai lu un certain nombre de documents sur Forth, parcouru quelques implémentations et même développé un jeu dans ce langage pour Hector HRX.
Plus récemment, en m'amusant avec le BASIC pour Famicom, je me suis demandé ce qui pourrait être développé sur la console pour tirer parti du clavier. Alors, pourquoi pas un Forth interactif sur Famicom ?
Une rapide recherche m'a montré que des expériences en Forth pour Famicom avaient déjà été faites, mais pas forcément sous l'angle interactif. Et bien entendu, il existe déjà des Forth pour 6502, le processeur qui équipe cette machine (même si c'est une version …
Ça y est, la nouvelle saison des Retro Programmers United for Obscure System a démarré. Et cette fois, c'est le PHC-25 qui est à l'honneur. Un ordinateur de Sanyo à base de Z80 (d'un clone plus précisément) et d'un MC6845 (... un clone aussi) et plutôt bien fourni en mémoire vive pour cette classe de machines : 16 ko de RAM et 6 ko pour la VRAM, accessible directement par le Z80 (avec des contraintes de timing si on veut éviter des parasites graphiques).
Bien entendu, comme toutes les machines concernées par cette game jam, le PHC-25 est un ordinateur qui n'a pas une grande logithèque, et pas non plus beaucoup d'activité ni de documentation. C'est le principe.
Pour cette Jam, je suis parti sur l'idée que le programme sera en assembleur. Certains vont certainement encore faire des miracles en BASIC, mais ce n'est pas ma tasse de thé, même si je …
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 …
Avec la nouvelle session de Retro Programmers United for Obscure Systems,
il est temps de découvrir la ligne des Hector HR. Que ce soit l'Hector 2HR, le 2HR+,
le HRX et probablement le MX.
Pour en savoir plus sur ces ordinateurs, il existe une page dédiée à ces machines.
Après avoir cherché un peu dans les resources Hector, je me suis dirigé pour ma contribution à cette
session vers le « Hector HRX » et son Forth. En effet, le HRX est un de ces rares ordinateurs 8 bits
qui venait avec un Forth en ROM, au lieu du plus classique BASIC.
Il existe un livre sur le Forth pour Hector HRX, « la pratique du Forth avec Hector », qui est plutôt
agréable à lire afin de découvrir la machine à travers ce langage, et pourquoi pas, découvrir le Forth
au passage.
L'ennui avec le livre, c'est qu'il présente les mots en contexte …
Il y a peu, j'ai eu une discussion à propos de l'apprentissage de l'assembleur. La discussion était partie de l'envie d'une personne de créer un jeu sur MSX, mais directement au niveau de la machine, plutôt que de passer par un langage de haut niveau, comme le BASIC natif. Et pourquoi pas. Une donnée importante : la personne en question connaît déjà la programmation, c'est donc un abord de nouveau langage dont on parle, et non des concepts généraux du développement d'un programme.
Lorsque l'on aborde un langage de plus haut niveau, que ce soit BASIC ou Pascal, on va se concentrer sur la manière d'exprimer des concepts dans ce langage en particulier. Lorsque l'on connaît déjà un autre langage de même famille (large), il s'agit même souvent de comprendre quelle sont les particularité du langage appris.
Lorsque l'on aborde une machine en particulier dans un langage de haut niveau, il …
Quand je vois passer des mentions du langage LOGO, elles sont généralement peu flatteuses. C'est compréhensible, la plupart des personnes qui se souviennent de ce langage de programmation y ont été exposées pendant leurs jeunes années d'études, lors du Plan Informatique pour Tous. Peu sont ceux qui ont creusé plus tard ce qu'ils avaient découverts au moyen d'ordinateurs poussifs et de cours pas toujours maîtrisés par des enseignants pas toujours bien convaincus.
Mes quelques souvenirs de séances en salle informatiques sont plutôt sur des activités de manipulation du crayon optique sur « Colorpaint ». Je ne sais plus si j'ai fait du LOGO en classe, mais c'est probable. Je me souviens cependant avec netteté la rencontre avec un professeur, lors de la fréquentation d'un « club informatique » pendant des vacances, qui pour une raison ou une autre (mon intérêt enthousiaste à la programmation ?) m'a donné quelques cours de LOGO. Et lors d'une conversation …