Lecture du scancode [tasm, port 60h, détournement d'int]

Soyez le premier à donner votre avis sur cette source.

Vue 6 536 fois - Téléchargée 317 fois

Description

En fichier EXE du MS-DOS
pour compiler : TASM nomdufichier
pour linker : TLINK nomdufichier

Le scancode est le code qu'envoie le clavier lors d'un changement d'état d'une de ses touches.

Source / Exemple :


.386
code	segment	use16
assume	cs:code,ds:code
prog:
	mov	ax,cs
	mov	ds,ax
	mov	ax,0B800h		;Pointe sur la mémoire vidéo du mode texte pour affichage de caractère
	mov	es,ax
	xor	ax,ax
	mov	gs,ax
	mov     eax, gs:[09h*4]
        mov     oldirq1, eax		;sauvegarde de l'IRQ1 lié à l'INT 09h (sinon PANIC)
        mov     ax, cs
        shl     eax, 16
        mov     ax, offset irq1
        mov     gs:[09h*4], eax		;place celle du code présent
boucle:
	xor	di,di
	mov	si,offset map
	mov	cx,256
actualiser:
	movsb
	inc	di
	loop	actualiser
	cmp	codefin,81h		;Dès que la touche ESC est relâcher on quitte
	jnz	boucle
fin:
	mov     eax, oldirq1		;restauration de l'Int 09h (sinon PANIC)
        mov     gs:[09h*4], eax
	mov	ah,4Ch
	int	21h			;Code de fin
irq1:
	pushad
	xor	ax,ax
	in	al,60h			;Lecture du Scancode
	mov	bx,ax
	cmp	ax,81h			;Test de la touche Esc relâchée
	jz	_esc
	jge	break
	mov	ds:[map+bx],'1'
	mov	ds:[map+0E0h],'.'
	mov	ds:[map+0E1h],'.'
	jmp	irqfin
_esc:
	mov	codefin,al
	jmp	irqfin
break:
	cmp	al,0E0h			;Teste si le code E0h est présent pour les touches étendues
	jz	.e0
	cmp	al,0E1h			;Teste si le code E1h est présent (seul la touche Pause l'utilise)
	jz	.e0
	and	bx,7Fh
	mov	ds:[map+bx],'.'
	jmp	irqfin
.e0:
	mov	ds:[map+bx],'X'
irqfin:
	mov	al,20h
	out	20h,al			;End Of Interrupt
	popad
	iret				;Comme ret sauf pour interruption
oldirq1	dd	?			;sauvegarde de l'ancienne adresse de l'IRQ1 (irq du clavier)
map	db 256 dup('.')			;Carte du scancode
codefin	db 0				;test du code 81h c'est le BreakCode de la touche Echap qui permettra de quitter le programme
code	ends
end	prog

Conclusion :


Ce code peut être optimisé en utilisant un bit par touche sur la carte du scancode au lieu d'un octet, on peut ainsi réduire la taille. On peut ne pas utiliser l'interruption du clavier mais c'est moins bien et un test est nécessaire avant la lecture du scancode c'est le bit 0 sur le port 64h. Il est peut-être plus facile d'utiliser les fonctions de l'INT 16h mais seulement en 16bits!

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
1243
Date d'inscription
jeudi 31 mars 2005
Statut
Membre
Dernière intervention
3 août 2016
2
mikevador02 pour trouver l'int correspondant à une IRQ tu doit faire :

pour le 1er 8259 , numero d'IRQ + 8h : exemple IRQ6 (la disquette) 6h + 8h = 0Eh
pour le 2ième 8259 , numero d'IRQ + 70h : exemple IRQ14 (disk principal) 14h + 70h = 76h


Le 8259 est un controleur d'interruption.
Messages postés
65
Date d'inscription
vendredi 14 février 2003
Statut
Membre
Dernière intervention
11 septembre 2004

Bonjour et plop a vous :-)
En ce moment, je me suis lancé dans un projet delirant : ecrire un OS (tout petit :-) ).
J'ai une fonction print qui prend en argument un char* et deux int (position du texte a l'ecran).
Dans la foulée, je me suis dit qu'utilisé le clavier pourrait etre une bonne idée a l'utilisateur de mon Kernel (donc moi en gros :-) ).
Alors j'ai reussi a faire une macro en ASM qui ecoute sur le port 0x60 (clavier) et je detourne ce qu'elle raconte pour le faire afficher par la fonctione print.
Bon, premier resultat : le PC reagit quand j'appuis sur une touche (ca c'est bon !)
Deuxieme resultat : le PC n'affiche pas du tout ce que je tape au clavier, mais affiche des choses assez bizard....
Donc je recherche le moyen de convertir le code que je choppe (qui n'est pas beau du tout, je pense à de l'hexa, mais rien n'est moins sur) en joli charactere ascii pour le mettre dans un joli tableau et que ca fasse quelque chose de beau a l'ecran.
si quelqu'un a le courage de me repondre :-)
ZiNoTrOn
PS: j'ecrit en C mais la macro est bien en ASM
Messages postés
69
Date d'inscription
samedi 28 octobre 2000
Statut
Membre
Dernière intervention
15 octobre 2004

les interruptions sont géré par les 2 PIC du PC branché en cascade qui fait la correspondance IRQ-INT. En mode réel il existe effectivement une table de vecteur d'interruption que l'on appelle IVT (Interrupt Vector Table) chaque entrée correspond a une adresse FAR donc 4 octets, il y a 256 int donc la taille de la table est de 4*256= 1024 octets et elle commence à l'adresse 0000:0000 c'est d'ailleurs le pourquoi j'avais gs=0 et un offset = 09h*4 pour détourner l'int 09h
Oui bien sur que faire reset ça remet l'ancienne table, car cette table se situe dans la RAM
Messages postés
5
Date d'inscription
mercredi 15 janvier 2003
Statut
Membre
Dernière intervention
16 janvier 2003

Merci pour la reponse SCSI (rapide) :)
ha ok mais donc en fait chaques irq de base pointe sur une interuption alors? ex sir irq2 est attribuer au port com1 et qu'une donnee arrive dessus irq2 possède alors aussi une interuption? y a t-il des tables pour ceux-ci alors? j'ai celle de toute les interuptions.
Et donc qd on reset un pc c'est de nouveau l'ancienne table qui revient je suppose? Je suis debutant en asm
Messages postés
69
Date d'inscription
samedi 28 octobre 2000
Statut
Membre
Dernière intervention
15 octobre 2004

bon c'est irq1 pas IRQL mais c'est tout à fait comme ça que ça fonctionne!!
Afficher les 6 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.