現在地

NSC800ボード(ソフトウェア編)


予告通り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,ALD A,Rも2バイト命令です。

事前に7FHというギリギリの値にしておくことによりビット6からビット7への繰上りがあるかを見るわけです。Z80なら01Hになるのでそのまま下に流れますが、NSC800では81H(MSBが立った負数)になるのでID_NSCへジャンプします。

3つ目はRレジスタの補正です。

上記のようにRレジスタの挙動が異なるので補正ルーチンも対応させる必要があります。

Gコマンドでユーザプログラムに飛ぶ際にジャンプと同時にRレジスタをセットする命令は無いので、ジャンプしたときに目的の値になるよう事前にジャンプまでの増加分を引いた値をセットしています。RST 38Hでブレークしたときもその瞬間のRレジスタの値は保存されていないので後でRレジスタを保存してからそれまでに増加した分を引いてRST 38H時点の値を逆算しています。

これまでは何もしない(Z280ではRレジスタはインクリメントされない)・7ビットとして補正(Z80・HD64180系)を切り替えていましたが、8ビットとして補正(NSC800)を追加しました。この切り替えには当然上記の識別の結果を利用しています。

参考文献・関連図書: 
”Microcommunication Elements Databook Rev.1", National Semiconductor.

コメントを追加

Plain text

  • HTMLタグは利用できません。
  • ウェブページアドレスとメールアドレスは、自動的にハイパーリンクに変換されます。
  • 行と段落は自動的に折り返されます。
※ コメントは原則公開です。個別のご相談などは「ご意見・ご要望」からお願いします。