Z80 Assembly Instruction Set
31 May 2023
As I am refreshing my Z80 assembly skills I realized that I don’t have a good understanding of some of the less popular instructions. To make sure that I understand how everything works I’ve gone through all of the instructions and made notes on how they work.
This will be a living document that I will update as I find errors or ommisions. It is intended to be a quick reference. Each of the instructions has the information that I find useful, not a full explanation. I hope that others find it valuable too.
Data Load
| Instruction | Destination | Source |
|---|---|---|
| LD | A | A B C D E H L (HL) (BC) (DE) (IX+index) (IY+index) (word) byte |
| LD | B C D E H L | A B C D E H L (HL) (IX+index) (IY+index) byte |
| LD | (HL) (IX+index) (IY+index) | A B C D E H L byte |
| LD | (BC) (DE) (word) | A |
| LD | BC DE HL SP IX IY | word (word) |
| LD | (word) | BC DE HL SP IX IY |
| LD | SP | HL IX IY |
Register Exchange
| Instruction | Operation | Description |
|---|---|---|
| EX | DE,HL | HL <-> DE |
| EX | (SP),HL | H <-> (SP+1); L <-> (SP) |
| EX | (SP),IX | IXh <-> (SP+1); IXl <-> (SP) |
| EX | (SP),IY | IYh <-> (SP+1); IYl <-> (SP) |
| EX | AF,AF’ | AF <-> AF’ |
| EXX | BC/DE/HL <-> BC’/DE’/HL’ |
Addition and Subtraction
| Instruction | Destination | Source | Description |
|---|---|---|---|
| ADD | A | A B C D E H L (HL) (IX+index) (IY+index) byte | A = A + SOURCE |
| ADC | A | A B C D E H L (HL) (IX+index) (IY+index) byte | A = A + SOURCE + Carry |
| SUB | A | A B C D E H L (HL) (IX+index) (IY+index) byte | A = A - SOURCE |
| SBC | A | A B C D E H L (HL) (IX+index) (IY+index) byte | A = A - SOURCE - Carry |
| ADD | HL IX IY | BC DE HL SP | DEST = DEST + SOURCE |
| ADC | HL | BC DE HL SP | HL = HL + SOURCE + Carry |
| SUB | HL | BC DE HL SP | HL = HL - SOURCE |
| SBC | HL | BC DE HL SP | HL = HL - SOURCE - Carry |
Interrupts and Control
| Instruction | Operation | Description |
|---|---|---|
| DI | Disable interrupts | |
| EI | Enable interrupts | |
| IM | 0 | Interrupt mode 0. Interrupting devices place data on the bus for the CPU to execute |
| IM | 1 | Interrupt mode 1. Interrupts execute RST 38H |
| IM | 2 | Interrupt mode 2. Interrupts perform a call to a location in memory |
| LD | I,A | Interrupt Page = A |
| LD | A,I | A = Interrupt Page |
| LD | R,A | Refresh Register = A |
| LD | A,R | A = Refresh Register |
| NOP | No Operation | |
| HALT | NOP and loop |
Increment and Decrement
| Instruction | Targets |
|---|---|
| INC | A B C D E H L (HL) (IX+index) (IY+index) |
| DEC | A B C D E H L (HL) (IX+index) (IY+index) |
| INC | BC DE HL SP IX IY |
| DEC | BC DE HL SP IX IY |
Special Accumulator and Flags
| Instruction | Description |
|---|---|
| DAA | Convert A to BCD. Used after adding or subtracting two BCD numbers |
| CPL | Complement A = NOT A |
| SCF | Set the Carry Flag to 1 |
| CCF | Complement the Carry Flag |
| NEG | Negate A |
Rotate
| Instruction | Targets | Description |
|---|---|---|
| RLCA | Rotate A left circular | |
| RRCA | Rotate A right circular | |
| RLA | Rotate A left through carry | |
| RRA | Rotate A right through carry | |
| RLD | For BCD. Move low nibble of (HL) to high nibble, move high nibble to A and move A to low nibble | |
| RRD | For BCD. Move low nibble of (HL) to A, high nibble to low and A to high nibble | |
| RLC | A B C D E H L (HL) (IX+index) (IY+index) | Rotate left circular |
| RL | A B C D E H L (HL) (IX+index) (IY+index) | Rotate left through carry |
| RRC | A B C D E H L (HL) (IX+index) (IY+index) | Rotate right circular |
| RR | A B C D E H L (HL) (IX+index) (IY+index) | Rotate right through carry |
| SLA | A B C D E H L (HL) (IX+index) (IY+index) | Shift left arithmetic, sets LSB to 0, MSB goes to Carry |
| SRA | A B C D E H L (HL) (IX+index) (IY+index) | Shift right arithmetic, MSB unchanged, LSB goes to Carry |
| SRL | A B C D E H L (HL) (IX+index) (IY+index) | Shift right logical, sets MSB to 0, LSB goes to Carry |
Logical Byte Operations
| Instruction | Targets | Description |
|---|---|---|
| AND | A B C D E H L (HL) (IX+index) (IY+index) byte | A = A AND Target |
| XOR | A B C D E H L (HL) (IX+index) (IY+index) byte | A = A XOR Target |
| OR | A B C D E H L (HL) (IX+index) (IY+index) byte | A = A OR Target |
| CP | A B C D E H L (HL) (IX+index) (IY+index) byte | Compare A to Target |
| CPI | Compare A to (HL) then increment HL and decrement BC | |
| CPIR | Same as CPI except repeat until a match is found or BC == 0 | |
| CPD | Compare A to (HL) then decrement HL and BC | |
| CPDR | Same as CPD except repeat until a match is found or BC == 0 |
Branch Control/Program Counter Load
| Instruction | Operation | Description |
|---|---|---|
| JP | address | Jump to address or label |
| JP | NZ,address | Jump if A != CP |
| JP | Z,address | Jump if A = CP |
| JP | NC,address | Jump if A >= CP |
| JP | C,address | Jump if A < CP |
| JP | PO,address | Jump if odd number of bits in CP |
| JP | PE,address | Jump if even number of bits in CP |
| JP | P,address | Jump if positive (first bit of A is 0) |
| JP | M,address | Jump if negative (first bit of A is 1) |
| JP | (HL) (IX) (IY) | Jump to what is stored at HL, IX, IY |
| JR | index | Relative jump to address or label |
| JR | NZ,index | Relative Jump if A != CP |
| JR | Z,index | Relative Jump if A = CP |
| JR | NC,index | Relative Jump if A >= CP |
| JR | C,index | Relative Jump if A < CP |
| DJNZ | index | Decreases B and Jumps if B is NotZero |
| CALL | address | Call address or label pushing PC to the stack |
| CALL | NZ Z NC C PO PE P M | Call on condition |
| RET | Pull PC from the stack and return from CALL | |
| RET | NZ Z NC C PO PE P M | Return on condition |
| RETI | Return from Interrupt | |
| RETN | Return from non-maskable Interrupt | |
| RST | 0H 8H 10H 18H 20H 28H 30H 38H | CALL 0H except 1 byte long instead of 3 |
Stack
| Instruction | Targets | Description |
|---|---|---|
| PUSH | BC DE HL AF IX IY | Push target to the stack and decrement stack by 2 |
| POP | BC DE HL AF IX IY | Pop target from the stack and increment stack by 2 |
Input/Output
| Instruction | Operation | Description |
|---|---|---|
| IN | A,(byte) | A = [byte] |
| IN | A,(port) | A = [port] |
| IN | B,(port) | B = [port] |
| IN | C,(port) | C = [port] |
| IN | D,(port) | D = [port] |
| IN | E,(port) | E = [port] |
| IN | H,(port) | H = [port] |
| IN | L,(port) | L = [port] |
| INI | Set (HL) = [port], decrement B and increment HL | |
| INIR | Same as INI, repeat until B = 0 | |
| IND | Set (HL) = [port], decrement B and HL | |
| INDR | Same as IND, repeat until B = 0 | |
| OUT | (byte),A | [byte] = A |
| OUT | (port),A | [port] = A |
| OUT | (port),B | [port] = B |
| OUT | (port),C | [port] = C |
| OUT | (port),D | [port] = D |
| OUT | (port),E | [port] = E |
| OUT | (port),H | [port] = H |
| OUT | (port),L | [port] = L |
| OUTI | Set [port] = (HL), decrement B and increment HL | |
| OTIR | Same as OUTI, repeat until B = 0 | |
| OUTD | Set [port] = (HL), decrement B and HL | |
| OTDR | Same as OUTD, repeat until B = 0 |
Data Transfer
| Instruction | Description |
|---|---|
| LDI | Sets (DE) = (HL), increment HL and DE, decrement BC |
| LDIR | Same as LDI but repeats until B = 0 |
| LDD | Sets (DE) = (HL), decrement HL, DE and BC |
| LDDR | Same as LDD but repeats until B = 0 |
Bit Manipulation
| Instruction | Bits | Registers | Description |
|---|---|---|---|
| BIT | 0-7 | A B C D E H L (HL) (IX+index) (IY+index) | Set Z flag to NOT bit in register |
| RES | 0-7 | A B C D E H L (HL) (IX+index) (IY+index) | Set bit in register to 0 |
| SET | 0-7 | A B C D E H L (HL) (IX+index) (IY+index) | Set bit in register to 1 |