Z80の24bit化(5) LD命令を整理しました
eZ80の命令を取り入れた16ビット転送と24ビット転送
MSXのCPUを24ビット化するプロジェクトを進めています。
ベースとなるのは、FPGAで動作するZ80互換CPU「T80」です。
従来のZ80との互換性をできるだけ維持しながら、24ビットのアドレス空間を利用できるようにすることを目指しています。
今回は、CPUの命令セットを見直し、特に16ビットと24ビットのLD命令を整理しました。
この整理で参考にしたのが、ZilogのeZ80です。
eZ80には、従来のZ80にはなかった便利なレジスタ間・メモリ間の転送命令があります。
そのうち、今回のMSX拡張CPUでも利用したい命令を取り入れ、さらに独自の24ビット転送命令を追加する方針にしました。
従来のZ80では16ビット転送に制約がある
Z80では、8ビットレジスタを使ったデータ転送は比較的自由に行えます。
例えば、
LD A,B
LD B,C
LD A,(HL)といった命令です。
しかし、16ビットレジスタペアを使った転送には制約があります。
例えば、IXレジスタが指すメモリからBCレジスタへ16ビットの値を読み込みたい場合、従来のZ80には次のような命令がありません。
LD BC,(IX+0)そのため、複数の命令を組み合わせる必要があります。
24ビットCPUを作るのであれば、このあたりも使いやすくしたいところです。
そこで、eZ80の命令セットを参考にしました。
eZ80の16ビットLD命令を採用
今回取り入れたのは、IX/IYを使った16ビット転送命令です。
例えば、次のような命令です。
LD BC,(IX+d)
LD DE,(IX+d)
LD HL,(IX+d)IXレジスタが示すアドレスに変位dを加えた場所から、16ビットの値を読み込みます。
逆方向の転送もできます。
LD (IX+d),BC
LD (IX+d),DE
LD (IX+d),HLもちろん、IXだけでなくIYも使用できます。
LD BC,(IY+d)
LD (IY+d),HLこれらはeZ80に存在する命令であり、今回のMSX拡張CPUでもeZ80と同じオペコードを採用しました。
採用した16ビットLD命令
オペコード 命令
DD 07 d LD BC,(IX+d)
DD 17 d LD DE,(IX+d)
DD 27 d LD HL,(IX+d)
DD 0F d LD (IX+d),BC
DD 1F d LD (IX+d),DE
DD 2F d LD (IX+d),HL
IYの場合は、先頭のDDをFDに置き換えます。
これにより、IX/IYをベースアドレスとして使用するプログラムで、16ビットデータを扱いやすくなります。
特に、構造体やテーブルなどのデータを扱う場面で便利そうです。
24ビットLD命令も用意する
今回のCPUは24ビット化を目指しているため、16ビットの転送だけでは足りません。
BC、DE、HLなどのレジスタペアは、上位8ビットのバンクレジスタと組み合わせて24ビットの値を保持できるようにする予定です。
例えばBCなら、
23 16 15 8 7 0
┌──────────┬───────────┬───────────┐
│ B' │ B │ C │
└──────────┴───────────┴───────────┘
8bit 8bit 8bitという構成です。
この24ビット全体を転送するために、独自のLD24命令を用意しました。
IXを使った24ビットLD命令
LD24 BC,(IX+d)
LD24 DE,(IX+d)
LD24 HL,(IX+d)逆方向も用意します。
LD24 (IX+d),BC
LD24 (IX+d),DE
LD24 (IX+d),HL16ビット版と24ビット版を並べると、次のようになります。
転送内容 16ビット版 24ビット版
メモリ→BC DD 07 d DD 08 d
メモリ→DE DD 17 d DD 10 d
メモリ→HL DD 27 d DD 18 d
BC→メモリ DD 0F d DD 20 d
DE→メモリ DD 1F d DD 28 d
HL→メモリ DD 2F d DD 30 d
こちらもIY版を用意しています。
16ビット版はeZ80と同じ命令コードを使用し、24ビット版はMSX拡張CPU独自の命令として割り当てています。
つまり、16ビット転送はeZ80の命令体系を活用し、24ビット転送は独自に拡張するという構成です。
16ビットと24ビットを明確に使い分ける
今回の設計では、16ビットと24ビットの転送を明確に区別しています。
例えば、
LD BC,(IX+0)は16ビットの転送です。
一方、
LD24 BC,(IX+0)は24ビットの転送です。
これにより、プログラム側で扱いたいデータ幅を明示できます。
MSXでは、従来の16ビットアドレス空間を使う処理も引き続き重要です。
すべてを24ビットにしてしまうのではなく、必要な場所だけ24ビットを使えるようにしたいと考えています。
レジスタ間の24ビット転送も追加
メモリとの転送だけでなく、24ビットレジスタ同士の転送も用意しています。
例えば、
LD24 HL,BC
LD24 BC,HL
LD24 HL,DE
LD24 DE,HLといった命令です。
24ビットのアドレス値をレジスタ間で移動する場合、上位8ビットも含めて転送できます。
また、IX/IYとの24ビット転送も用意しています。
LD24 HL,IX
LD24 IX,HL
LD24 HL,IY
LD24 IY,HL24ビットアドレスを扱うプログラムでは、こうした命令が役立つはずです。
eZ80と同じ命令コードを優先する理由
今回の命令整理では、Zilogの公式eZ80ユーザマニュアルを参照しています。
eZ80と同じ機能の命令については、できるだけ同じオペコードを使う方針です。
理由はいくつかあります。
まず、既存のCPUアーキテクチャを参考にできることです。
まったく独自の命令体系を作るよりも、既存の命令との共通部分があるほうが理解しやすくなります。
また、将来的にアセンブラなどの開発環境を整備するときにも、eZ80の命令体系が参考になります。
ただし、今回のCPUはeZ80互換CPUを目指しているわけではありません。
あくまでもMSXとの互換性を重視した、T80ベースの24ビット拡張CPUです。
そのため、eZ80の命令をすべて採用するのではなく、必要なものを選んで取り入れています。
命令コードの重複も整理
命令を追加するうえで難しいのが、オペコードの割り当てです。
Z80には既存の命令が多数あり、eZ80にも独自の拡張命令があります。
さらに今回のCPUにも、モード切り替えや24ビット演算などの独自命令があります。
そのため、Zilogの公式マニュアルと照合しながら、命令コードの重複を確認しています。
今回の整理では、命令一覧に**「eZ80との対応区分」**も追加しました。
これによって、eZ80と同じオペコードを使用する命令と、MSX拡張CPU独自の命令を区別できるようにしています。