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

Assembleur Intel avec NASM en mode protégé


précédentsommairesuivant

I. Un contrôleur clavier

68 commentaires Donner une note à l´article (5)

Relu par ClaudeLELOUP.

Il n'y a pas à dire, le mode protégé, c'est violent. Au chapitre précédent, on a retrouvé les interruptions. Lesquelles malheureusement sont vides. Retrouver l'entrée clavier, ce ne serait pas mal.

I-1. Que se passe-t-il lors de l'appui sur une touche ?

Lors de l'appui sur une touche, le PIC déclenche l'interruption à laquelle est branchée l'IRQ1. Doit s'ensuivre une discussion protocolaire avec le processeur afin de transmettre au processeur les connaissances du PIC.

I-2. Comment ça se passe ?

Pour faire ça convenablement, nous allons écrire l'interruption déclenchée par l'IRQ1. Pour écrire une interruption, on ne se soucie pas du contexte, il est sauvegardé par l'instruction INT. On va commencer par interdire les interruptions : cli. Ensuite, on demande au PIC s'il est disponible pour un échange fructueux :

 
Sélectionnez
	.attendBuffer:
		in		al,		0x64	; lire statut
		test	byte al,1		; bus de sortie prêt ?
		jz		.attendBuffer	; non => boucler

Ce qui signifie qu'on attend sagement qu'il y ait un octet avec le bit de poids faible à 1 sur le port 0x64, signifiant qu'il y a une entrée clavier à lire. Une fois qu'on est sûr qu'il y a une touche à traiter, on peut magnanimement en prendre connaissance :

 
Sélectionnez
		in		al, 	0x60	;Lit la touche pressée
		cmp		al, 	224		;224 est un code spécial, ça veut dire qu'il y a autre chose derrière, mais pour l'instant on s'en fiche
		je		.attendBuffer	;On va donc lire la suite

Le caractère se trouve sur un autre port, le port 0x60. Ensuite, le traitement commence, et pour cela, il nous faut un peu d'histoire. Le circuit qui gère le clavier n'est pas tout jeune. Il est standard, éprouvé, et vient de gens dont la principale motivation n'était pas le rendu typographique. De base, le clavier envoyait un octet qui donnait à la fois la touche concernée et son état : pressée ou relâchée. Cela fait deux codes par touche, sur un octet. On peut donc avoir 128 touches différentes. Il faut aussi savoir qu'au niveau où nous sommes, on parle de touche et non de caractère : la touche 23 a été relâchée, que celle-ci soit un 'A', un 'é' ou F4. Il a été remarqué que ce 128 pouvait être une limite un peu basse. Le code de touche a été étendu - voilà pourquoi on peut encore entendre qu'un ordinateur actuel possède un clavier étendu - sur deux octets. Pour marquer l'utilisation de code étendu, le premier octet prend des valeurs spéciales, dont 224, celle testée ici. Les codes clavier étendu ont été si bien faits que quand on ne prend pas en compte le mode étendu, le code signifie quand même quelque chose, caractéristique que nous mettons à profit ici en "oubliant" le code 224.

Pour la suite, j'ai un peu joué quand même. Après tout, on a bien le droit de se faire plaisir. Je me suis dit que j'allais stocker une carte de toutes les touches appuyées. Comme ça, si vous voulez savoir à n'importe quel moment si une touche est appuyée, un coup d'œil sur cette carte et vous saurez si Shift ou Ctrl sont pressées. Mais si vous voulez faire "A + 3 + ,", c'est aussi possible. Pour ce faire, on a besoin de stocker 128 bits, un bit (pressée : oui ou non) par touche gérée par ce qu'il faut bien appeler un gestionnaire de clavier. 128 bits, c'est 16 octets: touchesActives: dd 0, 0, 0, 0. La prochaine étape consiste donc à mettre le bit de la touche traitée à la valeur convenable. Première étape, trouver l'octet concerné dans la table :

 
Sélectionnez
		mov bl, al
		shr bl, 3; On divise le code par 8 pour savoir dans quel octet il se situe
		push eax	; On sauve le caractère dans la pile
		mov cl, 8
		div cl		; On le divise par 8
		mov cl, ah	; Pour une division par 8 bits, le reste est dans AH
		pop eax
		mov edx, 1
		shl dl, cl
		add ebx, touchesActives ;C'est l'adresse de l'octet contenant ce qui nous intéresse
		cmp		al,		128		;Les touches appuyées ont un code inférieur à 128, les touches relâchées, c'est le même code qu'appuyées plus 128
		jb		.stockeActif
		sub		al,		128
		sub		ebx,	128/8
		not dl
		and byte[ebx], dl
		jmp .suite
	.stockeActif:
		or byte[ebx], dl	; Un OU met le bit à 1, un NOT AND le mettra à 0
		mov [derniereTouche], al

À noter dans ce morceau de code : l'utilisation de la position du reste d'une division en fonction de la taille des opérandes, chose à laquelle il faut toujours faire attention. SHL et sa copine SHR ne peuvent décaler que d'un nombre constant ou du contenu du registre C. La différence de traitement entre touche pressée/touche relâchée est faite en un seul endroit, ce qui donne un code un peu contre-intuitif (pourquoi cette soustraction de 128/8 sur ebx ?). Notez l'utilisation du AND pour mettre des bits à 0 et du OR pour les mettre à 1. On termine, en cas de touche pressée, par la stocker en mémoire, afin que d'autres sous-programmes puissent y accéder. C'est grossier, vu qu'on stocke aussi les modificateurs, et je suis quasiment certain qu'un bon gestionnaire de clavier utilise un buffer circulaire.

Il reste à accuser réception, remettre les interruptions en place et quitter (ici, en appelant l'interruption PIC qui ne fait rien) :

 
Sélectionnez
	.suite:
		in 		al, 	0x61
		or		al, 	130
		out 	0x61, 	al		;Dit à l'ordi qu'une touche a été pressée

		and 	al,		127
		out 	0x61,	al		;Reinitialisation terminée
	 
		sti
		jmp 	interruptionPICMaitreParDefaut

I-3. Convertir en caractères

Car, suite à l'étape précédente, nous avons bien la dernière touche tapée, mais nous n'avons aucune idée du caractère auquel elle correspond. Nous allons avoir besoin d'une table de conversion qui fera la correspondance entre numéro de touche et caractère sérigraphié sur la touche. Voici cette table :

 
Sélectionnez
traductionASCII: db '.','.','1','2','3','4','5','6','7','8','9','0','.','+','.','.','a','z','e','r','t','y','u','i','o','p','^','$',13,'.','q','s','d','f','g','h','j','k','l','m','%','.','.','*','w','x','c','v','b','n',',',';',':','!';54 caractères gérés

La position du caractère dans cette table est son numéro de touche.

I-4. Lecture au clavier

Vous vous souvenez de la routine de lecture de caractères ? Oui, nous avons progressé, depuis, mais nous ne l'avons plus depuis le passage en mode protégé. Il faut la refaire.

L'idée est de commencer par vider le similitampon que nous avons dans la routine d'interruption. Ensuite, nous lirons le contenu de ce tampon. L'octet ainsi récupéré nous donne l'index à lire dans le tableau de conversion, et nous avons ainsi notre caractère.

 
Sélectionnez
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; litChaine														;;
	;;------------------------------------------------------------------;;
	;; Ecrit dans la chaîne pointée par EDI les caractères écrits au 	;;
	;; clavier, jusqu'à un retour chariot. 								;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	litChaine:
		push eax
		push ebx
		xor eax, eax
		mov byte [derniereTouche], 0
		mov esi, edi
	.attend_clavier:
		cmp byte [derniereTouche], 0
		jz .attend_clavier
		mov al, [derniereTouche]
		mov byte [derniereTouche], 0

		mov ebx, traductionASCII
		add ebx, eax
		mov al, [ebx]
		stosb
		cmp al, 13
		je .fin_attend_clavier
		mov al, 0
		stosb
		call afficheChaine
		dec edi
		dec esi
		jmp .attend_clavier
	.fin_attend_clavier:
		pop ebx
		pop eax
		ret
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; Fin litChaine													;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

I-5. Du code

L'ensemble du code se trouve ici : Paquet


précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2011 Etienne Sauvage. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.