Communitygithub.com

JoshRodd/86Box-tool

Outils pour instrumenter 86Box

Qu'est-ce que 86Box-tool ?

Ce skill fournit un ensemble d'outils et de procédures pour contrôler, configurer et déboguer des machines virtuelles 86Box. Il est utile pour les développeurs et les utilisateurs avancés qui ont besoin d'automatiser le cycle de vie des VM (démarrage, arrêt, redémarrage), d'inspecter l'état de l'invité (écran, console, mémoire) et de gérer des configurations ROM complexes, notamment pour les machines IBM PS/2 Model 80. Le skill supporte macOS (via l'application 86Box) et les builds avec support GDB (option -DGDBSTUB=ON) pour le débogage avancé. Il repose sur un script shell `86boxctl.sh` et des utilitaires Python (`rsp.py`, `screenmon.py`, `guest_console.py`) pour interagir avec la VM via le stub GDB, un serveur memdump, ou la console invité. Il impose des règles de sécurité strictes (identification par PID, pas de `killall`, etc.) pour éviter de perturber d'autres processus 86Box. Les fonctionnalités incluent la création de ROMs clonées, la vérification de l'intégrité des fichiers ROM, et la capture d'événements de l'invité (delta d'écran, changements de registres).

Compatible avec~Claude Code~Codex CLI✓Cursor
npx skills add JoshRodd/86Box-tool

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Opérations des machines virtuelles 86Box

Utilisez ce skill dès qu'une tâche nécessite de démarrer, configurer, attendre, redémarrer, déboguer ou inspecter une machine virtuelle 86Box.

Règles de sécurité non négociables

  1. Résoudre le répertoire exact de la VM avant le lancement.
  2. Lancer avec --vmpath <répertoire VM> --vmname <nom d'affichage>.
  3. Enregistrer le PID retourné pour ce lancement ainsi que le nom stable du processus du harnais.
  4. Vérifier l'identité du PID en utilisant l'exécutable et le --vmpath exact avant tout signal.
  5. Ne jamais utiliser killall, pkill large, pgrep large, ou un PID non vérifié.
  6. Supposer que d'autres personnes exécutent des processus 86Box indépendants.
  7. Privilégier un arrêt propre de l'interface utilisateur lorsque la NVRAM ou les changements de configuration sont importants.
  8. Ne jamais écraser des ROMs partagées pour une expérience sur une seule VM ; cloner un ensemble complet de ROMs et le sélectionner avec --rompath.

Pré-vol

  1. Résoudre un nom sous la racine des VM de la plateforme. Sur macOS :

    ~/Library/Application Support/86Box/Virtual Machines/<NOM>
    

    Un chemin direct de VM est également valide.

  2. Lire <VM>/86box.cfg. Enregistrer :

    • machine;
    • cpu_use_dynarec;
    • gdbstub_port optionnel ;
    • les périphériques et adaptateurs multimédia configurés.
  3. Choisir le binaire :

    • interaction normale : /Applications/86Box.app/Contents/MacOS/86Box;
    • débogage de l'invité : la build locale -DGDBSTUB=ON.
  4. Auditer la commande (exécuter depuis la racine du projet 86Box-tool, ou l'installer) :

    cd ~/src/86Box-tool && uv run ./86boxctl.sh <VM> command
    
  5. Si vous déboguez plusieurs VM, exigez un gdbstub_port distinct dans chaque configuration et cpu_use_dynarec = 0.

Lancement

Contrôleur autonome :

./86boxctl.sh <VM> start
./86boxctl.sh <VM> start --gdb-stub

BIOS IBM PS/2 Model 80 Type 2 corrigé :

./86boxctl.sh <VM> command \
  --model-80-type-2-rom /chemin/vers/sequential-128k.bin
./86boxctl.sh <VM> start \
  --model-80-type-2-rom /chemin/vers/sequential-128k.bin

La VM doit utiliser machine = ibmps2_m80. Le contrôleur découvre la racine standard des ROMs de la plateforme, clone l'arborescence complète sous <VM>/romsets/, sépare l'image dans les fichiers de voie paire/impaire actifs, les valide, et lance avec cette racine générée via --rompath. Utilisez --rom-source lorsque la découverte est ambiguë. Utilisez prepare-roms pour construire sans lancer.

Pour une session GUI longue médiée par un harnais, démarrez l'exécutable via le gestionnaire de processus du harnais avec :

name        = nom stable unique tel que 86box-automatic-configuration
application = binaire 86Box sélectionné
args        = [--vmpath, <chemin absolu de la VM>, --vmname, <nom d'affichage>]
pty         = false
persist     = true lorsque l'interaction s'étend sur plusieurs tours

Enregistrez le PID retourné. Utilisez uniquement ce nom de processus stable pour les opérations describe, logs, restart et stop ultérieures. Un redémarrage produit un nouveau PID ; enregistrez-le.

Ne passez pas 86box.cfg comme argument positionnel unique. Cela sélectionne une configuration mais ne définit pas le chemin des fichiers utilisateur de la VM 86Box, ce qui peut entraîner une résolution des médias relatifs, de la NVRAM et des ROMs locales dans le mauvais répertoire.

Établir l'état de disponibilité

La création du processus seule n'est pas une preuve de disponibilité de l'invité.

  • Build normale : exiger que le processus exact survive au démarrage, puis inspecter la VM visible ou un artefact concret de la VM.
  • Build GDB : exiger que le port RSP configuré de cette VM écoute.
  • Ne jamais interpréter un autre processus 86Box ou port comme preuve pour cette VM.

Utilisez :

./86boxctl.sh <VM> status
./86boxctl.sh <VM> logs --lines 100

Attendre un utilisateur

Lorsque l'utilisateur dit d'attendre jusqu'à une interruption du harnais, faites exactement cela. N'avancez pas lorsque la VM se termine sauf si l'utilisateur a demandé un travail déclenché par la sortie. L'attente du travail du harnais ne traite pas un processus GUI géré comme un travail d'arrière-plan, donc créez une sentinelle d'attente asynchrone longue et finie, attendez ce travail avec un délai d'attente indéfini du harnais, et annulez-le après l'interruption de l'utilisateur.

Gardez le processus VM suivi séparément par son nom de processus stable et son PID.

Observer

Cycle de vie de l'hôte

./86boxctl.sh <VM> status
./86boxctl.sh <VM> wait
./86boxctl.sh <VM> logs --lines 100

Écran, console et mémoire de l'invité

Deux chemins indépendants :

  1. Stub RSP (nécessite la build GDB-stub ; la connexion met l'invité en pause) :

    RSP_PORT=<port> ./rsp.py probe
    RSP_PORT=<port> ./rsp.py video-mode
    RSP_PORT=<port> ./rsp.py screen
    RSP_PORT=<port> ./rsp.py wait-screen "texte attendu" --wait-timeout 600
    RSP_PORT=<port> ./rsp.py dump b8000 fa0
    

    Dans les modes texte 0, 1, 2, 3 et 7, screen sélectionne 40x25 ou 80x25, utilise B8000h pour la couleur ou B0000h pour le monochrome, et suit la page vidéo active. En mode graphique 11h, il lit le framebuffer packagé 640x480 1bpp à A0000h, reprend l'invité, et demande au modèle @vision configuré du harnais d'interpréter le PNG généré. omp doit être dans le PATH ; utilisez --vision-question pour personnaliser la question. Les commandes de capture ne mettent en pause que pour inspection et se détachent avant l'inférence du modèle.

  2. Serveur Memdump (pas de stub GDB, pas de pause CPU) : définissez memdump_port dans la configuration de la VM. Interrogez le tampon de texte avec une vue delta en direct :

    ./screenmon.py --memdump-port 12348            # TTY interactif : delta ANSI
    ./screenmon.py --memdump-port 12348 --plain   # redirigé : trame complète + lignes modifiées
    ./screenmon.py --memdump-port 12348 --count 30 --interval 0.1
    

    screenmon.py n'affiche que ce qui a changé entre les interrogations ; le mode est choisi par isatty() sauf si --full/--plain le surchargent. L'intervalle par défaut est de 0,1 s.

Pour une opération bidirectionnelle continue :

# Miroir ANSI interactif ; Ctrl-] se détache
RSP_PORT=<port> ./guest_console.py

# Écran et événements delta traitables
RSP_PORT=<port> ./guest_console.py \
  --format jsonl --no-input --duration 10

# Taper une commande DOS via l'anneau du BIOS
RSP_PORT=<port> ./guest_console.py \
  --send "DIR" --enter --duration 10

# POST précoce nécessite une injection de code de balayage matérielle
RSP_PORT=<port> ./guest_console.py \
  --input-mode hardware --key F1 --duration 5

La console échantillonne à 70 Hz, conserve le tampon complet des caractères/attributs, et n'émet que les séquences modifiées coalescées. Un TTY reçoit des mises à jour du curseur ANSI ; une sortie redirigée par défaut en JSONL. L'entrée par défaut utilise l'anneau du clavier BIOS validé après le démarrage. Le mode matériel injecte des octets de balayage Set 1 cadencés via le 8042 émulé pour le POST. Gardez Ctrl-] pour le détachement afin que Ctrl-C de l'invité reste disponible.

Ne déduisez jamais le succès d'une simple touche injectée. Observez le delta d'écran résultant ou la sortie explicite de l'invité.

Configuration persistante de la VM

Après un arrêt propre, inspectez uniquement le répertoire VM résolu :

<VM>/86box.cfg
<VM>/nvr/<machine>.nvr
<VM>/nvr/<machine>_sec.nvr

Pour ce dépôt :

uv run --project . refdisk-view-config --vm <NOM> --adf-source rf7080a/disk

Ajouter une carte dans l'interface utilisateur 86Box ne peuple pas en soi la NVRAM MCA de l'invité. Le disque de référence de l'invité doit configurer l'état POS et 86Box doit le sauvegarder proprement.

Vérification des ROMs

machine = ... détermine les noms de fichiers ROM requis. Vérifiez :

  1. le --rompath exact enregistré par 86boxctl status, s'il est présent ;
  2. le fichier .86boxctl-romset.json de l'ensemble généré ;
  3. les noms de fichiers actifs exacts de la définition de la machine 86Box ;
  4. les hachages ou comparaisons octet par octet de ces fichiers actifs.

Pour ce workflow, un --rompath explicite doit contenir l'ensemble complet des ROMs 86Box. Bien que 86Box puisse se rabattre sur d'autres racines de recherche, la complétude rend l'exécution autonome et empêche les mélanges silencieux. Ne le pointez pas vers un répertoire ne contenant qu'une seule machine.

Pour une image brute séquentielle de 128 Kio du Model 80 Type 2, utilisez --model-80-type-2-rom. Le contrôleur écrit :

machines/ibmps2_m80/15f6637.bin = entrée[0::2]  # voie basse/paire
machines/ibmps2_m80/15f6639.bin = entrée[1::2]  # voie haute/impaire

Les deux fichiers font 65 536 octets ; leur entrelacement doit reproduire l'entrée. start et restart créent ou valident automatiquement le clone isolé :

./86boxctl.sh <VM> prepare-roms \
  --model-80-type-2-rom /chemin/vers/sequential-128k.bin
./86boxctl.sh <VM> status

Les valeurs par défaut sont les racines de ROMs standard de 86Box : macOS Application Support, XDG_DATA_HOME/XDG_DATA_DIRS sur Unix, et Local/Program/AppData sous Windows. Surchargez avec --rom-source CHEMIN ou 86BOX_ROM_ROOT. --refresh-rom-set ne reconstruit qu'un répertoire généré reconnu.

Les suffixes de sauvegarde comme .orig et .altered ne sont pas sélectionnés automatiquement. Préservez les originaux partagés.

Pour une preuve de bout en bout utilisant un véritable processus 86Box avec GDB-stub :

./model80_rom_smoke.py <VM_MODEL80>

Exigez machine = ibmps2_m80, cpu_use_dynarec = 0 et un gdbstub_port unique. Le harnais dérive une image séquentielle des voies standard, change KB OK en OKBMR, répare la somme de contrôle 64 Kio, lance via le clone isolé complet de la ROM, observe OKBMR dans la VRAM texte de l'invité, et arrête uniquement son PID enregistré. Utilisez --keep-running uniquement lorsqu'une inspection manuelle est nécessaire.

Arrêter ou récupérer

Privilégiez un arrêt propre de l'interface utilisateur, puis confirmez que le processus suivi s'est terminé. Si un contrôle est nécessaire :

./86boxctl.sh <VM> stop
./86boxctl.sh <VM> restart

stop envoie SIGTERM uniquement au PID dont l'identité a été vérifiée et ne le tue pas de force silencieusement. Utilisez --kill-after-timeout uniquement après avoir accepté une éventuelle perte de NVRAM ou de configuration.

En cas de plantage :

  1. capturez status et logs ;
  2. confirmez que l'enregistrement appartient à la VM prévue ;
  3. redémarrez uniquement cet enregistrement ;
  4. enregistrez le nouveau PID ;
  5. revenez à l'étape d'attente ou d'observation précédente.

Preuve d'achèvement

Avant de signaler le succès, fournissez les preuves appropriées à la tâche :

  • chemin exact de la VM et identifiant de la machine ;
  • binaire et commande de lancement exacte ;
  • nom de processus stable et PID actuel ;
  • preuve de disponibilité;
  • état de sortie propre ou de plantage ;
  • chemins et tailles de la configuration/NVRAM pertinents ;
  • écran de l'invité, registres, mémoire, ou sortie de configuration décodée.

Voir README.md pour les détails d'implémentation, les particularités du stub GDB, la recherche de ROMs et le diagnostic des pannes.

Skills associés