The Z80 CPU can execute 158 different instruction types including all 78 of the 8080A CPU. The instructions fall into these major groups:
The load instructions move data internally among CPU registers or between CPU registers and external memory. All of these instructions specify a source location from which the data is to be moved, and a destination location. The source location is not altered by a load instruction. Examples of load group instructions include moves between any of the general-purpose registers such as move the data to Register B from Register C. This group also includes load-immediate to any CPU register or to any external memory location. Other types of load instructions allow transfer between CPU registers and memory locations. The exchange instructions can trade the contents of two registers.
A unique set of block transfer instructions is provided in the Z80 CPU. With a single instruction, a block of memory of any size can be moved to any other location in memory. This set of block moves is extremely valuable when processing large strings of data. With a single instruction, a block of external memory of any required length can be searched for any 8-bit character. When the character is found or the end of the block is reached, the instruction automatically terminates. Both the block transfer and the block search instructions can be interrupted during their execution so they are not occupying the CPU for long periods of time.
The arithmetic and logical instructions operate on data stored in the Accumulator and other general-purpose CPU registers or external memory locations. The results of the operations are placed in the Accumulator and the appropriate flags are set according to the result of the operation.
An example of an arithmetic operation is adding the Accumulator to the contents of an external memory location. The results of the addition are placed in the Accumulator. This group also includes 16-bit addition and subtraction between 16-bit CPU registers
The rotate and shift group allows any register or any memory location to be rotated right or left, with or without carry, and either arithmetic or logical. Additionally, a digit in the Accumulator can be rotated right or left with two digits in any memory location.
The bit manipulation instructions allow any bit in the Accumulator, any general-purpose register, or any external memory location to be set, reset, or tested with a single instruction. For example, the most-significant bit of Register H can be reset. This group is especially useful in control applications and for controlling software flags in general-purpose programming.
The JUMP, CALL, and RETURN instructions are used to transfer between multiple locations in the user's program. This group uses several different techniques for obtaining the new program counter address from specific external memory locations. A unique type of call is the RESTART instruction. This instruction actually contains the new address as a part of the 8-bit op code. This instruction is possible because only eight separate addresses located in Page 0 of external memory can be specified. Program jumps can also be achieved by loading Register HL, IX, or IY directly into the Program Counter, which allows the jump address to be a complex function of the routine being executed.
The input/output group of instructions in the Z80 CPU allow for a wide range of transfers between external memory locations or the general-purpose CPU registers, and the external I/O devices. In each case, the port number is provided on the lower eight bits of the address bus during any I/O transaction. One instruction allows this port number to be specified by the second byte of the instruction while other Z80 instructions allow it to be specified as the contents of the C Register. One major advantage of using the C register as a pointer to the I/O device is that it allows multiple I/O ports to share common software driver routines. This advantage is not possible when the address is part of the op code if the routines are stored in ROM. Another feature of these input instructions is the automatic setting of the Flag Register, making additional operations unnecessary to determine the state of the input data. The parity state is one example.
The Z80 CPU includes single instructions that can move blocks of data (up to 256 bytes) automatically to or from any I/O port directly to any memory location. In conjunction with the dual set of general-purpose registers, these instructions provide fast I/O block transfer rates. The power of this I/O instruction set is demonstrated by the Z80 CPU providing all required floppy disk formatting on double-density floppy disk drives on an interruptdriven basis. For example, the CPU provides the preamble, address, data, and enables the CRC codes.
Finally, the basic CPU control instructions allow multiple options and modes. This group includes instructions such as setting or resetting the interrupt enable flip-flop or setting the mode of interrupt response.
Most of the Z80 instructions operate on data stored in internal CPU registers, external memory, or in the I/O ports. Addressing refers to how the address of this data is generated in each instruction. This section is a brief summary of the types of addressing used in the Z80 CPU.
In the Immediate Addressing Mode, the byte following the op code in memory contains the actual operand, as shown below:
Op Code | 1 or 2 bytes | |||||||
Operand | ||||||||
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
An example of this type of instruction is to load the Accumulator with a constant, in which the constant is the byte immediately following the op code.
This mode is an extension of immediate addressing in that the two bytes following the op codes are the operand, as shown below:
Op Code | 1 or 2 bytes | |||||||
Operand | low-order | |||||||
Operand | high-order | |||||||
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
An example of this type of instruction is to load the HL register pair (16-bit register) with 16 bits (two bytes) of data.
The Z80 contains a special single-byte CALL instruction to any of eight locations in Page 0 of memory. This instruction, which is referred to as a restart, sets the Program Counter to an effective address in Page 0. The value of this instruction is that it allows a single byte to specify a complete 16-bit address at which commonly-called subroutines are located, thereby saving memory space.
Op Code | 1 byte | |||||||
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | Effective Address is (00 b5 b4 b3 000) |
Relative addressing uses one byte of data following the op code to specify a displacement from the existing program to which a program jump can occur. This displacement is a signed two’s complement number that is added to the address of the op code of the following instruction.
Op Code | 1 byte | |||||||
Operand | 8-bit 2's complement displacement added to Address (A+2) | |||||||
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
The value of relative addressing is that it allows jumps to nearby locations while only requiring two bytes of memory space. For most programs, relative jumps are by far the most prevalent type of jump due to the proximity of related program segments. Therefore, these instructions can significantly reduce memory space requirements. The signed displacement can range between +127 and –128 from A+2. This range allows for a total displacement of +129 to –126 from the jump relative op code address. Another major advantage is that it allows for relocatable code.
Extended Addressing provides for two bytes (16 bits) of address to be included in the instruction. This data can be an address to which a program can jump or it can be an address at which an operand is located.
Op Code | 1 or 2 bytes | |||||||
Address | low-order address to low-order operand | |||||||
Address | high-order address to low-order operand | |||||||
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
Extended addressing is required for a program to jump from any location in memory to any other location, or load and store data in any memory location.
During extended addressing use, specify the source or destination address of an operand. This notation (nn) is used to indicate the contents of memory at nn, in which nn is the 16- bit address specified in the instruction. The two bytes of address nn are used as a pointer to a memory location. The parentheses always indicates that the value enclosed within them is used as a pointer to a memory location. For example, (1200) refers to the contents of memory at location 1200.
In the Indexed Addressing Mode, the byte of data following the op code contains a displacement that is added to one of the two index registers (the op code specifies which index register is used) to form a pointer to memory. The contents of the index register are not altered by this operation.
Op Code | 2-byte opcode | |||||||
Op Code | ||||||||
Displacement | Operand added to index register to form a pointer to memory | |||||||
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
An example of an indexed instruction is to load the contents of the memory location (Index Register + Displacement) into the Accumulator. The displacement is a signed two’s complement number. Indexed addressing greatly simplifies programs using tables of data because the index register can point to the start of any table. Two index registers are provided because often operations require two or more tables. Indexed addressing also allows for relocatable code.
The two index registers in the Z80 CPU are referred to as IX and IY. To indicate indexed addressing, use the following notation:
(IX+d) or (IY+d)
In this notation, d is the displacement specified after the op code. The parentheses indicate that this value is used as a pointer to external memory.
Many of the Z80 op codes contain bits of information that specify which CPU register is to be used for an operation. An example of register addressing is to load the data in Register B into Register C.
Implied addressing refers to operations in which the op code automatically implies one or more CPU registers as containing the operands. An example is the set of arithmetic operations in which the Accumulator is always implied to be the destination of the results.
This type of addressing specifies a 16-bit CPU register pair (such as HL) to be used as a pointer to any location in memory. This type of instruction is powerful and it is used in a wide range of applications.
Op Code | 1 or 2 byte opcode | |||||||
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
An example of this type of instruction is to load the Accumulator with the data in the memory location pointed to by the HL register contents. Indexed addressing is actually a form of Register Indirect addressing except that a displacement is added with indexed addressing. Register indirect addressing allows for powerful but simple to implement memory accesses. The block move and search commands in the Z80 CPU are extensions of this type of addressing in which automatic register incrementing, decrementing, and comparing is added. The notation for indicating Register Indirect addressing is to put parentheses around the name of the register that is to be used as the pointer. For example, the symbol (HL) specifies that the contents of the HL register are to be used as a pointer to a memory location. Often Register Indirect addressing is used to specify 16-bit operands. In this case, the register contents point to the lower order portion of the operand while the register contents are automatically incremented to obtain the upper portion of the operand.
The Z80 contains a large number of bit set, reset, and test instructions. These instructions allow any memory location or CPU register to be specified for a bit operation through one of three previous addressing modes (register, Register Indirect, and indexed) while three bits in the op code specify which of the eight bits is to be manipulated.
Many instructions include more than one operand (such as arithmetic instructions or loads). In these cases, two types of addressing can be employed. For example, load can use immediate addressing to specify the source and Register Indirect or indexed addressing to specify the destination.
The table below lists the operand notations and descriptions used in the Z80 instruction set.
Notation | Description |
r | Identifies any of the registers A, B, C, D, E, H or L |
(HL) | Identifies the contents of the memory location, whose address is specified by the contents of the register pair HL |
(IX+d) | Identifies the contents of the memory location, whose address is specified by the contents of the Index register pair IX plus the signed displacement d |
(IY+d) | Identifies the contents of the memory location, whose address is specified by the contents of the Index register pair IY plus the signed displacement d |
n | Identifies a one-byte unsigned integer expression in the range (0 to 255) |
nn | Identifies a two-byte unsigned integer expression in the range (0 to 65535) |
d | Identifies a one-byte signed integer expression in the range (-128 to +127) |
b | Identifies a one-bit expression in the range (0 to 7). The most-significant bit to the left is bit 7 and the least-significant bit to the right is bit 0 |
e | Identifies a one-byte signed integer expression in the range (-126 to +129) for relative jump offset from current location |
cc | Identifies the status of the Flag Register as any of (NZ, Z, NC, C, PO, PE, P or M) for the conditional jumps, calls, and return instructions |
Identifies any of the register pairs BC, DE, HL or AF | |
ss | Identifies any of the register pairs BC, DE, HL or SP |
pp | Identifies any of the register pairs BC, DE, IX or SP |
rr | Identifies any of the register pairs BC, DE, IY or SP |
s | Identifies any of r, n, (HL), (IX+d) or (IY+d) |
m | Identifies any of r, (HL), (IX+d) or (IY+d) |