Egér.:

Hogyan működik a PC egér, és hogyan programozható a legalacsonyabb szintről és a BIOS-ból?

1. Hogyan működik az egér?

A PC egér tipikus vezérlési lánca a következőképp épül fel:

érzékelő – egérvezérlő – kommunikációs kapcsolat – adatfelület – egérmeghajtó - szoftver

Az érzékelő mozgásérzékelőket és nyomógombokat jelent. Az egérvezérlő az érzékelők jele alapján határozza meg az egér pillanatnyi elmozdulását és a gombok állapotváltozását. Ha keletkezik ilyen információ, az egérvezérlő automatikusan elküld egy adatcsomagot az adatfelülethez a kommunikációs kapcsolaton keresztül. Az egérmeghajtó az adatcsomag vétele után dekódolja az információt, és ennek alapján hajt végre valamilyen tevékenységet. Jellemzően: az egérvezérlő tárolja az egér aktuális állapotát (pozíció és nyomógomb), és kérésre átadja az operációs rendszernek vagy alkalmazói programnak. Az egérmeghajtó normálisan kurzor mozgató rutinokat hív meg az egér mozgatásakor és üzenetet küld a nyomógombok állapotának megváltozásakor.

A modern PC egér meghajtóban az aktuális kurzor mozgatása nem lineáris az egér mozgásával. Ez furcsán hangzik, de jobbnak találták az egér mozgását külön kurzor mozgássá alakítani, mint az 1:1 megfeleltetést (1 egér lépés = 1 pixel kurzor lépés). A Xerox cég kezdte el az egér és grafikus felhasználói interfész (GUI) fejlesztését. Az Apple átvette a Xerox néhány ötletét, és saját gyártmányaiban továbbfejlesztette. A Xerox és Apple már korai fejlesztéseik során rájöttek, hogy nincs minden feladathoz megfelelő általános összefüggés az egér és kurzor mozgása között. Felismerték, hogy két alapvető mozgás létezik a mutató eszközök világában: mozgás a kívánt terület felé, és pontos mozgás a kívánt célhoz. A két mozgás ellentétes követelményeket támaszt, ezért az Apple a CPI (counts per inch = szám/hüvelyk) egységben történő egér mozgás követésével oldotta fel a problémát. Ha az egér lassan mozog 100 CPI módban marad, gyors mozgásnál viszont átvált 400 CPI üzemmódba. A CPI változtatáson alapuló felhasználást a Windows 95 meghajtók is átvették, és manapság ez a legelterjedtebb átalakítási módszer az egér és a kurzor mozgása között.

A legtöbb egér mozgásérzékelője optomechanikus érzékelőkre épül. Az egér elmozdulása X és Y irányú összetevőkre bomlik két, egymásra merőleges forgó tárcsa segítségével. A tárcsákat az egérből kinyúló dörzsfelületű golyó forgatja az egér elmozdításakor vagy a golyó forgatásakor. Az egér egy lehetséges megvalósításánál mindkét forgó tárcsára két-két optikai érzékelő van szerelve, és forgáskor a tárcsákon lévő réseken keresztül az optikai érzékelők szakaszosan kapnak fényt. A tárcsákra épített érzékelők egymáshoz 90-105 fokos szögben vannak szerelve, hogy az előre/hátra elmozdulást meg lehessen különböztetni. A tárcsákon szokás szerint hat rés van 60 fokos eltolással. Ha az egeret egyik irányban mozgatjuk, a tárcsa elfordulása során az alábbi ábrán látható állapotok lépnek fel a jeladók kimenő jelében. Az ábrán az A állapotból kiindulva (0. érzékelő világos, 1. érzékelő sötét) a B, C, D és E állapotok következnek (az E állapot megfelel az A-nak, csak közben 60 fokos lefordulás történt). Az egeret ellenkező irányban mozgatva az állapotváltás A–D–C–B sorrendű.

 

0. érzékelő

 

 

 

 

 

 

 

 

 

 

 

 

 

 

fény = 1

 

1

1

0

0

1

1

0

0

1

1

0

0

1

1

sötét = 0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1. érzékelő

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0

1

1

0

0

1

1

0

0

1

1

0

0

1

 

A jelsorozatban négy bit-pár állapot-ismétlése figyelhető meg az alábbi sorrendben:

Jobbra irány:     0. ézékelő:        1   1   0   0            Balra irány:       0. érzékelő:       1   0   0   1

                        1. érzékelő        0   1   1   0                                    1. érzékelő:       0   0   1   1

Ez az információ könnyen dekódolható a mikrokontrollerben, és a megfelelő formában elküldhető a számítógéphez.

2. Egér hardver

Szoftver oldalról a busz egér, a soros egér és a PS/2 egér egyforma. Az egérmeghajtó a hardver közötti különbségeket elmossa, az alkalmazói program azonos módon kommunikálhat mindhárom egértípussal. Hardver oldalról viszont a három típus között elvi különbségek vannak.

2.1. Soros egér

A soros egér kommunikációs eszközként működik. Adatot küld a soros portra, ha egér esemény történt. Az egér belsejében lévő mikroprocesszor minden állapotváltozáskor adatcsomagot küld be. Az adatokat a PC megszakítással veszi át, és az egérmeghajtó kezeli le.

Az egér nem rendelkezik saját tápegységgel, a működéshez szükséges áramot (kb. 10 mA) a szabványos RS-232C bemeneti vonalakról (DTR és RTS-ről +12 V, TxD lábról –12 V) szedi le. Az egértől a számítógéphez RS-232C feszültségű jelek jutnak +/- 5 és +/- 12 V közötti szinttel, maga az elektronika + 5 V feszültséget igényel. Az egér áramfelvétele lényegében az optikai jeladók LED áramából áll. A négy infravörös LED sorba van kötve, melyeken együttesen 5 V feszültség esik. Ez az 5 V ideális a mikrokontroller tápellátásához. A teljes egér elektronika a minél kevesebb teljesítmény igényre van tervezve.

2.1.1 Microsoft egér

A Microsoft egér a legnépszerűbb két gombos soros egér, a legtöbb operációs rendszer támogatja. Az egér maximális átvitele 5080 szám másodpercenként (40 riport/sec és 127 szám/riport). A tipikus egér jellemző tartománya 100 és 400 CPI közé esik, de elérheti az 1000 CPI-t. Ez azt jelenti, hogy a 100 CPI-s egeret max. 50,8 hüvelyk/sec, a 400 CPI-s egeret pedig 12,7 hüvelyk/sec sebességgel mozgathatjuk. A mozgás aktuális pontosságát az egérmeghajtó beállítása határozza meg, néhány egérmeghajtó lehetővé teszi az egér érzékenységének változtatását. Az egércsatlakozó lábkiosztása (9 és 25 lábú „D” csatlakozó):

ház         1. láb           védőföld

3. láb      2. láb           TxD             csak a tápellátáshoz

2. láb      3. láb           RxD             adat a gazdagéphez

7. láb      4. láb           RTS             pozitív feszültség az egérhez

8. láb      5. láb           CTS

6. láb      6. láb           DSR

5. láb      7. láb           jelföld

4. láb      20. láb         DTR             pozitív feszültség az egérhez és reset/érzékelés

A helyes működéshez az RTS és DTR vonalaknak pozitívnak kell lennie. A DTR-DSR és RTS-CTS vonalakat nem szabad összekötni. Az RTS átváltás funkcióhoz az RTS legyen negatív (min. 100 ms ideig), majd ismét pozitív. Hidegindítás után az RTS szokás szerint negatív. Ebben az esetben az RTS pozitív szintre állítása is RTS átváltással történik.

A Microdoft egér soros átvitel paraméterei: 1200 bps, 7 adatbit, nincs paritás, 1 stop bit.

Csomag formátum. Az adatcsomag három bájtból áll. Ezt minden alkalommal elküldi az egérvezérlő a számítógépnek, ha az egér állapota megváltozik (mozgás, gomb fel/le).

 

D7

D6

D5

D4

D3

D2

D1

D0

1.

X

1

LB

RB

Y7

Y6

X7

X6

2.

X

0

X5

X4

X3

X2

X1

X0

3.

X

0

Y5

Y4

Y3

Y2

Y1

Y0

Tekintve, hogy az átvitel 7 bites, a 7. bit nincs használva. Ha az egér 7 bites adatokkal és 2 stop bittel dolgozik, az X bitek értéke nulla. Lehetséges 8 adatbit és 1 stop bites keret is, ilyenkor az X értéke 1. Biztonságosabb azonban a 7 adatbites 1 stop bites átvitel. Az 1. bájt küldődik először, azután a többi. A D6 adatbit szinkronizációs célokat szolgál. Az LB (bal gomb) és RB (jobb gomb) értékénél 0 szint jelenti a lenyomott gombot. Az X7-X0 a vízszintes, az Y7-Y0 a függőleges irányú egér elmozdulást jelenti a legutolsó csomagban küldött pozícióhoz képest előjelesen. Az egér elmozdulás egysége a mickey, mely 1/200 hüvelyknek (0,13 mm) felel meg. Az egy bájtban megadható elmozdulás kb. 0,62 hüvelyknek (±15,75 mm, 127 egység) felel meg, az átküldés kb. 20 ms 1200 bps mellett. Egér azonosítás: ha a DTR vonal állapotot vált, az egérvezérlő 1 bájtos azonosítót küld a számítógépnek („M”).

2.1.2 Logitech egér

A Logitech hasonló protokollt használ saját egereinél. Az eredeti protokollt csak két egeret kezelt, a Logitech adott hozzá egy harmadikat néhány típusánál. A normál csomag után a középső gomb állapotát leíró kiegészítő bájtot küld be, ha szükséges (lenyomott állapothoz 20h értéket). Ezt a harmadik bájtot akkor is beküldi, ha a középső gomb lenyomva maradt, és megváltozott az egér pozíciója. A gomb elengedésekor beküldött érték nulla.

2.1.3 Mouse system egér

A soros átvitel paraméterei: 1200 bps, 8 adatbit, 1 stop bit.

Az adatcsomag öt bájtból áll a következő formátumban:

 

D7

D6

D5

D4

D3

D2

D1

D0

1.

1

0

0

0

0

LB

CB

RB

2.

X7

X6

X5

X4

X3

X2

X1

X0

3.

Y7

Y6

Y5

Y4

Y3

Y2

Y1

Y0

4.

X7’

X6’

X5’

X4’

X3’

X2’

X1’

X0’

5.

Y7’

Y6’

Y5’

Y4’

Y3’

Y2’

Y1’

Y0’


Az LB a bal, az RB a jobb, a CB pedig a középső gomb állapotát jelenti (0= lenyomva, 1= felengedve). Az X7-X0 és Y7-Y0 bitek az egér vízszintes illetve függőleges irányú elmozdulását jelenti a legutolsó csomag beküldése óta. A bájt előjeles (-128 és +127), a pozitív szám jobbra, ill. felfelé irányt jelent. A vesszős jeleket tartalmazó utolsó két bájt az X és Y irányú változásokat tartalmazza a 2. és 3. bájthoz képest (??).

2.2 Busz egér

A busz egér teljesen különbözik a soros egértől, a PC ISA aljzatába dugható egérkártyához csatlakozik. Az intelligencia a kártyán található, maga az egér csak érzékelőket tartalmaz. A legtöbb megvalósításban a kártya úgy van programozva, hogy megadott intervallumonként (1/30 és 1/60 sec között) megszakítja a processzort, így a meghajtó lekérdezheti a kártya állapot regiszterét. Az időzítés kb. megfelel a videókártya frissítésének. Az újabb busz egerekbe integrált InPort lapka nyomon követi az egér mozgását, és csak akkor szakítja meg a processzort, ha esemény történt.

A busz egér nem küld adatcsomagot, helyette az állapotot adja át. A kártya 9 pólusú Hosiden csatlakozóba dugható. Három láb a nyomógombok állapotát hordozza, az XA, XB, YA és YB kvadratura jelek az elmozdulás irányát és mértékét jelentik. A kvadratúra dekódolásban két jel határozza meg az egér elmozdulását az adott irányban. Pl. az XA jel pulzusa jelzi, hogy elmozdulás történt. Ha az XB pulzus kis késéssel érkezik, az irány pozitív. Ha az XB megelőzi az XA-t, negatív irányban történt elmozdulás. Az InPort számláló regisztere 8 bites kettes komplemens formában őrzi az elmozdulásokat (-128 és 127 között).

1.            +5V

2.            XA (mozgásérzékelő)

3.            XB (mozgásérzékelő)

4.            YA (mozgásérzékelő)

5.            YB (mozgásérzékelő)

6.            SW1 (bal nyomógomb)

7.            SW2 (közép nyomógomb)

8.            SW3 (jobb nyomógomb)

9.            jelföld

2.3 PS/2 egér

A PS/2 egér az ATX-tól kezdve az alaplaphoz kapcsolódik a PS/2 billentyűzethez hasonló 6 pólusú csatlakozóval, és nem foglal le soros portot. Az adat (a billentyűhöz hasonlóan) soros szinkron vonali protokollal küldődik át. Az egér adatokat a billentyűvezérlő kezeli. A PS/2 egér az IRQ 12 megszakítást, és a 060h, 064h portcímeket használja.

A busz egér esetenként ugyanolyan mini DIN csatlakozót használ, mint a PS/2. Vigyázzunk, mert a PS/2 csatlakozóba dugott busz egér tönkreteheti az alaplapot!

A billentyű vezérlő dekódolja a PS/2 egértől jövő jeleket, és a PS/2 BIOS hozzárendeli az egérmeghajtót. A BIOS programozási felületen az egér mintavételezése 10 – 200 Hz közötti értékekre állítható be.

A szabványos (Logitech) PS/2 egér alapértéke 160 CPI, de programmal 40 – 80 – 160 vagy 320 CPI is beállítható. A Windows 3.x és 95 Microsoft egérnél is 160 CPI az alapérték. A maximális átvitel 40 riport/sec és 255 szám/riport mellett 10 200. szám. 100 CPI esetén ez 100 hüvelyk/sec, 400 CPI-nél pedig 25,2 hüvelyk/sec sebességnek felel meg.

A mini DIN csatlakozó lábkiosztása a PC hátlap felöl nézve:

1=Data      2= fennt.    3= föld

4=+5 V      5= Clk       6= fenntartott,

Csomagformátum:

 

D7

D6

D5

D4

D3

D2

D1

D0

1.

XV

XV

YS

XS

1

0

R

L

2.

X7

X6

X5

X4

X3

X2

X1

X0

3.

Y7

Y6

Y5

Y4

Y3

Y2

Y1

Y0

Az XS és YS az elmozdulás előjelbitje (1= negatív), az XV és YV pedig azt jelzi, hogy túlcsordulás történt. Az L és R jelölés a nyomógombokra vonatkozik (1= lenyomva).

A kétirányú átvitelt a CLK és DATA vonalak vezérlik. Mindkettőt nyitott kollektoros kimenet hajtja meg +5 V-ra felhúzó ellenállással, így a vonalakat mindkét fél lehúzhatja nullára. Ha nincs átvitel, a CLK= 1, a DATA= 0 vagy 1 szintű. A gazdagép a CLK nullába húzásával tilthatja le az átvitelt. Ha ez az átvitel során történik (11. órajel előtt), az átvitelt meg kell ismételni később.

Vétel: ha a Clock inaktív (??), adat van a Data vonalon. Minden átvitt egység 1 start, 8 adat, 1 páratlan paritás és 1 stop bitből áll. A startbit alacsony, a stop magas. Az óra aktív/inaktív periódusa 30 – 50 µs. hosszú. Az adatátvitel az óra lefutó élénél 5 – 25 µs.

Adás: a Clock és Data magas szintje mellett start bittel lehet kezdeni az adást.

A PS/2 egér egyik különlegessége, hogy a csomag formátum nem tartalmaz szinkronizáló bitet, mint a soros egérnél. Tekintve, hogy az alaplapi vezérlő az egértől és a billentyűzetről jövő adatokat is kezeli, előfordulhat, hogy egy program, mely billentyűzetről és egértől is vesz adatokat bedugul, és az egérmeghajtó kiesik a szinkronból. Ha lenne szinkronizáló bit, ez nem fordulhatna elő.

Soros - PS/2 egér konverzió

A soros egér RS-232C jeleket használ (-5 és –12V illetve +5 és +12V között). A PS/2 egér ezzel szemben TTL szintű jelekkel dolgozik. Továbbá: a soros egér aszinkron, a PS/2 szinkron átvitelt használ (az adat mellett ott az órajel is). Az adat és órajelet mind a billentyűzet, mind az egérvezérlő meghajthatja, és a csatlakozott eszközök egyszerű kézfogásos módon dönti el, melyik az „adó” és melyik a „vevő”. Ezért nem egyszerű dolog a soros és PS/2 egér közötti konverzió. A kettős módú egér képes automatikusan felismerni, milyen interfészre dugták, és a megfelelő módon kezeli le.

Nem történik baleset, ha a PS/2 portra Microsoft soros egeret dugunk. A PS/2 csatlakozó 4. lábán +5 V feszültséget visz, a soros port nem tesz ilyet. A Microsoft soros egér figyeli ezt a vonalat, és ha talál feszültséget, az adat formátumát ennek megfelelően állítja be, egyébként soros egérként üzemel.

3. Programozás

Szerencsére a programozásnál nem kell foglalkoznunk az adatcsomagokkal, mivel ezt elintézi az egérmeghajtó (melyet előzetesen nekünk kell telepítenünk). A Microsoft egérmeghajtó neve MOUSE.SYS vagy MOUSE.COM (CONFIG.SYS vagy AUTOEXEC.BAT állományokban). A Microsoft és kompatíbilis meghajtó 54 magas szintű funkció (7.x változatig) készletét tartalmazza, melyet a felhasználói program használhat, ha kapcsolatot akar az egérrel. Ha az INT 33h 0-ra vagy IRET utasításra mutat, nincs telepítve a meghajtó.

00h    egér törlés                                                   1Bh    egér érzékenység bekérése (6.0)

01h    kurzor látható (1.0)                                       1Ch    egér IT viszony megadása (6.0)

02h    kurzor rejtett (1.0)                                        1Dh    CRT lapszám megadása (6.0)

03h    gomb / egér pozíció bekérés (1.0)                  1Eh    CRT lapszám bekérése (6.0)

04h    kurzor pozíció beállítása (1.0)                        1Fh    meghajtó tiltása (6.0)

05h    gomb lenyomás info bekérése (1.0)               20h    meghajtó engedélyezése (6.0)

06h    gomb felengedés info bekérése (1.0)              21h    szoftver reset (6.0)

07h    min/max. vízsz. kurz. poz. beállít. (1.0)          22h    üzenetek nyelv megadása (6.0)

08h    min/max. függ. kurz. poz. beállít. (1.0)           23h    üzenetek nyelv bekérése (6.0)

09h    grafikus kurzor blokk megadása (3.0)             24h    információ bekérése (6.26)

0Ah    szöveg kurzor megadása (3.0)                       25h    általános meghajtó info bekérése (6.26)

0Bh    egér mozgásszámláló olvasása (1.0)             26h    max. virtuális koordináták bekérése (6.26)

0Ch    IT maszk és cím megadása (1.0)                   27h    maszkok és mickey szám bekérése (7.01)

0Dh    fénytoll emuláció bekapcsolása (1.0)             28h    Videó mód beállítása (7.0)

0Eh    fénytoll emuláció kikapcsolása (1.0)              29h    videó módok felsorolása (7.0)

0Fh    mickey/képpont megadása (1.0)                    2Ah    kurzor forró pont bekérése (7.02)

10h    feltételes kikapcsolás (1.0)                           2Bh    gyorsító profile betöltése (7.0)

11h    fenntartott                                                    2Ch    gyorsító profile bekérése (7.0)

12h    nagy kurzor blokk megadása                        2Dh    gyorsító profile kiválasztása (7.0)

13h    kettős sebesség küszöb beállítása (5.0)        2Eh    gyorsító profile név megadása (8.10)

14h    IT rutinok cserélése (3.0)                              2Fh    egér hardver törlés (7.02)

15h    meghajtó állapot tárolási igény be (6.0)          30h    ballpoint info bekérés/megadás (7.04)

16h    meghajtó állapot mentése (6.0)                     31h    akt. min/max virt. koord. bekérése (7.05)

17h    meghajtó állapot vissza (6.0)                         32h    aktív kibővített funkciók bekérése (7.05)

18h    alternatív IT maszk/cím megadása (6.0)         33h    kapcs. beáll./gyors. profile adatok be (7.05)

19h    felhaszn. alt. IT cím bekérése (6.0)                4Dh    copyright füzér mutató bekérése

1Ah    egér érzékenység megadása (6.0)                 6Dh    változat füzér bekérése

Az egér funkció hívására az alábbi assembly program mutat példát:

MOV   AX, 05h    ; gomb lenyomás információ bekérése

MOV   BX, 1      ; jobb egérgomb

INT   33h        ; egér funkció

TEST  BX, 1           ; 0. bit (lenyomott = 1)

JZ    NOT_DEPR   ; ugrás, ha nincs lenyomva

3.1 Funkciók részletesen

 

AX= 00h      Egér törlés

Egérmeghajtó alapállapotba állítása.

Ki:      AX = nem nulla, ha hw/meghajtó telepített

          BX = nyomógombok száma

AX= 01h      Kurzor látható (számolja)

AX= 02h      Kurzor nem látható (számolja)

AX= 03h      Gomb / egér pozíció bekérés

Szöveg módban a koordináták cellaméret egységben (pl. 8*8)

Ki:      BX = 0. bit/bal, 1/jobb, 2/közép (1 = le)

          CX/DX = vízsz/függ. koord. (oszlop/sor)

AX= 04h      Kurzor pozíció beállítása

Kurzor mozgatás megadott helyre. A pozíció cellaméretre levágva.

Be:     CX/DX = vízsz/függ. koord. (oszlop/sor)

AX= 05h      Gomb lenyomás info bekérése

Be:     BX = gomb (0/bal, 1/jobb, 2/közép)

Ki       AX = 0. bit/bal, 1/jobb, 2/középső állapota

          BX = lenyomások száma utolsó hívás óta

          CX/DX = utolsó nyomás: oszlop/sor

AX= 06h      Gomb felengedés info bekérése

Be:     BX = gomb (0/bal, 1/jobb, 2/közép)

Ki       AX = 0. bit/bal, 1/jobb, 2/középső állapota

          BX = felengedések száma utolsó hívás óta

          CX/DX = utolsó felengedés: oszlop/sor

AX= 07h      Min/max. vízsz. kurzor poz. beáll.

Vízszintes korlát az egérkurzor számára.

Be:     CX/DX = min/max. vízsz. koord. (oszlop)

          DX = maximális vízszintes koordináta

AX= 08h      Min/max. függ. kurzor poz. beáll.

Függőleges korlát az egérkurzor számára.

Be:     CX/DX = min/max. függ. koord. (sor)

AX= 09h      Grafikus kurzor blokk megadása

Grafikus kurzor definiálása (ld. külön).

Be:     BX/CX = forró pont oszlop/sor a térképben

          ES:DX = maszk bittérkép.

AX= 0Ah      Szöveg kurzor megadása

Szöveges kurzor definiálása (ld. külön).

Be:     BX = kurzor típus (0 = sw / 1 = hw)

          CX = képernyő maszk / kezdő scan sor

          DX = kurzor maszk / befejező scan sor /

AX= 0Bh      Egér mozgásszámláló olvasása

Mozgás az utolsó hívás óta mickey egységben (pozitív = le, jobbra).

Ki:      CX/DX = vízszintes/függőleges mozgás

AX= 0Ch      IT maszk és cím megadása

A funkciót ld külön.

Be:     CX = esemény maszk (= 1)

              0. bit = egér mozgás, 1 = bal le, 2 = fel

              3-4. bit = jobb, 5-6. bit = közép

          ES:DX = egérkezelő rutin címe

IT hívás: AX = esemény maszk

          BX = 0. bit/bal, 1/jobb, 2/közép áll. (1 = le)

          CX:DX = vízszintes/függőleges koordináta

          SI:DI = vízszintes/függőleges mickey szám

AX= 0Dh      Fénytoll emuláció bekapcsolása

AX= 0Eh      Fénytoll emuláció kikapcsolása

AX= 0Fh      Mickey/képpont megadása

Be:     CX = 8 vízsz. képponthoz mickey (alap: 8)

          DX = 8 függ. képponthoz mickey (alap: 16)

AX= 10h      Feltételes kikapcsolás

A megadott területen a kurzor rejtett, külön be kell kapcsolni.

Be:     CX:DX = bal felső sarok X és Y koordinátái

          SI:DI = jobb alsó sarok X és Y koordinátái

AX= 12h      Nagy kurzor blokk megadása

Be:     BH = kurzor szélesség szavakban

          CH = sorok a kurzorban

          BL/CL = vízsz/függ. forró pont (-16 – 16)

          ES:DX = képernyő és kurzor maszk térkép

AX= 13h      Kettős sebesség küszöb beáll.

Ha a sebesség (mickey/sec) átlépi a küszöböt, a képernyőmozgás kétszereződik.

Be:     DX = küszöb sebesség (alap = 0 -> 64)

AX= 14h      IT rutinok cserélése

Be:     CX = esemény maszk (ld. 0Ch)

          ES:DX = új IT rutin címe

Ki:      CX = előző esemény maszk

          ES:DX = előző IT rutin címe

AX= 15h      Meghajtó állapot tárolási igény be

Ki:      BX = állapot tárolásához puffer méret

AX= 16h      Meghajtó állapot mentése

Be:     BX = puffer méret (ld. 15h)

          ES:DX = puffer címe

AX= 17h      Meghajtó állapot vissza

Be:     BX = puffer méret (ld. 15h)

          ES:DX = puffer, benne a mentett adatok

AX= 18h      Alternatív IT maszk/cím megadása

Az esemény során a Shift, Ctrl vagy valamelyike lenyomva. Három egérkezelő definiálható.

Be:     CX = esemény maszk (= 1)

              0. bit = egér mozgás, 1 = bal le, 2 = fel

              3-4. bit = jobb, 5-7. = Shift – Ctrl - Alt le

          ES:DX = rutin címe az eseményre

Ki:      AX = állapot (18h = sikeres, -1 = hiba)

IT hívás: ld. 0Ch

AX= 19h      Felh. alternatív IT cím bekérése

A 18h funkcióval létrehozott felhasználói eseménykezelő megkeresése, melyben az esemény maszk egyezik a CX- szel.

Be:     CX = esemény maszk (ld. 18h)

Ki:      BX:DX = felhasználó IT vektor

          CX = esemény maszk (0, ha nem talált)

AX= 1Ah      Egér érzékenység megadása

Be:     BX/CX = vízszintes/függőleges sebesség

          DX = kétszeres sebesség küszöb

AX= 1Bh      Egér érzékenység bekérése

Ld.:    1Ah

AX= 1Ch      Egér IT viszony megadása

Csak Inport egérnél létezik.

Be:     BX = (0= nincs, 1= 30, 2= 50, 3= 100

                   4= 200/sec

AX= 1Dh      CRT lapszám megadása

Be:     BX = képernyő lap száma (kurzor)

AX= 1Eh      CRT lapszám bekérése

Ki:      BX = képernyő lap száma (kurzor)

AX= 1Fh      Meghajtó tiltása

Ki:      AX = állapot (1Fh= sikeres, ilyenkor)

              ES:BX = Int 33h vektor első init előtt

AX= 20h      Meghajtó engedélyezése

Ki:      AX = állapot (20h= sikeres)

AX= 21h      Szoftver reset

Azonos a 00h függvénnyel, de nem törli az egeret.

Ki:      AX = állapot. 21h = nincs meghajtó,

                 -1 = meghajtó telepítve, ilyenkor

                   BX = gombok száma (-1 = 2)

AX= 22h      Üzenetek nyelv megadása

Be:     BX = nyelvkód (0 = GB, 1 = F, 2 = NL

          3 = D, 4 = S, 5 = SF, 6 = E, 7 = P, 8 = I

AX= 23h      Üzenetek nyelv bekérése

Ki:      BX = nyelvkód (ld. 22h)

AX= 24h      Információ bekérése

Ki:      AX = -1 (hiba)m egyébként

          BH/BL = egész/tört változat

          CH = 1 = busz, 2 = soros, 3 = Inport

                   4 = PS/2, 5 = HP)

          CL = IRQ (0 = PS/2, 2 - 7, 0Fh = 15)

AX= 25h      Általános meghajtó info bekérése

Ki:      AX = általános info (nem részl.)

          BX = kurzor zárolás jelző (OS/2)

          CX = egér kód aktív jelző (OS/2)

          DX = meghajtó foglalt jelző (OS/2)

AX= 26h      Max. virtuális koord. bekérése

Ki:      BX = egér tiltott jelző (0 = enged.)

          CX = max. virtuális X (akt. videó módhoz)

          DX = max. virtuális Y

AX= 27h      Maszkok / mickey szám bekérése

Ki:      AX = képernyő maszk

          BX = kurzor maszk

          CX/DX = vizsz/függ. mickey út. hívás óta

AX= 28h      Videó mód beállítása

Be:     CX = új videó mód

          DH/DL = Y /X fontméret (alap= 0)

Ki:      CL = állapot (0 = sikeres)

AX= 29h      Videó módok felsorolása

A felsorolt videó módok tetszőleges sorrendben lehetnek ismétléssel.

Be:     CX = előző videó mód (0 = első köv. mód,

                   egyébként CX utáni)

Ki:      CX = első/következő mód (0 = nincs több)

          DS:DX = videó mód leírása

AX= 2Ah      Kurzor forró pont bekérése

A forró pont a kurzor blokk bal felső sarkához viszonyított (-128 – 127)

Ki:      AX = belső számláló (kurzor látható)

          BX/CX = forró pont vízsz./függ. eltolása

          DX = egér típus (ld. 24h, 0 = nincs)

AX= 2Bh      Gyorsító profile betöltése

Be:     BX = aktív gyorsító profile

          ES:SI = puffer (profile adatok, ld. külön)

Ki:      AX = állapot (0 = sikeres)

AX= 2Ch      Gyorsító profile bekérése

Ki:      AX = állapot (0 = sikeres)

          BX = aktuálisan aktív gyorsító profile

          ES:SI = puffer (profile adatok ld. külön)

AX= 2Dh      Gyorsító profile kiválasztása

Be:     BX = profile száma

Ki:      AX = állapot (0 = sikeres, ilyenkor)

              ES:SI = profile neve 16 bájtra feltöltve

          BX = aktív gyorsító görbe száma

AX= 2Eh      Gyorsító profile név megadása

Be:     BL = jelző (<> 0 = pufferben alap név)

          ES:SI = 64 bájt puffer a nevek számára

Ki:      AX = állapot (0 = sikeres, -2 = hiba)

          ES:SI = alapértelmezett nevek, ha BL <> 0

AX= 2Fh      Egér hardver törlés

Ki:      AX = állapot jelző

AX= 30h      Ballpoint info bekérés/megadás

Be:     CX = parancs (0 = áll. be, <>0 = megadás)

          BX = forgási szög (-32768 – 32767 fok)

          CH/CL = elsődl./másodlagos gomb maszk

Ki:      AX = gomb állapot (-1, ha nem BallPoint)

          BX = forgási szög (0-360 fok)

          CH/CL = elsődl./másodlagos gomb maszk

AX= 31h      Akt. min/max virt. koord. bekérése

Ki:      AX/BX = virtuális X/Y minimum

          CX/DX = virtuális X/Y maximum

AX= 32h      Aktív kibőv. funkciók bekérése

Ki:      AX = funkciók jelző

              15. bit = 25h funkció támogatva

                 0. bit = 34h funkció támogatva

AX= 33h      Kapcs./gyors. profile adatok be

Be:     CX = pufferméret (0 = méret bekérés)

          ES:DX = puffer, ha CX <> 0, ld. külön

Ki:      AX = 0, ha CX = 0

          CX = igényelt puffer méret (CX = 0)

                 visszaadott adatok (CX <> 0)

                 ES:DX = feltöltve (ld, külön)

AX= 4Dh      Copyright füzér mutató bekérése

Ki:      ES:DI = copyright üzenet

AX= 6Dh      Meghajtó változat füzér bekérése

Ki:      ES:DI = változatszám (egész/tört BCD)

 

3.2 Néhány funkció részletesebben

AX= 09h      Grafikus kurzor blokk megadása

Grafikus kurzor definiálása. Grafikus módban a képernyő kurzor körüli blokkja ÉS kapcsolatba kerül a képernyő maszkkal, és XOR kapcsolatba kerül a kurzor maszkkal. A bittérképben 8 szó képernyő maszk, 8 szó kurzor maszk. Minden szó a sor 16 képpontját határozza meg (alacsony bit jobbra).

AX= 0Ah      Szöveg kurzor megadása

Szöveges kurzor definiálása. Hardver vagy szoftver kurzort választhatunk. Hardvernél a kurzor téglalap alsó és első letapogatási sorát kell megadnunk. Szoftver kurzornál a karakter/attribútum az aktuális képernyő pozícióban ÉS kapcsolatba kerül a képernyő maszkkal és XOR kapcsolatba kerül a kurzor maszkkal.

AX= 0Ch      IT maszk és cím megadása

A funkció utasítja az egérmeghajtót, hogy szakítsa őt meg aszinkron, ha az egér elmozdult, vagy a gombok állapota megváltozott. A program két paramétert ad át a meghajtónak, hívási maszkot és szubrutin címet. A maszk szűrőként működik: ha a programot nem érdekli az egér mozgása vagy gomb elengedése, a maszk beállítható, hogy csak gomb lenyomására történjen megszakítás. A másik paraméter a megszakításkor végrehajtandó szubrutin 32 bites kezdőcíme.

AX = 2B/2Eh     Gyorsító profile

Hívás:   BX = aktív profile (1 – 4, vagy –1 az alapértelmezett visszaállításához).

Puffer:

000h   1        1. profile hossza                                 084h   32      gyorsítási tényező az 1. profile-hoz

001h   1        2. profile hossza                                 0A4h  32      gyorsítási tényező a 2. profile-hoz

002h   1        3. profile hossza                                 0C4h  32      gyorsítási tényező a 3. profile-hoz

003h   1        4. profile hossza                                 0E4h  32      gyorsítási tényező a 4. profile-hoz

004h   32      küszöbsebesség az 1. profile-hoz        104h   16      1. gyorsító profile neve (szóköz tölt)

024h   32      küszöbsebesség a 2. profile-hoz          114h   16      2. gyorsító profile neve (szóköz tölt)

044h   32      küszöbsebesség a 3. profile-hoz          124h   16      3. gyorsító profile neve (szóköz tölt)

064h   32      küszöbsebesség a 4. profile-hoz          134h   16      4. gyorsító profile neve (szóköz tölt)

Megjegyzések:

1. Gyorsító tényező a profile-hoz: 10h = 1.0, 14h = 1.25, 20h = 2.0, stb.

2. A nem használt bájtok a küszöbfeszültségnél 7Fh-vel, a gyorsítási tényezőnél 10h-val vannak feltöltve.

AX= 33h      Kapcsolók/gyorsító profile adatok be

Puffer tartalma:

00h    1        egér típus                                          09h    1        memória típus (00h-02h)

01h    1        aktuális nyelv                                     0Ah    1        SVGA támogatás (00h,01h)

02h    1        vízszint. érzékenység (00h-64h)           0Bh    1        forgási szög

03h    1        függőleges érzékenység (00h-64h)       0Ch    1        ???

04h    1        kettős sebesség küszöb (00h-64h)       0Dh    1        elsődleges gomb (01h-04h)

05h    1        ballisztikus görbe (01h-04h)                 0Eh    1        másodlagos gomb (01h-04h)

06h    1        IT viszony (01h-04h)                            0Fh    1        click zárás engedély (00h,01h)

07h    1        kurzor felülíró maszk                           10h    324    gyorsító profile (ld profile puffer)

08h    1        laptop állítás                                      154h   5        ???

3.3 Programozási alapok

Az első feladat az egérmeghajtó inicializálása. Ehhez az AX = 0 paraméterrel kell meghívni az INT 33h megszakítást. Ha a visszaadott AX tartalma nem nulla, van egér és telepítve van a meghajtó.

A képernyőn az egér megjelenítéséhez az AX = 1 paraméterrel hívjuk az INT 33h-at. Szöveg módban láthatjuk a téglalap alakú kurzort, grafikus módban pedig az alapértelmezett nyilat. A meghajtó érzékeli milyen módban van a videó, és a megfelelő alakban rajzolja ki a kurzort.

A kurzor elrejtéséhez az AX = 2 hívás kell. Az elrejtés/megjelenítés akkor hasznos, ha a képernyőre rajzolunk. Jegyezzük meg, hogy az egérmeghajtó képernyő számlálóval nyomon követi az egér láthatóságát (0, ha látszik, negatív, ha nem). A többszöri elrejtés a számlálót mindig csökkenti, ezért a megjelenítéshez is többszöri funkcióhívás kell. A többszöri engedélyezés nem viszi a számláló értékét 0 fölé. A számláló értékét a 2Ah funkcióval kérhetjük be (AX-be).

Gyakran szükségünk lehet arra, hogy ismerjük a nyomógombok állapotát és a kurzor helyét. Ehhez csak az AX = 3 funkciót kell meghívnunk. A vízszintes koordináta a CX, a függőleges a DX, a gombok állapota a BX regiszterben tér vissza. A BX -ben külön bitek jelentik az egyes nyomógombokat, a bit 1 értéke jelenti a lenyomást. A koordináták megértéséhez tudni kell, hogy az egérmeghajtó általában 640*200 képpontos virtuális képernyővel számol. Ha a képernyő felbontása nem ilyen, nekünk kell konvertálni.

A kurzor alakjának megváltoztatása

Ha grafikus módban használunk egeret, alapértelmezésben nyíl alakú kurzorunk lesz. Ez legtöbbször megfelel, de esetenként szükség lehet más formájú kurzorra is. A grafikus módú kurzor képe 16 * 16 képpontból áll, melyet egy 64 bájtos pufferben adhatunk át az AX = 09 funkcióval (ES:DX). Az első 32 bájt kurzor maszkot tartalmaz a képernyőn megjelenítéshez (ÉS kapcsolat). A második 32 bájt (képernyő maszk, XOR kapcsolat) határozza meg a kurzor alatti képernyő megjelenését. A 64 bájtos pufferben minden bit egy képpontnak felel meg, pl. az első két bájt a két maszkban megfelel a kurzor felső sorában lévő 16 képpontnak. A bit 1 értéke jelenti a megjelenítést (kurzor maszk), illetve az átlátszóságot (képernyő maszk). Az egérmeghajtó a következőképp építi fel a kurzort:

képernyő maszk bit     kurzor maszk bit         képernyő bit

0                               0                                0

0                               1                                1

1                               0                                nem változik

1                               1                                invertált

Fontos tudnunk, hogy a kurzornak van egy ún. forró pontja (hot spot), ahová a kurzor éppen mutat. Általában ez az 1,1 pont a kurzor bal (vagy jobb ???) felső sarkához képest. Ha megváltoztatjuk a kurzor képét, megváltoztathatjuk a forró pont helyét is (AX = 9, CX/DX).

Apróságok

Korlátozhatjuk a képernyő egy tartományára az egér mozgását. A 07 és 08 funkció állítja a vízszintes és függőleges koordináta korlátokat. Mindkét esetben a CX tartalmazza a minimális és a DX a maximális koordinátákat képpontban. A kurzor helyét programból módosíthatjuk a 04 funkcióval (CX = vízszintes, DX = függőleges koordináták). Ha túl nagy koordinátákat adunk meg, a kurzor a 07/08 funkcióval megadott korlátból nem lép ki.

Meghatározhatjuk azt is, hogy az egér mozgása a képernyőn mekkora kurzor mozgást eredményezzen. Az egér mozgásának egysége a mickey, mely 1/200 hüvelyknek felel meg. A mickey/képpont megadása a 0Fh funkcióval történhet (CX= vízszintes, DX= függőleges). A regiszter értékek meghatározzák, hány mickey elmozdulás kell a képernyőn 8 képpontnyi elmozduláshoz. Alapértelmezésben a CX = 8, a DX = 16, de 1 és 32767 között változtatható.

Saját kezelőprogram írása

A legtöbb egérmeghajtó nem támogatja az SVGA módot, ezért saját kezelőprogramot kell írnunk, ha az egér támogatást ebben a módban is igényeljük. Nem kell az egész meghajtót megírnunk, melyre az alábbi Pascal program megfelelő ötletet ad. A program 13h videó módot állít be, alapállapotba helyezi az egeret és vár egy gombnyomásra. Ha közben valamilyen egér esemény történik, a kezelő meghívásra kerül, és kirajzol egy képpontot. A képpont színe attól függ, melyik gombot nyomtuk meg.

 

---------------------------------------------------------------

Uses Crt, Dos;

{$F+}

{ called with bl = buttons, cx = x * 2, dx = y }

procedure Handler; far; assembler;

asm

  { This mouse "handler" just draws a pixel at the current mouse pos }

  pusha

  push es                  ; pusha doesn't save es

  mov ax, $A000

  mov es, ax

  shr cx, 1

  xchg dh, dl

  mov di, dx

  shr dx, 2

  add di, dx

  add di, cx

  mov al, bl

  inc al

  stosb

  pop es

  popa

end;

{$F-}

begin

  asm

    { Set graphics mode 13h }

    mov ax, $13

    int $10

    { Initialize mouse driver }

    xor ax, ax

    int $33

    { Install custom handler }

    mov ax, SEG Handler

    mov es, ax

    mov dx, OFS Handler

    mov ax, 12

    mov cx, $1F

    int $33

    { Wait for a key press }

    xor ah, ah

    int $16

    { Back to text mode }

    mov ax, 3

    int $10

  end;

end.

----------------------------------------------------------------

 

 

Saját megszakítási rutint is írhatunk az egér események lekezelésére. Ha ilyen történik, három megszakítást generál az egér, és három bájt olvasódik be a COM portról. Az X és Y növekmények kettes komplemens előjeles számok. Az alábbi egyszerű Borland Pascal 7.0 egérkezelő szintén példaként szolgál. Először deklarálunk néhány szükséges dolgot.

 

-----------------------------------------------------------------

Uses Crt, Dos;

{$F+}

const COM1INTR = $0C;

      COM1PORT = $3F8;

var bytenum : word;

 

    combytes : array[0..2] of byte;

    x, y : longint;

    button1, button2 : boolean;

    MouseHandler : procedure;

---------------------------------------------------------------

 

A bytenum változó követi, melyik bájt következik (0, 1 vagy 2). A combytes tömb őrzi a vett bájtokat. Az egér pozíciója az x és y változóban van (nincs tartomány ellenőrzés). A button1 és button2 a gombok állapotát tartalmazza. A MouseHandler eljárás tárolja a normál egér eseménykezelőt. Minden alkalommal törölnünk kell, ha végeztünk. Az aktuális handler:

 

-----------------------------------------------------------------

procedure MyMouseHandler; Interrupt;

var dx, dy : integer;

var inbyte : byte;

begin

  { Get the port byte }

  inbyte := Port[COM1PORT];

  { Make sure we are properly "synched" }

  if (inbyte and 64) = 64 then bytenum := 0;

  { Store the byte and adjust bytenum }

  combytes[bytenum] := inbyte;

  inc(bytenum);

  { Have we received all 3 bytes? }

  if bytenum = 3 then

 

    begin

      { Yes, so process them }

      dx := (combytes[0] and 3) shl 6 + combytes[1];

      dy := (combytes[0] and 12) shl 4 + combytes[2];

      if dx >= 128 then dx := dx - 256;

      if dy >= 128 then dy := dy - 256;

      x := x + dx;

      y := y + dy;

      button1 := (combytes[0] And 32) <> 0;

      button2 := (combytes[0] And 16) <> 0;

      { And start on first byte again }

      bytenum := 0;

    end;

  { Acknowledge the interrupt }

  Port[$20] := $20;

end;

---------------------------------------------------------------

 

Még egy apróság. Beolvassuk a COM1 port adatát, és ha a 6. bit = 1, akkor az első bájt jött meg, ezért nullázni kell a bytenum változót óvatosságból. Ha mind a 3 bájt megjött, dekódoljuk a tartalmat, és frissítjük a megfelelő változók tartalmát. A 'Port[$20] := $20;' parancs a megszakítás vezérlőnek jelzi a kiszolgálást végét (EOI), és jöhet a következő megszakítás.

Megjegyzés: a fenti „handler” nem követi az egér pozíciót és a gombok állapotát. Ha teljes egérmeghajtót írunk SVGA játékhoz, el kell készítenünk kurzor rutinokat is.

Az egérmeghajtó telepítéséhez minden változót be kell állítanunk, mentenünk kell az aktuális egérkezelő címeit, és telepítenünk sajátunkat.

 

----------------------------------------------------------------

procedure InitMyDriver;

begin

  { Initialize the normal mouse handler }

  asm

    mov ax, 0

    int $33

  end;

  { Initialize some of the variables we'll be using }

  bytenum := 0;

  x := 0;

 

y := 0;

  button1 := false;

  button2 := false;

  { Save the current mouse handler and set up our own }

  GetIntVec(COM1INTR, @MouseHandler);

  SetIntVec(COM1INTR, Addr(MyMouseHandler));

end;

----------------------------------------------------------------

 

Ha a program befejeződött, mindent ki kell takarítanunk, és vissza kell térnünk a normál meghajtóhoz.

--------------------------------------------------------------------------------------------------------------------------------------

procedure CleanUpMyDriver;

begin

  SetIntVec(COM1INTR, @MouseHandler);

end;

--------------------------------------------------------------------------------------------------------------------------------------

Az alábbi rövid forrás teszteli a fenti kódot. Semmi mást nem csinál, csak kiírja az egér pozíciót és gombok állapotát a képernyőre, míg nem nyomunk egy gombot.

-------------------------------------------------------------------------------------------------------------------------------------

begin

  ClrScr;

  InitMyDriver;

  while not keypressed do

    WriteLn(x : 5, y : 5, button1 : 7, button2 : 7);

  CleanUpMyDriver;

end.

--------------------------------------------------------------------------------------------------------------------------------------

 

Forrás:

http://www.hut.fi/~then/mytexts/mouse.html, Tomi Engdahl

http://www.geocities.com/SiliconValley/2151/mouse.html, Mark Feldman

http://www.inwave.com/~ohlandl/mouse.html