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