0から作るソフトウェア開発
日々勉強中。。。 |
Follow @Nina_Petipa |
0から作るOS開発 キーボードドライバその2 |
キーボードエンコーダの標準制御コマンド | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
コマンド | 名称 | 説明 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xED | LED設定 |
ポートアドレス0x60に0xEDを書き込んだ後に続けてLEDの設定値をポートアドレス0x60に書き込みます LEDの設定値は次のフォーマットになります 各ビットについては次のようになります。
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xEE | エコー | キーボードエンコーダに書き込んだ値0xEEをそのままポートアドレス0x60に返してきます。 キーボードエンコーダが正常に動作しているか確認することができます | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF0 | スキャンコード設定/取得 |
キーボードエンコーダから取得するスキャンコードセットを設定することができます。
設定するスキャンコードは下記フォーマットでコマンドに続けてポートアドレス0x60に書き込みます。
設定する値は次のようになります
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF2 | キーボードID取得 |
2バイトのキーボードIDを取得します。
コマンド書き込み後ポートアドレス0x60を続けて読み込むことでキーボードIDを
取得できます。コマンド書き込み後は読み込み前に最低10ms待ちます。
キーボードIDの例は下記となります。キーボードごとにいろいろなIDがあります
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF3 | タイプマティックレート/ディレイ設定 |
タイプマティックレート(キーを押し続けている場合にスキャンコードが送信される間隔)と
タイプマティックディレイ(タイプマティックモードになるまでの遅延時間)が設定できます
このコマンド書き込み後続けてポートアドレス0x60に次のフォーマットで設定値を
書き込みます ビット0-4:タイプマティックレートを設定します。 設定値と対応するレートは下記表を参照してください ビット5-6:タイプマティックディレイを設定します。 設定値と対応するディレイは下記表を参照してください ビット7:予約。0固定となります。
レートと設定値の関係は(2^ビット4-3)*(ビット2-0+8)/240秒となります |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF4 | キーボード有効 | キーボードを有効にします。キーボードが有効の場合にコマンドを書き込むと 内部バッファがクリアされます。エラーコードが返ってきた場合はキーボードは 無効となります。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF5 | キーボード無効 | キーボードを無効にします。キーボードを無効にするとアウトプットバッファをクリア、 LEDをOFF、タイプマティックレート/ディレイをデフォルト値に設定、キーボードスキャンを 無効にします。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF6 | デフォルト設定 | アウトプットバッファをクリア、LEDをOFF、タイプマティックレート/ディレイをデフォルト値に設定します | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF7 | 全キーのリピート設定 | スキャンコードセット3でスキャンコードのリピートビットを常にセットするようになります。 スキャンコードセット3以外のスキャンコードセットには影響はありません。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF8 | 全キーのブレークコード設定 | スキャンコードセット3でスキャンコードのブレークコード生成ビットを常にセットするようになります。 スキャンコードセット3以外の スキャンコードセットには影響はありません。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xF9 | 全キーのブレークコード設定クリア | スキャンコードセット3でスキャンコードのブレークコード生成ビットを常にクリアするようになります。 スキャンコードセット3以外の スキャンコードセットには影響はありません。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xFA | 全キーのリピート/ブレークコード設定 | スキャンコードセット3でスキャンコードのリピートビットとブレークコード生成ビットを 常にセットするようになります。スキャンコードセット3以外のスキャンコードセットには 影響はありません。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xFB | キーのリピート設定 | スキャンコードセット3で指定したキーのスキャンコードのリピートビットを常に セットするようになります。スキャンコードセット3以外のスキャンコードセットには 影響はありません。このコマンドを書き込み後続けいてポートアドレス0x60に リピート設定したいキーのスキャンコードセット3を書き込みます。設定したい キー分書き込んだ後終了コマンドとして"0xED 0xEE 0xF0 0xF2 0xF3 0xF4 0xF5 0xF6 0xF7 0xF8 0xF9 0xFA 0xFB 0xFC 0xFD 0xFE 0xFF"を書き込みます。終了コマンドを書き込んだ後は0xF4キーボード有効コマンドを 書き込みキーボードを有効にしておきます | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xFC | キーのブレークコード設定 | スキャンコードセット3で指定したキーのスキャンコードのブレークコードビットを常に セットするようになります。スキャンコードセット3以外のスキャンコードセットには 影響はありません。このコマンドを書き込み後続けいてポートアドレス0x60に ブレークコード設定したいキーのスキャンコードセット3を書き込みます。設定したい キー分書き込んだ後終了コマンドとして"0xED 0xEE 0xF0 0xF2 0xF3 0xF4 0xF5 0xF6 0xF7 0xF8 0xF9 0xFA 0xFB 0xFC 0xFD 0xFE 0xFF"を書き込みます。終了コマンドを書き込んだ後は0xF4キーボード有効コマンドを 書き込みキーボードを有効にしておきます | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xFD | キーのブレークコード設定クリア | スキャンコードセット3で指定したキーのスキャンコードのブレークコードビットを常に クリアするようになります。スキャンコードセット3以外のスキャンコードセットには 影響はありません。このコマンドを書き込み後続けいてポートアドレス0x60に ブレークコード設定クリアしたいキーのスキャンコードセット3を書き込みます。設定したい キー分書き込んだ後終了コマンドとして"0xED 0xEE 0xF0 0xF2 0xF3 0xF4 0xF5 0xF6 0xF7 0xF8 0xF9 0xFA 0xFB 0xFC 0xFD 0xFE 0xFF"を書き込みます。終了コマンドを書き込んだ後は0xF4キーボード有効コマンドを 書き込みキーボードを有効にしておきます | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xFE | 再送信要求 | キーボードエンコーダにデータの再送信要求をします。 このコマンドはキーボードコントローラがキーボードエンコーダに対して 書き込むコマンドとなります | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0xFF | リセット/セルフテスト | リセットしてからセルフテストを行います。セフルテスト完了ごポートアドレス0x60に 結果を格納します。0xAAであればテスト結果OK、0xFCであればテスト結果NGと なります。セフルテスト中はLEDを点灯/消灯します |
キーボードエンコーダの各社独自制御コマンド | |||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
コマンド | 名称 | 説明 | |||||||||||||||||||||||||||||||||||
0xE8 | OmniKeyキーボードID取得 | OmniKey101キーボードのIDを取得することができます。 IDは0xE0 0x4Cとなります | |||||||||||||||||||||||||||||||||||
0xEA | 拡張キー有効/無効 |
IBMキーボードの拡張キーを有効/無効にします 有効:0xEA 0x70 無効:0xEA 0x71 |
|||||||||||||||||||||||||||||||||||
0xEB | 拡張LED ON/OFF |
拡張LEDをON/OFFします。
下記表のコマンド最後のバイトでLED ON/OFFを切り替えます。
該当ビットが1でLEDをON、ビットが0であればLEDをOFFにします
|
/* ================================================================================== Description :Commands of Keyboard Encoder ================================================================================== */
#define DEF_KBD_ENC_COM_SETLED 0xED #define DEF_KBD_ENC_COM_ECHO 0xEE #define DEF_KBD_ENC_COM_GETSET_SCANCODE 0xF0 #define DEF_KBD_ENC_COM_GET_KBD_ID 0xF2 #define DEF_KBD_ENC_COM_SET_TYPEMATIC 0xF3 #define DEF_KBD_ENC_COM_ENABLE_KBD 0xF4 #define DEF_KBD_ENC_COM_DISABLE_KBD 0xF5 #define DEF_KBD_ENC_COM_SET_DEFAULT 0xF6 #define DEF_KBD_ENC_COM_SET_ALL_REPEAT 0xF7 #define DEF_KBD_ENC_COM_SET_ALL_BREAK 0xF8 #define DEF_KBD_ENC_COM_CLEAR_ALL_REP_BRK 0xF9 #define DEF_KBD_ENC_COM_SET_ALL_REP_BRK 0xFA #define DEF_KBD_ENC_COM_SET_REPEAT 0xFB #define DEF_KBD_ENC_COM_SET_BREAK 0xFC #define DEF_KBD_ENC_COM_CLEAR_REP_BRK 0xFD #define DEF_KBD_ENC_COM_REQ_RESEND 0xFE #define DEF_KBD_ENC_COM_RESET_SELFTEST 0xFF
/* ================================================================================== Description :Keyboad LED ================================================================================== */
typedef enum { E_KBD_NONE_LED = 0x00000000, E_KBD_SCROLL_LOCK_LED = 0x00000001, E_KBD_NUM_LOCK_LED = 0x00000002, E_KBD_CAPS_LOCK_LED = 0x00000004 } E_KBD_LED;
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :keyboardSetLED Input :E_KBD_LED led < designated led > Output :void Return :STATUS Description :set leds of keyboard _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
STATUS keyboardSetLED( E_KBD_LED led ) { unsigned char wirte_data; STAUS status;
/*--------------------------------------------------------------------------*/ /* if designated leds are unknow */ /*--------------------------------------------------------------------------*/
if( ( E_KBD_SCROLL_LOCK_LED | E_KBD_NUM_LOCK_LED | E_KBD_CAPS_LOCK_LED ) < led) { return( DEF_KBD_ERROR ); } status = writeKbdEncCommand( DEF_KBD_ENC_COM_SETLED ); status |= writeKbdEncCommand( ( unsigned char )led ); return( status ); }
キーボードエンコーダのリターンコード | |
---|---|
リターンコード | 説明 |
0x00 | エラーまたは内部バッファのオーバーランが発生しました。 スキャンコードセット2またはセット3の場合のみ書き込まれます |
0x**、・・・ | スキャンコードが書き込まれます。 (コマンド書き込み後以外) |
0x**、0x** | 0xF2キーボードID取得コマンド発行後のキーボードIDが書き込まれます |
0xAA | 0xFFリセット/セルフテストのセルフテスト(BAT:Basic Assurance Test) 実行中または成功後に書き込まれます。(スキャンコードのなかにも0xAAが含まれる コードがありますので注意します)。 |
0xEE | 0xEEエコーコマンド書き込み後に書き込まれます |
0xFA | キーボードエンコーダのOK応答です。 キーボードコントローラに対して発行されます。キーボードエンコーダが正常動作しているか この応答で確認できます |
0xFC | 0xFFリセット/セルフテストのセルフテスト(BAT:Basic Assurance Test) が失敗した場合に書き込まれます。PS/2プロトコルのみ適用されます。 |
0xFD | 0xEEエコーコマンドが失敗した場合に書き込まれます |
0xFE | 解釈できないコマンドやノイズなどでキーボードエンコーダが最後に受信した コマンドが正常に解釈できないときに書き込まれる、コマンドの再送信要求です |
キーボードコントローラの標準制御コマンド | ||
---|---|---|
コマンド | 名称 | 説明 |
0x20 | キーボードコントローラコマンド読み込み | キーボードコントローラから制御コマンドを1バイト(CCB:Control Command Byte)を読み込みます。 制御コマンドバイトについては下のほうで詳細を見ていきます |
0x60 | キーボードコントローラコマンド書き込み | キーボードコントローラから制御コマンドを1バイト(CCB:Control Command Byte)を書き込みます。 この0x60のコマンドをポートアドレス0x64に書き込み後、制御コマンドバイトをポートアドレス0x60に 書き込みます。 制御コマンドバイトについては下のほうで詳細を見ていきます |
0xA7 | マウスポート無効 | MCAシステムでは、マウスとAUXデバイスのクロックをLowにして 制御コマンドバイトのビット5を1にします。その結果 ポートP23の出力が1になります。 ISA/EISAシステムのAMIBIOSではキャッシュバッドを書き込みます |
0xA8 | マウスポート有効 | MCAシステムでは、マウスとAUXデバイスのクロックを有効にして 制御コマンドバイトのビット5を0にします。その結果 ポートP23の出力が0になります。 ISA/EISAシステムのAMIBIOSではキャッシュグッドを書き込みます |
0xA9 | マウスポートのテスト |
キーボードコントローラとマウス間のシリアル通信をテストします。
テスト結果はポートアドレス0x60に格納されます。
テスト結果は下記となります 0x00:テスト結果OK 0x01:マウスクロックラインがLowになったままです 0x02:マウスクロックラインがHighになったままです 0x03:マウスデータラインがLowになったままです 0x04:マウスデータラインがHighになったままです 0xFF:マウスは接続されていません ISA/EISAシステムのAMIBIOSではキャッシュバッドもしくはキャッシュグッドを 読み込みます。結果は下記となります 0x00:キャッシュバッド 0x01:キャッシュグッド |
0xAA | セルフテスト |
セルフテストを行います。セルフテストの結果をポートアドレス0x64に返します。
セルフテストの結果は下記となります 0x55:テスト結果OK 0xFC:テスト結果NG |
0xAB | インターフェイステスト |
キーボードコントローラとキーボードエンコーダとのシリアル通信が正常に行えるかテストします。
テスト結果はポートアドレス0x60に返します。テスト結果は下記となります 0x00:テスト結果OK 0x01:キーボードクロックラインがLowになったままです 0x02:キーボードクロックラインがHighになったままです 0x03:キーボードデータラインがLowになったままです 0x04:キーボードデータラインがHighになったままです 0xFF:その他のエラーが発生しました |
0xAD | キーボード無効 | キーボードエンコーダとのクロックラインを無効化し、制御コマンドバイトの4ビット目を1にします。 制御コマンドバイトについては下の方で詳細を見ていきます |
0xAE | キーボード有効 | キーボードエンコーダとのクロックラインを有効化し、制御コマンドバイトの4ビット目を0にします。 制御コマンドバイトについては下の方で詳細を見ていきます |
0xC0 | インプットポート読み込み | インプットポートを読み込んで、その結果をポートアドレス0x64に格納します。 インプットポートについては下の方で詳細を見ていきます |
0xD0 | アウトプットポート読み込み | アウトプットポートを読み込んで、その結果をポートアドレス0x64(アウトプットバッファ)に 格納します。アウトプットポートについては下の方で詳細を見ていきます |
0xD1 | アウトプットポート書き込み | アウトプットポートに書き込みします。アウトプットポートのビット0に0を書き込むと ハードウェアリセットします。アウトプットポートについては下の方で詳細を見ていきます |
0xD4 | マウスへの書き込み | このコマンド書き込み後ポートアドレス0x60にマウスへ書き込むデータを 書き込みます。MCAシステムで使用します。 |
0xE0 | テストポート読み込み |
テストポートを読み込み、結果をポートアドレス0x60に格納します。
アウトプットバッファが空の場合のみ使用できるコマンドです。
テストポートは下記となります ビット0:キーボードクロック(入力) ビット1:ATの場合はキーボードデータ(入力)、PS/2の場合はマウスクロック(入力) |
0xFE | システムリセット | アウトプットポートのビット0を0にしてハードウェアリセットを行います |
キーボードコントローラの標準以外の制御コマンド | ||
---|---|---|
コマンド | 名称 | 説明 |
0x00-1F | キーボードコントローラのRAM読み込み |
0x20-0x3Fのエイリアスとなります (AMIBIOSのみ) |
0x20-3F | キーボードコントローラのRAM読み込み |
キーボードコントローラは32バイトRAMを持っています。RAMのアドレスを0x00から0x3Fまでで
指定し、ポートアドレス0x64に書き込みます。RAMから読みだしたデータはポートアドレス0x60に
格納されます。MCA(Micro Channel Architecture)では、タイプ1コントローラが32バイト目の
アドレスまでアクセスできます。タイプ2コントローラでは0x00、0x13-0x17、0x1D、0x1Fのみ
アクセスできます。下記アドレスは特殊なデータを格納するアドレスとなります アドレス0x00:制御コマンドバイトのデータが格納されています(下の方で詳細を見ていきます) アドレス0x13:パスワードが有効に設定されている場合0以外が格納されます(MCAのみ) アドレス0x14:パスワードが認証された場合0以外が格納されます(MCAのみ) アドレス0x16,0x17:パスワード認証中にメイクコードが格納されます(MCAのみ) |
0x40-5F | キーボードコントローラのRAM書き込み | 0x60-0x7Fのエイリアスとなります (AMIBIOSのみ) |
0x60-7F | キーボードコントローラのRAM書き込み | キーボードコントローラのRAM上のアドレスを指定して、ポートアドレス0x64に書き込みます。 続けて書き込みたいデータをポートアドレス0x60に書き込みます |
0x90-93 | Synapticsルーティングプリフィクス |
PS/2プロトコルで接続されているAUXデバイスを選択するプリフィクスコマンドです。
Synaptics社
から
PS/2マルチプレクシングの仕様
がダウンロードできますので、
気になる方は参照してください。
下記プリフィクスをポートアドレス0x64に書き込んでから、デバイスに書き込む
データをポートアドレス0x60に書き込みます 0x90:AUXポートNo.1にコマンドを書き込みます 0x91:AUXポートNo.2にコマンドを書き込みます 0x92:AUXポートNo.3にコマンドを書き込みます 0x93:AUXポートNo.4にコマンドを書き込みます (VIAがこのコマンドを採用しています) |
0x90-0x9F | ポート13-ポート10書き込み |
このコマンドのローニブルがポート13-ポート10の出力になります。
各ポートに同時に出力するときはローニブルをORします 0x90:全ポートをLowにします 0x91:ポート13をHighにします 0x92:ポート12をHighにします 0x94:ポート11をHighにします 0x98:ポート10をHighにします (VIA VT82C42で使用できます) |
0xA0 | コピーライト読み込み | ポートアドレス0x64にこのコマンドを書き込むとポートアドレス0x60に コピーライトがアスキーコードで格納されます。(Nullだけの場合もあります)。 このコマンドに対応していないキーボードコントローラには無視されます |
0xA1 | ファームウェアバージョン読み込み | ポートアドレス0x64にこのコマンドを書き込むとポートアドレス0x60に ファームウェアバージョンがアスキーコードで1バイト格納されます。 このコマンドに対応していないキーボードコントローラには無視されます |
0xA2 | スイッチスピードリセット | キーボードコントローラのP22とP23をLowにします。P22とP23は スイッチスピード切り替えに使用されます。処理が完了すると キーボードコントローラからダミーデータが送信されます。 (ISA/EISAシステムのAMIBIOSで使用できます) |
0xA3 | スイッチスピード設定 | キーボードコントローラのP22とP23をHighにします。 処理が完了するとキーボードコントローラからダミーデータが送信されます。 (ISA/EISAシステムのAMIBIOSで使用できます、COMPAQのBIOSでは システムスピード制御を有効にします) |
0xA4 | パスワード設定確認 |
ポートアドレス0x64にこのコマンドを書き込むと、パスワードが設定されて
いるかどうかを確認し、その結果がポートアドレス0x60に格納されます。
格納されれる結果は次のようになります 0xF1:MCAシステムでパスワードが設定されていない 0xFA:MCAシステムでパスワード設定されている 0xF1:パスワード機能が無いその他のシステム ISA/EISAシステムのAMIBIOSではクロックがLowになります COMPAQのBIOSはシステムスピードが変更されます |
0xA5 | パスワード読み込み |
MCAシステムではNullで終わるパスワード文字列がポートアドレス0x60に
格納されます。格納されるデータはスキャンコードです。
ISA/EISAシステムのAMIBIOSではクロックをHighにします。
COMPAQのBIOSではポートアドレス0x60に次のデータが格納されます ビット4が0:アウトプットバッファフル割り込みが無効 ビット4が1:アウトプットバッファフル割り込みが有効 ビット5が0:9ビットキーボードエンコーダ ビット5が1:11ビットキーボドエンコーダ |
0xA6 | パスワードチェック |
MCAシステムでパスワードが設定されている場合、設定されているパスワードと
このコマンドが書き込まれた以降に押されたキーが一致しているかチェックします。
一致していればキーボードが有効になります。
ISA/EISAシステムのAMIBIOSではクロックの状態を読み込みます 0:クロックはLowです 1:クロックはHighです |
0xAC | 診断データダンプ | キーボードコントローラのRAMから16バイトのデータ、アウトプットポート、 インプットポート、キーボードコントローラのプログラムステータスを ポートアドレス0x60から読み込みます。 |
0xAF | キーボードエンコーダバージョン読み込み |
Award BIOS、VIAで使用します。 キーボードエンコーダのバージョンを読み込みます |
0xB0-0xB5 | キーボードコントローララインのリセット |
<AMIBIOS> ポートアドレス0x64に0xB0から0xB5を書き込むとキーボードコントローラの ポートをLowにします。ポートとコマンドの対応関係は下記となります。 0xB0:P10をLowにします(ISA/EISAシステムのみ) 0xB1:P11をLowにします(ISA/EISAシステムのみ) 0xB2:P12をLowにします 0xB3:P13をLowにします 0xB4:P22をLowにします(ISA/EISAシステムのみ) 0xB5:P23をLowにします(ISA/EISAシステムのみ) コマンド書き込み後キーボードコントローラからダミーデータが送信されます <VIA BIOS> ポートアドレス0x64に0xB0から0xB7を書き込むとキーボードコントローラの ポートをLowにします。ポートとコマンドの対応関係は下記となります。 0xB0:P10をLowにします 0xB1:P11をLowにします 0xB2:P12をLowにします 0xB3:P13をLowにします 0xB4:P22をLowにします 0xB5:P23をLowにします 0xB6:P14をLowにします 0xB7:P15をLowにします |
0xB8-0xBD | キーボードコントローララインの設定 |
<AMIBIOS> ポートアドレス0x64に0xB0から0xB5を書き込むとキーボードコントローラの ポートをHighにします。ポートとコマンドの対応関係は下記となります。 0xB0:P10をHighにします(ISA/EISAシステムのみ) 0xB1:P11をHighにします(ISA/EISAシステムのみ) 0xB2:P12をHighにします 0xB3:P13をHighにします 0xB4:P22をHighにします(ISA/EISAシステムのみ) 0xB5:P23をHighにします(ISA/EISAシステムのみ) コマンド書き込み後キーボードコントローラからダミーデータが送信されます <VIA BIOS> ポートアドレス0x64に0xB0から0xB7を書き込むとキーボードコントローラの ポートをLowにします。ポートとコマンドの対応関係は下記となります。 0xB0:P10をHighにします 0xB1:P11をHighにします 0xB2:P12をHighにします 0xB3:P13をHighにします 0xB4:P22をHighにします 0xB5:P23をHighにします 0xB6:P14をHighにします 0xB7:P15をHighにします |
0xC1 | インプットポート連続ポーリング(ローニブル) |
MCAシステムのタイプ1コントローラのみ使用できます このコマンド書き込み後インプットポートのビット3-0がポートアドレス0x64の ビット7-4に連続で書き込まれます。別のコマンドをキーボードコントローラに 書き込むと終了します。 |
0xC2 | インプットポート連続ポーリング(ハイニブル) |
MCAシステムのタイプ1コントローラのみ使用できます このコマンド書き込み後インプットポートのビット7-4がポートアドレス0x64の ビット7-4に連続で書き込まれます。別のコマンドをキーボードコントローラに 書き込むと終了します。 |
0xC8 | ブロック解除(P22とP23) |
ISA/EISAシステムのAMIBIOSで使用できます このコマンド送信後に、コマンド0xD1アウトプットポート書き込みで P22とP23をLow/Highにすることができます |
0xC9 | ブロック設定(P22とP23) |
ISA/EISAシステムのAMIBIOSで使用できます このコマンド送信後に、コマンド0xD1アウトプットポート書き込みで P22とP23をLow/Highにすることができなくなります |
0xCA | キーボードコントローラモード読み込み |
AMIBIOS、VIA BIOSで使用できます コマンド書き込み後ポートアドレス0x60のビット0にキーボードコントローラの モードを格納します。モードは下記となります 0:PS/2(MCA)インターフェイス 1:ISA(AT)インターフェイス |
0xCB | キーボードコントローラモード書き込み |
AMIBIOS、VIA BIOSで使用できます コマンド書き込むとポートアドレス0x60のビット0がキーボードコントローラの モードに設定できます。モードは下記となります 0:PS/2(MCA)インターフェイス 1:ISA(AT)インターフェイス このコマンドを書き込む前に、一度0xCAで1バイト読み込み、ビット0を変更してから モードを設定します |
0xD2 | キーボードコントローラアウトプットバッファ書き込み |
MCAシステムで使用します。 このコマンド書き込み後ポートアドレス0x60に書き込むデータを書き込みます (キーボードコントローラのアウトプットバッファにポートアドレス0x60のデータを 書き込みます)。特に注意すべき点は、このコマンドで書き込んだデータは キーボードエンコーダからキーボードコントローラに送信したように振る舞う ということです。ですので、割り込みの設定をしている場合IRQ1が発生します |
0xD3 | マウスアウトプットバッファ書き込み |
<MCAシステム> このコマンド書き込み後ポートアドレス0x60に書き込むデータを書き込みます (キーボードコントローラのアウトプットバッファにポートアドレス0x60のデータを 書き込みます)。特に注意すべき点は、このコマンドで書き込んだデータは マウスからキーボードコントローラに送信したように振る舞う ということです。ですので、割り込みの設定をしている場合IRQ12が発生します <Synaptics仕様のパソコン> ノートパソコンなどはAUXデバイスが接続されているためAUXデバイスとの 通信プロトコルでこのコマンドを使用します。 Synaptics社 から PS/2マルチプレクシングの仕様 がダウンロードできますので、 気になる方は参照してください |
0xDD | A20アドレスライン無効 |
HP Vectraで使用できます。 A20アドレスラインを無効にします |
0xDF | A20アドレスライン有効 |
HP Vectraで使用できます。 A20アドレスラインを有効にします |
0xF0-0xFF | パルス出力 |
キーボードコントローラのアウトプットポートのビット3-0から約6秒間パルスを出します。
ローニブルのビット3-0がアウトプットポートのビット3-0に対応しています。
ビットが0であればパルスを出し、ビットが1であればパルスを出しません。 0xF7:アウトプットポートのビット3からパルスを出します 0xFB:アウトプットポートのビット2からパルスを出します 0xFD:アウトプットポートのビット1からパルスを出します 0xFE:アウトプットポートのビット0からパルスを出します (0xFEはすなわちシステムのリセットコマンドとなります) 出力したいポートのビットを複数0にすることもできます |
キーボードコントローラの制御コマンドバイト | |||
---|---|---|---|
ビット | ラベル | 名称 | 説明 |
ビット0 | KIE | キーボード割り込み有効 |
このビットを操作することで、キーボード割り込みを有効にしたり無効にしたりすることができます 0:キーボード割り込みは無効です 1:キーボード割り込みは有効で、キーボードコントローラのアウトプットバッファがフルになるとIRQ1を発生させます |
ビット1 | KIE | マウス割り込み有効 |
<ISAシステム> 使用しません <PS/2またはEISAシステム> このビットを操作することで、マウス割り込みを有効にしたり無効にしたりすることができます 0:キーボード割り込みは無効です 1:キーボード割り込みは有効で、マウスのアウトプットバッファがフルになるとIRQ12を発生させます |
ビット2 | SYSF | システムフラグ |
0:システムはコールドリブート(Cold Reboot)しました 1:システムはウォームリブート(Warm Reboot)しました。(ウォームリブートはBIOSがBAT処理を完了した状態となります)。 このフラグによりBIOSのPOST処理で行う検査・初期化処理が変わります。 このビットはキーボードドライバその1で 見てきましたステータスレジスタのビット2と同じ内容となります。 |
ビット3 | IGNLK |
キーボードロック強制解除 (Ignore Keyboard Lock) |
<PS/2システム> 使用しません <ATシステム> このビットを1にすることで強制的にキーボードロックを解除します 0:何もしません 1:キーボードドライバその1で 見てきましたステータスレジスタのビット4を強制的に1にします。 このビットは電源ON後にキーボードをテストするために使用します。 |
ビット4 | KE | キーボード有効 |
このビットを操作することで、キーボードを有効にしたり無効にしたりすることができます 0:キーボードを有効にします 1:キーボードを無効にします(クロックラインをLowに固定します) |
ビット5 | ME | マウス有効 |
<PS/2またはEISAシステム> このビットを操作することで、マウスを有効にしたり無効にしたりすることができます 0:マウスを有効にします 1:マウスを無効にします(クロックラインをLowに固定します) <ISAシステムの”PCモード”> 0:11ビットコードの使用、パリティ検査、スキャンコード変換をします 1:8086コードの使用し、パリティ検査とスキャンコード変換はしません |
ビット6 | XLATE | スキャンコード変換 |
このビットを操作することで、キーボードエンコーダから8042に送信されてくるキーデータをスキャンコードに変換するか
どうかを設定することができます 0:スキャンコードに変換しません 1:スキャンコードに変換します <MCAシステムのタイプ2コントローラ> このビットを変更することはできません。キーボードエンコーダの制御コマンド0xF0を使用します |
ビット7 | 0 | 予約ビット | 0固定です |
キーボードコントローラのインプットポート | ||||
---|---|---|---|---|
ビット | 対応ポート | ラベル | 名称 | 説明 |
ビット0 | P10 | KBD |
<ISAシステム以外> キーボードデータ入力ポートです <ISAシステム> 使用しません |
|
ビット1 | P11 | MOUSE |
<ISAシステム以外> マウスデータ入力ポートです <ISAシステム> 使用しません |
|
ビット2 | P12 | CLK2 | クロック2 |
<PS/2とMCAシステム以外> クロックスイッチに使用します。 <PS2とMCAシステム> 0:キーボード電源は正常です 1:キーボード電源が入っていません |
ビット3 | P13 | CLK1 | クロック1 | クロックスイッチに使用します。ISA、EISA、PS/2システムでは使用しません。 |
ビット4 | P14 | RAM | RAM |
0:マザーボード上のRAMは512KBです 1:マザーボード上のRAMは256KBです 現在使用されているキーボードのRAMは512KBです |
ビット5 | P15 | JAMPER | ジャンパ |
0:ジャンパで端子が接続されています 1:ジャンパで端子が接続されていません ジャンパで物理的に端子が接続されている場合にはBIOSは診断処理を無限ループします |
ビット6 | P16 | DISP | ディスプレイ |
0:ディスプレイはCGAです 1:ディスプレイはMDAです |
ビット7 | P17 | LOCK | キーボードロック |
0:キーボードはロック状態です 1:キーボードはロック解除状態です |
キーボードコントローラのアウトプットポート | ||||
---|---|---|---|---|
ビット | 対応ポート | ラベル | 名称 | 説明 |
ビット0 | P20 | Reset | リセット |
0:システムをリセットします 1:システムは通常稼働します |
ビット1 | P21 | A20 | A20有効/無効 |
0:A20ラインをLowにして無効にします 1:A20ラインをHighにして有効にします このビットの操作についてはカーネルローダその3で見てきました |
ビット2 | P22 | MDATA | マウスデータ |
<ISAシステム以外> マウスデータ出力ポートです <ISAシステム> 使用しません |
ビット3 | P23 | MCLK | マウスデータ |
<ISAシステム以外> マウスクロックポートです <ISAシステム> 使用しません |
ビット4 | P24 | IRQ1 | IRQ1ステータス |
0:IRQ1の割り込みは発生していません 1:IRQ1の割り込みが発生しています |
ビット5 | P25 | IRQ12 | IRQ12ステータス |
0:IRQ12の割り込みは発生していません 1:IRQ12の割り込みが発生しています |
ビット6 | P26 | CLK | キーボードクロック | キーボードエンコーダとの通信クロックです |
ビット7 | P27 | DATA | キーボードデータ | キーボードエンコーダとの通信データ出力です |
/* ================================================================================== Description :Commands of Keyboard Controller ================================================================================== */ /* Standard Commands */
#define DEF_KBD_CTRL_COM_READ_CCB 0x20 #define DEF_KBD_CTRL_COM_WRITE_CCB 0x60 #define DEF_KBD_CTRL_COM_DISABLE_MOUSE 0xA7 #define DEF_KBD_CTRL_COM_ENABLE_MOUSE 0xA8 #define DEF_KBD_CTRL_COM_TEST_MOUSE 0xA9 #define DEF_KBD_CTRL_COM_SELF_TEST 0xAA #define DEF_KBD_CTRL_COM_TEST_IF 0xAB #define DEF_KBD_CTRL_COM_DISABLE_KBD 0xAD #define DEF_KBD_CTRL_COM_ENABLE_KBD 0xAE #define DEF_KBD_CTRL_COM_READ_IN_PORT 0xC0 #define DEF_KBD_CTRL_COM_READ_OUT_PORT 0xD0 #define DEF_KBD_CTRL_COM_WRITE_OUT_PORT 0xD1 #define DEF_KBD_CTRL_COM_WRITE_MOUSE 0xD4 #define DEF_KBD_CTRL_COM_READ_TEST_PORT 0xE0 #define DEF_KBD_CTRL_COM_SYSTEM_RESET 0xFE
/* Vendo-Specific Commands */
#define DEF_KBD_CTRL_COM_READ_RAM_0x00 0x20 #define DEF_KBD_CTRL_COM_READ_RAM_0x01 0x21
. . .
#define DEF_KBD_CTRL_COM_READ_RAM_0x3F 0x3F #define DEF_KBD_CTRL_COM_WRITE_RAM_0x00 0x60 #define DEF_KBD_CTRL_COM_WRITE_RAM_0x01 0x61
. . .
#define DEF_KBD_CTRL_COM_WRITE_RAM_0x7F 0x7F
/* ---------------------------------------------------------------------------------- Description :Status of Self Test Command ---------------------------------------------------------------------------------- */
#define DEF_KBD_CTRL_STS_SELF_TEST_OK 0x55 #define DEF_KBD_CTRL_STS_SELF_TEST_NG 0xFC
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :keyboardSelfTest Input :void Output :void Return :STATUS Description :command keyboard to test itself _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
STATUS keyboardSelfTest( VOID ) { unsigned char enc_buffer; STATUS status;
/*--------------------------------------------------------------------------*/ /* execute self test */ /*--------------------------------------------------------------------------*/
status = writeKbdCtrlCommand( DEF_KBD_CTRL_COM_SELF_TEST ); if( DEF_KBD_OK != status ) { return( status ); }
/*--------------------------------------------------------------------------*/ /* wait */ /*--------------------------------------------------------------------------*/
status = waitKbdOutputBufferFull( ); if( DEF_KBD_OK != status ) { return( status ); }
/*--------------------------------------------------------------------------*/ /* test result of self test */ /*--------------------------------------------------------------------------*/
enc_buffer = readKbdEncBuffer( ); if( enc_buffer == DEF_KBD_CTRL_STS_SELF_TEST_OK ) { return( status ); } return( DEF_KBD_ERROR ); }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :waitKbdOutputBufferFull Input :void Output :void Return :STATUS < DEF_KBD_ERROR : timeout occurs > Description :wait untill output buffer of keyboard controller is full _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
STATUS waitKbdOutputBufferFull( VOID ) { unsigned char kbd_status; int retry; for( retry = 0 ; retry < MAX_RETRY ; retry++ ) { kbd_status = readKbdCtrlStatus( ); if( ( kbd_status & DEF_KBD_STS_OBF ) == DEF_KBD_STS_OBF ) { return( DEF_KBD_OK ); } } return( DEF_KBD_ERROR ); }
PRIVATE BOOL keyboard_disable;
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :keyboardDisableKBD Input :void Output :void Return :void Description :disable a keyboard _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
STATUS keyboardDisableKBD( VOID ) {
/*--------------------------------------------------------------------------*/ /* disable a keyboard */ /*--------------------------------------------------------------------------*/
status = writeKbdCtrlCommand( DEF_KBD_CTRL_COM_DISABLE_KBD ); if( DEF_KBD_OK != status ) { keyboard_disable = False; } else { keyboard_disable = True; } return( status ); }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :keyboardEnableKBD Input :void Output :void Return :void Description :enable a keyboard _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
STATUS keyboardEnableKBD( VOID ) {
/*--------------------------------------------------------------------------*/ /* enable a keyboard */ /*--------------------------------------------------------------------------*/
status = writeKbdCtrlCommand( DEF_KBD_CTRL_COM_ENABLE_KBD ); if( DEF_KBD_OK != status ) { keyboard_disable = True; } else { keyboard_disable = False; } return( status ); }
/* =================================================================================== Description :key state =================================================================================== */
typedef struct { BOOL caps_on; BOOL alt_on; BOOL shift_on; BOOL ctrl_on; BOOL numlock_on; BOOL scrolllock_on; BOOL insert_on; } KEY_STATE; PRIVATE KEY_STATE key_state; PRIVATE unsigned char scan_code;
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :initKeyboard Input :void Output :void Return :STATUS < status of initialization > Description :initialize keyboard driver _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
STATUS initKeyboard( VOID ) { STATUS status;
/*--------------------------------------------------------------------------*/ /* initialize keyboard management information */ /*--------------------------------------------------------------------------*/
key_state.caps_on = False; key_state.alt_on = False; key_state.shift_on = False; key_state.ctrl_on = False; key_state.numlock_on = False; key_state.scrolllock_on = False; key_state.insert_on = False; scan_code = 0x00;
/*--------------------------------------------------------------------------*/ /* set leds of keyboard off */ /*--------------------------------------------------------------------------*/
status = keyboardSetLED( E_KBD_NONE_LED ); return( status ); }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :keyboard_interrupt Input :void Output :void Return :void Description :handling keyboard interrupt _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
void keyboard_interrupt( void ) {
/* --------------------------------------------------------------------- */ /* entering interrupt */ /* --------------------------------------------------------------------- */
enter_interrupt( );
/* --------------------------------------------------------------------- */ /* read scan code from keyboard encoder */ /* --------------------------------------------------------------------- */
scan_code = readKbdEncBuffer( );
/* --------------------------------------------------------------------- */ /* inform end of interrupt to pics */ /* --------------------------------------------------------------------- */
interrupt_done( );
/* --------------------------------------------------------------------- */ /* exit interrupt */ /* --------------------------------------------------------------------- */
exit_interrupt( ); }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :initPIC Input :void Output :void Return :void Description :initialize pics _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
void initPIC( void ) {
/* PIC 初期化関数続き */ /* --------------------------------------------------------------------- */ /* send IMR ot PIC */ /* --------------------------------------------------------------------- */
outPortByte( PORT_MASTER_PIC_IMR, ( ~PIC_IMR_MASK_IRQ0 ) & ( ~PIC_IMR_MASK_IRQ1 ) & ( ~PIC_IMR_MASK_IRQ2 ) ); outPortByte( PORT_SLAVE_PIC_IMR, PIC_IMR_MASK_IRQ_ALL ); }
#define DEF_IDT_INT_NUM_IRQ1 33
setupInterruptGate( DEF_IDT_INT_NUM_IRQ1, keyboard_interrupt );