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.