CPU判別法(68編)
現在のCPUではその種類や対応する命令の範囲などを取得する命令(例えばx86系のCPUID命令)がありますが、以前は微妙な挙動の違いなどから判別していました。
自作のUniversal Monitorのソースコードを例に解説してみます。
MC6800系
まずは昨日目処が立ったと書いたMC6800系からです。
該当部分のソースは次のようになっています。
現在のCPUではその種類や対応する命令の範囲などを取得する命令(例えばx86系のCPUID命令)がありますが、以前は微妙な挙動の違いなどから判別していました。
自作のUniversal Monitorのソースコードを例に解説してみます。
まずは昨日目処が立ったと書いたMC6800系からです。
該当部分のソースは次のようになっています。
8080, Z80, 6809に続いて6800用でもCPU判別を追加しようと思っているのですが情報があまりありません。
わかった範囲ではMC6800 ⇒ MC6801/MC6803 ⇒ HD6301/HD6303と改良されるにしたがって命令は追加されていますが、既存命令の挙動は変化が無いようです。これは互換性という点では非常にありがたいのですが、判別という点では困ったことです。
追加された命令の存在が確認できれば良いのですが、そのオペコードは旧プロセッサでは未定義なので何が起こるかわかりません。データシートにも記載は無いので試してみるしかないのです。
レジスタを設定し、問題の命令を実行し、レジスタがどう変化したかを地道に見ていく必要があります。
そこでレジスタを任意に設定して実行する機能、レジスタの内容を表示する機能を追加することにしました。これはデバッグにも有効です。
Universal MonitorをZ280のI/Oページレジスタに対応させました。
先日のI/O命令追加はそもそもZ280ボードで内蔵UARTの検討用に始めたのですが、あのままではZ280内蔵デバイスへのアクセスには使えません。
Z280内蔵デバイスはI/Oページ0FEH, 0FFHに配置されています。I/OページレジスタはOS 8,FE
などとすれば変更できますが、0FEH, 0FFHに切り替えたとたんに外部I/Oデバイスへのアクセスができなくなります。現状コンソールを外部のZ80 SIOに頼っているのでこれではキー入力・画面出力が不能になってしまいます。
そこで"I", "O"コマンドで実際にI/Oアクセスする直前にI/Oページレジスタを変更し終わったら元に戻す必要があります。
ここまでは簡単ですが、コマンドをどうするのかは悩みました。
8080とZ80のUniversal MonitorにI/OアクセスのコマンドとCPU判別を追加しました。
I <port>
IW <port>
(Z280のみ)IS <port>
(Z280のみ) 1の形式では<port>番の入力ポートから8ビット幅で入力して表示します。2の形式では16ビット幅で入力して表示します。3の形式ではZ280のCPU制御/ステータス・レジスタを読んで表示します。
Z80系では<port>は16ビットアドレスが使用可能です。
モニタとして必要最小限の機能はできたかなと思っていましたが、大事なものが抜けていました。
ユーザプログラムからモニタの内部ルーティンを呼び出す方法です。
大昔のトレーニングキットや初期のパソコンでは直接ROM内のルーティンを呼び出していました。基本的に完成したモニタなのでアドレスは変わりません。バージョンアップ時もよく使われるルーティンのアドレスは動かないように配慮されています。
でもこのUniversal Monitorはまだ発展途上です。
それでアドレス固定のエントリポイントを用意して、本来のルーティンへジャンプするようにしてみました。