Micral P2 - Partie 3 - Analyse de la disquette
Analyse d’une disquette système CP/M
Grace à Jeff (HxC2001), la disquette CP/M 2.2 pour le Micral P2 a pu être lue. Etant donné qu’il s’agit du seul dump en ligne, il n’y a pas d’informations pour décoder cette disquette. Dans cet article, je vais documenter comment je déduis les paramètres pour extraire les données de cette disquette.
Le fichier que je vais manipuler est une image IMD, faite via l’outil Pauline.
IMD est le format de fichier d’ImageDisk (par Dave Dunfield), mais d’autres
formats pourraient être utilisés aussi : TD0 (Teledisk), HFE (HxC) etc.
Lorsque je me réfère aux pistes et secteurs, je vais utiliser la notation
CX HY SZ notation, qui correspont à Cylindre X (= Piste), Tête Y (= Face), Secteur Z.
A noter que les pistes et têtes sont numérotées à partir de 0, tandis que les
secteurs commencent à 1.
Pour une introduction au format de fichier CP/M, je recommande la documentation de cpmtools, disponible en ligne ici (en anglais) : https://linux.die.net/man/5/cpm
Géométrie

En ouvrant le fichier dans le logiciel HxC, on voit rapidement ces informations :
- 2 faces
- 76 pistes par face (la 77ème n’a pas de secteur)
- 16 secteurs par piste
- 256 octets par secteur

En allant dans la vue d’une piste, on constate que l’ordre des secteurs n’est pas consécutif, mais utilise 1 secteur entre chaque secteur consécutif, ce qui donne 1->9->2->10->3…
- Facteur d’entrelacement : 1
Bien qu’il y ait un entrelacement dans les secteurs sur le disque (visible via les numéros de secteurs dans les en-têtes), il se peut que ce ne soit utilisé que par le BIOS, et que CP/M ignore l’existence de cet entrelacement. Ca peut être vérifié soit en testant différents paramètres, soit de manière plus sûre en lisant la table DPB (Disk Parameter Block) contenue dans le BIOS.
En revenant dans la vue disque, on observe que le disque est rempli par l’extérieur
et sur les 2 faces à la fois, ce qui veut dire que le disque est rempli dans
l’ordre CHS (Cylinder, Head, Sector). Certains ordinateurs remplissent la première
face entièrement avant de remplir la seconde, mais ce n’est pas le cas ici. A titre
informatif, cet ordre de remplissage correspond au paramètre ORDER dans l’outil
22DISK (MS-DOS), et n’est pas supporté par cpmtools.
Attributs CP/M
Maintenant que je sais dans quel ordre le disque est rempli, je peux chercher où est le superblock. Le début du disque contient CP/M sur les premières pistes, puis le superblock. Ce dernier contient la liste des fichiers, ainsi que leurs propriétés et emplacement sur le disque.
C0H0, C0H1 et C1H0 sont remplis de données binaires.
A partir de C1H1S1, on observe des noms de fichier lisibles.
Puis de la fin de C1H1S1 à C2h0S16, tout est rempli de 0xE5, ce qui est la valeur
par défaut pour les champs vides du superblock.
Ensuite, il y a de nouveau des données à partir de C2H1. Cela veut donc dire
que le superblock occupe 2 pistes
De cela, je déduis que :
- 3 pistes sont réservées pour CP/M
- Le nombre maximum de fichiers dans le superblock est 256
- 2 pistes * 16 secteurs * 256 = 8192. Un fichier occupe 32 octets, donc on a au plus 8192 / 32 = 256 fichiers.
Le dernier attribut manquant pour décoder la disquette est la taille de bloc. Les fichiers sont divisés en blocs de cette taille. Etant donné que le superblock occupe des blocs, on peut deviner la taille de bloc en regardant quel est le premier numéro de bloc utilisé par des fichiers, et diviser la taille du superblock par ce numéro.
Pour lire le superblock, je convertis l’image en .IMG afin d’avoir juste le
contenu des secteurs (ordonné en CHS). Je le fais via HxC, soit via l’interface
graphique par laquelle je charge l’image IMD pour l’exporter en IMG, soit
en ligne de commandes avec :
/hxcfe -finput:"Micral_P2_System_CPM_Basic.imd" -conv:RAW_LOADER -foutput:"Micral_P2_System_CPM_Basic.img"
Ensuite, j’affiche le superblock en hexadécimal (en commençant à 0x3000 pour
sauter les 3 premières pistes. 0x3000 = 3 * 16 * 256), et je filtre les lignes
“vides” commençant par 0xE5.
xxd -s 0x3000 -c 32 -l 0x2000 Micral_P2_System_CPM_Basic.img | grep -v ": e5"
00003000: 0044 554d 5020 2020 2043 4f4d 0000 0004 0400 0000 0000 0000 0000 0000 0000 0000 .DUMP COM....................
00003020: 0046 5032 2020 2020 2043 4f4d 0000 0042 0500 0600 0700 2300 2400 0000 0000 0000 .FP2 COM...B......#.$.......
00003040: 004d 4f56 4350 4d20 2043 4f4d 0000 004c 0800 0900 0a00 0b00 0c00 0000 0000 0000 .MOVCPM COM...L................
00003060: 0053 5542 4d49 5420 2043 4f4d 0000 000a 0d00 0000 0000 0000 0000 0000 0000 0000 .SUBMIT COM....................
00003080: 0050 4950 2020 2020 2043 4f4d 0000 003a 0e00 0f00 1000 1100 0000 0000 0000 0000 .PIP COM...:................
000030a0: 0053 5441 5420 2020 2043 4f4d 0000 0029 1200 1300 1400 0000 0000 0000 0000 0000 .STAT COM...)................
000030c0: 0053 5953 4750 3220 2043 4f4d 0000 000d 1500 0000 0000 0000 0000 0000 0000 0000 .SYSGP2 COM....................
000030e0: 0045 4420 2020 2020 2043 4f4d 0000 0034 1600 1700 1800 1900 0000 0000 0000 0000 .ED COM...4................
00003100: 004c 4f41 4420 2020 2043 4f4d 0000 000e 1a00 0000 0000 0000 0000 0000 0000 0000 .LOAD COM....................
00003120: 0044 4454 2020 2020 2043 4f4d 0000 0026 1b00 1c00 1d00 0000 0000 0000 0000 0000 .DDT COM...&................
00003140: 0044 4454 2020 2020 2043 4810 7fff ffc8 cfff ce40 1100 0000 0000 0000 0000 0000 .DDT CH........@............
00003160: 0021 20a2 090e 27e7 e410 d3d3 1fff ffcf f31f f27f f21f f23f f21f f0ff f09f f140 .! ...'................?.......@
00003180: 0008 4828 8243 89f9 f904 c101 040b fffe 0603 fe30 00b4 00a3 ffff ffff ffff ffff ..H(.C.............0............
000031a0: fffe 7060 1079 0044 9ea0 393c 5300 0000 072f 0000 0000 0000 0000 0000 0000 0000 ..p`.y.D..9<S..../..............
000031c0: 0000 7888 b640 c45c 8808 1090 54cf ffff fe71 ffff ffff ffff ffff ffff ffff ffff ..x..@.\....T....q..............
000031e0: ffff e700 2834 8524 fcfc f9c9 e098 0000 0021 8bff ffff ffff ffff ffff ffff ffff ....(4.$.........!..............
00003200: 0050 4552 4945 5231 2042 4153 0000 0002 2f00 0000 0000 0000 0000 0000 0000 0000 .PERIER1 BAS..../...............
00003220: 0050 4552 4945 5232 2042 4153 0000 0001 3000 0000 0000 0000 0000 0000 0000 0000 .PERIER2 BAS....0...............
00003240: 0050 4552 4945 5233 2042 4153 0000 0002 3100 0000 0000 0000 0000 0000 0000 0000 .PERIER3 BAS....1...............
00003260: 0050 4552 4945 5234 2042 4153 0000 0002 3200 0000 0000 0000 0000 0000 0000 0000 .PERIER4 BAS....2...............
00003280: 0043 4f50 5920 2020 2043 4f4d 0000 0030 2000 2100 2200 0000 0000 0000 0000 0000 .COPY COM...0 .!."...........
000032a0: 0042 4153 4943 2020 2043 4f4d 0000 0080 1e00 1f00 2500 2600 2700 2800 2900 2a00 .BASIC COM........%.&.'.(.).*.
000032c0: 0042 4153 4943 2020 2043 4f4d 0100 003e 2b00 2c00 2d00 2e00 0000 0000 0000 0000 .BASIC COM...>+.,.-...........
000032e0: 0070 6572 6965 7235 2062 6173 0000 0003 3300 0000 0000 0000 0000 0000 0000 0000 .perier5 bas....3...............
00003300: 0050 4552 4945 5235 2042 4153 0000 0005 3400 0000 0000 0000 0000 0000 0000 0000 .PERIER5 BAS....4...............
00003320: 0050 4552 4945 5220 3642 4153 0000 0002 3500 0000 0000 0000 0000 0000 0000 0000 .PERIER 6BAS....5...............
00003340: 0074 6974 6920 2020 2042 4153 0000 0003 3800 0000 0000 0000 0000 0000 0000 0000 .titi BAS....8...............
00003360: 0074 6f74 6f20 2020 2062 6173 0000 0001 3600 0000 0000 0000 0000 0000 0000 0000 .toto bas....6...............
....
Il semble y avoir des corruptions entre 0x3160 et 0x31FF, mais je vais les ignorer pour l’instant étant donné que tout le reste est valide.
Les 16 derniers octets de chaque ligne contiennent les allocations de bloc utilisés, et le numéro indiqué est sur un ou deux octets selon la géométrie. Dans ce cas, on voit “0500 0600 0700” sur la seconde ligne donc on devine que cela occupe deux octets par bloc.
Le premier identifiant de bloc utilisé est 0x0004, ce qui indique que le superblock occupe 4 blocs (de 0 à 3 inclus). On a donc :
- Taille de bloc = 2048 (= 8096 / 4)
Test des paramètres
Je peux donc écrire la définition de disque suivante pour cpmtools :
diskdef micral-p2
seclen 256
tracks 152 # 76 cylinders * 2 sides
sectrk 16
blocksize 2048
maxdir 256
skew 1
boottrk 3
os 2.2
end
En la testant avec cpmls, on a des résultats qui semblent bon (hormis les 3 lignes de données corrompues observées plus haut).
cpmls -l -f micral-p2 -T imd Micral_P2_System_CPM_Basic.img
0:
-r-x------3573412791104 Jan 01 1970
-r-x------3573412791104 Jan 01 1970 h(c yy.a
-r-x------3573412791104 Jan 01 1970 !.ss
-rwxrwxrwx 24320 Jan 01 1970 basic.com
-rwxrwxrwx 6144 Jan 01 1970 copy.com
-rwxrwxrwx 6144 Jan 01 1970 ddt.ch
-rwxrwxrwx 4864 Jan 01 1970 ddt.com
-rwxrwxrwx 512 Jan 01 1970 dump.com
-rwxrwxrwx 6656 Jan 01 1970 ed.com
-rwxrwxrwx 8448 Jan 01 1970 fp2.com
-rwxrwxrwx 1792 Jan 01 1970 load.com
-rwxrwxrwx 9728 Jan 01 1970 movcpm.com
-rwxrwxrwx 0 Jan 01 1970 perier.bas
-rw-rw-rw- 256 Jan 01 1970 perier1.bas
-rw-rw-rw- 128 Jan 01 1970 perier2.bas
-rw-rw-rw- 256 Jan 01 1970 perier3.bas
-rw-rw-rw- 256 Jan 01 1970 perier4.bas
-rw-rw-rw- 640 Jan 01 1970 perier5.bas
-rw-rw-rw- 640 Jan 01 1970 perier5.bas
-rwxrwxrwx 7424 Jan 01 1970 pip.com
-rwxrwxrwx 5248 Jan 01 1970 stat.com
-rwxrwxrwx 1280 Jan 01 1970 submit.com
-rwxrwxrwx 1664 Jan 01 1970 sysgp2.com
-rwxrwxrwx 0 Jan 01 1970 titi.bas
-rwxrwxrwx 0 Jan 01 1970 toto.bas
Pour s’assurer de leur validité, j’extrais PIP.COM et m’assure que le contenu est consistant :
# Extraction
cpmcp -f micral-p2 -T imd Micral_P2_System_CPM_Basic.img 0:pip.com .
# Visualisation du contenu
xxd pip.com | less
Tout le contenu du fichier semble cohérent, avec des instructions Z80 sans trou, ce qui veut dire que les paramètres sont valides.
Je peux désormais utiliser cette définition de disque pour manipuler la disquette, que ce soit pour en extraire les données ou ajouter des fichiers.
La suite?
Il reste encore deux problèmes :
- TOTO.BAS indique une taille de 0 octets, alors que d’après le superblock il devrait en occuper 128. Cela semble être un problème spécifique à cpmtools, que j’investiguerai avec mes propres outils de manipulation d’image CP/M.
- Entrées corrompues : semblent être une erreur par le dernier utilisateur, il faudra s’assurer que ça ne concernait pas de fichiers importants.
Et pour vraiment confirmer à 100% la validité de la définition, il faudra extraire
le DPB du BIOS, soit via un désassemblage, soit en démarrant la machine et en
utilisant l’appel système DRV_DPB du BDOS qui nous le retournera.
Liens
- cpmtools 2.23: https://www.moria.de/~michael/cpmtools/
- HxC Floppy Emulator: https://github.com/jfdelnero/HxCFloppyEmulator