MC6800 SDFS/68を作る その7 ~VDGとキーボードでスタンドアロン機っぽくする~

SDFS/68MC6800 SDFS/68を作る その7 ~VDGとキーボードでスタンドアロン機っぽくする~

前回は、SDFS/68で .COM トランジェントコマンドっぽいものを動かしました。SDカード上の HELLO.COMARGS.COM をロードして、RTS でSDFS/68へ戻ってくる。かなり小さいDOSっぽくなってきました。

今回は、機能追加というより「実機で使うときの環境を整える」話です。

K68-VDGの画面と、2nd ACIAにつないだキーボードだけで、ROMモニタから BOOT して、SDFS/68の DIRLOADRUNEXIT を使えるようにする。要するに、Macのターミナルを開かなくても、スタンドアロンの小さいパソコンっぽく操作できるところまで持っていきます。

そして、その途中でUARTの扱いとビルド手順も整理しました。

UARTを外しても止まらないようにしたい

もともとのROMモニタは、1st ACIAのUARTが主コンソールでした。文字を出すときは、ACIAの送信レディ、つまり TDRE を待ってから送ります。

UARTだけで使うなら、これは自然です。

でもVDG画面がある構成では、話が変わります。画面には出せるのに、1st ACIA側の状態が悪いせいでROMモニタやSDFS/68が止まると困ります。USBシリアルをつないでいない、あるいはUSBシリアル側の制御線や状態が微妙、というだけで起動表示が止まるのは、スタンドアロン機としてはつらいです。

そこで、FEATURE_VDG=1 のROMでは、1st ACIAは必須コンソールではなく「補助のミラー出力」として扱うことにしました。

`VDG有効ROM:
  VDG画面には必ず出す
  UARTは送信できるときだけ出す
  UARTが送信不可なら、その文字は捨てて進む`

これで、1st ACIAの TDRE が立たない状態でも、VDG画面とキーボードだけで起動して操作できます。

ただしUARTログは文字落ちする

ところが、実機で確認すると別の問題が出ました。

USBシリアルをつないでMac側でログを見ていると、UART側の文字が取りこぼされることがあります。9600bpsでも起きます。

これは理屈としては自然です。9600bpsは1文字に約1msかかります。MC6800側のVDG表示処理はそれより速く次の文字を出しに行けます。直前の文字を送った直後は、まだACIAの TDRE が立っていない。そこで待たずに次の文字を出そうとすると、その文字はUARTへ送れず捨てられます。

スタンドアロン性を優先するとUARTログは欠ける。UARTログを優先するとACIAの状態次第で止まる。

両方を自動でうまくやるには、有限待ちタイムアウトなども考えられます。でもMC6800で「少し待つ」を文字ごとに入れると、すぐ体感速度に効きます。しかも実機ごとにちょうどよい待ち時間を決めるのも面倒です。

そこで今回は、手動で切り替えることにしました。

UWコマンドを追加した

VDG有効ROMに UW コマンドを追加しました。UART Waitのつもりです。

`] UW
UW OFF`

起動時のデフォルトは UW OFF です。この状態では、UARTが送信不可なら文字を捨てて、VDG画面を止めません。

`] UW ON
UW ON`

UW ON にすると、従来どおりACIAの TDRE を待ってからUARTへ送ります。Mac側でUSBシリアルログをちゃんと取りたいときは、これを使います。

`] UW OFF
UW OFF`

UW OFF に戻せば、またスタンドアロン優先です。

注意点は、UW ON は本当に待つことです。USBシリアル未接続、制御線の状態異常、ACIA送信不可などでは止まり得ます。だからデフォルトはOFFにしました。普段はVDG+keyboardだけで使う。ログを取りたいときだけ人間が明示的にONにする。これが一番わかりやすい落としどころでした。

SDFS/68の余計な空行も直した

VDG画面でSDFS/68を使っていると、UART表示よりVRAM側だけ1行多く空くことがありました。

特に SDFS> DIR の直後です。UARTでは普通に見えているのに、VDGだけ空改行が増える。原因はCR/LFの扱いでした。

SDFS/68やROMモニタ側は、場面によってCR、LF、CR/LFを出します。VDG側がそれを全部単純に改行扱いすると、CRの直後のLFや連続CRで余計に行が進みます。

そこでVDGの文字出力で、CR/LFと連続CRを整理しました。

`CR      → 改行
CR LF   → 1回だけ改行
CR CR   → 2回目のCRでは追加改行しない
通常文字 → CR状態を解除`

これで、SDFS/68の DIR 実行直後にVDGだけ空行が増える現象は収まりました。

32桁画面向けのDSも入れた

VDGは横32桁です。従来の D コマンドは16 byte/行で、ASCII欄も出します。UARTなら便利ですが、32桁のVDG画面では折り返されます。

そこで、VDG有効ROMだけに DS を追加しました。Dump Shortです。

`] DS0100
0100 00 01 02 03 04 05 06 07
0108 08 09 0A 0B 0C 0D 0E 0F`

8 byte/行、ASCII欄なしです。1行は28桁くらいなので、VDGの32桁に収まります。

既存の D はそのままです。UARTで広く見たいときは D、VDG画面で折り返したくないときは DS、という使い分けです。

ビルド手順も整理した

今回もうひとつ整理したのがビルドです。

ここは自分でも混乱しやすいところでした。MONITOR_PROFILE という名前と、実際の構成要素がだんだん増えてきたからです。

今ある主なprofileはこうです。

`base        最小ROM。SDなし、VDGなし
sbcio       SBC-IO RAM拡張 + 2nd ACIAキーボード。SDなし
sbcio_vdg   SBC-IO + VDG + keyboard + SD BOOT
k6802_vdg   K6802-SBC向け。VDGのVRAM配置違い + SD BOOT`

普段のVDG+keyboard+SDFS/68構成は、今までどおりです。

`MONITOR_PROFILE=sbcio_vdg make bin
MONITOR_PROFILE=sbcio_vdg make stage1
MONITOR_PROFILE=sbcio_vdg make sdfs`

K6802-SBC側ならこうです。

`MONITOR_PROFILE=k6802_vdg make bin
MONITOR_PROFILE=k6802_vdg make stage1
MONITOR_PROFILE=k6802_vdg make sdfs`

ここは変えていません。

変えたのは、stage1 / sdfs を作れるかどうかの判定です。

以前はprofile名で見ていました。

`MONITOR_PROFILE が sbcio_vdg または k6802_vdg ならOK`

でも、SDFS/68の起動に必要なのはVDGそのものではありません。必要なのは、ROM側にraw SD sector readと BOOT があり、SBC-IOがあり、stage1とSDFS/68を置けるRAM配置であることです。

そこで、判定を構成軸へ変えました。

`FEATURE_SD=1
BOARD_IO=sbcio
MEMORY_CONFIG が stage1対応RAM配置
なら stage1 / sdfs を生成できる`

これで、VDGなしSBC-IOでもSDFS/68を使う構成を作れるようになります。

VDGなしSBC-IOでSDFS/68を作る

標準の sbcio profileは、今までどおりSDなしです。これは変えません。

でも必要なときは、構成軸を上書きしてSD BOOTを入れたROMを作れます。出力名を短く安定させるため、BUILD_CONFIG_NAME=sbcio-sdfs を付けます。

`MONITOR_PROFILE=sbcio FEATURE_SD=1 FEATURE_FAT=0 BUILD_CONFIG_NAME=sbcio-sdfs make bin
MONITOR_PROFILE=sbcio FEATURE_SD=1 FEATURE_FAT=0 BUILD_CONFIG_NAME=sbcio-sdfs make stage1
MONITOR_PROFILE=sbcio FEATURE_SD=1 FEATURE_FAT=0 BUILD_CONFIG_NAME=sbcio-sdfs make sdfs`

出力はこうなります。

`build/mc6800-monitor-sbcio-sdfs.bin
build/stage1-sbcio-sdfs.bin
build/SDFS-sbcio-sdfs.BIN`

これで、VDGは使わず、UARTコンソールのままSDFS/68を起動するSBC-IO構成も作れます。

ROM焼きは今までどおり

W27C512へ sbcio_vdg のROMを焼くなら、コマンドは今までどおりです。

`MONITOR_PROFILE=sbcio_vdg make program ROM_KIND=W27C512`

確認だけなら:

`MONITOR_PROFILE=sbcio_vdg make verify ROM_KIND=W27C512`

ROMライタ用のファイルだけ作るなら:

`MONITOR_PROFILE=sbcio_vdg make rombin ROM_KIND=W27C512`

sbcio_vdg では、ROM側は BOOT 入口を持ちます。SDFS/68本体はROMに焼くのではなく、system SD側に置きます。

`MONITOR_PROFILE=sbcio_vdg make stage1
MONITOR_PROFILE=sbcio_vdg make sdfs`

生成される build/SDFS-sbcio-vdg.BIN は、SDカード上では SDFS.BIN という名前でrootに置きます。stage1はfixed boot areaへ入れます。ここはSDFS/68の仕組みとして、ROM本体とは別の成果物です。

実機で一段落した

今回の流れで、VDG+keyboard環境はかなり実用に近づきました。

  • VDG画面にROMモニタとSDFS/68の表示が出る
  • 2nd ACIAキーボードから操作できる
  • 1st ACIA UARTが送信不可でも、デフォルトではVDG側が止まらない
  • UARTログを取りたいときは UW ON にできる
  • SDFS/68の DIR / LOAD / RUN / EXIT をVDG+keyboardで確認できる
  • VDG向けに DS で32桁以内のダンプもできる
  • VDGなしSBC-IO + SDFS/68構成も、構成軸指定で作れる

このあたりまで来ると、SBC6800にSDカードと画面とキーボードをつけて、小さいスタンドアロン機として動かしている感じがかなり出ます。

次はサブディレクトリか

SDFS/68側は、root directoryのファイルを扱うところまではかなり整ってきました。

次に大きく使い勝手を上げるなら、サブディレクトリとpath指定です。

`SDFS> DIR /BASIC
SDFS> LOAD /BASIC/HELLO.S
SDFS> RUN GAMES/DEMO.S`

みたいなことをやりたい。

ただ、ここは単に文字列をparseすれば終わりではありません。path parser、directory cluster走査、カレントディレクトリを持つかどうか、8.3名の扱い、LOAD / RUN / .COM との関係など、決めることが多いです。

なので、その前に今回のような土台整理をしておきました。VDG+keyboardのスタンドアロン環境、UARTの待ち方、ビルド構成軸。ここが曖昧なままpath対応へ入ると、後でたぶん混乱します。

地味ですが、ここでいったん足元が揃った感じです。

関連リンク

SDFS/68