2025/11/30 22:39
Apple Desktop Bus Protocol (2021)
RSS: https://news.ycombinator.com/rss
要約▶
Apple Desktop Bus (ADB) を用いて古いMacキーボードをUSB‑compatibleに再活性化するプロジェクトです。
- プロトコル概要:ホストは8bitコマンドでTalk/Listen/Reset/Flushを送信し、デバイスは16bitレジスタ(0–3)で状態・設定を保持。
- アドレス割り当て:複数同種デバイスがある場合はレジスタ3をポーリングして衝突回避し、ユニークアドレスを与える。
- 実装方法:STM32 Blue Pill でゼロからコードを書き、ADB信号(Attention, Sync, Stop, Srq)タイミングを正確に再現。
この手順でメカニカルキーボードをモダンPCへ接続できるようになる。
本文
背景
幼少期、母はパワーマックintosh 8500を所有しており、デスクトップ出版作業に使用していました。やがてその機械はパワーマック G4 に置き換えられ—私がコンピュータに興味を持ち始めた頃でした。両親は古いMacでゲーム(例:Lemmings、Fury of the Furries、オランダの教育タイトル、Internet Explorer 5 で動く初期ブラウザゲーム)をプレイさせてくれました。
重要なのは、パワーマックintosh が Apple Extended Keyboard II を標準装備していたことです。これは今でも史上最高クラスと評されるメカニカルキーボードの一つで、両親の手に残っています。ヘアブリーチクリームに過酸化水素を混ぜて「レトロブライト」処理した後も、古いMac ではまだ動作します。
私はこのキーボードを現代ハードウェア用に復活させることにしました。安価な ADB‑to‑USB アダプタは市販されていますが、自分で構築してプロトコルを学びたかったため、STM32 の「Blue Pill」ボード上でゼロからコードを書きました。Arduino や Teensy など類似のプロジェクトは多数存在しますが、私は「ハードコア」な道を選択しました。
以下に ADB プロトコルの簡潔仕様を示します。最も役立った情報は Apple の Guide to the Macintosh® Family Hardware(Apple’s Guide)から取得しています。
ADB:概要
Apple Desktop Bus (ADB) は、キーボード・マウス・トラックボール・タブレットなど複数の入力デバイスをチェーン接続できるシリアルバスです。
- ホストがバスを制御し、コマンドを発行します。
- デバイスはポーリング時または短時間のサービスリクエスト窓でのみバスを使用できます。
- バスのアイドル状態では 5 V がプルアップされ、任意のデバイスが低電位に引き下げることが可能です。
主な特徴
| Feature | Description |
|---|---|
| Device address | デバイスを識別する 4bit の値。複数同種デバイスがある場合、ホストはアドレスを再割り当てできます。 |
| Registers | デバイスごとに最大 4 個の 16bit レジスタがあります。レジスタ 3 はデバイスのアドレスとハンドラ ID を保持します。 |
| Commands | ホストから送るコマンドは 4 種類:Talk(読み取り)、Listen(書き込み)、SendReset、Flush。 |
セットアップ
-
グローバルリセット – ホストがバスを ≥ 3 ms 低電位にします。
-
必要ならば ≤ 1 s の遅延でデバイス(例:AEKII)がリセット完了するまで待ちます。
-
アドレス割り当て – 同種デバイスが複数ある場合、ホストはレジスタ 3 をポーリングして衝突を解消し、ユニークなアドレスを割り当てます。以下は二つのキーボードに対する手順です。
- ホスト → Talk レジスタ 3(addr 2)。キーボード A が最初に応答。
- キーボード B は送信を停止し、再度アドレスが割り当てられるまで黙ります。
- ホスト → Listen レジスタ 3(addr 2)でキーボード A に新しいアドレス(例:8)を与えます。
- キーボード B へ同様に処理し、アドレス 9 を割り当てます。
- 最後の Talk to addr 2 は応答がなく、ホストは次へ進みます。
このステップをスキップしても、各タイプのデバイスが一台ずつしか存在しない場合は問題ありません。
-
通常動作 – ホストはデバイス(既定ではマウス)をポーリング開始します。デバイスはストップビット中にサービスリクエスト (Srq) を主張でき、ホストはレジスタ 0 を再度ポーリングして該当デバイスをアクティブ化します。
タイミング概要(Apple’s Guide)
| Parameter | Nominal | Host ± 3% | Device |
|---|---|---|---|
| Bit‑cell time | 100 µs | – | 3 ms min |
| ‘0’ low time | 65 µs | – | – |
| ‘1’ low time | 35 µs | – | – |
| Attention (low) | 800 µs | – | – |
| Sync (high) | 70 µs | – | – |
| Stop‑bit low | 70 µs | – | ±30% |
| Global reset low | 3 ms | 3 ms min | 3 ms min |
| Srq low | 300 µs | – | ±30% |
| Tlt (high) | 200 µs | 140–260 µs | 140–260 µs |
コマンド
各コマンドは 8bit パケットです。
| Command | Bits | Description |
|---|---|---|
| SendReset | | すべてのデバイスを初期状態にリセット。 |
| Flush | | デバイス固有;通常はレジスタをクリアします。 |
| Listen | | レジスタ RR に 16bit データを書き込みます(バスが忙しい場合トランザクションはキャンセル)。 |
| Talk | | レジスタ RR から 16bit を読み取ります(RR = 3 のとき必ず応答します)。 |
AAAA = デバイスアドレス、RR = レジスタ番号、* = 無視。
トランザクション構造
- Attention – ホストが 800 µs 低電位にします。
- Sync – バスを 70 µs 高電位に保ちます。
- Command byte – 上記の 8bit コマンド。
- Stop bit (0) – 70 µs の低電位;その間に任意デバイスが最大 300 µs で Srq を主張できます。
- Tlt – バスを 140–260 µs 高電位に保ちます。
- Device response – 要求された場合、スタートビット (1)、16bit データ、ストップビット (0)。 Listen の場合はホストが同様にデータを送信します。
Srq が主張されると、ホストは全デバイスのレジスタ 0 をポーリングし、該当デバイスを見つけてアクティブ化します。
レジスタ
| Register | Purpose |
|---|---|
| 0 | メインデータ:キーボードのキーイベント、マウスのオフセット/ボタン。Srq を主張する際には必ずデータを保持している必要があります。 |
| 1 | デバイス固有の補助データ。 |
| 2 | デバイス固有のフラグ(例:LED 状態)。 |
| 3 | 設定とメタデータ:アドレス、ハンドラ ID、SRQ 有効フラグ等。 |
レジスタ 3 のレイアウト
| Bit | Meaning |
|---|---|
| 15 | Reserved (0) |
| 14 | Exceptional event |
| 13 | Enable Srq (1 = enabled) |
| 12 | Reserved (0) |
| 11–8 | デバイスアドレス(4bit) |
| 7–0 | ハンドラ ID |
デバイスとアドレス範囲
Apple’s Guide は最初の八つのアドレスを割り当てています。
| Addr | Description |
|---|---|
, | Reserved |
| エンコードデバイス(例:キーボード) |
| 相対デバイス(マウス、トラックパッド) |
| 絶対デバイス(タブレット) |
| Reserved |
| 再割り当て可能 |
キーボード
二つのプロトコルがあります:Standard と Extended。
レジスタ 0 – キーイベント(両プロトコル共通)
| Bits | Meaning |
|---|---|
| 15 | 最初に離されたキーかどうか (1 = 離した) |
| 14–8 | 最初のキーコード |
| 7 | 二番目に離されたキーかどうか |
| 6–0 | 二番目のキーコード |
パワーキーは両バイトを占有します。
レジスタ 2 – 修飾子 & LED
| Bit | Standard | Extended |
|---|---|---|
| 15 | Reserved | Reserved |
| 14 | Delete (Backspace) | Delete |
| 13 | Caps Lock | Caps Lock |
| 12 | Reset | Reset |
| 11 | Control | Control |
| 10 | Shift | Shift |
| 9 | Option (Alt) | Option |
| 8 | Command | Command |
| 7 | Reserved / Num Lock/Clear | Num Lock/Clear |
| 6 | Reserved / Scroll Lock | Scroll Lock |
| 5–3 | Reserved | Reserved |
| 2 | Reserved / Scroll Lock LED | Scroll Lock LED |
| 1 | Reserved / Caps Lock LED | Caps Lock LED |
| 0 | Reserved / Num Lock LED | Num Lock LED |
Bits 0–2 は Listen で書き込み可能で、LED の制御に使用します。
キーコード
Apple’s Guide(pp. 306, 308)または元投稿に添付された ISO 配列表を参照してください。
マウス
二つのプロトコルがあります:Standard(ハンドラ ID
$0001)と Extended($0004)。
レジスタ 0 – Standard プロトコル
| Bits | Meaning |
|---|---|
| 15 | ボタン状態 (1 = 離した) |
| 14–8 | Y 軸移動量(2’s complement、上方向が負) |
| 7 | Reserved |
| 6–0 | X 軸オフセット(2’s complement、左方向が負) |
標準マウスは約 100 ± 10 counts/inch を報告します。ハンドラ ID を
$0002 に設定すると精度が倍増し(約 200 ± 10 counts/inch)、より高い解像度を得られます。
Extended プロトコルではボタン数と精度が向上しますが、ここでは詳細は割愛します。
仕様書の終わり。