MC6800 ROMモニタ自作 その23 ~VDGとUSBキーボードで単体機っぽくなってきた~

前回あたりから、ROMモニタのVDG表示、SDFS/68、USBキーボードまわりを並行して触っています。画面が出て、キーボードがつながって、SDFS/68の DIR まで見えてくると、だんだんROMモニタというより「小さいコンピュータ環境を作っている」感じになってきます。
で、今回の話を書こうとして少し迷いました。これはまだROMモニタネタなのか?
でも、やっぱりROMモニタの話でした。INEEE で1文字入力する。OUTEEE で1文字出力する。このMIKBUG互換の入口は変えずに、その裏側でVDGへ表示をミラーしたり、2nd ACIAのキーボード入力を拾ったりしています。外から見える入り口はなるべくそのままにして、実機の使い勝手だけ少しずつ単体機っぽくしている、という話であります。
VDG画面とキーボードでだいぶ単体機っぽい
VDG表示がだいぶ使えるようになった
K68-VDGの表示は、これまでもPoCとしては出ていました。ただ、最初のころは「文字が出る」くらいで、端末として使うにはまだいろいろ足りませんでした。シリアル端末ならCR/LFまわりは端末側がだいたいうまく扱ってくれます。でもVDGの画面はただのVRAMなので、ROMモニタ側でちゃんと行制御しないといけません。
今回、VDG console側でこのへんを整理しました。CRは次行先頭へ、LF単独でも改行、CRLFでは二重改行しない。行末を越えたら次行へ送り、最終行を越えたら1行スクロールする。BS/DELでは1文字戻して消す。書いてしまうと普通の端末処理ですが、いざ8KB ROMの中でやるとなると地味に効きます。
以前は画面末尾まで行くとVRAM先頭へ巻き戻るような動きが残っていました。これはテスト表示ならよいのですが、モニタ画面として見るとつらいです。今回はちゃんと上へスクロールするようにしました。
あと、カーソルも入りました。最初はVDG文字の都合で、なんだか左矢印みたいに見えるカーソルになっていて、実機で見たときに「何かと思ったw」となりました。最終的には $20 の黒背景スペースっぽい表示にして、黒豆腐みたいなカーソルにするのもありかなと思っています。このあたりは見た目の好みもありますが、今はまず「入力位置が分かる」ことを優先しています。
VDGの32桁画面にSDFS/68のDIRが出ている
USBキーボードをROMモニタの入力にする
もう一つ進めたのがキーボード入力です。USBキーボードそのものは、別で作っているKKBD-USBが担当しています。Raspberry Pi PicoでUSBキーボードを読み、ASCIIに変換して、SBC側へUARTで送ります。
MC6800側から見ると、これは2つ目のACIAです。
`1st ACIA 既存のシリアル端末
2nd ACIA $8094-$8095 KKBD-USBからのキー入力`
ここで少し悩みました。入力元が2つあるなら、ROMモニタ側に切り替えコマンドを作る? それとも、SDFS/68や外部プログラムにも「キーボード入力」と「シリアル入力」を見せる?
でも、それはやりたくありませんでした。MIKBUG互換入力を使う外部プログラムには、キーボードが2つあることを意識させたくないです。外部から見れば、今まで通り JSR INEEE でAレジスタに1文字返るだけであってほしい。
なので、内部で統合入力ルーチンを作りました。動きは単純です。
`2nd ACIAに文字がある → それを読む
なければ1st ACIAを待って読む`
つまり、USBキーボード優先、シリアルfallbackです。これで、ROMモニタのコマンド入力も、SDFS/68のコマンド入力も、同じ INEEE 経由で自然に動きます。
USBキーボードからPico経由で2nd ACIAへ入れる
SDFS/68もVDG画面で見えてきた
ここまで来ると、やはり試したくなるのはSDFS/68です。ROMモニタから BOOT して、stage1を読み、SDカードのFAT rootにある SDFS.BIN を起動します。
VDG画面で見ると、こんな感じです。
`] BOOT
SDFS/68 V1.2 #150
SDFS> DIR
SDFS.BIN A 00000A9A
HELLO.S A 00000052
HELLO2.S A 00000052
SDFS>`
おお、見えた。SDFS/68自体は前から動いていましたが、シリアル端末の画面ではなく、VDG画面とUSBキーボードで操作できるようになると、かなり雰囲気が変わります。いきなりDOSっぽい。
ただし、ここで大事なのは、SDFS/68側に特別な「VDG対応」を入れたわけではないことです。SDFS/68は今まで通り INEEE / OUTEEE 相当の入出力を使っています。その下のROMモニタ側で、入力元を統合し、出力をVDGへミラーしているので、結果としてSDFS/68もVDG画面で使えるようになりました。これはなかなか気分がよいです。
でもまだスタンドアロンではない
ここまで来ると、シリアル端末を外して、VDG画面とUSBキーボードだけで動かしたくなります。でも、まだ完全なスタンドアロンではありません。
実機で試したところ、元々のシリアルをつないでいないと、起動メッセージ MC6800 MONITOR の1文字目出力で詰まりました。これは今の設計では自然です。ROMモニタの出力はあくまでUARTが主経路で、VDGはミラーです。つまり、1st ACIAの送信待ちで止まると、VDGへ表示するところまで進みません。
このあたりは、スタンドアロン化するならちゃんと考える必要があります。VDG向けprofileではUART送信待ちにtimeoutを入れるのか。UARTなしでも進むスタンドアロンprofileを別に作るのか。MIKBUG互換出力をどこまで維持するのか。このへんは別Issueにしました。
シリアル側では従来通り全部見えている
気になっているところ
今回の実機確認で、ほかにもいくつか気になるところが見えてきました。
まず、VDG側でSDFS/68を起動したとき、DIR や RUN の直後に余計な空改行が入ることがあります。UART側ではそこまで気にならないのですが、VDGの32桁画面だと空行の存在感が大きいです。これはSDFS/68側のCR/LF出力と、ROMモニタ側のVDG行制御の相互作用を見た方がよさそうです。
それから、Dコマンドが横に長すぎます。シリアル端末なら80桁くらいあるのでよいのですが、VDGは32桁です。今のDコマンド出力は1行が長く、VDGではかなり見にくいです。既存の D 互換は壊したくないので、VDG向けに8バイト/行の狭幅ダンプ表示を追加する案を別Issueに分けています。
あと、VDGなしの sbcio profileでも、ハード的にはSBC-IOのSDカード回路があります。FEATURE_SD=1 にすればSDFS/68 boot構成として使えるはずですが、現状の make stage1 / make sdfs は sbcio_vdg / k6802_vdg というprofile名を直接見ていて、軸指定だけでは通りません。ここもbuild profile整理の課題です。
だいぶ単体マイコン機に近づいた
そんなわけで、今回はVDG表示と2nd ACIAキーボード入力をROMモニタ側へ統合しました。まだ完全なスタンドアロンではありません。でも、画面にROMモニタの MAP が出て、USBキーボードから BOOT して、VDG画面で SDFS> DIR が見えるところまで来ました。
これはだいぶ楽しいです。最初はシリアル端末からメモリを覗くだけのROMモニタでしたが、少しずつ「画面とキーボードのあるMC6800機」っぽくなってきました。
次は、SDFS/68のVDG+keyboard操作をもう少し詰めたいところです。空改行を直して、Dコマンドの狭幅表示も入れて、1st ACIAなしでどこまで動かすかを決める。このへんをやると、かなり実用的な画面端末になりそうであります。
関連リンク
- Issue #168: VDG console: CR/LF、BS、簡易スクロールを整える
- PR #180: fix: VDG consoleの行制御を整える
- Issue #169: keyboard console: 2nd ACIAキーボードをROM入力へ統合する
- PR #181: fix: 2nd ACIAキーボードを入力経路へ統合する
- Issue #170: SDFS/68のVDG+keyboard統合確認
- Issue #179: D command: VDG向けの狭幅ダンプ表示を追加する
- Issue #182: VDG: SDFS/68でDIR/RUN直後に余計な空改行が入る
- Issue #183: VDG: 1st ACIA未接続でも起動表示で停止しないスタンドアロン動作を検討する
- Issue #184: build: stage1/sdfs生成条件をprofile名固定からSD機能軸へ整理する