Z80 コンピュータを作ろう!(その1)
さて,いい加減,電子工作ネタに入っていきたいと思いますが,ここまでの流れもあって,Z80 を使ったコンピュータを作っていきたいと思います。
何を今さら…と言った感じですか?まぁ,そうですよね…。
昨今のマイコンと言えば,普通ワンチップマイコンのことを指すと思います。
PIC とか,AVR,もう少し高機能なもので mbed などがありますね。
これらには,ROM,RAM,I/O が組み込まれていて,(電源やクロックは必要になるにしろ)プログラムを書き込んで動作させることができます。
Z80 は,CPU そのものなので,外部にメモリや I/O を接続しないとマイコンシステムとしては動作させることはできません。(周辺をワンチップ化した Z80もありますが,ここでは 素の Z80 を使いたいと思います)
なぜ,Z80 なの?
私が好きだから…というのが一番の理由なのですが…。
上にも書きましたが,CPU の周辺に他のデバイスを物理的に繋げないと,システムとして動作しないので,逆に全体像が目で確認できるというメリット(?)があります。
各デバイス間を「バス」と呼ばれる信号線で繋ぎ,それらを専用の制御信号線で切り替えながらコントロールします。
ですので,かなり配線が多くなるのですが,回路が完成すると,全体がどういう構造で動いているかがわかりやすいと思います。
CPU 単体で使うなら,別に他の 8bit CPU でもいいんじゃないの?と言われそうですが,発売から40年以上経った現在でも実チップが入手しやすく(…と言っても,置いているお店はほとんどありません),資料も豊富です。
国産パソコンの黎明期にシェアが大きかったので,ソフトウェア資産も非常に多いと思います。
内部的な構造とか,レジスタ構成とか,命令セットなどは,ネットで検索すれば山ほどヒットしますし,多分,これを読んでいる人は,Z80 でアセンブラプログラムができる人が多いでしょうから(ですよね?),今回は割愛して,ハードウェア的な信号(足に出ているピン)などについて書いてみたいと思います。
電源とクロック
CPU を動作させるには,電源とクロックパルスが必要です。
電源は,5V 単一電源で,クロックは単相クロックです。これは今のマイコンに近いですね。
バス信号線
アドレスやデータはそれぞれ,バスと言われる信号線に乗せて伝達します。
アドレスバスは,A0~A15 まで 16 本あります。
CPU からメモリやデバイスに対してアドレスを決定するために出力されます。
16bit なので,64KB までの範囲を指定することができますが,まともなコンピュータやゲーム機を作ろうとすると,このアドレス幅では足りなくなるケースが多く,「バンク切り替え」と言う,アドレスの一部範囲を物理的に別メモリまたはデバイスに切り替える手法が一般的でした。
スポーツで言うと,試合に参加できる人数は決まっていますが,そのうちの一人を控え選手と途中交代させて,実質多くの選手を使うという感じに近いですね。
データバスは,D0~D7 まで 8 本あります。
8bit なので,0〜255 までのデータを扱うことができますが,CPU 内部では,8bit のレジスタを2つ合わせて 16bit のデータとして扱うこともできます。
その場合でも,ピンに出ている外部バスは 8 本しかないので,16bit データは,2回に分けて入出力されます。
このデータバスが 8bit なので,8bitCPU と言われます。
ちなみに MSX TurboR に採用されていた上位 CPU の R800 は,16bit CPU と呼ばれていましたが,外部バスは 8bit です。(内部のバスが 16bit なんですね)
アドレスデコーダーとチップセレクト
Z80 にメモリや,I/O デバイスを複数繋げてデータのやり取りをするには,それぞれをアドレスバス,データバスに繋げる必要があります。
ただし,複数のデバイスが同時にバスを使うことはできません。
これは道路と同じで,信号機がない状態で,それぞれの道路を車が勝手に走ると交通渋滞や事故が起こりますよね。
「今回は,あなたとの間で道路を使いますよ」という信号を与えて,データのやり取りをする相手を決めるのです。
一般的に,これは,チップセレクトとかチップイネーブル信号とか言われていますが,ある特定の周辺デバイスのみにこの信号を与えてやります。
この信号が与えられない他の周辺デバイスは,バスには物理的に繋がっていても,電気的に切り離された状態になります。(これをハイインピーダンス状態と言います。詳細はまた別の機会に書きたいと思います)
これで,ある特定のデバイスとだけ,バスでの信号のやり取りを行うことができるのです。
では,このチップセレクト信号を出してやる特定のデバイスはどうやって決めるのでしょう?
これはアドレスバスに出力されている信号,すなわちアドレスそのものによって決まります。
よく,ROM は,このアドレスからこのアドレスまで…とか,RAM はここから…とか,I/O ポートのここには何が繋がっている…なんて聞いたことありますよね。
このアドレス信号から範囲を特定して,そのデバイスに対して,チップセレクト信号を出します。
この範囲を特定する回路をアドレスデコーダと言います。
メモリ,I/O リクエスト信号と読み書き信号
Z80 の書き込みと読み込みは,メモリに対する命令(LD とか PUSH とか)と I/O に対する命令(IN とか OUT)がありますが,どちらもアドレスは同じアドレスバスに出力されます(I/O ポートは 8bit なので実質下位 8bit 分しか使われませんが)。
ですので,アドレス情報だけでは,メモリに対するアクセスなのか,I/O に対するアクセスなのかがわかりません。
そこで,メモリに対するアクセス時は,/MREQ 信号,I/O に対するアクセスは /IORQ 信号が出力され,それぞれ区別されます。
この /MREQ 信号と,/IORQ 信号と,アドレス信号をごにょごにょして最終的なアクセスデバイスがチップセレクトされることになります。
アクセスするデバイスが決定すると,後は読み込みなのか,書き込みなのかですが,読み込みの場合は,/RD 信号が,書き込みの場合は /WR 信号が出力されます。
基本はこれらの信号で動作しています
アドレスバスでアドレス決定,/MREQ,/IORQ で,メモリか,I/O を決定,書き込みだったら,データバスにデータを出力して,/WR。読み込みだったら,/RD を出力してデータバスからデータを読みだす。
後は CPU 内部で足し算だったり,引き算だったり,論理演算だったり,シフト演算だったり,計算しますが,外との信号のやり取りは,上記信号の出力をクロック信号に合わせて繰り返しています。
他にも,リセットとか,割り込みとか,バスをよこせとか,動作を止めたよ,とかの信号がありますが,基本的には,上で説明した信号でプログラムが動作しています。
次回へ続く…
次回は,残りのコントロール信号と,メモリのアクセス周りに関して書いてみたいと思います。(いいから早く作れって?まあ,お気楽ですから…)