Voici la fonction RLEAD telle que je l'ai analysée, elle m'a permis de comprendre comment le leader est constitué et comment le DAI peut le reconnaître. L'organigramme ci-dessous a été coloré et les lignes d'assembleur qui correspondent également. Le détail et le commentaire de chaque ligne est donné juste après l'organigramme.

  Adr

Mnémonique

NbCycles

Commentaires

1 RHDR CALL SNDDI

17+d(SNDDI)

Désactive l'interruption son
2   CALL   RLEAD 17+d(RLEAD) Cherche un morceau de leader
3   CALL RBYTE 17+d(RBYTE) Lire un octet
4   JC RHDR 10 On recommence si erreur
5   CPI :55 7 Octet terminant le leader
6   JNZ RHDR 10 Ce n'est pas :55, on recommence
7   CALL RBYTE 17+d(RBYTE) Lire l'octet donnant le type de fichier
8   JC RHDR 10 On recommence si erreur
9   RET   10 Retour au programme appelant
           
10 RLEAD PUSH B 11  
11   PUSH D 11  
12   PUSH H 11  
13   MVI B,:28 7 Estimation de la longueur de l'impulsion
14   LXI H,:FDOO 10 HL = adresse du port d'entrée
15 RDL05 MVI A,:FF 7  
16 RDL10 EI   4 Autorise les interruptions
17   NOP   4 Temps laissé pour clignotement du curseur sur l'écran du DAI
18 DI 4 Désactivation des interruptions
19   ANA M 7  
20   JM RDL10 10 Attendre le passage à l'état bas
21   MOV C,B 5 On stocke dans C la durée du dernier état haut lu.
22   MVI D,:14 7 On considère que si le teste réussit 20 fois c'est que l'on est sur un leader
23 RDL30 MVI E,:00 7  
24   XRA A 4  
25 RDL40 DCR E 5  
26   JZ RDL05 10 Trop longtemps à l'état bas, alors on recommence à zéro.
27   ORA M 7  
28   JP RDL40 10  

Le programme commence à être intéressant à la ligne 21, là où l'on détecte un état bas sur le signal. Au début de l'exécution de la ligne 21, le signal est bas au moins depuis la ligne 19, c'est à dire au moins depuis 7+10 cycles (lignes 19 et 20). Je dis "au moins" car en réalité et selon toute vraisemblance, il y est depuis beaucoup plus longtemps... Effectivement, vous pouvez remarquer que lors de l'attente de ce premier état bas, le programme boucle entre les ligne 16 et 20 mais vous noterez qu'à la ligne 16 on autorise les interruptions (EI), ce qui permet lors de l'arrivée d'une interruption (qui a lieu toutes les 20 ms grâce au blanking signal de synchro TV, mais peu importe) et ce qui permet au programme de se dérouter pour faire clignoter le curseur à l'écran... Donc pendant toute ce temps, inutile de vous faire un dessin, nous dépassons allègrement les 7+10 cycles des lignes 19 et 20.

Quoiqu'il en soit, arrivé à la ligne 21, nous pouvons être sûr d'une chose, c'est d'avoir détecté le signal à l'état bas depuis un temps égal à 17 cycles machines.

Près l'exécution de la ligne 24, il se sera passé 7+10+5+7+7+4=40 cycles. Nous entrerons alors dans une boucle (ligne 25 à 28) dont nous sortirons soit en ligne 26, soit en ligne 28. Si l'on sort en ligne 26 c'est qu'il s'est passé 40 + 255*(5+10+7+10) + 5+10 = 8215 cycles sans avoir détecté de niveau haut sur le signal cassette. Cela signifie alors que nous sommes restés au moins 8215 cycles à l'état bas... Or, l'horloge du 8080A du DAI est réglée sur une fréquence d'horloge d'exactement 2MHZ. Le cycle machine est donc égale à 1/2000000 = 0,5µs ! Ceci signifie donc que nous sommes à l'état bas depuis 8215*0,5µs, c'est à dire depuis 4,1075 ms, ce qui est beaucoup trop pour l'état bas d'un bit leader (CF ici)  et c'est pourquoi l'on se permet de recommencer à zéro en RDL05, ce qui donne l'occasion au DAI de nous faire de l'oeil avec son curseur.

En revanche, si l'on sorte en ligne 28, c'est que l'on vient de détecter un niveau haut... Poursuivons notre investigation :

29 MVI  B,:00 7 B sert à mesurer le temps passé à l'état haut
30 RDL50 INR B 5 On incrémente B à chaque passage dans la boucle
31   JZ RDL05 10 Ce coup ci on est resté trop longtemps à l'état haut, c'est insupportable, on recommence au début
32   ANA M 7 On teste le port d'entrée
33   JM RDL50 10 Attendre le passage à l'état bas

Si nous sommes sortis à l'état haut ligne 28, c'est qu'on y est depuis au moins 7+10 = 17 cycles lorsque l'on arrive en début de ligne 29.

Admettons que nous sortions de la boucle RDL50 en ligne 31, il se sera alors passé 17 + 7 + 255*(5+10+7+10)+5+10 = 8199 cycles, soit 4,0995 ms au niveau haut... C'est bien trop pour le niveau haut d'un bit leader qui ne devrait jamais excéder 283,5 µs !!! Dans ces condition, on peut de nouveau se permettre de reprendre tout au début ce qui donne encore  l'occasion au DAI de nous faire de l'oeil avec son curseur.

En revanche, si l'on sort en ligne 33, c'est que l'on vient de détecter un retour au niveau bas... Nous sommes donc sortis de la boucle RDL50 avec dans B, le nombre de passages dans la boucle... Dans ces conditions, nous sommes restés à l'état haut pendant 17+ B*(5+10+7+10) - 7 - 10 = B*32 cycles.

Notons que la durée normale de l'état haut d'un bit leader est de 567 cycles, soit 283,5 µs. L'on peut donc s'attendre à ce que l'on passe 567/32 = 18 fois dans la boucle. On s'attendrait donc à ce que le programme initialise la valeur C avec 18 et non pas 40 (:28 en ligne 13). Toutefois, on sait également que la taille du bit leader est modifiable, ce qui signifie que cette fonction doit aussi fonctionner pour d'autres valeurs, alors pourquoi pas 40 ?

Voyons la suite :

34 MOV  A,B 5 A contient le nombre de passages dans la boucle RDL50
35   SUB C 4 A  = A - C; On calcule la différence entre la durée de l'état haut de la première des impulsions et la durée de l'états haut de l'impulsion qui vient d'être lue
36   JP RDL60 10 Si le résultat est positif on continue ligne 39
37   CMA   4 Sinon, on calcule le complément à deux
38   INR A 5 Pour obtenir la valeur absolue de la différence
39 RDL60 MOV E,A 5  La valeur absolue de A-C est stockée dans E
40   MOV A,C 5 Les lignes de 40 à 44 calculent C/8 (à peu de choses près, en fait le résultat de cette opération est égale à 2*ENT(C/16)
41   ANI :F0 7  
42   RAR   4  
43   RAR   4  
44   RAR   4 A cette étape A contient à peu de choses près C/8. Comme dit ci-desssus, A contient en fait 2*ENT(C/16)
45   CMP E 4 On teste si la différence de durée entre l'état haut de la première impulsion et l'état haut de l'impusion courante dépasse 1/8ème de la durée de l'état haut de la première impulsion.
46   JC RDL70 10 Si c'est le cas on continue en RDL70
47   DCR D 5 Tout va bien la marge est respectée, on décrémente D
48   JNZ RDL30 10 Si nous n'avons pas réalisé positivement le test 20 fois, alors continuer
49   INR D 5 On s'attendrait à terminer... Mais non,le résultat de cette ligne consiste à mettre 1 dans D pour continuer à attendre jusqu'à ce que l'on tombe sur un état haut qui dépasse la marge de 1/8ème. Cela signifiera alors qu'on a probablement atteint le bit de fin de leader dont la durée à l'état haut est celle de la première impulsion du bit de donnée 1. Vous noterez que cela interdit de définir la durée de l'état haut des bits leader égale à la durée de l'état haut du bit 1 !
50   JMP RDL30 10 On attend donc un dépassement.
51 RDL70 DCR D 5 On décrémente D
52   JNZ RDL05 10 Si D n'est pas égal à zéro, c'est que le dernier état haut lu n'est pas dans la marge de 1/8ème fixée, on recommence donc depuis le début en tentant une nouvelle synchronisation.
53   XRA A 4 Si D est à zéro, c'est que la synchronisation a été réalisée et que le dernier état haut lu est probablement l'état haut du bit de données 1 marquant la fin du leader. On s'apprête donc à lire la fin de ce bit de données à 1. Il faut donc attendre la fin de l'état bas en cours, puis l'état haut suivant et le repassage à l'état bas. C'est ce qui est fait ci-dessous.
54 RDL80 ORA M 4  
55   JP RDL80 10 On boucle tant que le signal est bas
56 RDL90 ANA M 4  
57   JM RDL90 10 On boucle tant que le signal est haut
58   POP H 10 Arrivé à ce point nous avons normalement lu la fin du bit de de données 1 marquant la fin du leader. On peut restaurer les registres utilisés et sortir
59   POP D 10  
60   POP B 10  
61   RET   10  

On voit qu'à la fin de cette routine, nous n'avons nullement la garantie que le leader est bel et bien terminé, c'est pourquoi il faut encore tester que les signaux qui suivent constituent 8 bits marquant la fin définitive du leader. C'est ce que fait la ligne 3 en appelant RBYTE chargée de lire 8 bits de donnée. Si cette fonction réussit, il faut encore que l'octet lu soit égal à :55, faute de quoi on reprendra tout à zéro une fois de plus (lignes 5 et 6).

Enfin, on essaye de lire l'octet de type de fichier (ligne 7), si la fonction échoue, on reprend tout à zéro, sinon on sort de RHDR avec le type de fichier lu dans A.

 

 

Copyright 2004-2023 © Bruno VIVIEN tous droits réservés.