Chrono.pas

PROGRAM CHRONO;
{ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
 º Programme : CHRONO.PAS                                                  º
 º BUT ..... : RelevEle chronogramme lors de la configuration d'un port   º
 º             en sortie et ensuite de l'écriture de valeurs sur ce        º
 º             dernier.                                                    º
 º Auteur .. : CLAUS Stéphane                                              º
 º Date .... : 2.2.1997                                                    º
 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ}
 
USES
  Crt,      { UnitEstd Borland }
  Keyboard; { UnitEissue du Guide Turbo Pascal, Neil Rubenking }
 
 
VAR
  AdresseBase : WORD;
  LePort      : CHAR;
  Erreur      : INTEGER;
  Parametre   : STRING;
 
 
PROCEDURE AfficheSyntaxe(AvecPause:BOOLEAN);
{ BUT .......... : Affiche la syntaxe d'utilisation de ce programme
  PARAMETRES
    Entrée ..... : AvecPause: Si ETRUE, attend qu'une touche soit pressée
                   avant de terminer.
    Sortie ..... : --
  EFFETS DE BORD : Le PPI est configurEcorectement                         }
VAR
  Ch : CHAR;
BEGIN
  WriteLn;
  TextColor(LightRed);
  WriteLn ('ERREUR DE SYNTAXE');
  TextColor(LightGray);
  Writeln ('La syntaxe d''utilisation de ce programme est:');
  WriteLn;
  WriteLn ('CHRONO.EXE  Adresse  Port');
  WriteLn ('               Ý       Ý ');
  WriteLn ('               Ý       +-- Le port Eutiliser pour l''écriture (A, B ou C),');
  WriteLn ('               Ý           ce port est configurEen sorti, et les deux autres');
  WriteLn ('               Ý           en entrée.');
  WriteLn ('               +---------- L''adresse de base du PPI 8255 (300h = 768d)');
  WriteLn;
  IF AvecPause THEN BEGIN
    Write ('Pressez une touche pour continuer . . .');
    REPEAT UNTIL KeyPressed;
    WHILE KeyPressed DO BEGIN
      Ch := ReadKey;
    END; {WHILE}
    WriteLn;
  END; {IF}
END; {PROCEDURE AfficheSyntaxe}
 
 
PROCEDURE AffichePlageAdresses(AvecPause:BOOLEAN);
{ BUT .......... : Affiche la plage d'adresses utilisable avec ce programme
  PARAMETRES
    Entrée ..... : AvecPause: Si ETRUE, attend qu'une touche soit pressée
                   avant de terminer.
    Sortie ..... : --
  EFFETS DE BORD : Le PPI est configurEcorectement                         }
VAR
  Ch : CHAR;
BEGIN
  WriteLn;
  TextColor(LightRed);
  WriteLn ('ERREUR D''ADRESSES');
  TextColor(LightGray);
  WriteLn ('La plage d''adresses utilisable avec ce programme va de 300h E31Fh');
  WriteLn ('les adresses peuvent être données en hexa, en les faisant précéder du');
  WriteLn ('signe $ ($300 par exemple) ou directement en décimal.');
  WriteLn;
  IF AvecPause THEN BEGIN
    Write ('Pressez une touche pour continuer . . .');
    REPEAT UNTIL KeyPressed;
    WHILE KeyPressed DO BEGIN
      Ch := ReadKey;
    END; {WHILE}
    WriteLn;
  END; {IF}
END; {PROCEDURE AffichePlageAdresses}
 
 
PROCEDURE OutPortB(LePort:WORD; Value:BYTE); ASSEMBLER;
{ BUT: Ecriture sur un port
  PARAMETRES
    Entrée ..... : LePort = Adresse du port
                   Value = Valeur Eécrire
    Sortie ..... : --
  EFFETS DE BORD : Ecriture de données dur le port indiquE                 }
ASM
  PUSH  DX
  MOV   DX, LePort
  MOV   AL, Value
  OUT   DX, AL
  POP   DX
END; {PROCEDURE OutPortB}
 
 
PROCEDURE ConfigurePorts(Adresse : WORD; PortSortie: CHAR);
{ BUT .......... : Configure correctement le 8255
  PARAMETRES
    Entrée ..... : Adresse = L'adresse de base du PPI
                   PortSortie = Le port Econfigurer en sortie
    Sortie ..... : --
  EFFETS DE BORD : Le PPI est configurEcorectement
  REMARQUES .... : Mot de contrôle:
                   Bit 7 6 5 4  3 2 1 0
                       1-0-0-|--|-0-|-|--> Valeurs par défaut pour
                             |  |   | |    l'initialisation du mode 0
                             |  |   | |
                             +--|---|-|--> A (0=Sortie, 1=Entrée)
                                |   | |
                                |   +-|--> B (0=Sortie, 1=Entrée)
                                |     |
                                +-----+--> C haut/bas (0=Sortie, 1=Entrée)
 
                       1 0 0 0  1 0 1 1 = $83 = A out; B in;  C in
                       1 0 0 1  1 0 0 1 = $99 = A in;  B out; C in
                       1 0 0 1  0 0 1 0 = $92 = A in;  B in;  C out }
VAR
  AdresseCtrl    : WORD;
  ValeurControle : BYTE;
BEGIN
  AdresseCtrl := AdresseBase + 3;
  CASE PortSortie OF
    'a', 'A' : BEGIN
                 ValeurControle := $83;
                 OutPortB(AdresseCtrl, ValeurControle);
               END; {BRANCH OF CASE}
    'b', 'B' : BEGIN
                 ValeurControle := $99;
                 OutPortB(AdresseCtrl, ValeurControle);
               END; {BRANCH OF CASE}
    'c', 'C' : BEGIN
                 ValeurControle := $92;
                 OutPortB(AdresseCtrl, ValeurControle);
               END; {BRANCH OF CASE}
  END; {CASE OF}
END; {PROCEDURE ConfigurePorts}
 
 
PROCEDURE Teste(Adresse: WORD; PortSortie: CHAR);
{ BUT .......... : Effectue une boucle d'écriture sur le port choisi
  PARAMETRES
    Entrée ..... : Adresse = L'adresse de base du PPI
                   PortSortie = Le port Econfigurer en sortie
    Sortie ..... : --
  EFFETS DE BORD : Ecriture de valeurs sur le port choisi
  REMARQUES .... : --                                                       }
CONST
  valeur : ARRAY [1..8] OF BYTE = ($7F, $BF, $DF, $EF, $F7, $FB, $FD, $FE);
VAR
  AdressePort: WORD;
  StopTest   : BOOLEAN;
  Delai      : INTEGER;
  NoValeur   : BYTE;
  Ch         : CHAR;
 
PROCEDURE AfficheEtat(Pause:INTEGER);
{ BUT: Affiche la configuration actuelle }
BEGIN
  { Affiche infos}
  WriteLn;
  TextColor (LightGray);
  Write ('TEST EN COURS SUR LE PORT: ');
  TextColor (Yellow);
  WriteLn (PortSortie);
  TextColor (LightGray);
  Write ('ADRESSE DE BASE: ');
  TextColor (Yellow);
  Write (Adresse, ' ');
  TextColor (LightGray);
  Write ('(');
  TextColor (Yellow);
  Write (ParamStr(1));
  TextColor (LightGray);
  WriteLn (')');
  WriteLn;
  TextColor (LightCyan);
  Write ('[ESC]');
  TextColor (LightGray);
  WriteLn (' => Arrête le test');
  TextColor (LightCyan);
  Write ('[+]');
  TextColor (LightGray);
  WriteLn (' => Augmente le temps d''arrêt entre chaque changement d''état');
  TextColor (LightCyan);
  Write ('[-]');
  TextColor (LightGray);
  WriteLn (' => Diminue le temps d''arrêt entre chaque changement d''état');
  WriteLn;
  TextColor (LightGray);
  Write ('Pause entre chaque changement d''état: ');
  TextColor (Yellow);
  Write (Pause);
  TextColor (LightGray);
  WriteLn (' [ms].');
END; {PROCEDURE AfficheEtat}
 
 
BEGIN {PROCEDURE Teste}
  { Choix de l'adresse de sortie }
  CASE PortSortie OF
    'a', 'A' : AdressePort := Adresse + 0;
    'b', 'B' : AdressePort := Adresse + 1;
    'c', 'C' : AdressePort := Adresse + 2;
  END; {CASE OF}
  { Initialisation }
  Delai := 0;
  StopTest := FALSE;
  NoValeur := 0;
  AfficheEtat(Delai);
  { Et on teste... }
  REPEAT
    {-- Ecrit la valeur sur le port }
    OutPortB(AdressePort, valeur[NoValeur]);
    {-- Valeur suivante }
    Inc(NoValeur);
    IF NoValeur > 8 THEN NoValeur := 1;
    {-- Pour sortir une fois de la boucle }
    IF Keyboard.FasterKeyPressed THEN BEGIN
      WHILE KeyPressed DO Ch := ReadKey;
      CASE Ch OF
        #27 : StopTest := TRUE; { ESC Arrête le test }
        '+' : BEGIN
                IF Delai <= 3000 THEN Inc(Delai);
                AfficheEtat(Delai);
              END; {BRANCH OF CASE}
        '-' : BEGIN
                IF Delai >= 1 THEN Dec(Delai);
                AfficheEtat(Delai);
              END; {BRANCH OF CASE}
      END; {CASE OF}
    END; {IF}
    IF Delai > 0 THEN Delay(Delai);
  UNTIL StopTest;
 
END; {PROCEDURE Teste}
 
 
BEGIN {PROGRAM CHRONO}
  {Test si les param?tre sont corrects}
  IF ParamCount = 2 THEN BEGIN
    {------------------------------------------------------ ADRESSE DE BASE }
    Val(ParamStr(1), AdresseBase, Erreur);
    IF Erreur <> 0 THEN BEGIN
      AfficheSyntaxe(FALSE);
      AffichePlageAdresses(TRUE);
      Exit;
    END; {IF}
    IF (AdresseBase < $300) OR (Adressebase > $31F) THEN BEGIN
      AffichePlageAdresses(TRUE);
      Exit;
    END; {IF}
    {------------------------------------------------------- PORT DE SORTIE }
    Parametre := ParamStr(2);
    LePort := Parametre[1];
    IF NOT ((LePort = 'A') OR (LePort = 'B') OR (LePort = 'C') OR
            (LePort = 'a') OR (LePort = 'b') OR (LePort = 'c')) THEN BEGIN
      AfficheSyntaxe(FALSE);
      Exit;
    END; {IF}
    ConfigurePorts(AdresseBase, LePort);
    {----------------------------------------------------------------- TEST }
    Teste(AdresseBase, LePort);
  END {IF}
  ELSE BEGIN
    AfficheSyntaxe(TRUE);
  END; {BEGIN}
END. {PROGRAM CHRONO}