2019-11-19 00:06 — asano
カテゴリー:
前回は簡単なテストプログラムを動かしましたが、その後アセンブラもある程度動作するようになったのでいつものUniversal Monitorを移植することにします。
しばらくボードを動かしていなかったので念のためにもう一度小さなプログラムを試してみましたが、何故か動作が変というかいきなり暴走している感じです。
原因はいくつか考えられます。
- ボードかCPUが壊れてしまった
- (リセット動作には不明な点が多いので)以前動いたのは偶然だった
- アセンブラが誤ったコードを吐いている
ハンドアセンブルと比較したり、以前と同じコードを試したりで3.で無いことはすぐに判明しました。
出力されているアドレスを確認するとLSB側2ビットのみが変化していて残りは"L"なので0~3番地の範囲でループしているようです。この辺りは割り込み時にSTR
, IC
を保存するエリアなのでストローブ系の信号も見てみましたがメモリ読み出しのみでした。また試しにこのエリアに X'2000'(H
(alt)命令)を書いておくとCSRQ/RUNのLEDが消灯して停止したことがわかります。これでCPUを壊した可能性は低くなりました。
バス周りなどの配線を確認しても特に異常は見られません。
これ以上の原因究明は保留して0~3番地に本来のコードへのB
(ranch)命令をおいたところその後は正常に実行されるらしいことがわかり、やはりリセット時に何かがあることは確かなようです。
リセット問題は置いておいてモニタの移植に進みます。
今回のボードはMN1613を搭載してはいますが、MN1610命令のみで書くことにしました。理由の一つはMN1613命令をまだアセンブラに実装していないこと、もう一つは少しでも多くのCPUで実行可能にしたいことです。
まずはコンソールのドライバから、MN1613ボードにUARTなどは載せていないのでEMILYボードの共有メモリを使います。
MN1613からバイトアクセスはできませんので、X'0040'~X'004F'の16ワード(有効なのは下位バイトのみ)を使うことにします。上下バイトを使うにはRead-Modify-Writeが必要になり煩雑になるから、ゼロページが不足してきたら考えますが。
これはEMILYボードからは0x81, 0x83, 0x85, ... 0x9Fに見えるので、A 0081,2
と設定しておきます。
後は似たCPUのソースを見ながら黙々と書いていくことになります。今回はZ80を参考にしながら書きました。そこそこの数のレジスタがあり、レジスタ間演算が中心というあたりが似ていると感じたからです。
以下、書いていて感じたことなどを挙げておきます。
- 即値を使える命令が少ない
特に多用しているC
(ompare)に使えないのはまいりました。常にレジスタを1つ空けておかないとなりません。 - 8ビットを超える定数が扱いづらい
たとえ即値が使えてもビット数が限られることです。AI
命令などはINC
命令の一種と考えればそんなものかもしれませんが、MVI
命令でも8ビットしかありません。上位8ビットは変化しないのでBSWP
命令と組み合わせて2度に分けて設定するか、メモリに定数を置いておいてL
命令で読むしかありません。 - アドレス指定
上でメモリに定数を置いておくと書きましたが、これの置き場も厄介です。アドレスの指定も8ビットだからです。X'0000'~X'00FF'に置いておけば直接指定できますが、ゼロページは限られた資源なので多用はできません。近傍(サブルーチンの前後など)に置いてIC相対でアクセスする方法もあります。今回は主にあちこちから参照されるものやワークエリアを前者に、それ以外を後者にしています。 - 分岐命令の飛び先
分岐命令の飛び先もやはり8ビット指定のみなので、遠くへの分岐も飛び先アドレスをメモリに定数として置いておいて間接アドレッシングで分岐する必要があります。この定数の置き場も上の「アドレス指定」と同じです。 - 16ビット演算
16ビットCPUなので当然ですが、アドレスの比較などが一発でできるので意外と書きやすい面もあります。 - 短距離分岐が意外に届く
8ビットCPUだと2バイト・3バイト命令になるものが1ワード命令でアドレス1つ分ですから、8ビットのディスプレースメントでも意外と届く印象です。届かなくなったとたん上記のように面倒なことになるわけですが。
慣れればそう書き難くはないかな、といった印象ですね。
ということで最低限の D, S, G の各コマンドが実行可能になりました。
写真はX'400'番地にH
(alt)命令を書き込み、付近をダンプして、実行したところです。
これを動作させる環境をもっている人は少ないと思いますがファイルを置いておきます。
- ソースコードは Index of /unimon/src/ からダウンロードできます。20191118以降のものにMN1610対応が含まれます。
- The Macro Assembler AS を MN1610 対応させるパッチはASに新CPU対応を(その3)に添付されています。
コメント
アドレスをDACで変換してオシロで見る
アドレスバスのLSB側の2ビットだけ動いていて、残りはゼロだったという話を読んで思い出したのですが、
CPUが何をやっているか全く判らない時の調査方法で、アドレスバスの内容をDACでアナログに変換してオシロで見る、なんて力業が昔ありました。
私はやったことないですが、雑誌の記事で見たことがあります。
海外メーカーのマイコンをこの方法で調べて、アイドル中はここでループ、割り込みが入ると、なんて調べていたような気がします。今ならロジアナを使うんでしょうけどね。
Re: アドレスをDACで変換してオシロで見る
なるほど、チャンネルが足りないのを補うのですね。
ピンポイントでアドレスわからなくても、イベント待ちなのか暴走しているのくらいはわかりそう。
今だとロジアナ迄いかずともミックストシグナルオシロスコープもあります。
マイコンの入力ポートが足りないとき、ボタンに抵抗組み合わせてA/Dポート使う技にも似ていますね。
MN1613
マイクロプログラムによるハードウエアのテスト行いCPUは実行状態に遷移したものだと思います。
コメントを追加