Booterify: (Re)conversion de jeux à PC-Booter

Introduction

Booterify est un petit loader pouvant tenir dans le premier secteur d'une disquette (512 octets) et un outil Linux permettant de convertir des fichiers exécutables DOS (.COM ou .EXE) en disquettes amorçables («bootable»).

Mon objectif premier était d'arriver à remettre certains jeux d'époque de type PC booter sur disquette de sorte qu'ils puissent démarrer à nouveau directement sans passer par DOS. Mais l'outil est également utile pour faire un PC booter de votre projet de jeu rétro.

Caractéristiques de la version actuelle:
  • Support des exécutables .COM
  • Support des exécutables .EXE (64 ko max)
  • BPB (Bios parameter block) pour permettre le démarrage sur clef USB
  • Détection des appels potentiels aux services du DOS, affichage de leur adresse et hexdump
  • Génération d'une liste de breakpoints en format bochs pour chaque instance d'appel de service DOS
  • Services du DOS supportés:
    • int 21h/AH=02h : Affiche un caractère
    • int 21h/AH=09h : Affiche une chaîne de caractères
    • int 21h/AH=25h : Get interrupt vector
    • int 21h/AH=35h : Set interrupt vector
  • Loader pour cartouche PCjr et outil de manipulation de ROM.
Voir plus bas: Liste de jeux testés


Qu'est-ce qu'un PC-Booter?

Le terme PC Booter désigne un jeu ou logiciel qui démarre sans passer par le système d'exploitation de la machine, directement depuis la disquette lors de la mise sous tension.

Cette technique était populaire pendant les années 80. Dans le cas d'un PC sans disque dur, c'était tout de même pratique, car cela évitait de devoir d'abord lancer DOS pour ensuite, ayant changé pour la disquette du jeu, le faire démarrer. Cela rendait aussi la copie plus difficile (c'était donc aussi une forme de protection contre la copie) et ne permettait pas d'installer le jeu dans le disque dur...

Plusieurs de ces jeux d'époque sont maintenant disponibles sur les sites d'abandonware, mais la plupart sont en versions piratées et convertis en format .COM ou .EXE car plus pratique.



Pourquoi de nos jours?

Je suis entré en possession d'un ordinateur Tandy 1000 EX qui n'a qu'un lecteur de disquette et pas de disque dur. J'avais envie de revivre l'expérience de démarrer directement sur le jeu, comme je le faisais il y a plusieurs années.

Il aurait été facile de formater une disquette pour qu'elle puisse démarrer avec format /s et d'y mettre un autoexec.bat qui lancerait le jeu en version .COM ou .EXE. Mais cela n'aurait pas été très intéressant. J'ai donc plutôt opté pour la méthode plus difficile (mais très éducative) consistant à écrire mon propre loader et outil pour convertir les fichiers .COM et .EXE à une image de disquette de démarrage.


Fonctionnement de Booterify

Le BIOS d'un PC se charge de lire le premier secteur (512 octets) de la disquette vers la mémoire. Ce petit bout de code ne fait souvent qu'en lire un plus gros qui fera le vrai travail, mais pour booterify 512 octets suffisent largement pour charger le jeu et l'exécuter.

Le loader fait appel en boucle à l'interruption 13h, fonction 2 du BIOS qui permet de lire un nombre de secteurs vers la mémoire. Le secteur 0 étant réservé au loader, le jeu est divisé en blocs de 512 octets et simplement stocké dans les secteurs 1 à N selon la taille totale (maximum 64K présentement).

Certains emplacements mémoire dans le loader correspondent à des paramètres qui sont ajustés automatiquement par l'outil de création d'image de disque:
  • Nombre total de secteurs à copier
  • Nombre de secteurs par piste (dépends du type de disquette que nous créons [Ex: Pour une disquette 360K, ce serait 9])
  • Offset pour le point d'entrée du logiciel (ex: Pour un .COM, ce serait 100h)
  • Offset initial pour le stack pointer (Pour un .COM, pointera à la fin du segment)
  • Segment de destination pour le code (CS)
  • Segments Data (DS) et stack (SS) (tous égaux à CS dans le cas d'un .COM)
Pour un exécutable .COM, c'est très simple et les deux premiers paramètres (taille et nombre de secteurs par piste) sont les seuls vraiment utiles. Les paramètres supplémentaires permettent de supporter les fichiers .EXE, pourvu que le Load module ne soit pas plus gros que 64K. L'outil de création de disque reconnait automatiquement le format de fichier (.COM ou .EXE) et s'occupe des complications spécifiques au format .EXE comme la relocalisation des références de segments.

Attention: Que ce soit un .EXE ou un .COM, le jeu ou logiciel ne fonctionnera que s'il ne fait pas appel[1] à des services du DOS. L'outil de création de disquette tente de détecter les octets qui ressemblent à de tels appels (séquences CD xx), vous avertira et affichera un hex dump autour de l'appel. Mais la création de la disquette ne sera pas abandonnée pour autant, car il se peut très bien que ce soit une fausse alerte, ces séquences pouvant survenir n'importe où (dans des donnés par exemple).

C'est à vous de vérifier ce qu'il en est en déassemblant votre exécutable ou le hex dump. Il est bien entendu toujours possible de simplement tenter un démarrage. Mais sinon en général, si le jeu a plus qu'un fichier, ça ne fonctionnera certainement pas. S'il en a qu'un seul, cela fonctionnera peut-être. (Vérifier si le jeu est listé quelque part comme PC booter peut aussi être une bonne indication des chances de fonctionnement.)

[1] Note: Le loader demeure en mémoire et implémente en fait quelques services du DOS: INT 21h,AH=09h, INT 21h,AH=25h et INT 21H,Ah=35h. Les autres services de l'interruption 21h ne sont pas implémentés et redonnent immédiatement le contrôle à l'appelant via RETI.


Générer l'image de disque

Voici l'aide:
$ ./booterify -h
Usage: ./booterify [options] bootsector.bin executable output.dsk

Where:
 - bootsector.bin is the bootloader,
 - executable is the input file (.exe or .com),
 - output.dsk is the output file.

Options:
 -h             Prints help
 -c             Force input file format as .com (default: auto-detect)
 -e             Force input file format as .exe (default: auto-detect)
 -s             Sectors per track
 -t             Target disk size (padded with zeros). If 0, no padding.

Debugging/Development:
 -B file        Generate list of breakpoints commands for bochs for all
                instances of DOS int calls

Common disk parameters:
	360k floppy:  -s 9 -t 368640
	1.44MB floppy:  -s 18 -t 1474560

Note: Padding with -t as above is not required when writing to
	a physical floppy, but it can help for emulators or virtual
	machines that use the file size to determine the floppy type.
Voici l'outil à l'œuvre pour la création d'une disquette de 360K pour Alley Cat:
$ ./booterify -s 9 -t 368640 bootsector.bin ../exeinfo/cat.exe boot1.dsk
Bootstrap file: bootsector.bin
Bootstrap size: 512
Payload file: ../exeinfo/cat.exe
Payload file type: .EXE
Output file: boot1.dsk
Sectors per track: 9
Output file padding: 368640 B / 360.00 kB / 0.35 MB)
Reading exe file...
File size: 55067
Load module size: 54555
Relocating...
Relocation 0 : 0723:0009 (linear address 0x00007239) : 0x0010 -> 0x1010
Relocation 1 : 0723:0541 (linear address 0x00007771) : 0x0010 -> 0x1010
Relocation 2 : 0723:1125 (linear address 0x00008355) : 0x0010 -> 0x1010
Relocation 3 : 0723:13ed (linear address 0x0000861d) : 0x0010 -> 0x1010
Relocation 4 : 0723:14b8 (linear address 0x000086e8) : 0x0010 -> 0x1010
Relocation 5 : 0723:1501 (linear address 0x00008731) : 0x0010 -> 0x1010
Relocation 6 : 0723:2ade (linear address 0x00009d0e) : 0x0010 -> 0x1010
Relocation 7 : 0723:3a98 (linear address 0x0000acc8) : 0x0010 -> 0x1010
Relocation 8 : 0723:5c9f (linear address 0x0000cecf) : 0x0010 -> 0x1010
Payload size: 54555
Code : 0x1723:0x0000
Stack : 0x1000:0x0100
Writing boot1.dsk...
Bootstrap: 107 sectors to copy, 9 sectors per track, initial IP 0x0000



Tester l'image

L'image de disque générée ainsi peut être testée dans vmware:



L'émulateur bochs est également une bonne option pour tester l'image. Il faudra dans le fichier de configuration se servir d'une ligne comme celle ci:
floppya: type=1_2, 360k="boot1.dsk", status=inserted, write_protected=1


Installation sur disquette

Sous Linux

Sous Linux, il suffit simplement d'insérer une disquette formatée et de copier le contenu de l'image directement vers le périphérique:
dd if=boot1.dsk of=/dev/fd0
107+1 records in
107+1 records out
55067 bytes (55 kB) copied, 4.69115 s, 11.7 kB/s
Comme prévu, un PC démarrera avec la disquette ainsi créée:
Lecture...

Lecture...

Démarrage réussi!

Démarrage réussi!



Sous Dos avec disque dur ou deux lecteurs

L'outil rawrite, disponible ici, est idéal pour créer une disquette à partir d'une image. C'était beaucoup utilisé avant, à l'époque où les PC ne pouvaient pas démarrer sur CD-ROM et clef USB.


Sous Windows

Vous pourriez probablement vous servir de rawrite32.


Sous Dos avec un seul lecteur

Si vous n'avez qu'un lecteur de disquette du type voulu et que ce lecteur est le seul dans la machine cible qui n'a pas de disque dur, plutôt que de déplacer le lecteur vers un autre système, considérez l'emploi de PPUSBComm.

PPUSBComm permet de transférer une image de disque par USB et le port parallèle de la machine cible. L'image est écrite directement vers la disquette de la machine cible.
Transfert en cours

Transfert en cours

Écriture des secteurs

Écriture des secteurs

Succès!

Succès!



Le jeu ci-dessus est Tandy Cat (Alley Cat patché pour Tandy).


Support du PCjr

Depuis la version 1.6, booterify comprends un loader (pcjrloader.asm) capable de démarrer à partir du ROM d'une cartouche pour PCjr plutôt que depuis une disquette. Un outil nommé jrromchk est aussi introduit dans cette version pour calculer le CRC, écrire la taille dans l'en-tête du ROM et convertir entre les formats de ROM bruts et .JRC.

Jetez un coup d'oeil à ma page de projet de Cartouche PCjr pour un exemple concret où j'utilise booterify et jrromchk pour fabriquer une cartouche du jeu Alley Cat.

Alley Cat sur cartouche!

Alley Cat sur cartouche!





Téléchargements

Voici le code source. Pour compiler le loader (bootsector.bin) il vous faudra nasm. Et pour compiler l'outil de création de disque, les outils de compilation standard sous Linux (gcc, etc).

Pour l'instant, le projet n'est que distribué en format source. Mais s'il y a de la demande, je ferai une version pré-compilée de l'outil pour Windows. Mais cela sera quand même un outil en ligne de commande.
Nouveau, Juin 2018: Pour une version Windoiws déjà compilée fonctionnant en ligne de commande, téléchargez le fichier .zip.

Flux RSS pour cette table
Version 1.6
20 octobre 2019 (Dimanche)
Première version capable de convertir des exécutables en ROM de cartouche PCjr.
  • L'écriture d'un Bios Parameter Block de même que le padding du fichier peuvent être déactivés avec l'option -f 0
  • Introduction de l'outil jrromchk, pour convertir les .JRC en image de ROM bruts et vis-versa.
  • Ajout d'un loader pour les cartouches PCjr.
Fichier(s):
booterify-1.6.tar.gz (14.9 KB)
booterify_win32-1.6.zip (147 KB)
Afficher les versions précédentes
Version 1.4
5 février 2019 (Mardi)
  • Initialise le PSP comme il faut pour les fichiers .COM (Plutôt que de tout mettre à zéro, donne une longueur de 1 et place le terminateur de ligne 0D)
  • Implémente le service 21h,02 de DOS (impression d'un caractère)
  • Ajoute une chaîne de caractère indiquant la version dans le loader et dans l'outil.
  • Ajout d'un makefile pour compiler la version win32 avec MXE sous Linux
Fichier(s):
booterify-1.4.tar.gz (11.4 KB)
booterify_win32-1.4.zip (94.3 KB)
Version 1.3
1 mars 2017 (Mercredi)
Les disquettes créées contiennent maintenant un système de fichier FAT12. Elles sont donc utilisables normalement en plus d'êtres bootables.
Fichier(s):
booterify-1.3.tar.gz (10.6 KB)
booterify_win32-1.3.zip (93.8 KB)
Version 1.2
26 juillet 2016 (Mardi)
Première version publiée
Fichier(s):
booterify-1.2.tar.gz (7.6 KB)
Ce projet est aussi disponible sur GitHub!
Pour suggérer de nouvelles fonctionnalités, signaler un problème ou contribuer au projet, vous pouvez m'écrire ou utiliser le dépôt GitHub:
https://github.com/raphnet/booterify


Jeux testés

Voici quelques jeux avec lesquels j'ai testé l'outil:

  • Agent USA
  • Alley Cat (original et version patchée pour Tandy)
  • Apple Panic
  • Burger Time
  • Digger
  • Dig-Dug
  • Galaxian
  • Miss Pac-man
  • Pac-man
  • Pipes
J'ai également testé avec RATillery, un jeu de ma création.

Si vous testez avec d'autres jeux ou logiciels, veuillez m'en faire part! Je serais heureux d'apprendre que quelqu'un d'autre que moi s'est servi de ce projet...


Références

Quelques références qui m'ont été particulièrement utiles pour réaliser ce projet:


Avertissement

Je ne saurais être tenu responsable pour les dommages que l'utilisation des informations ou la mise en œuvre des instructions présentées sur cette page pourrait causer à votre équipement, à vous-même ou à autrui. Aussi, je ne donne aucune garantie quant à l'exactitude des informations et à leur fonctionnement.