Accueil > QBasic > QBasic – Le langage machine et la souris

QBasic – Le langage machine et la souris

This entry is part 28 of 30 in the series QBasic - Tutoriel

Oubliez tout ceux qui vous ont dit que le QBasic était un langage limité. Non, le QBasic a bien
d’autres possibilités que celles qu’on lui connaît. Il peut, comme le Pascal par exemple, inclure
des portion de langage machine, peut-être plus connu sous le nom de langage d’assemblage. Simplement,
la mise en oeuvre est peut-être un peu plus compliquée en QBasic.

Pour vous démontrer tout ceci, nous allons créer pas à pas une routine cruellement manquante au
QBasic : le support de la souris. En effet, vous aurrez beau chercher partout dans le fichier
d’aide fourni avec QBasic, jamais vous ne trouverez une quelconque allusion à l’utilisation de
ce périphérique.

Certains vous rétorqueront que l’on peut faire appel à la fonction CALL INTERRUPT. Mais
cette fonction n’est présente que dans la version 4.5 de QBasic (appellée aussi Quick Basic).
Nous allons donc utiliser un cheminement qui peu paraître un peu plus compliqué au premier abord,
mais qui donne néanmoins le même résultat, et qui à le méritte de fonctionner sur n’importe quelle
version de QBasic, dès la 1.1.

Mais il vous faut tout de même connaitre quelques notions d’assembleur. Vous pouvez pour cela
vous reporter à la section correspondante sur ce même site.

Avant de découvrir les instructions elles même, nous allons détailler celles qui nous serviront
à écrire et à executer le sous-programme en langage machine que nous allons écrire.

Notre programme sera stocké directement en mémoire. Comme vous le savez si vous avez lu le chapitre
précédent, un emplacement de la mémoire est défini par un segment et un offset.

Vu que le sous programme sera stocké dans un tableau, les premières lignes vont de soit :


DIM Asm%(0) ‘ Tableau INTEGER (préfixe %)

SegAsm = VARSEG(Asm%(0)) ‘ Segement du tableau Asm%
OffAsm = VARPTR(Asm%(0)) ‘ OffSet du tableau Asm%
DEF SEG = SegAsm ‘ On va au segment du tableau Asm%


Ensuite, on va stocker notre passage en langage machine dans des DATA (comme pour les sprites),
c’est ce qu’il y a de plus pratique après un fichier indépendant.

Pour l’instant, on va se contenter d’afficher seulement le curseur de la souris. Il faut savoir
que pour l’afficher, il faut utiliser la fonction 0001h dans le registre AX, puis
l’interruption 33h (charabia ? pas si sûr…).

Le registre AX est en fait représenté par la valeur héxadécimale B8. Pour 0001h, on écrira
01, puis 00. Pour appeler une intérruption (INT en assembleur), on écrit le code héxadécimal
CD. Ensuite, pour 33h, on écrit bêtement 33.

Vu que se sont des valeurs hexadécimal, il faut rajouter &H devant chaque terme.

Notre programme dans les DATA donnera :

‘ Code pour afficher le curseur de la souris
DATA &HB8, &H01, &H00, &HCD, &H33, &HCB

Le &HCB, c’est pour terminer proprement le sous-programme. Ommétez le et les conséquences
seront terribles !

Pour stocker des octets en mémoire, on utilise l’instruction POKE. La syntaxe est :

POKE OffSet, Octet%

Donc, pour stocker notre sous-programme en mémoire, on écrira :

DIM Asm%(5) ‘ Tableau INTEGER (préfixe %)

SegAsm = VARSEG(Asm%(0)) ‘ Segement du tableau Asm%
OffAsm = VARPTR(Asm%(0)) ‘ OffSet du tableau Asm%
DEF SEG = SegAsm ‘ On va au segment du tableau Asm%
FOR i% = LBOUND(Asm%, 1) TO UBOUND(Asm%, 1)
READ Octet% ‘ INTEGER
POKE OffAsm + i%, Octet% ‘ On décale d’une position à chaque fois
NEXT i%

‘ Code pour afficher le curseur de la souris
DATA &HB8, &H01, &H00, &HCD, &H33, &HCB


N’oubliez pas de changer la dimension du tableau, à la première ligne. Maintenant, il faut qu’il
fasse 6 !

Ensuite, pour executer le programme, on va utiliser l’instruction CALL ABSOLUTE. La syntaxe
est :

CALL ABSOLUTE([Arg, ] OffSet)

Entre crochets, ce sont les arguments (en général, les valeurs renvoyées). Ici, il n’y en a pas,
donc :

DIM Asm%(5) ‘ Tableau INTEGER (préfixe %)

SegAsm = VARSEG(Asm%(0)) ‘ Segement du tableau Asm%
OffAsm = VARPTR(Asm%(0)) ‘ OffSet du tableau Asm%
DEF SEG = SegAsm ‘ On va au segment du tableau Asm%
FOR i% = LBOUND(Asm%, 1) TO UBOUND(Asm%, 1)
READ Octet% ‘ INTEGER
POKE OffAsm + i%, Octet% ‘ On décale d’une position à chaque fois
NEXT i%

CALL ABSOLUTE(OffSeg) ‘ Appel du sous-programme
DEF SEG ‘ NE PAS OUBLIER DEF SEG

DO
LOOP UNTIL INKEY$ <> «  » ‘ Petite boucle, pour voir ce qu’il se passe

‘ Code pour afficher le curseur de la souris
DATA &HB8, &H01, &H00, &HCD, &H33, &HCB


Saisissant, non ? Et attention, vous n’êtes pas encore au bout de vos surprises ! Ce n’était qu’une
simple démonstration des capactités de QBasic ce traiter le langage d’assemblage.

Maintenant que vous avez compris le fonctionnement de la gestion de la mémoire, je vais vous
donner le secret pour utiliser correctement la souris. On pourra, ainsi afficher le curseur ou le
faire disparaitre, connaitre les coordonnées X et Y, déplacer le curseur… Bref, l’indispensable.

Vu que le programme est totalement en assembleur, je ne vais pas le détailler, vu que le langage
traité dans cette rubrique est le Basic.

Voici le programme :

CONST TRUE = -1
CONST FALSE = 0

DIM SHARED SegAsm%
DIM SHARED OffAsm%
DIM Asm%(56)

SegAsm% = VARSEG(Asm%(0))
OffAsm% = VARPTR(Asm%(0))
DEF SEG = SegAsm%
FOR i% = LBOUND(Asm%, 1) TO UBOUND(Asm%, 1)
READ Octet%
POKE OffAsm% + i%, Octet%
NEXT i%
DEF SEG

‘ Langage machine pour la gestion de la souris
DATA &H55,&H89,&HE5,&H8B,&H5E,&H0C,&H8B,&H07,&H50,&H8B
DATA &H5E,&H0A,&H8B,&H07,&H50,&H8B,&H5E,&H08,&H8B,&H0F
DATA &H8B,&H5E,&H06,&H8B,&H17,&H5B,&H58,&H1E,&H07,&HCD
DATA &H33,&H53,&H8B,&H5E,&H0C,&H89,&H07,&H58,&H8B,&H5E
DATA &H0A,&H89,&H07,&H8B,&H5E,&H08,&H89,&H0F,&H8B,&H5E
DATA &H06,&H89,&H17,&H5D,&HCA,&H08,&H00

FUNCTION InitMouse()
‘—————————————–
‘| |
‘| Initialise la souris |
‘| + TRUE si une souris est détectée |
‘| + FALSE si aucune souris détectée |
‘| |
‘—————————————–
DEF SEG = SegAsm%
ax% = 0
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
IF ax% = 0 THEN InitMouse = FALSE ELSE InitMouse = TRUE
DEF SEG
END FUNCTION

FUNCTION GetMouseX()
‘—————————————–
‘| |
‘| Renvoi les coordonnées X de la souris |
‘| |
‘—————————————–
DEF SEG = SegAsm%
ax% = 3
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
GetMouseX = cx%
DEF SEG
END FUNCTION

FUNCTION GetMouseY()
‘—————————————–
‘| |
‘| Renvoi les coordonnées Y de la souris |
‘| |
‘—————————————–
DEF SEG = SegAsm%
ax% = 3
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
GetMouseY = dx%
DEF SEG
END FUNCTION

FUNCTION GetMouseLButton()
‘————————————————
‘| |
‘| Renvoi l’état du bouton gauche de la souris: |
‘| + TRUE si enfoncé |
‘| + FALSE si relaché |
‘| |
‘————————————————
DEF SEG = SegAsm%
ax% = 3
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
IF bx% = 1 OR bx% = 3 THEN GetMouseLButton = TRUE ELSE GetMouseLButton = FALSE
DEF SEG
END FUNCTION

FUNCTION GetMouseRButton()
‘———————————————–
‘| |
‘| Renvoi l’état du bouton droit de la souris: |
‘| + TRUE si enfoncé |
‘| + FALSE si relaché |
‘| |
‘———————————————–
DEF SEG = SegAsm%
ax% = 3
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
IF bx% = 2 OR bx% = 3 THEN GetMouseRButton = TRUE ELSE GetMouseRButton = FALSE
DEF SEG
END FUNCTION

SUB ShowMouse()
‘———————————–
‘| |
‘| Affiche le curseur de la souris |
‘| |
‘———————————–
DEF SEG = SegAsm%
ax% = 1
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
DEF SEG
END SUB

SUB HideMouse()
‘———————————-
‘| |
‘| Masque le curseur de la souris |
‘| |
‘———————————-
DEF SEG = SegAsm%
ax% = 2
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
DEF SEG
END SUB

SUB MoveMouse(x%, y%)
‘———————————–
‘| |
‘| Déplace le curseur de la souris |
‘| |
‘———————————–
DEF SEG = SegAsm%
ax% = 4
cx% = x%
dx% = y%
CALL Absolute(ax%, bx%, cx%, dx%, OffAsm%)
DEF SEG
END SUB


Bien entendu, on aurrait pu faire plus simple (on peut toujours faire plus simple). Mais le but
est de vous montrer comment fonctionne chaque fonction.

J’ai écris le nom des fonctions en English parceque je trouve que GetMouseX sonnait
mieux que DonneSourisX. Mais rien ne vous empêche de les traduire…

Les fonctions de cette ébauche de programme sont :

  • InitMouse : initialise la souris. L’utilisation en est conseillée avant toute intervention
    sur la souris.

  • GetMouseX : renvoi les coordonnées X virtuel de la souris.

  • GetMouseY : renvoi les coordonnées Y virtuel de la souris.

  • GetMouseLButton : renvoi l’état du bouton gauche de la souris (TRUE si enfoncé, FALSE
    si relaché).

  • GetMouseRButton : renvoi l’état du bouton droit de la souris (TRUE si enfoncé, FALSE
    si relaché).

  • ShowMouse : affiche le curseur de la souris.

  • HideMouse : masque le curseur de la souris.

  • MoveMouse : déplace le curseur au coordonnées X et Y spécifiée. Le curseur doit cependant
    être visible.

Series Navigation«QBasic – La mémoireQBasic – L’heure, la date, le temps»
Categories: QBasic Tags:
  1. phil
    16/12/2001 à 16:04 | #1

    bonjour, j’ai essayé le premier code où apparait pour la première fois call absolute, le programme ne fonctionne pas.

  2. webmaster
    17/12/2001 à 21:08 | #2

    Quel est cette erreur?
    Si tu utilise QBasic 4.5, il faut que tu charge la librairie qb.qlb où se trouve l’instruction CALL ABSOLUTE, comme ceci par exemple : C:\QB\QB.EXE /L qb.qlb

    Raphaël

  3. Spout
    18/05/2005 à 00:42 | #3

    Moi, j’ai réussi. Le problème, il ne veux pas le compiler. Que faire?

  4. linio
    16/09/2005 à 16:51 | #4

    pour le compiler tu doit utiliser le programme bcom45.com
    puis le programme link.com
    attention
    les noms doivent être en ms dos

  1. Pas encore de trackbacks