ファミベーキーボードの特徴は、左右のSHIFTが別キー扱いになっている他、F6,F7,F8があってTAB,BS,SELECT,CAPSがないことである。キー数はMSXと同じ72(テンキーは除く)なので、適当にF6 -> TAB , F7 -> SELECT , F8 -> BS , 右SHFT -> CAPSとかアサインすれば良いだろう。データは4bit毎のシリアル通信で18回に分けて取得する。正論理なのでキーが押されていれば「1」。詳しくはEnriさんのサイトを参照のこと。
一方、MSXのキーボードインターフェイスはパラレル通信で、IOポートの#AAh(bit3:0)に行データ(Yx)を書き込んでから#A9hを読んで8bitずつ取得する。負論理でキー押下状態が「0」。任意のタイミングで任意のキーを読むことができる。
これをPICマイコンで変換することになるが、プログラム的には、メインルーチンでファミベのキーマトリクスをスキャンして、9バイトのバッファメモリに蓄積。一方でMSXの#AAhの書き込みを検出して割り込みをかけ、瞬時に行データ(YA-YD)を取り込んでバッファメモリの内容をGPIOに出力する感じになる。問題はMSXのデータ要求に応えられる速度が出るかどうか。最速だと以下のルーチンになる。
in/out命令はそれぞれ12Tステート消費するが、内訳はM1サイクル5T+メモリサイクル3T+IOサイクル4Tである。PICの処理的にはout命令の終わりで割り込みをかけて、in命令のIOサイクルまでに目的のデータを出力する必要がある。猶予は8T=2.23usとシビアであるが、32MHzドライブのPICならこの間に17命令実行できる。速度的にはいけそうな感じ。
|
|
割り込みのトリガー信号にはS1985のKBDIRが使えそう。この信号は外付けキーボードを接続する際にケーブルの配線を少なくするために用意されているものらしい。 |
|
|
タイミングチャートを見ると、#AA/ABhアクセスの終わりに1.5Clock(0.42us)立ち上がることになっている。PICの割り込み信号に要求されるパルス幅は25ns(0.025us)以上なので十分に追従できるはず。
|
|
ちなみにKBDIR信号はS1985の3pから出力されるが、マッパーアドレスMA18と排他である。よってメモリ512kB化改造している場合この信号は使えない。上で増設した4MBメモリボードはCPLD内部でMA18を生成しているためS1985のMA18は不使用。 |
|
実際のMSXのBIOSによるキーボードスキャンの波形を観測してみた。画像が暗くて見難いが、上半分の矩形波がS1985のYA、その下のドットがKBDIRのHパルスを示している(DIV 20us)。テンキーを含めて11回の行指定がされていることが分かる。YAは都度反転しているのでYマトリクスは0〜10にインクリメントされていると推定できる。
|
BIOSにおける全体のスキャンはVSYNC同期(1.67ms周期)と思われるが、スキャン中の行指定の間隔は実測で約17us。PICで割り込み処理を完了するのに十分な時間的猶予がある。KBDIRのHパルスも理論値0.42usと概ね一致していた。 |
| C0D12: IN A,(0AAH) AND 0F0H LD C,A LD B,11 LD HL,NEWKEY J0D1C: LD A,C ;5T OUT (0AAH),A ;12T IN A,(0A9H) ;12T LD (HL),A ;8T INC C ;5T INC HL ;7T DJNZ J0D1C ;14T |
|
MSX BIOSのキースキャンコードを読んでみた。予想通り、OUT -> IN間隔はあまり余裕がないが、Yマトリクス指定が0〜10でインクリメントされることや、OUT -> OUT周期は63T=17.6usで観測結果と一致していた。
|
画像クリックで拡大
|
PICマイコンに要求されるスペックは、クロック32MHz、テーブル変換データ用メモリ72バイト、8bitバスを含むGPIOが20本(FB側7本+MSX側13本)、IOC(状態変化割り込み機能)ということで、手持ちの16F1933か16F18857が使えそう。いつものようにオールマシン語(笑)でプログラムを書いた。HEXファイルはコチラ(FBKB2MSX.zip)。いずれもRaspberry Pi のPickleで書き込める。16F1933はp14コマンド、16F18857はn14コマンドに対応。
|
|
回路図上はシンプルにS1985とファミベーキーボードの間にPICを繋ぐだけであるが、実際の配線はメイン基板から引き出す信号が多いので意外と面倒。S1985の信号はできるだけ取り出しやすい端子を探して接続した。ほとんどの信号はIC15と集合抵抗RB2から取り出せるが、KBDIRだけは直接S1985から取り出す必要あり。なお、キーボードリターン信号/X1はRB2ではなくIC10の8pから取り出す。
S1985のキーボードリターン信号はリセット時に機能設定ピンとして使われるため、PICにリセット状態を明示する必要がある。PICの/MCLRピンをリセットIC(IC14)の出力端子(5p)に接続した。ちなみにPICのファームウエアでキーボードリターン信号をオープンドレイン出力にしているので、既存のキーボードと並列に繋いでも競合せずに動作するはずである。
余談だが、MSXでは原則カートリッジ式の外付けキーボードI/Fは作ることができない。IO競合の問題が発生するためである。通常、キーボードリターン信号はプルアップされ、オープンドレインのキースイッチからS1985等のキーマトリクス処理系統に入力される。よって今回の改造のようにキーボードリターン信号に並列にオープンドレイン出力のデバイスを接続すれば問題ない。
一方で、S1985やS3527のデータシートを読む限り、キーボードIOアクセス時のデータバスがオープンドレイン出力になるという記載はなく、キー押下のないbitについては普通にHレベルを出力していると思われる(実機では測定していない)。ここでカートリッジが外付けキーボードの押下を検出してLレベルを出力すると本体のH出力と競合する。注意すべきは競合が発生してもLレベルが優位になって一見普通に機能しているように見えることがあり、「機能する=IO競合していない」とは言えない点である。IO競合は故障を誘発する要因になると思われ、このようなカートリッジを作成しようと思うなら事前に本体の回路を調べてキーボードI/Fの出力信号がオープンドレインになっているかどうか確認すべきである。なお、そのような機種が存在するかどうかは不明。
|
|
|
ブレッドボード上でテストを繰り返し、最終的に全てのキーが正しく入力できるようになった。刻印の異なるキーは下記の通り割り当てた。
HVC-007
|
MSX
|
F6
|
TAB
|
F7
|
SELECT
|
F8
|
BS
|
SHIFT(右)
|
CAPS
|
IO直アクセスなど、BIOSのキースキャン以外のタイミングでアクセスがあると正しい応答ができないことがあるが、実用上ほぼ問題ないレベルである。
|
|
|