MC6800 ROMモニタ自作 その26 ~BOOT3でSDFS/68 v3が実機起動した日~

MC6800 ROMモニタMC6800 ROMモニタ自作 その26 ~BOOT3でSDFS/68 v3が実機起動した日~

前回はSDFS/68 v1.3で電大版Tiny BASICを.COMとして動かすところまで進みました。今回はその続きで、いよいよSDFS/68 v3です。(v2が飛んだのは気にしない)

v3といっても、いきなり全部作り直すのではなく、RAM上にresidentを置いて、ROMモニタ側からCMD DIRCMD HELLO.COMのように呼び出す構成です。

今日のゴールは「K6802-SBC + K68-VDG の実機で、ROMのBOOT3コマンドからSDFS/68 v3 residentを直接ロードして、CMD DIR.COM実行まで通す」でした。

結果から言うと、動きました。BOOT3コマンドでv3 SDFSをロードしたあとにCMD DIRが通り、CMD HELLO.COMも動きました。ここまで来るのに、「?S5」エラーでロードできず、WindowsのSDマウント、SDイメージが小さすぎる問題、SDFS3SYS.BINって何だっけ問題まで、ひととおり踏みました。今日もちゃんと右往左往したのであります。

v3 residentをROMから呼ぶ形にしたい

SDFS/68 v3では、固定RAM8kにコマンド解釈やFAT処理を全部持たせるのではなく、SD上のsystem imageからresidentをRAMへ読み込んで、ROMは薄い入口だけ持つ構成に寄せています。ROMモニタにはCMD という入口を置き、RAM上のSDFS3API headerを探して、resident側のCMD_DISPATCHへtailを渡す形です。

この設計にした理由は単純で、固定RAM 8KBがもう狭いからです。VDG、キーボード、SD raw read、BOOT、CMD gatewayまで入れると、固定RAMにFAT32や.COMローダを全部持って、かつコマンド解釈まで持つのはしんどい。だったら、ROMは「residentをロードして呼ぶ」だけにして、DIR/TYPE/LOAD/RUN/COMとかの部分をRAM上へ寄せる、という考え方です。

BOOT3の責務分離

この構成だと、residentだけ差し替えればSDFS/68側の機能を増やせます。ROMは薄く保てます。ROMを焼き直さなくても、SD上のsystem image更新だけでSDFS/68を更新できる未来が見えてきます。ここがv3の狙いであります。あと、2段ブートも諦めましたw

今日の前半はPH1の実装を一気に畳んだ

昨日から今日にかけて、SDFS/68 v3のPH1相当をかなりまとめて進めました。SDFS3API header、ROM側のheader検出、CMD gateway、resident側のtail parser、DIR / TYPELOAD / RUN / .COM、そしてSDFS3SYS system imageまでです。

`PR #287  SDFS3SYS固定LBA loader harness
PR #288  resident CMD_DISPATCH parser
PR #289  v3 DIR / TYPE
PR #290  v3 LOAD / RUN / COM
PR #292  SDFS3_LOAD_BASEをv2 SDFS_LOAD_BASEから分離
PR #294  SDFS LOAD境界回帰修正
PR #297  BOOT3固定LBAローダ`

こう書くとずいぶん整って見えますが、実際には途中で何度も「ん?」となりました。特にK6802-VDG構成では、v2 SDFS/68本体はこれまで$B000付近へロードする前提でした。一方でv3 residentは低RAM側の$5000へ置きたい。SDFS3_LOAD_BASEを分けないと、v2の都合にv3が引っ張られてしまいます。そこでSDFS_LOAD_BASESDFS3_LOAD_BASEを分離しました。

しばらく ?S5 エラーに苦戦

ところが実機で試すと、LOAD SDFS3.SがしばらくSDを読んだあとに?S5 のエラー表示で落ちました。S3A.SからS3D.Sまで、分割しても全部?S5 のエラー表示です。最初は「v3のS-Recordが悪いのか?」「Intel HEXだから?I5 エラーなのか?」みたいな方向を疑いました。

実際には、ここはv3そのものではなく、直前に直したv2側のLOAD境界回帰でした。128バイトくらいなら読めるけど、256バイトを超えると落ちる。昔は電大BASICの.COMが読めていた気がするのに、なんで今だけ、というやつです。結論としては、SDFS/68 v2をいじったときにセクタ境界まわりを壊していました。これがIssue #293 / PR #294です。

なんか、2バイトづつ読む時のロジックでレジスタ壊していたみたい。バイナリだと1バイトづつロードするから露見しなかったというオチ。

WindowsでSD imageを書いたらマウントされない

もう一つ、今日の地味なハマりどころがWindowsでした。以前はMacで作業していて、今日はWindowsです。SD imageを書き込んだあと、ドライブがマウントされない。見えない。これは不便であります。

結果としては、Windowsのディスク管理でドライブ文字を割り当てたら見えるようになりました。imageそのものが壊れているわけではなく、Windows側が自動でドライブレターを付けてくれていなかっただけです。分かってしまえばそれだけなのですが、SDカードを何度も抜き差ししている最中だと、こういうので時間を吸われます。

あと、最初に作ったBOOT3用imageが小さすぎました。エミュレータでは320KBくらいの最小imageでも動きます。しかし実機SDへ書くには小さすぎて、ツールやWindows側の扱いが微妙になります。そこで同じ配置のまま32MB版を作り直しました。

BOOT3用SD imageの配置

BOOT3が読むのはFAT上のファイルではありません。physical LBA 64に直置きしたSDFS3SYSです。FAT32 partitionはそれと重ならないようにphysical LBA 128以降へ置きました。最初、FAT rootにも確認用コピーとしてSDFS3SYS.BINを置いたのですが、これは分かりにくかったです。BOOT3がrootのSDFS3SYS.BINを読んでいるように見えてしまう。実際には関係ありません。

BOOT3が動いた

最終的に、W27C512用のK6802-VDG ROMと、32MBのBOOT3用SD imageを作りました。ROMはSDFS3_LOAD_BASE=$5000SDFS3_LOAD_LIMIT=$7EFFです。SD imageはLBA64にSDFS3SYS、LBA128以降にFAT32 partitionという配置です。

`MC6800 MONITOR
] BOOT3
OK] CMD DIR
README.TXT A 00000068
HELLO.S A 00000092
HELLO.COM A 00000020
ARGS.COM A 0000003E
] CMD TYPE README.TXT
BOOT3 SDFS/68 v3 test image for K6802-SBC + K68-VDG.`

実機でも、BOOT3が動いて、CMD DIRCMD HELLO.COMも動きました。ここはかなり大きいです。v2 SDFS/68を経由してLOAD SDFS3.Sする道もデバッグ用には残せますが、運用としてはROMのBOOT3でv3 residentを直接読む方がずっと素直です。

ただ、実機で見ると表示が少し寂しいです。

`] BOOT3
OK]`

こういう感じで、OKのあとすぐモニタプロンプトの]へ戻ります。中身としてはresidentがロードされているのですが、画面だけ見ると何が起きたのか分かりにくい。v1.3のSDFS/68 V1.3 #157みたいなWelcomeが欲しくなります。

Welcome表示はresident側に寄せたい

最初はROM側で短い文字列を出せばいいかな、と思いました。BOOT3成功時にSDFS/68 v3と出すだけなら簡単です。ただ、それだとresidentを差し替えても表示はROM側に残ります。v3のビルド番号やAPIバージョンを出したいなら、ロードされた側が自分で表示する方がきれいです。

`- SDを初期化する
- physical LBA 64のSDFS3SYSを読む
- header / checksum / load addressを検証する
- payloadをSDFS3_LOAD_BASEへ配置する
- SDFS3API headerを見つける
- residentのINIT APIを呼ぶ`

ROMの責務はここまでにしたい。その先のWelcome表示、ビルド番号表示、将来の初期化処理はresident側に持たせたい。プロンプトは当面モニタの]のままにします。ここでプロンプトだけSDFS>っぽく変えると、「いまresidentが生きているか」「壊れたらどう戻すか」「CMDが失敗したときの状態はどうするか」という管理が増えます。今はそこまでやらなくてよさそうです。

この方針でIssue #298を作りました。SDFS3_INIT APIを追加して、BOOT3成功後にROMがそれを呼び、resident側がWelcomeを出す、という内容です。

AUTOEXEC.COMも見えてきた

Welcome表示の話をしているうちに、HELLO.COMINIT.COMAUTOEXEC.COMをBOOT3後に呼べるとよさそう、という話になりました。将来、RTC初期化やVDG設定、キーボード設定をSD上のファイル差し替えで仕込めるからです。

ファイル名としては、HELLO.COMはサンプルっぽい。INIT.COMはAPI名のINITと少し紛らわしい。実機運用の自動起動ファイルとしてはAUTOEXEC.COMが一番分かりやすいかな、という判断です。ただし、いきなりBOOT3後に任意COMを自動実行すると、デバッグ中に邪魔になる可能性があります。なので順番としては、まずIssue #298でSDFS3_INITとWelcome表示。そのあとIssue #304でAUTOEXEC.COM自動実行を検討する、という段階にしました。

PH2をIssueに分け直した

今日の最後に、SDFS/68 v3 PH2の作業もIssue化しました。BOOT3が動いた、で終わらせると、次に何をやるのかが曖昧になります。ここから先は「実機で扱いやすいsystem運用」に寄せるフェーズです。

SDFS/68 v3 PH2のIssue化

`#298 INIT APIとWelcome表示
#299 BOOT3用SD image生成ツールの正式化
#300 system slot A/Bとactive marker形式
#301 BOOT3をslot A/B対応loaderへ拡張
#302 PC側ツールで非active slot更新
#303 SD raw write primitive
#304 AUTOEXEC.COM自動実行`

まずは#298と#299です。Welcome表示が出るようにして、今日手作業で作ったBOOT3用SD imageを正式な生成ツールへ落とす。次に#300と#301でslot A/Bとactive markerです。system更新で壊しても旧slotへ戻れるようにするには、この二重化が欲しい。そのあとPC側ツールで非active slotを更新する#302。実機側で更新したいなら、raw write primitiveの#303が必要になります。AUTOEXEC.COMは#304で、その先のRTC初期化につながる入口です。

今日の到達点

今日の到達点は、K6802-SBC + K68-VDG + W27C512 ROMで、SDFS/68 v3 residentをBOOT3から直接ロードし、CMD DIRCMD HELLO.COMが実機で動いた、というところです。これはv3としてかなり大きい一歩です。

まだ、画面上はOK]だけで地味です。SD image生成も手作業です。system領域も単一slotで、更新失敗への強さはありません。それでも、ROMがresidentをロードし、residentがFAT32を読んで、.COMを実行する、という基本の線はつながりました。

次はWelcome表示を入れて、BOOT3した瞬間に「SDFS/68 v3が来た」と分かるようにしたいところです。そのあと、SD image生成ツールを正式化して、LBA64やLBA128の話を毎回手で思い出さなくて済むようにします。今日はここまでであります。

関連リンク

MC6800 ROMモニタSDFS/68