Triceraprog
La programmation depuis le Crétacé

Injecter un programme dans un émulateur VG5000µ, partie II ()

La fois dernière était consacrée au lancement d'un programme sur VG5000µ avec l'émulateur MAME de manière à injecter un programme binaire directement en mémoire puis à l'appeler. Tout cela automatiquement. Pour rappel, l'idée derrière cela est d'éviter les erreurs de manipulations qui arrivent de temps en temps.

La première option utilisée dans l'article précédent était d'utiliser un script pour le debuggeur d'une part, et la capacité de MAME à entrer au clavier de la machine émulée une suite de frappes de touches.

Cette méthode fonctionne mais a ses limites : il faut régler le délai avant la frappe de touches de manière empirique, et le script est linéaire. Dans cet article, je vais utiliser une autre possibilité de MAME pour résoudre ces deux écueils.

La console

Commençons par une première manipulation.

mame64 vg5k -ramsize 48k -nomax -window -debug -debugger none -console

Dans le shell depuis lequel vous avez entré cette commande s'affiche un bandeau et une invite [MAME]>. Vous avez à présent accès à une console qui comprend le LUA. C'est bien entendu le paramètre -console qui a permis cela.

Le couple -debug -debugger none est plus surprenant. Il indique que le debuggeur est activé, mais sans interface graphique. Le debuggeur est donc utilisable depuis la console, et c'est parfait. Au passage, vous remarquerez que, en l'absence d'interface graphique pour le debuggeur, l'émulateur ne s'est pas mis en pause.

Depuis la console, vous pouvez essayer ceci :

m = manager:machine()
md = m:debugger()
print(md)

Vous devez voir quelque chose comme sol.debugger_manager*: 0xf9de9a8 qui indique que md contient bien un debuggeur (l'adresse sera différente). Si vous obtenez nil, c'est que le debuggeur n'est pas actif.

L'object md permet de s'adresser au debuggueur.

Par exemple :

md:command("help")

Et l'aide du debuggeur s'affiche. Nous communiquons bien avec le debuggeur. C'est pratique.


Script LUA

Mais si une console est pratique pour essayer des choses, ce n'est pas ce que je recherche au final. Ce que je recherche à faire est toujours automatiser le démarrage d'un programme pour sa mise au point.

Et MAME a la commande qu'il me faut : -autoboot_script. Cette commande, suivie par un nom de fichier, va exécuter un script écrit en LUA qui aura accès au fonctionnement de l'émulateur.

La commande pourra ressembler à quelque chose comme ça :

mame64 vg5k -ramsize 48k -nomax -window -debug -debugger none -autoboot_delay 0 -autoboot_script vgboot.lua

-autoboot_delay 0 indique que le script doit être lancé dès le démarrage de l'émulation de la machine. La première chose (ou presque) à faire dans le script si vous voulez contrôler la machine cible dès le début est alors un emu.pause() que vous pourrez balancer avec un emu.unpause() lorsque votre script sera prêt.

Le script que j'utilise est trop long pour s'afficher sur cette page. Vous pouvez le trouver ici.

Des choses intéressantes à savoir :

  • manager:machine() renvoie l'objet contrôlant machine émulée,
  • manager:machine():debugger() renvoie l'objet de contrôle du debuggeur,
  • manager:machine():debugger().consolelog est le log du debuggeur, pratique pour vérifier les retours de commandes,
  • manager:machine().devices[":maincpu"] renvoie l'objet contrôlant le CPU principal de la machine (le Z80 pour le VG5000µ),
  • manager:machine().devices[":maincpu"]:debug() renvoie l'objet de commande du debuggeur sur ce CPU (qui offre des facilités sur les commandes du debuggeur pour ce processeur en particulier).

Sur l'objet renvoyé par debug() sur le CPU, par exemple, on peut appeler bpset() pour placer un point d'arrêt. Sur l'objet renvoyé par debugger(), on peut envoyer tous les commandes que l'on entrerait dans l'interface graphique avec command().

Ainsi ...:debugger():command("go") a le même effet, sur cette machine, que ...:debug():go().

L'objet emu qui permet de faire pause() et unpause() permet aussi de simuler les appuis sur les touches du clavier émulé. Par exemple emu.keypost('CALL &"7000"\n').


C'est plus complexe !

Oui, cette méthode est plus complexe, plus longue à écrire. Elle permet aussi un meilleur contrôle et des choses que ne permettent pas un script de debuggeur simple. À vous de choisir !

La console LUA dans MAME