DECODING Z80 OPCODES

- of use to disassembler and emulator writers -
Revision 1
Document by Cristian Dinu, based on various sources of information (see the acknowledgements section)
For any suggestions, factual error reports, please visit the World Of Spectrum forum and post a message there for GOC.

CONTENTS

General info
Unprefixed opcodes
CB-prefixed opcodes
ED-prefixed opcodes
DD-prefixed opcodes
FD-prefixed opcodes
Acknowledgements

GENERAL INFO

Notations

x = the number formed from bits 6 and 7 of the opcode (0 is the least significant)
y = the number formed from bits 3, 4 and 5 of the opcode
z = the number formed from bits 0, 1 and 2 of the opcode
p = the number formed from bits 4 and 5 of the opcode (i.e. y divided by 2)
q = the value of bit 3 of the opcode (i.e. y mod 2)

n = 8-bit immediate unsigned operand (number)
d = 8-bit immediate signed displacement
nn = 16-bit immediate operand (number)
tab[x] = whatever is contained in the table named tab at index x (analogous for y and z and other table names)

All instructions with d, n or nn in their expression are generally immediately followed by the displacement/operand (a byte or a word, respectively).

Although relative jump instructions are often shown with a 16-bit address following them, here they will take the form JR/DJNZ d, where d is the signed 8-bit displacement that follows. The jump's final address is obtained by adding the displacement to the instruction's address plus 2.

In this document, the jump-to-hl instruction is written in its correct form JP HL, not JP (HL).

In the expression of an instruction, everything in bold should be taken ad literam, everything italic should be evaluated.

Tables

8-bit registers (table name: r)
Index01234567
ValueBCDEHL(HL)A

Registers pairs (table name: rp)
Index0123
ValueBCDEHLSP

Registers pairs with AF instead of SP (table name: rp2)
Index0123
ValueBCDEHLAF

Conditions (table name: cc)
Index01234567
ValueNZZNCCPOPEPM

Artithmetic/logic operations (table name: alu)
Index01234567
ValueADD A,ADC A,SUBSBC A,ANDXORORCP

Rotation/shift operations (table name: rot)
Index01234567
ValueRLCRRCRLRRSLASRASLLSRL

Interrupt modes (table name: im)
Index01234567
Value00/11200/112

Block instructions (table name: bli)
z0123
y=4LDICPIINIOUTI
y=5LDDCPDINDOUTD
y=6LDIRCPIRINIROTIR
y=7LDDRCPDRINDROTDR

UNPREFIXED OPCODES

FOR x=0

z=0: Relative jumps and assorted ops

y=0NOP y=3JR d
y=1EX AF, AF' y=4..7JR cc[y-4], d
y=2DJNZ d

z=1: 16-bit load immediate/add

q=0LD rp[p], nn
q=1ADD HL, rp[p]

z=2: Indirect loading

y=0LD (BC), A y=4LD (nn), HL
y=1LD A, (BC) y=5LD HL, (nn)
y=2LD (DE), A y=6LD (nn), A
y=3LD A, (DE) y=7LD A, (nn)

z=3: 16-bit INC/DEC

q=0INC rp[p]
q=1DEC rp[p]

z=4: 8-bit INC

INC r[y]

z=5: 8-bit DEC

DEC r[y]

z=6: 8-bit load immediate

LD r[y], n

z=7: Assorted operations on accumulator/flags

y=0RLCA y=4DAA
y=1RRCA y=5CPL
y=2RLA y=6SCF
y=3RRA y=7CCF

FOR x=1

8-bit loading

LD r[y], r[z]

Exception: if y=6 and z=6, the instruction is HALT.

FOR x=2

Operate on accumulator and register/memory location

alu[y] r[z]

FOR x=3

z=0: Conditional return

RET cc[y]

z=1: POP & various ops

q=0POP rp2[p]
q=1p=0RET p=2JP HL
p=1EXX p=3LD SP, HL

z=2: Conditional jump

JP cc[y], nn

z=3: Assorted operations

y=0JP nn y=4EX (SP), HL
y=1(CB prefix) y=5EX DE, HL
y=2OUT (n), A y=6DI
y=3IN A, (n) y=7EI

z=4: Conditional call

CALL cc[y], nn

z=5: PUSH & various ops

q=0PUSH rp2[p]
q=1p=0CALL nn p=2(ED prefix)
p=1(DD prefix) p=3(FD prefix)

z=6: Operate on accumulator and immediate operand

alu[y] n

z=7: Restart

RST y*8 (in hex)

CB-PREFIXED OPCODES

x=0: Roll/shift register or memory location

rot[y] r[z]

x=1: Test bit

BIT y, r[z]

x=2: Reset bit

RES y, r[z]

x=3: Set bit

SET y, r[z]

ED-PREFIXED OPCODES

FOR x=0

Invalid instruction, equivalent to two NOPs.

FOR x=1

z=0: Input from 16-bit port

y<>6IN r[y], (C)
y=6IN (C)

z=1: Output to 16-bit port

y<>6OUT (C), r[y]
y=6OUT (C), 0

z=2: 16-bit add/subtract with carry

q=0SBC HL, rp[p]
q=1ADC HL, rp[p]

z=3: Retrieve/store register pair from/to immediate address

q=0LD (nn), rp[p]
q=1LD rp[p], (nn)

z=4: Negate accumulator

NEG

z=5: Return from interrupt

y<>1RETN
y=1RETI

z=6: Set interrupt mode

IM im[y]

z=7: Assorted ops

y=0LD I, A y=4RRD
y=1LD R, A y=5RLD
y=2LD A, I y=6NOP
y=3LD I, A y=7NOP

FOR x=2

For y=4..7 and z=0..3, the instruction is bli[y,z].

Otherwise, invalid instruction, equivalent to two NOPs.

FOR x=3

Invalid instruction, equivalent to two NOPs.

DD-PREFIXED OPCODES

If the next byte is a DD, ED or FD prefix, this DD prefix is ignored (equiv. to a NOP) and processing continues with the next byte.

If the next byte is a CB prefix, the instruction will be read as follows:

DD CB d op (a total of 4 bytes)

CB and op will form a CB-instruction which can be decoded as stated earlier. However, the instruction will now also act on (IX+d). For instance, RLC B becomes RLC B, (IX+d). If the instruction acted on (HL) or if the mnemonic was BIT, the instruction will only act on (IX+d).

Otherwise:

If the next opcode makes use of HL, H, L, but not (HL), any occurence of these will be replaced by IX, IXH, IXL respectively. An exception of this is EX DE, HL which is unaffected.

If the next opcode makes use of (HL), it will be replaced by (IX+d), where d is a signed 8-bit displacement immediately following the opcode (any immediate data such as n or nn will follow the displacement byte). Other instances of H and L are unaffected.

All other opcodes are unaffected.

FD-PREFIXED OPCODES

The FD prefix acts exactly like the DD prefix, but it brings in the IY register instead of IX.

ACKNOWLEDGEMENTS

The 'algorithm' described herein was constructed by studying an "instruction/flags affected/binary form/effect" list in a Romanian book called "Ghidul Programatorului ZX Spectrum" ("The ZX Spectrum Programmer's Guide").

The exact effects and quirks of the CB/DD/ED/FD prefixes, as well as the undoccumented ED and CB instructions, were learnt from "The Undocumented Z80 Documented" by Sean Young.


- EOF -