Z80-COREはコンパクトでシンプルなその構成とは裏腹に、以下に示す、ユニークなあるいはかなり強力なメモリ管理機構を持っています。
- 起動時には、メモリ領域の最初の16KBをROMが占めるが、任意の時点で、メモリのすべてをRAMに切り替えることができる。
- 当初メモリ領域の最初の16KBを占めているROMも含めて、32KBのROMがI/O空間の後半に配置されており、I/O空間を読み取り専用のコード・データストレージとして使用できる。
これらの機能を使うと、0番地からRAMが必要なCP/Mの移植も行うことができます。
これらの機能は、PIC18のCLCによって実現されています。
全メモリのRAM化
Z80-COREは、起動時にはメモリ領域の最初の16KバイトがROMで、残りの48KバイトがRAMとなっています。しかしながら、Universal Monitor のCコマンド(あるいは切り替え用コード)で、ROMをメモリから分離し、すべてのメモリをRAMにする構成変更をシステムの稼働中に行うことができます。
ROM領域のRAMへのコードとデータの書き込み
ROMが配置されているメモリ領域は、面白い機能を持っています。
Z80-COREの起動後の状態で、ROMが配置されているメモリ領域にデータを書き込むと、そこに配置されているけれどもその時点では読み出せるように構成されていないRAMにデータが書き込まれます。この機能を利用して、ROMに書き込まれたコードとデータをRAMに転写することができます。
ROMのコードとデータをRAMに転写するコードを以下に示します。
CPTORAM:
LD DE,0
LD HL,0
LD BC,4000H
LDIR
モニタのコールドスタートの処理で、上記のコードが実行されるため、Z80-COREのコールドスタート後には、ROMの内容がまだ読み出せる状態にはなっていないRAMに転写されています。
このため、任意の時点でROMを切り離し全メモリがRAMに切り替わっても、もともとROMがあった領域に配置されたRAMから、ROMに書かれていた内容と同じコードやデータが読み出せるので、特段の変化は発生しません。
また、ROMが配置されている状態で、自身でコードやデータの書き込みを行えば、RAMにはそれらのコードやデータが書き込まれるものの、ROM領域の読み出し結果は何ら影響を受けませんが、RAMへの設定がすべて終わったのちにROMを切り離してRAMに切り替えれば、その時点から自分で書き込んだプログラムやデータを読み出して使用するようになります。
ROMからRAMへの切り替え
ROMを切り離しRAMに切り替える処理は、下記の処理の様にI/Oアドレスのアクセスで実施することができます。なお、ROMからRAMへの切り替えは可能ですが、RAMからROMへの切り替えはできないのでご注意ください。
SWITCHRAM:
LD BC,0E0H
OUT (C),A ; Switch to RAM
動作確認
まずZ80-COREが起動されたすぐ後の状態で、Dコマンドを使用してROM領域内の3000番地からのデータを表示します。
そして、Sコマンドを使用して、一部のデータの修正を試みます。
書き込みを行った領域はROMなので、Dコマンドで再度内容の確認を行っても、変化はありません。
ここで、Cコマンドを実行して、ROM領域のRAMへの切り替えを行います。
そして、再度Dコマンドを使用して3000番地からのデータを表示します。
すると、3000番地からのデータが01,02,03,04に書き換わっていることが確認できます。
DコマンドでROM領域のデータを書き換えてもROMの変化は当然ありませんでしたが、その裏側のRAMには書き込まれており、ROMがRAMに切り替えられると、書き込まれていたデータが読み出せるようになったということです。
ROM領域がRAMに切り替わった後は以下のように、書き込んだデータはすぐさま読み出し結果にも反映されます。
全メモリがRAMになっているので、以下のように0-100H領域にも余裕で書き込めます。
暴走書き込みに注意
とても柔軟性の高い魅力的な機能ですが、コードがROMに書かれている状態とは違って、プログラムが暴走してRAM上のコードエリアを書き換えてしまうと、どうしようもなくなるということが欠点でしょうか。メモリ保護機構がないのでしょうがないよね。
ROMのI/O空間への配置
Z80-COREに搭載されるROMの容量は64Kバイトで、2組の32Kバイト領域に分離して利用します。ROMの前半と後半のどちらの32Kバイトを使用するかは、JP2で設定します。
2つに分割されたROM領域のそれぞれの前半の16Kバイトは、Z80-COREの起動時には、メモリ空間の最初の16Kバイトの領域に配置されます。この配置は、前半で示した機能で無効にし、RAMの配置に置き換えることができます。
また、JP2で選択された32KバイトのROMはメモリ空間に配置された前半の16Kバイトの部分も含めて、16ビットのI/O空間の後半の8000Hからの領域に配置され、IN r,(C)命令で読み出すことができます。また、Universal MonitorのIコマンドで読み出すこともできます。
まず、0番地からのメモリ、この例ではZ80-COREが起動したばかりですので、ROMの内容となりますが、それをDコマンドで表示して見ました。
次に、モニタのIコマンドを使用して、16ビットのI/O空間の8000番地台のアドレスの内容を読み出してみました。
ROMの0000とI/Oの8000は同じF3、ROMの0001とI/Oの8001は同じC3、ROMの0070とI/Oの8070は同じ20であることが確認できます。同様にして、I/O空間の8000からFFFFまでに、JP2で選択されている32KバイトのROMの内容が配置されています。