2022-03-27 16:44 — asano
カテゴリー:
予告通りNSC800ボードのソフトウェア編をお送りします。
NSC800はソフトウェア的にはZ80互換なので基本的にはZ80用のUniversal Monitorがそのまま動作します。とはいえ例外もありまして今回は以下の3点を追加・変更しています。
一つ目はコンソールドライバです。
これまではZ80 SIOかHD64180系・Z280の内蔵シリアル用しか無かったのでEMILY Boardのものを追加しました。適当なCPUから移植するだけなのですが...
実はCONOUTルーチンでAレジスタ保存するのを忘れてハマってしまいました。
通常のハードウェアシリアルだとステータス待ちのあと送信バッファに書き込むだけのものが多いのですが、対EMILY Boardの場合はデータを書いた後でハンドシェイクの必要があってそこで壊していたのですね。行編集ルーチンはエコーバック後に行バッファに格納していたので、正常にエコーバックされるけどバッファにはゴミが入っていて何を入力してもエラーになってしまっていました。
これ、最初にEMILY Boardドライバを書いたものでは壊す前提で先にバッファに入れているものもあってハマってしまったのでした。
2つ目はNSC800の識別です。
これはそもそも製作の目的みたいなものです。
識別のために使えるZ80との違いはどんなものがあるでしょう?
未定義命令の挙動も一つの候補ですが、NSC800はあまり情報がないので実物を調べるところからのスタートになります。
NSC800で追加された0BBH番地のポートは書き込み専用なうえ、I/Oポートは外部回路の構成によってはうまく働かなかったり思わぬ副作用の原因になることもあるので避けたいところです。
そこでマニュアルにも明記されているRレジスタの挙動を利用することにしました。Z80では命令ごと(正確にはM1サイクルごと)に下7ビットがインクリメントされるのに対し、NSC800では8ビット全体がインクリメントされます。そこで以下のようなコードを書いてみました。
184/ 148 : 3E 7F LD A,7FH
185/ 14A : ED 4F LD R,A
186/ 14C : ED 5F LD A,R
187/ 14E : FA DC 01 JP M,ID_NSC
185,186行でAレジスタの値をRレジスタにコピーしてすぐにまたAレジスタに戻すわけですが、これによってAレジスタの値は2増えることになります。
LD R,A
もLD A,R
も2バイト命令です。
事前に7FHというギリギリの値にしておくことによりビット6からビット7への繰上りがあるかを見るわけです。Z80なら01Hになるのでそのまま下に流れますが、NSC800では81H(MSBが立った負数)になるのでID_NSCへジャンプします。
3つ目はRレジスタの補正です。
上記のようにRレジスタの挙動が異なるので補正ルーチンも対応させる必要があります。
これまでは何もしない(Z280ではRレジスタはインクリメントされない)・7ビットとして補正(Z80・HD64180系)を切り替えていましたが、8ビットとして補正(NSC800)を追加しました。この切り替えには当然上記の識別の結果を利用しています。
コメントを追加