MC6800 ROMモニタ自作 その12 〜起動表示、ヘルプ、メモリフィル、ロード改善〜

前回は、D コマンドの範囲指定、SWI を使ったブレークポイント、U コマンドの簡易逆アセンブルを入れました。これで、RAM 上にロードした小さいプログラムを「動かす」「止める」「見る」ための最低限の道具はそろってきました。
今回は、そこからもう少し実機で使いやすくするための改善です。起動時の表示、ヘルプ、メモリフィル、ブレークポイント状態の照会、そして L コマンドのロード処理を見直しました。
今回の ROM も実機へ書き込んで確認しました。起動表示、F コマンド、ブレークポイント照会、BASIC ロードまで確認できています。
今回やりたかったこと
今回の追加要件は、大きく分けると次の 5 つです。
- 起動時に
MC6800 MONITORと表示する Hコマンドで短いヘルプを表示するFコマンドでメモリ範囲を同じ値で埋めるB単独で現在のブレークポイント状態を表示するLコマンドを高速貼り付けに強くする
WELCOME メッセージを出す
まずは起動表示です。これまでは起動時に * を出すだけでした。動作確認用としてはこれでも十分ですが、ROM を焼いて実機で起動したときに、何の ROM が動いているのか少し分かりにくいです。
そこで、起動時に MC6800 MONITOR と表示するようにしました。
ROM 書き込み後の実機起動で MC6800 MONITOR が表示されたところ
`RESET:
lds #STACK_TOP
clr DUMP_ADDR
clr DUMP_ADDR+1
clr BP_ACTIVE
clr BRK_ACTIVE
jsr ACIA_INIT
ldx #TXT_WELCOME
jsr PDATA1
ldaa #CHR_CR
jsr MON_OUTEEE`
文字列本体は短くしています。ROM 容量はまだ気にしておきたいので、凝ったバナーではなく名前だけです。
H コマンドで短いヘルプを出す
コマンドが増えてくると、何を入れたか忘れます。そこで H コマンドを追加しました。
`] H
D M G L B C R U H F
]`
`CMD_HELP:
ldab LINE_LEN
cmpb #1
bne CMD_HELP_ERR
ldx #TXT_HELP
jsr PDATA1
ldaa #CHR_CR
jsr MON_OUTEEE
jmp MAIN_LOOP`
F コマンドでメモリをまとめて埋める
次は F コマンドです。RAM の一部を 0 で消したい、テスト用に同じ値で埋めたい、という場面はよくあります。
`F0100-01FF 00`
F コマンドで RAM 範囲をまとめて埋めてからダンプで確認しているところ
`CMD_FILL:
ldab LINE_LEN
cmpb #1
beq CMD_FILL_ERR
ldx #LINE_BUF+1
decb
jsr PARSE_FILL_ARGS
bcs CMD_FILL_ERR
CMD_FILL_LOOP:
ldx MOD_ADDR
ldaa FILL_VALUE
staa 0,x
jsr CMP_X_DUMP_END
beq CMD_FILL_DONE
inx
stx MOD_ADDR
bra CMD_FILL_LOOP`
B 単独でブレークポイント状態を見る
前回、SWI を使った単一ブレークポイントを入れました。ただ、ブレークポイントに到達すると、停止時に元の命令へ復元して、ブレークポイントは自動解除されます。
そのため、操作している側から見ると「今まだブレークポイントが設定されているのか」「もう解除されたのか」を確認したくなります。そこで、B 単独入力を照会にしました。
`] B
BP NONE
]
] B0105
] B
BP 0105
]`
B 単独でブレークポイント状態を確認しているところ
`CMD_BREAK_QUERY:
ldx #TXT_BP
jsr PDATA1
tst BP_ACTIVE
bne CMD_BREAK_QUERY_ACTIVE
ldx #TXT_NONE
jsr PDATA1
jsr PRINT_CRLF
jmp MAIN_LOOP
CMD_BREAK_QUERY_ACTIVE:
ldx BP_ADDR
jsr PRINT_HEX16
jsr PRINT_CRLF`
L コマンドを受信しながら解析する形にした
今回いちばん大きく変えたのは L コマンドです。これまでは、S-Record や Intel HEX の 1 行をいったん LINE_BUF に読み込み、その後で解析していました。
実機でターミナルソフトから連続して流し込むと、行末に 100msec 程度の待ちを入れないと不安定になることがありました。そこで、今回は「行を全部ためてから解析」ではなく、「受信しながら解析」に寄せました。
`CMD_LOAD_LOOP:
jsr READ_LOADER_RECORD
bcs CMD_LOAD_ERROR
cmpa #1
beq CMD_LOAD_OK
bra CMD_LOAD_LOOP`
`READ_LOADER_RECORD:
jsr READ_RECORD_HEAD
bcs READ_LOADER_RECORD_FAIL
ldaa LOADER_MODE
bne READ_LOADER_RECORD_MODE_SET
ldaa HEX_NIBBLE
cmpa #'S'
beq READ_LOADER_RECORD_SET_SREC
cmpa #':'
beq READ_LOADER_RECORD_SET_IHEX
sec
rts`
16 進 2 桁を 1 バイトにする処理も、入力から直接読むようにしました。
`READ_HEXBYTE_INPUT:
pshb
jsr ACIA_GETC
jsr HEX_TO_NIBBLE
bcs READ_HEXBYTE_INPUT_FAIL
lsla
lsla
lsla
lsla
tab
jsr ACIA_GETC
jsr HEX_TO_NIBBLE
bcs READ_HEXBYTE_INPUT_FAIL
aba
pulb
clc
rts`
改良後の L コマンドで BASIC をロードして READY まで確認したところ
未使用になった旧ローダコードも削った
L コマンドを大きく変えたので、旧実装が残っていないかも見直しました。最初の実装では、旧 READ_RECORD、旧 PARSE_LOADER_RECORD、旧 PARSE_HEXBYTE_PTR が残っていました。
ここはレビューで見つけて、追加で削除しました。アセンブラのリストで見ると、SPURIOUS_IRQ の位置が EED2 から EC78 へ前に移動し、実コード領域としては約 602 バイト削減できました。
テストと実機確認
エミュレータ側では、いつもの smoke test を更新しました。
`make
make bin
python tests\test_smoke.py
Result: 15 passed, 0 failed`
さらに、実機 ROM へ書き込んで、起動表示、F、B 照会、BASIC ロード確認まで OK でした。エミュレータで通っていても、最終的には実機で見るとやはり安心します。
今回のまとめ
- 起動時に
MC6800 MONITORを表示 Hコマンドで短いヘルプを表示Fコマンドでメモリ範囲をまとめて初期化B単独でブレークポイント状態を照会Lコマンドを受信しながら解析する形に変更- 旧ローダ経路のデッドコードを削除
- 実機 ROM 書き込み後の動作確認 OK
これで、ROM モニタとして日常的に使う部分はかなり整ってきました。特に L コマンドの安定性が上がると、BASIC や小さいテストプログラムを何度も流し込む作業が楽になります。
そろそろROM モニタの機能もそろってきたので、電大版TinyBASICが動くかなど、いろいろと試してみたいですね。