| Zeile 356: | Zeile 356: | ||
Die Overflow-Bits geben an, ob die Maus auf der jeweiligen Achse zu schnell bewegt wurden. Die Sign-Bits geben an, ob die jeweiligen Movements negativ sind. Und die Button-Bits geben an, ob die jeweilige Taste gedrückt ist. Der Beispiel-Code, der das Daten-Paket der Maus abholt ist beim Code für den [[#Handler-Code|IRQ12-Handler]] in der Rubrik Anwendung zu finden. | Die Overflow-Bits geben an, ob die Maus auf der jeweiligen Achse zu schnell bewegt wurden. Die Sign-Bits geben an, ob die jeweiligen Movements negativ sind. Und die Button-Bits geben an, ob die jeweilige Taste gedrückt ist. Der Beispiel-Code, der das Daten-Paket der Maus abholt ist beim Code für den [[#Handler-Code|IRQ12-Handler]] in der Rubrik Anwendung zu finden. | ||
| − | < | + | <asm> |
147 irq12-handler: | 147 irq12-handler: | ||
. zum Anschauend des Codes gehe bitte zum IRQ12-Handler in der Rubrik Anwendung (Link in Text oben) | . zum Anschauend des Codes gehe bitte zum IRQ12-Handler in der Rubrik Anwendung (Link in Text oben) | ||
| Zeile 380: | Zeile 380: | ||
302 ret ;zum Abschluss springen wir zum Aufrufsort zurück; das Byte liegt dabei in al und ZF zeigt Erfolg bei 1 an | 302 ret ;zum Abschluss springen wir zum Aufrufsort zurück; das Byte liegt dabei in al und ZF zeigt Erfolg bei 1 an | ||
303 ;************************* wartet eine Weile ob Daten kommen und speichert diese ggf. in al ab ************************* | 303 ;************************* wartet eine Weile ob Daten kommen und speichert diese ggf. in al ab ************************* | ||
| − | </ | + | </asm> |
Besonders interessant ist eig. nur die Prozedur kb.read.mouse, die vom irq12 3x angesprungen wird, um die einzelnen Bytes des Maus-Pakets abzurufen. Der Rest des Codes des IRQ12's speichert diese Bytes, untersucht diese Bytes und verändert die xy-Coordinate des Mauszeigers in den Variablen [x] und [y] entsprechend der Movement- und Sign-Bits. | Besonders interessant ist eig. nur die Prozedur kb.read.mouse, die vom irq12 3x angesprungen wird, um die einzelnen Bytes des Maus-Pakets abzurufen. Der Rest des Codes des IRQ12's speichert diese Bytes, untersucht diese Bytes und verändert die xy-Coordinate des Mauszeigers in den Variablen [x] und [y] entsprechend der Movement- und Sign-Bits. | ||
| Zeile 409: | Zeile 409: | ||
Byte 4, also die Z-Bewegung kann eigentlich nur Werte von -8(1111) bis +7(0000) annehmen und nutzt deswegen eigentlich nur Bit 3-0, die anderen Bits dienen dabei nur als Sign-Extension, also nehmen den Zustand von Bit3 an (man schlage auch mal die Befehle movsx, movzx nach x) ). Dazu noch der Code, der in den Wheel-Mode schaltet, der Code zum abholen sollte klar sein, dass ist der selbe wie bei dem Standard-Paket nur, dass noch per call kb.read.mouse ein Byte mehr abgeholt werden muss. Der COde gibt am Ende noch die ID plus dem Error auf ah aus... dafür die Zeilen 45-47. | Byte 4, also die Z-Bewegung kann eigentlich nur Werte von -8(1111) bis +7(0000) annehmen und nutzt deswegen eigentlich nur Bit 3-0, die anderen Bits dienen dabei nur als Sign-Extension, also nehmen den Zustand von Bit3 an (man schlage auch mal die Befehle movsx, movzx nach x) ). Dazu noch der Code, der in den Wheel-Mode schaltet, der Code zum abholen sollte klar sein, dass ist der selbe wie bei dem Standard-Paket nur, dass noch per call kb.read.mouse ein Byte mehr abgeholt werden muss. Der COde gibt am Ende noch die ID plus dem Error auf ah aus... dafür die Zeilen 45-47. | ||
| − | < | + | <asm> |
71 mov al,0F3h ;Befehl zum senden und neu setzen der SampleRate auf al schieben | 71 mov al,0F3h ;Befehl zum senden und neu setzen der SampleRate auf al schieben | ||
72 call kb.write.mouse ;und per vordefinierter Prozedur an die Maus senden | 72 call kb.write.mouse ;und per vordefinierter Prozedur an die Maus senden | ||
| Zeile 428: | Zeile 428: | ||
87 sti ;nun da wir das Byte entgegengenommen haben, können wir die IRQs wieder aktivieren | 87 sti ;nun da wir das Byte entgegengenommen haben, können wir die IRQs wieder aktivieren | ||
88 mov [mouseid],al ;speichere die erhaltene MausID in einer Variable, damit der IRQ12-Handler weiß, ob die Maus ein Rad hat | 88 mov [mouseid],al ;speichere die erhaltene MausID in einer Variable, damit der IRQ12-Handler weiß, ob die Maus ein Rad hat | ||
| − | </ | + | </asm> |
| − | < | + | <asm> |
304 .write.mouse: | 304 .write.mouse: | ||
305 push ax ;al sichern, da dort der zu sendende Befehl gesichert ist | 305 push ax ;al sichern, da dort der zu sendende Befehl gesichert ist | ||
| Zeile 444: | Zeile 444: | ||
315 ret ;verlasse Prozedur und springe zumi Aufruf zurück | 315 ret ;verlasse Prozedur und springe zumi Aufruf zurück | ||
316 ;******* Prozedur schickt den Befehl per D4h an die Maus und gibt error von kb.read aus (prc succesfull if ah=0 und al=FAh sein) ********* | 316 ;******* Prozedur schickt den Befehl per D4h an die Maus und gibt error von kb.read aus (prc succesfull if ah=0 und al=FAh sein) ********* | ||
| − | </ | + | </asm> |
=== Wheel-and-5-Button-Mode-Packet === | === Wheel-and-5-Button-Mode-Packet === | ||
| Zeile 478: | Zeile 478: | ||
Das Programm hakt sich in den IRQ12 ein, der auf den INT74h sein sollte, ansonsten muss diese Zeile geändert werden: | Das Programm hakt sich in den IRQ12 ein, der auf den INT74h sein sollte, ansonsten muss diese Zeile geändert werden: | ||
| − | < | + | <asm> |
13 mov [es:74h*4+2],cs ;und dann an den Eintrag für den Int74h/IRQ12 das Segment | 13 mov [es:74h*4+2],cs ;und dann an den Eintrag für den Int74h/IRQ12 das Segment | ||
14 mov [es:74h*4],word irq12 ;und den Offset des Int-Handlers speichern | 14 mov [es:74h*4],word irq12 ;und den Offset des Int-Handlers speichern | ||
| − | </ | + | </asm> |
=== Maus im Stream-Modus aktivieren === | === Maus im Stream-Modus aktivieren === | ||
| Zeile 487: | Zeile 487: | ||
Nun da der Handler installiert ist, müssen wir die Maus immernoch dazu bringen ihre Daten an diesen zu senden, dies geschieht mit folgenden Befehlszeilen, in denen in dieser Reihenfolge erst dem KBC gesagt wird, dass er die Maus aktivieren soll, danach der Maus selber gesagt, dass sie sich aktivieren soll und zuletzt im CommanByte des KBC das ansprignen des IRQ12 bei Daten aktiviert wird. | Nun da der Handler installiert ist, müssen wir die Maus immernoch dazu bringen ihre Daten an diesen zu senden, dies geschieht mit folgenden Befehlszeilen, in denen in dieser Reihenfolge erst dem KBC gesagt wird, dass er die Maus aktivieren soll, danach der Maus selber gesagt, dass sie sich aktivieren soll und zuletzt im CommanByte des KBC das ansprignen des IRQ12 bei Daten aktiviert wird. | ||
| − | < | + | <asm> |
18 mov al,0a8h ;schiebe auf al den Befehl zur Aktivierung der Maus | 18 mov al,0a8h ;schiebe auf al den Befehl zur Aktivierung der Maus | ||
19 out 64h,al ;schicke den Befehl an den Keyboard-Controller | 19 out 64h,al ;schicke den Befehl an den Keyboard-Controller | ||
| Zeile 515: | Zeile 515: | ||
43 out 60h,al ;und schicke das Command-Byte an den Daten-Port 60h, durch den Befehl 60h wird dieses neu eingelesen | 43 out 60h,al ;und schicke das Command-Byte an den Daten-Port 60h, durch den Befehl 60h wird dieses neu eingelesen | ||
44 call kb.checkcmd ;und warte, bis das Byte vollständig angenommen wurde | 44 call kb.checkcmd ;und warte, bis das Byte vollständig angenommen wurde | ||
| − | </ | + | </asm> |
=== Rad und/oder 5 Tasten-Modus aktivieren === | === Rad und/oder 5 Tasten-Modus aktivieren === | ||
| Zeile 521: | Zeile 521: | ||
Nachdem der Handler installiert ist und die Maus eingeschalten ist, prüft es, ob die Maus ein Rad und/oder 5 Tasten hat, dies geshieht mit folgenden Zeilen, in dem es die gerade eben besprochenen Sample-Rate-Sequenzen durchführt und dann die ID in eine Variable speichert, die der Int-Handler ausliest um zu wissen, ob er nun 3 oder 4 Bytes holen soll: | Nachdem der Handler installiert ist und die Maus eingeschalten ist, prüft es, ob die Maus ein Rad und/oder 5 Tasten hat, dies geshieht mit folgenden Zeilen, in dem es die gerade eben besprochenen Sample-Rate-Sequenzen durchführt und dann die ID in eine Variable speichert, die der Int-Handler ausliest um zu wissen, ob er nun 3 oder 4 Bytes holen soll: | ||
| − | < | + | <asm> |
46 lea si,[three_button_mode] ;zum debuggen, gibt nachricht aus, dass maus sich | 46 lea si,[three_button_mode] ;zum debuggen, gibt nachricht aus, dass maus sich | ||
47 call write ;im 3-tasten-modus befindet | 47 call write ;im 3-tasten-modus befindet | ||
| Zeile 570: | Zeile 570: | ||
92 call write ; ~ | 92 call write ; ~ | ||
93 .no_5_button_mode | 93 .no_5_button_mode | ||
| − | </ | + | </asm> |
=== PIC - IRQ12 aktivieren === | === PIC - IRQ12 aktivieren === | ||
| Zeile 576: | Zeile 576: | ||
Um nun sicher zu gehen, dass der IRQ12 überhaupt angeschalten ist, schalten wir ihn lieber nocheinmal persönlich mit folgenden Zeilen über den PIC ein: | Um nun sicher zu gehen, dass der IRQ12 überhaupt angeschalten ist, schalten wir ihn lieber nocheinmal persönlich mit folgenden Zeilen über den PIC ein: | ||
| − | < | + | <asm> |
95 in al,0A1h ;hole von dem PIC2 das IMR | 95 in al,0A1h ;hole von dem PIC2 das IMR | ||
96 and al,11101111b ;um darin den IRQ12 zu maskieren, damit er aktiviert wird | 96 and al,11101111b ;um darin den IRQ12 zu maskieren, damit er aktiviert wird | ||
97 out 0A1h,al ;und sende das modifizierte IMR an den Slave | 97 out 0A1h,al ;und sende das modifizierte IMR an den Slave | ||
| − | </ | + | </asm> |
=== Schleife, in der Mauseingaben möglich sind === | === Schleife, in der Mauseingaben möglich sind === | ||
| Zeile 586: | Zeile 586: | ||
Nun da die Maus aktiviert und ein funktionierender IRQ12-Handler installiert sein solte, wartet eine Schleife auf ESC. Solange diese Schleife ausgeführt wird, kann der IRQ12 ja trotzdem den Handler anspringen, also kurz gesagt, solange man sich in folgender Schleife befindet werden alle Bewegungen der Maus abgefangen und grafisch dargestellt. | Nun da die Maus aktiviert und ein funktionierender IRQ12-Handler installiert sein solte, wartet eine Schleife auf ESC. Solange diese Schleife ausgeführt wird, kann der IRQ12 ja trotzdem den Handler anspringen, also kurz gesagt, solange man sich in folgender Schleife befindet werden alle Bewegungen der Maus abgefangen und grafisch dargestellt. | ||
| − | < | + | <asm> |
99 wait_esc: | 99 wait_esc: | ||
100 mov ah,1 ;Funktion 1 des Int16h wählen, um abzufragen, ob ein Tastendruck vorhanden ist | 100 mov ah,1 ;Funktion 1 des Int16h wählen, um abzufragen, ob ein Tastendruck vorhanden ist | ||
| Zeile 596: | Zeile 596: | ||
106 cmp ah,1 ;vergleicht den asciicode mit dem von ESC | 106 cmp ah,1 ;vergleicht den asciicode mit dem von ESC | ||
107 jne wait_esc ;wenn ESC nicht gedrückt wurde, warte auf näcshten Tastendruck | 107 jne wait_esc ;wenn ESC nicht gedrückt wurde, warte auf näcshten Tastendruck | ||
| − | </ | + | </asm> |
=== Maus deaktivieren, Programm beenden === | === Maus deaktivieren, Programm beenden === | ||
| Zeile 602: | Zeile 602: | ||
Wenn die Schleife durch drücken von Esc verlassen wurde, dann lösche als erstes Bit1 im command-Byte des Keyboards, damit das anspringen des IRQ12 bei Daten deaktiviert wird.^ | Wenn die Schleife durch drücken von Esc verlassen wurde, dann lösche als erstes Bit1 im command-Byte des Keyboards, damit das anspringen des IRQ12 bei Daten deaktiviert wird.^ | ||
| − | < | + | <asm> |
109 cli ;alle Interrupts auschalten, damit nicht unser Keyboard-Int das gesendete Byte erhält xD | 109 cli ;alle Interrupts auschalten, damit nicht unser Keyboard-Int das gesendete Byte erhält xD | ||
110 mov al,20h ;Befehl zum auslesen des Kommando-Bytes auf al schieben | 110 mov al,20h ;Befehl zum auslesen des Kommando-Bytes auf al schieben | ||
| Zeile 621: | Zeile 621: | ||
125 out 60h,al ;und schicke das Command-Byte an den Daten-Port 60h, durch den Befehl 60h wird dieses neu eingelesen | 125 out 60h,al ;und schicke das Command-Byte an den Daten-Port 60h, durch den Befehl 60h wird dieses neu eingelesen | ||
126 call kb.checkcmd ;und warte, bis das Byte vollständig angenommen wurde | 126 call kb.checkcmd ;und warte, bis das Byte vollständig angenommen wurde | ||
| − | </ | + | </asm> |
Danach wird einfach nur noch ein mal die Maus selber deaktiviert, danach wird dem Keyboard-Controller gesagt, dass diese deaktiviert wird und zuletzt wird der IRQ12 im PIC wieder maskiert. Am Ende der Ende-Sequenz wird mit "retf" zu meinem Kernel zurückgesprungen. Retf sollte man je nach seinem eigenen OS anpassen. | Danach wird einfach nur noch ein mal die Maus selber deaktiviert, danach wird dem Keyboard-Controller gesagt, dass diese deaktiviert wird und zuletzt wird der IRQ12 im PIC wieder maskiert. Am Ende der Ende-Sequenz wird mit "retf" zu meinem Kernel zurückgesprungen. Retf sollte man je nach seinem eigenen OS anpassen. | ||
| − | < | + | <asm> |
128 mov al,0F5h ;auf al den Befehl zum deaktivieren der Maus selbst schieben | 128 mov al,0F5h ;auf al den Befehl zum deaktivieren der Maus selbst schieben | ||
129 call kb.write.mouse ;und an die Maus senden | 129 call kb.write.mouse ;und an die Maus senden | ||
| Zeile 638: | Zeile 638: | ||
138 | 138 | ||
139 retf ;springe zum Kernel zurück | 139 retf ;springe zum Kernel zurück | ||
| − | </ | + | </asm> |
=== Programm Konzept === | === Programm Konzept === | ||
| Zeile 689: | Zeile 689: | ||
Joa und in Assembler würde das wie folgt aussehen: | Joa und in Assembler würde das wie folgt aussehen: | ||
| − | < | + | <asm> |
141 ;*************************************************************************************************************** | 141 ;*************************************************************************************************************** | ||
142 ;dies ist der IRQ12, der immer angesprungen wird, wenn sich die Daten der Maus verändert habe (sofern der Stream-Mode benutzt wird) | 142 ;dies ist der IRQ12, der immer angesprungen wird, wenn sich die Daten der Maus verändert habe (sofern der Stream-Mode benutzt wird) | ||
| Zeile 791: | Zeile 791: | ||
240 actualb db 0 ;hier wird gespeichert, welche bytes des Maus-Daten-Pakets schon abgeholt wurden (für jedes Byte wird der IRQ12 | 240 actualb db 0 ;hier wird gespeichert, welche bytes des Maus-Daten-Pakets schon abgeholt wurden (für jedes Byte wird der IRQ12 | ||
241 ;einzeln angesprungen) | 241 ;einzeln angesprungen) | ||
| − | </ | + | </asm> |
=== Die Ausgabe-Prozedur === | === Die Ausgabe-Prozedur === | ||
| Zeile 797: | Zeile 797: | ||
Wie schon erwähnt wird evtl. hier noch etwas am Abholen und Interpretieren modifiziert, aber ich wollte euch nicht warten lassen, da ich erst ein externes Disketten-Laufwerk bei Amazon bestellen muss ;). Doch weiter gehts. Zum Schluss möchte ich es wenigstens versuchen euch einen Ansatz zu geben, wie man sich am besten in die Visualisierungs-Prozedur hineinzuversetzen hat, denn auch wenn alles kommentiert ist, ist das ein bisschen schwierig meinen genauen Gedankengang dabei festzuhalten. Das ganze funktioniert, indem das Bild und die Daten und Co alles gleich in den Bildschirmspeicher geschrieben wird. Der Bildschrimspeicher, also die Addressen sind alle darauf eingestellt, dass der momentan VideoModus 03h ist, also 80 Zeichen Zeilenlänge bei 25 Zeilen pro Bildschirm hat. So fängt der Bildschirmspeicher im 03h-Modus am segment 0B800h im Speicher an. Der Speicher selber ist 4000Bytes groß, für jedes Zeichen 2 Bytes, eins für das Attribut des Zeichen wie Hintergrund- und Schriftfarbe und eins, wo das Char gespeichert ist, macht bei 25 Zeilen*80 Zeichen*2 Bytes=4000Byte. Das ganze sei an einer Befehlszeile verdeutlicht: | Wie schon erwähnt wird evtl. hier noch etwas am Abholen und Interpretieren modifiziert, aber ich wollte euch nicht warten lassen, da ich erst ein externes Disketten-Laufwerk bei Amazon bestellen muss ;). Doch weiter gehts. Zum Schluss möchte ich es wenigstens versuchen euch einen Ansatz zu geben, wie man sich am besten in die Visualisierungs-Prozedur hineinzuversetzen hat, denn auch wenn alles kommentiert ist, ist das ein bisschen schwierig meinen genauen Gedankengang dabei festzuhalten. Das ganze funktioniert, indem das Bild und die Daten und Co alles gleich in den Bildschirmspeicher geschrieben wird. Der Bildschrimspeicher, also die Addressen sind alle darauf eingestellt, dass der momentan VideoModus 03h ist, also 80 Zeichen Zeilenlänge bei 25 Zeilen pro Bildschirm hat. So fängt der Bildschirmspeicher im 03h-Modus am segment 0B800h im Speicher an. Der Speicher selber ist 4000Bytes groß, für jedes Zeichen 2 Bytes, eins für das Attribut des Zeichen wie Hintergrund- und Schriftfarbe und eins, wo das Char gespeichert ist, macht bei 25 Zeilen*80 Zeichen*2 Bytes=4000Byte. Das ganze sei an einer Befehlszeile verdeutlicht: | ||
| − | < | + | <asm> |
01 mov [es:100], word 1234h | 01 mov [es:100], word 1234h | ||
| − | </ | + | </asm> |
Diese Zeile würde an die Stelle 0;50 auf den Bildschirm eine grüne 4 auf blauem Hintergrund ausgeben. Der Hintergrund ist blau, weil die "1" dies so sagt, bei 2 gilt das für den Vordergrund und 34h ist wie schon gesagt das Zeichen selber. Das wäre es dann auch schon, mehr kann ich dazu einfach nicht sagen, versucht euch einfach in die Prozedur hineinzuversetzen, ein bisschen rumzuspielen und die eigenartige Adressierungen durchzudenken. Und hier ist die langersehnte Prozedur zum veranschaulichen des Pakets xD: | Diese Zeile würde an die Stelle 0;50 auf den Bildschirm eine grüne 4 auf blauem Hintergrund ausgeben. Der Hintergrund ist blau, weil die "1" dies so sagt, bei 2 gilt das für den Vordergrund und 34h ist wie schon gesagt das Zeichen selber. Das wäre es dann auch schon, mehr kann ich dazu einfach nicht sagen, versucht euch einfach in die Prozedur hineinzuversetzen, ein bisschen rumzuspielen und die eigenartige Adressierungen durchzudenken. Und hier ist die langersehnte Prozedur zum veranschaulichen des Pakets xD: | ||
| − | < | + | <asm> |
369 ;*************************************************************************************** | 369 ;*************************************************************************************** | ||
370 ;Display-Mouse -> eine ganz spezifische Prozedur, die die Daten des Mouse-Packets vernaschaulicht | 370 ;Display-Mouse -> eine ganz spezifische Prozedur, die die Daten des Mouse-Packets vernaschaulicht | ||
| Zeile 833: | Zeile 833: | ||
584 popad ;dann stelle die Register wieder her | 584 popad ;dann stelle die Register wieder her | ||
585 ret ;und kehre zum Aufrufsort zurück | 585 ret ;und kehre zum Aufrufsort zurück | ||
| − | </ | + | </asm> |
== Schlusswort == | == Schlusswort == | ||
| Zeile 840: | Zeile 840: | ||
Soviel von mir, für Fragen per ICQ(412207644) stehe ich gerne zur Verfügung.<br> | Soviel von mir, für Fragen per ICQ(412207644) stehe ich gerne zur Verfügung.<br> | ||
| − | |||
Das Original dieses Dokuments ist auch [http://maxinator.meugster.net/index2.php?site=http://maxinator.meugster.net/programming/ps2mouse/00600064mouse.html hier] zu finde und stammt von mir. | Das Original dieses Dokuments ist auch [http://maxinator.meugster.net/index2.php?site=http://maxinator.meugster.net/programming/ps2mouse/00600064mouse.html hier] zu finde und stammt von mir. | ||
--[[Benutzer:Maxinator|Maxinator]] 22:03, 11. Nov 2007 (CET) | --[[Benutzer:Maxinator|Maxinator]] 22:03, 11. Nov 2007 (CET) | ||