石原 博の覚書

電子工作に関する日々の覚書を記載します

Z80-MBC2のブートについて

2021-08-05 17:49:27 | 日記

昔からZ80をAVRなどでコントロールすることは考えたことが何度かあった。しかしデータバスが8bitで、アドレスバスが16bitで MREQ, RD, WR, RESET, BUSREQ, BUSACKとコントロールするバスが多い。ラッチしてとか、アドレスバスはバイナリカウンタでとか、3ステートのコントロールがとか考えて複雑になりすぎて諦めていた。

ところがZ80-MBC2では思いもよらない方法でこれを回避している(アドレスバスで使っているのは1ビットだけ)
そこでブート部分を簡単に整理してみた。(S220618_IOS-LITE-Z80-MBC2.ino)

メモリは128KB
BANK0, BANK1で32KB毎のバンク
BANK0=Hの場合は通常の64KB

 

[0]初期状態は
  CPU    RESET=L、WAIT=L、INT=H、BUSREQ=H という完全停止
  メモリ  CE2=Hとしてアクセス可能状態

  MREQ、RD、WR、AD0はavrから読み込める状態になっている

[1]メモリマップセット
 BANK0=H, BANK1=L

[2]リセット(singlePulsesResetZ80())
 RESET=Lとしていはいるが、CLKが停止しているのでCPUは実際にRESETされているわけではない。
 この状態でクロックを入れる。(RESET=Lで6クロック、RESET=Hで2クロック)
  この段階でRESETはHになっている

[3]メモリへ書き込み
 スタートアドレスが0なら、そのままスタートアドレスから書き込むが、そうでなければ0〜3バイトにスタートアドレスへのJMP命令を書き込む。

[3-1]メモリへの書き込み詳細(loadHL(BootStrAddr))
 ・クロックを1回入れる->M1サイクルのT1ステート
 ・CE2=LとしてメモリをHiZ状態として、データバスに LD HL, のオペコードを書き込む
 ・クロックを2回入れる->M1サイクルのT2, T3ステート
 ・AVRのデータバスをinput状態に戻し、クロックを2回->M1サイクルのT4ステート、次のM2サイクルのT5ステート
 ・AVRのデータバスをoutput状態にし、BootStrAddrの下位8ビットを出力し、クロックを3回->M2サイクルT6,T7,M3サイクルT8ステート
 ・AVRのデータバスにBootStrAddrの上位8ビットを出力し、クロックを2回->M3サイクルT9, T10ステート
 ・AVRのデータバスをinput状態に戻しCE2=Hとしてメモリを有効状態とする
 
[3-2]メモリへの書き込み詳細(loadByteToRAM())
 ・クロックを1回入れる->M1サイクルのT1ステート
 ・CE2=LとしてメモリをHiZ状態として、データバスに LD (HL), のオペコードを書き込む
 ・クロックを2回入れる->M1サイクルのT2, T3ステート
 ・AVRのデータバスをinput状態に戻し、クロックを2回->M1サイクルのT4ステート、次のM2サイクルのT5ステート
 ・AVRのデータバスをoutput状態にし、メモリへ書き込むべき8ビットを出力し、クロックを2回->M2サイクルT6,T7ステート
 ・AVRのデータバスをinput状態に戻し、メモリを有効状態としてクロックを3回->M3サイクルのT8, T9, T10ステート

 ・クロックを1回入れる->M1サイクルのT1ステート
 ・CE2=LとしてメモリをHiZ状態として、データバスに INC HL のオペコードを書き込む
 ・クロックを2回入れる->M1サイクルのT2, T3ステート
 ・AVRのデータバスをinput状態に戻し、メモリを有効状態としてクロックを3回->M1サイクルT4, T5, T6

[4]クロックの供給
 リセットして、クロックを供給して、リセット解除(Hにする)
 クロックはAVRのTimer2を使用 (8MHz or 4MHz)

要するに、z80に1バイト書き込みプログラムを強制的に読み込ませ、z80自身にメモリへ書き込みをさせている。このためアドレスの管理やMREQ, RD, WR などのタイミングを含めて制御はすべてz80自身が行ってくれることになる。

その他
 メモリのバンクについては、ダイオードを使っている。ちょっとわかりにくかったので調べた。
 32KB単位のバンクで128KBメモリなので4つのブロックがある。00000-07FFFが1つ目のブロック、08000-0FFFFが2つ目のブロック...。CP/M3.0は、OSのある上位32KBは変化せず下位32KBだけ切り替えているので、以下のような割当になっている。