ゲームボーイを作るその13。加算・減算などを実装しようと思って、仕様を読んでいたのだがフラグ系のレジスタの動きを整理しておきたいと思ったので、簡単にまとめておく。
CPUの算術/論理演算とフラグレジスタ
9回目にCPUの持っているレジスタについて軽く取り上げているが、その時にフラグレジスタの各ビット配置と説明も記載していた。(表自体hPanDocsから持ってきたもの)
フラグレジスタのみ、ビットフィールドの定義が別口になるので、そちらも確認しておく。
N
/H
/C
の(BCD)
は、これらのフラグビットがDAA
命令の時にのみ使用されることを示している。 | Bit | Name| Explanation | |--------|-----|-------------------------| | 7 | Z | Zero Flag | | 6 | N | Add/Sub Flag (BCD) | | 5 | H | Half Carry Flag (BCD) | | 4 | C | Carry Flag | | 3-0 | - | Not used (alwasys Zero) |
Z
とC
がそのままなのはわかるが、N
/H
は?となったのが、この記事を書こうと思った理由になっている。Z
/C
も含む各ビットの詳細な説明がPan Docsに載っているが、改めてまとめてみようと思う。
各命令セットのFlagsの見方
Pan Docsの命令セットの説明には次のようなFlgas
の扱いが記載されているが、最初はこの見方がイマイチわからなかった。
Mnemonic | Encoding | Clock cycles | Flags | Description |
---|---|---|---|---|
add A,r | 8x | 4 | z0hc | A=A+r |
理解してしまえばなんという事はなかったのだが、次のような解釈でOKっぽい。
0
/1
→ 演算実行時に指定される0
/1
のいずれかをセットz
/h
/c
→ 演算結果の各z
/h
/c
の条件を満たせば1
、それ以外は0
に設定
ここからはz
/n
/h
/c
の各フラグを1
にする条件について、まとめておく。
Zero (Z)
Z
についてはZeroの示すとおりで、演算結果が0x0
になっていれば1
をセットする。
N
N
はPan Docsの説明的には「直前の実行した命令が減算の場合には1
」となっている。ただこの指定は計算結果によるものではなく、命令の種類によって一意に決まるものとなっており、各資料の命令セットでは「この命令を実行した場合には1
/0
をセットする」と言った形で記載されている。
H (Half Carry)
H
はHalf Carry
をなっている。このフラグビットは、演算のビット幅の半分のビット位置を基準にして、演算した結果キャリーが発生したかどうかに応じて1
/0
が設定される。
たとえば次のような命令を実行した場合にH
が1
に設定される。
ld a, $0f ld b, $01 add a, b ;; a = $0f + $01 = $10 となりbit4に1が立つ
このフラグビットは、最初に記載した表にもあるとおりDAA
命令の時に使用される。
C (Carry)
こちらは通常のキャリーフラグ。演算のビット幅に対してキャリーが起きたかどうかで1
/0
が設定される。
ld a, $0f ld b, $01 add a, b
これでどう実装すれば良いかがわかったので、今度こそ算術演算系の命令の実装に進もうと思う。