MC6800 SDFS/68を作る その6 ~.COMでトランジェントコマンドっぽくする~

SDFS/68MC6800 SDFS/68を作る その6 ~.COMでトランジェントコマンドっぽくする~

SDFS/68は、V1.2で DIRLOADRUNEXIT まで入りました。SDカード上のファイルを見て、S-RecordやIntel HEXをロードして、アドレス指定やentry addressから実行できる。ここまで来ると、もうかなり小さいDOSっぽいです。

でも、DOSっぽいと言い出すと、次に欲しくなるものがあります。トランジェントコマンドです。

DIRLOAD のような内蔵コマンドだけではなく、SDカードに置いた FOO.COM をその場でロードして実行する。終わったらSDFS/68のプロンプトへ戻る。CP/MやMS-DOSの .COM みたいな使い方であります。

SDFS/68でHELLO.COMとARGS.COMが動いた実機

RUNとは別のものにしたい

最初に考えたのは、今ある RUN をRTS前提にするかどうかでした。

でも、これは分けることにしました。RUN addrRUN filename は、ROMモニタの G コマンドに近いものです。指定した先へ JMP して、あとは実行先に任せる。戻ってくる保証はありません。

一方で .COM は、SDFS/68が呼び出し元になります。

`SDFS> FOO.COM
  SDからFOO.COMを読む
  $0100へロードする
  JSR $0100
  FOO.COM側はRTSで戻る
SDFS>`

この違いをはっきりさせたかったので、.COMRUN とは別のABIとして設計しました。正常終了は RTSSWI はROMモニタのブレークや非常口として残す。ここはかなり大事な割り切りでした。

.COMの形はかなり単純にした

今回の .COM は、headerなしのraw binaryです。ロード先もentryも固定で $0100 です。

`        CPU     6800
        ORG     $0100

START   ; command body
        RTS
        END     START`

Macro Assembler ASで作るなら、だいたいこんな流れです。

`asl -q -L -o FOO.p FOO.ASM
p2bin FOO.p FOO.bin -q
mv FOO.bin FOO.COM`

CP/MのCOMっぽく、開始アドレスを $0100 にしておく。SDFS/68側はファイルの中身をそのまま $0100 へ置くだけです。余計なheaderやrelocationはありません。

ファイルサイズは $0100 から USER_RAM_END までに収まる範囲だけ許可します。現行の sbcio_vdgk6802_vdg では USER_RAM_END=$7FFF なので、最大は $7F00 byteです。0 byteの .COM も実行できないので拒否します。

引数はXとBで渡す

トランジェントコマンドなら、やっぱり引数も渡したいです。

`SDFS> ARGS.COM AAA BBB`

こう入力したとき、ARGS.COM の後ろの AAA BBB をどう渡すか。

CP/Mっぽくゼロページの $0080 あたりにコマンドテールを置く案もありました。でもMC6800ではゼロページ、というかdirect pageがかなり貴重です。既存の小さいプログラムが好きに使っている可能性もあります。

なので、今回はゼロページを予約しないことにしました。

`X = 引数テール先頭へのポインタ
B = 引数テール長
A = 0`

引数文字列はSDFS/68の行入力バッファ上に残っています。.COM 側で長く使いたいなら、自分のワークへコピーする作法です。このへんは小さい環境らしい、ゆるいけど明確な約束にしました。

ちょっと悩んだコマンド判定

最初の実装範囲では、FOO と入力して FOO.COM を探すところまではやりません。これは後でやると面白いですが、検索規則や内蔵コマンドとの優先順位が増えます。

今回はあくまで、拡張子まで明示します。

`SDFS> HELLO.COM
SDFS> ARGS.COM AAA BBB`

ただ、ここで少し罠がありました。SDFS/68には DLRUNLOAD などの内蔵コマンドがあります。DUMP.COMLIST.COMREAD.COM を置いたときに、先頭文字だけで内蔵コマンド扱いされると困ります。

特にレビューで見つかったのが LOAD.COM でした。LOAD prefixとして拾われるので、.COM 候補に落ちてこない。これはかなりありそうな名前なので、内蔵コマンドとして成立しなかった場合には .COM として再判定するようにしました。

このあたりを入れると、だいぶトランジェントコマンドらしくなります。

サンプルもMakefileに入れた

.COM は作法が大事なので、サンプルも残しました。

  • HELLO.COM: HELLO COM と表示して RTS する
  • ARGS.COM: X / B で渡された引数テールを表示する

make sdfs-tools でS-Recordの HELLO.S と一緒に .COM サンプルも生成します。実機で試すときは、system SDのrootに SDFS.BIN と一緒に HELLO.COMARGS.COM を置けばよいです。

`SDFS> HELLO.COM
HELLO COM
SDFS> ARGS.COM AAA BBB
ARGS AAA BBB
SDFS>`

これはかなり気分がよいです。RUN で飛びっぱなしではなく、ちゃんとSDFS/68へ戻ってくる。小さいDOS感があります。

HELLO.COMとARGS.COMを実行したVDG画面

実装して実機でも動いた

実装はSDFS/68側に .COM 専用のparse、サイズチェック、raw load、起動処理を追加しました。既存のS-Record / Intel HEX loaderは通しません。FATのstream読み込みだけ使って、1 byteずつ $0100 以降へコピーしています。

実装後の SDFS.BIN は、両profileとも3115 byteでした。

`build/SDFS-sbcio-vdg.BIN  3115 bytes
build/SDFS-k6802-vdg.BIN  3115 bytes`

SDFS/68の枠は3840 byteなので、まだ少し余裕があります。でも、だいぶ詰まってきました。ここから先は本当に機能を選ばないといけません。

テストでは、通常の .COM 実行、引数渡し、LOAD.COM みたいな内蔵コマンド名との衝突、存在しない .COM、0 byte .COM、サイズ超過 .COM、ネストした JSR / RTS での復帰を確認しました。

そして実機でも、SDFS.BIN を入れ替えて動きました。写真の通り、VDG画面上で HELLO.COMARGS.COM AAA BBB が動いて、ちゃんと SDFS> へ戻っています。これはうれしい。

いったんここまで

今回で、#190で考えていた「最小 .COM ABI」はいったん閉じられます。

まだやりたいことはあります。FOO とだけ入力したら FOO.COM を探す本格トランジェントコマンド探索。.COM からSDFS/68のファイルAPIを呼べるようにする話。将来のpath対応後に、どこから .COM を探すかという話。

でも、まずは FOO.COM 明示指定でSDからロードして、RTS でSDFS/68へ戻るところまでできました。

SDFS/68は、最初はSDからSDFS本体を起動するだけの小さい仕組みでした。それが DIRLOADRUN を持ち、今度は .COM まで呼べるようになりました。派手ではないですが、かなりDOSっぽくなってきた感じであります。

関連リンク

SDFS/68