手動クロックで動かすZ80

ようやくZ80(LH0080A)の動作確認できました。
課題になっていた手動クロックは 74HC123 で無事解決。C=0.001μF(1000pF)× R=470Ω の時定数で、タクトスイッチを押したときに 1μsec 弱のLパルスが出る回路を作ってLH0080Aを動作させました。

f:id:marlesan:20161015210937p:plain:w400
角のギザギザが若干不安でしたが、原因も解消法も見当つかないので無視。

実験回路全景(いい加減、回路図作成ツールを覚えないと…)
f:id:marlesan:20161015214647j:plain:w400
ごちゃっとしてますが、大半はLEDなど状態表示のための配線になります。
基本の考え方は単純で「RDがアクティブのタイミングでデータバスに適切な信号が乗ってさえいれば動作確認はとれるだろう」という発想です。この操作は手動クロックならDIPスイッチでのんびり行えるので、メモリが不要になって作業量を大幅に省略できます。メモリを使う場合、配線の手間はもちろんですが「そもそもメモリに動作確認用のプログラムを書いておかなきゃいけない問題」が発生してしまうのですね。とりあえずはCPUの動作確認をしたかったので、メモリと連携した動作は後回しにしました。

実際の回路はLH0080Aのアドレス出力ピンから台湾Mega2560に向かってジャンパ線がもりもり伸びていますが、これはアドレスバスの内容を確認するためのものです。台湾Megaの外部割込みを使って、クロック立ち上がり→アドレスバスの信号をキャプチャ→16進数でシリアルに出力→PCでアドレス内容を確認、とできるようにしてます。

実験回路の操作手順は次のような感じで。

  1. リセットをアクティブ(スライドスイッチを右)にした状態で電源投入
  2. クロックを3回以上入れる。制御信号が全て非アクティブ(点灯)になる
  3. リセットを非アクティブにする
  4. 好きなタイミングでクロックを入れてCPUを動作させる
  5. RD がアクティブになったら、DIPスイッチを操作してデータバスに適切な信号を乗せる

上の写真はこの手順でLD A,(4321H); LD (1234H),A;と続けて実行したところです。上述の通り実際はメモリがないので(4321H)(1234H)のアドレス指定は無意味で、1回目のLDの最後のメモリ・リード・サイクルでデータバスに乗っていた値(10101010)をアキュムレータに取り込み、2回目のLDの最後のメモリ・ライト・サイクルで先ほど取り込んだ値をデータバスに出力する、という動作になっています(写真はこのサイクルのT3で止めている)。
f:id:marlesan:20161015225415j:plain:w400
Z80ファミリ・ハンドブック』p23 より

ほか「JP命令でプログラムカウンタを適当な番地に設定した後、DIPスイッチを00Hに固定してクロック連打」という実験もしてみました。00HはNOPなのでM1サイクルがただ繰り返されますが、台湾Megaでキャプチャしているアドレスを確認すると、2つの値がインクリメントしながら交互に出力されます。片方はNOPを実行しながら増えていくプログラムカウンタです。もう片方はなんでしょう?
おお、これがZ80自慢の(?)DRAMリフレッシュ機能なのですね。「M1サイクル中、オペコードをフェッチした後、命令を解釈する間の時間を使ってリフレッシュ用のアドレスをバスに出力する」動作が大変よくわかります(もちろんこの時、RFSH信号がアクティブ=消灯になる)。


【追記】リフレッシュ用アドレスはバスの下位7bitに出力されるようです。インクリメントしていくと7FHの次は00Hに戻ります。DRAMは行アドレスと列アドレスを順次指定してアクセスするようにできていて、リフレッシュは行単位で行われるので7bitで間に合う、ということかな。ちなみに7FHとか00Hという値は上位9bitが全て0の場合の話です。こちらのサイトでマニュアルを引用しつつ解説されてますが、上位8bitはIレジスタの中身が出力されるとのこと。引用部分をさらに読むと、下位から8bit目はLD R,AでRレジスタにロードされた値が残り続けるようです(ただし、通常はプログラムでRレジスタを操作する意味はないとも書いてある)。


準備中は「こんな手間かけるより小規模なシステム組んじゃった方が話が早いんじゃないか」とも思ってましたが、やはり実際に手を動かして損することはないですね。実作業半日程度の実験でZ80の基本動作が体感できました。

さて、次は再びメモリです。前回の実験から大幅に飛躍して、Z80を動かすためのプログラムを書き込めるようにする必要があります。ROMライタを作るか、ブートロードの仕組みを作るかですが、スタンドアロンなシステムも視野に入れるならROMを扱えた方がいいのかな。