Triceraprog
La programmation depuis le Crétacé

Injecter un programme dans un émulateur VG5000µ ()

Reprenons sur la programmation en assembleur sur VG5000µ depuis un ordinateur actuel. Car s'il est possible et tout à fait légitime, par hobby, de programmer directement sur la machine, à l'ancienne, pour « retro programmer » comme il y a du « retro gaming » en éprouvant les sensations originelles, ce n'est pas mon but ici.

Mon but, c'est de pouvoir programmer depuis un éditeur de texte simple, mais pas trop, et de pouvoir mettre au point avec certaines facilités comme un retour d'erreur d'assemblage et l'accès à un debuggeur. Et tout ceci avec une chaîne qui minimise les manipulations répétitives.

Minimiser les manipulations répétitives permet de rester concentré au maximum sur ce que je fais. Je n'ai pas envie, à chaque lancement, de taper des commandes particulières ou de faire quelques clics souris, toujours les mêmes, avec un risque de me tromper et de chasser un bug que je crois être là alors que je me suis juste trompé dans une manipulation.

Il y a de nombreuses manière d'automatiser une chaîne de construction de programme. Certains choix sont contraints par les outils que l'on utilise. D'autres sont des choix par préférences.

Après avoir fait mon travail de reflexion, lorsque je passe à la partie d'entrée au clavier, les données sont les suivantes :

  • j'entre le code source dans un éditeur,
  • j'effectue une action qui produit un fichier binaire,
  • ce fichier binaire doit se lancer dans un émulateur et/ou produire un fichier pour chargement sur machine réelle,
  • s'il y a des erreurs, les afficher,
  • s'il n'y a pas d'erreurs l'émulateur se lance automatiquement et lance à son tour le programme.


Cette dernière opération est mon point de départ et le sujet de cet article. Vous aurez compris au passage, et suite à l'article précédent, que j'utiliserai un émulateur pour la mise au point, avant de passer sur machine réelle pour confirmation du fonctionnement.


Choix de l'émulateur

Au niveau VG5000µ, au moment de l'écriture, il n'y a pas beaucoup de choix : soit DCVG5K, soit MAME. Les deux possèdent un debuggeur et le moyen d'injecter un binaire en mémoire.

Je vois en MAME deux avantages pour moi : la possibilité de scripter le debuggeur et le lancement en natif sous Linux, qui est derrière le système d'exploitation que j'utilise (Ubuntu). DCVG5K a l'avantage de la légèreté dû au fait qu'il est dédié à une seule machine, ainsi que de la simplicité d'utilisation.

Pour savoir comment utiliser MAME, c'est très simple, il suffit de taper mame -showusage en ligne de commande... Ooops... 462 lignes d'explication de paramètres... Et ce n'est qu'un résumé.

MAME est un gros morceau et j'espère qu'avec les renseignements de cet article, je vous aurait débrousaillé le terrain.


Lancement de l'émulation

Avant toute chose : tout ce que j'explique est du lancement en ligne de commande. Il est possible de faire la même chose à travers des fichiers de configuration ou des raccourcis Windows avec paramètres mais le but final est d'inclure ça à un script de lancement. La ligne de commande est aussi la manière la plus simple de jouer avec les paramètres (pour peu qu'on utilise un shell moderne).

Pour lancer l'émulation du VG5000µ, c'est tout simplement :

mame64 vg5k

Note : l'exécutable s'appelle mame64 pour quoi car je compile la version depuis les sources. Suivant les distributions de MAME, il peut avoir un autre nom.

Note : Si MAME vous annonce qu'il vous manque une ROM, revenez à mon article précédent, dumpez votre ROM, placez-là dans le répertoire attendu par MAME et c'est reparti.

Le lancement de l'émulateur dans cette configuration lance la machine après un bandeau la présentant et, à l'heure actuelle, un bandeau rouge indiquant que l'émulation ne fonctionne pas. En effet, l'émulation n'est pas considérée comme terminée ; mais en ce qui nous concerne, cela sera suffisant.

J'ai évoqué un debuggeur. Il est accessible sous plusieurs formes et je vais laisser celle par défaut :

mame64 vg5k -ramsize 48k -nomax -window -debug

J'ai ajouté au passage quelques options supplémentaires :

  • -ramsize 48k indique que je veux l'extension RAM maximale disponible sur le VG5000µ (l'autre option est 32k, et par défaut, la machine aura ses 16k)
  • -nomax indique que je ne veux pas maximiser la fenêtre
  • -window indique que je veux lancer l'émulateur dans une fenêtre et non en plein écran
  • -debug, bien entendu, lance le debugger


En mode debugger par défaut, l'émulation ne se lance pas tout de suite. Elle est immédiatement mise en pause. Sur l'image suivante, vous pouvez voir que le PC est à $0000, sur la première instruction qui sera exécutée par le processeur de la machine jp $1000.

Debugger par défaut (Qt) sur MAME

Ce debugger accepte des raccourcis clavier mais peut aussi accepter des commandes. Le debugger peut aussi prendre ses commandes depuis un fichier texte grace à la commande source.

Je vous invite à entrer le texte suivant dans un fichier debug.txt.

go $2adf
load hello.bin,$7000
go

Note : go $2adf indique de lancer l'émulation avec un point d'arrêt temporaire à l'adresse $2adf, qui est une addresse qui, lorsqu'elle est atteinte, garanti que le VG5000µ a terminé son initialisation.

Puis d'avoir un fichier binaire au nom de hello.bin de mettre ces deux fichiers dans le répertoire de travail de MAME.

Et enfin, depuis le debuggeur, taper source debug.txt

Le debuggeur devrait afficher :

>go $2adf
Stopped at temporary breakpoint 2ADF on CPU ':maincpu'
>load hello.bin,$7000
Data loaded successfully to memory : 0x7000 to 0x7018
>go

Suivant votre fichier, l'addresse 0x7018 peut varier. Dans mon cas, le fichier provient du résultat de l'assembleur d'un article précédent.

Dans le debuggeur, vous pouvez ouvrir une fenêtre de visualisation de mémoire pour vérifier que le fichier binaire a été injecté. Et si votre fichier est le même que le mien, vous pouvez entrer CALL &"7000" dans la machine émulée pour voir apparaître Bonjour! à l'écran.

C'est déjà bien, non ?


Automatique on a dit !

C'est bien... mais taper source à chaque lancement, c'est long, on peut se tromper et cela serait mieux si cela pouvait être automatique.

Et c'est tout à fait possible :

mame64 vg5k -ramsize 48k -window -nomax -debug -debugscript debug.txt

-debugscript, comme son nom l'indique, fourni un nom de script pour le debugger qui sera exécuté au démarrage. Juste après le lancement de l'émulateur, le fichier binaire est donc injecté sans manipulation.

D'accord, mais il faut encore taper la commande CALL &"7000" pour lancer le programme, et avec la disposition d'un clavier qui change entre la machine émulée et la machine hôte, personnellement, je trouve cela fastidieux (surtout pour la touche ", qui est une touche morte dans ma configuration par défaut).

Pas de problème :

mame64 vg5k -ramsize 48k -window -nomax -debug -debugscript debug.txt -autoboot_command 'CALL &"7000"\n' -autoboot_delay 2

  • -autoboot_command indique la chaîne à passer à l'émulateur comme si les touches étaient appuyées,
  • -autoboot_delay pose un délai de 2 secondes avant de lancer les commandes, ce qui laisse le temps au script de s'exécuter.


À vrai dire, le délai de 2 secondes est la valeur par défaut, mais l'idée était de montrer la commande, pour pouvoir ajuster le délai.

Là, ça commence à être pas mal.


Mais...

Mais il y a deux choses encore qui me chiffonnent. Tout d'abord, la fenêtre du debuggeur se place au-dessus de ma fenêtre d'émulation, et je dois systématiquement la bouger pour voir le résultat. Il y a bien la possibilité d'utiliser la commande -debugger none, mais alors le script n'est plus exécuté.

Il y a la possibilité d'utiliser un debuggeur qui utilise la bibliothèque imgui et qui s'affiche dans la fenêtre d'émulation. Je vous suggère alors de passer -nomax en -max. Possibilité aussi pour le debugger par défaut (mais imgui est semi-transparent, le debugger par défaut opaque).

mame64 vg5k -ramsize 48k -window -max -debug -debugscript debug.txt -autoboot_command 'CALL &"7000"\n' -autoboot_delay 2 -debugger imgui -video bgfx

Cela donne déjà de quoi s'amuser et automatiser la chaîne de développement. Il y a cependant moyen d'aller encore plus loin avec MAME. Ça sera pour la prochaine fois.

Debugger utilisant ImGUI sur MAME