CS22! An Example of a Real Computer: The Z80                    10/17/98

Need: Transparency of Z80 Architecture

I. Introduction
-  ------------

   A. We will devote a brief time to an overview of the Zilog Z80 CPU as an
      example of a "real" computer - in contrast to the abstract models of
      computation studied in CS220.  We will also devote one lab in this
      course to a few experiments with an MPF-IP one board microcomputer that
      uses this CPU.  (We will also use this one board microcomputer for several
      labs in CS222).

   B. Our goal

      1. NOT that you master the Z80.

      2. RATHER that you gain an appreciation of what a computer is like at
         the machine-language level of description - the dividing line between
         hardware and software.

      3. The Z80/MPF-IP are early 1980's technology, and are very simple
         when compared to more modern systems.  However, their very simplicity
         is an advantage to accomplishing our goal, which is why we are using
         them.  We will cover only a few key features, and omit may details.
 
   C. Terminology

      1. The Z80 is a CPU - central processing unit - having the ability to 
         fetch and execute machine language instructions.  These instructions,
         in turn, can specify simple operations such as transferring an item
         of data between the outside world and one of the Z80's internal
         registers, or performing simple a computational operations (e.g. 
         addition).

      2. The MPF-IP is a COMPUTER - it includes a Z80 CPU, plus a memory
         system, plus an input-output system. 

II. Z80 CPU architecture
--  --- --- ------------

   TRANSPARENCY: Z80 ARCHITECTURE

   A. The Z80 is a pure 8-bit microprocessor, which means that its internal
      registers and data paths (as well as its external data bus) are 8 bits
      wide.

      1. This means that basic arithmetic operations are performed on 8-bit
         operands, which can represent values in the range of 0..255 (unsigned)
         or -128 .. 127 (signed).

      2. When it is desired to work on numbers having a larger range of values,
         it is possible to combine two 8-bit operands to yield a 16-bit
         value (range 0..65535 (unsigned) or -32768..32767 (signed) or even to
         combine four to yield a 32-bit value.  However, the internal
         arithmetic is done 8-bits at a time - thus adding two 16-bit numbers
         requires two steps, one for each half of the operands.

      3. Many modern CPU's are 32-bit processors, which means their internal
         data paths and registers are 32 bits wide (though some high-end
         processors are 64-bit).  These machines typically allow the user the
         option of working with 8, 16, or 32 bit operands, so less storage can
         be used when a smaller range of values is all that is needed.  (E.g.
         character strings are typically represented using 8 bits per 
         character).

      4. However, 8-bit CPU's are still manufactured and used extensively in
         embedded systems - e.g.home appliances - where the power of a 16-bit or
         32-bit CPU is not needed and does not warrant the extra cost and wiring
         complexity.  (The latter is a key issue - a 32-bit system needs four
         times as many data lines between the CPU and memory as an 8-bit system
         needs, which adds to manufacturing complexity and cost. It is probable 
         that a typical home contains more 8-bit CPU's than anything else!)

   B. The Z80 CPU connects to the outside world through two BUSSES plus a
      set of control lines.

      1. The 8-bit DATA BUS can be used to transfer a byte of information
         between the CPU and the outside world.

      2. The 16-bit ADDRESS BUS is used to specify exactly where the data is
         to be transferred from or to.  With 16-bits, it is possible to specify
         65536 (64K) unique addresses - thus the Z80 can connect to up to
         64K of memory.  (A larger memory would be useless, because there would 
         be no way to address locations beyond 64K.)

      3. The control lines are used to specify what type of operation is to be
         performed - e.g. read (transfer to data to the Z80 from some external
         source) or write (transfer of data from the Z80 to some external
         destination), and whether the external device being addressed is
         memory or an input-output device.  (We will discuss details of the 
         control lines in CS222.)

      4. On the MFP-IP, these busses are connected to on-board memory chips
         that provide 8K bytes of read only memory (ROM) and 4K bytes of 
         read- write memory (RAM), plus various IO devices (keyboard, display,
         etc.)  That means that less than 20% of possible memory addresses 
         correspond to actual memory on the MPF-IP.

      5. The use of an 8-bit data bus and a 16-bit address bus (as contrasted
         to 32 bits for each on more powerful CPU's) will be an advantage for 
         us in lab - a lot less wires to hook up when interfacing things to the 
         system!  

   C. The Z80 is basically a one-accumulator machine, which means that for
      most arithmetic and logical operations the A register (the accumulator)
      contains one of the source operands and receives the result of the
      operation.  This contrasts with many newer computers - including the VAX
      and the MIPs described in the text, which have a number of general
      registers which are equally capable of participation in arithmetic and 
      logical operations.

      Example: The HLL statement

         x := y + z;

         (where x, y, and z are variables stored in memory)

         would be implemented by the following (using a slightly modified 
         version of Z80 assembly language)

         LOAD   A, (address of Y)
         LOAD   HL, address of Z
         ADD    (HL)
         STORE  (address of X), A

         where (a) means the memory cell whose address is a      

   D. The Z80 has a total of 16 8-bit registers and 4 16-bit registers. 

      1. The 16-bit PC contains the address of the next instruction to be
         executed.

      2. The 16-bit SP is a stack pointer used to maintain a hardware stack
         in memory - it contains the address of the memory cell holding the
         top item on the stack. 

      3. The 8-bit A register is the accumulator, and participates in most
         arithmetic and logical operations.

      4. The 8-bit F register has only 5 bits that are actually used - the other
         3 have undefined values.  These bits serve as condition codes to 
         reflect the results of various arithmetic and logical operations.

      5. The 8-bit registers B,C,D and E provide temporary storage for
         intermediate results of operations, and can also be paired up (BC, 
         DE) to form 16-bit registers that can be used as pointers to memory 
         cells.

      6. The 8-bit registers H and L are seldom used as 8-bit registers.  More
         often they are paired to form a 16-bit register that is used to point
         to a memory location.  Many memory-reference instructions require that
         the address of the item to be fetched or stored be in HL.  

      7. In some contexts the F register can be paired with A to form a 16
         bit AF register.  This is primarily done when pushing registers on
         a stack - they are pushed 16 bits at a time, so A and F are pushed
         together.  

      8. There is an alternative set of 8-bit registers A', B', C' ... which can
         be exchanged with the normal set

      9. There are two 16-bit registers IX and IY, and two 8-bit registers I
         and R, that we won't discuss now.

III. Highlights of the Z80 instruction set
---  ---------- -- --- --- ----------- ---

   A. The Z80 has a total of 694 basic instructions, though many are slight
      variations on a basic theme - so the total number of distinct 
      instructions is actually much less.

      1. All instructions begin with an operation code, which is 1, 2, or 3 
         bytes long.  There are 253 instructions with 1 byte op-codes, and most 
         of the rest use a 2 byte op-code.

         a. The op code specifies the basic operation to be performed.

         b. It also frequently specifies one or two registers that are to be
            used in the operation.

      2. Many instructions have one or two additional bytes after the
         op-code, which may specify:
        
         a. An 8 or 16 bit value to be used as an operand by the instruction.

         b. A 16 bit address of a location in memory that holds an operand of
            the instruction.

   B. We will now discuss a subset of the Z80 instruction set that will
      serve to give us a "feel" for the architecture.  We will use many of
      the instructions we cover in lab, too.  For each instruction we will
      give both a symbolic representation and the actual machine encoding.

      1. Data movement instructions are used to copy values from one location
         to another.

         a. Load a byte from a specified memory address into register A

            LD A, (address)     -- note () means "contents of memory cell
                                   whose address is"

            3A   low-byte       high-byte
                of address      of address

            Note "byte reversed" format.

            Example: 3A 00 80   -- load contents of memory cell 8000 into A

         b. Store byte in A to a specified memory address

            LD (address), A

            32   low-byte       high-byte
                of address      of address

            Note "byte reversed" format.

            Example: 32 00 80   -- store contents of A into memory cell 8000 

         c. Load a constant into a register (or memory location)

            LD reg, value

            00 rrr 110  value

            Where rrr is:       000 register B
                                001 register C
                                010 register D
                                011 register E
                                100 register H
                                101 register L
                                110 MEMORY LOCATION whose address is in HL
                                111 register A

            Examples: 06 99     -- load 99 into register B
                      3E 42     -- load 42 into register A
                      36 10     -- put 10 into the memory location whose
                                   address is in HL

         d. Copy a value from one register to another (or to/from memory)

            LD dest, src

            01 ddd sss

            Where ddd specifies the destination register, encoded as above
                  sss specifies the source register, encoded as above
        
            Examples: 48        -- copy the contents of register B into C
                      06        -- load the contents of the memory location
                                   whose address is in HL into register B
                      70        -- stoe the contents of register B into the
                                   memory location whose address is in HL

            Special case: 76 would copy the contents of the memory location
                          whose address is in HL back into itself - a   
                          "do nothing" instruction which would also be 
                          complicated to implement due to two references to
                          memory - therefore redefined as HALT

         e. Load a 16 bit value into the HL register pair

            LD HL, value

            21   low-byte       high-byte
                 of value       of value

            Note "byte reversed" format.

            Example: 21 00 80   -- load constant value 8000 into HL

         f. Exchange the contents of registers A and F with A' and F'

            EX AF,AF'

            08

      2. Arithmetic logical instructions are used to perform basic computations.

         a. Perform an operation on register A using some other register or
            memory

            ADD A, reg
            ADC A, reg
            ...

            10fffrrr

            Where rrr specifies the source register, encoded as above
            Where fff specifies the operation, encoded as follows:

                000 Add
                001 Add with carry
                010 Subtract
                011 Subtract with borrow
                100 Bitwise and
                101 Bitwise xor
                110 Bitwise or
                111 Compare

            Example: 80         -- Add contents of register B to register A

         b. Perform an operation on register A using a constant value

            ADD A, value
            ADC A, value
            ...

            11fff110    value

            Where fff specifies the operation, encoded as above

            Example: EE 20      -- XOR register A with 20

         c. Increment (add 1 to) a register (or memory location)

            INC r

            00rrr100

            where rrr is encoded as above

            Example: 3C         -- increment register A
        
         d. Decrement (subtract 1 from) a register (or memory location)

            DEC r

            00rrr101

            Where rrr is encoded as above

            Example: 0D         -- decrement register C

      3. Input-output operations transfer a byte of data between register A
         and an input or output port (numbered 0..255)

         a. Input:

            IN A, (port)

            DB port

            Exaple: DB 90       -- input a byte from port 90 into A

         b. Output:

            OUT (port), A

            D3 port

            Example: D3 92      -- output a byte from A to port 92

      4. Program control instructions alter the normal sequence of instruction
         execution.

         a. Normally, instructions are executed sequentially - e.g. if the
            instruction at FB00 is executed and is 2 bytes long, then the
            next instruction will be taken from FB02

         b. Unconditional jump - take next instruction from a designated
            address, and continue execution from that point

            JP address

            C3   low-byte       high-byte
                of address      of address

            Note "byte reversed" format.

            Example: C3 00 FC   -- take next instruction from FC00, and
                                   continue execution from that point

         c. Conditional jump - jump or don't jump, based on result produced
            by last computational instruction (encoded in flags register F)

            JP condition, address

            110ccc010

            Where ccc encodes the condition to be tested, as follows:

                000     Result of last operation was non-zero
                001     Result of last operation was zero
                010     Last operation did not produce carry
                011     Last operation did produce carry
                100     Last operation did not result in overflow
                101     Last operation did result in overflow
                110     Result of last operation was positive (>= 0)
                111     Result of last operation was negative

         d. Procedure call/return

            CALL address

            CD   low-byte       high-byte
                of address      of address

            Same as jump - EXCEPT PC (which contains address of next 
            instruction after this one) is pushed on runtime stack

            RET

            C9

            Pop value from stack into PC - execution will continue at this
            address (which is instruction following the CALL that we are
            returning from.)

         e. Halt the processor.  No further instructions will be executed until
            the CPU is reset.  (Not normally used to terminate a program -
            only used to totally shut down the system)

            HALT

            76

      5. The program control instructions can be used to implement the
         familiar control structures of HLL's:

         Example:       repeat
                           statement(s)
                        until condition

                aaaa    code for statement(s)
                        code to test condition
                        jump to address aaaa if condition is FALSE

         Example:       while condition do
                            statement(s)

                        JP bbbb
                aaaa    code for statement(s)
                bbbb    code to test condition
                        jump to address aaaa if condition is TRUE

                        (for is similar, but requires code to maintain loop
                         variable)

         Example:       if condition then
                            statement(s)
                        else
                            statements(s)

                        code to test condition
                        jump to address aaaa if condition is FALSE
                        code for then statement(s)
                        jump to address bbbb (unconditional)
                aaaa    code for else statement(s)
                bbbb    ...

                        (case can be translated into nested if .. then ..
                         elses, or can use a machine language instruction
                         we have not discussed)

         Example:       procedure p
                        begin
                            statement(s)
                        end
                        ...
                        p;

                aaaaa   code for body of procedure p
                        RET
                        ...

                        CALL aaaa

Copyright ©1998 - Russell C. Bjork