MC6800 ROMモニタ自作 その7 ~S-Record / Intel HEX ローダを実装して実機確認した~

前回までで、メモリダンプ、メモリ変更、指定アドレス実行あたりの、ROM モニタとして最低限の形はだいぶ揃ってきました。
今回はその続きで、フェーズ4として Hex ローダを実装しました。つまり、外から S-Record や Intel HEX を流し込んで、そのまま RAM に配置できるようにするやつです。
最初は「まあ、行入力ができて 16 進変換もあるし、そんなに大変ではないかな」と思っていたのですが、実際にはかなり苦戦しました。最終的には SBC6800 実機で S-Record と Intel HEX の両方をロードできるところまで確認できたのですが、そこへ行くまでに、いくつか見事にハマりました。
今回やりたかったこと
今回やりたかったのは、端末からレコードを貼り付けて、そのままメモリへ書き込めるようにすることです。UX としてはかなりシンプルで、こんな感じを目指しました。
`] L
L
OK
] `
この「L コマンド 1 本で、S-Record / Intel HEX を自動判別する」という形にしたのは、貼り付け運用と相性が良さそうだったからです。
今回の方針
- ローダ入口は
Lコマンド 1 本 - 最初のレコード先頭文字で形式を自動判別する
- ローダ中は無エコー
- 正常終了時は
OK - 異常時は
?S1~?S5/?I1~?I5を返す
これは最初「デバッグ用だから最終的には外すかな」と思っていたのですが、実際にはかなり助かりました。実機上だと観測手段が少ないので、こういう 1 文字 2 文字の差が効いてきます。

キャプション案: 最初は ?S4 が出ていて、S-Record のデータ処理あたりで落ちていることが分かりました。
ローダ中は通常の行入力を使わないようにした
ローダ中に通常の READ_LINE をそのまま使うと、貼り付け中に余計な表示が増えたり、バックスペース処理が混ざったりして危ないので、ローダ専用に READ_RECORD を用意して、無エコーで 1 レコードずつ読むようにしました。
`READ_RECORD:
ldx #LINE_BUF
stx LINE_PTR
clr LINE_LEN
READ_RECORD_LOOP:
jsr ACIA_GETC
cmpa #CHR_LF
beq READ_RECORD_LF
cmpa #CHR_CR
beq READ_RECORD_DONE
cmpa #CHR_SPACE
blo READ_RECORD_LOOP`
?S4 で分かったこと
最初に実機で試したときは、S-Record がまるで通りませんでした。?S4 が出たので、S-Record のデータ処理あたりで落ちているところまでは分かりました。
原因は、X レジスタを「入力バッファの現在位置」として使っていたのに、そのまま「書き込み先アドレス」にも使ってしまっていたことでした。2 バイト目以降で LINE_BUF ではなく RAM 側を読みに行ってしまっていたわけです。
`PARSE_SREC_STORE:
ldaa HEX_NIBBLE
pshb
stx LOADER_PARSE_PTR
ldx LOADER_ADDR
staa 0,x
inx
stx LOADER_ADDR
ldx LOADER_PARSE_PTR
pulb`
この修正で、S-Record は通るようになりました。

キャプション案: S-Record のロードが通って、D0100 で内容確認できたところ
次は Intel HEX が ?I2 で落ちる
S-Record が通ったので「やっと終わったかな」と思ったのですが、今度は Intel HEX が ?I2 で落ちました。これもデバッグ表示が効いていて、Intel HEX のヘッダ処理あたりだとすぐ絞れました。
原因は、長さチェックの直後に失敗ラベルへ落ちる分岐ミスでした。正常レコードでもそのまま ?I2 になってしまう状態です。ここを直して、Intel HEX も実機で OK が出るところまで確認できました。

キャプション案: Intel HEX のロードも通って、同じ RAM 内容を確認できたところ
今回の実装で入れたもの
Lコマンド追加- ローダ専用の
READ_RECORD - S-Record / Intel HEX 自動判別
- チェックサム検証
OK表示?S1~?S5/?I1~?I5の保守用エラー表示Mコマンド値入力の 1~2 桁制限
実機で確認できたこと
- S-Record のロード成功
- Intel HEX のロード成功
D0100でロード内容確認Mコマンドの 3 桁以上入力が?になること
一方で、現時点では 16bit アドレス空間前提、Intel HEX の拡張アドレス未対応、終端レコード検証は最小実装、高速貼り付けでは行間待ちが必要などの制限もあります。このへんは今回は仕様として明記して進むことにしました。
今回のまとめ
- フェーズ4として
Lコマンドの Hex ローダを実装した S-RecordとIntel HEXを自動判別するようにした- 実機で両形式のロード成功を確認した
?S4と?I2の保守用表示がかなり役に立った- アセンブリではレジスタの使い分けとラベル位置が本当に大事だと改めて思い知った
地味ですが、今回の進捗はかなり大きいです。これで外から RAM にプログラムを流し込めるようになったので、ROM モニタとしてだいぶそれっぽくなってきました。
変更点はgithubをご覧ください。
今後の予定
次は、貼り付け安定性の改善、フェーズ5以降の機能、実際にロードしたコードを実行する使い方の整理あたりを進めていきたいです。まだ小さいですが、少しずつ「ただのシリアル実験」から「ちゃんとした ROM モニタ」へ育ってきた感じがしてよいですね。