Chick-Bug の標準機能がだいたい動くようになりました(カセットテープのロード/セーブは未検証)。予想通りフロントパネルの DMA スイッチ類はほとんど使わなくなってきましたがそこは気にせず、Chick-Bug へ次の機能を追加します。
- S19 読み込み
- メモリダンプ
- MB8861 命令の書き換え
S19 ストリームの読み込み
SBC68 シリーズを使ってわかったことですが、シリアルコンソールが近代的なコンピュータに接続されている場合、ユーザプログラムをロードするには S19 ファイルの内容をコンソール画面にコピペする方法が最も手軽です。この機能、つまり MikBug の L コマンドを Chick-Bug に追加します。
基本的なコードは SBC68 版 MikBug とほぼ同じです。コマンド名には ‘O’ を割り当てます(’L’ はカセットテープロードコマンドですでに使用されているため)。ロードが終わったら待機モードに戻ります(他の Chick-Bug コマンドと同じ終わり方)。
ちなみに元祖 MikBug の L コマンドはテレタイプ端末の紙テープリーダを前提としていたようです。’L’ コマンドをテレタイプ端末のキーボードから入力した後、入力ラインをテープリーダに切り替えてテープを走らせ、内容を読み込みます。すると S19 データストリームが 110 baud でテープリーダからコンピュータへ送られるという仕組みです。一度でいいのでこの紙テープ読み込みを SBC シリーズや Λ-1 でやってみたいですね。
メモリダンプ
Chick-Bug 標準機能の M コマンドは 1 バイトずつの表示・確認となり操作が若干煩雑です。ダンププログラムは 64 バイト単位で表示するので操作が楽になります。「マイコン手づくり塾」の Chick-Bug 開発編にユーザプログラムとして掲載されているものを Chick-Bug 自体に組み込んでしまいます。コマンド名は ‘D’ とします。
***
これらのコマンドを追加することでモニタ内各ルーチンのエントリアドレスが変わってしまいます。今までに作成した、モニタサービスルーチンを使ったユーザプログラムは変更が必要になりますが、そもそも Lambda-2022 ではオリジナル Λ-1 から ROM アドレス自体が変わっているので今回の変更の影響は相対的に小さいものです。
MB8870 命令の書き換え
「マイコン手づくり塾」ではモトローラ MC6802 互換の各種チップを総合的に比較検討した結果、富士通 MB8870 が採用されました。MB8870 の最大の特徴は独自命令が追加されていることです。富士通製 MPU では MC6800 互換の MB8861 の頃から同じ独自命令群が採用されていました。Chick-Bug プログラムの中でもこれらの独自命令が使用されているのですが使用箇所はそれほど多くなく、多少の工夫で置き換えられます。MB8870 と MC6802 はピン互換ですから、MB8870 独自命令がなくなるよう書き換えてしまえば MC6802 チップを Lambda-2022 に装着できます。
以下、MB8870 の独自命令と使用箇所をそれぞれについて検討します。
ADX 命令
6 箇所使われており、そのうち 4 箇所は ADX #$03
という固定値加算で、加算値も小さいので inx を 3 行並べるだけで置き換えられます。
もう一つは ADX #$1F
となっています。inx
を 31 個も並べるというのも不格好でどうしたものかと思っていたところ、前後をよく読むとこの行での X レジスタの値は不変です。次のように書き換えられます。
変更前: ldx #ccrm stx xopnd1 adx #$1f stx xopnd2 変更後: ldx #ccrm stx xopnd1 ldx #ccrm+$1f stx xopnd2
最後の一つは変数へ加算しているため、A/B アキュムレータを使った 2 バイト加算に展開せざるを得ません。前後に A/B アキュムレータの退避・復帰を含むためステップ数が増えます。逆に言うと、これが MB8870 ADX
命令の真価を発揮するケースになります。
変更前:
lf ldx cpoint
adx #$20
stx cpoint
変更後:
lf psha
pshb
ldaa cpoint
ldab cpoint+1
addb #$20
adca #0
staa cpoint
stab cpoint+1
pulb
pula
NIM、OIM 命令
それぞれ一箇所しか使われていません。どちらもカセットインターフェイス出力処理の中です。
bitout psha pshb ldx #pdrb1 nim1 nim $fe00 [8] decb [2] bne nim1 [4] pulb oim1 oim $0100 [8] decb [2] bne oim1 [4] pula rts
ここでは PIA の DRB レジスタの PB0(カセットデータ出力)のオフとオンを行い、オーディオ出力を一瞬トグルする効果を求めています。周期は bitout ルーチン呼び出し元で指定する AccB の値で決まります。次のように設定されています。
soutlp lsra bcs markot ldab #$64 bsr bitout bra nxtbit markot ldab #$32 bsr bitout nxtbit dec bitctr bne soutlp
つまり出力 ‘1’ の半周期分のループは $32 カウント(50)、出力 ‘0’ の半周期分のループは $64 カウント(100)です。具体的な半周期長はループ処理の命令サイクル数で決まりますが、命令サイクル計算に必要なデータは MB8861 命令シートに書いてあります(「マイコン手づくり塾」に掲載されています)。簡単のためループ外の命令サイクルを除外して計算すると出力 ‘1’ の半周期は 14us x $32 = 700us、出力 ’0’ の半周期は 14us x $64 = 1400us となります。
同等の処理を MC6800 命令で再現するには次のように nim、oim を書き換えます。
bitout psha pshb ldx #pdrb1 ldaa 0,X anda #$fe staa 0,X nim1 nop [2] nop [2] nop [2] nop [2] decb [2] bne nim1 [4] ldaa 0,X oraa #$01 staa 0,X pulb oim1 nop [2] nop [2] nop [2] nop [2] decb [2] bne oim1 [4] pula rts
nim ないし oim 命令 1 個の代わりに nop を 4 個挿入することでループ内の合計サイクル数が一致するので、タイミングも同じになります。
以上で MB8870 独自命令使用部分をすべて書き換えることができました。一箇所を除いていずれも独自命令を使用する必然性があまりない処理であったように思えます。特にカセットインターフェイス出力の部分は nim/oim を使用するのであればそもそも AccA を退避する必要はありません。書き換え後のように PIA レジスタ操作に AccA を使うのであれば事前退避が必要になるので、ここはもともと MC6802 互換で書かれていたという可能性も考えられます。
注:
現時点ではまだカセットインターフェイス回路を作っておらず、PIA ポートが未接続のまま放置されています。せっかくなので SAVE コマンド出力信号を実測しました。最初に MB8870 拡張命令を使った処理の場合の出力波形です(D0 チャネル)。
たしかにマーク半周期 ~720us、スペース半周期 ~1410us となっています。
次が MC6802 命令で書き換えた後の SAVE 出力波形です。
こちらもマーク半周期 ~700us、スペース半周期 ~1490us とおよそ一致します。どうもデューティ比が正確に 50% ではないようで、ループ外の命令サイクルの影響だと思われます。