2021-10-28 23:59 — asano
カテゴリー:
ボードが出来たら当然次はソフトウェアを何とかしなくてはなりません。
いつものようにUniversal Monitorを移植することにします。
こういうのってCなどの高級言語か擬似コードを元にアセンブリ言語に変換していくのが一般的なのかもしれませんが、私の場合は似たプロセッサ向けのアセンブリ言語のソースを見ながら直接アセンブリ言語で書き下ろしています。
元にしたソースのバグを発見したり、最適化を思いついたりすることもありますね。ある意味コードレビューしているようなものですから。
今回は8080用を元にしていて、現時点でD(ump), S(et), G(o), L(oad), P(unch)の各コマンドが動いています。ここまでで感じたことをあげてみます。
- ニーモニックは8080にそっくりなものが多い。
SHLD
,LXI
など - レジスタも8080とほぼ同じ。裏レジスタがある点はZ80に近いとも言えるが、
IX
などは無い。PSW
(フラグレジスタ)には裏レジスタは無いので要注意。 - 条件分岐命令は無く、条件スキップと無条件分岐命令の組み合わせを使用する。分岐命令以外もスキップできるので条件付加算とか条件付ストアなどもできる。
- 条件スキップは比較命令がほとんど。例外はあるが結果を残す演算命令では条件スキップしない。
結果としてEQI A,0
(Aが0だったらスキップ)といった命令を多用することになる。2021年11月4日 訂正:
SK
,SKN
というフラグの状態でスキップする命令がありました。 - 2項演算命令はディスティネーションがアキュムレータに固定されているプロセッサが多い中、C←C+AとかL←L+immなどが可能。
HEXファイルのチェックサム計算には便利でした。 - レジスタ間の転送に制限(
MOV L,E
などはできない)がある。 - 8ビットの
INR
,DCR
でキャリー・ボローが発生すると次の命令をスキップする。これは次のようなループに便利でした。
149/ 1ED : 6A 0F MVI B,16-1 150/ 1EF : DPL0: 151/ 1EF : 40 16 02 CALL DPB 152/ 1F2 : 52 DCR B 153/ 1F3 : FB JR DPL0
だが16ビットの
INX
,DCX
にはこの動作は無いので注意。 MVI
,LXI
命令で特定のレジスタの場合にだけ"stacking effect"と呼ばれる動作がある。
395/ 373 : 67 31 NEI A,'1' 396/ 375 : C5 JR LHS00 397/ 376 : 67 39 NEI A,'9' 398/ 378 : C4 JR LHS01 399/ 379 : 4F 95 JRE LH3 ; Unsupported record type 400/ 37B : LHS00: 401/ 37B : 69 00 MVI A,0 402/ 37D : LHS01: 403/ 37D : 69 01 MVI A,1 404/ 37F : 70 79 DA 0F MOV RECTYP,A
これAが"1"で400行目から実行すると、401行でAに0を入れても403行で1が入って、402行から実行したのと同じになってしまうように見えますね。実は
MVI A,byte
が連続すると先頭以外は実行されない(これが"stacking effect")のです。飛び越すためのJR
命令が不要になります。
他にMVI L,byte
,LXI H,word
も同様です。
今回はμPD78C10ですがμPD7800も持っているので両対応にしたいところ。以前書いたようにRET
命令といった基本的な命令のコードが変更されているので同一バイナリは諦めていますが、ソースはできれば共通にしたいのでEA
レジスタなどは避けて書いています。
最後にCPUコア以外で気になった点をいくつか。
MM
レジスタを設定しないと内蔵RAMが使えません。- 内蔵シリアルI/Oはステータスレジスタがありません。割り込み要因レジスタを
SKIT
,SKNIT
命令で判定するしかありませんが、これは破壊読出しになるので要注意。CONST
ルーチンの実装にてこずりました。 - 内蔵タイマをボーレートジェネレータに使う場合は意外に自由度が低いです。深く考えずに12MHzにしたら2400bpsまでしか出ませんでした。もちろん半端な値でよければもっと上げられますが。
コメントを追加