実験でZ80をやるということで指導書見ながら実験してた。
大方プログラムは用意されてるので、ハンドアセンブルするだけ。
まぁそれも穴埋めだし、実験自体はさほど難しくもない。
今回はI/Oと割り込みを使う実験ということ。
まぁ割り込みの方はまだやってないけど、I/Oはおもしろいですね。
スイッチの状態を読み込んで、LEDにビットの状態が表示されると。そういうI/Oです。
一番始めにこんなプログラムが書いてあった。
ST: IN A,(01h)
OUT (00h),A
JR ST
さて、このプログラムはなんでしょうか?
01hのポートからなんか読み込んでAレジスタに入れる、
00hのポートにAレジスタの内容を送る、という無限ループ。
01hのポートにはスイッチが8つ、00hのポートにはLEDが8つ。
というわけで、実はひたすらスイッチの内容をLEDに転送してると。
まぁそういうことです。
まぁこんなプログラムだったらすぐわかるからうれしいのだが、
複雑なのになってくると動くか簡単に確かめたいものですね。
なんかいい方法ない? となるとシミュレーター使えと。
Z80シミュレータ
このシミュレーターは有名ですね。
シミュレーターというよりかは、アセンブラ + アセンブリ言語インタプリタに近いけどね。
このインタプリタというのはステップ実行の時、わかりやすいですね。
時々動作がへんなことありますけど。
RRC命令が動作しなかったり。よくわからない。
しかし基本的にはうまく動きますよ。
実はこのシミュレーター、I/O関係もきちんと動くんです。
が…説明書に書いてない。しょうがないのでソースコードを読む。
Step.CppのTStepForm::INSimメソッドの一部。
switch( *adr2 ) {
case 0x0F8:
adr2 = &MainForm->a_port; break;
case 0x0F9:
adr2 = &MainForm->b_port; break;
case 0x0FA:
adr2 = &MainForm->c_port; break;
case 0x0FB:
adr2 = &MainForm->cntl_port; break;
case 0x0FC:
if( ComRead( adr2 ) == false ) goto error; break;
case 0x0FD:
if( SockRead( adr2 ) == false ) goto error; break;
Aポートに対応するのはF8h、BポートはF9h、CポートはFAhと。
作者の環境にあわせたのかな。
まぁさっきのプログラムの00hをF8h、01hをF9hに置き換えて打ち込む。
打ち込むとき、初めにORG 8000h、最後にENDと打ち込む。
このシミュレーターはアセンブリ言語で打ち込んで、
雷ボタンでアセンブルウインドウなので、ここで雷ボタンを押すとアセンブルされる。
それとは別に実行するときは三角ボタンですね。
さて、実行ウインドウで出力先はポートAを選ぶ。
ここで選んだのがレジスタウインドウのLEDに転送される。
ここでポートBのチェックをいじると…
LEDにポートBのチェックの状態が転送されるのがよくわかります。
というわけで、これでI/Oが絡むのもある程度テストできますね。
まぁ限界はあると思うけど。
実験で出てきた、点灯するLEDが左右に動くプログラムがあったの。
スイッチのON/OFFで動き方、点灯のしかたをセットしてやるのだけどね。
指導書の作者(担当の教員?)のプログラムでは多少不気味な動作があったので、
直感的な動作にできんかなと思っていろいろやってたんだけどね。
書いてるだけではなかなか実感わかんから、シミュレーターを使ってみようと。
それで実際やってみると、うまく動きませんねぇ…
けどシミュレーターの何がいいって、ステップ実行させたときの動きがすごく見やすいこと。
これでバグを大量に発見して、すぐにきれいなプログラムが完成。
これを写して、実験の2日目の余った時間で遊んでみようかなとか。