*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