15

私は現在、古き良きゲームボーイ用のエミュレーターを開発していますが、いくつかの基本的な操作コードを実装する方法を理解する上でいくつかの問題に直面しています。

現在、AND 演算を実装しています。最初のいくつか (0xA0 -> 0xA3; 0xA6 & 0xA7) は非常に単純ですが、レジスタ H、L の AND 演算は少し異なります。

z80 のドキュメントは、次のリンクからダウンロードできます: um0080.pdf (172 ページ)

ここに、私が何を意味するか (疑似コードを使用) と基本的に何をするかを示すいくつかの例を示します。

AND A,H (ビットシフトに注意)

(read HL register; >> 8) save in cache C
R->C = R->HL >> 8;

perform AND operation with cache
AND_H(R->C);
R->A &= R->C;

AND A,L (ビットマスキングに注意)

(read HL register; &0xFF) save in cache C
R->C = R->HL &0xFF;

私はすべてのビット操作を知っており、それらが何をするかを知っていますが、なぜそのようにする必要があるのか​​ 理解できないようです. 私にはいくつかの理論があります (間違っていたら訂正してください :-)):

私がすでに理解していることは、レジスタ H と L は基本的に 16 ビット レジスタであるレジスタ HL であるということです。CPU/バスは 8 ビット操作しか処理できないため、分割する必要があります。または、より論理的な提案: 唯一のレジスタであるため、H と L の値はレジスタでマスクされ、単に互いに分離する必要があります (上位/下位ニブル?)。

背景知識(これらすべてが内部でどのように機能するか)を知りたいので、誰かがこれをより明確にしてくれれば、深く感謝します。

4

1 に答える 1

11

コメントが指摘しているように、見つけた実装はHレジスタとLレジスタを16ビットエンティティHLとして一緒に格納し、右にシフトしてHに分解し、マスクオフしてLに分解するという事実は純粋に実装固有です。

オリジナルのz80には4ビットのALUがあり(コンピュータ歴史博物館のパネルのこのトランスクリプトの9ページの下部から始まるShimaのコメントを参照)、実際には(i)Lの下位4ビットとアキュムレータがあります。次に(ii)Lの上位4ビットとアキュムレータ。ただし、レジスタを個別の8ビットエンティティとして公開するため、内部実装は完全に非表示になります。

HLは、2つのレジスタを組み合わせて16ビットの量を作成するため、レジスタペアと呼ばれます。シャドウレジスタとインデックスレジスタを無視すると、元のz80には実際にはHL、BC、DEの3つがあります。BCとDEは、ゲームボーイのCPUで、間接ロード(opcode 0x1a — LD A、(BC)など)および16ビット演算(0x09 ADD HL、BCなど)の代替ペアとして存続し、 z80。

SPとPCは一般に分割できない16ビットレジスタと見なされ(もちろん、メモリに格納してバイトを個別に読み取ることで分割できます)、プッシュとポップ用にAFが存在しますが、FはAFのような特殊なケースです。通常、16ビット整数としては特に有用ではありません。

簡単にまとめると、オペコードどのように実装する必要があるかを理解するのに問題はなく、特定の作成者によってどのように実装されているかだけです。

于 2012-03-13T01:19:33.323 に答える