IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Turbo Pascal Discussion :

Interruptions, timer et "mode resident"


Sujet :

Turbo Pascal

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 26
    Par défaut Interruptions, timer et "mode resident"
    Bonjour,
    Je suis de nouveau confronté à un soucis sur la gestion des interruptions et je dois dire que je ne comprends pas tout.
    On m'a refilé le code source d'un programme compilé en mode protegé qui a une procedure appelée resident. D'apres ce que j'ai compris, cette derniere est appelée toute les x millisecondes.

    La procedure init_axfond permet d'initialiser des variables et le plus important, permet la sauvegarde du Vecteur Interruption 8 ( Timer). On met ce dernier dans l'interrupt 80. Enfin, on remplace vecteur de interruption 8 par l'adresse de la procedure resident

    1. Pourquoi mettre le vecteur d'interruption 8 en 80 ?

    2. Que fait cette ligne INTR($80,Dos.Registers(PARMS)) ?

    3. Pourquoi on utlise un PARMS qui n'est jamais initialisée ?

    4. Comment ca marche, la reprogrammation du timer, je suis aussi un peu perdu avec les lignes suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PORT[$43] := $36 ;  
    PORT[$40] := LO(DIVISEUR) ;
    PORT[$40] := HI(DIVISEUR) ;

    D'autres questions viendront par la suite

    Merci d'avoir pris le temps de me lire



    Extrait du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    {$i-}
    Program AxTDF;
     
    Uses DOS, CRT, WINAPI;
     
    Const
     the_dev_add = 1;    (*Adresse peripherique usb*)
     in_endpoint = 1;
     out_endpoint = 1;    (* 2 avant *)
     
     TIMER_DIV : Integer = 6;
     
     
     
     
     
    Var
     tab_out: Array[0..16] Of Byte;   (*PC To PIC*)
     tab_in: Array[0..32] Of Byte;   (*PIC to PC*)
     i,j,k,l,mm : integer;
     PointInt08 : pointer ;
     PARMS :Registers ;
     TIMER_COUNT : Integer;
     TEMPS_SECONDE : real;
     h, m, s, ms : word ;
     h2, m2, s2, ms2 : word ;
     h1, m1, s1, ms1 : word ;
     duree : double;
     
     
    {$F+}
    PROCEDURE RESIDENT; Interrupt ;
    BEGIN
      (*TEMPS_SECONDE:=TEMPS_SECONDE+T_base;*)
      do_in;
      for i:=1 to 32 do tab_in[i]:=buffer_i[i];
      for i:=1 to 16 do buffer_o[i]:=tab_out[i];
      do_out;
     
      TIMER_COUNT:=(TIMER_COUNT+1) MOD TIMER_DIV;
      IF TIMER_COUNT=0 THEN
            INTR($80,Dos.Registers(PARMS))
      ELSE
      begin timer_count:=0;
            PORT[$20]:=$20; {Signale Fin d'interruption}
      end;
    END; {-----procedure RESIDENT}
    {$F-}
     
    PROCEDURE INIT_AXFOND ;
    const diviseur : integer = 3730;
    BEGIN
     
      for i:=0 to 16 do tab_out[i]:=0;
      for i:=0 to 32 do tab_in[i]:=0;
     
      {-----------------  Installation IT  -------------------------------------}
     
     INLINE($FA) ;   {CLI _ Clear Interrupt}
     
      {Sauvegarde Vecteur Interruption 8 ( Timer), on le met dans l'interrupt
      80, qui est appel‚e de temps en temps pour mettre … jour le Timer. Enfin,
      on remplace vecteur de interruption 8 par l'adresse du programme de fond}
      GetIntVec ($08, PointInt08) ;
      SetIntVec ($80, PointInt08) ;
      SetIntVec ($08, @RESIDENT) ;
      {Lancement du Timer}
      PORT[$43] := $36 ;   {   at : PORT[$5F]:=$36;}
      PORT[$40] := LO(DIVISEUR) ;
      PORT[$40] := HI(DIVISEUR) ;
     INLINE($FB) ;  {STI - Set Interrupt}
     WRITELN ('Tache de Fond installee en IT ') ;
     
    END ; {Fin de la Procedure INIT_AXFOND}
     
    PROCEDURE FIN_IT ;
     {d‚sactive la tache de fond}
    BEGIN
      INLINE($FA) ;   {CLI _ Clear Interrupt}
      {R‚tablit le vecteur d'interruption 08 d'origine}
      GetIntVec ($80, PointInt08) ;
      SetIntVec ($08, PointInt08) ;
      {Lancement du Timer}
      PORT[$43] := $36 ;
      PORT[$40] := 0 ;
      PORT[$40] := 0 ;
      INLINE($FB) ;  {STI - Set Interrupt}
      WRITELN ('IT Tache de Fond desinstallee ') ;
     
    END ;
     
    (*//////////////////////////// MAIN ////////////////////////////////////*)
    Begin
      clrscr;
      j:=0;k:=0;m:=0;s:=0;m2:=0;s2:=0;
      timer_count:=0;
      gettime(h,m,s,ms);
      writeln('Heure debut : ',h,':',m,':',s);
      init_axfond;
     
      repeat
        k:=k+1;
        if j<10 then
        begin
          j:=j+1;
          TAB_OUT[2] :=$80;
        end
        else
        begin
          TAB_OUT[2] :=$40;
          j:=j+1;
          if j>20 then j:=0;
        end;
        for mm:=1 to 100 do
          FOR L:=1 to 30000 do TAB_OUT[3]:=$02;
    (*    do_in;
        for i:=1 to 32 do tab_in[i]:=buffer_i[i];
        for i:=1 to 16 do buffer_o[i]:=tab_out[i];
      (*  do_out;   *)
        gettime(h2,m2,s2,ms2);
        write('temps:',h2,':',m2,':',s2,':',ms2,
                ' prec :',h,':',m,':',s,':',ms);
        h1:=h2; m1:=m2; s1:=s2; ms1:=ms2;
        if k>1 then
        BEGIN
          IF ms>ms2 THEN BEGIN s2:=s2-1; ms2:=ms2+100; END;
          IF s>s2 THEN BEGIN m2:=m2-1; s2:=s2+60; END;
          IF m>m2 THEN BEGIN h2:=h2-1; m2:=m2+60; END;
          duree := (h2-h)*3600 + (m2-m)*60 + (s2-s) +(ms2-ms)/100;
        END;
        h:=h1; m:=m1; s:=s1; ms:=ms1;
        writeln(' B28+B29:',TAB_IN[1],' d=',duree:5:2,' k=',k,' ',timer_count);
      until (k=100) or keypressed;
      write('k=',k);
      gettime(h2,m2,s2,ms2);
      writeln(' Heure fin: ',h2,':',m2,':',s2);
      {FIN_IT;}
     end.

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    salut,

    je n'ai pas tout compris, mais ce qui me surprend c'est qu'en mode protégé les interruptions $00 à $1F correspondent aux exceptions du processeur, il faut donc reprogrammer le PIC pour le mode protégé...à moins que DMPI s'en charge ?!
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 465
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 465
    Par défaut
    Quelques infos ici, mais c'est du mode réel :
    http://pascal.developpez.com/cours/artint/

    La Ralf Brown Interruption List peut t'aider pour comprendre le calcul pour la modification du Timer. J'avais une vieille version compilée qui pouvait s'intégrer dans l'aide de Turbo Pascal (si je ne l'ai pas perdue lors du crash de mon dernier disque dur...). Cette version était plus complète car il y avait aussi les ports et la mémoire, si je la retrouve je l'uploade sur le site...
    Sinon à partir des sources de Ralf Brown, il doit bien y avoir un outil qui permet de browser ça de façon conviviale.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 26
    Par défaut
    Apparemment dmpi se débrouille pour faire le lien.

    La variable DIVISEUR me permet apparemment de gérer la fréquence d'appel à la procédure interruption RESIDENT. Faut que j'essaie de comprendre ce que fait ce $80 !!

  5. #5
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    Citation Envoyé par rocky77 Voir le message
    Apparemment dmpi se débrouille pour faire le lien.

    La variable DIVISEUR me permet apparemment de gérer la fréquence d'appel à la procédure interruption RESIDENT. Faut que j'essaie de comprendre ce que fait ce $80 !!
    à priori $80 ne fait rien, c'est juste un vecteur libre utilisé pour appeler le code original...mais ça me parait surprenant comme méthode, un JMP vers le vecteur d'origine est plus classique...à moins que ce ne soit lié au mode protégé ?!
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre émérite

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    à priori $80 ne fait rien, c'est juste un vecteur libre utilisé pour appeler le code original...mais ça me parait surprenant comme méthode, un JMP vers le vecteur d'origine est plus classique...à moins que ce ne soit lié au mode protégé ?!
    JMP: Classique en assembleur ! Mais en pur Turbo Pascal c'est moins évident. La Procedure INTR de l'unité Dos, employée ici, exige que le vecteur soit présent dans la table des interruptions.

    En ce qui concerne justement l'instruction INTR($80,Dos.Registers(PARMS)) je pense que le transtypage en type Registers de l'unité Dos est inutile car la variable PARMS est déjà déclarée comme étant de ce type. On pourrait simplement écrire INTR($80, PARMS);

    Pour répondre aux questions 2 et 3 de rocky77 PARMS est utilisé pour initialiser les registres du processeur avant l'appel de l'interruption et renvoyer la nouvelle valeur de ces registres au retour. Cela est prévu pour passer des paramètres et récupérer le résultat des interruptions Logicielles. Mais ici il s'agit d'une interruption Matérielle qui, par définition, ne prend aucun paramètre dans les registres (mais est sensée les restituer inchangés). PARMS peut donc avoir un contenu quelconque et n'a pas besoin d'être initialisé.

Discussions similaires

  1. Interruption Timer sous Borland C
    Par Spacy_green dans le forum C
    Réponses: 3
    Dernier message: 20/06/2006, 23h40
  2. Réponses: 17
    Dernier message: 19/02/2005, 19h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo