AT互換機のPS/2キーボードコントローラ †
- I/Oポート
アドレス(hex) | wide | R/W | デバイス | 説明 | 備考 | 0060 | byte | R | KBC | KBCデータポート/キーボードデータ | | 0060 | byte | W | KBC | KBCデータ出力 | | 0064 | byte | R | KBC | ステータスレジスタ | | 0064 | byte | W | KBC | KBC制御コマンド出力 | |
- ステータスレジスタについて
- I/Oポート0064をバイトリードすると読める
- bit0:1==データポートにキーデータが来ている
- このbitが1になっていたら速やかに0060を読んでデータを受け取ること
- IRQ-1は、ここが0→1になると発生すると考えてよい
- bit1:0==キーボードコントローラに送信データを送ってよい
- bit2:システムフラグ(起動後に0になる)
- bit3:キーボードへ送信中のデータは、1==コマンド、0==データ
- これは、0064に書き込むと自動的に1になり、0060に書き込むと自動的に0になる
- bit4:1==キーボードは入力可能状態(enable)になっている
- bit5:1==データ送信エラー
- データポートにキーデータが来ているのに、受け取らないでいて、さらに次のキーコードがきてしまうとこれになる
- bit6:1==データ受信エラー
- bit7:パリティビットなので基本的に気にしなくてよいと思う
- キーコード
- 基本:0060から読み取った値の、bit0-6がキーコード、bit7がメイク・ブレイク種別(0:メイク、1:ブレイク)
- 以下に見るとおり、Aを押したらAの文字コードが送信されてくるわけではない。PCからみると、キーボードはただのスイッチボタンのかたまりであって、何番のボタンを押した(メイク)か、離した(ブレイク)か、が知らされるに過ぎない。ShiftやCtrlやAltなどとの組み合わせの管理や、NumLockやCapsLockの状態の管理、把握も全部やらなければいけない。
- まあ逆にいえば、キー配置を変える(たとえばShiftとCtrlを入れ替えるなど)は、ソフトウェアで好きなようにできるということでもある。
- 一般キーコード
00:割り当てなし(これはこないはず) | 10:Q | 20:D | 01:ESC | 11:W | 21:F | 02:フルキーの1 | 12:E | 22:G | 03:フルキーの2 | 13:R | 23:H | 04:フルキーの3 | 14:T | 24:J | 05:フルキーの4 | 15:Y | 25:K | 06:フルキーの5 | 16:U | 26:L | 07:フルキーの6 | 17:I | 27:; | 08:フルキーの7 | 18:O | 28::(英語キーボードでは') | 09:フルキーの8 | 19:P | 29:全角・半角(英語キーボードでは`) | 0A:フルキーの9 | 1A:@(英語キーボードでは[) | 2A:左Shift | 0B:フルキーの0 | 1B:[(英語キーボードでは]) | 2B:](英語キーボードではバックスラッシュ) | 0C:フルキーの- | 1C:フルキーのEnter | 2C:Z | 0D:フルキーの^(英語キーボードでは=) | 1D:左Ctrl | 2D:X | 0E:バックスペース | 1E:A | 2E:C | 0F:タブキー | 1F:S | 2F:V |
30:B | 40:F6 | 50:テンキーの2 | 60:リザーブ | 70:ひらがな | 31:N | 41:F7 | 51:テンキーの3 | 61:リザーブ? | 71:リザーブ? | 32:M | 42:F8 | 52:テンキーの0 | 62:リザーブ? | 72:リザーブ? | 33:, | 43:F9 | 53:テンキーの. | 63:リザーブ? | 73:_ | 34:. | 44:F10 | 54:SysReq | 64:リザーブ? | 74:リザーブ? | 35:/ | 45:NumLock | 55:リザーブ? | 65:リザーブ? | 75:リザーブ? | 36:右Shift | 46:ScrollLock | 56:リザーブ? | 66:リザーブ? | 76:リザーブ? | 37:テンキーの* | 47:テンキーの7 | 57:F11 | 67:リザーブ? | 77:リザーブ? | 38:左Alt | 48:テンキーの8 | 58:F12 | 68:リザーブ? | 78:リザーブ? | 39:スペース | 49:テンキーの9 | 59:リザーブ? | 69:リザーブ? | 79:変換 | 3A:CapsLock | 4A:テンキーの- | 5A:リザーブ? | 6A:リザーブ? | 7A:リザーブ? | 3B:F1 | 4B:テンキーの4 | 5B:リザーブ? | 6B:リザーブ? | 7B:無変換 | 3C:F2 | 4C:テンキーの5 | 5C:リザーブ? | 6C:リザーブ? | 7C:リザーブ? | 3D:F3 | 4D:テンキーの6 | 5D: リザーブ? | 6D:リザーブ? | 7D:\ | 3E:F4 | 4E:テンキーの+ | 5E:リザーブ? | 6E:リザーブ? | 7E:リザーブ? | 3F:F5 | 4F:テンキーの1 | 5F:リザーブ? | 6F:リザーブ? | 7F:リザーブ? |
- E0拡張キーコード
- これは E0 1C などの形式で送られてくる。メイクは E0 1C で、ブレイクは E0 9C というふうになる。ここに書かれていないものはリザーブ。
E0 1C:テンキーのEnter | E0 49:PageUp | E0 5B:左Windows | E0 1D:右Ctrl | E0 4B:← | E0 5C:右Windows | E0 35:テンキーの/ | E0 4D:→ | E0 5D:メニュー?キー | E0 37:PrintScreen | E0 4F:End | | E0 38:右Alt | E0 50:↓ | | E0 46:Break | E0 51:PageDown | | E0 47:Home | E0 52:Insert | | E0 48:↑ | E0 53:Delete | |
- 以下のキーコードは、実際のキー入力と関わりなく送られてくるので、読み捨てるのが良いとKは考えている。
E0 2A:無視 | E0 AA:無視 | E0 36:無視 | E0 B6:無視 |
- E1拡張キーコード
- これは2種類しかない
E1 1D 45:Pauseのメイク | E1 9D C5:Pauseのブレイク |
- キーのリピート
- リピートは、ブレイクすることなくメイクが送られてくることで表現される
- BreakとPauseはリピートが発生しない
- LEDの制御など
- NumLockやCapsLockなどのLEDの制御には、次の方法でキーボードにコマンドやデータを送る。
- 1.ステータスレジスタを読んで、bit1が0になるのを待つ。
- 2.データ出力(0060のこと)に、送りたい1バイトを書く。
- 3.キーボードから1バイト通知が来るのを待つ。これはキー入力を待つのと同じ方法になる(IRQで待ってもいいし、ステータスレジスタのbit0が1になるのをループで見張ってもいい)。
- 4.その通知が0xfaであれば、その1バイトは正しくキーボードに送られたことを意味する。0xfeであれば送信ミスなので、1.に戻ってもう一回送る。
- LED制御の場合は、上記の手法を2回やって、 ED xx というデータを送ればよい。ここで、xxのbit0がScrollLock、bit1がNumLock、bit2がCapsLockになる(それぞれ0で消灯、1で点灯)。bit3-7はリザーブで常に0。
- その他のコマンドとして以下のものがある。
- EE:このコマンドはキーボードが正常に動作しているかどうかのチェックのためのもので、うまくいっているときは、キーボードから0xeeという1バイトが送られてくる。この1バイトは、4.での0xfaの代わりに送られてくるので注意。
- F0 xx:このコマンドはキーボードのスキャンコード(キーコード)のフォーマットを設定するためのもので、xx=01に設定するのが一般的である。xx=02やxx=03にもできるが、この場合このページでの説明通りにはならなくなる。なお、xx=00にすると現在設定されているモードを通知してくる。04以上はリザーブ。キーボードをリセットするとデフォルトでは F0 02 になっていると説明している資料もあるけど、Kが試した範囲ではみんな F0 01 になっているようであった。
- F2:このコマンドを送ると、2バイトのキーボードIDが通知されてくる。これは通常、0x83abである。これで英語キーボードか日本語キーボードかを見分けられるということはないと思うが、実験したことはないのでKには確信はない。英語キーボードで0x83abが送られてくるのはまず間違いない。
- F3 xx:このコマンドはキーリピート間隔を設定する。xxのbit0-4の5ビットで、リピート間隔を設定でき、数字が小さいほどリピート間隔が小さくなる(=リピートが速くなる)。bit5-6の2ビットでリピート開始までの時間を制御できて、0:250ms、1:500ms、2:750ms、3:1000msから選べる。bit7はリザーブで常に0にすること。キーボードがリセットされたときは、 F3 2B の状態になっている。
- F4:キーボード入力を可能にする(キーボードイネーブル)。電源投入時はイネーブルになっている。
- F5:キーボード初期化&キーボードディゼーブル。設定を電源時状態に戻して、しかもキーボード入力を受け付けない状態にする(これはいろいろ設定をやり直すときに、設定中にキーデータが混ざるとややこしくなるので、それを避けるためのコマンド)。
- F6:キーボード初期化(ディゼーブルなし)。基本的にF5と同じだけど、キーボードはイネーブルになっている。
- F7:スキャンコード(コマンドF0参照)が3の場合しか関係ないので、説明省略。
- F8:スキャンコード(コマンドF0参照)が3の場合しか関係ないので、説明省略。
- F9:スキャンコード(コマンドF0参照)が3の場合しか関係ないので、説明省略。
- FA:スキャンコード(コマンドF0参照)が3の場合しか関係ないので、説明省略。
- FB:スキャンコード(コマンドF0参照)が3の場合しか関係ないので、説明省略。
- FC:スキャンコード(コマンドF0参照)が3の場合しか関係ないので、説明省略。
- FD:スキャンコード(コマンドF0参照)が3の場合しか関係ないので、説明省略。
- FE:キーボードに対して、「直前の1バイトをうまく受け取れなかったから再度送ってくれ」と通知するためのコマンド。キーコード受信時などでパリティエラーがあったりしたときに、利用するといいかもしれない。
- FF:キーボードリセット。これはF6とは異なり、単に初期化するだけではなく、電源投入時に行う自己診断も再度やる。自己診断に成功すると、キーボードは0xaaというデータを勝手に送ってくる。自己診断に失敗すると、0xfcというデータを送ってくる。PC動作中にキーボードを接続した場合も(こういうことをやっていいのかどうかは分からないけど)、0xaaか0xfcが最初にやってくる。
- ほかにキーボードインターフェースを使ってできること
- キーボードインタフェースは、なぜかキーボード以外のデバイスも管轄していて、いろいろなことができます。
- 以下のコマンドや後続データを書く場合は、かならずステータスレジスタを読んで、「キーボードコントローラに送信データを送ってよい」になっているかどうか確認してくださいね。
- 8042モードレジスタ直接書き込み:
- KBC制御コマンド出力(0064)に、60を書き込む。
- その後、KBCデータ出力(0060)にモードレジスタに書き込みたいデータを書く。
- モードレジスタのビット構成は以下のとおり。
- bit0:これを1にすると、キーボードからデータが来たときにIRQ-1を発生させるようになる。
- bit1:これを1にすると、マウスからデータが来たときにIRQ-12を発生させるようになる。
- bit2:システムフラグ。用途はよく分からない。とりあえず1にしとけばいいらしい(パワーオンリセットによってここは0クリアされるらしい)。
- bit3:これを1にするとキーボードロックができなくなるらしい。
- bit4:これを1にするとキーボードインタフェースが使えなくなる。
- bit5:これを1にするとマウスインタフェースが使えなくなる。
- bit6:スキャンコード01を使うときはこれを1にする。他のスキャンコードを使うときはこのビットを0にするらしいが実は良く分からない。
- bit7:このピットはリザーブなので常に0を設定する。
- 8042モードレジスタ直接読み込み:
- KBC制御コマンド出力(0064)に、20を書き込む。
- するとKBCデータポートに8042モードレジスタの内容が送られてくるので、これを受け取る。
- キーボードインタフェース無効化コマンド:
- KBC制御コマンド出力(0064)に、ADを書き込む。
- このコマンドによって8042モードレジスタのbit4が1になる。
- キーボードインタフェース有効化コマンド:
- KBC制御コマンド出力(0064)に、AEを書き込む。
- このコマンドによって8042モードレジスタのbit4が0になる。
- マウスインタフェース無効化コマンド:
- KBC制御コマンド出力(0064)に、A7を書き込む。
- このコマンドによって8042モードレジスタのbit5が1になる。
- マウスインタフェース有効化コマンド:
- KBC制御コマンド出力(0064)に、A8を書き込む。
- このコマンドによって8042モードレジスタのbit5が0になる。
リンク †
こめんと欄 †
- マウスはどのように制御するのですか? -- 名無しさん 2005-03-08 (火) 19:42:26
- ご質問ありがとうございます。マウス関係はそのうちページを作りたいと思います。 -- K 2005-03-10 (木) 13:15:21
- レスありがとうございます。マウスページ期待しております。 -- 名無しさん 2005-03-10 (木) 23:45:05
- CapsLockが知らないうちについているってことはあるのでしょうか? -- kyon? 2007-06-19 (火) 15:19:35
- 参考になりました。 -- 名無しさん2 2009-07-12 (日) 18:43:04
- 参考になりました。 -- 名無しさん2 2009-07-13 (月) 20:37:48
- 8042モードレジスタのbit6は、scan code set 1に変換するかどうかを選択するビットらしいです。1にセットすると、スキャンコードがscan code set 1に変換された後、インプットバッファに送られ、0にクリアすると、スキャンコードが無変換でバッファに送られます。(参考:http://www.computer-engineering.org/ps2keyboard/) -- uchan 2009-08-30 (日) 17:48:12
- なぜ98のキーボードの説明がないのか。疑問を持っている -- 忍 2010-04-07 (水) 15:22:47
- Why isn't the page English-commented? -- RS 2010-06-07 (月) 21:24:16
- 初めまして。ちょっと質問があります。5Bはwindowsキー,5Dはアプリケーションキーではないでしょうか。 -- MNAS? 2014-03-16 (日) 07:01:26
- 確認ができたので、編集しました。 -- MNAS? 2014-03-25 (火) 18:56:12
- すみません。拡張キーコードの時もありました. -- MNAS? 2014-03-31 (月) 11:14:29
|