スキャンコード

**スキャンコード** (scancode) とは、コンピュータのキーボードのキーが押されたり離されたりしたときに、キーボードからCPUに送られるコード（符号）のこと。**走査コード**（そうさコード）ともいう。

## 概要
コンピュータのキーボードでは、たとえば「A」のキーを押した場合、「A」という文字の文字コード（ASCIIコードなど）が直接送られるわけではない。

キーボードコントローラは、キーの押下あるいは解放を検出すると、そのキーに固有のスキャンコードをCPUに送る。スキャンコードは、キーボードのキーを物理的に識別するものであり、そのキーの表す文字や機能とは関係ない。CPUはスキャンコードを受け取ると、キー配列の設定や修飾キー・ロックキーなどの状態を参照して、該当する文字の入力として受理したり、修飾キーやファンクションキーの処理を実行したりする。

キーが押されたときに発生するスキャンコードを**メイク** (make) コード、離されたときに発生するものを**ブレイク** (break) コードという。同じキーのメイクとブレイクはMSBやプレフィクスコードによって区別されることが多い。オートリピート（タイプマティック）の処理をキーボード側で行う場合、キーが押されている間、メイクコードを周期的に発生する。

スキャンコードの体系はコンピュータの機種によって異なる。また、インタフェース規格によって決まっていることもある。さらに、同じ機種・インタフェースであっても、複数の体系をもっている場合もある。そのため、オペレーティングシステム (OS) は受け取ったスキャンコードをOS独自の仮想キーコードに変換・統一してから扱うのが一般的である。

## キー配列とスキャンコード
キーボードには、国や言語によってJIS配列・US配列などさまざまなキー配列があるが、同じ機種用・同じインタフェースのキーボードであれば、キートップの刻印にかかわらず、物理的に同じ位置にあるキーは同じスキャンコードを発生するのが普通である（たとえば、パーソナルコンピュータ (PC) のキーボードでは、「1」の左のキーはJIS配列では「半角/全角」、US配列では「` ~」であるが、スキャンコードは同じ）。

すなわち、キートップの刻印の違いは多くの場合表面的なもので、物理的な配列が類似していれば、スキャンコードのレベルではほとんど変わりがない（特に欧州各国のキーボードのように、物理的なキー配列に差がない場合は、刻印を無視すればまったく同一のキーボードとみなせる）。

したがって、JIS配列キーボードにUS配列の設定を適用するなどしても、ほとんどのキーは問題なくUS配列として動作する（一部、物理的にキーの有無や位置が異なるものについては、この限りではない）。

## PC/AT・PS/2キーボードのスキャンコード
PC/AT互換機のスキャンコードは、歴史的な経緯により複雑な体系となっている。

以下、スキャンコードの値を16進数2桁で表す。

; 83キーボード (IBM PC, PC/XT)
* 最初の製品であるためスキャンコードは整然としている(01〜53)。ブレイクはMSBを立てることで示す。
; 84キーボード (PC/AT)
* 物理的な配置は一部変更されたが、スキャンコードは変わっていない。SysReqキーが追加された(54)。
; 101拡張キーボード (PC/AT)
* キーが大幅に追加された。
* 右Ctrl・右Alt・テンキーのEnter・テンキーの/（スラッシュ）は、それぞれ左Ctrl(1D)・左Alt(38)・Enter(1C)・/(35)にプレフィクスE0がつく。
* 従来テンキーと兼用していたカーソルキー、Insert、Delete、Home、End、PageUp、PageDownが独立した。それぞれ対応するテンキーのコードにプレフィクスE0がつく。
* F11(57)、F12(58)は新規のコード。
* PrintScreenキーは83/84キーボードではShift(2A)+テンキーの*(37)だったため、E0 2A E0 37を発生する。
* SysReqキー(54)がなくなり、Alt+PrintScreenとなったため、Alt+PrintScreenで54を発生する。
* Pauseキーは83/84キーボードではCtrl(1D)+NumLock(45)だったため、E1 1D 45を発生する。また、オートリピートの対象外であり、すぐにブレイクコード(E1 9D C5)を発生する。
* Ctrl+Pause(Break)キーは83/84キーボードのScroll Lock(46)にならってE0 46を発生する。また、オートリピートの対象外であり、すぐにブレイクコード(E0 C6)を発生する。
; 101拡張キーボード (PS/2)
* 従来のコード体系をコードセット1とし、新たにコードセット2と3が定義された。
* コードセット2は、コードの値は一新されているものの、コードセット1のプレフィクスや歴史的特例などは保たれており、セット2からセット1に機械的に変換可能。ただしブレイクはプレフィクスF0で表す。
* コードセット3はさらに整然とした体系として再定義されており、コードセット1/2のプレフィクスや特例は廃止され、すべてのキーがシンプルな1バイトのメイクコードを発生する。コードの値はセット2とおおむね共通（一部異なる）。ブレイクはプレフィクスF0で表す。

今日のPC/AT互換機では、キーボードはスキャンコードセット2を発生し、本体のキーボードコントローラがこれをセット1に変換してCPUに送るのが一般的である。(この変換をしない設定にもできる。PCやPC/XTにはこの変換がないためセット1しか受け付けない)ただし、ノートPCでは直接セット1を発生し変換しないものがある。セット3は使われていない（3270 PCなどで使用される。UNIXワークステーションのキーボードでセット3を発生するものがあるが、このようなものはPCのBIOSやOSでは通常使うことができない）。

リピートはメイクのみを繰り返し、離した時点でブレイクとなる。

## Macintosh ADBキーボードのスキャンコード

## PC-9800キーボードのスキャンコード
PC-9800/9821シリーズのキーボードは、いくつかのキーが追加された程度で大きな変化がなかったため、スキャンコードも整然としている。ブレイクはMSBを立てることで表す。リピートはメイクとブレイクの連続を繰り返す。左右のSHIFTキーや右SHIFTの上のリターンとテンキーのリターンはそれぞれが電気的に並列に接続されているため区別することはできない。
一部のハイレゾ機用キーボードにあるHOMEキー（←と→の間）・CLRキー（テンキー）ともに、一般機のキーボードにあるHOME CLRキーとはコードが異なる。

なお、PC-9800シリーズの資料ではスキャンコードでなくキーコードと呼んでいる。

## USBキーボードのUsage
USBでは、キーボードはヒューマン・インタフェース・デバイス (HID) デバイスクラスの一部として定義される。HIDデバイスクラスでスキャンコードに相当するものは**Usage**という用語で呼ばれている情報である。

Usageは32ビットの符号なし整数で、USB IFにより定義されリストされている。HID Usage Table

Usageの上位16ビットを**Usage page**下位16ビットを**Usage ID**と呼ぶ。
UsageはあるHIDデバイスが送信(あるいは受信)するある数値 (Report) が**どのような物理状態を表現しているのか**をホストに通知するために使われる。すなわちUsageは値 (report) の使われ方 (usage) を定義する。例えばマウスのようなデバイスの場合2つの-127〜+127の範囲のReportを送るとすると、それらのUsageは0x00010030 (Generic desktop-X) と0x00010031(Generic desktop-Y)であるとHIDデバイスはホストに送信する。
キーボードの場合にはReportの値として、Usageそのものを送信する。

Usageは32ビットありこれをすべて送ると不経済であるため省略して送ることができる。あるReportの集まりが共通のUsage Pageを持つUsageだった場合には、グループ化して表現でき、下位16ビットのUsage IDだけを送信することができる。またUsage PageやUsage IDの上位ビットが0だった場合にはそれを省略できる。このためキーボードのUsageは、たとえば"A"キーは'0x00070004'ではなく'0x04'だけを送るようにできる。

一般的なキーボードでは、押されたり離されたりしたキーのスキャンコードだけを送るが、USBキーボードのデータの送信方法はこれとはかなり異なり、そのときに押されているすべてのキーの情報を静的に送る。そのため、以下のような性質がある。
* Aキーを押したままBキーを押すと、Bキーを押した時点で送られるHIDレポートには、AキーとBキーの両方のUsage IDが含まれる。そのため、今回新たに押されたのはBキーであるということは、本体側で判定する必要がある。
* キーを離した場合にも、どのキーが離されたかを送るのではなく、離した後の状態を送るため、キーが離されたことはやはり本体側で判定する必要がある（したがって、ブレイクコードに相当するものはない）。
また、オートリピートやLEDの制御もキーボード内部では行わない。
キーボードは単なるスイッチに徹するという思想で設計されているということができる。

多くのUSBキーボードが送信するHIDレポートはUSB HID規格書にある**"Boot protocol"**と同一となっていて8バイトである。先頭バイトは、そのとき押されている修飾キーを示す8ビットのフラグである。PC用キーボードのAltキー・WindowsキーとMac用キーボードのOptionキー・Commandキーはそれぞれ同じに扱われる。HIDレポートの後ろ6バイトは、そのとき押されているキー（最大6個、修飾キーは除く）のUsage IDが入る。ロックキーも一般のキーと同様に扱われる。

USBは特定の機種に依存したものではないため、キーボードもAT互換機・Mac・PC-9800/9821シリーズ・UNIXワークステーションなどさまざまな機種間でなるべく共通化できるように定められている。そのため、異なる機種用のUSBキーボードを接続しても、基本的には操作が可能である。

最近のキーボードは、CD・DVDなどを再生する「マルチメディアキー」や、ウェブブラウザ・電子メールクライアントなどを起動する「インスタントキー」を備えているものが少なくないが、キーボードのUsage page (0x0007) のUsage IDの定義にはこれらのキーは含まれていない（音量調節関連キーは例外）。これらのキーはConsumer pageのUsage IDとして定義されている。
このようなキーを備えるUSBキーボードは、通常内部的にはkeyboard usage pageを生成するデバイスとConsumer usage pageを生成するデバイス（リモコンなどの類）の複合デバイスになっている。Boot protocolでのreportがkeyboard usage pageのみで構成されているため互換性確保のためこのような実装になっていることが多いものと思われる。

初期のMac用USBキーボードには従前のADB用キーボードと同様にパワーキーがあった。信号線とGNDを接続する仕組みになっており、USB規格外である。

## 関連項目
* キーボード (コンピュータ)
* キー配列
* PS/2コネクタ
* Apple Desktop Bus
* ユニバーサル・シリアル・バス (USB)
* ヒューマン・インタフェース・デバイス

## 外部リンク
* USB Implementers Forum HID Information
* Keyboard scancodes: written by Andries Brouwer
*  - Detailed information on keyboard scancodes from beyondlogic.org
* Keyboard Scan Codes (XT) 
* Keyboard Scan Codes (AT)