< Gérer les interruptions - la mise en oeuvre | TutoOS | Créer et exécuter une tâche >
Gérer les interruptions du clavier
Sources
Le package contenant les sources : kernel_ManageKBD.tgz
Pour naviguer dans l'arborescence : ManageKBD
Le chipset 8042
Le clavier contient un micro-contrôleur chargé de gérer les différents évènements (pression, relachement des touches et affichages lumineux) : le 8042.
Les ports d'entrée/sortie utilisés pour communiquer avec ce chipset sont les suivants :
60h
pour la lecture ou la transmission de données
64h
pour connaître le statut ou émettre des commandes
Quand une touche est pressée ou relachée, le contrôleur écrit dans son registre de données un code appelé scan code.
Le contenu de ce registre est accessible via le port 60h
:
La routine suivante attend que le buffer de sortie du 8042 soit plein puis stocke le contenu de celui-ci :
do {
i = inb(0x64);
} while((i & 0x01) == 0);
i = inb(0x60);
Il existe deux types de scan code :
- la pression d'une touche génère un make code
- le relachement d'une touche génère un break code (break_code = make_code +
0x80
)
La routine d'interruption complète pour la gestion des interruptions du clavier :
isr_kbd_int()
#include "types.h"
#include "screen.h"
#include "io.h"
#include "kbd.h"
void isr_default_int(void)
{
print("interrupt\n");
}
void isr_clock_int(void)
{
static int tic = 0;
static int sec = 0;
tic++;
if (tic % 100 == 0) {
sec++;
tic = 0;
}
}
void isr_kbd_int(void)
{
uchar i;
static int lshift_enable;
static int rshift_enable;
static int alt_enable;
static int ctrl_enable;
do {
i = inb(0x64);
} while ((i & 0x01) == 0);
i = inb(0x60);
i--;
//// putcar('\n'); dump(&i, 1); putcar(' ');
if (i < 0x80) { /* touche enfoncee */
switch (i) {
case 0x29:
lshift_enable = 1;
break;
case 0x35:
rshift_enable = 1;
break;
case 0x1C:
ctrl_enable = 1;
break;
case 0x37:
alt_enable = 1;
break;
default:
putcar(kbdmap
[i * 4 + (lshift_enable || rshift_enable)]);
}
} else { /* touche relachee */
i -= 0x80;
switch (i) {
case 0x29:
lshift_enable = 0;
break;
case 0x35:
rshift_enable = 0;
break;
case 0x1C:
ctrl_enable = 0;
break;
case 0x37:
alt_enable = 0;
break;
}
}
show_cursor();
}
La gestion du curseur
Le curseur est géré en s'adressant directement au contrôleur VGA via le port 0x3d4
(contrôle) et le port 0x3d5
(données). La routine qui affiche le curseur à l'écran est très simple :
void move_cursor (u8 x, u8 y)
{
u16 c_pos;
c_pos = y * 80 + x;
outb(0x3d4, 0x0f);
outb(0x3d5, (u8) c_pos);
outb(0x3d4, 0x0e);
outb(0x3d5, (u8) (c_pos >> 8));
}
void show_cursor (void)
{
move_cursor(kX, kY);
}
< Gérer les interruptions - la mise en oeuvre | TutoOS | Créer et exécuter une tâche >