LA PROGRAMMATION DU PIC (8259)

              ***********************************************
              * ecrit par PC-CODER pour PROGRAZINE le 09/97 *
              * E-mail :  pccoder@club-internet.fr          *
              ***********************************************
               Si vous avez des informations suplementaire
               ou si vous constater une erreur ecriver moi 
               --------------------------------------------

Le PIC (Programmable Interrupt Controller)permet de gérer et
d'avertir le CPU d'une interruption (IRQ) provenant
d'un péripherique (c'est donc une interruption HARDWARE).
Une interruption sert à signaler au CPU qu'il doit interompre
le programme en cours pour executer un gestionnaire d'
interruption(c'est autre programme) pour s'occuper du
périphérique concerné.
Le CPU ne peut pas exécuter plusieurs interruption en même
temps ,c'est pourquoi chaque interruption (appelé IRQ )
possede un niveau de priorité .
Le PC dispose de 2 PIC relié en cascade et situés aux ports :

20H et 21H pour le PIC1 (C'est le MAÎTRE)
A0H et A1H pour le PIC2 (C'est l'ESCLAVE)

Voici un tableau avec la description de toute les IRQ :

----------------------------------------------------------------+
    | PIC1 | PIC2  | N°d'| ADR |                   | PORT       |
IRQ |MAITRE|ESCLAVE|INTER| GEST|   DESCRIPTION     |            |
----+------+-------+-----+-----+-------------------+------------+
  0 | IRQ0 |  ---  | 08H | 20H |  TIMER (8254)     | 40H à 43H  |
----+------+-------+-----+-----+-------------------+------------+
  1 | IRQ1 |  ---  | 09H | 24H |  CLAVIER (8042)   | 60H - 64H  |
----+------+-------+-----+-----+-------------------+------------+
  2 | IRQ2 |CASCADE| 0AH | 28H |PIC relié en cascad| A0H - A1H  |
----+------+-------+-----+-----+-------------------+------------+
----+------+-------+-----+-----+-------------------+------------+
  3 | ---- |  IRQ0 | 70H | 1C0H| RTC  (MC146814)   |  70H - 71H |
----+------+-------+-----+-----+-------------------+------------+
  4 | ---- |  IRQ1 | 71H | 1C4H| LIBRE (carte SON) |            |
----+------+-------+-----+-----+-------------------+------------+
  5 | ---- |  IRQ2 | 72H | 1C8H| LIBRE             |            |
----+------+-------+-----+-----+-------------------+------------+
  6 | ---- |  IRQ3 | 73H | 1CCH| LIBRE             |            |
----+------+-------+-----+-----+-------------------+------------+
  7 | ---- |  IRQ4 | 74H | 1D0H| LIBRE             |            |
----+------+-------+-----+-----+-------------------+------------+
  8 | ---- |  IRQ5 | 75H | 1D4H| COPRO-ARITHMETIC  |  F0H à FFH |
----+------+-------+-----+-----+-------------------+------------+
  9 | ---- |  IRQ6 | 76H | 1D8H|  IDE - PCI ++     |170Hà1FFH ++|
----+------+-------+-----+-----+-------------------+------------+
 10 | ---- |  IRQ7 | 77H | 1DCH|  IDE - PCI ++     |170Hà1FFH ++|
----+------+-------+-----+-----+-------------------+------------+
----+------+-------+-----+-----+-------------------+------------+
 11 | IRQ3 |  ---  | 0BH | 2CH | COM 2 (UART16550) | 2F8H à 2FFH|
----+------+-------+-----+-----+-------------------+------------+
 12 | IRQ4 |  ---  | 0CH | 30H | COM 1 (UART16550) | 3F8H à 3FFH|
----+------+-------+-----+-----+-------------------+------------+
 13 | IRQ5 |  ---  | 0DH | 34H |CARTE SON(ou LPT2) | 220H à 230H|
----+------+-------+-----+-----+-------------------+------------+
 14 | IRQ6 |  ---  | 0EH | 38H |LECTEUR DE DIQUETTE| 3F2H à 3F5H|
----+------+-------+-----+-----+-------------------+------------+
 15 | IRQ7 |  ---  | 0FH | 3CH | LPT 1(=imprimante)| 378H à 37FH|
----+------+-------+-----+-----+-------------------+------------+

Remarque : Pour LPT1,IDE-PCI et CARTE SON ,il existe d'autre port .
Pour les IRQ libre ,il est possible aussi qu'il l'interruption de
retour de balayage vertical (Si vous l'avez configurer dans votre
bios) ou l'interruption d'un modem interne .

La premiere colone indique le niveau de priorité(pour les 2 PIC)
IRQ0 est la priorité la plus forte
IRQ15 est la priorité la plus faible
Si 2 interruption arrive en même temps c'est la plus fort qui sera
pris en compte en premier.
Une interrution en cours ne peut pas être interrompue par une 
interruption  de priorité plus faible qu'elle ,mais elle peut
trés bien être intérrompue par une intérruption de priorité
plus elevé qu'elle (à moins qu'on interdise les interruptions
pendant l'interruption en cours)

Les 2 suivantes indique la priorité par raport au PIC concerné.

La 4éme indique le numero de l'interruption par rapport aux
 255 interruption .

La 5éme est l'adresse du vecteur d'interruption (ou est
 indiqué l'adresse du gestionnaire d'interruption .)

DESCRIPTION DES REGISTRES INTERNE :
 
Le PIC dispose de 3 registres internes pour gerer les
interruptions :

Le registre IRR (Interrupt Request Register):
Ce registre est relié directement au ligne d'interruption
exterieur IR (periphérique).Quand un peripherique demande 
une interruption le bit correspondant est mis directement
à 1 dans IRR.(à condition que le bit correspondant ne soit
pas un 1 dans le registre IMR)
Ce registre indique qu'elle interruption sont en attente .
(L'interruption de plus haute priorité est mis à 0 quand
le CPU la traite)

Le registre ISR (In Service Register) :
Ce registre indique les interruptions en cours.

Le registre IMR (Interrupt Mask Register) :
Ce registre permet d'interdire certaines interruption ,
en mettant le bit de l'interruption correspondante à 1.

DESCRIPTION DES COMMANDES :

Il existe 2 types de commande pour programmer le PIC :

Tout d'abord ,il y a les commandes ICW ( Initialization
Command Word ) qui servent à initialiser le PIC .

Puis ,il y a les commande OCW ( Output Command Word )qui
servent à controler le PIC .

Voici ou ce situe les commandes :

PIC2   PIC1
A0H ou 20H  -W  : ICW1 ou OCW2 ou OCW3
A0H ou 20H  R-  : ISR ou IRR imediatement apres OCW3
A1H ou 21H  -W  : ICW2,ICW3,ICW4 imediatement apres ICW1
A1H ou 21H  RW  : OCW1 (=IMR)

LES COMMANDES ICW :
Pour l'initialisation ,il faut envoyer toute ces commandes
dans l'ordre et les une imediatement à la suite des autre :
(Elle sont dépendante les unes des autres)

 ICW1 , ICW2 , ICW3 (facultatif) ,ICW4 (facultatif)
--------------------------------------------------------------------

ICW1 :  doit être envoyer sur le port 20H (A0H)

      b7   b6   b5   b4   b3   b2   b1   b0
    +----+----+----+----+----+----+----+----+
-/W |  0 |  0 |  0 |  1 |  M |  1 |  C | I4 |  20H (A0H)
    +----+----+----+----+----+----+----+----+

Bit 7-5 = 000  Reservé (pour 8080/8085)

Bit 4 = 1  Indique que c'est ICW1

Bit 3 = 0 Mode attaque(par defaut)
      = 1 Mode palier 

Bit 2 = 0 mode 8080/8085 (vecteur interruption 8 byte ) 
      = 1 mode 8086+ (vecteur d'interruption 4 byte)

Bit 1 = 0 indique PIC en cascade (alors ecrire ICW3)
        1 indique 1 seul PIC (Ne pas ecrire ICW3)

Bit 0 = 0 Ne pas ecrire ICW4
      = 1 Ecrire ICW4

--------------------------------------------------------------------

ICW2 :  Cete commande doit être envoyer tout de suite apres
        ICW1 sur le port 21H (A1H)

Bit 7-0 = N° d'interruption de base pour IRQ0 

Par Défaut 08H pour 21H et 70H pour A1H

Cela indique l'adresse de debut la table des vecteur
(gestionnaire)d'interruption (= 4* N° d'interruption).

--------------------------------------------------------------------

ICW3 pour le maitre:  Cete commande doit être envoyer tout
                      de suite apres ICW2 sur le port 21H,

Bit 7 = 0 IR7 est relié au materiel.
        1 IR7 est relié à l'esclave (pic en cascade)
Bit 6 = 0 IR6 est relié au materiel
        1 IR6 est relié à l'esclave
...
...
Bit 0 = 0 IR0 est relié au materiel
      = 1 IR0 est relié à l'esclave (pic en cascade)

SUR PC, 21H = 04H (TOUJOURS)

ICW3 pour l'esclave:  Cete commande doit être envoyer tout
                      de suite apres ICW2 sur le port A1H.
                     
Pour l'esclave ce registre fonctionne differement:

Bit 7-3 = 0 inutilisé

Bit 2-0 = Numero(binaire) de la ligne d'interreption
par lequel l'esclave est relié au maitre.

SUR PC, A1H = 02H  (TOUJOURS)
--------------------------------------------------------------------

ICW4 :  Cete commande doit être envoyer tout de suite apres
        ICW3 (ou ICW2) sur le port 21H (A1H)uniquement si
        le bit 0 de ICW1 =1.

Bit 7-5 = 0  RESERVE 

Bit  4 =  1 running in special fully-nested mode (?)
          0 sequentielle  (?)

Bit 3-2 = 0x nonbuffered mode (?)
          10 buffered mode/slave (?)
          11 buffered mode/master (?)

Bit  1 = 0 interruption terminer manuellement (EOI)(par defaut)
           C'est à dire qu'à la fin du gestionnaire ,il faut
           envoyer OCW2 pour indiquer sa fin.
         1 interruption terminer automatiquement (EOI)
                   EOI = End Of Interrupt
            Cela veut dire qu'il ne faut pas envoyer OCW2
            à la fin d'un gestionnaire.

Bit  0 = 0 pic fonctionne avec 8080/8085
         1 pic fonctionne avec 8086+

Sur PC ,par defaut ICW4=01H
--------------------------------------------------------------------
LES COMMANDES OCW :
C'est commande peuvent être envoyer dans n'importe qu'elle ordre
et indépendante les unes des autres .

OCW1 : = IMR (R/W sur le port 21H ou A1H).

Ce registre peut être lu ou ecrit directement par
l'intermediaire du port 21H ou A1H .
Chaque bit correspond à une interruption (voir tableau):

Bit 7 = 0 Autorise les interruptions pour IRQ7
      = 1 Interdie les interruption pour IRQ7

Bit 6 = 0 Autorise les interruptions pour IRQ6
      = 1 Interdie les interruption pour IRQ6
...
...

Bit 0 = 0 Autorise les interruptions pour IRQ0
      = 1 Interdie les interruption pour IRQ0
--------------------------------------------------------------------

OCW2: Ce registre est utilisé pour indiquer la fin
      d'un gestionnaire d'interruption.Cete commande
      est envoyer sur le port 20H (A0H).

Bit 7-5 = 010 Reserve
          000 Déactive la rotation des priorité en mode
              EOI automatique.
          100 Active la rotation des priorité en mode
              EOI automatique.
          001 EOI non specifié. Commande EOI par defaut
          011 Commande EOI particuliere.
          110 Définie la priorité.
          101 Rotation des priorité en mode EOI non specifié.
          111 Rotation des priorité en mode EOI specifié.

Bit 4-3 = 00 Indique que c'est OCW2.

Bit 2-0 = numero d'interruption pour 110 (definie la priorité),
          111 et 011
--------------------------------------------------------------------

OCW3: Ce registre est utilisé pour Selectionner ISR/IRR .
      Cete commande est envoyé sur la port 20H (A0H).

Bit  7 = 0 Réservé

Bit 6-5 = 0x Pas operation      (Par defaut)
        = 10 Reset special mask (??)
        = 11 Set special mask mode (??)
Le mode special mask permet à n'inporte qu'elle interruption
(quelle que soit son niveau)d'être executer pendant qu'une
autre interruption est deja en cours..(??)

Bit 4-3 = 01 Indique que c'est OCW3

Bit  2 = 0 Pas de mode polling (=interruption) Par defaut
       = 1 Mode polling   (= pas d'interruption)

En mode polling le CPU n'est plus avertie des interruption ,
il doit alors demander au PIC(à intervalle regulier) si il 
y a une interruption .(pas utiliser sur PC)

Bit 1-0 = 0x Reserve
        = 10 Select IRR (il faut lire le port 20H(A0H)
                         immediatement aprés)
        = 11 Select ISR (il faut lire le port 20H(A0H)
                         imediatement aprés)

--------------------------------------------------------------------
REMARQUE : IL SEMBLE APRES EXPERIMENTATION QUE CERTAIN BIT(CEUX EN BLEU)
           NE SERVENT PLUS A RIEN , IL ETAIT UTILISE PAR LES VIEUX PC .
Pour ecrire un gestionnaire d'interruption ,il est important de
sauvegarder les registres utilisé par le gestionnaire au debut de
celui-ci et de les restitués à la fin du gestionnaire .