6.1 THE Z80 PROGRAMMING MODEL
In Chapter 2, we developed a model to represent the internal structure of the MPU shown in Figure 2.3. We will now describe a similar model of the Z80 microprocessor; however, we will include only those components necessary for the programmer. Figure 6.1 shows such a model, which includes an accumulator and a flag register, general-purpose register arrays, registers used as memory pointers,
and special-purpose registers. These registers and their functions were described briefly in Chapter 3 in the context of the Z80 architecture; now, they are described in detail in the following sections.
6.1.1 Accumulator
The accumulator is an 8-bit register that is part of the Arithmetic/Logic unit (ALU) and is also identified as register A. This register is used to store 8-bit data and to perform arithmetic and logic operations. The result of an operation performed in the ALU is also stored in the accumulator. For example, in an 8-bit addition, the instruction ADD always assumes that one of the numbers is the byte in the accumulator. and the result of the addition is stored in the accumulator by replacing the previous byte.
Figure 6.1 shows an additional accumulator called A’ in the alternate register set. A’ is not directly accessible to store a byte or perform an ALU operation, but the contents of A’ are accessible by using the exchange instruction EX AF,AF’.
6.1.2 Flag Register
The ALU includes, six flip-flops that are set or reset according to data conditions after an ALU operation, and the status of each flip-flop, also known as flags, is shown in the flag register F. The status of each of the six flags is stored in the 8bit flag register so that they can be examined if necessary. The bit position of each flag is shown in Figure 6.2; bits D5 and D3 are unused.
Among the six flags, the H (Half-Carry) and N (Add/Subtract) flags are used .internally by the microprocessor for BCD (Binary Coded Decimal) operations.
These two flags cannot be tested by any instruction and are not available to the programmer for decision making. The remaining four flags-S (Sign), Z (Zero), P/V (Parity/Overflow), and C (Carry)* -can be tested in conjunction with Conditional Jump or .Call instructions. Each of these four flags has two Jumps or Call instructions associated with it: one when the flag is set and the other when the flag is reset. These flags have critical importance in the decision-making process;
all decisions are based on the status of these flags. For example, the instruction JP C, 2050H (Jump on Carry to memory location 2050H) is implemented to change the sequence of a program when the Carry flag is set.
The details of these flags are described below in the order of frequency of use. They will be discussed again in the context of illustrative programs. At the outset. The descriptions of these flags may appear quite complex. However, when we begin to write programs, we will see that, in general, most flags are ignored except one or two depending upon the operations being performed. For the time being, to understand their function, you should focus on three flags: C (Carry), Z (Zero). and S (Sign).
Ø C-Carry flag: If an arithmetic operation generates a carry (in addition) or a borrow (in subtraction), the Carry flag is set; otherwise it is reset.
It is important to remember that when an arithmetic operation does not generate a carry (or borrow), the flag is reset.
The flag is also affected by such other ; instructions as logic and shift instructions. The details will be discussed when specific instructions are explained. The Z80 includes instructions SCF-Set Carry Fla8-and CCF- Complement Carry Flag-that can set or complement this flag independent of the previous ALU operation.
Ø Z-Zero flag: If an 8-bit operation results in zero, the Z flag is set; otherwise it is reset.
In a bit testing operation, if the bit is zero, this flag is set; otherwise it is reset. In comparing two numbers, the Z flag is set when they are equal; otherwise it is reset.
The Z flag is also affected by special input instructions, block I/O instructions, and counting instructions.
Ø S-Sign flag: After an ALU operation, if the most significant bit D7 is 1, the sign flag is set; otherwise it is reset. When the flag is set, you do not necessarily have a negative result. The interpretation of the Sign flag depends upon the number system (unsigned number, signed magnitude, or 2’s complement) being used by the programmer. This flag can, of course, be used to indicate negative numbers, but its usage can be confusing. Therefore, it is discussed in detail in the context of the appropriate instructions. This flag is also affected by special input instructions in the Z80 set.
Ø P/V-Parity/Overflow flag: This flag is used for two purposes: to check the parity (the number of Is in a byte) and to check an overflow in dealing with signed numbers.
In the case of a parity check after an operation, if the number of ls in the result is even (even parity), this flag is set, and if the number of ls is odd (odd parity), the flag is reset. For example, if the result of ANDing two bytes is 0 0 0 0 0 0 11, the parity flag is set to indicate even parity (two ls). In this example, the magnitude base-ten (310) is odd; however, the odd or even number has no relationship with the odd or the even parity.
In arithmetic operations of signed numbers where bit D7 is used to indicate sign, this flag is set to indicate an overflow condition. For example, when bit D7 is reserved for a sign, the magnitude of a number is represented by the remaining seven bits, the maximum being 01 1 1 1 1 1 1 (+ 12710), After an addition, if the sum goes beyond + 127,bit D7 changes to l, a change that would indicate a negative result. In fact, this is an overflow condition and it is indicated by the overflow (V) flag,
This flag is also used for other functions such as block transfer, search, and interrupt.
Ø H-Half-Carry flag: In an arithmetic operation, this flag is affected by the carry or borrow between bits D3 and D4.In addition, when there is a carry from bit D3 to D4,the Half-Carry flag (H) is set; otherwise, it is reset. In a subtraction, when there is a borrow from bit D4 to D3, this flag is set; otherwise, it is reset. The flag is used internally for BCD (Binary Coded Decimal) operations, and there are no Jump or Call instructions associated with this flag.
Ø N-Add/Subtract flag: This flag is also used internally for BCD operations to distinguish between addition and subtraction. For BCD addition, this flag is 0 and for subtraction it is set to l ,
The alternate flag register F’ is associated with the alternate accumulator A’ as shown in Figure 6.1. The contents of this register can be accessed by using the exchange instruction.
6.1.3 General- Purpose and Alternate Registers
The Z80 microprocessor has six programmable general-purpose registers named B, C, D, E, H, and L, as shown in Figure 6. I. These are 8-bit registers used for storing data during the program execution. They can be combined as register pairs-BC, DE, HL- to perform 16-bit operations or to hold memory addresses.
The programmer can use these registers to load or copy data. For example, the instruction LD B, C copies the data from register C into register B, Conceptually, these registers can be viewed as memory locations, except that they are built inside the microprocessor and identified by specific names. Some microprocessors do not have this type of register; instead, they use memory as their registers.
In addition to the general-purpose registers, the Z80 includes a similar set of six alternate registers designated as B’, C’, D’, E’, H’, and L’. They are not directly available to the programmer, except through the exchange instructions; The contents of general-purpose register pairs can be exchanged with the alternate register pairs.
6.1.4 16-Bit Registers as Memory Pointers
The Z80 microprocessor includes four 16-bit registers used to hold memory addresses; they are classified here as memory pointers. The primary function of memory is to store instructions and data, and the microprocessor needs to access Memory registers to read these instructions and data. To access a memory register, the microprocessor identifies the register by using the addresses in these memory pointers.
INDEX REGISTERS (IX AND IY)
The Z80 has two 16-bit index registers called IX and IY. Each register is used to specify a memory address by the 16-bit address it holds and a displacement count. For example, if the IX register holds 2050H; a higher memory address such as 2060H can be specified by adding the displacement count of 10H. Similarly, a lower memory address such as 2040H can be specified by adding the negative of 10H in 2’s complement.
In addition to the index registers, the HL Pair is frequently used as a memory pointer. Similarly, the BC and DE pairs can used also memory pointers in a limited way. However, no displacement byte can be added to the contents of these pairs.
STACK POINTER (SP)
The stack pointer is also a 16-bit register used to point to the memory location called the stack. The stack is a defined area of memory locations in R/W memory, and the beginning of the stack is defined by loading a 16-bit address into the stack
pointer.
We will discuss the concept of the stack memory in detail when we introduce the topic of subroutines.
PROGRAM COUNTER (PC)
This register functions as a 16-bit counter. The microprocessor uses this register to sequence the execution of instructions. The program counter points to the memory address from which the next byte is to be fetched, and when the microprocessor places an address on the address bus to fetch the byte from memory, it then increments the program counter by one to point to the next memory location.
6.1.5 Special-Purpose Registers
The Z80 microprocessor includes two special-purpose registers, generally absent in other 8-bit microprocessors. These registers are shown in Figure 6.1 as interrupt vector register (I)and the memory refresh register (R).
INTERRUPT VECTOR REGISTER (I)
This is an 8-bit register used in the interrupt process. When an external device interrupts the microprocessor with a request to do something else, the microprocessor should be directed to a 16-bit address in memory where it can find what to do next. The I register is used to store the high-order eight bits of the 16-bit address; the low-order eight bits must be supplied by the interrupting device . We will discuss the details and applications of this register in chapter 12.
MEMORY REFRESH REGISTER (R)
The memory refresh register (R) is also an 8-bit register that is used as a 7-bit counter to provide an address of memory cells to be refreshed in dynamic memory. "As mentioned in Chapter 2, information stored as a capacitive charge in dynamic memory leaks; therefore, bit information should be refreshed, meaning it should be read and stored again every few milliseconds. Applications of the memory refresh register (R) will be discussed in detail with the topic of Interfacing Dynamic Memory. ‘