                 ------------------------------------------
                  - PROGRAMME DE LECTURE DES IDS ET DU GAP -
                  ------------------------------------------ 
 
        Se r{f{rer au fichier pr{c{dent (analyse 1) pour les d{tails .
 
     NOTE : Les pistes format{es en simple densit{ {tant aussi communes que le 
 cercueil @ 8 places ,  la  section  analyse  est  limit{e aux piste en double 
 densit{ . Toute piste en SD  renverra  un r{sultat erronn{ . L'emplacement o| 
 devrait figurer l'analyse en SD est mentionn{ . Ce point ne sera compl{t{ que 
 beaucoup plus tard . Au cas o|  vous souhaiteriez {crire votre propre routine 
 d'analyse en SD , notez  que  le  principe  est  absolument identique !
 ;
 ;- CHERCHER GAP & NB.SECTEURS -
 ;
 TFGAP   DB 31,2,24,18,24," RECHERCHE TAILLE FORMAT ",24+#80
 ;
 FINDLEN CALL VERIID   ;D{termine densit{,lit IDS,stocke IDS,compte secteurs  
 ;
 ;Ici la densit{ et le nombre de secteurs  sont  connus , la s{rie d'IDS de la 
 ;piste @ {t{ stock{e dans la zone IDINRA ou IDINRB selon le drive .
 ;
         LD HL,TFGAP    ;Afficher message lecture gap
         CALL PRT
         LD HL,128       ;Commencer par la plus petite taille possible
         LD (LONGSEC),HL ;Longueur du secteur en octets
         LD HL,LITFDC2   ;Adresse @ appeler par le biais d'INSTRU9 (Rout.FDC) 
         CALL COMLIPI    ;Composer commande Lire piste
         XOR A           ;1}re taille secteur @ tester = 0
 ;
 NEXTLON LD (QUATRID+3),A ;Initialiser zone IDS @ transmettre pour instruction
         LD (LENSEC),A
         CALL INSTRU9    ;Aller Lire la Piste
 ;
         LD A,(ET1)      ;Voir si Missing Adress Mark ? VERIID ayant d{j@
         BIT 0,A         ;test{ ce point c'est juste une s{curit{ de plus
         JR Z,FORMOUI
 ;
         LD HL,TNONFOR   ;MAM! , la piste n'est pas format{e
         CALL PRT        ;Sortir erreur
         XOR A           ;Oter les flags pour interpr{tation correcte
         RET             ;Au retour
 ;
 FORMOUI LD HL,ET2    ;Voir maintenant si DD (Erreur Data dans Donn{es ?
         BIT 5,(HL)   ;Si pas DD la longueur donn{e dans QUATRID+3
         JR Z,OKLONG  ;correspond @ la vraie longueur de secteur
 ;
         LD HL,(LONGSEC)  ;Sinon on passe @ la taille imm{diatement
         ADD HL,HL        ;sup{rieure
         LD (LONGSEC),HL
         LD A,(QUATRID+3) ;LS+1
         INC A            ;En principe un secteur ne peut e^tre de taille 6
         CP 6             ;(8192 octets) dans le doute on pouura remplacer
         JR NZ,NEXTLON    ;par CP 7
 ;
 OKLONG  LD IY,QUATRID  ;Augmenter la taille r{elle de 1 pour tromper
         INC (IY+3)     ;l'instruction lire piste
         CALL INSTRU9   ;Lire GAP par le biais de Lire piste
         DEC (IY+3)     ;Restaurer vraie taille secteur
         LD HL,BUFGAPS  ;Pointer le buffer de stockage des GAPS
         LD A,(HL)      ;Ranger le 1er octet qui doit e^tre &4E
 OKGAP1  LD (VALGAPF),A
         CP #4E
         JR Z,OKGAP     ;Si c'est bien &4E c'est bon
 ;
         LD A,(FLAGDEN) ;Si le GAP est <>#4E . L'erreur vient peut e^tre d'une
         CP #FF         ;piste en simple densit{ . V{rifier !
         JR Z,NOGAP     ;Si FLAGDEN=#FF (D.Dens.)le GAP est vraiment <> #4E
 ;
         LD A,#4E       ;Sinon fixer arbitrairement et continuer
         JR OKGAP1      ;* ECRIRE ULTERIEUREMENT SECTION ANALYSE POUR SD !!! *
 ;
 NOGAP   LD BC,TBADGAP  ;GAP vraiment<>#4E : Echec .
         JP PRTERR      ;Afficher erreur et fini .
 ;
 OKGAP   LD A,(NBSEC)   ;Si un seul secteur , GAP = #FF d'office car on ne
         DEC A          ;peut utiliser les octets SYNC. du secteur suivant
         JR NZ,FINDGAP  ;pour en d{terminer la longueur .
 ;
 UNSEUL  DEC A          ;0-1 = #FF
         LD (GAPFORM),A
         SCF            ;Marque op{ration r{ussie .
         RET
 ;
 ;- Trouver la longueur du GAP -
 ;
 FINDGAP LD HL,BUFGAPS+1 ;Sauter le 1er octet
         LD B,255        ;Ne peut pas e^tre plus long que 255
         LD C,1          ;Compteur de longueur du GAP (Ne peut e^tre 0)
 ;
 BCLGAPS LD A,(HL)       ;Octet pris dans le buffer de GAP
         OR A            ;Si 0 ou #FF voir si on est arriv{ en zone SYNC
         JR Z,NEXTSYN    ;du secteur suivant .
         CP #FF
         JR Z,NEXTSYN
 ;
 SUITGAP INC HL
         INC C           ;Sinon 1 octet de plus et on continue
         DJNZ BCLGAPS
 ;
         LD BC,TGAPTL ;Si on sort de la boucle par ici le GAP est plus
         JP PRTERR    ;long que #FF . Il y-@ un malaise donc on annule
 ;
 ;Tester si on est bien en zone SYNC du secteur suivant . On pourrait en
 ;effet trouver un octet @ 0 ou @ #FF dans le GAP . Sur une centaine de
 ;disquettes , nous n'avons pas rencontr{ de longues s{ries de ces 2 valeurs
 ;pour cette raison on ne teste la r{p{tition de 0 ou #FF que sur 3 octets
 ;de distance . En cas de besoin on pourra rajouter quelques INC HL (jusqu'@
 ;8 - 9) . N'oubliez pas que la zone SYNC est parfois modifi{e et que le 
 ;nombre d'octets identiques passe souvent de 12 @ 10 !
 ;
 NEXTSYN PUSH HL       ;Voir si suite = SYNC
         INC HL
         INC HL
         INC HL
         CP (HL)
         POP HL
         JR NZ,SUITGAP  ;NON : On continue
         LD A,C
         LD (GAPFORM),A ;OUI : On range le GAP et c'est fini .
         SCF
         RET
 ;
 ;Ici commence la routine VERIID appel{e au d{but de cette section .
 ;
 ;- LIRE LES ID -
 ;
 TLITIDS DB 31,2,24,18,24," LECTURE DES IDS ",24+#80
 ;
 VERIID  LD HL,TLITIDS  ;Afficher commande
         CALL PRT
         XOR A          ;Mise @ 0 du flag d'erreurs
         LD (FLAGERR),A
         LD IX,IDINDRA  ;Table des IDS LUS
         CALL INCPTID   ;dans IX & HL et selon le drive
         CALL RAZIDS    ;RAZ zone ID
 ;
         PUSH IX
         POP DE         ;Debut de la zone IDS dans DE
         LD (PTRIDS),DE ;Memoriser
         CALL TSTDIDC   ;Chercher densite et debut piste (Voir ANALYSE 1)
 ;
         DI            ;Modifier un vecteur d'interruption alors que celles
         LD HL,SUBROUT ;ci sont actives est tr}s d{conseill{ !
         LD (#39),HL   ;La routine SUBROUT activ{e par les interruptions se
         XOR A         ;contente d'incr{menter r{guli}rement le compteur
         LD (NBFOIS),A ;NBFOIS
         LD C,#FF      ;#FF Parce qu'un secteur de trop est lu
         EI
 ;
 NEXTID  INC C         ;Compter le nombre d'IDS lus
         PUSH BC
         CALL INSTRU2
         CALL RESU1     ;Branchement sp{cial . Les interruptions ne doivent pas
         LD  HL,ETPIST  ;e^tre interdites par la phase r{sultat , cela 
         LD DE,(PTRIDS) ;stopperait le compteur
         LD BC,4        ;Range 4 octets du resultat (les 4 IDS)
         LDIR
         LD (PTRIDS),DE ;Nouveau pointeur IDS
         LD A,(NBFOIS)  ;Tester compteur
         CP 60          ;60 fois
         POP BC
         JR C,NEXTID    ;Pas fini tant que < 60
         LD A,C
         LD (NBSEC),A   ;Fini donc ranger
 ;
         DI             ;Restaurer vecteur . On teste d'abord le type du
         LD A,(#BD17)   ;CPC (464-6128) car le vecteur en #38 n'est pas
         CP 11          ;le me^me sur les 2 !
         LD HL,#B939
         JR Z,PASONZE
         LD HL,#B941
 PASONZE LD (#39),HL
         EI
 ;
         CALL ID4TRANS  ;Recopier les 4 premiers IDS lus dans QUATRID
         CALL RECOPID   ;Recopier IDS lus dans IDS a ecrire
         PUSH HL
         LD A,(COMMAND) ;Afficher densite de la piste
         CP #4A
         LD A,#FF
         LD HL,TDDENS
         JR Z,SETDENS
         LD A,%10111111
         LD HL,TSDENS
 SETDENS CALL CHGD
         SCF
         POP HL
 ;
 RETVERI DB  0        ;Ici est parfois implant{ un #C9 qui interdit
         LD A,(NBSEC) ;L'affichage des IDS .
 ;
 ;- Affichage des IDS LUS -
 ;
         LD B,A
         LD C,0       ;C = Compteur de lignes
         CALL FENIDL  ;Ouvrir 1}re fene^tre IDS
         CALL INV     ;Vid{o inverse
 ;
 AFFIDS  CALL AFF4ID    ;Afficher 4 IDS
         CALL Z,FENIDL1 ;Si C=16 changer de fene^tre
         DJNZ AFFIDS
 ;
         CALL INV     ;Restaurer vid{o normale
         JP FINLIID   ;Fini
 :
 ;- Sub routines li{es @ VERIID -
 ;
 RECOPID PUSH IX       ;Pr}server pointeur IDS LUS
         LD IX,IDOUTDA ;Chercher pointeur IDS a ecrire selon drive
         CALL INCPTID
         EX DE,HL      ;Ranger dans DE
         POP HL
         PUSH HL
         LD BC,256     ;Recopier IDS LUS dans IDS a ecrire
         LDIR
         POP HL
         RET
 ;
 AFF4ID  PUSH BC    ;Afficher une s{rie de 4 IDS
         LD B,4
         CALL SPACE
 ;
 BCLAFID LD A,(HL)
         CALL PRTHEX1
         INC HL
         DJNZ BCLAFID
 ;
         POP BC
 TSTC    INC C
         LD A,C
         CP 16       ;Tester si 16 IDS lignes sorties . Si oui Z mis
         RET
 ;
 TSTC1   CALL TSTC  ;Test sp{cial du nombre de lignes sorti sur 16 ou 32
         RET Z      ;16 lignes sorties
         CP 32
         RET NZ     ;Pas 32 lignes sorties
 ;
         LD A,11
         CALL #BB5A ;Annuler le dernier CR sinon scroll FEN2 si 32 secteurs
         XOR A
         INC A      ;SET FLAG NZ pour interpr{tation au retour
         RET
 ;
 IDRATE  LD A,(ET1)   ;Erreur dans la lecture des IDS
         BIT 0,A
         JR Z,IDRATE1 ;Autre que MAM , juste signaler et stopper
 
         PUSH HL       ;Missing Adress Mark , aucun ID ne peut e^tre lu
         LD HL,TNONFOR ;La piste n'est pas format{e !
         CALL PRT
         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 GAP
