Le programme suivant, écrit en Turbo Pascal 7, permet d'utiliser la souris PS/2 à partir du BIOS.
{Projet: Démonstrateur de souris PS/2
Date de rédaction: Lundi le 11 juin 2001
Nom du programmeur: Sylvain Maltais
Groupe: Gladir.com
Configuration requise: Souris avec port PS/2
Courriel: support@gladir.com
Site de distribution: http://www.gladir.com/
Description
ÍÍÍÍÍÍÍÍÍÍÍ
Cette programme est un démonstrateur de l'utilisation d'une souris
utilisant le port PS/2 sans utilisé de pilote d'INTERRUPTION 33h. Ce
programme déplace le pointeur de souris tant et aussi longtemps que
l'utilisateur n'a pas enfoncé un bouton de la souris.
Remarque
ÍÍÍÍÍÍÍÍ
þ On doit toujours lancée se programme dans un écran de texte!
}
Program MousePS2;
Const
{ Les masques d'évenements de la souris }
meMsMove=1; { Déplacement de la souris }
meLeftButPressed=2; { Le bouton de gauche enfoncé }
meLeftButReleased=4; { Le bouton de gauche relâché }
meRightButPressed=8; { Le bouton de droite enfoncé }
meRightButReleased=16; { Le bouton de droite relâché }
meMiddleButPressed=32; { Le bouton du centre enfoncé }
meMiddleButReleased=64; { Le bouton du centre enfoncé }
meAll=$7F; { Tous changements de la part de la souris (Déplacement, Bouton,...) }
Var
MouseTextX,MouseTextY:Byte; { Coordonnée actuel du pointeur de souris }
Button:Word; { Position des boutons de souris }
{ Cette routine permet d'installer la routine devant s'exécuter à
chaque déplacement de la souris.
}
Function InstallPS2(Routine:Pointer):Boolean;Assembler;ASM
MOV CX,2
@Try2:
LES BX,Routine
MOV AX,0C207h
INT 15h
JNC @PSokyet
CMP AH,4
JNE @noPS2det
LOOP @Try2
JMP @noPS2det
@PSokyet:
MOV BH,3
MOV AX,0C203h
INT 15h
JC @NoPS2det { Fixe la résolution Souris BH}
MOV BH,1
MOV AX,0C200h
INT 15h
JC @NoPS2det { Active la souris}
XOR DL,DL
XOR BH,BH
MOV AX,0C206h
INT 15h
MOV AL,True
JMP @End
@NoPS2det:
MOV AL,False
@End:
END;
{ Cette routine est lancée par notre «Handler» écrit en assembleur
«PS2Hand», ormis la directive «NEAR», vous pouvez modifier sans
danger le contenu de celui-ci. Même vous pourriez afficher directement
un pointeur de souris à partir de cette routine comme le font les pilotes
souris toutefois si vous pouvez l'évitez, comme dans cet exemple, je
vous le déconseil parce que la machine doit nécessairement est plus
rapide pour une programmation de se style.
}
Procedure MouEventHandler(EvFlags,ButState,X,Y:Integer);Near;Begin
If X<0Then X:=0;
If Y<0Then Y:=0;
If(EvFlags and meMsMove=meMsMove)Then Begin
ASM
{X:=X shr 3;}
{Y:=Y shr 4;}
MOV CL,3
SHR X,CL
INC CX
SHR Y,CL
END;
MouseTextX:=X;
MouseTextY:=Y;
End;
Button:=ButState; { Dernière état des boutons de la souris }
End;
{Variable sur le Code Segment:}
Procedure Actif;Assembler;ASM
DB 0 { Indique si un appel est actuellement en cours d'exécution}
END;
{ Etat des boutons souris }
Procedure ButtonFlags;Assembler;ASM
DW 0
END;
{ Position horizontal actuel de la souris en pixel }
Procedure XMov;Assembler;ASM
DW 0
END;
{ Position vertical actuel de la souris en pixel }
Procedure YMov;Assembler;ASM
DW 0
END;
{ Variable dans le segment de code contenant l'adresse du segment de donnée }
Procedure AdresseData;Assembler;ASM
DD MouseTextX {Indique l'adresse du Segment de donnée }
END;
{ Cette routine est exécutée à chaque déplacement de la souris, on
comprendra qu'il est indispensable de préservé chacun des registres
et cela en utilisant le code segment pour éviter des conflits.
}
Procedure PS2Hand;Far;Assembler;ASM
CLD
CMP Byte Ptr Actif,0 { Appel non encore terminé ? }
JNE @Fin { Non --> ne pas permettre l'appel }
MOV Byte Ptr Actif,1 { Ne plus autoriser d'appels }
PUSH BP
MOV BP,SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH DI
PUSH SI
PUSH CS
PUSH CS
POP DS
POP ES
MOV AX,[BP+0Ch]
TEST AH,AH
JNZ @InvPS2Data
AND AL,3
MOV Byte Ptr ButtonFlags,AL
MOV AX,[BP+0Ch]
MOV BX,[BP+0Ah]
MOV CX,[BP+8]
TEST AL,10h
JZ @PSxNeg
MOV BH,0FFh
@PSxNeg: TEST CX,CX
JZ @NoYMov
NEG CL
TEST AL,20h
JNZ @NoYMov
MOV CH,0FFh
@NoYMov: ADD Word Ptr YMov,CX
ADD Word Ptr XMov,BX
MOV AX,meMsMove
PUSH AX
PUSH Word Ptr ButtonFlags
PUSH Word Ptr XMov
PUSH Word Ptr YMov
MOV DS,Word Ptr AdresseData[2]
CALL MouEventHandler
@InvPS2Data:
POP SI
POP DI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
POP BP
MOV Byte Ptr Actif,0 { Appel à nouveau autorisé }
@Fin:
END;
{ Cette procédure très rudimentaire permet de changer un attribut de
couleur à un endroit précis de l'écran.
}
Procedure SetAttr(X,Y,Attr:Byte);Var Segment:Word;Begin
If MemW[Seg0040:$63]=$3D4Then Segment:=$B800
Else Segment:=$B000;
Mem[Segment:((X+(Y*MemW[Seg0040:$4A]))shl 1)+1]:=Attr;
End;
{ Cette fonction très rudimentaire permet de connaître un attribut de
couleur à un endroit précis de l'écran.
}
Function GetAttr(X,Y:Byte):Byte;Var Segment:Word;Begin
If MemW[Seg0040:$63]=$3D4Then Segment:=$B800
Else Segment:=$B000;
GetAttr:=Mem[Segment:((X+(Y*MemW[Seg0040:$4A]))shl 1)+1];
End;
Var
OldAttr:Byte; { Couleur de l'ancienne attribut }
OldX,OldY:Byte; { Ancienne position du pointeur de souris }
CurrX,CurrY:Byte; { Position actuel du pointeur souris }
BEGIN
If Not InstallPS2(@PS2Hand)Then Begin
WriteLn('Une souris avec port PS/2 est requise pour ce programme!');
End
Else
Begin
WriteLn('Presse un bouton de la souris pour quitter!');
OldX:=$FF;OldY:=$FF;
Repeat
CurrX:=MouseTextX;CurrY:=MouseTextY; { Copie la position actuel du pointeur souris }
If(OldX<>CurrX)or(OldY<>CurrY)Then Begin
{ Restauration d'affichage du pointeur de souris }
SetAttr(OldX,OldY,OldAttr);
{ Préservation de l'emplacement affecté }
OldAttr:=GetAttr(MouseTextX,MouseTextY);
{ Affiche le pointeur souris }
SetAttr(CurrX,CurrY,Not OldAttr);
{ Préserve les coordonnées où a été afficher le pointeur souris }
OldX:=CurrX;OldY:=CurrY;
End;
Until Button<>0;
{ Restauration d'affichage du pointeur de souris }
SetAttr(OldX,OldY,OldAttr);
{ Attendre que l'utilisateur lache le bouton de souris }
Repeat Until Button=0;
InstallPS2(NIL);
End;
END.
Dernière mise à jour : Dimanche, le 1 mai 2016