Z80 は 1980 年頃によく使われた 8bit CPU です。 搭載されていたパソコンでは、NEC の PC-8001/PC-8801 シリーズが有名です。
当時のほとんどのパソコンには BASIC 言語が内蔵されていましたが動作が遅く、 コンパイル言語はほとんど普及していなかったため、 もっと処理速度が必要なゲームなどを作るときには Z80 アセンブリ(当時は「マシン語」という言葉がよく使われていました) で頑張って記述していました。
今回「Z80 で円周率を計算」を書いていて、初めは「Z80 に関する詳しいことはググってください」で済ませようかと思ったのですが、 ある程度の知識を前提にしないと解説しにくいので書くことにしました。
Z80 には比較的多くのレジスタ(register)があります。 レジスタというのは、メモリ空間とは別の一時記憶です。 図示すると以下のようになります。
F(フラグ)レジスタは、 命令実行の結果によって変化するフラグ(1bit)の集合体です。 各条件が成立すると 1 になります(「立つ」と表現します)。 ただし命令によっては変化しなかったり、条件が異なったりするので、 以下の説明は参考程度にしてください。
ほとんどの場合、Z フラグと C フラグで事足りると思います。 この 2 つは特にどの命令で変化するかに注目しておいてください。
ここからは各命令の解説です。まずは一番よく出てくる LD 命令で、次の形式になっています。
命令 | 動作 |
---|---|
LD dest,src | dest←src |
LD は LoaD の略で、データを右から左へ転送します。 CPU によっては、メモリが転送元か転送先かによって load と store に分かれていたりしますが、Z80 では全て LD です。
なお、「LD」の部分を「オペコード(op code)」、 「dest,src」の部分を「オペランド(operand)」と言います。
LD 命令では、一部の特殊な命令(LD A,I
と
LD A,R
)を除いて、フラグが一切変化しません。
大事なことなのでよく覚えておいてください。
命令 | 動作 |
---|---|
LD r,r' | r←r' |
r(と r')は 8bit レジスタ B,C,D,E,H,L,A のいずれかを指します。 今後この表記はよく出てくるので覚えておいてください。
これらの 8bit レジスタ間では全ての組み合わせがありますが、 メモリアクセスに関するものは組み合わせが限られています。
命令 | 動作 |
---|---|
LD r,n | r←n |
LD r,(HL) | r←(HL) |
LD A,(BC) LD A,(DE) |
A←(BC) A←(DE) |
LD A,(nn) | A←(nn) |
LD (HL),r | (HL)←r |
LD (BC),A LD (DE),A |
(BC)←A (DE)←A |
LD (nn),A | (nn)←A |
LD (HL),n | (HL)←n |
n は任意の 8bit 値、nn は任意の 16bit 値です。
オペランドの各要素が括弧で囲まれている場合は、 基本的にメモリアクセスを意味します(IN, OUT, JP 命令は例外)。
(HL)
に関するものは、(IX+d)
と
(IY+d)
に置き換えたものもあります。
命令 | 動作 |
---|---|
LD r,(IX+d) LD r,(IY+d) |
r←(IX+d) r←(IY+d) |
LD (IX+d),r LD (IY+d),r |
(IX+d)←r (IY+d)←r |
LD (IX+d),n LD (IY+d),n |
(IX+d)←n (IY+d)←n |
d は符号付き 8bit 値で、-80H~+7FH の範囲を指定できます。 インデックスレジスタはこのようにオフセット付きでメモリアクセスできますが、 動作速度はかなり遅いので、 速度の要求されるプログラムではあまり活躍しません。
LD rr,nn LD IX,nn LD IY,nn |
rr←nn IX←nn IY←nn |
LD rr,(nn) LD IX,(nn) LD IY,(nn) |
rrL←(nn), rrH←(nn+1) IXL←(nn), IXH←(nn+1) IYL←(nn), IYH←(nn+1) |
LD (nn),rr LD (nn),IX LD (nn),IY |
(nn)←rrL, (nn+1)←rrH (nn)←IXL, (nn+1)←IXH (nn)←IYL, (nn+1)←IYH |
rr は 16bit レジスタ BC,DE,HL,SP のいずれかを指します。
16bit メモリアクセスについてですが、Z80 では 16bit データは「下位 8bit, 上位 8bit」の順になることに注意してください。 これを「リトルエンディアン(little endian)」と言います。
CPU によっては「上位 8bit, 下位 8bit」の順のものもあり、こちらは「ビッグエンディアン(big endian)」 と言います。
残りの LD 命令は以下の通りです。16bit レジスタ間の LD 命令は他にはありません。
LD SP,HL LD SP,IX LD SP,IY |
SP←HL SP←IX SP←IY |
LD A,I | A←I |
LD I,A | I←A |
LD A,R | A←R |
LD R,A | R←A |
交換命令には EX 命令(EXchange)と EXX 命令があります。 いずれもフラグは変化しません。
命令 | clk | 動作 |
---|---|---|
EX DE,HL | 4 | DE←→HL |
EX AF,AF' | 4 | AF←→AF' |
EXX | 4 | BC←→BC', DE←→DE', HL←→HL' |
16bit レジスタでは HL が演算やメモリアクセスの中心なので、EX DE,HL
で挟んで DE レジスタも活用することがよくあります。
EX AF,AF'
と EXX
は表レジスタと裏レジスタを交換します。裏レジスタを操作する命令はこの 2
つだけです。
ここでは特別に clk 数も記載しましたが、いずれも 4clk と最低限で済み、高速化によく使われます。
ちなみに裏レジスタは、 本来は割り込み処理でレジスタをすばやく退避するためのものだと思われます。 メイン処理で使う場合にはそのことを考慮する必要があります。
命令 | 動作 |
---|---|
EX (SP),HL EX (SP),IX EX (SP),IY |
(SP)←→第 2 オペランドの下位 8bit, (SP+1)←→第 2 オペランドの上位 8bit |
これらはスタックトップと 16bit レジスタを交換します。
Z80 の算術演算命令は、主に加減算命令です。乗除算はありません。
まずは 1 足す INC(INCrement)命令です。
命令 | フラグ変化S Z H P N C |
動作 |
---|---|---|
INC r | * * * V 0 - | r←r+1 |
INC (HL) INC (IX+d) INC (IY+d) |
* * * V 0 - | (HL)←(HL)+1 (IX+d)←(IX+d)+1 (IY+d)←(IY+d)+1 |
INC rr INC IX INC IY |
- - - - - - | rr←rr+1 IX←IX+1 IY←IY+1 |
8bit 演算では C フラグ以外のフラグが変化しますが、16bit 演算では変化しないことに注意してください。
DEC(DECrement)は 1 引く命令で、N フラグが 1 になる以外は INC と同様です。
次に加算命令 ADD です。
命令 | フラグ変化S Z H P N C |
動作 |
---|---|---|
ADD A,r | * * * V 0 * | A←A+r |
ADD A,n | * * * V 0 * | A←A+n |
ADD A,(HL) ADD A,(IX+d) ADD A,(IY+d) |
* * * V 0 * | A←A+(HL) A←A+(IX+d) A←A+(IY+d) |
ADD HL,rr ADD IX,ii ADD IY,ii |
- - ? - 0 * | HL←HL+rr IX←IX+ii IY←IY+ii |
ii は第 1 オペランドが IX なら BC,DE,IX,SP、IY なら BC,DE,IY,SP のいずれかを指します。
8bit 演算ではフラグが一通り変化しますが、16bit 演算ではあまり変化しないことに注意してください。
加算命令には ADC(ADd with Carry flag)という、C フラグも一緒に足す命令もあります。
命令 | フラグ変化S Z H P N C |
動作 |
---|---|---|
ADC A,r | * * * V 0 * | A←A+r+Cflag |
ADC A,n | * * * V 0 * | A←A+n+Cflag |
ADC A,(HL) ADC A,(IX+d) ADC A,(IY+d) |
* * * V 0 * |
A←A+(HL)+Cflag A←A+(IX+d)+Cflag A←A+(IY+d)+Cflag |
ADC HL,rr | * * ? V 0 * | HL←HL+rr+Cflag |
16bit 演算には ADD と違ってインデックスレジスタに関するものはありません。 また、フラグは全て変化します。
ADD、ADC と同様に、減算には SUB(SUBtract)、SBC(SuBtract with Carry flag)命令があります。
命令 | フラグ変化S Z H P N C |
動作 |
---|---|---|
SUB r | * * * V 1 * | A←A-r |
SUB n | * * * V 1 * | A←A-n |
SUB (HL) SUB (IX+d) SUB (IY+d) |
* * * V 1 * | A←A-(HL) A←A-(IX+d) A←A-(IY+d) |
SBC A,r | * * * V 1 * | A←A-r-Cflag |
SBC A,n | * * * V 1 * | A←A-n-Cflag |
SBC A,(HL) SBC A,(IX+d) SBC A,(IY+d) |
* * * V 1 * |
A←A-(HL)-Cflag A←A-(IX+d)-Cflag A←A-(IY+d)-Cflag |
SBC HL,rr | * * ? V 1 * | HL←HL-rr-Cflag |
SUB 命令にオペランドが 1 つしか無いのは、ADD と違って SUB は A
レジスタとの演算しか無く、「A,
」が省略されているためです。つまり
SUB HL,rr
などの 16bit
演算命令はありません。C フラグを 0 にしてから SBC
命令を実行するか、8bit 命令を組み合わせることで代用します。
SUB 命令は A レジスタに結果が残りますが、残らずにフラグ変化だけする CP(ComPare)という命令があります。値の比較のために使用します。
命令 | フラグ変化S Z H P N C |
動作 |
---|---|---|
CP r | * * * V 1 * | A-r |
CP n | * * * V 1 * | A-n |
CP (HL) CP (IX+d) CP (IY+d) |
* * * V 1 * | A-(HL) A-(IX+d) A-(IY+d) |
その他の算術命令には、以下のものがあります。
命令 | フラグ変化S Z H P N C |
動作 |
---|---|---|
CPL | - - 1 - 1 - | A←not A |
NEG | * * * V 1 * | A←0-A |
CPL(ComPLement)命令は A レジスタの全ビットを反転します(1 の補数)。
NEG(Negate)命令は A レジスタの符号を反転します(2
の補数)。ちなみに CPL
→INC A
でも計算結果は同じですが、フラグ変化が違います。
最後にもう一つ、加減算に関する特殊な命令があるので、 ここで解説しておきます。
命令 | clk | 動作 |
---|---|---|
DAA | 4 | A←packed BCD 補正した A |
8bit 加減算命令(のうちフラグが全て変化するもの)の実行直後に DAA(Decimal Adjust Accumulator)命令を実行すると、演算が packed BCD(BCD=Binary Coded Decimal、上位 4bit と下位 4bit で 10 進数 2 桁と見なす)で行われたものとして A レジスタとフラグを補正します。
最初にこの命令を知ったときには「えっ、たった 4clk でそんなことできるの?」と驚きました。うまくできてますね。
論理演算命令には AND、OR、XOR(eXclusive OR)の 3 種類があります(論理演算についての説明は省略します)。 いずれも A レジスタとの演算しか無いため、オペランドは省略して 1 つだけになっています。
命令 | 動作 |
---|---|
AND r | A←A and r |
AND n | A←A and n |
AND (HL) AND (IX+d) AND (IY+d) |
A←A and (HL) A←A and (IX+d) A←A and (IY+d) |
OR、XOR についても同様です。フラグ変化についてですが、
命令 | フラグ変化S Z H P N C |
---|---|
AND | * * 1 P 0 0 |
OR | * * 0 P 0 0 |
XOR | * * 0 P 0 0 |
となっており、いずれも
C フラグが 0 になります。Z80 には他に C
フラグを直接 0 にする命令が無いので、これらの命令が利用されます(ちなみに
2 命令なら SCF
→CCF
という方法はあります)。
特に
AND A
と
OR A
は A レジスタを壊さずに
0 かどうかや正負の判定もできますし、XOR A
は A レジスタを 0 にするためによく使われます。
退避命令は 16bit レジスタの値をスタックに退避/復帰する命令です。 PUSH は退避、POP は復帰です。
命令 | 動作 |
---|---|
PUSH qq PUSH IX PUSH IY |
(SP-1)←qqH, (SP-2)←qqL,SP←SP-2 (SP-1)←IXH, (SP-2)←IXL,SP←SP-2 (SP-1)←IYH, (SP-2)←IYL,SP←SP-2 |
POP qq POP IX POP IY |
qqL←(SP), qqH←(SP+1), SP←SP+2 IXL←(SP), IXH←(SP+1), SP←SP+2 IYL←(SP), IYH←(SP+1), SP←SP+2 |
qq は BC,DE,HL,AF のいずれかです。
いずれもフラグは基本的に変化しませんが、POP AF
は F
レジスタに戻すため、その値がフラグに反映されます。
分岐命令はプログラムの流れを変える命令です。 いずれもフラグは変化しません。
まずは JP(JumP)命令です。
命令 | clk | 動作 |
---|---|---|
JP nn | 10 | PC←nn |
JP cc,nn | 10 | if (cc) PC←nn |
無条件にジャンプするものと、 フラグの状態によってジャンプするかどうかが変わるものがあります。 いずれも実行時間は同じ 10clk です。 cc については以下の通りです。
cc | 成立条件 |
---|---|
NZ | Z=0(Non Zero) |
Z | Z=1(Zero) |
NC | Cflag=0(Non Carry) |
C | Cflag=1(Carry) |
PO | P/V=0(Parity Odd) |
PE | P/V=1(Parity Even) |
P | S=0(Plus) |
M | S=1(Minus) |
直接アドレスを指定する以外に、 レジスタの指すアドレスにジャンプする命令もあります。 オペランドになぜか括弧が付いているのですが、 メモリからアドレスを読み出すわけではないので注意してください。
命令 | clk | 動作 |
---|---|---|
JP (HL) | 4 | PC←HL |
JP (IX) JP (IY) |
8 | PC←IX PC←IY |
次に相対ジャンプ命令です。
命令 | clk | 動作 |
---|---|---|
JR e | 12 | PC←PC+e |
JR cc,e | 12/7 | if (cc) PC←PC+e 分岐時 12clk/非分岐時 7clk |
DJNZ e | 13/8 | B←B-1, if (B≠0) PC←PC+e 分岐時 13clk/非分岐時 8clk |
JR(Jump Relative)命令は、次の命令アドレスを基準にして -80H~+7FH の範囲にジャンプできます。JP と同様にフラグの状態によるジャンプもありますが、cc には NZ,Z,NC,C しか使えません。また、分岐時には JP より遅いことにも注意してください。
DJNZ(Decrement and Jump if Non
Zero)は、DEC B
→JR NZ,e
をまとめたような命令です(ただしフラグは変化しません)。
実行時間も少し短くて、ループ処理に便利です。
次にサブルーチン呼び出しのための命令です。
命令 | clk | 動作 |
---|---|---|
CALL nn | 17 | (SP-1)←PCH, (SP-2)←PCL, SP←SP-2, PC←nn |
CALL cc,nn | 17/10 | if (cc) (SP-1)←PCH, (SP-2)←PCL, SP←SP-2, PC←nn 分岐時 17clk/非分岐時 10clk |
RET | 10 | PCL←(SP), PCH←(SP+1), SP←SP+2 |
RET cc | 11/5 | if (cc) PCL←(SP), PCH←(SP+1), SP←SP+2 分岐時 11clk/非分岐時 5clk |
CALL 命令はスタックに PC を退避してからジャンプし、RET(RETurn)命令はスタックから PC に戻します。いずれも JP 命令と同様に、フラグの状態によるものもあります。
他に RETI、RETN という割り込み処理用の命令もありますが、解説は省略します。
もう一つ、RST(ReSTart)という命令があります。
命令 | clk | 動作 |
---|---|---|
RST p | 11 | (SP-1)←PCH, (SP-2)←PCL, SP←SP-2, PCL←p, PCH←0 |
CALL 命令の一種なのですが、アドレスが「0000H~0038H のうち 8 の倍数」と限定されています。命令が 1Byte で済むので、 頻繁に使用するサブルーチンを配置することでプログラムサイズを節約できます (もちろん、そのあたりに配置できるなら、ですが)。
ローテート/シフト命令は、 レジスタやメモリの値をビット単位でずらす命令です。 ずらし方によっていろいろな命令があります。
命令 | 動作 |
---|---|
RLC r | Cflag←r7..0←r7 |
RLC (HL) RLC (IX+d) RLC (IY+d) |
Cflag←(HL)7..0←(HL)7 Cflag←(IX+d)7..0←(IX+d)7 Cflag←(IY+d)7..0←(IY+d)7 |
RRC r | r0→r7..0→Cflag |
RRC (HL) RRC (IX+d) RRC (IY+d) |
(HL)0→(HL)7..0→Cflag (IX+d)0→(IX+d)7..0→Cflag (IY+d)0→(IY+d)7..0→Cflag |
ちょっと動作がわかりにくいかもしれませんが、RLC(Rotate Left Circular)命令と RRC(Rotate Right Circular)命令は、8bit 値をグルッと回した上で、飛び出たビットを C フラグに反映させます。
命令 | 動作 |
---|---|
RL r | Cflag←r7..0←Cflag |
RL (HL) RL (IX+d) RL (IY+d) |
Cflag←(HL)7..0←Cflag Cflag←(IX+d)7..0←Cflag Cflag←(IY+d)7..0←Cflag |
RR r | Cflag→r7..0→Cflag |
RR (HL) RR (IX+d) RR (IY+d) |
Cflag→(HL)7..0→Cflag Cflag→(IX+d)7..0→Cflag Cflag→(IY+d)7..0→Cflag |
一方、RL(Rotate Left)命令と RR(Rotate Right)命令は、C フラグも含めてグルッと回します (今でもどっちがどっちだったか迷うことがあります)。
これらの命令には、A レジスタ専用命令もあります。
命令 | 動作 |
---|---|
RLCA | Cflag←A7..0←A7 |
RRCA | A0→A7..0→Cflag |
RLA | Cflag←A7..0←Cflag |
RRA | Cflag→A7..0→Cflag |
こちらは「A」の前にスペースが入らないことに注意してください。 1Byte 命令で 4clk と速いですが、フラグ変化が違います(Z,S,P/V フラグは変化しません)。
次にシフト命令です。3 種類あります。
命令 | 動作 |
---|---|
SLA r | Cflag←r7..0←0 |
SLA (HL) SLA (IX+d) SLA (IY+d) |
Cflag←(HL)7..0←0 Cflag←(IX+d)7..0←0 Cflag←(IY+d)7..0←0 |
SRA r | r7..0→Cflag |
SRA (HL) SRA (IX+d) SRA (IY+d) |
(HL)7..0→Cflag (IX+d)7..0→Cflag (IY+d)7..0→Cflag |
SRL r | 0→r7..0→Cflag |
SRL (HL) SRL (IX+d) SRL (IY+d) |
0→(HL)7..0→Cflag 0→(IX+d)7..0→Cflag 0→(IY+d)7..0→Cflag |
SLA(Shift Left Arithmetical)と SRA(Shift Right Arithmetical)は「算術シフト」と言い、符号付きの値を 2 倍もしくは 1/2 にします(したがって SRA では bit7 は変化しません)。
一方 SRL(Shift Right Logical)は「論理シフト」と言い、符号無しの値を 1/2 にします。 こちらに左シフトが用意されていないのは、 算術シフトと結果が同じになるからです。
他に、ちょっと変わったローテート命令があります。
命令 | 動作 |
---|---|
RLD | A3..0←(HL)7..4←(HL)3..0←A3..0 |
RRD | A3..0→(HL)7..4→(HL)3..0→A3..0 |
RLD(Rotate Left Decimal)命令と RRD(Rotate Right Decimal)命令は、A レジスタの下位 4bit と HL が指すメモリを、1bit ではなく 4bit 単位で回します。Decimal は packed BCD のことを指し、ようするに 10 進数 1 桁ずらすための命令です。
レジスタやメモリの 8bit のうち 1bit だけを対象にした命令があります。
命令 | 動作 |
---|---|
RES b,r | rb←0 |
RES b,(HL) RES b,(IX+d) RES b,(IY+d) |
(HL)b←0 (IX+d)b←0 (IY+d)b←0 |
SET b,r | rb←1 |
SET b,(HL) SET b,(IX+d) SET b,(IY+d) |
(HL)b←1 (IX+d)b←1 (IY+d)b←1 |
b はビット位置(0~7、最下位が 0)です。RES(RESet)は 0 に、SET は 1 にします。いずれもフラグは変化しません。
命令 | 動作 |
---|---|
BIT b,r | Z←not rb |
BIT b,(HL) BIT b,(IX+d) BIT b,(IY+d) |
Z←not (HL)b Z←not (IX+d)b Z←not (IY+d)b |
BIT 命令はビットの状態を Z フラグに反映させます。Z フラグは結果が 0 のときに立つ(1 になる)ので、ビットの値とは逆になることに注意してください。
データをまとめて転送したいときに便利なのがブロック転送命令です。 LDIR(Load and Increment Repeat)命令と LDDR(Load and Decrement Repeat)命令があります。
命令 | 動作 |
---|---|
LDIR | (DE)←(HL), DE←DE+1, HL←HL+1, BC←BC-1, BC=0 になるまで繰り返し |
LDDR | (DE)←(HL), DE←DE-1, HL←HL-1, BC←BC-1, BC=0 になるまで繰り返し |
HL が指すアドレスから DE が指すアドレスに BC バイト転送します。 HL と DE には、LDIR ではデータの先頭、LDDR ではデータの末尾を指定しておきます。
それぞれに、1Byte だけ転送する命令もあります。
命令 | 動作 |
---|---|
LDI | (DE)←(HL), DE←DE+1, HL←HL+1, BC←BC-1 |
LDD | (DE)←(HL), DE←DE-1, HL←HL-1, BC←BC-1 |
これらの命令では、BC レジスタが 0 になったかどうかが P/V フラグに反映されます。BC=0 で P/V=0、他は P/V=1 になります。
ブロック転送命令と似たものに、ブロックサーチ命令があります。 こちらはデータから特定の 8bit 値を探すために使われます。 CPIR(Compare and Increment Repeat)命令と CPDR(Compare and Decrement Repeat)命令、それとそれぞれの 1Byte 版があります。
命令 | 動作 |
---|---|
CPIR | A-(HL), HL←HL+1, BC←BC-1, A=(HL) か BC=0 になるまで繰り返し |
CPDR | A-(HL), HL←HL-1, BC←BC-1, A=(HL) か BC=0 になるまで繰り返し |
CPI | A-(HL), HL←HL+1, BC←BC-1 |
CPD | A-(HL), HL←HL-1, BC←BC-1 |
CPIR と CPDR は A レジスタと HL が指すデータを比較していき、一致するか BC バイト比較したら終了します。HL には、CPIR ではデータの先頭、CPDR ではデータの末尾を指定しておきます。
いずれの命令も、一致したかどうかは Z フラグで判定できます。 また、BC=0 で P/V=0、他は P/V=1 になります。
Z80 にはメモリ空間とは別に、アドレス 8bit/データ 8bit の I/O 空間というものがあり、専用命令でアクセスします。
命令 | 動作 |
---|---|
IN A,(n) | A←I/O port(n) |
IN r,(C) | r←I/O port(C) |
OUT (n),A | I/O port(n)←A |
OUT (C),r | I/O port(C)←r |
また、ブロック転送命令と同様に I/O 空間に繰り返しアクセスする命令がありますが、詳しい解説は省略します。
命令 | 動作 |
---|---|
INIR | (HL)←I/O port(C), B←B-1, HL←HL+1, B=0 になるまで繰り返し |
INDR | (HL)←I/O port(C), B←B-1, HL←HL-1, B=0 になるまで繰り返し |
INI | (HL)←I/O port(C), B←B-1, HL←HL+1 |
IND | (HL)←I/O port(C), B←B-1, HL←HL-1 |
OTIR | B←B-1, I/O port(C)←(HL), HL←HL+1, B=0 になるまで繰り返し |
OTDR | B←B-1, I/O port(C)←(HL), HL←HL-1, B=0 になるまで繰り返し |
OTI | B←B-1, I/O port(C)←(HL), HL←HL+1 |
OTD | B←B-1, I/O port(C)←(HL), HL←HL-1 |
命令 | 動作 |
---|---|
SCF | Cflag←1 |
CCF | Cflag←not Cflag |
C フラグを操作する命令です。SCF(Set Carry Flag)は 1 にし、CCF(Complement Carry Flag)は 0/1 を反転します。直接 0 にする方法は「論理演算命令」を参照してください。
命令 | clk | 動作 |
---|---|---|
NOP | 4 | 何もしない |
NOP(No OPeration)命令は何もしません。何もしないとは言っても 4clk かかるので、少し待ちたいとき(I/O ポートへの出力など)に使われたりします。 ちなみに命令コードは 00H ですが、たいていの CPU では 00H 以外に割り当てられています。
命令 | 動作 |
---|---|
DI | IFF1←0, IFF2←0(割り込み禁止) |
EI | IFF1←1, IFF2←1(割り込み許可) |
IM m | 割り込みモード←m |
HALT | 実行停止(割り込み/リセット待ち) |
DI(Disable Interrupt)は割り込み禁止、EI(Enable Interrupt)は割り込み許可状態にします。
IM(Interrupt Mode)命令は割り込みモード(0~2) を切り替えます。詳しいことは省略します。
HALT 命令は割り込みかリセットがかかるまで停止します(実際には NOP を実行し続けます)。
Z80 は命令セットや挙動に偏りが多いため、 さまざまな高速化の余地があります。ここからは主に高速化のテクニックを、 プログラムサイズについても気にしながら紹介していきます。
なお、高速化には各命令の clk 数を知っておく必要がありますが、 メモリアクセスは 1Byte につき 3clk ということを知っていると、多少は覚えやすくなると思います (ちなみに命令の読み込みもメモリアクセスです)。
あと、参考リンクをいくつか挙げておきます。
レジスタの値が 0 かどうかを調べたいことはよくあります。「0 なら Z フラグを立てる(1 にする)」方法をいくつか紹介します。
まず A レジスタなら CP 0
が思い付くかもしれませんが、これは 2Byte 7clk です。
しかし
AND A/OR A
なら
1Byte 4clk で済みます。
その他の 8bit レジスタの場合、たとえば B レジスタなら、
LD A,B AND A ; または OR A
で調べられます。これは A レジスタや C フラグを壊してしまいますが、
INC B DEC B
なら壊さずに済みます。 どちらも 2Byte 8clk です。
16bit レジスタの場合は BC/DE/HL に限定されますが、たとえば BC レジスタなら、
LD A,B OR C
で調べられます。ちなみに 16bit レジスタの INC/DEC ではフラグが変化しないので注意してください。
AND/OR/XOR いずれかで 0
になります。AND A/OR A/XOR A
を使用することが多いでしょう。
もし Z フラグや S フラグを変化させたくないのであれば、2 命令になってしまいますが、
SCF CCF
という方法があります。
LD A,0
は 2Byte 7clk ですが、XOR A
や SUB A
なら 1Byte 4clk
です。
ただし LD A,0
がフラグ変化しないのに対して、XOR A
も SUB A
も全てのフラグが変化します。特に C フラグは
0 になります。状況に応じて使い分けましょう。
絶対アドレス指定の JP は全て 10clk です。条件付きの分岐時/非分岐時も全て同じです。
JP と比べると、相対アドレス指定の JR は分岐時は遅く、非分岐時は速いです。表にすると、
命令 | 分岐時 clk | 非分岐時 clk | 命令バイト数 |
---|---|---|---|
JP nn |
10 | 10 | 3 |
JR e |
12 | 7 | 2 |
となります。 一長一短あるので、状況に応じて使い分けましょう。
A レジスタの符号反転は NEG
でできますが、16bit レジスタの場合は、
XOR A SUB C LD C,A SBC A,A SUB B LD B,A
と 0 から引くことで符号反転できます。 6Byte 24clk です。
そして条件がかなり限定されますが、
XOR A LD H,A LD L,A SBC HL,BC
なら 5Byte 27clk になります。
HL レジスタに関する加減算命令ですが、ADD HL,rr
は 11clk、ADC HL,rr
と SBC HL,rr
は
15clk です。つまり定数を引くだけなら、SBC
で引くよりも、符号を逆にした値を ADD で足すほうが速く、先に C
フラグをクリアしておく必要も無くなります。
ただし計算後のフラグ変化が異なることには注意してください。
ブロック転送命令 LDIR/LDDR は最後の 1Byte 以外は 21clk で最後だけ 16clk です。
しかし 1Byte だけ転送する LDI/LDD は 16clk です。つまり LDI/LDD を並べると、1Byte につき 5clk ずつ節約できます。
もちろんプログラムサイズが増えるので、 ある程度並べてループするのがいいでしょう。
広い範囲を 0 クリアしたいなど、メモリを同じ値で埋めたいときは、
LD HL,START LD DE,START+1 LD BC,SIZE-1 LD (HL),0 LDIR
などと LDIR を使用するのが簡単です。 プログラムサイズも小さいので、 よほどの速度が要求されない限りはこれでいいでしょう。 転送サイズは 1 引くのを忘れずに。
先ほどの方法とは違って条件付きになりますが、
DI LD (SP_TMP),SP LD SP,START+SIZE LD DE,0 PUSH DE PUSH DE PUSH DE : LD SP,(SP_TMP) EI
などと PUSH を並べる方法があります。仮に
LD (HL),A
と INC HL
を並べても 1Byte
につき 13clk ですが、PUSH は 2Byte につき
11clk(IX/IY は 15clk)と、かなり速いです。
しかしこの方法は SP レジスタを使うため、処理中に割り込みがかかると破綻します。 そのため DI 命令で通常の割り込みを禁止にしていますが、それでも NMI(Non Maskable Interrupt)が発生する可能性がある場合には使えません。
ちなみに類似の技として、POP をメモリ読み込みに使用するというものがあります。POP は 2Byte につき 10clk(IX/IY は 14clk)と高速です。割り込みがかかると破綻するのも同様です。
プログラムを書き換える技です。たとえばこんな処理があるとします。
COUNTUP: LD A,(COUNT) INC A LD (COUNT),A RET COUNT: DS 1 ; 1Byteの領域を確保
この処理は次のように置き換えることができます。
COUNTUP: LD A,0 ; 3E 00 INC A LD (COUNTUP+1),A RET
こうするとワークエリアやプログラムサイズが節約できる上に、 少し速くなります。
欠点はプログラムが読みにくくなることと、ROM 上にプログラムがある場合は使えないことです。 使いどころには気を付けましょう。
他にはたとえばこんな技もあります。
LD (ADD_IX_A+2),A ADD_IX_A: LD (IX+0),1 ; DD 36 00 01
これで
LD (IX+A),1
に相当する処理(A
は符号付きと見なす)が、他のレジスタを使わずにできます。
たとえば、
OR A JR NZ,L1 LD A,12H JR L2 L1: LD A,34H L2:
これは「A レジスタが 0 なら 12H、それ以外なら 34H に変える」という処理で 9Byte ですが、もし BC レジスタを壊していいなら、
OR A JR NZ,L1+1 LD A,12H L1: LD BC,343EH ; 3E 34 LD A,34H
と書けて 8Byte に減っています。
処理速度も遅くはなっていません(前者の JR L2
を
JP L2
に変えても同じクロック数)。
いろんなバリエーションがあるのですが、いずれも非常に見づらく、逆アセンブルするとますます見づらい
(分岐先アドレスが中途半端な上に、上記の例での LD A,34H
が出てこないため)という大きな欠点があります。
よほどのことが無い限り、使うのはおすすめしません。
ループ回数が 16bit の場合、
; BC=ループ回数 L1: : DEC BC LD A,B ; Aレジスタを破壊 OR C ; Cフラグも破壊 JR NZ,L1 RET
でループできますが、これだと A レジスタを破壊するだけでなく、壊したくないこともある C フラグまで破壊されてしまいます。もし仮に、
L1: : DEC C JR NZ,L1 DEC B JR NZ,L1
のように書けるなら、どちらも破壊せずに済む上に、 速度も(ループ回数が多い場合は)速くなります。しかしこれでは、たとえば BC=1 のときには DEC B で 0FFH になり、またループしてしまいます。
そこで前処理で「C レジスタが 0 でなければ B レジスタに 1 足す」としておくと、 正しい回数ループできるようになります。さらに B レジスタなら DJNZ が使えるので、内側のループで使用できるように B レジスタと C レジスタを入れ替えておきます。
; BC=ループ回数 LD A,C OR A JR Z,L1 INC B L1: LD C,B LD B,A L2: : DJNZ L2 DEC C JR NZ,L2
または次のようにも書けます。
; BC=ループ回数 DEC BC INC C INC B LD A,C LD C,B LD B,A L1: : DJNZ L1 DEC C JR NZ,L1
こちらのほうが速くてプログラムサイズも小さく、C
フラグは変化しません。前者は C フラグが(OR A
で)0
になるので、場合によってはそちらを使う選択肢もあります。
以上、ちょっとややこしいですが、これで A レジスタや C フラグを壊さずに、かつ高速にループすることができます。
オペランド
r
: 8bit レジスタ(B,C,D,E,H,L,A)r'
: 同上n
: 8bit 値nn
: 16bit 値d
: 符号付き 8bit 値b
: ビット位置(0~7)e
: 符号付き 8bit PC
相対(次の命令アドレスが基準)rr
: 16bit レジスタ(BC,DE,HL,SP)qq
: 16bit レジスタ(BC,DE,HL,AF)ii
: 16bit レジスタ(BC,DE,IX/IY,SP)xx
: インデックスレジスタ(IX,IY)cc
: フラグの状態(NZ,Z,NC,C,PO,PE,P,M)p
: RST アドレス(00H~38H のうち 8 の倍数)フラグ変化
-
: 変化しない0
: 0(リセット)1
: 1(セット)*
: 実行結果により変化P
: P/V フラグがパリティとして変化V
: P/V フラグがオーバーフローとして変化?
: 不定(もしくは意味の無い値)コード内表記
rrr, r'r'r'
: B=0, C=1, D=2, E=3, H=4, L=5, A=7rr
: BC=0, DE=1, HL=2, SP=3qq
: BC=0, DE=1, HL=2, AF=3ii
: BC=0, DE=1, IX/IY=2, SP=3x
: IX=0, IY=1cc
: NZ=0, Z=1, NC=2, C=3ccc
: NZ=0, Z=1, NC=2, C=3, PO=4, PE=5, P=6, M=7ppp
: 00H=0, 08H=1, 10H=2, 18H=3, 20H=4, 28H=5, 30H=6,
38H=7命令 | clk | フラグ変化S Z H P N C |
動作 | コード |
---|---|---|---|---|
ADC A,r | 4 | * * * V 0 * | A←A+r+Cflag | 10001rrr |
ADC A,n | 7 | * * * V 0 * | A←A+n+Cflag | 11001110 n |
ADC A,(HL) | 7 | * * * V 0 * | A←A+(HL)+Cflag | 10001110 |
ADC A,(xx+d) | 19 | * * * V 0 * | A←A+(xx+d)+Cflag | 11x11101 10001110 d |
ADC HL,rr | 15 | * * ? V 0 * | HL←HL+rr+Cflag | 11101101 01rr1010 |
ADD A,r | 4 | * * * V 0 * | A←A+r | 10000rrr |
ADD A,n | 7 | * * * V 0 * | A←A+n | 11000110 n |
ADD A,(HL) | 7 | * * * V 0 * | A←A+(HL) | 10000110 |
ADD A,(xx+d) | 19 | * * * V 0 * | A←A+(xx+d) | 11x11101 10000110 d |
ADD HL,rr | 11 | - - ? - 0 * | HL←HL+rr | 00rr1001 |
ADD xx,ii | 15 | - - ? - 0 * | xx←xx+ii | 11x11101 00ii1001 |
AND r | 4 | * * 1 P 0 0 | A←A and r | 10100rrr |
AND n | 7 | * * 1 P 0 0 | A←A and n | 11100110 n |
AND (HL) | 7 | * * 1 P 0 0 | A←A and (HL) | 10100110 |
AND (xx+d) | 19 | * * 1 P 0 0 | A←A and (xx+d) | 11x11101 10100110 d |
BIT b,r | 8 | ? * 1 ? 0 - | Z←not rb | 11001011 01bbbrrr |
BIT b,(HL) | 12 | ? * 1 ? 0 - | Z←not (HL)b | 11001011 01bbb110 |
BIT b,(xx+d) | 20 | ? * 1 ? 0 - | Z←not (xx+d)b | 11x11101 11001011 d 01bbb110 |
CALL nn | 17 | - - - - - - | (SP-1)←PCH, (SP-2)←PCL, SP←SP-2, PC←nn |
11001101 nnL nnH |
CALL cc,nn | 17/10 ※ |
- - - - - - | if (cc)
(SP-1)←PCH, (SP-2)←PCL, SP←SP-2, PC←nn ※分岐時 17clk/非分岐時 10clk |
11ccc100 nnL nnH |
CCF | 4 | - - ? - 0 * | Cflag←not Cflag | 00111111 |
CP r | 4 | * * * V 1 * | A-r | 10111rrr |
CP n | 7 | * * * V 1 * | A-n | 11111110 n |
CP (HL) | 7 | * * * V 1 * | A-(HL) | 10111110 |
CP (xx+d) | 19 | * * * V 1 * | A-(xx+d) | 11x11101 10111110 d |
CPD | 16 | * * * * 1 - ※ |
A-(HL), HL←HL-1, BC←BC-1 ※BC=0 で P/V←0/他は 1 |
11101101 10101001 |
CPDR | 21/16 ※1 |
* * * * 1 - ※2 |
A-(HL), HL←HL-1, BC←BC-1, A=(HL) か BC=0 になるまで繰り返し ※1 終了時 16clk/他は 21clk ※2 BC=0 で P/V←0/他は 1 |
11101101 10111001 |
CPI | 16 | * * * * 1 - ※ |
A-(HL), HL←HL+1, BC←BC-1 ※BC=0 で P/V←0/他は 1 |
11101101 10100001 |
CPIR | 21/16 ※1 |
* * * * 1 - ※2 |
A-(HL), HL←HL+1, BC←BC-1, A=(HL) か BC=0 になるまで繰り返し ※1 終了時 16clk/他は 21clk ※2 BC=0 で P/V←0/他は 1 |
11101101 10110001 |
CPL | 4 | - - 1 - 1 - | A←not A | 00101111 |
DAA | 4 | * * * P - * | A←packed BCD 補正した A | 00100111 |
DEC r | 4 | * * * V 1 - | r←r-1 | 00rrr101 |
DEC (HL) | 11 | * * * V 1 - | (HL)←(HL)-1 | 00110101 |
DEC (xx+d) | 23 | * * * V 1 - | (xx+d)←(xx+d)-1 | 11x11101 00110101 d |
DEC rr | 6 | - - - - - - | rr←rr-1 | 00rr1011 |
DEC xx | 10 | - - - - - - | xx←xx-1 | 11x11101 00101011 |
DI | 4 | - - - - - - | IFF1←0, IFF2←0(割り込み禁止) | 11110011 |
DJNZ e | 13/8 ※ |
- - - - - - | B←B-1, if (B≠0) PC←PC+e ※分岐時 13clk/非分岐時 8clk |
00010000 e |
EI | 4 | - - - - - - | IFF1←1, IFF2←1(割り込み許可) | 11111011 |
EX AF,AF' | 4 | - - - - - - ※ |
AF←→AF' ※交換後の F がフラグに反映 |
00001000 |
EX DE,HL | 4 | - - - - - - | DE←→HL | 11101011 |
EXX | 4 | - - - - - - | BC←→BC', DE←→DE', HL←→HL' | 11011001 |
EX (SP),HL | 19 | - - - - - - | (SP)←→L, (SP+1)←→H | 11100011 |
EX (SP),xx | 23 | - - - - - - | (SP)←→xxL, (SP+1)←→xxH | 11x11101 11100011 |
HALT | 4 | - - - - - - | 実行停止(割り込み/リセット待ち) | 01110110 |
IM 0 IM 1 IM 2 |
8 | - - - - - - | 割り込みモード←0 割り込みモード←1 割り込みモード←2 |
11101101 01000110 11101101 01010110 11101101 01011110 |
IN A,(n) |
11 | - - - - - - | A←I/O port(n) | 11011011 n |
IN r,(C) |
12 | * * 0 P 0 - | r←I/O port(C) | 11101101 01rrr000 |
INC r | 4 | * * * V 0 - | r←r+1 | 00rrr100 |
INC (HL) | 11 | * * * V 0 - | (HL)←(HL)+1 | 00110100 |
INC (xx+d) | 23 | * * * V 0 - | (xx+d)←(xx+d)+1 | 11x11101 00110100 d |
INC rr | 6 | - - - - - - | rr←rr+1 | 00rr0011 |
INC xx | 10 | - - - - - - | xx←xx+1 | 11x11101 00100011 |
IND |
16 | ? * ? ? ? ? ※ |
(HL)←I/O port(C), B←B-1, HL←HL-1 ※B=0 で Z←1/他は 0 |
11101101 10101010 |
INDR |
21/16 ※ |
? 1 ? ? ? ? | (HL)←I/O port(C), B←B-1, HL←HL-1, B=0 になるまで繰り返し ※終了時 16clk/他は 21clk |
11101101 10111010 |
INI |
16 | ? * ? ? ? ? ※ |
(HL)←I/O port(C), B←B-1, HL←HL+1 ※B=0 で Z←1/他は 0 |
11101101 10100010 |
INIR |
21/16 ※ |
? 1 ? ? ? ? | (HL)←I/O port(C), B←B-1, HL←HL+1, B=0 になるまで繰り返し ※終了時 16clk/他は 21clk |
11101101 10110010 |
JP nn | 10 | - - - - - - | PC←nn | 11000011 nnL nnH |
JP cc,nn | 10 | - - - - - - | if (cc) PC←nn | 11ccc010 nnL nnH |
JP (HL) | 4 | - - - - - - | PC←HL | 11101001 |
JP (xx) | 8 | - - - - - - | PC←xx | 11x11101 11101001 |
JR e | 10 | - - - - - - | PC←PC+e | 00011000 e |
JR cc,e | 12/7 ※ |
- - - - - - | if (cc) PC←PC+e ※分岐時 12clk/非分岐時 7clk |
001cc000 e |
LD r,r' | 4 | - - - - - - | r←r' | 01rrrr'r'r' |
LD r,n | 7 | - - - - - - | r←n | 00rrr110 n |
LD A,(BC) LD A,(DE) |
7 | - - - - - - | A←(BC) A←(DE) |
00001010 00011010 |
LD A,(nn) | 13 | - - - - - - | A←(nn) | 00111010 nnL nnH |
LD r,(HL) | 7 | - - - - - - | r←(HL) | 01rrr110 |
LD r,(xx+d) | 19 | - - - - - - | r←(xx+d) | 11x11101 01rrr110 d |
LD (BC),A LD (DE),A |
7 | - - - - - - | (BC)←A (DE)←A |
00000010 00010010 |
LD (nn),A | 13 | - - - - - - | (nn)←A | 00110010 nnL nnH |
LD (HL),r | 7 | - - - - - - | (HL)←r | 01110rrr |
LD (xx+d),r | 19 | - - - - - - | (xx+d)←r | 11x11101 01110rrr d |
LD (HL),n | 10 | - - - - - - | (HL)←n | 00110110 n |
LD (xx+d),n | 19 | - - - - - - | (xx+d)←n | 11x11101 00110110 d n |
LD A,I | 9 | * * 0 * 0 - | A←I, P/V←IFF2 | 11101101 01010111 |
LD I,A | 9 | - - - - - - | I←A | 11101101 01000111 |
LD A,R | 9 | * * 0 * 0 - | A←R, P/V←IFF2 | 11101101 01011111 |
LD R,A | 9 | - - - - - - | R←A | 11101101 01001111 |
LD rr,nn | 10 | - - - - - - | rr←nn | 00rr0001 nnL nnH |
LD xx,nn | 14 | - - - - - - | xx←nn | 11x11101 00100001 nnL nnH |
LD HL,(nn) | 16 | - - - - - - | L←(nn), H←(nn+1) | 00101010 nnL nnH |
LD xx,(nn) | 20 | - - - - - - | xxL←(nn), xxH←(nn+1) | 11x11101 00101010 nnL nnH |
LD BC,(nn) LD DE,(nn) LD SP,(nn) |
20 | - - - - - - |
C←(nn), B←(nn+1) E←(nn), D←(nn+1) SPL←(nn), SPH←(nn+1) |
11101101 01001011 nnL nnH 11101101 01011011 nnL nnH 11101101 01111011 nnL nnH |
LD (nn),HL | 16 | - - - - - - | (nn)←L, (nn+1)←H | 00100010 nnL nnH |
LD (nn),xx | 20 | - - - - - - | (nn)←xxL, (nn+1)←xxH | 11x11101 00100010 nnL nnH |
LD (nn),BC LD (nn),DE LD (nn),SP |
20 | - - - - - - |
(nn)←C, (nn+1)←B (nn)←E, (nn+1)←D (nn)←SPL, (nn+1)←SPH |
11101101 01000011 nnL nnH 11101101 01010011 nnL nnH 11101101 01110011 nnL nnH |
LD SP,HL | 6 | - - - - - - | SP←HL | 11111001 |
LD SP,xx | 10 | - - - - - - | SP←xx | 11x11101 11111001 |
LDD | 16 | - - 0 * 0 - ※ |
(DE)←(HL), DE←DE-1, HL←HL-1, BC←BC-1 ※BC=0 で P/V←0/他は 1 |
11101101 10101000 |
LDDR | 21/16 ※ |
- - 0 0 0 - | (DE)←(HL), DE←DE-1, HL←HL-1, BC←BC-1, BC=0 になるまで繰り返し ※終了時 16clk/他は 21clk |
11101101 10111000 |
LDI | 16 | - - 0 * 0 - ※ |
(DE)←(HL), DE←DE+1, HL←HL+1, BC←BC-1 ※BC=0 で P/V←0/他は 1 |
11101101 10100000 |
LDIR | 21/16 ※ |
- - 0 0 0 - | (DE)←(HL), DE←DE+1, HL←HL+1, BC←BC-1, BC=0 になるまで繰り返し ※終了時 16clk/他は 21clk |
11101101 10110000 |
NEG | 8 | * * * V 1 * | A←0-A | 11101101 01000100 |
NOP | 4 | - - - - - - | 何もしない | 00000000 |
OR r | 4 | * * 0 P 0 0 | A←A or r | 10110rrr |
OR n | 7 | * * 0 P 0 0 | A←A or n | 11110110 n |
OR (HL) | 7 | * * 0 P 0 0 | A←A or (HL) | 10110110 |
OR (xx+d) | 19 | * * 0 P 0 0 | A←A or (xx+d) | 11x11101 10110110 d |
OTDR |
21/16 ※ |
? 1 ? ? ? ? | B←B-1, I/O port(C)←(HL), HL←HL-1 B=0 になるまで繰り返し ※終了時 16clk/他は 21clk |
11101101 10111011 |
OTIR |
21/16 ※ |
? 1 ? ? ? ? | B←B-1, I/O port(C)←(HL), HL←HL+1 B=0 になるまで繰り返し ※終了時 16clk/他は 21clk |
11101101 10110011 |
OUT (n),A |
11 | - - - - - - | I/O port(n)←A | 11010011 n |
OUT (C),r |
12 | - - - - - - | I/O port(C)←r | 11101101 01rrr001 |
OUTD |
16 | ? * ? ? ? ? ※ |
B←B-1, I/O port(C)←(HL), HL←HL-1 ※B=0 で Z←1/他は 0 |
11101101 10101011 |
OUTI |
16 | ? * ? ? ? ? ※ |
B←B-1, I/O port(C)←(HL), HL←HL+1 ※B=0 で Z←1/他は 0 |
11101101 10100011 |
POP qq | 10 | - - - - - - ※ |
qqL←(SP), qqH←(SP+1), SP←SP+2 ※POP AF は F がフラグに反映 |
11qq0001 |
POP xx | 14 | - - - - - - | xxL←(SP), xxH←(SP+1), SP←SP+2 | 11x11101 11100001 |
PUSH qq | 11 | - - - - - - | (SP-1)←qqH, (SP-2)←qqL, SP←SP-2 | 11qq0101 |
PUSH xx | 15 | - - - - - - | (SP-1)←xxH, (SP-2)←xxL, SP←SP-2 | 11x11101 11100101 |
RES b,r | 8 | - - - - - - | rb←0 | 11001011 10bbbrrr |
RES b,(HL) | 15 | - - - - - - | (HL)b←0 | 11001011 10bbb110 |
RES b,(xx+d) | 23 | - - - - - - | (xx+d)b←0 | 11x11101 11001011 d 10bbb110 |
RET | 10 | - - - - - - | PCL←(SP), PCH←(SP+1), SP←SP+2 | 11001001 |
RET cc | 11/5 ※ |
- - - - - - | if (cc) PCL←(SP), PCH←(SP+1), SP←SP+2 分岐時 11clk/非分岐時 5clk |
11ccc000 |
RETI | 14 | - - - - - - | PCL←(SP), PCH←(SP+1), SP←SP+2 割り込み処理からのリターン |
11101101 01001101 |
RETN | 14 | - - - - - - | PCL←(SP), PCH←(SP+1), SP←SP+2, IFF1←IFF2 NMI 処理からのリターン |
11101101 01000101 |
RL r | 8 | * * 0 P 0 * | Cflag←r7..0←Cflag | 11001011 00010rrr |
RL (HL) | 15 | * * 0 P 0 * | Cflag←(HL)7..0←Cflag | 11001011 00010110 |
RL (xx+d) | 23 | * * 0 P 0 * | Cflag←(xx+d)7..0←Cflag | 11x11101 11001011 d 00010110 |
RLA | 4 | - - 0 - 0 * | Cflag←A7..0←Cflag | 00010111 |
RLC r | 8 | * * 0 P 0 * | Cflag←r7..0←r7 | 11001011 00000rrr |
RLC (HL) | 15 | * * 0 P 0 * | Cflag←(HL)7..0←(HL)7 | 11001011 00000110 |
RLC (xx+d) | 23 | * * 0 P 0 * | Cflag←(xx+d)7..0←(xx+d)7 | 11x11101 11001011 d 00000110 |
RLCA | 4 | - - 0 - 0 * | Cflag←A7..0←A7 | 00000111 |
RLD | 18 | * * 0 P 0 - | A3..0←(HL)7..4←(HL)3..0←A3..0 | 11101101 01101111 |
RR r | 8 | * * 0 P 0 * | Cflag→r7..0→Cflag | 11001011 00011rrr |
RR (HL) | 15 | * * 0 P 0 * | Cflag→(HL)7..0→Cflag | 11001011 00011110 |
RR (xx+d) | 23 | * * 0 P 0 * | Cflag→(xx+d)7..0→Cflag | 11x11101 11001011 d 00011110 |
RRA | 4 | - - 0 - 0 * | Cflag→A7..0→Cflag | 00011111 |
RRC r | 8 | * * 0 P 0 * | r0→r7..0→Cflag | 11001011 00001rrr |
RRC (HL) | 15 | * * 0 P 0 * | (HL)0→(HL)7..0→Cflag | 11001011 00001110 |
RRC (xx+d) | 23 | * * 0 P 0 * | (xx+d)0→(xx+d)7..0→Cflag | 11x11101 11001011 d 00001110 |
RRCA | 4 | - - 0 - 0 * | A0→A7..0→Cflag | 00001111 |
RRD | 18 | * * 0 P 0 - | A3..0→(HL)7..4→(HL)3..0→A3..0 | 11101101 01100111 |
RST p | 11 | - - - - - - | (SP-1)←PCH, (SP-2)←PCL, SP←SP-2, PCL←p, PCH←0 |
11ppp111 |
SBC A,r | 4 | * * * V 1 * | A←A-r-Cflag | 10011rrr |
SBC A,n | 7 | * * * V 1 * | A←A-n-Cflag | 11011110 n |
SBC A,(HL) | 7 | * * * V 1 * | A←A-(HL)-Cflag | 10011110 |
SBC A,(xx+d) | 19 | * * * V 1 * | A←A-(xx+d)-Cflag | 11x11101 10011110 d |
SBC HL,rr | 15 | * * ? V 1 * | HL←HL-rr-Cflag | 11101101 01rr0010 |
SCF | 4 | - - 0 - 0 1 | Cflag←1 | 00110111 |
SET b,r | 8 | - - - - - - | rb←1 | 11001011 11bbbrrr |
SET b,(HL) | 15 | - - - - - - | (HL)b←1 | 11001011 11bbb110 |
SET b,(xx+d) | 23 | - - - - - - | (xx+d)b←1 | 11x11101 11001011 d 11bbb110 |
SLA r | 8 | * * 0 P 0 * | Cflag←r7..0←0 | 11001011 00100rrr |
SLA (HL) | 15 | * * 0 P 0 * | Cflag←(HL)7..0←0 | 11001011 00100110 |
SLA (xx+d) | 23 | * * 0 P 0 * | Cflag←(xx+d)7..0←0 | 11x11101 11001011 d 00100110 |
SRA r | 8 | * * 0 P 0 * | r7..0→Cflag | 11001011 00101rrr |
SRA (HL) | 15 | * * 0 P 0 * | (HL)7..0→Cflag | 11001011 00101110 |
SRA (xx+d) | 23 | * * 0 P 0 * | (xx+d)7..0→Cflag | 11x11101 11001011 d 00101110 |
SRL r | 8 | * * 0 P 0 * | 0→r7..0→Cflag | 11001011 00111rrr |
SRL (HL) | 15 | * * 0 P 0 * | 0→(HL)7..0→Cflag | 11001011 00111110 |
SRL (xx+d) | 23 | * * 0 P 0 * | 0→(xx+d)7..0→Cflag | 11x11101 11001011 d 00111110 |
SUB r | 4 | * * * V 1 * | A←A-r | 10010rrr |
SUB n | 7 | * * * V 1 * | A←A-n | 11010110 n |
SUB (HL) | 7 | * * * V 1 * | A←A-(HL) | 10010110 |
SUB (xx+d) | 19 | * * * V 1 * | A←A-(xx+d) | 11x11101 10010110 d |
XOR r | 4 | * * 0 P 0 0 | A←A xor r | 10101rrr |
XOR n | 7 | * * 0 P 0 0 | A←A xor n | 11101110 n |
XOR (HL) | 7 | * * 0 P 0 0 | A←A xor (HL) | 10101110 |
XOR (xx+d) | 19 | * * 0 P 0 0 | A←A xor (xx+d) | 11x11101 10101110 d |
00 NOP | 20 JR NZ,e | 40 LD B,B | 60 LD H,B | 80 ADD A,B | A0 AND B | C0 RET NZ | E0 RET PO |
01 LD BC,nn | 21 LD HL,nn | 41 LD B,C | 61 LD H,C | 81 ADD A,C | A1 AND C | C1 POP BC | E1 POP HL | 02 LD (BC),A | 22 LD (nn),HL | 42 LD B,D | 62 LD H,D | 82 ADD A,D | A2 AND D | C2 JP NZ,nn | E2 JP PO,nn |
03 INC BC | 23 INC HL | 43 LD B,E | 63 LD H,E | 83 ADD A,E | A3 AND E | C3 JP nn | E3 EX (SP),HL |
04 INC B | 24 INC H | 44 LD B,H | 64 LD H,H | 84 ADD A,H | A4 AND H | C4 CALL NZ,nn | E4 CALL PO,nn |
05 DEC B | 25 DEC H | 45 LD B,L | 65 LD H,L | 85 ADD A,L | A5 AND L | C5 PUSH BC | E5 PUSH HL |
06 LD B,n | 26 LD H,n | 46 LD B,(HL) | 66 LD H,(HL) | 86 ADD A,(HL) | A6 AND (HL) | C6 ADD A,n | E6 AND n |
07 RLCA | 27 DAA | 47 LD B,A | 67 LD H,A | 87 ADD A,A | A7 AND A | C7 RST 00H | E7 RST 20H |
08 EX AF,AF' | 28 JR Z,e | 48 LD C,B | 68 LD L,B | 88 ADC A,B | A8 XOR B | C8 RET Z | E8 RET PE |
09 ADD HL,BC | 29 ADD HL,HL | 49 LD C,C | 69 LD L,C | 89 ADC A,C | A9 XOR C | C9 RET | E9 JP (HL) |
0A LD A,(BC) | 2A LD HL,(nn) | 4A LD C,D | 6A LD L,D | 8A ADC A,D | AA XOR D | CA JP Z,nn | EA JP PE,nn |
0B DEC BC | 2B DEC HL | 4B LD C,E | 6B LD L,E | 8B ADC A,E | AB XOR E | CB 別表 | EB EX DE,HL |
0C INC C | 2C INC L | 4C LD C,H | 6C LD L,H | 8C ADC A,H | AC XOR H | CC CALL Z,nn | EC CALL PE,nn |
0D DEC C | 2D DEC L | 4D LD C,L | 6D LD L,L | 8D ADC A,L | AD XOR L | CD CALL nn | ED 別表 |
0E LD C,n | 2E LD L,n | 4E LD C,(HL) | 6E LD L,(HL) | 8E ADC A,(HL) | AE XOR (HL) | CE ADC A,n | EE XOR n |
0F RRCA | 2F CPL | 4F LD C,A | 6F LD L,A | 8F ADC A,A | AF XOR A | CF RST 08H | EF RST 28H |
10 DJNZ e | 30 JR NC,e | 50 LD D,B | 70 LD (HL),B | 90 SUB B | B0 OR B | D0 RET NC | F0 RET P |
11 LD DE,nn | 31 LD SP,nn | 51 LD D,C | 71 LD (HL),C | 91 SUB C | B1 OR C | D1 POP DE | F1 POP AF |
12 LD (DE),A | 32 LD (nn),A | 52 LD D,D | 72 LD (HL),D | 92 SUB D | B2 OR D | D2 JP NC,nn | F2 JP P,nn |
13 INC DE | 33 INC SP | 53 LD D,E | 73 LD (HL),E | 93 SUB E | B3 OR E | D3 OUT (n),A | F3 DI |
14 INC D | 34 INC (HL) | 54 LD D,H | 74 LD (HL),H | 94 SUB H | B4 OR H | D4 CALL NC,nn | F4 CALL P,nn |
15 DEC D | 35 DEC (HL) | 55 LD D,L | 75 LD (HL),L | 95 SUB L | B5 OR L | D5 PUSH DE | F5 PUSH AF |
16 LD D,n | 36 LD (HL),n | 56 LD D,(HL) | 76 HALT | 96 SUB (HL) | B6 OR (HL) | D6 SUB n | F6 OR n |
17 RLA | 37 SCF | 57 LD D,A | 77 LD (HL),A | 97 SUB A | B7 OR A | D7 RST 10H | F7 RST 30H |
18 JR e | 38 JR C,e | 58 LD E,B | 78 LD A,B | 98 SBC A,B | B8 CP B | D8 RET C | F8 RET M |
19 ADD HL,DE | 39 ADD HL,SP | 59 LD E,C | 79 LD A,C | 99 SBC A,C | B9 CP C | D9 EXX | F9 LD SP,HL |
1A LD A,(DE) | 3A LD A,(nn) | 5A LD E,D | 7A LD A,D | 9A SBC A,D | BA CP D | DA JP C,nn | FA JP M,nn |
1B DEC DE | 3B DEC SP | 5B LD E,E | 7B LD A,E | 9B SBC A,E | BB CP E | DB IN A,(n) | FB EI |
1C INC E | 3C INC A | 5C LD E,H | 7C LD A,H | 9C SBC A,H | BC CP H | DC CALL C,nn | FC CALL M,nn |
1D DEC E | 3D DEC A | 5D LD E,L | 7D LD A,L | 9D SBC A,L | BD CP L | DD 別表(IX) | FD 別表(IY) |
1E LD E,n | 3E LD A,n | 5E LD E,(HL) | 7E LD A,(HL) | 9E SBC A,(HL) | BE CP (HL) | DE SBC A,n | FE CP n |
1F RRA | 3F CCF | 5F LD E,A | 7F LD A,A | 9F SBC A,A | BF CP A | DF RST 18H | FF RST 38H |
00 RLC B | 20 SLA B | 40 BIT 0,B | 60 BIT 4,B | 80 RES 0,B | A0 RES 4,B | C0 SET 0,B | E0 SET 4,B |
01 RLC C | 21 SLA C | 41 BIT 0,C | 61 BIT 4,C | 81 RES 0,C | A1 RES 4,C | C1 SET 0,C | E1 SET 4,C |
02 RLC D | 22 SLA D | 42 BIT 0,D | 62 BIT 4,D | 82 RES 0,D | A2 RES 4,D | C2 SET 0,D | E2 SET 4,D |
03 RLC E | 23 SLA E | 43 BIT 0,E | 63 BIT 4,E | 83 RES 0,E | A3 RES 4,E | C3 SET 0,E | E3 SET 4,E |
04 RLC H | 24 SLA H | 44 BIT 0,H | 64 BIT 4,H | 84 RES 0,H | A4 RES 4,H | C4 SET 0,H | E4 SET 4,H |
05 RLC L | 25 SLA L | 45 BIT 0,L | 65 BIT 4,L | 85 RES 0,L | A5 RES 4,L | C5 SET 0,L | E5 SET 4,L |
06 RLC (HL) | 26 SLA (HL) | 46 BIT 0,(HL) | 66 BIT 4,(HL) | 86 RES 0,(HL) | A6 RES 4,(HL) | C6 SET 0,(HL) | E6 SET 4,(HL) |
07 RLC A | 27 SLA A | 47 BIT 0,A | 67 BIT 4,A | 87 RES 0,A | A7 RES 4,A | C7 SET 0,A | E7 SET 4,A |
08 RRC B | 28 SRA B | 48 BIT 1,B | 68 BIT 5,B | 88 RES 1,B | A8 RES 5,B | C8 SET 1,B | E8 SET 5,B |
09 RRC C | 29 SRA C | 49 BIT 1,C | 69 BIT 5,C | 89 RES 1,C | A9 RES 5,C | C9 SET 1,C | E9 SET 5,C |
0A RRC D | 2A SRA D | 4A BIT 1,D | 6A BIT 5,D | 8A RES 1,D | AA RES 5,D | CA SET 1,D | EA SET 5,D |
0B RRC E | 2B SRA E | 4B BIT 1,E | 6B BIT 5,E | 8B RES 1,E | AB RES 5,E | CB SET 1,E | EB SET 5,E |
0C RRC H | 2C SRA H | 4C BIT 1,H | 6C BIT 5,H | 8C RES 1,H | AC RES 5,H | CC SET 1,H | EC SET 5,H |
0D RRC L | 2D SRA L | 4D BIT 1,L | 6D BIT 5,L | 8D RES 1,L | AD RES 5,L | CD SET 1,L | ED SET 5,L |
0E RRC (HL) | 2E SRA (HL) | 4E BIT 1,(HL) | 6E BIT 5,(HL) | 8E RES 1,(HL) | AE RES 5,(HL) | CE SET 1,(HL) | EE SET 5,(HL) |
0F RRC A | 2F SRA A | 4F BIT 1,A | 6F BIT 5,A | 8F RES 1,A | AF RES 5,A | CF SET 1,A | EF SET 5,A |
10 RL B | 30 - | 50 BIT 2,B | 70 BIT 6,B | 90 RES 2,B | B0 RES 6,B | D0 SET 2,B | F0 SET 6,B |
11 RL C | 31 - | 51 BIT 2,C | 71 BIT 6,C | 91 RES 2,C | B1 RES 6,C | D1 SET 2,C | F1 SET 6,C |
12 RL D | 32 - | 52 BIT 2,D | 72 BIT 6,D | 92 RES 2,D | B2 RES 6,D | D2 SET 2,D | F2 SET 6,D |
13 RL E | 33 - | 53 BIT 2,E | 73 BIT 6,E | 93 RES 2,E | B3 RES 6,E | D3 SET 2,E | F3 SET 6,E |
14 RL H | 34 - | 54 BIT 2,H | 74 BIT 6,H | 94 RES 2,H | B4 RES 6,H | D4 SET 2,H | F4 SET 6,H |
15 RL L | 35 - | 55 BIT 2,L | 75 BIT 6,L | 95 RES 2,L | B5 RES 6,L | D5 SET 2,L | F5 SET 6,L |
16 RL (HL) | 36 - | 56 BIT 2,(HL) | 76 BIT 6,(HL) | 96 RES 2,(HL) | B6 RES 6,(HL) | D6 SET 2,(HL) | F6 SET 6,(HL) |
17 RL A | 37 - | 57 BIT 2,A | 77 BIT 6,A | 97 RES 2,A | B7 RES 6,A | D7 SET 2,A | F7 SET 6,A |
18 RR B | 38 SRL B | 58 BIT 3,B | 78 BIT 7,B | 98 RES 3,B | B8 RES 7,B | D8 SET 3,B | F8 SET 7,B |
19 RR C | 39 SRL C | 59 BIT 3,C | 79 BIT 7,C | 99 RES 3,C | B9 RES 7,C | D9 SET 3,C | F9 SET 7,C |
1A RR D | 3A SRL D | 5A BIT 3,D | 7A BIT 7,D | 9A RES 3,D | BA RES 7,D | DA SET 3,D | FA SET 7,D |
1B RR E | 3B SRL E | 5B BIT 3,E | 7B BIT 7,E | 9B RES 3,E | BB RES 7,E | DB SET 3,E | FB SET 7,E |
1C RR H | 3C SRL H | 5C BIT 3,H | 7C BIT 7,H | 9C RES 3,H | BC RES 7,H | DC SET 3,H | FC SET 7,H |
1D RR L | 3D SRL L | 5D BIT 3,L | 7D BIT 7,L | 9D RES 3,L | BD RES 7,L | DD SET 3,L | FD SET 7,L |
1E RR (HL) | 3E SRL (HL) | 5E BIT 3,(HL) | 7E BIT 7,(HL) | 9E RES 3,(HL) | BE RES 7,(HL) | DE SET 3,(HL) | FE SET 7,(HL) |
1F RR A | 3F SRL A | 5F BIT 3,A | 7F BIT 7,A | 9F RES 3,A | BF RES 7,A | DF SET 3,A | FF SET 7,A |
01 - | 11 - | 21 LD IX,nn | 31 - |
02 - | 12 - | 22 LD (nn),IX | 32 - |
03 - | 13 - | 23 INC IX | 33 - |
04 - | 14 - | 24 - | 34 INC (IX+d) |
05 - | 15 - | 25 - | 35 DEC (IX+d) |
06 - | 16 - | 26 - | 36 LD (IX+d),n |
09 ADD IX,BC | 19 ADD IX,DE | 29 ADD IX,IX | 39 ADD IX,SP |
0A - | 1A - | 2A LD IX,(nn) | 3A - |
0B - | 1B - | 2B DEC IX | 3B - |
40 - | 50 - | 60 - | 70 LD (IX+d),B |
41 - | 51 - | 61 - | 71 LD (IX+d),C |
42 - | 52 - | 62 - | 72 LD (IX+d),D |
43 - | 53 - | 63 - | 73 LD (IX+d),E |
44 - | 54 - | 64 - | 74 LD (IX+d),H |
45 - | 55 - | 65 - | 75 LD (IX+d),L |
46 LD B,(IX+d) | 56 LD D,(IX+d) | 66 LD H,(IX+d) | 76 - |
47 - | 57 - | 67 - | 77 LD (IX+d),A |
4E LD C,(IX+d) | 5E LD E,(IX+d) | 6E LD L,(IX+d) | 7E LD A,(IX+d) |
86 ADD A,(IX+d) | 96 SUB (IX+d) | A6 AND (IX+d) | B6 OR (IX+d) |
8E ADC A,(IX+d) | 9E SBC A,(IX+d) | AE XOR (IX+d) | BE CP (IX+d) |
|
E1 POP IX |
E3 EX (SP),IX |
E5 PUSH IX |
E9 JP (IX) |
F9 LD SP,IX |
40 IN B,(C) | 50 IN D,(C) | 60 IN H,(C) | 70 - | A0 LDI | B0 LDIR |
41 OUT (C),B | 51 OUT (C),D | 61 OUT (C),H | 71 - | A1 CPI | B1 CPIR |
42 SBC HL,BC | 52 SBC HL,DE | 62 SBC HL,HL | 72 SBC HL,SP | A2 INI | B2 INIR |
43 LD (nn),BC | 53 LD (nn),DE | 63 - | 73 LD (nn),SP | A3 OUTI | B3 OTIR |
44 NEG | 54 - | 64 - | 74 - | A4 - | B4 - |
45 RETN | 55 - | 65 - | 75 - | A5 - | B5 - |
46 IM 0 | 56 IM 1 | 66 - | 76 - | A6 - | B6 - |
47 LD I,A | 57 LD A,I | 67 RRD | 77 - | A7 - | B7 - |
48 IN C,(C) | 58 IN E,(C) | 68 IN L,(C) | 78 IN A,(C) | A8 LDD | B8 LDDR |
49 OUT (C),C | 59 OUT (C),E | 69 OUT (C),L | 79 OUT (C),A | A9 CPD | B9 CPDR |
4A ADC HL,BC | 5A ADC HL,DE | 6A ADC HL,HL | 7A ADC HL,SP | AA IND | BA INDR |
4B LD BC,(nn) | 5B LD DE,(nn) | 6B - | 7B LD SP,(nn) | AB OUTD | BB OTDR |
4C - | 5C - | 6C - | 7C - | AC - | BC - |
4D RETI | 5D - | 6D - | 7D - | AD - | BD - |
4E - | 5E IM 2 | 6E - | 7E - | AE - | BE - |
4F LD R,A | 5F LD A,R | 6F RLD | 7F - | AF - | BF - |