読者です 読者をやめる 読者になる 読者になる

Z80カツドウ再開!

仕事落ち着いてきたようなそうでもないような。いろいろ中途半端にぶん投げておりますので、順に消化していきたいと思います。

まずは「Z80コンピュータを作ろう」企画から。

前回、といっても半年…!?近く前ですが、ブレッドボードで作っていた最小構成を基板で実装しよう、というところで止まっておりました。これは新居に机も無事導入でき、先週から作業再開してなんとか完成。

f:id:marlesan:20170427005046j:plain:w400

RAMは32KByteを2階建てにしてアドレス空間分フルに用意しました。

右のスペースは拡張用で、DMAと外部ボードへのコネクタを置く予定でいます。

Arduinoからのコネクタのそばに並んでいるのは74HC541で、Arduinoがバス権を持ってる間だけ開通するようになってます。これArduino側のボードに置くべきだったと思いますが、「Z80CPUにバス権がある時に出力と出力でぶつかる」ということに気付くのが遅れまして…。ただ、これについてはやはりArduinoの方で、出力しない時はピンを入力に設定しておくことで3ステート的なIOを実現できるんじゃないかと思ってます。やはりと言ったのは、一応試してはみたらしいんですよね。改めて勉強してみます。

ブランク明けでしたが2ヶ所の結線ミスで済んだのは、火入れをする前のチェックで気付けたことも含めて良し。でも、CPUがちゃんと動いているか不安です。RAMがブランクなので電源入れたらNOPを実行し続けるはず。つまり、4クロックのM1サイクルがひたすら繰り返されるはず。そして、クロック4MHzなので、M1端子の周波数を調べると1MHzが計測されるはず。なんですが、1MHzピタッと出ることもあれば、300KHzくらいだったり500KHzくらいだったり……。この周波数は電源入れ直すと変化しますが、ホットリセットをかけた場合はそのままです。また、M1の周波数が何であっても、CLKにはきっちり4MHzが入っています。なんなんでしょうね~。「RAMがブランク=全部0」という前提が勘違い、というのが最も穏やかな真実です。不定なコードが実行される場合はM1の周期が1MHzにはならないわけですね。まぁ他の電気的なミスがあるとしても現状の知識ではわからないので、Arduino側のRAM書き込みソフトの実装に移っています。こちらは週末完成が目標。

Arduinoプログラミングで1ヶ所詰まったのでシェアいたします。
pinModeでピンをOUTPUTに設定する時、なんもしないと最初はLOWが出力されます。このデフォルト出力をHIGHにしたい場合は、pinModeする前にdigitalWriteでHIGHを出力しましょう。こうするとピンがプルアップされて、OUTPUTに設定した瞬間からHIGHになるようです。ポートレジスタを弄る場合でも理屈は同じで、DDRxで出力設定する前にPORTxの目的ピンのビットに1を書き込めばOKです(私はこっちでやってます)。 これに気づかず、BUSRQ出す前にZ80さんからBUSAKアクティブが来てるんですけど?ってなりました。BUSRQをHIGHにするコードが一切なかったので当たり前だったんですが、少し考えてpinMode(BUSRQ, OUTPUT);のあとすぐにdigitalWrite(BUSRQ, HIGH);としてもその間でBUSRQ=LOWが拾われちゃうよね、と思い当たって調べた結果が上記です。

プルアップ関係でもうひとつ。オンボードで13番ピンにLEDが繋がっているArduinopinMode(13, INPUT_PULLUP);としてもピン開放時にHIGHになりません。ピンは開放してても回路完成しているので、LEDの電圧降下+電流調整抵抗の分圧ぶんでLOWレベルの電圧になってしまうようです(台湾で買った怪しいMega互換ボードの実測で、約1.8V)。