PS/2-Maus — Änderungen 8030 → 8320

Zeile 1: Zeile 1:
−
== Beschreibung ==
+
Die "Maus" zählt zu den '''Human Interface Devices''', dient also als Schnittstelle zwischen dem Computer und dem Menschen.
  
−
So, wie ich daraus schließe, dass ihr das hier lest, seid ihr sicher schon ganz versessen darauf zu erfahren, wie die PS/2-Maus zu programmieren geht, mir jedenfalls ging es so, als mir vor kurzen ein funktionierendes PS/2-Maus-Assembler-Skript in die Hände gefallen ist :). Die PS/2-Maus teilt sich zusammen mit dem Keyboard eine Schnittstelle, die PS/2-Schnittstelle, wie ihr euch sicher denken könnt xD.
+
== Funktionsweise ==
 +
Die Maus teilt sich mit dem Keyboard die gleiche Schnittstelle, die PS/2-Schnittstelle. Damit unterschieden werden kann, welcher Befehl für welches Gerät ist, ist bei der Übertragung entweder das fünfte Bit im 54h-Status-Byte gesetzt (dann ist der Befehl für die Maus) oder nicht (dann ist der Befehl für die Tastatur).
  
−
Doch, wenn die beiden sich eine Schnittstelle teilen, wie sollen dann die beiden wissen, welche Commands/Befehle für wen gedacht sind? Eigentlich ist das ja relativ einfach, denn vor jedem Befehl, der an die Maus gehen soll, muss ein Befehl an den Tastatur-Kontroller geschickt werden, dem man damit mitteilt, das der nächste Befehle für die Maus bestimmt ist. Genauso muss auch beim Auslesen der Daten darauf geachtet werden, dass wenn das Bit5 im 54h-Status-Byte gesetzt ist, das nächste auszulesende Byte im Port 60h von der Maus ist.
 
−
 
−
Das zur kurzen Einführung, jetzt kommen die Spezifikationen des PS/2-Ports, wobei ich [[#Spezifikationen|hier]] alle Befehle und Spezifikationen aufgelistet habe, also auch die für die Tastatur. Eigentlich werden trotzdem alle Tabellen außer der, die alle TastaturBefehle aufgelistet hat (60h), für das Arbeiten mit der Maus benötigt und Tabellen nur teils teils aufzuführen, möchte ich auch nicht, da ich ein ordentlicher Mensch bin und es mich stören würde, wenn die Hälfte der Spezifikationen im Maus- und die andere Hälfte im Tastatur-Tutorial liegen würden.
 
−
 
−
Ich empfehle den meisten erst einmal die Spezifikationen nur zu überfliegen und sie sich dann genauer anzuschauen, wenn diese Anhand des Quelltextes beschrieben werden. Leider konnte ich nicht zu jeden Befehl eine 100%-ige Beschreibung anfertigen, da ich noch nicht das vergnügen hatte, diesen zu testen.
 
−
 
−
[http://maxinator.meugster.net/programming/ps2mouse/ps2mouse.asm Download des Codes]
 
  
 
== Spezifikationen ==
 
== Spezifikationen ==
−
 
 
=== Der PS/2-Port und der KBC ===
 
=== Der PS/2-Port und der KBC ===
  
Zeile 19: Zeile 12:
 
! Port || Zugriff || Beschreibung
 
! Port || Zugriff || Beschreibung
 
|-
 
|-
−
|'''60h''' || ''Lesezugriff'' || Der Port 60h ist zweiseitig, er kann als Keyboard-Controller(64h)-Daten-Port oder als Keyboard-In-/Output-Buffer dienen. An diesen Port werden die Scancodes der gedrückten Tasten gesendet, die dann der Keyboard-Treiber per "in al,60h" auslesen kann. Deaktiviert man bevor man aus diesem Port etwas ausliest das Keybord per Befehl ADh, so erhält man die Daten aus dem Maus-Output-Buffer!
+
|'''60h''' || ''Lesezugriff'' || Der Port 60h ist zweiseitig, er kann als Keyboard-Controller(64h)-Daten-Port oder als Keyboard-In-/Output-Buffer dienen. An diesen Port werden die Scancodes der gedrückten Tasten gesendet, die dann der Keyboard-Treiber per "in al,60h" auslesen kann. Deaktiviert man bevor man aus diesem Port etwas ausliest das Keybord per Befehl ADh, so erhält man die Daten aus dem Maus-Output-Buffer.
  
−
Zum auslesen sei gesagt, dass die nur geschehen sollte, wenn entweder das Bit 1 im Keyboard-Controller-Output-Status-Byte, welches anzeigt, dass das Keyboard am 60h Daten hat, oder das Bit 5 in diesem Status-Byte des 64h gesetzt ist, welches anzeigt, dass im Maus-Output-Buffer Daten liegen! Um das zu realisieren habe ich in meinem Programm ein Schleife genutzt, die eine Zeit lang abfragt, ob Daten da sind.
+
Zum Auslesen sei gesagt, dass dies nur geschehen sollte, wenn entweder das erste Bit im Keyboard-Controller-Output-Status-Byte, welches anzeigt, dass das Keyboard an 60h Daten sendet, oder das fünfte Bit in diesem Status-Byte des 64h gesetzt ist, welches anzeigt, dass im Maus-Output-Buffer Daten liegen.  
 
|-
 
|-
−
|  || ''Schreibzugriff'' || Wenn an diesen Port geschrieben werden, fungiert dieser entweder als Keyboard-Controller-Daten-Port, oder als Input-Buffer des Keyboards. Zweiteres geschieht, wenn man einfach einen der Befehle, die weiter unten für diesen Port aufgelistet sind, an diesen Port sendet. Dies sind überwiegend Befehle zu adjustierung des Keyboards, wie z.b. das Einstellen der Typematic-Rate.
+
|  || ''Schreibzugriff'' || Wenn an diesen Port geschrieben wird, fungiert dieser entweder als Keyboard-Controller-Daten-Port, oder als Input-Buffer des Keyboards. Zweiteres geschieht, wenn man einfach einen der Befehle, die weiter unten für diesen Port aufgelistet sind, an diesen Port sendet. Dies sind überwiegend Befehle zu adjustierung des Keyboards, wie z.b. das Einstellen der Typematic-Rate.
  
−
Als Ersteres, also als Daten-Port des KC, wird dieser Port nur genutzt, wenn es Befehle des 64h verlangen. So muss an z.b. den Befehl "60h" für das Senden eines neuen Commado-Bytes zwar an den Port 64h senden, doch das Commando-Byte, was dann nach korrekter Annahme des Befehls gesendet werden muss, muss an den Port 60h gesendet werden!
+
Als Ersteres, also als Daten-Port des KBC, wird dieser Port nur genutzt, wenn es Befehle des 64h verlangen. So muss an z.b. den Befehl "60h" für das Senden eines neuen Commado-Bytes zwar an den Port 64h senden, doch das Commando-Byte, was dann nach korrekter Annahme des Befehls gesendet werden muss, muss an den Port 60h gesendet werden.
  
−
Für die möglichen Befehle, die an das Keyboard gesendet werden können, siehe [[#60hcmds|hier]]. Für die möglichen Mausbefehle, die an diesen Port geschickt werden können, jedoch den Befehl "D4h" auf Port 64h voraussetzen, siehe [[#60hmouse|hier]]. Für die KC-Befehle, die ein zweites Daten-Byte an diesen Port geschickt verlangen, sie auch [[#64hcmds|hier]].
+
Für die möglichen Befehle, die an das Keyboard gesendet werden können, siehe [[#60hcmds|hier]]. Für die möglichen Mausbefehle, die an diesen Port geschickt werden können, jedoch den Befehl "D4h" auf Port 64h voraussetzen, siehe [[#60hmouse|hier]]. Für die KBC-Befehle, die ein zweites Daten-Byte an diesen Port geschickt verlangen, sie auch [[#64hcmds|hier]].
 
|-
 
|-
−
| '''64h''' || ''Lesezugriff'' || Das Lesen für diesen Port ist sehr wichtig, wenn man den Keyboard-Controller programmieren will, da man beim Lesen das Status-Byte des KC bekommt, welches z.b. anzeigt, ob gerade Daten zum abholen verfügbar sind, oder ob der letzte Befehl SCHON vollständig verarbeitet wurde!
+
| '''64h''' || ''Lesezugriff'' || Das Lesen für diesen Port ist sehr wichtig, wenn man den Keyboard-Controller programmieren will, da man beim Lesen das Status-Byte des KBC bekommt, welches z.b. anzeigt, ob gerade Daten zum abholen verfügbar sind, oder ob der letzte Befehl bereits vollständig verarbeitet wurde.
  
 
Für die Bitfields des Statusbytes siehe [[#64hread|hier]]
 
Für die Bitfields des Statusbytes siehe [[#64hread|hier]]
 
|-
 
|-
−
|  || ''Schreibzugriff'' || Beim Schreibzugriff an diesen Port fungiert dieser als Keyboard-Controller-Input-Buffe, sodass eine Reihe von Byte-großen Befehlen gesendet werden können, die zumeist das System des Keyboards beeinflussen, so muss man auch an diese Port den Befehl "D4h" senden, um den nächsten Befehl, der zum Keyboard-Port(60h) geht, an die Maus senden zu lassen.
+
|  || ''Schreibzugriff'' || Beim Schreibzugriff an diesen Port fungiert dieser als Keyboard-Controller-Input-Buffer, sodass eine Reihe von Byte-großen Befehlen gesendet werden können, die zumeist das System des Keyboards beeinflussen, so muss man auch an diese Port den Befehl "D4h" senden, um den nächsten Befehl, der zum Keyboard-Port(60h) geht, an die Maus senden zu lassen.
 
Eine Reihe von Befehlen ist [[#64hcmds|hier]] aufgelistet.
 
Eine Reihe von Befehlen ist [[#64hcmds|hier]] aufgelistet.
 
|}
 
|}
Zeile 43: Zeile 36:
 
{| {{prettytable}}
 
{| {{prettytable}}
 
|-
 
|-
−
|+ Dies ist die Liste der Befehle, die an den Keyboard-Input-Buffer (60h) gesendet werden können.<br>Werden 2 Bytes verlangt, wird das zweite auch an den Port 60h gesendet.
+
|+ Dies ist die Liste der Befehle, die an den Keyboard-Input-Buffer (60h) gesendet werden können.
 +
Werden zwei Bytes verlangt, wird das Zweite auch an den Port 60h gesendet.
 
|-
 
|-
 
! Befehl || Größe || Beschreibung
 
! Befehl || Größe || Beschreibung
Zeile 49: Zeile 43:
 
| ''EEh'' || 1 Byte || Dieser Befehl sendet zur Diagnostik EEh an den Port 60h.
 
| ''EEh'' || 1 Byte || Dieser Befehl sendet zur Diagnostik EEh an den Port 60h.
 
|-
 
|-
−
| ''F0h'' || 2 Bytes || Mit diesem Befehl kann abhängig vom zweiten Byte das Scancode Set entweder gesetzt oder abgerufen werden
+
| ''F0h'' || 2 Bytes || Mit diesem Befehl kann, abhängig vom zweiten Byte das Scancode Set, entweder gesetzt oder abgerufen werden
−
Das Format des zweiten Byte:
+
Das Format des zweiten Bytes:
 
: 00h - holt den aktuellen Scancode Set ab, sodass dieser an den Port 60h gesendet wird
 
: 00h - holt den aktuellen Scancode Set ab, sodass dieser an den Port 60h gesendet wird
 
: 01h - scancode set 1 (PCs and PS/2 mod 30, except Type 2 ctrlr)
 
: 01h - scancode set 1 (PCs and PS/2 mod 30, except Type 2 ctrlr)
Zeile 101: Zeile 95:
 
| ''FFh'' || 1 Byte || perform internal power-on reset function
 
| ''FFh'' || 1 Byte || perform internal power-on reset function
 
|-
 
|-
−
|+ Note: Jeder Befehl wird durch das senden von FAh (ACK) an den Port 60h bestätigt, und achtung, denn bei Befehlen, die aus 2 Bytes bestehen, wird jedes<br>
+
|+ Hinweis: Jeder Befehl wird durch das Senden von FAh (ACK) an den Port 60h bestätigt. Besteht ein Befehl aus zwei Bytes, so wird jedes eizelne Byte bestätigt.
−
Byte einzeln bestätigt, für andere SpecialCodes siehe hier
 
 
|}
 
|}
  
Zeile 111: Zeile 104:
 
{| {{prettytable}}
 
{| {{prettytable}}
 
|-
 
|-
−
|+ Dies ist die Liste der Befehle, die zur Adjustierung der Maus dienen. Bevor einer dieser Befehle an den Port 60h gesendet werden kann, muss zuerst per<br>"D4h" an den Port 64h, dem Controller gesagt werden, dass das nächste Byte, also eins aus dieser Liste, auch an die Maus gesendet wird. Wir "D4h" nicht<br>zuvor verwendet würde der Befehl an die Tastatur und nicht die Maus gehen.<br>ACHTUNG: Bei 2 Byte großen Befehlen muss auch vor dem senden des 2. Bytes dies mit "D4h" initiiert werden.
+
|+ Dies ist die Liste der Befehle, die zur Adjustierung der Maus dienen. Bevor einer dieser Befehle an den Port 60h gesendet werden kann, muss zuerst per "D4h" an den Port 64h, dem Controller gesagt werden, dass das nächste Byte, also eins aus dieser Liste, auch an die Maus gesendet wird. Wir "D4h" nicht zuvor verwendet, würde der Befehl an die Tastatur und nicht die Maus gehen. '''Achtung''': Bei zwei Byte großen Befehlen muss auch vor dem Senden des zweiten Bytes dies mit "D4h" initiiert werden.
 
|-
 
|-
 
! Befehl || Größe || Beschreibung
 
! Befehl || Größe || Beschreibung
Zeile 139: Zeile 132:
 
| ''EAh'' || 1 Byte || Versetze Maus in den Stream-Modus. In diesem aktiviert die Maus bei jeder Änderung den IRQ12, sodass dieser die Daten auslesen kann
 
| ''EAh'' || 1 Byte || Versetze Maus in den Stream-Modus. In diesem aktiviert die Maus bei jeder Änderung den IRQ12, sodass dieser die Daten auslesen kann
 
|-
 
|-
−
| ''EBh'' || 1 Byte || Hole Maus-Data-Paket. sollte nur genutzt werden, wenn der Remote-Modus gesetzt ist. Für eine Beschreibung des Pakets, siehe [[#Das_Maus-Daten-Packet|hier]]
+
| ''EBh'' || 1 Byte || Hole Maus-Data-Paket. Sollte nur genutzt werden, wenn der Remote-Modus gesetzt ist. Für eine Beschreibung des Pakets, siehe [[#Das_Maus-Daten-Packet|hier]]
 
|-
 
|-
−
| ''ECh'' || 1 Byte || Versetze Maus aus den Wrap-Modus wieder in den normlen. Der Wrap-Modus ist zur Fehleranalyse gedacht und echoet jeden Befehl, statt
+
| ''ECh'' || 1 Byte || Versetze Maus aus den Wrap-Modus wieder in den normalen Modus. Der Wrap-Modus ist zur Fehleranalyse gedacht und echoet jeden Befehl, statt ihn mit FAh zu bestätigen.
−
ihn mit FAh zu bestätigen.
 
 
|-
 
|-
 
| ''EEh'' || 1 Byte || Betrete Wrap-Mouds
 
| ''EEh'' || 1 Byte || Betrete Wrap-Mouds
Zeile 156: Zeile 148:
 
: 3Ch=60/s
 
: 3Ch=60/s
 
|-
 
|-
−
| ''F4h'' || 1 Byte || Aktiviere die Maus und setze den Modus auf Stream. (in diesem Modus wird bei jeder Veränderung der IRQ12 aufgerufen)
+
| ''F4h'' || 1 Byte || Aktiviere die Maus und setze den Modus auf Stream. In diesem Modus wird bei jeder Veränderung der IRQ12 aufgerufen
 
|-
 
|-
−
| ''F5h'' || 1 Byte || Deaktivier die Maus im Stream-Modus und setze die vorgegebenen Parameter
+
| ''F5h'' || 1 Byte || Deaktivierz die Maus im Stream-Modus und setze die vorgegebenen Parameter
 
|-
 
|-
−
| ''F6h'' || 1 Byte || Stelle alles auf die Vorgaben zurück -> StramMode, 4/mm-Maus-Resolution, Scaling 1:1, 100/s-Sample-Rate
+
| ''F6h'' || 1 Byte || Stelle alles auf die Vorgaben zurück -> StreamMode, 4/mm-Maus-Resolution, Scaling 1:1, 100/s-Sample-Rate
 
|-
 
|-
−
| ''FEh'' || 1 Byte || Sende nocheinmal das letzte Maus-Data-Paket (für Beschreibung des Pakets siehe [[#Das_Maus-Daten-Packet|hier]])
+
| ''FEh'' || 1 Byte || Sende das letzte Maus-Data-Paket erneut (für Beschreibung des Pakets siehe [[#Das_Maus-Daten-Packet|hier]])
 
|-
 
|-
 
| ''FFh'' || 1 Byte || Reset Maus
 
| ''FFh'' || 1 Byte || Reset Maus
 
|-
 
|-
−
|+ Notiz: Um es zur Sicherheit wiederholen, vor jeden diser Befehle muss "D4h" an den Port 64h geschickt werden. Alle Befehle werden entweder per FAh(ACK)
+
|+ Notiz: Vor jedem dieser Befehle muss "D4h" an den Port 64h geschickt werden. Alle Befehle werden entweder per FAh(ACK)
−
oder FEh(Resend) aktzeptiert. Ausnahmen hierbei sind ECh, F2h, FFh. Obowhl das mit den Ausnahmen anscheinend nicht stimmt(entnommen ralf Browns interrupt
+
oder FEh(Resend) aktzeptiert. Ausnahmen hierbei sind ECh, F2h, FFh, wobei F2h ein Sonderfall unter den Ausnahmen ist: Es schickt erst FAh und dann 00h.
−
list), denn bei mir hat F2h erst FAh und dann EXTRA noch 00h gesendet!
 
 
|}
 
|}
  
  
−
==== SpecialCodes als Rückgabe von Befehlen (60h) ====
+
==== Spezial-Codes als Rückgabe von Befehlen (60h) ====
  
 
<span id="spcs"></span>
 
<span id="spcs"></span>
 
{| {{prettytable}}
 
{| {{prettytable}}
 
|-
 
|-
−
|+ SpecialCode Liste - SpecialCodes werden an den Port 60h nach Befehlen geschickt
+
|+ Spezial-Code Liste - Spezial-Codes werden an den Port 60h nach Befehlen geschickt
 
|-
 
|-
 
! '''Code''' || '''Beschreibung'''
 
! '''Code''' || '''Beschreibung'''
Zeile 183: Zeile 174:
 
| ''00h'' || (Maus) ID
 
| ''00h'' || (Maus) ID
 
|-
 
|-
−
| ''9Ch'' || Dieser Code wurde MIR geschickt, als ich die maus in den Streaminig-Mode geschickt habe, bevor ich den IRQ12-INT-Vektor
+
| ''9Ch'' || Dieser Code wird empfangen, wenn die Maus in den Streaming-Modus geschickt wurde, bevor ein Handler für den IRQ 12 initialisiert wurde.  
−
auf meinen IntHandler gesetzt hatte. ich schlussfolgere daraus mal, dass dieser Code gesendet wird, wenn am IRQ12-Interrupt ein
 
−
ungültiger Vektor angegeben ist, den die Maus anpingen könnte(im streaming Modus sendet die Maus ja bei jeder veränderung die
 
−
Veränderung an den IRQ12, wenn dies im Command Byte aktiviert ist)
 
 
|-
 
|-
 
| ''AAh'' || BAT completion code (sent after errorfree Basic Assurance Test)
 
| ''AAh'' || BAT completion code (sent after errorfree Basic Assurance Test)
 
|-
 
|-
−
| ''ABh'' || das ist das erste der zwei Bytes, die bei MF2-Keyboards als ID geliefert werden (siehe Befehl F2h)
+
| ''ABh'' || Das erste der zwei Bytes, die bei MF2-Keyboards als ID geliefert werden (siehe Befehl F2h)
 
|-
 
|-
 
| ''EEh'' || Wird als Echo bei der Selbstdiagnostik zurückgegeben (siehe Befehl EEh)
 
| ''EEh'' || Wird als Echo bei der Selbstdiagnostik zurückgegeben (siehe Befehl EEh)
Zeile 205: Zeile 193:
 
| ''FEh'' || dieser Befehl sagt, dass letzte Befehl nocheinmal gesendet werden soll
 
| ''FEh'' || dieser Befehl sagt, dass letzte Befehl nocheinmal gesendet werden soll
 
|-
 
|-
−
|+ Notiz: Bei den SpecialCodes FCh und FDh hört das Keayboard erstneinmal mit dem selftest auf und wartet auf den nächsten Befehl
+
|+ Notiz: Bei den Spezial-Codes FCh und FDh hört das KBC mit dem Selftest auf und wartet auf nächste Befehle
 
|}
 
|}
  
Zeile 221: Zeile 209:
 
| width="12.5%" style="background:lightgrey" |  
 
| width="12.5%" style="background:lightgrey" |  
 
| width="12.5%" style="background:lightgrey" |  
 
| width="12.5%" style="background:lightgrey" |  
−
| width="12.5%" | Es liegen keine Daten für uns bereit
+
| width="12.5%" | Es liegen keine Daten für bereit
 
| width="12.5%" | Keyboard verfügbar
 
| width="12.5%" | Keyboard verfügbar
 
| width="12.5%" | Das letzte geschriebene Byte waren Daten und gingnen an den Port 60h
 
| width="12.5%" | Das letzte geschriebene Byte waren Daten und gingnen an den Port 60h
 
| width="12.5%" | power up or reset
 
| width="12.5%" | power up or reset
−
| width="12.5%" | Der Input-Buffer ist leer und alle Befehle sind verarbeitet, nun können wir einen Befehl senden
+
| width="12.5%" | Der Input-Buffer ist leer und alle Befehle sind verarbeitet, nun kann ein Befehl gesendet werden
 
| width="12.5%" | Es liegen keine Daten bereit und es sollte somit auch noch nichts aus dem Port 60h ausgelesen werden
 
| width="12.5%" | Es liegen keine Daten bereit und es sollte somit auch noch nichts aus dem Port 60h ausgelesen werden
 
|- valign='top'
 
|- valign='top'
Zeile 236: Zeile 224:
 
| Selftest OK
 
| Selftest OK
 
| Der Input-Buffer hat noch Daten, also es liegt noch der zuletzt gesendete Befehl in 60h/64h und wartet auf seine Verarbeitung
 
| Der Input-Buffer hat noch Daten, also es liegt noch der zuletzt gesendete Befehl in 60h/64h und wartet auf seine Verarbeitung
−
| Im OutputBuffer befinden sich Daten für den User. Im Sourcecode wird dies genutzt um auf das Ergebnis einer Operation zu warten
+
| Im OutputBuffer befinden sich Daten für den User.  
 
|}
 
|}
  
Zeile 244: Zeile 232:
 
{| {{prettytable}}
 
{| {{prettytable}}
 
|-
 
|-
−
|+ Dies ist die Liste der Befehle, die an den Keyboard-Controller (64h) gesendet werden können.<br>
+
|+ Dies ist die Liste der Befehle, die an den Keyboard-Controller (64h) gesendet werden können.
−
Werden 2 Bytes verlangt, wird das zweite an den Port 60h gesendet!
+
Werden zwei Bytes verlangt, wird das Zweite an den Port 60h gesendet.
 
|-
 
|-
 
! Befehl || Größe || Beschreibung
 
! Befehl || Größe || Beschreibung