じょんのブログ

じょんのブログ

NEC PC-88VA2を修理(?)している記録です。

↓この続きです。

 

 

PC-88VA用USBキーボード変換器のお話の続きです。

動作確認では、ずっと安物のキーボードを使っていましたが、HUB経由で複数のキーボードを接続する試験のために、ちょっと高級(?)な別のキーボードを接続してみたところ、正常に動作してくれないことが判明しました。

 

接続時のログを調べてみたところ、このキーボードは、以下のように、1つのUSBデバイス内に2つのInterfaceを持っているようです。

  • Interface 0
    HID Boot Keyboard (class=3, subclass=1, protocol=1)

  • Interface 1
    N-Keyロールオーバー キーボード + Consumer Control
    Report ID付き

元々のUSBホストの実装は、

  • 1デバイス = 1キーボード

を前提に処理していたため、同一USBデバイス内に存在する複数のインターフェイスを別々のキーボードと認識して、キーボードオブジェクトを2つ作ってしまい、USBメッセージを奪い合っていたようです。

AIとお話して分かったのですが、このキーボードが特殊というわけではなく、そもそもUSB HIDデバイスでは

  • 1つの物理USBデバイス

  • 複数の論理入力デバイス

という構成が普通に存在するらしいですね。

 

以前に書いた記事で、USBキーボードは一定の時間間隔で、以下の8バイトのデータを垂れ流してくる、と書きました。

ofs. val.
0 modifier
1 reserved
2 usageID 0
3 usageID 1
:
7 usageID 5

これは概ねウソではないのですが、すべてのキーボードが常に上記のプロトコルで動作しているわけではありません。

高級なゲーミングキーボード等では、たくさんのキーの同時押しを正しく処理するために、OS起動後は別のプロトコルに切り替えることがある、ということなのだそうです。

ただし、そういったゲーミングキーボードでも、BIOSブート等の為に上記のプロトコルもサポートする必要があるので、高級なキーボードほど、1つの物理USBデバイスに複数の論理入力デバイスという構成になりがちなのだそうです。

 

上記の表に書いた古典的なプロトコルをBoot Keyboardとか、BIOS Keyboard等と言ったりすようです。

デバイスのインターフェイスディスクリプタの内容で判別可能なので、class=3, subclass=1, protocol=1であることをチェックするように修正し、Boot Keyboard Interface のみ処理するようにしたところ、問題なく動作するようになりました。

 

なかなか奥が深いですね。

↓こちらの話の続きです。

 

1.メカニカルロックキーの扱い

PC-88VAのキーボード、というかPC-8801系キーボードは、CAPSキーとかなキーが、メカニカルロックキーになっています。

そして、キーボードから本体へは、キーのMake/Break、つまり、押した時と離した時にキーコードを送るようになっていす。

このままの仕様だと、本体側は、電源ON直後にメカロックキーがONなのかOFFなのか知るすべがなく、最初にキーを入力した時に、何を表示すべきか困ることになります。

この対策として、電源ON時に、メカニカルロックキーがロック状態、つまり押下されたままの状態だった場合は、そのキーのMakeコードを本体に送るようになっていたようです。

 

しかし、よく見ると、CAPSキーやかなキーのコードを送る前に00h(ESCキーのMakeコードに相当)も送っているように見えることがあります。ESCキーのMakeを送っているのは意味がわからないので、キーボードの状態を何等かのビット並びで送っているのか、電源ONによるノイズなのか、或いはまだバグが残っているのか、よくわかりません。

ご存じの方、いらっしゃいましたら、情報求む!

2. 複数のキーボードを接続した時の動作

PC-88VAに複数のキーボードなんて接続しないかもしれませんが、USBって、ハブが使えるので複数のキーボードを接続することができるんですよね。

そして今回使っている「かんたんUSBホスト」は、ハブ経由で複数のキーボードを接続することに対応しています。

このへんのルーチンはそのまま利用すれば、PC-88VAに複数のキーボードが接続できて、なんか面白いので、そのままにしています。

 

ただし、またしてもCAPSキー/かなキーが問題になります。これらのキーのロック状態は、キーボードのLED状態には全く関係なく、本体内のキーボードBIOSで管理しています。

複数のキーボードでバラバラにCAPSキー/かなキーをON/OFFすると、本体内部の状態とキーボードのLED表示がズレてしまいます。

さすがにこれでは困るので、接続されているいずれかのキーボードでCAPSキー/かなキーを操作したら、接続されているすべてのキーボードのLED状態を更新する必要があります。

「かんたんUSBホスト」では同期するかバラバラに操作するか選択できるようになっていますが、PC-88VAキーボード変換器としては、同期動作一択になります。

3.マウスも接続する?

キーボード変換器としては、まあだいたい完成しました。

一番面倒なUSB接続の部分を「かんたんUSBホスト」の機能をそのまま利用したので、比較的簡単にできてしまいました。

今後のために、もう少しきちんと資料を整理して残しておこうと思います。

 

さて、かんたんUSBホストでは、元々通信以外に、他のI/Oピンを使って色々と設定を変更できるようになっていましたが、PC-88VA用USBキーボード変換器としては、そういった設定機能はほぼ必要ありません。

これらI/Oピンによる各種設定、およびSPI通信を使った設定機能のあたりは、今回の変換器では、ザックリと削除したので、今のところ、I/Oピンは余っています。

 

この余ったピンを活用すれば、USBマウスとかUSBジョイスティックも接続できてしまうような気がしてきました。

まあ、とりあえず先にマウスかな?

因みにキーボードはシリアル通信、しかも片方向通信なので、データ線は1本だけでしたが、マウスの動作には、入力ピンが6本(ボタン用2本、移動データ用4本)必要です。

まあ、気が向いたら考えてみようかな。

 

この続きは↓こちら

 

 

↓だいぶ前の記事ですが、この記事の続きです。

 

久々の投稿です。

ゴールデンウイークに入って時間ができましたので、今日は調子の悪いPC-88VA2のキーボードを分解して掃除…ではなく、キーボード変換器を作っていこうと思います。

はい、前回は、黒井電波さんから発売されていた(現在品切れ中。再販予定は不明。)『かんたんUSBホスト (HIDキーボード用)』を使ったら、比較的簡単にUSBキーボードをつなげられるんじゃないかな?

という話でした。

 

1. 環境構築

記事の中では、そのうちソースコードを公開する予定と書いてありますが、既に公開されています。

q61org/CH559_EasyUSBHost: Firmware for CH559 that converts USB keyboard inputs to ASCII text, with USB hub support.

 

ソースコードは、Ubuntu上で、SDCCというCコンパイラ向けに書かれているので、私のように普段Linuxを使わない人は、まず環境を作成するところから始めなければなりません。

Linux環境の構築って、今までも何度か挑戦しましたが、誰かが書いた記事をなぞって、違いがあるとお手上げの繰り返しでした。

でも大丈夫。今の世の中、チャッピーくんという、(よく嘘つくけど)頼れる味方がいます。

誰かが書いた記事と多少違っても、お手上げにはならなくなりました。

いい時代になりましたね!

 

で、方法は色々とあるのですが、今回はMSYS2のMinGW64環境を構築しました。

Linux用に書かれたソースコードを再コンパイルして、同じ挙動をするWindows上の実行ファイル(*.exe)を作成する環境です。(違っていたらご指摘ください。)

bash.exeもあって、Linuxの基本ツール類もWindows形式の実行ファイル(*.exe)になってそろっています。

つまり、完全なるWindows環境なのですが、何となくLinuxを使っているような気分になれる、という代物です。

 

「かんたんUSBホスト」は、中国の半導体メーカーである南京沁恒(WCH)のワンチップマイコンCH559Lが使われています。

このMPUは、キーボードコントローラ等でよく使われているインテル8051のCPUコア(MCS51)を採用していますが、機能・性能共に、大幅に改良・拡張されたものになっています。

拡張メモリもチップに内蔵されており、「かんたんUSBホスト」ではスタックを拡張メモリに配置しています。

ここで1つ問題があります。スタックを拡張メモリに配置すると、C言語の関数呼び出しインタフェースが変わってしまいます。しかし、そのインタフェースのライブラリはバイナリで提供されておらず、必要ならば自分でソースファイルをコンパイルして作成しなければなりません。

 

これがなかなかたいへんでした。

やりたいことはライブラリのソースコードをコンパイルしたいだけなのですが、.configureを実行すると、コンパイラ本体からすべてコンパイルしようとしてしまい、そうするとgccが無いとか、なんちゃらライブラリが無いとか、色々と文句を言われます。

Makefileを作ってもらうために.configureの実行は必須なので、困ったものです。

しかし、コンパイラ本体のコンパイルは通らなくてもOK。そんなのは公式から実行形式をダウンロードしてくればよいのです。

ただし、ここで注意しなければならないことがあります。

公開されたSDCCの最新の実行形式ファイルと、最新のソースコードのバージョンが微妙に違っていたのです。

というか、そもそもコンパイルエラーが出ていたのはこれが原因だったようです。

ソースコードの最新版Ver.4.5.0に合わせて実行形式もVer.4.5.0を探して再インストール。これでやっとライブラリをコンパイルする環境が整いました。

 

どこに説明があるのかサッパリわかりませんでしたが、拡張メモリスタック配置版のライブラリをコンパイルするには、

make model-mcs51-xstack-auto

とターゲット指定してビルドすると良いそうです。

コンパイルが完了したら、sdcc-4.5.0/build/device/lib/build/large-xstack-autoディレクトリに所望のライブラリが作成されるので、これを/msys64/mingw64/share/sdcc/lib/large-xstack-autoディレクトリに格納すれば完了なのだそうです。

 

…って、そんなのわかるかよ(怒)!

こんなの自力では到底たどり着けなかったと思います。チャッピー様様です。

 

ちなみに、MSYS2には「~環境のbash」を実行するラッパーアプリが、何種類も用意されています。

でも、今回はVS Codeを使って編集をするので、ラッパーからではなく、VS Codeのコンソールから実行できるとベストです。はい、そしてここでもチャッピー登場!

コンソールでCtrl+Shift+Pでユーザー設定(*.json)を開いて、

"MSYS2 MINGW64": {
  "path": "C:\\msys64\\usr\\bin\\bash.exe",
  "args": ["--login"],

  "env": {
    "MSYSTEM": "MINGW64",
    "CHERE_INVOKING": "1"
  },
  "overrideName": true
}

を適切な場所に追加すればよいそうで…。

こちらも以前だったら間違いなく諦めていた内容ですね。

これで無事、VS Codeのコンソールからmakeできるようになりました。

2. ソースコード

さて、やっとソースコードの内容を見る段階に入りました。

元々「かんたんUSBホスト」はUSBキーボードから入力したデータをシリアルポートにテキストで出力するというものです。

USBキーボードは一定の時間間隔で、以下の8バイトのデータを垂れ流してきます。

ofs. val.
0 modifier
1 reserved
2 usageID 0
3 usageID 1
:
7 usageID 5

modifierは、いわゆるシフトキー、Ctrlキー等の状態です。ビット毎に以下のようになっています。

bit 7 6 5 4 3 2 1 0
key GUI(R) Alt(R) Shift(R) Ctrl(R) GUI(L) Alt(L) Shift(L) Ctrl(L)

reservedは使われていません。0が入っています。
usageIDはキースキャンコードです。6バイトあるので、6つまでキーの同時押しを検出できます。

 

対して、PC-88VAのキーボードの方は、キーのMake/Breakのタイミングで、1バイトのデータを送ります。

1バイトデータの内容は、bit0~6が、7ビットのキースキャンコードで、bit7はMake=0/Break=1です。

つまり、変換器は、USBキーボードから送られてくるキー状態を前回値と比較して、状態の変化分をPC-88VA本体に送信する必要があります。

因みに、PC-88VAでは、modifierのキーも他のキーと変わりません。

なので、modifierキーも同様にMake/Breakを検出してキースキャンコードを送ればよいということになります。

ちょっと考えなければならないのは、[CapsLock]キーと[かな]キーです。

PC-88VAではこれらのキーはメカニカルロックになっていて、1回押すとMakeコードが発生して押しっ放しの状態になります。もう1回押すとBreakコードが発生してキーが解放されます。

対してUSBキーボードでは、キーを押す度にLEDがON/OFFしてロック状態を変化させます。キーの押下状態からMake/Breakを監視するのは変わりませんが、Makeの時にLED状態をトグルして、LED状態に応じてキースキャンコードを送信します。

 

あとはキーマップですが、これはクラシックPC研究会さんのクラシックキーボード88VAを参考にさせていただきました。

PC-88VAにあるのにUSBキーボードに無くて困るのは、テンキーの[,]と[=]ですね。

これらはちょうどファンクションキーが2個余っているので、F11, F12に割り当てられています。

まあ、正直、私はテンキーを使わない人なのでどうでも良いのですが…

 

主なキー変換は以下の通りです。

USBキーボード PC-88VAキーボード
半角/全角 全角
Windowsキー PC
Alt GRPH
無変換 決定
変換 変換
カタカナ/ひらがな かな
Menuキー PC
F11 テンキー[,]
F12 テンキー[=]
Print Screen 画面コピー
Scroll Lock (割当て無し)
Pause Break 停止
Insert 挿入
Delete 削除
Home 画面消去
End 説明
Page Up ROLL DN
Page Down ROLL UP
Num Lock (Num Lock)

 

LEDの方は、CapsがそのままCAPS状態、Scrollが[かな]キー状態としています。

Num Lockについては、クラシックPC研究会さんの変換器ではNum Lockキーがテンキー[,]に割当てられていますが、私はそのままNum Lockキーとしました。

実は私が持っているUSBキーボードはコンパクト系ばかりで、Num Lockキーが使えないとテンキー入力に困るからです。困るキーボードもあるということで、そのままNum Lockキーとして残します。本体にキーコードは送りません。

あと、クラシックPC研究会さんのキーバインドでは、Scroll LockキーもPCキーに割り当てていますが、私はちょっと違和感を感じるので、割当て無しにしています。こちらも本体にキーコードを送りません。

 

3.進捗状況

まだ時々止まっちゃうことがあるので、何かバグがあるのだと思いますが、普通の操作をする限りにおいては、だいたい問題なく動作しているようです。

電源ON時にWindowsキーを押しながら起動すれば、ちゃんと初期設定画面にも移行します。

とりあえずもう少しデバッグは継続する予定です。

冒頭の写真の通り、まだブレッドボード状態なので、子亀基板化とか作って、ちゃんとした変換器にしたいな…。

 

反応の悪い元のキーボードの掃除とかスイッチの交換も真面目に考えてみてもいいかもしれませんが、物理的に形の合うような、都合のいい交換部品は無いかもしれません。
そんな時にこれがあれば、キー入力の問題は解決です。

既にハードウェアが入手困難なので皆さんに使ってもらうのは難しいかもしれませんが、誰かが同じことをしようとした時の参考になれば幸いです。

 

この続きは↓こちら