                  -----------------------------------------
                   - ANALYSE DE PISTE . SUITE ET FIN (OUF) -
                   -----------------------------------------
 
     A ce stade , notre analyse nous a donn{ : Les IDS , le nombre de secteurs 
 , la taille du GAP , la taille  du  format . Il reste encore @ d{terminer les 
 {tats d'erreur provoqu{s par la lecture  de  chaque  secteur . Pour ceci , on 
 lance une instruction de lecture  secteur  par  secteur  avec en param}tres : 
 Piste , te^te , taille  secteur  ,  GAP  ,  conformes aux donn{es de formatage 
 fournies par l'analyse et le num{ro de  secteur  lu  dans l'ID . Au retour on 
 interroge le r{sultat , FLAGERR  est  calcul{  dans  TESTERR et rang{ dans un 
 buffer qui conserve en m{moire l'{tat d'erreur  de  chaque secteur lu . Il ne 
 reste plus qu'@ afficher les erreurs en face de chaque ID .
 
     Comme les secteurs sont lus 1 @ 1 , un formatage irr{gulier ne posera pas 
 de probl}mes . Reste @ envisager la possibilit{ de plusieurs secteurs de me^me 
 num{ro sur une me^me piste .
 
     Soit la pire {pouvante concevable : Tous les secteurs de la piste portent 
 le me^me num{ro ! Comment les lire tous et dans l'ordre ?
 
                   La solution est dans la routine VERISEC .
 
     1 - Prendre les 4 IDS secteur stock{s par VERIID
     2 - Eliminer les IDS piste et te^te  .  Les remplacer par la piste et te^te 
 r{elles faute de quoi un {ventuel EP ou HD stopperait l'op{ration de lecture! 
 (C'est pour cela que les FLAG EP HD sont d{duits par comparaison , VERISEC ne 
 peut commettre  EP ou HD me^me si l'ID est erron{)
     3 - La recherche d'un secteur  @ lire commen\ant depuis l'orifice d'index 
 on acc{dera normalement au premier secteur .
     4 - Le premier secteur  vient  d'e^tre  lu  et  analys{  , il faut pointer 
 les suivants . On se cale sur le premier ID disponible comme pour lire le 1er 
 ID (TSTIDC) . Un compteur nous donne le nombre de secteurs d{ja lu . A partir 
 du moment ou on sait e^tre avant  le  1er  ID , on lance l'op{ration 'Lire ID' 
 autant de fois que de secteurs d{ja  analys{s  .  Le prochain ID @ venir sera 
 celui du secteur qu'il faut effectivemnt lire !
     Une piste du genre  :  12,12,12,12,12,12,12,12,12  peut maintenant livrer 
 tous ses secrets .
 ;
 ;- Analyse piste -
 ;
 ANAPIST CALL SELEPI1    ;Selection piste , 1 POP Pour menu si erreur
         LD A,#C9
         LD (RETVERI),A ;Pas afficher les IDS de mani}re habituelle
 ;
 NEXTANA LD HL,TEFFLB1  ;Branchement pour boucle analyse
         CALL PRT       ;Effacer ligne basse
         CALL GOPIST1   ;Aller sur piste
         JP NC,ERPFORM  ;Piste pas trouvee = Erreur
 ;
 ANABIS  CALL FINDLEN   ;Lire ID et calculer longueur GAP
 PASFOR1 JP NC,PASFORM  ;Si piste pas formatee
 ;
         CALL FIXLFF   ;0 ou #FF selon taille secteur
 ;
         LD HL,TANAP   ;Afficher la serie des IDS
         CALL PRT
         PUSH IX       ;Zone IDS dans HL
         POP HL
         LD A,(NBSEC)  ;Ranger nombre de secteurs dans B
         LD B,A
         LD C,0        ;C est utilis{ par AFF4ID
         PUSH HL
         PUSH BC
 ;
         CALL FENIDE
         CALL INV
 AFFIDS1 CALL AFF4ID   ;Afficher 4IDS
         CALL Z,FENIDL
         DJNZ AFFIDS1
         CALL INV
 ;
         CALL FENIDE1A ;Ouvrir fene^tre r{sultat secteur
         LD A,#46      ;Commande lire secteur
         LD HL,LITFDC1 ;Lire les donn{es sans stocker les octets
         CALL SETCOM2  ;Initialiser commande
 ;
         XOR A
         LD (COUNT),A  ;Nombre de secteurs lus = 0
         LD HL,LISTERR
         LD (POINTER),HL ;Initialiser pointeur stockage flags erreurs
 ;
         POP BC
         POP HL        ;IDS lus dans HL
 ;
 VERISEC INC HL           ;Sauter ID piste pour EP
         LD A,(HL)
         LD (QUATRID+1),A ;Ranger numero tete r{elle
         INC HL
         LD A,(HL)
         LD (QUATRID+2),A ;Numero de secteur en cours
         LD (DERSEC),A    ;donne comme numero dernier secteur
         INC HL
         LD A,(HL)        ;Longueur secteur lue dans l'ID
         LD (QUATRID+3),A
         INC HL           ;Pointer ID suivant
         PUSH HL          ;Et pr{server
         PUSH BC
 ;
         LD A,(COUNT)    ;Comptage des secteurs lus . Si <> de 0
         OR A            ;Appeler VISESEC qui attendra que la rotation du
         CALL NZ,VISESEC ;disque am}ne le bon secteur en position de lecture
         CALL INSTRU9    ;Lire secteur
 ;
         CALL TSTERRS    ;Tester et ranger erreurs
         LD A,(IY+0)     ;Stocker le flag erreurs
         LD HL,(POINTER)
         LD (HL),A
         INC HL
         LD (POINTER),HL
 ;
         CALL INV
         CALL SPACE
         CALL PRT3ERR    ;Afficher les erreurs
         CALL INV
         POP BC
         CALL TSTC1     ;C=C+1=16 ou 32 ?
         CALL NZ,CR     ;Changer de fene^tre si + de 16 lignes
         CALL Z,FENIDL1A
         LD HL,COUNT
         INC (HL)       ;Un secteur de plus a {t{ lu
 ;
         POP HL
         DJNZ VERISEC   ;Au suivant
 ;
         CALL FEN1     ;Fene^tre pour affichage r{sultat global
         LD HL,TLEN    ;Afficher VRAIE longueur de formatage
         CALL PRTLOC2
         LD A,(LENSEC)
         CALL PRTHEX1
         LD HL,TLONG   ;Afficher VRAIE longueur en octets
         CALL PRT
         LD HL,(LONGSEC)
         LD (VALEUR),HL
         CALL DEUCON16
         LD HL,TGAPF    ;Octet GAP
         CALL PRT
         LD A,(VALGAPF)
         CALL PRTHEX1
         LD HL,TLGAPF
         CALL PRT
         LD A,(GAPFORM) ;Taille GAP
         CALL PRTHEX1
 ;
 PASFORM LD HL,TFINANA  ;Options de fin d'analyse Stop , Continue ou Print
         CALL PRT
 TSTANA  CALL #BB06
         AND #DF
         CP "P"
         JP NZ,RETANA
 ;
 ;- Imprimer r{sultat d'analyse -
 ;
         CALL #BD2E    ;Imprimante ready ?
         JP C,RETANA   ;Non ! Annuler
 ;
 ;- Imprimer analyse -
 ;
         CALL SETIMP   ;D{tourner routines
         LD HL,TPIST
         CALL PRT
         LD A,(PISTSEL)
         CALL PRTHEX1
         CALL CR
 ;
         PUSH IX
         POP HL
         LD DE,LISTERR ;S{rie des FLAGERR
 ;
         LD A,(NBSEC)
         LD B,A
 ;
 IMPERRS CALL AFF4ID   ;Imprimer 4IDS
         LD A,(DE)
         INC DE
         PUSH HL
         PUSH DE
         PUSH BC
         LD (FLAGERR),A ;Suivis de l'{tat d'erreur
         CALL PRT3ERR
         LD HL,TINTIMP
         CALL PRT
         POP BC
         POP DE
         POP HL
         DJNZ IMPERRS
 ;
         CALL CR        ;Imprimer donn{es g{n{rales
         LD HL,TLEN
         CALL PRT
         LD A,(LENSEC)
         CALL PRTHEX1
         LD HL,TGAPF
         CALL PRT
         LD A,(VALGAPF)
         CALL PRTHEX1
         LD HL,TLGAPF
         CALL PRT
         LD A,(GAPFORM)
         CALL PRTHEX1
         CALL CR
 
 REIMP   LD A,"*"
         CALL #BD2B
         JR NC,REIMP
         CALL CR
         CALL RESIMP    ;Restaurer routines affichage
 ;
 RETANA  DB 0           ;RET Si l'appel vient de LITSEC ou LITPIST
         CP "S"
         JR Z,FINANAP
         CALL FEN2
         CALL INCPIST   ;Piste suivante
         JP NZ,NEXTANA
 ;
 FINANAP LD A,41        ;Fin d'analyse
         LD (WAITPIS),A ;Restaurer temporisation
         CALL FIXPARA   ;Initialiser les param}tres g{n{raux en fonction
         JP FINLIID     ;du r{sultat d'analyse et c'est fini
 ;
 TFINANA DB 31,26,22,24," [P]rint - [S]top - Continue ",24+#80
 ;
 ;- Initialise le programme en fonction d'une analyse -
 ;
 FIXPARA CALL ID4TRANS    ;Remettre les 4 1ers IDS dans QUATRID
         LD A,(LENSEC)
         LD (QUATRID+3),A ;Vraie taille secteur
         LD DE,4
         AND A
         SBC HL,DE
         LD HL,QUATRID+2
         LD A,(HL)
         LD (PREMSEC),A   ;1er secteur physiquement sur la piste
         INC HL
         LD A,(NBSEC)     ;Chercher le dernier secteur PHYSIQUE et
         PUSH IX          ;Ranger en DERSEC
         POP HL
         LD DE,4
         DEC A
 PTDERSC ADD HL,DE
         DEC A
         JR NZ,PTDERSC
         INC HL
         INC HL
         LD A,(HL)
         LD (DERSEC),A
 ;
         LD A,(GAPFORM) ;Longueur GAP formatage
         SRL A          ;GAP RW = GAP Formatage / 2
         JR NZ,OKGAPRW
         LD A,1         ;Si etait 1 , devient 0 dans de cas GAPRW=GAFORM=1
 OKGAPRW LD (GAPRW),A
 ;
         XOR A
         LD (RETVERI),A ;Annuler le RET
         RET            ;Fini
 ;
 FIXLFF  LD A,(LENSEC) ;Si taille secteur = 0 l'octet LD est @ 0 @ #FF sinon
         OR A
         JR Z,SETLEN2
         LD A,#FF
 SETLEN2 LD (LSZERO),A
         RET
 ;
 ;- Viser un secteur pr{cis sur le disque -
 ;
 VISESEC PUSH BC
         CALL TSTDIDC  ;Attendre orifice d'index
 ;
         LD A,(COUNT)
         LD B,A        ;Nombre de secteurs d{ja test{s
 POINSEC CALL INSTRU2  ;Lire B IDS pour sauter secteurs deja lus
         CALL RESULT
         DJNZ POINSEC
 ;
         POP BC        ;L'ID qui arrive est celui qu'il nous faut
         RET
 ;
 COUNT   DB 0
 TOK     DB "O","K",8,8+#80
 TERRS   DB 31,2,22,24," Etat d'erreur : ",24," OK",8,8+#80
 TERRFDC DB "EP ","HD ","CR ","ND ","CM ","DD ","MA ","DA "
 TLEN    DB "Taille reelle : ","&"+#80
 TLONG   DB "Soit :"," ",#80
 TGAPF   DB "octets.GAP-F : ","&"+#80
 TLGAPF  DB "Longueur : ","&"+#80
 TINTIMP DB 32,32,32,">",32+#80
 ;
                    FIN DE SECTION : SUITE : "ROUTINES FDC"
    RT
         POP HL
         LD A,1
         LD (FLAGERR),A ;Marquer non formate
         XOR A
         RET
 ;
 IDRATE1 LD BC,TERRID
         JP PRTERR
 ;
 ID4TRANS PUSH IX ;Transf{rer les 4 premiers IDS dans QUATRID
         POP HL
 ;
 IDTRANS4 PUSH BC ;Transf{rer les 4 octets point{s par HL
         PUSH DE
         LD DE,QUATRID
         LD BC,4
         LDIR
         POP DE
         POP BC
         RET
 ;
 SUBROUT DI          ;Compteur activ{ par interruption #39
         PUSH HL
         LD HL,NBFOIS
         INC (HL)
         POP HL
         EI 
         RET
 ;
 NBFOIS  DB 0
 PTRIDS  DEFW 0
 ;
 COMLIPI LD A,#42          ;Octet de commande lire piste
 SETCOM2 LD (COMMAN2),A
         LD (CODEOPE+1),HL ;Initialiser l'adresse @ 'CALLER' par INSTRU9
         RET               ;(En routines FDC)
 ;
 TNONFOR DB 31,60,2,24,"   NON  FORMATEE  ",7,24+#80
 TERRID  DB 31,15,23,"Commande ID","S"+#80
 TLITID  DB " Lire ID","s"+#80
 TGAPTL  DB 24," GAP > #FF ! ",7,24+#80
 TBADGAP DB 24," GAP DIFFERENT DE #4E ! ",24,7+#80
 ;
                 FIN DE SECTION : SUITE DANS "LECTURE DU FDC"
    itialiser une v{ritable 
 routine d'interruption ! Heureusement ,  @  l'adresse  &39  de tous les CPC'S 
 figure un vecteur d'interruption  (INTERRUPT  ENTRY  CONT'D) vers &B939 (464) 
 &B941 (6128) . En 2 br}ves instructions  , on remplace ce vecteur par SUBROUT 
 et c'est le syst}me Amstrad qui  s'occupera de l'incr{mentation du compteur . 
 Ce vecteur doit bien sur e^tre restaur{ apr}s usage .
 
       Les 3 probl}mes pos{s par la lecture des IDS sont enfin r{solus .
 
                  -------------------------------------------
                  - DETERMINER LA VRAIE LONGUEUR DE SECTEUR -
                  -------------------------------------------
 
     On peut parfaitement formater une piste avec  N secteurs de taille X puis 
 fournir des IDS longueur tous diff{rents  de  la taille r{elle de formatage . 
 On ne peut donc se baser sur  la  lecture des IDS pour d{terminer la longueur 
 r{elle d'un secteur .
 
     La solution est des plus simple . Toute instruction de lecture - {criture 
 demande entre autre , la transmission de la taille secteur (Voir SOS1 Th{orie 
 FDC) en phase instruction .  Si  cette  valeur  n'est  pas  {gale @ la taille 
 r{elle du secteur lu , la  phase  r{sultat  renverra le message Data Error in 
 Data Field (DD pour les intimes) . On en d{duit le principe suivant :
 
     1 - Taille envoy{e dans la phase instruction = 0 (+ Petite possible)
        2 - Lancer instruction de lecture   <-------------------------!
        3 - Lire r{sultat                                             !
        4 - R{sultat renvoie flag DD ?                                !
        5 - NON on vient de trouver la taille r{elle et c'est fini .  !
        6 - OUI on augmente la taille de 1 et on recommence en 2 >----!
 
     Une nouvelle fois la m{thode de l'essai et de l'erreur est payante !
 
                  -------------------------------------------
                  - TROUVER LA LONGUEUR DU GAP DE FORMATAGE -
                  -------------------------------------------
 
     Dernier point @ traiter , mais pas  le moindre . C'est un d{tournement de 
 l'instruction lire piste qui est employ{ .
 
     En cas d'erreur , les instructions  'Lire  - Ecrire secteurs' mettent les 
 flags {quivalents et stoppent imm{diatement la phase instruction en cours .
 
     Dans  les  me^mes  conditions  ,  'Lire   piste'  met  les  bits  d'erreur 
 correspondants mais continue l'op{ration  comme  si  de  rien n'{tait . Seule 
 l'erreur Over  run  l'interrompt  .  L'Over  run  est  le  flag  des  grandes 
 catastrophes . Il signifie que le  FDC  est compl}tement d{synchronis{ et est 
 incapable d'interpr{ter ce qu'il lit .
     
  Il faudra donc {tablir une routine sp{ciale le lecture pour ce cas pr{cis :
               1 - D{terminer le nombre exact d'octets @ lire .
               2 - Lire un octet en phase instruction . <-----!
               3 - Le stocker                                 !
               4 - D{cr{menter le nombre @ lire .             !
               5 - Si pas 0 recommencer  >--------------------!
               6 - Si 0 attendre l'Over Run 
               7 - Over run apparu , c'est fini .
 
     Faute de cette pr{caution , la  quantit{  d'octets lus et stock{s dans le 
 buffer d{passerait de tr}s loin la totalit{ de la m{moire disponible !
 
        Voyons un peu plus en d{tail le fonctionnement de lire piste .
 
  Soit une piste tout @ fait normale de 9 secteurs de taille 2 (512 octets) .
  En transmettant des param}tres exacts @ 'Lire piste' on aura dans l'ordre :
 
     1 - Reconnaissance de l'orifice d'index .
     2 - Test des octets d'en te^te de la piste . (Interne au FDC)
 
     3 - Contro^le Sync et IDAM 1er secteur .     (Interne au FDC)
     4 - Contro^le des IDS et du CRC .            (Interne au FDC)
     5 - GAP2 qui laisse le temps au FDC de finir le contro^le ci-dessus
     6 - 12 Octets pour synchro avec horloge interne
     7 - Lecture de la DAM                       (Interne au FDC)
     8 - Lecture des 512 octets de donn{es       (Disponibles au programmeur)
     9 - Lecture et contro^le du CRC
    10 - GAP3 de formatage pour temps de calcul CRC DAM (DD si incorrect)
    11 - Retour en 3 pour secteur suivant .
 
     Comme on le voit , l'instruction  est  bien  con\ue  pour ne lire QUE LES 
 OCTETS DE DONNEES .
     Conservant la me^me piste , transmettons @ cette instruction 'miracle' les 
 me^mes param}tres @ l'exception de  la  taille  secteur  que nous mettrons @ 3 
 soit 1024 octets .
 
      SOIT TAILLE REELLE + 1 = LE DOUBLE DE LA LONGUEUR REELLE DE SECTEUR
 
     Que va faire le FDC ? Pour  le  d{but  de  la piste et le premier secteur 
 tout se passera comme ci-dessus de 1  @  8  .  Mais apr}s , croyant qu'il y-@ 
 encore 512 octets de donn{es , il lira : 9 - Les 2 octets  CRC du 1er secteur 
 (qui ne nous int{ressent pas) ,  10  -  Les  Octets du GAP3 de formatage (que 
 l'on veut) , de 3 @ 8  les  octets  d'en te^te du secteur suivant ainsi qu'une 
 partie des donn{es . Apr}s quoi le FDC  cherchera @ lire des octets synchro - 
 CRC , etc... Au beau milieu de la  zone de donn{es du second secteur .Il s'en 
 trouvera fort perturb{ et renverra des  choses plus o| moins coh{rentes avant 
 de sombrer dans la folie et crier @ l'over run !
 
   NOTE 1 : Quelque soit la  taille  de  formatage  , ce proc{d{ reste valable 
 sauf dans le cas d'un secteur  de  taille  5  !  Dans  ce  cas il n'y a qu'un 
 secteur sur la piste et on ne peut lire le 