À la découverte du FDC – Épisode 3

par roudoudou.

Dans l’épisode 2, je vous racontais que Discology essayait de rater la lecture d’un secteur pour trouver le début de la piste, afin de récupérer les secteurs lisibles dans le bon ordre. En effet, la fonction GetID renvoie le premier secteur trouvé et on ne peut jamais savoir où on va démarrer sur la piste.

L’analyse de piste

Il faut savoir que Discology joue avec le feu en utilisant cette méthode car le premier appel à l’instruction GetID ne déroge pas à la règle de lenteur des instructions de lecture/écriture du FDC : elle est lente, entre 1980 et 3900 nops soit le temps que le FDC survole jusqu’à 120 octets de données sur la piste.

Heureusement pour Discology, l’entête d’une piste écrite par un FDC fait presque toujours 146 octets. La raison est assez simple, un FDC standard qui formate une piste écrira 80 octets de GAP, 16 octets de synchro+identification et enfin une nouvelle GAP avant l’entête du premier secteur.

Ainsi il n’y avait plus qu’à dérouler des GetID et compter les nops en fonction de la longueur de piste configurée pour lire tous les secteurs dans l’ordre. Sur la capture ci dessous le réglage maximum de longueur de piste.

Quand la fiction devient réalité

Si les premières protections ont été créées sur CPC, les meilleurs système anti-copie viennent de créations industrielles sur des machines dédiées qui n’ont rien à voir avec le CPC. Les éditeurs envoyaient leur master qui était injecté dans la machine traceuse mais l’opérateur pouvait modifier certains paramètres comme augmenter la taille de GAP d’un seul secteur de la piste, modification anodine qui rendait la copie impossible.

Ici une traceuse en 3.5″ mais le système est similaire en 3″, YFOYAKA changer le lecteur ! Photo honteusement chipée chez AWP

Pour la création d’une protection plus évoluée, l’opérateur devait créer un script dans le format FreeForm, associé à un logiciel propriétaire qui permettait de définir bit à bit la piste. Un réglage fin sur la vitesse moteur permettait aussi de tasser les bits sur le tour de piste, pratique pour dépasser la capacité théorique de 6250 octets.

Plus sale, on s’apercevait rapidement que l’entête piste ne servait à rien. On gagnait alors 146 octets à le supprimer. Enfin, les données du dernier secteur pouvaient même chevaucher le trou d’index (le secteur taille 6 de Fighter Bomber déborde de cette façon et rebique dans la GAP pré-sectorielle). Ci-dessous le début du dump IPF de la deuxième piste. Les données terminent sur 72 octets, suivie d’une énorme GAP de 76 octets. les 12 octets de synchronisation et le reste de l’entête surligné dans lequel on repère les informations secteur (piste 01/tête 00/ID C1/taille 06).

Au petit jeu de celui qui en mettra le plus, il est possible de s’amuser à dépasser les spécifications du FDC et mettre un peu plus de 64 secteurs (32 max théorique, 25 max réel) dépourvus de données. Une telle protection existe depuis 1986 que l’on retrouve sur les jeux 2112 AD, N.E.X.O.R., Time and Motion, Working Backwards ainsi qu’une compilation.

En recréant cette protection, j’ai découvert un amusant message dans Discology (peut-être uniquement le fruit de la traduction ?), et aussi vu qu’il ne plantait pas ! Attention, trop de secteurs sur Disc+Ultra vous amènera directement au reset !

Si Discology ne peut pas tout copier, on remarque quand même qu’il ne rate aucun secteur malgré que ma protection soit une suite continue d’entêtes. Je vous disais en préambule que seul le premier appel de GetID était lent. Mais le premier, ça veut tout dire et rien dire non ?

L’optimisation interne du GetID

Lors de mes tests de l’instruction GetID, mon programme envoyait deux instructions à la suite. J’ai rapidement remarqué que le premier appel était toujours lent, suivi d’un second rapide.

=> #4A [#10,#10,#10,#10,#10,#10,#10,#10,#10,#90]
=> #00 [#10,#10,#10... entre 1980 et 3890 nops
        #30,           statut de transition
        #70,#70,#70    jusqu'à ce qu'un secteur soit rencontré
; une fois l'entête secteur lu
        #10,#50,#D0]
; on peut alors récupérer les 7 octets de résultat

=> #4A [#10,#10,#10,#10,#10,#10,#10,#10,#10,#90]
=> #00 [#10,#10,#10,#10,#10,#10,#10,#10,#10   entre 90 et 100 nops seulement!
        #30,                                  statut de transition
        #70,#70,#70                           jusqu'à ce qu'un secteur soit rencontré
; une fois l'entête secteur lu
        #10,#50,#D0]
; on peut alors récupérer les 7 octets de résultat

Qu’est-ce qui pouvait conditionner la rapidité du second appel ? Je relançais ma séquence et j’avais toujours la même chose alors que je ne faisais rien d’autre entre temps. Il y avait obligatoirement une durée seuil qui faisait sortir le FDC de sa routine optimisée.

Je trouve assez rapidement un intervalle de transition entre 28.000 et 31.000 nops dans lequel l’optimisation semble fonctionner de façon graduelle. Je créé une disquette “normale” avec 25 petits secteurs et j’entame une campagne de mesure. Avec 8 nops de précision, je peux scanner un intervalle de 5120 nops et voir comment se comporte l’instruction. Pour lisser la courbe, je fais 256 mesures à chaque fois. Je sors ma calculatrice, un tel test va prendre minimum 1H30 mais le résultat en valait la chandelle !

Note pour Madram : ceci est une capture d’une vieille télévision à écran plat en résolution non HD, son comportement visuel est assez proche d’un CTM, tu noteras la jambe du “m” sachant que le signal est dégradé en largeur par la carte de conversion et qu’en péritel ça serait meilleur ;) Une démonstration de mes pouvoirs psychiques maintenant. Tu ne t’appelles pas Madram mais tu as quand même lu ce texte !

À part aider les auteurs d’émulateurs à reproduire fidèlement notre FDC, ce graphique montre surtout qu’il ne faut jamais attendre trop longtemps entre deux GetID sous peine de se manger le temps de préparation dans les dents.

À l’usage

L’utilisation de la fonction GetID ne nécessite pas obligatoirement de couper les interruptions pour fonctionner mais on les coupera quand même pour être sûr de ne rien rater et d’avoir d’éventuels comptage de longueur corrects !

Dans le prochain épisode

Le prochain épisode sera intitulé La légende de l’instruction ReadTrack qui ne sait pas lire une piste entière mais qui peut quand même lire une piste entière ou bien tout le monde peut se tromper, je ne suis pas encore fixé.

Merci à Denis Lechevalier pour les infos traceuses ;)