*AT互換機のPS/2キーボードコントローラ 
-コントローラは8042

-I/Oポート
|アドレス(hex)|wide|R/W|デバイス|説明|備考|h
|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:パリティビットなので基本的に気にしなくてよいと思う
---0==奇数パリティ、1==偶数パリティ

-キーコード
--基本: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:リザーブ?|
---註:
---00はキーボードエラーを意味する。

--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になる。
//AA,AB,AC,C0,D0,D1,E0,F0~FF


-(まだ未完成)

*** リンク 
-http://members.tripod.com/~oldboard/assembly/8042.html

* こめんと欄 
-マウスはどのように制御するのですか? -- [[名無しさん]] SIZE(10){2005-03-08 (火) 19:42:26}
-ご質問ありがとうございます。マウス関係はそのうちページを作りたいと思います。 -- [[K]] SIZE(10){2005-03-10 (木) 13:15:21}
-レスありがとうございます。マウスページ期待しております。 -- [[名無しさん]] SIZE(10){2005-03-10 (木) 23:45:05}
-CapsLockが知らないうちについているってことはあるのでしょうか? -- [[kyon]] SIZE(10){2007-06-19 (火) 15:19:35}
-参考になりました。 -- ''名無しさん2'' SIZE(10){2009-07-12 (日) 18:43:04}
-参考になりました。 -- ''名無しさん2'' SIZE(10){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'' SIZE(10){2009-08-30 (日) 17:48:12}
-なぜ98のキーボードの説明がないのか。疑問を持っている -- ''忍'' SIZE(10){2010-04-07 (水) 15:22:47}

-Why isn't the page English-commented? -- ''RS'' SIZE(10){2010-06-07 (月) 21:24:16}
-初めまして。ちょっと質問があります。5Bはwindowsキー,5Dはアプリケーションキーではないでしょうか。 -- [[MNAS]] SIZE(10){2014-03-16 (日) 07:01:26}
-確認ができたので、編集しました。 -- [[MNAS]] SIZE(10){2014-03-25 (火) 18:56:12}
-すみません。拡張キーコードの時もありました. -- [[MNAS]] SIZE(10){2014-03-31 (月) 11:14:29}

#comment


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS