memo.log

技術情報の雑なメモ

ROMとZ80でLチカして、CPUの動作を理解する【命令サイクル注釈動画付き】

概要

Z80とROMでLチカしてみました。

基本的にLEDはZ80のアドレスバスに接続し、アドレスバスの出力を可視化します。加えて、動作の理解のため、M1のピンと、リフレッシュのピンにも接続します(役割は後述します)。

まず、動作させた動画を掲載します。クロックは1Hzとしているので、命令サイクルごとの動きがよく分かると思います。本記事では、これらの回路の設計、プログラム、CPUの動作原理をまとめて紹介します。

使用した部品一覧

回路図

実物の回路は以下です。LEDはアドレスバスとM1ピンとリフレッシュピンに接続しています。LEDは下の方から下位のビットに接続してます。(例:一番下だけ点灯したら1)

回路図は以下の通りです。Z80とROMだけを接続したシンプルな回路です。ROMを使っていますが、CPU的にはメモリの役割として使っています。

Z80とROMが接続されているのは、以下です。メモリとして使っているため、MREQとRDをROMに接続します。

  • アドレスバス
  • データバス
  • MREQ(メモリリクエスト) ⇔ CE(チップセレクト)
  • RD(リード) ⇔ OE(アウトプットイネーブル

Z80の動作原理

実際に回路を動かす前にZ80の動作原理を確認します。下部に掲載の図はトランジスタ技術 SPECIAL No.49から抜粋です。サンプルはLD A (1234h) 命令の様子です。(メモリの1234h番地からAレジスタに値を読み込む)

  • 前提として、メモリの0番地~2番地にLD A (1234h) 命令が格納されており、メモリの1234hに読み取らせたいデータが格納されているということです。つまり
    • メモリ0番地: LD
    • メモリ1番地: 34h
    • メモリ2番地: 12h
  • まず電源を入れてZ80をリセットすると、プログラムカウンタが0になり、0番地から命令を読み込んでいきます。
    • 0なので、アドレスバスはすべてLOW
    • 命令(オペコード)を読み込みます(例: LD
    • オペコード分、プログラムカウンタを進めます( LD の場合は1Byte)
  • プログラムカウンタが1になり、1番地からオペランドを読み込んでいきます。LDの場合は、オペランドが1Byte * 2 の2Byteなので、1Byteを2回読み取っていきます。
    • 1なので、アドレスバスの最下位のピンをHIGHにします
    • オペランドの下位バイト(アドレス1)の値をデータピン経由で読み取ります(34h)
  • プログラムカウンタが2になり、2番地からオペランドを読み取ります
  • 命令 LD A (1234h) が読み取れたので、命令を実行します。命令はアドレス 1234h からAレジスタに読み込むということなので、アドレスバスに 1234h を出力します。
  • 無事に命令を実行できました。次の命令に移るため、プログラムカウンタを1増やして、アドレスバスに3を出力して命令(オペコード)をフェッチします。
    • オペコードフェッチ時はM1サイクルと呼ばれるので、M1ピンがLOWになります
  • オペコード読み取り後は通常「リフレッシュアドレス」というものを出力するようです。これはDRAMの際に、必要な処理らしいのですが、今回は関係ないので深堀りしていません。
    • この際、リフレッシュピンがLOWになります

以上がZ80が命令を読み込んで、実行するまでのサイクルになります。これをプログラムカウンタを増やしながら順次進めていきます。

かいつまむと、

オペコードをフェッチする→オペランドをフェッチする→実行する

をプログラムカウンタを増やしながら繰り返す、ということです。

その他メモ

  • Z80のアドレスピンは16個=2Byte分あります
    • 2Byteということは、10進数で65536通りの値を表現できます
    • データピンは8個=1Byteです。ということは、1Byte * 65536 = 64KB までのメモリを扱えるということです。すなわち、アドレス空間が64KB。

ROMプログラムの準備

さて、大体の動作原理がわかったところで、いよいよプログラムを動かしていきます。

最初にROMにプログラムを書き込みます。 ※ROMの使い方は以前、この記事で紹介していますので、省略します。

今回は、CPUの動作原理を確認するのが目的なので、意味のないプログラムですが、以下のように先程の動作原理の解説でも用いた命令 LD A, (0x01) を連続で実行していきます。

START:
    LD A, (0x01)
    LD A, (0x01)
    LD A, (0x01)
    LD A, (0x01)
    LD A, (0x01)
    JP START

Z80を動作させる

それでは、Z80に電源を入れて、リセットします。リセットすることで、PCが0から、Z80がメモリから命令を順番に読み込んで行きます。リセットは、リセットピンをLOW→HIGHにすることで可能です。

最初の動画を再掲します。いかがでしょうか。動作原理に解説したとおり、アドレスバスに想定どおりの出力がされながら、実行が進んでいく様子が分かるのではないでしょうか。

おわりに

雑誌片手にZ80の動作原理を学習しつつ、Lチカさせることで、実際の動作を確認していきました。 理屈と動作が辻褄があっているので、おそらく記載した内容も間違っていないとは思うのですが、不正確な部分等あればご指摘いただけますと幸いです。

次は、IOデバイスも加えて、もう少しコンピューターらしくしていきたいと思います。

その他参考記事

sanuki-tech.net

データシート

https://suzushoweb.com/pdf_file/533506202c31a.pdf